From e8a3f7e0ea433edd39edeb9562fb21ca67a807d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Thu, 14 Nov 2024 16:59:30 +0100 Subject: [PATCH 01/15] vc/intel/fsp/fsp2_0/iot/meteorlake: add missing MemInfoHob from client vc dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- .../fsp/fsp2_0/iot/meteorlake/MemInfoHob.h | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 src/vendorcode/intel/fsp/fsp2_0/iot/meteorlake/MemInfoHob.h diff --git a/src/vendorcode/intel/fsp/fsp2_0/iot/meteorlake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/iot/meteorlake/MemInfoHob.h new file mode 100644 index 00000000000..7660a30d301 --- /dev/null +++ b/src/vendorcode/intel/fsp/fsp2_0/iot/meteorlake/MemInfoHob.h @@ -0,0 +1,325 @@ +/** @file + This file contains definitions required for creation of + Memory S3 Save data, Memory Info data and Memory Platform + data hobs. + + @copyright + Copyright (c) 1999 - 2022, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +@par Specification Reference: +**/ +#ifndef _MEM_INFO_HOB_H_ +#define _MEM_INFO_HOB_H_ + + +#pragma pack (push, 1) + +extern EFI_GUID gSiMemoryS3DataGuid; +extern EFI_GUID gSiMemoryS3Data2Guid; +extern EFI_GUID gSiMemoryInfoDataGuid; +extern EFI_GUID gSiMemoryPlatformDataGuid; + +#define MAX_NODE 2 +#define MAX_CH 4 +#define MAX_DDR5_CH 2 +#define MAX_DIMM 2 +// Must match definitions in +// Intel\ClientOneSiliconPkg\IpBlock\MemoryInit\Mtl\Include\MrcInterface.h +#define HOB_MAX_SAGV_POINTS 4 + +/// +/// Host reset states from MRC. +/// +#define WARM_BOOT 2 + +#define R_MC_CHNL_RANK_PRESENT 0x7C +#define B_RANK0_PRS BIT0 +#define B_RANK1_PRS BIT1 +#define B_RANK2_PRS BIT4 +#define B_RANK3_PRS BIT5 + +// @todo remove and use the MdePkg\Include\Pi\PiHob.h +#if !defined(_PEI_HOB_H_) && !defined(__PI_HOB_H__) +#ifndef __HOB__H__ +typedef struct _EFI_HOB_GENERIC_HEADER { + UINT16 HobType; + UINT16 HobLength; + UINT32 Reserved; +} EFI_HOB_GENERIC_HEADER; + +typedef struct _EFI_HOB_GUID_TYPE { + EFI_HOB_GENERIC_HEADER Header; + EFI_GUID Name; + /// + /// Guid specific data goes here + /// +} EFI_HOB_GUID_TYPE; +#endif +#endif + +/// +/// Defines taken from MRC so avoid having to include MrcInterface.h +/// + +// +// Matches MAX_SPD_SAVE define in MRC +// +#ifndef MAX_SPD_SAVE +#define MAX_SPD_SAVE 29 +#endif + +// +// MRC version description. +// +typedef struct { + UINT8 Major; ///< Major version number + UINT8 Minor; ///< Minor version number + UINT8 Rev; ///< Revision number + UINT8 Build; ///< Build number +} SiMrcVersion; + +// +// Matches MrcChannelSts enum in MRC +// +#ifndef CHANNEL_NOT_PRESENT +#define CHANNEL_NOT_PRESENT 0 // There is no channel present on the controller. +#endif +#ifndef CHANNEL_DISABLED +#define CHANNEL_DISABLED 1 // There is a channel present but it is disabled. +#endif +#ifndef CHANNEL_PRESENT +#define CHANNEL_PRESENT 2 // There is a channel present and it is enabled. +#endif + +// +// Matches MrcDimmSts enum in MRC +// +#ifndef DIMM_ENABLED +#define DIMM_ENABLED 0 // DIMM/rank Pair is enabled, presence will be detected. +#endif +#ifndef DIMM_DISABLED +#define DIMM_DISABLED 1 // DIMM/rank Pair is disabled, regardless of presence. +#endif +#ifndef DIMM_PRESENT +#define DIMM_PRESENT 2 // There is a DIMM present in the slot/rank pair and it will be used. +#endif +#ifndef DIMM_NOT_PRESENT +#define DIMM_NOT_PRESENT 3 // There is no DIMM present in the slot/rank pair. +#endif + +// +// Matches MrcBootMode enum in MRC +// +#ifndef __MRC_BOOT_MODE__ +#define __MRC_BOOT_MODE__ //The below values are originated from MrcCommonTypes.h + #ifndef INT32_MAX + #define INT32_MAX (0x7FFFFFFF) + #endif //INT32_MAX +typedef enum { + bmCold, ///< Cold boot + bmWarm, ///< Warm boot + bmS3, ///< S3 resume + bmFast, ///< Fast boot + MrcBootModeMax, ///< MRC_BOOT_MODE enumeration maximum value. + MrcBootModeDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI. +} MRC_BOOT_MODE; +#endif //__MRC_BOOT_MODE__ + +// +// Matches MrcDdrType enum in MRC +// +#ifndef MRC_DDR_TYPE_DDR5 +#define MRC_DDR_TYPE_DDR5 1 +#endif +#ifndef MRC_DDR_TYPE_LPDDR5 +#define MRC_DDR_TYPE_LPDDR5 2 +#endif +#ifndef MRC_DDR_TYPE_LPDDR4 +#define MRC_DDR_TYPE_LPDDR4 3 +#endif +#ifndef MRC_DDR_TYPE_UNKNOWN +#define MRC_DDR_TYPE_UNKNOWN 4 +#endif + +#define MAX_PROFILE_NUM 7 // number of memory profiles supported +#define MAX_XMP_PROFILE_NUM 5 // number of XMP profiles supported + +#ifndef MAX_RCOMP_TARGETS +#define MAX_RCOMP_TARGETS 5 +#endif + +#ifndef MAX_ODT_ENTRIES +#define MAX_ODT_ENTRIES 11 +#endif + +#define MAX_TRACE_REGION 5 +#define MAX_TRACE_CACHE_TYPE 2 + +// +// DIMM timings +// +typedef struct { + UINT32 tCK; ///< Memory cycle time, in femtoseconds. + UINT16 NMode; ///< Number of tCK cycles for the channel DIMM's command rate mode. + UINT16 tCL; ///< Number of tCK cycles for the channel DIMM's CAS latency. + UINT16 tCWL; ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time. + UINT16 tFAW; ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time. + UINT16 tRAS; ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time. + UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time. + UINT16 tREFI; ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval. + UINT16 tRFC; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. + UINT16 tRFCpb; ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time. + UINT16 tRFC2; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. + UINT16 tRFC4; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. + UINT16 tRPab; ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks. + UINT16 tRRD; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time. + UINT16 tRRD_L; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups. + UINT16 tRRD_S; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups. + UINT16 tRTP; ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time. + UINT16 tWR; ///< Number of tCK cycles for the channel DIMM's minimum write recovery time. + UINT16 tWTR; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time. + UINT16 tWTR_L; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups. + UINT16 tWTR_S; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups. + UINT16 tCCD_L; ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group. + UINT16 tCCD_L_WR; ///< Number of tCK cycles for the channel DIMM's minimum Write-to-Write delay for same bank group. +} MRC_CH_TIMING; + +typedef struct { + UINT16 tRDPRE; ///< Read CAS to Precharge cmd delay +} MRC_IP_TIMING; + +/// +/// Memory SMBIOS & OC Memory Data Hob +/// +typedef struct { + UINT8 Status; ///< See MrcDimmStatus for the definition of this field. + UINT8 DimmId; + UINT32 DimmCapacity; ///< DIMM size in MBytes. + UINT16 MfgId; + UINT8 ModulePartNum[20]; ///< Module part number for DDR3 is 18 bytes however for DDR4 20 bytes as per JEDEC Spec, so reserving 20 bytes + UINT8 RankInDimm; ///< The number of ranks in this DIMM. + UINT8 SpdDramDeviceType; ///< Save SPD DramDeviceType information needed for SMBIOS structure creation. + UINT8 SpdModuleType; ///< Save SPD ModuleType information needed for SMBIOS structure creation. + UINT8 SpdModuleMemoryBusWidth; ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation. + UINT8 SpdSave[MAX_SPD_SAVE]; ///< Save SPD Manufacturing information needed for SMBIOS structure creation. + UINT16 Speed; ///< The maximum capable speed of the device, in MHz + UINT8 MdSocket; ///< MdSocket: 0 = Memory Down, 1 = Socketed. Needed for SMBIOS structure creation. +} DIMM_INFO; + +typedef struct { + UINT8 Status; ///< Indicates whether this channel should be used. + UINT8 ChannelId; + UINT8 DimmCount; ///< Number of valid DIMMs that exist in the channel. + MRC_CH_TIMING Timing[MAX_PROFILE_NUM]; ///< The channel timing values. + DIMM_INFO DimmInfo[MAX_DIMM]; ///< Save the DIMM output characteristics. +} CHANNEL_INFO; + +typedef struct { + UINT8 Status; ///< Indicates whether this controller should be used. + UINT16 DeviceId; ///< The PCI device id of this memory controller. + UINT8 RevisionId; ///< The PCI revision id of this memory controller. + UINT8 ChannelCount; ///< Number of valid channels that exist on the controller. + CHANNEL_INFO ChannelInfo[MAX_CH]; ///< The following are channel level definitions. +} CONTROLLER_INFO; + +typedef struct { + UINT64 BaseAddress; ///< Trace Base Address + UINT64 TotalSize; ///< Total Trace Region of Same Cache type + UINT8 CacheType; ///< Trace Cache Type + UINT8 ErrorCode; ///< Trace Region Allocation Fail Error code + UINT8 Rsvd[2]; +} PSMI_MEM_INFO; + +/// This data structure contains per-SaGv timing values that are considered output by the MRC. +typedef struct { + UINT32 DataRate; ///< The memory rate for the current SaGv Point in units of MT/s + MRC_CH_TIMING JedecTiming; ///< Timings used for this entry's corresponding SaGv Point - derived from JEDEC SPD spec + MRC_IP_TIMING IpTiming; ///< Timings used for this entry's corresponding SaGv Point - IP specific +} HOB_SAGV_TIMING_OUT; + +/// This data structure contains SAGV config values that are considered output by the MRC. +typedef struct { + UINT32 NumSaGvPointsEnabled; ///< Count of the total number of SAGV Points enabled. + UINT32 SaGvPointMask; ///< Bit mask where each bit indicates an enabled SAGV point. + HOB_SAGV_TIMING_OUT SaGvTiming[HOB_MAX_SAGV_POINTS]; +} HOB_SAGV_INFO; + +typedef struct { + UINT8 Revision; + UINT16 DataWidth; ///< Data width, in bits, of this memory device + /** As defined in SMBIOS 3.0 spec + Section 7.18.2 and Table 75 + **/ + UINT8 MemoryType; ///< DDR type: DDR3, DDR4, or LPDDR3 + UINT16 MaximumMemoryClockSpeed;///< The maximum capable speed of the device, in megahertz (MHz) + UINT16 ConfiguredMemoryClockSpeed; ///< The configured clock speed to the memory device, in megahertz (MHz) + /** As defined in SMBIOS 3.0 spec + Section 7.17.3 and Table 72 + **/ + UINT8 ErrorCorrectionType; + + SiMrcVersion Version; + BOOLEAN EccSupport; + UINT8 MemoryProfile; + UINT32 TotalPhysicalMemorySize; + UINT32 DefaultXmptCK[MAX_XMP_PROFILE_NUM];///< Stores the tCK value read from SPD XMP profiles if they exist. + UINT8 XmpProfileEnable; ///< If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs. + UINT8 XmpConfigWarning; ///< If XMP capable DIMMs config support only 1DPC, but 2DPC is installed + BOOLEAN DynamicMemoryBoostTrainingFailed; ///< TRUE if Dynamic Memory Boost failed to train and was force disabled on the last full training boot. FALSE otherwise. + UINT16 Ratio; ///< DDR Frequency Ratio, used for programs that require ratios higher then 255 + UINT8 RefClk; + UINT32 VddVoltage[MAX_PROFILE_NUM]; + UINT32 VddqVoltage[MAX_PROFILE_NUM]; + UINT32 VppVoltage[MAX_PROFILE_NUM]; + UINT16 RcompTarget[MAX_PROFILE_NUM][MAX_RCOMP_TARGETS]; + UINT16 DimmOdt[MAX_PROFILE_NUM][MAX_DIMM][MAX_ODT_ENTRIES]; + CONTROLLER_INFO Controller[MAX_NODE]; + UINT32 NumPopulatedChannels; ///< Total number of memory channels populated + HOB_SAGV_INFO SagvConfigInfo; ///< This data structure contains SAGV config values that are considered output by the MRC. + BOOLEAN IsIbeccEnabled; + UINT16 TotalMemWidth; ///< Total Memory Width in bits from all populated channels + UINT16 PprDetectedErrors; ///< PPR: Counts of detected bad rows + UINT16 PprRepairFails; ///< PPR: Counts of repair failure + UINT16 PprForceRepairStatus; ///< PPR: Force Repair Status +} MEMORY_INFO_DATA_HOB; + +/** + Memory Platform Data Hob + + Revision 1: + - Initial version. + Revision 2: + - Added TsegBase, PrmrrSize, PrmrrBase, Gttbase, MmioSize, PciEBaseAddress fields +**/ +typedef struct { + UINT8 Revision; + UINT8 Reserved[3]; + UINT32 BootMode; + UINT32 TsegSize; + UINT32 TsegBase; + UINT32 PrmrrSize; + UINT64 PrmrrBase; + UINT32 GttBase; + UINT32 MmioSize; + UINT32 PciEBaseAddress; + PSMI_MEM_INFO PsmiInfo[MAX_TRACE_CACHE_TYPE]; + PSMI_MEM_INFO PsmiRegionInfo[MAX_TRACE_REGION]; + BOOLEAN MrcBasicMemoryTestPass; +} MEMORY_PLATFORM_DATA; + +typedef struct { + EFI_HOB_GUID_TYPE EfiHobGuidType; + MEMORY_PLATFORM_DATA Data; + UINT8 *Buffer; +} MEMORY_PLATFORM_DATA_HOB; + +#pragma pack (pop) + +#endif // _MEM_INFO_HOB_H_ From 9443006a1aeb521101b89c5f5a08b517f0b498e3 Mon Sep 17 00:00:00 2001 From: Shuo Liu Date: Thu, 25 Apr 2024 05:41:16 +0800 Subject: [PATCH 02/15] soc/intel/xeon_sp: Support CHIPSET_LOCKDOWN_FSP In a server platform many silicon specific register lock operations are by default in FSP space. CHIPSET_LOCKDOWN_FSP provides an option to make sure the codes could be used out-of-box to build products. Change-Id: I8efcc1f27446be8e35f51e2568c4af6f8165486b Signed-off-by: Shuo Liu Reviewed-on: https://review.coreboot.org/c/coreboot/+/82081 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/intel/xeon_sp/lockdown.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c index 9e25920011b..a3d17b46c33 100644 --- a/src/soc/intel/xeon_sp/lockdown.c +++ b/src/soc/intel/xeon_sp/lockdown.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -20,6 +21,9 @@ static void lpc_lockdown_config(void) void soc_lockdown_config(int chipset_lockdown) { + if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) + return; + lpc_lockdown_config(); pmc_lockdown_config(); sata_lockdown_config(chipset_lockdown); From a4f9bd2d8c1f957792edbd37c5edb526f7507f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sat, 23 Nov 2024 22:43:10 +0100 Subject: [PATCH 03/15] soc/intel/lockdown: Allow locking down SPI and LPC in SMM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Heads payload uses APM_CNT_FINALIZE SMI to set and lock down the SPI controller with PR0 flash protection for pre-Skylake platforms. Add new option to skip LPC and FAST SPI lock down in coreboot and move it to APM_CNT_FINALIZE SMI handler. Reuse the INTEL_CHIPSET_LOCKDOWN option to prevent issuing APM_CNT_FINALIZE SMI on normal boot path, like it was done on pre-Skylake platforms. As the locking on modern SOCs became more complicated, separate the SPI and LPC locking into new modules to make linking to SMM easier. The expected configuration to leverage the feautre is to unselect INTEL_CHIPSET_LOCKDOWN and select SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM. Testing various microarchitectures happens on heads repository: https://github.com/linuxboot/heads/pull/1818 TEST=Lock the SPI flash using APM_CNT_FINALIZE in heads on Alder Lake (Protectli VP66xx) and Comet Lake (Protectli VP46xx) platforms. Check if flash is unlocked in the heads recovery console. Check if flash is locked in the kexec'ed OS. Change-Id: Icbcc6fcde90e5b0a999aacb720e2e3dc2748c838 Signed-off-by: Michał Żygowski --- src/soc/intel/alderlake/finalize.c | 4 +- src/soc/intel/cannonlake/finalize.c | 4 +- src/soc/intel/common/block/lpc/Makefile.mk | 4 + src/soc/intel/common/block/smm/smihandler.c | 10 +++ .../common/pch/include/intelpch/lockdown.h | 3 + src/soc/intel/common/pch/lockdown/Kconfig | 15 ++++ src/soc/intel/common/pch/lockdown/Makefile.mk | 5 ++ src/soc/intel/common/pch/lockdown/lockdown.c | 49 ++--------- .../intel/common/pch/lockdown/lockdown_lpc.c | 24 ++++++ .../intel/common/pch/lockdown/lockdown_spi.c | 33 ++++++++ src/soc/intel/denverton_ns/lpc.c | 3 +- src/soc/intel/elkhartlake/finalize.c | 4 +- src/soc/intel/jasperlake/finalize.c | 3 +- src/soc/intel/meteorlake/finalize.c | 4 +- src/soc/intel/pantherlake/finalize.c | 84 +++++++++++++++++++ src/soc/intel/skylake/finalize.c | 3 +- src/soc/intel/tigerlake/finalize.c | 4 +- src/soc/intel/xeon_sp/finalize.c | 4 +- src/soc/intel/xeon_sp/lockdown.c | 18 +--- 19 files changed, 211 insertions(+), 67 deletions(-) create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_lpc.c create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_spi.c create mode 100644 src/soc/intel/pantherlake/finalize.c diff --git a/src/soc/intel/alderlake/finalize.c b/src/soc/intel/alderlake/finalize.c index 460c8af174e..9cd9351d96a 100644 --- a/src/soc/intel/alderlake/finalize.c +++ b/src/soc/intel/alderlake/finalize.c @@ -84,7 +84,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c index ba7fc69b552..825dd0aadf1 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -87,7 +87,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT) && CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PMC_IPC)) heci1_disable(); diff --git a/src/soc/intel/common/block/lpc/Makefile.mk b/src/soc/intel/common/block/lpc/Makefile.mk index b510cd0ec35..60792654b5a 100644 --- a/src/soc/intel/common/block/lpc/Makefile.mk +++ b/src/soc/intel/common/block/lpc/Makefile.mk @@ -5,3 +5,7 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc.c + +ifeq ($(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM),y) +smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c +endif diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index c1f895fbd2a..65a15b09649 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -15,12 +15,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -347,6 +349,14 @@ static void finalize(void) } finalize_done = 1; + if (CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) { + /* SPI lock down configuration */ + fast_spi_lockdown_bios(CHIPSET_LOCKDOWN_COREBOOT); + + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(CHIPSET_LOCKDOWN_COREBOOT); + } + if (CONFIG(SPI_FLASH_SMM)) /* Re-init SPI driver to handle locked BAR */ fast_spi_init(); diff --git a/src/soc/intel/common/pch/include/intelpch/lockdown.h b/src/soc/intel/common/pch/include/intelpch/lockdown.h index b5aba06fe0e..1b96f41a2a4 100644 --- a/src/soc/intel/common/pch/include/intelpch/lockdown.h +++ b/src/soc/intel/common/pch/include/intelpch/lockdown.h @@ -22,4 +22,7 @@ int get_lockdown_config(void); */ void soc_lockdown_config(int chipset_lockdown); +void fast_spi_lockdown_bios(int chipset_lockdown); +void lpc_lockdown_config(int chipset_lockdown); + #endif /* SOC_INTEL_COMMON_PCH_LOCKDOWN_H */ diff --git a/src/soc/intel/common/pch/lockdown/Kconfig b/src/soc/intel/common/pch/lockdown/Kconfig index 38f60d20569..545185c52f2 100644 --- a/src/soc/intel/common/pch/lockdown/Kconfig +++ b/src/soc/intel/common/pch/lockdown/Kconfig @@ -3,7 +3,22 @@ config SOC_INTEL_COMMON_PCH_LOCKDOWN bool default n + select HAVE_INTEL_CHIPSET_LOCKDOWN help This option allows to have chipset lockdown for DMI, FAST_SPI and soc_lockdown_config() to implement any additional lockdown as PMC, LPC for supported PCH. + +config SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM + bool "Lock down SPI controller in SMM" + default n + depends on HAVE_SMI_HANDLER && !INTEL_CHIPSET_LOCKDOWN + select SPI_FLASH_SMM + help + This option allows to have chipset lockdown for FAST_SPI and LPC for + supported PCH. If selected, coreboot will skip locking down the SPI + and LPC controller. The payload or OS is responsible for locking it + using APM_CNT_FINALIZE SMI. Used by heads to set and lock PR0 flash + protection. + + If unsure, say N. diff --git a/src/soc/intel/common/pch/lockdown/Makefile.mk b/src/soc/intel/common/pch/lockdown/Makefile.mk index 71466f8edd1..64aad562acf 100644 --- a/src/soc/intel/common/pch/lockdown/Makefile.mk +++ b/src/soc/intel/common/pch/lockdown/Makefile.mk @@ -1,2 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_lpc.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_spi.c + +smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_lpc.c +smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_spi.c diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c index 1b1d99cc0c9..2d229e1a90a 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include #include #include #include @@ -61,56 +60,17 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) /* Set FAST_SPI opcode menu */ fast_spi_set_opcode_menu(); - /* Discrete Lock Flash PR registers */ - fast_spi_pr_dlock(); - /* Check if SPI transaction is pending */ fast_spi_cycle_in_progress(); /* Clear any outstanding status bits like AEL, FCERR, FDONE, SAF etc. */ fast_spi_clear_outstanding_status(); - /* Lock FAST_SPIBAR */ - fast_spi_lock_bar(); - /* Set Vendor Component Lock (VCL) */ fast_spi_vscc0_lock(); - /* Set BIOS Interface Lock, BIOS Lock */ - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { - /* BIOS Interface Lock */ - fast_spi_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { - fast_spi_set_eiss(); - fast_spi_enable_wp(); - } - - /* BIOS Lock */ - fast_spi_set_lock_enable(); - - /* EXT BIOS Lock */ - fast_spi_set_ext_bios_lock_enable(); - } -} - -static void lpc_lockdown_config(int chipset_lockdown) -{ - /* Set BIOS Interface Lock, BIOS Lock */ - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { - /* BIOS Interface Lock */ - lpc_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { - lpc_set_eiss(); - lpc_enable_wp(); - } - - /* BIOS Lock */ - lpc_set_lock_enable(); - } + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + fast_spi_lockdown_bios(chipset_lockdown); } static void sa_lockdown_config(int chipset_lockdown) @@ -136,8 +96,9 @@ static void platform_lockdown_config(void *unused) /* SPI lock down configuration */ fast_spi_lockdown_cfg(chipset_lockdown); - /* LPC/eSPI lock down configuration */ - lpc_lockdown_config(chipset_lockdown); + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(chipset_lockdown); /* GPMR lock down configuration */ gpmr_lockdown_cfg(); diff --git a/src/soc/intel/common/pch/lockdown/lockdown_lpc.c b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c new file mode 100644 index 00000000000..79a27d520f3 --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void lpc_lockdown_config(int chipset_lockdown) +{ + /* Set BIOS Interface Lock, BIOS Lock */ + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { + /* BIOS Interface Lock */ + lpc_set_bios_interface_lock_down(); + + /* Only allow writes in SMM */ + if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { + lpc_set_eiss(); + lpc_enable_wp(); + } + + /* BIOS Lock */ + lpc_set_lock_enable(); + } +} diff --git a/src/soc/intel/common/pch/lockdown/lockdown_spi.c b/src/soc/intel/common/pch/lockdown/lockdown_spi.c new file mode 100644 index 00000000000..0815a370bf0 --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_spi.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void fast_spi_lockdown_bios(int chipset_lockdown) +{ + /* Discrete Lock Flash PR registers */ + fast_spi_pr_dlock(); + + /* Lock FAST_SPIBAR */ + fast_spi_lock_bar(); + + /* Set BIOS Interface Lock, BIOS Lock */ + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { + /* BIOS Interface Lock */ + fast_spi_set_bios_interface_lock_down(); + + /* Only allow writes in SMM */ + if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { + fast_spi_set_eiss(); + fast_spi_enable_wp(); + } + + /* BIOS Lock */ + fast_spi_set_lock_enable(); + + /* EXT BIOS Lock */ + fast_spi_set_ext_bios_lock_enable(); + } +} diff --git a/src/soc/intel/denverton_ns/lpc.c b/src/soc/intel/denverton_ns/lpc.c index ae923d7c0ed..b04e928bfa8 100644 --- a/src/soc/intel/denverton_ns/lpc.c +++ b/src/soc/intel/denverton_ns/lpc.c @@ -536,7 +536,8 @@ static const struct pci_driver lpc_driver __pci_driver = { static void finalize_chipset(void *unused) { - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); } BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL); diff --git a/src/soc/intel/elkhartlake/finalize.c b/src/soc/intel/elkhartlake/finalize.c index 712a6c037f5..3fcc29e2a13 100644 --- a/src/soc/intel/elkhartlake/finalize.c +++ b/src/soc/intel/elkhartlake/finalize.c @@ -51,7 +51,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) heci_finalize(); diff --git a/src/soc/intel/jasperlake/finalize.c b/src/soc/intel/jasperlake/finalize.c index 6cff7a80f30..1b68cc51786 100644 --- a/src/soc/intel/jasperlake/finalize.c +++ b/src/soc/intel/jasperlake/finalize.c @@ -75,7 +75,8 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); /* Indicate finalize step with post code */ post_code(POSTCODE_OS_BOOT); diff --git a/src/soc/intel/meteorlake/finalize.c b/src/soc/intel/meteorlake/finalize.c index 38e3c7d3f9f..0118f5d79aa 100644 --- a/src/soc/intel/meteorlake/finalize.c +++ b/src/soc/intel/meteorlake/finalize.c @@ -83,7 +83,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); sa_finalize(); if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && diff --git a/src/soc/intel/pantherlake/finalize.c b/src/soc/intel/pantherlake/finalize.c new file mode 100644 index 00000000000..1d47dd7a0b6 --- /dev/null +++ b/src/soc/intel/pantherlake/finalize.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void pch_finalize(void) +{ + /* TCO Lock down */ + tco_lockdown(); + + pmc_clear_pmcon_sts(); +} + +static void tbt_finalize(void) +{ + int i; + const struct device *dev; + + /* Disable Thunderbolt PCIe root ports bus master */ + for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { + dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); + if (dev) + pci_dev_disable_bus_master(dev); + } +} + +static void sa_finalize(void) +{ + if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) + sa_lock_pam(); +} + +static void heci_finalize(void) +{ + heci_set_to_d0i3(); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) + heci1_disable(); +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + + tbt_finalize(); + sa_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && + CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) + heci_finalize(); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); +/* + * The purpose of this change is to accommodate more time to push out sending + * CSE EOP messages at post. + */ +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index fd80aeac1a0..a147b62e46f 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -106,7 +106,8 @@ static void soc_finalize(void *unused) pch_finalize_script(dev); soc_lockdown(dev); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); /* Indicate finalize step with post code */ post_code(POSTCODE_OS_BOOT); diff --git a/src/soc/intel/tigerlake/finalize.c b/src/soc/intel/tigerlake/finalize.c index cd02745a9e6..158b2fb6916 100644 --- a/src/soc/intel/tigerlake/finalize.c +++ b/src/soc/intel/tigerlake/finalize.c @@ -55,7 +55,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) heci1_disable(); diff --git a/src/soc/intel/xeon_sp/finalize.c b/src/soc/intel/xeon_sp/finalize.c index af630fe8127..16799fe38e2 100644 --- a/src/soc/intel/xeon_sp/finalize.c +++ b/src/soc/intel/xeon_sp/finalize.c @@ -59,7 +59,9 @@ static void soc_finalize(void *unused) if (!CONFIG(USE_PM_ACPI_TIMER)) setbits8(pmc_mmio_regs() + PCH_PWRM_ACPI_TMR_CTL, ACPI_TIM_DIS); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + lock_pam0123(); if (CONFIG_MAX_SOCKET > 1) { diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c index a3d17b46c33..51a5cf54317 100644 --- a/src/soc/intel/xeon_sp/lockdown.c +++ b/src/soc/intel/xeon_sp/lockdown.c @@ -6,25 +6,15 @@ #include #include -static void lpc_lockdown_config(void) -{ - /* Set BIOS Interface Lock, BIOS Lock */ - lpc_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { - lpc_set_eiss(); - lpc_enable_wp(); - } - lpc_set_lock_enable(); -} - void soc_lockdown_config(int chipset_lockdown) { if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) return; - lpc_lockdown_config(); + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(chipset_lockdown); + pmc_lockdown_config(); sata_lockdown_config(chipset_lockdown); spi_lockdown_config(chipset_lockdown); From 092267f37dfc9d8fbd6b4cfbea25c6ef56602fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Tue, 10 Dec 2024 14:52:19 +0100 Subject: [PATCH 04/15] soc/intel/mtl/fsp_params.c: wire up sleep mode option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/soc/intel/meteorlake/fsp_params.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index 138643a63e9..41534e29c2c 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -436,7 +436,7 @@ static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg, /* D3Hot and D3Cold for TCSS */ s_cfg->D3HotEnable = !config->tcss_d3_hot_disable; - s_cfg->D3ColdEnable = CONFIG(D3COLD_SUPPORT); + s_cfg->D3ColdEnable = get_sleep_type_option() == SLEEP_TYPE_OPTION_S0IX; s_cfg->UsbTcPortEn = 0; for (int i = 0; i < MAX_TYPE_C_PORTS; i++) { From 9f5143b0f952b74d3ee09ec26d86e02fecc0645b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Tue, 10 Dec 2024 14:51:41 +0100 Subject: [PATCH 05/15] clevo/mtl-h/ramstage.c: implement sleep mode option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/mainboard/clevo/mtl-h/ramstage.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mainboard/clevo/mtl-h/ramstage.c b/src/mainboard/clevo/mtl-h/ramstage.c index dfdf257f041..ba237f60e67 100644 --- a/src/mainboard/clevo/mtl-h/ramstage.c +++ b/src/mainboard/clevo/mtl-h/ramstage.c @@ -201,6 +201,14 @@ static void mainboard_enable(struct device *dev) #endif } +void mainboard_update_soc_chip_config(struct soc_intel_meteorlake_config *config) +{ + if (get_sleep_type_option() == SLEEP_TYPE_OPTION_S3) + config->s0ix_enable = 0; + else + config->s0ix_enable = 1; +} + struct chip_operations mainboard_ops = { .enable_dev = mainboard_enable, .init = mainboard_init, From 8d960e94b73d5cc3a2aee49b0a0742f0ef23a9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Wed, 18 Dec 2024 13:28:32 +0100 Subject: [PATCH 06/15] soc/intel/cmn/blk/cse/cse.c: skip me_enable while ME is in Debug mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/soc/intel/common/block/cse/cse.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 877b99c141e..053ad362b8f 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1437,6 +1437,16 @@ static void cse_set_state(struct device *dev) printk(BIOS_DEBUG, "CMOS: me_state = %u\n", cmos_me_state); + /* + * Skip action while ME is in debug (HAP) mode, as HECI will not work + * in this state + */ + + if (cse_is_hfs1_com_debug()) { + printk(BIOS_DEBUG, "ME is in HAP mode, skipping soft temp disable"); + return; + } + /* * We only take action if the me_state doesn't match the CS(ME) working state */ From 3138e53472b1bf9dd6d2edb215c6d0aca2954d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Thu, 19 Dec 2024 13:08:38 +0100 Subject: [PATCH 07/15] Makefile.mk: Always pull FSP submodule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- Makefile.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index 212cb6116f0..d23029b2d86 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -227,9 +227,7 @@ ifeq ($(CONFIG_USE_BLOBS),y) # until expressly requested and enabled with --checkout forgetthis:=$(shell git submodule update --init --checkout 3rdparty/blobs $(quiet_errors)) forgetthis:=$(shell git submodule update --init --checkout 3rdparty/intel-microcode $(quiet_errors)) -ifeq ($(CONFIG_FSP_USE_REPO),y) forgetthis:=$(shell git submodule update --init --checkout 3rdparty/fsp $(quiet_errors)) -endif ifeq ($(CONFIG_USE_AMD_BLOBS),y) forgetthis:=$(shell git submodule update --init --checkout 3rdparty/amd_blobs $(quiet_errors)) endif From b890d38d0f14946e5f9c26631b6c64ac58e7d2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Wed, 8 Jan 2025 20:04:21 +0100 Subject: [PATCH 08/15] soc/intel/cmn/blk/graphics: ensure framebuffer is allocated <4G MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/soc/intel/common/block/graphics/graphics.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/soc/intel/common/block/graphics/graphics.c b/src/soc/intel/common/block/graphics/graphics.c index 7ee0c69792a..43b426817f0 100644 --- a/src/soc/intel/common/block/graphics/graphics.c +++ b/src/soc/intel/common/block/graphics/graphics.c @@ -278,6 +278,13 @@ static void graphics_dev_read_resources(struct device *dev) pci_dev_set_resources(dev); res_bar0->flags |= IORESOURCE_FIXED; } + + if (ENV_X86_32) { + /* Place framebuffer below 4G to ensure coreboot can access it */ + struct resource *res_bar2 = find_resource(dev, PCI_BASE_ADDRESS_2); + res_bar2->limit = 0xffffffff; + res_bar2->flags &= ~IORESOURCE_ABOVE_4G; + } } static void graphics_join_mbus(void) From c4edf103987af0fdaa8ea101ff7ca35a8454335a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Wed, 8 Jan 2025 20:04:52 +0100 Subject: [PATCH 09/15] soc/intel/cmn/blk/i2c: ensure resources are allocated <4G MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/soc/intel/common/block/i2c/i2c.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index c0f0b6e0bab..49bc7323843 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -134,6 +134,19 @@ uintptr_t dw_i2c_base_address(unsigned int bus) return (uintptr_t)ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16); } +static void dw_i2c_read_resources(struct device *dev) +{ + /* Read standard PCI resources. */ + pci_dev_read_resources(dev); + + if (ENV_X86_32) { + /* Put resource below 4G to ensure coreboot can access it */ + struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); + res->limit = 0xffffffff; + res->flags &= ~IORESOURCE_ABOVE_4G; + } +} + /* * This function ensures that the device is actually out of reset and * its ready for initialization sequence. @@ -161,7 +174,7 @@ static void dw_i2c_device_init(struct device *dev) } struct device_operations i2c_dev_ops = { - .read_resources = pci_dev_read_resources, + .read_resources = dw_i2c_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .scan_bus = scan_static_bus, From 5a313c76af2bc5e53e5c29d8c245b04f048ae776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Thu, 16 Jan 2025 11:54:11 +0100 Subject: [PATCH 10/15] soc/intel/cmn/blk/cse/cse.c: ensure resources are allocated <4G MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch, if RESOURCE_ALLOCATION_TOP_DOWN is enabled and coreboot is compiled for IA32, the HECI device becomes inaccessible after resource allocation. Signed-off-by: Michał Kopeć --- src/soc/intel/common/block/cse/cse.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 053ad362b8f..214e47beeac 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1599,9 +1599,24 @@ static void cse_final(struct device *dev) cse_final_end_of_firmware(); } +#if ENV_RAMSTAGE +static void heci_read_resources(struct device *dev) +{ + /* Read standard PCI resources. */ + pci_dev_read_resources(dev); + + if (ENV_X86_32) { + /* Put resource below 4G to ensure coreboot can access it */ + struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); + res->limit = 0xffffffff; + res->flags &= ~IORESOURCE_ABOVE_4G; + } +} +#endif + struct device_operations cse_ops = { .set_resources = pci_dev_set_resources, - .read_resources = pci_dev_read_resources, + .read_resources = heci_read_resources, .enable_resources = pci_dev_enable_resources, .init = pci_dev_init, .ops_pci = &pci_dev_ops_pci, From 40e8d1a9b99deec2cc6264ffead5f350bf63c317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Thu, 9 Jan 2025 16:53:22 +0100 Subject: [PATCH 11/15] mb/clevo/mtl-h: Set MMIO size to 2.5GB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- src/mainboard/clevo/mtl-h/romstage.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/clevo/mtl-h/romstage.c b/src/mainboard/clevo/mtl-h/romstage.c index 5f6d3b5cfdb..c4870fb52b2 100644 --- a/src/mainboard/clevo/mtl-h/romstage.c +++ b/src/mainboard/clevo/mtl-h/romstage.c @@ -49,5 +49,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) mupd->FspmConfig.DcLoadline[1] = 310; mupd->FspmConfig.DcLoadline[2] = 490; + mupd->FspmConfig.MmioSize = 2560; + memcfg_init(mupd, &mem_config, &dimm_module_spd_info, half_populated); } From d047598fdf4e9ce66ed26225d03ea9abf957f1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Fri, 10 Jan 2025 14:11:40 +0100 Subject: [PATCH 12/15] soc/intel/mtl: move IOE P2SB BAR below 4G MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This frees up two MTRRs for SPI flash caching IOM_BASE_ADDR has to be hardcoded, otherwise iasl throws an error while building ``` dsdt.asl 1374: 0x1600,,,) Error 6050 - ^ Length is not equal to fixed Min/Max window ``` It seems like IASL can't perform arithmetic operations inside QWordMemory definitions. See https://review.coreboot.org/c/coreboot/+/84216 Signed-off-by: Michał Kopeć --- src/soc/intel/meteorlake/Kconfig | 2 +- src/soc/intel/meteorlake/include/soc/iomap.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 49bee491e44..519b5a1bcb1 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -255,7 +255,7 @@ config PCR_BASE_ADDRESS config IOE_PCR_BASE_ADDRESS hex - default 0x3fff0000000 + default 0x60000000 help This option allows you to select MMIO Base Address of IOE sideband bus. diff --git a/src/soc/intel/meteorlake/include/soc/iomap.h b/src/soc/intel/meteorlake/include/soc/iomap.h index 742af482e37..03ef56d3d81 100644 --- a/src/soc/intel/meteorlake/include/soc/iomap.h +++ b/src/soc/intel/meteorlake/include/soc/iomap.h @@ -66,9 +66,10 @@ #define IOE_P2SB_BAR IOE_PCR_ABOVE_4G_BASE_ADDR #define IOE_P2SB_SIZE (256 * MiB) -#define IOM_BASE_ADDR 0x3fff0aa0000 +/* IOE_P2SB_BAR + 0xaa0000, but iasl refuses to perform arithmetics */ +#define IOM_BASE_ADDR 0x60aa0000 #define IOM_BASE_SIZE 0x1600 -#define IOM_BASE_ADDR_MAX 0x3fff0aa15ff +#define IOM_BASE_ADDR_MAX 0x60aa15ff /* * I/O port address space From 21058cb21a5b4792771f04937674e7874bf86be8 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Tue, 13 Aug 2024 22:29:21 +1000 Subject: [PATCH 13/15] lib/jpeg: avoid calling malloc and free Since commit 1d029b40c9de ("lib/jpeg: Replace decoder with Wuffs' implementation"), a relatively large heap allocation is needed to decode many JPEGs for use as work area. The prior decoder did not need this, but also had many limitations in the JPEGs it could decode, was not as memory-safe and quickly crashed under fuzzing. This commit keeps using Wuffs' JPEG decoder, but it no longer requires any heap allocation (and thus configuring the heap size depending on how big a bootsplash image you want to support). Change-Id: Ie4c52520cbce498539517c4898ff765365a6beba Signed-off-by: Nigel Tao Reviewed-on: https://review.coreboot.org/c/coreboot/+/83895 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Felix Singer Reviewed-by: Jonathon Hall --- src/lib/jpeg.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/lib/jpeg.c b/src/lib/jpeg.c index 242cf0ca8ee..617ab0b22aa 100644 --- a/src/lib/jpeg.c +++ b/src/lib/jpeg.c @@ -1,9 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Provide a simple API around the Wuffs JPEG decoder - * Uses the heap (and lots of it) for the image-size specific - * work buffer, so ramstage-only. + * Provide a simple API around the Wuffs JPEG decoder. */ #include @@ -85,6 +83,24 @@ int jpeg_decode(unsigned char *filedata, size_t filesize, unsigned char *pic, return JPEG_DECODE_FAILED; } + /* Opting in to lower quality means that we can pass an empty slice as the + * "work buffer" argument to wuffs_jpeg__decoder__decode_frame below. + * + * Decoding progressive (not sequential) JPEGs would still require dynamic + * memory allocation (and the amount of work buffer required depends on the + * image dimensions), but we choose to just reject progressive JPEGs. It is + * simpler than sometimes calling malloc (which can fail, especially for + * large allocations) and free. + * + * More commentary about these quirks is at + * https://github.com/google/wuffs/blob/beaf45650085a16780b5f708b72daaeb1aa865c8/std/jpeg/decode_quirks.wuffs + */ + wuffs_jpeg__decoder__set_quirk( + &dec, WUFFS_BASE__QUIRK_QUALITY, + WUFFS_BASE__QUIRK_QUALITY__VALUE__LOWER_QUALITY); + wuffs_jpeg__decoder__set_quirk( + &dec, WUFFS_JPEG__QUIRK_REJECT_PROGRESSIVE_JPEGS, 1); + wuffs_base__image_config imgcfg; wuffs_base__io_buffer src = wuffs_base__ptr_u8__reader(filedata, filesize, true); status = wuffs_jpeg__decoder__decode_image_config(&dec, &imgcfg, &src); @@ -104,19 +120,9 @@ int jpeg_decode(unsigned char *filedata, size_t filesize, unsigned char *pic, return JPEG_DECODE_FAILED; } - uint64_t workbuf_len_min_incl = wuffs_jpeg__decoder__workbuf_len(&dec).min_incl; - uint8_t *workbuf_array = malloc(workbuf_len_min_incl); - if ((workbuf_array == NULL) && workbuf_len_min_incl) { - return JPEG_DECODE_FAILED; - } - - wuffs_base__slice_u8 workbuf = - wuffs_base__make_slice_u8(workbuf_array, workbuf_len_min_incl); status = wuffs_jpeg__decoder__decode_frame(&dec, &pixbuf, &src, - WUFFS_BASE__PIXEL_BLEND__SRC, workbuf, NULL); - - free(workbuf_array); - + WUFFS_BASE__PIXEL_BLEND__SRC, + wuffs_base__empty_slice_u8(), NULL); if (status.repr) { return JPEG_DECODE_FAILED; } From d8b2452924913c9db0d0f1cb3b45484504f0866b Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Tue, 13 Aug 2024 22:10:52 +1000 Subject: [PATCH 14/15] vc/wuffs: upgrade to Wuffs 0.4.0-alpha.8 We were previously at Wuffs 0.4.0-alpha.2. The C file was copied from https://github.com/google/wuffs-mirror-release-c and its hash matches https://github.com/google/wuffs-mirror-release-c/blob/90e4d81a6a8b7b601e8e568da32a105d7f7705e5/sync.txt#L9-L10 $ sha256sum src/vendorcode/wuffs/wuffs-v0.4.c 6c22caff4af929112601379a73f72461bc4719a5215366bcc90d599cbc442bb6 src/vendorcode/wuffs/wuffs-v0.4.c Change-Id: Ie90d989384e0db2b23d7d1b3d9a57920ac8a95a2 Signed-off-by: Nigel Tao Reviewed-on: https://review.coreboot.org/c/coreboot/+/83894 Reviewed-by: Felix Singer Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/vendorcode/wuffs/wuffs-v0.4.c | 101194 ++++++++++++++++----------- 1 file changed, 58878 insertions(+), 42316 deletions(-) diff --git a/src/vendorcode/wuffs/wuffs-v0.4.c b/src/vendorcode/wuffs/wuffs-v0.4.c index bce9eb97980..0c6616a652b 100644 --- a/src/vendorcode/wuffs/wuffs-v0.4.c +++ b/src/vendorcode/wuffs/wuffs-v0.4.c @@ -81,15 +81,43 @@ extern "C" { // each major.minor branch, the commit count should increase monotonically. // // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision -// ae8531f7f846fbbe3a7340bf88499ad294a1367b committed on 2023-10-07. +// 5d69840f8e7ca481551b02c7e8d4c5fb69521bb9 committed on 2024-08-12. #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.2" -#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3603 -#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20231007 -#define WUFFS_VERSION_STRING "0.4.0-alpha.2+3603.20231007" +#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.8" +#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3796 +#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20240812 +#define WUFFS_VERSION_STRING "0.4.0-alpha.8+3796.20240812" + +// ---------------- Private Implementation Macros Re-definition Check + +// Users (those who #include the "wuffs-vM.N.c" file) should not define any +// WUFFS_PRIVATE_IMPL__ETC macros, only WUFFS_CONFIG__ETC macros (and +// WUFFS_IMPLEMENTATION). Mucking about with the private implementation macros +// is not supported and may break when upgrading to newer Wuffs versions. + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) || \ + defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) || \ + defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) || \ + defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) || \ + defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) || \ + defined(WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) || \ + defined(WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) || \ + defined(WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) || \ + defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U16) || \ + defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32) || \ + defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64) || \ + defined(WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U8) + +#if defined(__GNUC__) || defined(__clang__) +#warning "Defining WUFFS_PRIVATE_IMPL__ETC yourself is not supported" +#elif defined(_MSC_VER) +#pragma message("Defining WUFFS_PRIVATE_IMPL__ETC yourself is not supported") +#endif + +#endif // ---------------- Configuration @@ -117,11 +145,11 @@ extern "C" { // intrinsics. Look for __ARM_FEATURE_CRC32 instead. #if defined(__ARM_FEATURE_CRC32) #include -#define WUFFS_BASE__CPU_ARCH__ARM_CRC32 +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32 #endif // defined(__ARM_FEATURE_CRC32) #if defined(__ARM_NEON) #include -#define WUFFS_BASE__CPU_ARCH__ARM_NEON +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON #endif // defined(__ARM_NEON) #endif // defined(__ARM_FEATURE_UNALIGNED) etc @@ -129,26 +157,82 @@ extern "C" { // POPCNT. This is checked at runtime via cpuid, not at compile time. // // Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2. -#if defined(__i386__) || defined(__x86_64__) +// +// ---- +// +// Technically, we could use the SSE family on 32-bit x86, not just 64-bit x86. +// But some intrinsics don't compile in 32-bit mode. It's not worth the hassle. +// https://github.com/google/wuffs/issues/145 +#if defined(__x86_64__) #if !defined(__native_client__) #include #include -// X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously). -#define WUFFS_BASE__CPU_ARCH__X86_FAMILY -#if defined(__x86_64__) -#define WUFFS_BASE__CPU_ARCH__X86_64 -#endif // defined(__x86_64__) +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64 +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2 +#define WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3 #endif // !defined(__native_client__) -#endif // defined(__i386__) || defined(__x86_64__) +#endif // defined(__x86_64__) #elif defined(_MSC_VER) // (#if-chain ref AVOID_CPU_ARCH_1) -#if defined(_M_IX86) || defined(_M_X64) -#if defined(__AVX__) || defined(__clang__) +#if defined(_M_X64) + +// 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 +#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 -// We need for the __cpuid function. #include -// That's not enough for X64 SIMD, with clang-cl, if we want to use +// intrin.h isn't enough for X64 SIMD, with clang-cl, if we want to use // "__attribute__((target(arg)))" without e.g. "/arch:AVX". // // Some web pages suggest that is all you need, as it pulls in @@ -157,25 +241,9 @@ extern "C" { #include // AVX, AVX2, FMA, POPCNT #include // SSE4.2 #include // AES, PCLMUL -// X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously). -#define WUFFS_BASE__CPU_ARCH__X86_FAMILY -#if defined(_M_X64) -#define WUFFS_BASE__CPU_ARCH__X86_64 -#endif // defined(_M_X64) - -#else // defined(__AVX__) || 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:AVX or -mavx compiler flag), not -// of individual functions (that can be conditionally selected at runtime). -#pragma message("Wuffs with MSVC+IX86/X64 needs /arch:AVX for best performance") - -#endif // defined(__AVX__) || defined(__clang__) -#endif // defined(_M_IX86) || defined(_M_X64) +#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) @@ -198,20 +266,20 @@ extern "C" { static inline bool // wuffs_base__cpu_arch__have_arm_crc32(void) { -#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) return true; #else return false; -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) } static inline bool // wuffs_base__cpu_arch__have_arm_neon(void) { -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) return true; #else return false; -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) } static inline bool // @@ -220,7 +288,7 @@ wuffs_base__cpu_arch__have_x86_avx2(void) { defined(__AVX2__) return true; #else -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) // GCC defines these macros but MSVC does not. // - bit_AVX2 = (1 << 5) const unsigned int avx2_ebx7 = 0x00000020; @@ -258,9 +326,9 @@ wuffs_base__cpu_arch__have_x86_avx2(void) { } } #else -#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler" +#error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler" #endif // defined(__GNUC__); defined(_MSC_VER) -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) return false; #endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) && // defined(__AVX2__) @@ -271,7 +339,7 @@ wuffs_base__cpu_arch__have_x86_bmi2(void) { #if defined(__BMI2__) return true; #else -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) // GCC defines these macros but MSVC does not. // - bit_BMI2 = (1 << 8) const unsigned int bmi2_ebx7 = 0x00000100; @@ -293,9 +361,9 @@ wuffs_base__cpu_arch__have_x86_bmi2(void) { return true; } #else -#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler" +#error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler" #endif // defined(__GNUC__); defined(_MSC_VER) -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) return false; #endif // defined(__BMI2__) } @@ -305,7 +373,7 @@ wuffs_base__cpu_arch__have_x86_sse42(void) { #if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) return true; #else -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) // GCC defines these macros but MSVC does not. // - bit_PCLMUL = (1 << 1) // - bit_POPCNT = (1 << 23) @@ -329,9 +397,9 @@ wuffs_base__cpu_arch__have_x86_sse42(void) { return true; } #else -#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler" +#error "WUFFS_PRIVATE_IMPL__CPU_ARCH__ETC combined with an unsupported compiler" #endif // defined(__GNUC__); defined(_MSC_VER) -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64) return false; #endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) } @@ -350,9 +418,15 @@ wuffs_base__cpu_arch__have_x86_sse42(void) { // The "defined(__clang__)" isn't redundant. While vanilla clang defines // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not. #if defined(__GNUC__) || defined(__clang__) +#define WUFFS_BASE__FORCE_INLINE __attribute__((__always_inline__)) #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused)) #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#elif defined(_MSC_VER) +#define WUFFS_BASE__FORCE_INLINE __forceinline +#define WUFFS_BASE__POTENTIALLY_UNUSED +#define WUFFS_BASE__WARN_UNUSED_RESULT #else +#define WUFFS_BASE__FORCE_INLINE #define WUFFS_BASE__POTENTIALLY_UNUSED #define WUFFS_BASE__WARN_UNUSED_RESULT #endif @@ -415,6 +489,37 @@ struct wuffs_unique_ptr_deleter { // -------- +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +static inline uint8_t* // +wuffs_base__strip_const_from_u8_ptr(const uint8_t* ptr) { + return (uint8_t*)ptr; +} + +static inline uint16_t* // +wuffs_base__strip_const_from_u16_ptr(const uint16_t* ptr) { + return (uint16_t*)ptr; +} + +static inline uint32_t* // +wuffs_base__strip_const_from_u32_ptr(const uint32_t* ptr) { + return (uint32_t*)ptr; +} + +static inline uint64_t* // +wuffs_base__strip_const_from_u64_ptr(const uint64_t* ptr) { + return (uint64_t*)ptr; +} + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +// -------- + // wuffs_base__empty_struct is used when a Wuffs function returns an empty // struct. In C, if a function f returns void, you can't say "x = f()", but in // Wuffs, if a function g returns empty, you can say "y = g()". @@ -483,6 +588,7 @@ extern const char wuffs_base__suspension__even_more_information[]; extern const char wuffs_base__suspension__mispositioned_read[]; extern const char wuffs_base__suspension__mispositioned_write[]; extern const char wuffs_base__suspension__short_read[]; +extern const char wuffs_base__suspension__short_workbuf[]; extern const char wuffs_base__suspension__short_write[]; extern const char wuffs_base__error__bad_i_o_position[]; extern const char wuffs_base__error__bad_argument_length_too_short[]; @@ -496,9 +602,11 @@ extern const char wuffs_base__error__bad_vtable[]; extern const char wuffs_base__error__bad_workbuf_length[]; extern const char wuffs_base__error__bad_wuffs_version[]; extern const char wuffs_base__error__cannot_return_a_suspension[]; +extern const char wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist[]; extern const char wuffs_base__error__disabled_by_previous_error[]; extern const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[]; extern const char wuffs_base__error__initialize_not_called[]; +extern const char wuffs_base__error__insufficient_history[]; extern const char wuffs_base__error__interleaved_coroutine_calls[]; extern const char wuffs_base__error__no_more_information[]; extern const char wuffs_base__error__not_enough_data[]; @@ -728,6 +836,9 @@ typedef struct wuffs_base__transform__output__struct { // Lempel–Ziv 4. #define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420 +// Lzip. +#define WUFFS_BASE__FOURCC__LZIP 0x4C5A4950 + // Lempel–Ziv Markov-chain Algorithm. #define WUFFS_BASE__FOURCC__LZMA 0x4C5A4D41 @@ -839,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 @@ -1092,6 +1205,96 @@ wuffs_base__multiply_u64(uint64_t x, uint64_t y) { // -------- +typedef struct wuffs_base__bitvec256__struct { + // elements_u64[0] holds the LSBs (least significant bits) and + // elements_u64[3] holds the MSBs (most significant bits). + uint64_t elements_u64[4]; +} wuffs_base__bitvec256; + +static inline wuffs_base__bitvec256 // +wuffs_base__make_bitvec256(uint64_t e00, + uint64_t e01, + uint64_t e02, + uint64_t e03) { + wuffs_base__bitvec256 res; + res.elements_u64[0] = e00; + res.elements_u64[1] = e01; + res.elements_u64[2] = e02; + res.elements_u64[3] = e03; + return res; +} + +static inline uint64_t // +wuffs_base__bitvec256__get_u64(const wuffs_base__bitvec256* b, uint32_t i) { + return b->elements_u64[i & 3]; +} + +// -------- + +// wuffs_base__optional_u63 is like a std::optional, but for C (not +// just C++) and the value can only hold 63 bits (not 64). +// +// Do not manipulate repr directly; it is a private implementation detail. +typedef struct wuffs_base__optional_u63__struct { + uint64_t repr; + +#ifdef __cplusplus + inline bool has_value() const; + inline uint64_t value() const; + inline uint64_t value_or(uint64_t default_value) const; +#endif // __cplusplus + +} wuffs_base__optional_u63; + +// wuffs_base__make_optional_u63 ignores value when has_value is false. +// +// Preconditions: +// - value < (1 << 63). +static inline wuffs_base__optional_u63 // +wuffs_base__make_optional_u63(bool has_value, uint64_t value) { + wuffs_base__optional_u63 res; + res.repr = has_value ? ((value << 1u) | 1u) : 0u; + return res; +} + +static inline bool // +wuffs_base__optional_u63__has_value(const wuffs_base__optional_u63* o) { + return o->repr; +} + +// wuffs_base__optional_u63__value returns zero when o does not have a value. +static inline uint64_t // +wuffs_base__optional_u63__value(const wuffs_base__optional_u63* o) { + return o->repr >> 1u; +} + +static inline uint64_t // +wuffs_base__optional_u63__value_or(const wuffs_base__optional_u63* o, + uint64_t default_value) { + return o->repr ? (o->repr >> 1u) : default_value; +} + +#ifdef __cplusplus + +inline bool // +wuffs_base__optional_u63::has_value() const { + return wuffs_base__optional_u63__has_value(this); +} + +inline uint64_t // +wuffs_base__optional_u63::value() const { + return wuffs_base__optional_u63__value(this); +} + +inline uint64_t // +wuffs_base__optional_u63::value_or(uint64_t default_value) const { + return wuffs_base__optional_u63__value_or(this, default_value); +} + +#endif // __cplusplus + +// -------- + // The "defined(__clang__)" isn't redundant. While vanilla clang defines // __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not. #if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8) @@ -1529,7 +1732,7 @@ wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) { static inline wuffs_base__slice_u8 // wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) { wuffs_base__slice_u8 ret; - ret.ptr = ptr + i; + ret.ptr = ptr ? (ptr + i) : NULL; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1537,7 +1740,7 @@ wuffs_base__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) { static inline wuffs_base__slice_u16 // wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) { wuffs_base__slice_u16 ret; - ret.ptr = ptr + i; + ret.ptr = ptr ? (ptr + i) : NULL; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1545,7 +1748,7 @@ wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) { static inline wuffs_base__slice_u32 // wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) { wuffs_base__slice_u32 ret; - ret.ptr = ptr + i; + ret.ptr = ptr ? (ptr + i) : NULL; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1553,7 +1756,7 @@ wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) { static inline wuffs_base__slice_u64 // wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) { wuffs_base__slice_u64 ret; - ret.ptr = ptr + i; + ret.ptr = ptr ? (ptr + i) : NULL; ret.len = (j >= i) ? (j - i) : 0; return ret; } @@ -1696,7 +1899,7 @@ wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) { if ((i <= SIZE_MAX) && (i <= s.len)) { return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(s.len - i))); } - return wuffs_base__make_slice_u8(NULL, 0); + return wuffs_base__empty_slice_u8(); } // wuffs_base__slice_u8__subslice_j returns s[:j]. @@ -1707,7 +1910,7 @@ wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) { if ((j <= SIZE_MAX) && (j <= s.len)) { return wuffs_base__make_slice_u8(s.ptr, ((size_t)j)); } - return wuffs_base__make_slice_u8(NULL, 0); + return wuffs_base__empty_slice_u8(); } // wuffs_base__slice_u8__subslice_ij returns s[i:j]. @@ -1720,7 +1923,7 @@ wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s, if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) { return wuffs_base__make_slice_u8(s.ptr + i, ((size_t)(j - i))); } - return wuffs_base__make_slice_u8(NULL, 0); + return wuffs_base__empty_slice_u8(); } // wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy]. @@ -1814,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 @@ -3011,7 +3228,8 @@ wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) { // wuffs_base__io_buffer__compact_retaining moves any written but unread bytes // closer to the start of the buffer. It retains H bytes of history (the most // recently read bytes), where H is min(buf->meta.ri, history_retain_length). -// A postcondition is that buf->meta.ri == H. +// It is therefore a no-op if history_retain_length is UINT64_MAX. A +// postcondition is that buf->meta.ri == H. // // wuffs_base__io_buffer__compact_retaining(0) is equivalent to // wuffs_base__io_buffer__compact(). @@ -3056,7 +3274,7 @@ wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) { static inline uint8_t* // wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) { - return buf ? (buf->data.ptr + buf->meta.ri) : NULL; + return (buf && buf->data.ptr) ? (buf->data.ptr + buf->meta.ri) : NULL; } static inline uint64_t // @@ -3066,7 +3284,8 @@ wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) { static inline wuffs_base__slice_u8 // wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) { - return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri, + return (buf && buf->data.ptr) + ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri, buf->meta.wi - buf->meta.ri) : wuffs_base__empty_slice_u8(); } @@ -3078,7 +3297,7 @@ wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) { static inline uint8_t* // wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) { - return buf ? (buf->data.ptr + buf->meta.wi) : NULL; + return (buf && buf->data.ptr) ? (buf->data.ptr + buf->meta.wi) : NULL; } static inline uint64_t // @@ -3088,7 +3307,8 @@ wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) { static inline wuffs_base__slice_u8 // wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) { - return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi, + return (buf && buf->data.ptr) + ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi, buf->data.len - buf->meta.wi) : wuffs_base__empty_slice_u8(); } @@ -3183,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 // -------- @@ -3245,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) @@ -3264,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 // -------- @@ -3292,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 @@ -3305,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 // -------- @@ -3421,6 +3649,22 @@ wuffs_base__token::length() const { // -------- +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +static inline wuffs_base__token* // +wuffs_base__strip_const_from_token_ptr(const wuffs_base__token* ptr) { + return (wuffs_base__token*)ptr; +} + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +// -------- + typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token; static inline wuffs_base__slice_token // @@ -3574,7 +3818,8 @@ wuffs_base__token_buffer__compact(wuffs_base__token_buffer* buf) { // wuffs_base__token_buffer__compact_retaining moves any written but unread // tokens closer to the start of the buffer. It retains H tokens of history // (the most recently read tokens), where H is min(buf->meta.ri, -// history_retain_length). A postcondition is that buf->meta.ri == H. +// history_retain_length). It is therefore a no-op if history_retain_length is +// UINT64_MAX. A postcondition is that buf->meta.ri == H. // // wuffs_base__token_buffer__compact_retaining(0) is equivalent to // wuffs_base__token_buffer__compact(). @@ -3730,51 +3975,51 @@ wuffs_base__token_buffer::writer_token_position() const { // // You can pass the C stdlib's malloc as the malloc_func. // -// It returns an empty slice (containing a NULL ptr field) if (num_uxx * -// sizeof(uintxx_t)) would overflow SIZE_MAX. +// It returns an empty slice (containing a NULL ptr field) if num_uxx is zero +// or if (num_uxx * sizeof(uintxx_t)) would overflow SIZE_MAX. static inline wuffs_base__slice_u8 // wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) { - if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) { + if (malloc_func && num_u8 && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) { void* p = (*malloc_func)((size_t)(num_u8 * sizeof(uint8_t))); if (p) { return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)num_u8); } } - return wuffs_base__make_slice_u8(NULL, 0); + return wuffs_base__empty_slice_u8(); } static inline wuffs_base__slice_u16 // wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) { - if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) { + if (malloc_func && num_u16 && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) { void* p = (*malloc_func)((size_t)(num_u16 * sizeof(uint16_t))); if (p) { return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)num_u16); } } - return wuffs_base__make_slice_u16(NULL, 0); + return wuffs_base__empty_slice_u16(); } static inline wuffs_base__slice_u32 // wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) { - if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) { + if (malloc_func && num_u32 && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) { void* p = (*malloc_func)((size_t)(num_u32 * sizeof(uint32_t))); if (p) { return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)num_u32); } } - return wuffs_base__make_slice_u32(NULL, 0); + return wuffs_base__empty_slice_u32(); } static inline wuffs_base__slice_u64 // wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) { - if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) { + if (malloc_func && num_u64 && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) { void* p = (*malloc_func)((size_t)(num_u64 * sizeof(uint64_t))); if (p) { return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64); } } - return wuffs_base__make_slice_u64(NULL, 0); + return wuffs_base__empty_slice_u64(); } // ---------------- Images @@ -3838,6 +4083,26 @@ wuffs_base__color_u32_argb_premul__as__color_u8_gray( return (uint8_t)(weighted_average >> 24); } +static inline uint16_t // +wuffs_base__color_u32_argb_premul__as__color_u16_alpha_gray_nonpremul( + wuffs_base__color_u32_argb_premul c) { + uint32_t a = 0xFF & (c >> 24); + if (a == 0) { + return 0; + } + uint32_t a16 = a * 0x101; + + uint32_t cr = 0xFF & (c >> 16); + cr = (cr * (0x101 * 0xFFFF)) / a16; + uint32_t cg = 0xFF & (c >> 8); + cg = (cg * (0x101 * 0xFFFF)) / a16; + uint32_t cb = 0xFF & (c >> 0); + cb = (cb * (0x101 * 0xFFFF)) / a16; + + uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768; + return (uint16_t)((a16 & 0xFF00) | (weighted_average >> 24)); +} + static inline uint16_t // wuffs_base__color_u32_argb_premul__as__color_u16_gray( wuffs_base__color_u32_argb_premul c) { @@ -4114,49 +4379,53 @@ wuffs_base__make_pixel_format(uint32_t repr) { // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid // wuffs_base__pixel_format values are present. -#define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000 +// clang-format off + +#define WUFFS_BASE__PIXEL_FORMAT__INVALID 0x00000000 -#define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008 +#define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008 -#define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008 -#define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B -#define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B -#define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008 -#define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008 +#define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008 +#define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B +#define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B +#define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000088 +#define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000088 -#define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888 -#define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888 -#define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888 +#define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888 +#define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888 +#define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888 -#define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888 -#define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888 -#define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888 +#define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888 +#define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888 +#define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888 -#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008 -#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008 -#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008 +#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008 +#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008 +#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008 -#define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565 -#define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888 -#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888 -#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB -#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888 -#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB -#define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888 -#define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888 +#define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565 +#define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888 +#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888 +#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB +#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888 +#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB +#define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888 +#define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888 -#define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888 -#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888 -#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB -#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888 -#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB -#define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888 -#define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888 +#define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888 +#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888 +#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB +#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888 +#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB +#define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888 +#define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888 -#define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888 -#define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888 +#define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888 +#define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888 -extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16]; +// clang-format on + +extern const uint32_t wuffs_private_impl__pixel_format__bits_per_channel[16]; static inline bool // wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) { @@ -4170,10 +4439,14 @@ wuffs_base__pixel_format__bits_per_pixel(const wuffs_base__pixel_format* f) { if (((f->repr >> 16) & 0x03) != 0) { return 0; } - return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] + - wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] + - wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] + - wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)]; + return wuffs_private_impl__pixel_format__bits_per_channel[0x0F & + (f->repr >> 0)] + + wuffs_private_impl__pixel_format__bits_per_channel[0x0F & + (f->repr >> 4)] + + wuffs_private_impl__pixel_format__bits_per_channel[0x0F & + (f->repr >> 8)] + + wuffs_private_impl__pixel_format__bits_per_channel[0x0F & + (f->repr >> 12)]; } static inline bool // @@ -4391,15 +4664,20 @@ wuffs_base__pixel_config__set(wuffs_base__pixel_config* c, return; } if (pixfmt_repr) { - uint64_t wh = ((uint64_t)width) * ((uint64_t)height); - // TODO: handle things other than 1 byte per pixel. - if (wh <= ((uint64_t)SIZE_MAX)) { + do { +#if SIZE_MAX < 0xFFFFFFFFFFFFFFFFull + uint64_t wh = ((uint64_t)width) * ((uint64_t)height); + // TODO: handle things other than 1 byte per pixel. + if (wh > ((uint64_t)SIZE_MAX)) { + break; + } +#endif c->private_impl.pixfmt.repr = pixfmt_repr; c->private_impl.pixsub.repr = pixsub_repr; c->private_impl.width = width; c->private_impl.height = height; return; - } + } while (0); } c->private_impl.pixfmt.repr = 0; @@ -5117,7 +5395,7 @@ wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) { tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH); } } - return wuffs_base__make_slice_u8(NULL, 0); + return wuffs_base__empty_slice_u8(); } static inline wuffs_base__slice_u8 // @@ -6202,6 +6480,113 @@ struct wuffs_base__hasher_u64__struct { // -------- +extern const char wuffs_base__hasher_bitvec256__vtable_name[]; + +typedef struct wuffs_base__hasher_bitvec256__func_ptrs__struct { + wuffs_base__bitvec256 (*checksum_bitvec256)( + const void* self); + uint64_t (*get_quirk)( + const void* self, + uint32_t a_key); + wuffs_base__status (*set_quirk)( + void* self, + uint32_t a_key, + uint64_t a_value); + wuffs_base__empty_struct (*update)( + void* self, + wuffs_base__slice_u8 a_x); + wuffs_base__bitvec256 (*update_bitvec256)( + void* self, + wuffs_base__slice_u8 a_x); +} wuffs_base__hasher_bitvec256__func_ptrs; + +typedef struct wuffs_base__hasher_bitvec256__struct wuffs_base__hasher_bitvec256; + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_base__hasher_bitvec256__checksum_bitvec256( + const wuffs_base__hasher_bitvec256* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_bitvec256__get_quirk( + const wuffs_base__hasher_bitvec256* self, + uint32_t a_key); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__hasher_bitvec256__set_quirk( + wuffs_base__hasher_bitvec256* self, + uint32_t a_key, + uint64_t a_value); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_base__hasher_bitvec256__update( + wuffs_base__hasher_bitvec256* self, + wuffs_base__slice_u8 a_x); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_base__hasher_bitvec256__update_bitvec256( + wuffs_base__hasher_bitvec256* self, + wuffs_base__slice_u8 a_x); + +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_base__hasher_bitvec256__struct { + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable first_vtable; + } private_impl; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; +#endif + + inline wuffs_base__bitvec256 + checksum_bitvec256() const { + return wuffs_base__hasher_bitvec256__checksum_bitvec256(this); + } + + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_base__hasher_bitvec256__get_quirk( + this, a_key); + } + + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_base__hasher_bitvec256__set_quirk( + this, a_key, a_value); + } + + inline wuffs_base__empty_struct + update( + wuffs_base__slice_u8 a_x) { + return wuffs_base__hasher_bitvec256__update( + this, a_x); + } + + inline wuffs_base__bitvec256 + update_bitvec256( + wuffs_base__slice_u8 a_x) { + return wuffs_base__hasher_bitvec256__update_bitvec256( + this, a_x); + } + +#endif // __cplusplus +}; // struct wuffs_base__hasher_bitvec256__struct + +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +// -------- + extern const char wuffs_base__image_decoder__vtable_name[]; typedef struct wuffs_base__image_decoder__func_ptrs__struct { @@ -6225,8 +6610,6 @@ typedef struct wuffs_base__image_decoder__func_ptrs__struct { uint64_t (*get_quirk)( const void* self, uint32_t a_key); - uint64_t (*history_retain_length)( - const void* self); uint32_t (*num_animation_loops)( const void* self); uint64_t (*num_decoded_frame_configs)( @@ -6291,11 +6674,6 @@ wuffs_base__image_decoder__get_quirk( const wuffs_base__image_decoder* self, uint32_t a_key); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__image_decoder__history_retain_length( - const wuffs_base__image_decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t wuffs_base__image_decoder__num_animation_loops( @@ -6398,11 +6776,6 @@ struct wuffs_base__image_decoder__struct { this, a_key); } - inline uint64_t - history_retain_length() const { - return wuffs_base__image_decoder__history_retain_length(this); - } - inline uint32_t num_animation_loops() const { return wuffs_base__image_decoder__num_animation_loops(this); @@ -6466,11 +6839,11 @@ struct wuffs_base__image_decoder__struct { extern const char wuffs_base__io_transformer__vtable_name[]; typedef struct wuffs_base__io_transformer__func_ptrs__struct { + wuffs_base__optional_u63 (*dst_history_retain_length)( + const void* self); uint64_t (*get_quirk)( const void* self, uint32_t a_key); - uint64_t (*history_retain_length)( - const void* self); wuffs_base__status (*set_quirk)( void* self, uint32_t a_key, @@ -6486,17 +6859,17 @@ typedef struct wuffs_base__io_transformer__func_ptrs__struct { typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_base__io_transformer__dst_history_retain_length( + const wuffs_base__io_transformer* self); + WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t wuffs_base__io_transformer__get_quirk( const wuffs_base__io_transformer* self, uint32_t a_key); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__io_transformer__history_retain_length( - const wuffs_base__io_transformer* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status wuffs_base__io_transformer__set_quirk( @@ -6531,6 +6904,11 @@ struct wuffs_base__io_transformer__struct { using unique_ptr = std::unique_ptr; #endif + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_base__io_transformer__dst_history_retain_length(this); + } + inline uint64_t get_quirk( uint32_t a_key) const { @@ -6538,11 +6916,6 @@ struct wuffs_base__io_transformer__struct { this, a_key); } - inline uint64_t - history_retain_length() const { - return wuffs_base__io_transformer__history_retain_length(this); - } - inline wuffs_base__status set_quirk( uint32_t a_key, @@ -6583,8 +6956,6 @@ typedef struct wuffs_base__token_decoder__func_ptrs__struct { uint64_t (*get_quirk)( const void* self, uint32_t a_key); - uint64_t (*history_retain_length)( - const void* self); wuffs_base__status (*set_quirk)( void* self, uint32_t a_key, @@ -6609,11 +6980,6 @@ wuffs_base__token_decoder__get_quirk( const wuffs_base__token_decoder* self, uint32_t a_key); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__token_decoder__history_retain_length( - const wuffs_base__token_decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status wuffs_base__token_decoder__set_quirk( @@ -6656,11 +7022,6 @@ struct wuffs_base__token_decoder__struct { this, a_key); } - inline uint64_t - history_retain_length() const { - return wuffs_base__token_decoder__history_retain_length(this); - } - inline wuffs_base__status set_quirk( uint32_t a_key, @@ -6918,9 +7279,7 @@ extern const char wuffs_bmp__error__unsupported_bmp_file[]; // ---------------- Public Consts -#define WUFFS_BMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 - -#define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u // ---------------- Struct Declarations @@ -7053,11 +7412,6 @@ wuffs_bmp__decoder__tell_me_more( wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bmp__decoder__history_retain_length( - const wuffs_bmp__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_bmp__decoder__workbuf_len( @@ -7116,14 +7470,14 @@ struct wuffs_bmp__decoder__struct { bool f_rle_padded; wuffs_base__pixel_swizzler f_swizzler; - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; - uint32_t p_tell_me_more[1]; - uint32_t p_read_palette[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_tell_me_more; + uint32_t p_read_palette; } private_impl; struct { @@ -7132,14 +7486,14 @@ struct wuffs_bmp__decoder__struct { struct { uint64_t scratch; - } s_do_decode_image_config[1]; + } s_do_decode_image_config; struct { uint64_t scratch; - } s_do_decode_frame[1]; + } s_do_decode_frame; struct { uint32_t v_i; uint64_t scratch; - } s_read_palette[1]; + } s_read_palette; } private_data; #ifdef __cplusplus @@ -7283,11 +7637,6 @@ struct wuffs_bmp__decoder__struct { return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src); } - inline uint64_t - history_retain_length() const { - return wuffs_bmp__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_bmp__decoder__workbuf_len(this); @@ -7316,9 +7665,9 @@ extern const char wuffs_bzip2__error__unsupported_block_randomization[]; // ---------------- Public Consts -#define WUFFS_BZIP2__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_BZIP2__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#define WUFFS_BZIP2__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_BZIP2__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u // ---------------- Struct Declarations @@ -7386,8 +7735,8 @@ wuffs_bzip2__decoder__set_quirk( uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bzip2__decoder__history_retain_length( +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_bzip2__decoder__dst_history_retain_length( const wuffs_bzip2__decoder* self); WUFFS_BASE__GENERATED_C_CODE @@ -7452,12 +7801,12 @@ struct wuffs_bzip2__decoder__struct { uint32_t f_num_sections; uint32_t f_code_lengths_bitmask; - uint32_t p_transform_io[1]; - uint32_t p_do_transform_io[1]; - uint32_t p_prepare_block[1]; - uint32_t p_read_code_lengths[1]; - uint32_t p_flush_slow[1]; - uint32_t p_decode_huffman_slow[1]; + uint32_t p_transform_io; + uint32_t p_do_transform_io; + uint32_t p_prepare_block; + uint32_t p_read_code_lengths; + uint32_t p_flush_slow; + uint32_t p_decode_huffman_slow; } private_impl; struct { @@ -7474,15 +7823,15 @@ struct wuffs_bzip2__decoder__struct { uint32_t v_i; uint64_t v_tag; uint32_t v_final_checksum_want; - } s_do_transform_io[1]; + } s_do_transform_io; struct { uint32_t v_i; uint32_t v_selector; - } s_prepare_block[1]; + } s_prepare_block; struct { uint32_t v_i; uint32_t v_code_length; - } s_read_code_lengths[1]; + } s_read_code_lengths; struct { uint32_t v_flush_pointer; uint32_t v_flush_repeat_count; @@ -7491,10 +7840,10 @@ struct wuffs_bzip2__decoder__struct { uint32_t v_block_size; uint8_t v_curr; uint64_t scratch; - } s_flush_slow[1]; + } s_flush_slow; struct { uint32_t v_node_index; - } s_decode_huffman_slow[1]; + } s_decode_huffman_slow; } private_data; #ifdef __cplusplus @@ -7572,9 +7921,9 @@ struct wuffs_bzip2__decoder__struct { return wuffs_bzip2__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_bzip2__decoder__history_retain_length(this); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_bzip2__decoder__dst_history_retain_length(this); } inline wuffs_base__range_ii_u64 @@ -7606,25 +7955,23 @@ extern const char wuffs_cbor__error__unsupported_recursion_depth[]; // ---------------- Public Consts -#define WUFFS_CBOR__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -#define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024u -#define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024 +#define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2u -#define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2 +#define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9u -#define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9 +#define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997u -#define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997 +#define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143u -#define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143 +#define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216u -#define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216 +#define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608u -#define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608 - -#define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304 +#define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304u // ---------------- Struct Declarations @@ -7691,11 +8038,6 @@ wuffs_cbor__decoder__set_quirk( uint32_t a_key, uint64_t a_value); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_cbor__decoder__history_retain_length( - const wuffs_cbor__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_cbor__decoder__workbuf_len( @@ -7738,7 +8080,7 @@ struct wuffs_cbor__decoder__struct { bool f_end_of_data; - uint32_t p_decode_tokens[1]; + uint32_t p_decode_tokens; } private_impl; struct { @@ -7750,7 +8092,7 @@ struct wuffs_cbor__decoder__struct { uint32_t v_depth; bool v_tagged; uint8_t v_indefinite_string_major_type; - } s_decode_tokens[1]; + } s_decode_tokens; } private_data; #ifdef __cplusplus @@ -7828,11 +8170,6 @@ struct wuffs_cbor__decoder__struct { return wuffs_cbor__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_cbor__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_cbor__decoder__workbuf_len(this); @@ -8074,6 +8411,227 @@ struct wuffs_crc32__ieee_hasher__struct { #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) || defined(WUFFS_NONMONOLITHIC) + +// ---------------- Status Codes + +// ---------------- Public Consts + +// ---------------- Struct Declarations + +typedef struct wuffs_crc64__ecma_hasher__struct wuffs_crc64__ecma_hasher; + +#ifdef __cplusplus +extern "C" { +#endif + +// ---------------- Public Initializer Prototypes + +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_crc64__ecma_hasher__initialize( + wuffs_crc64__ecma_hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); + +size_t +sizeof__wuffs_crc64__ecma_hasher(void); + +// ---------------- Allocs + +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. + +wuffs_crc64__ecma_hasher* +wuffs_crc64__ecma_hasher__alloc(void); + +static inline wuffs_base__hasher_u64* +wuffs_crc64__ecma_hasher__alloc_as__wuffs_base__hasher_u64(void) { + return (wuffs_base__hasher_u64*)(wuffs_crc64__ecma_hasher__alloc()); +} + +// ---------------- Upcasts + +static inline wuffs_base__hasher_u64* +wuffs_crc64__ecma_hasher__upcast_as__wuffs_base__hasher_u64( + wuffs_crc64__ecma_hasher* p) { + return (wuffs_base__hasher_u64*)p; +} + +// ---------------- Public Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_crc64__ecma_hasher__get_quirk( + const wuffs_crc64__ecma_hasher* self, + uint32_t a_key); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_crc64__ecma_hasher__set_quirk( + wuffs_crc64__ecma_hasher* self, + uint32_t a_key, + uint64_t a_value); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__update( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_crc64__ecma_hasher__update_u64( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_crc64__ecma_hasher__checksum_u64( + const wuffs_crc64__ecma_hasher* self); + +#ifdef __cplusplus +} // extern "C" +#endif + +// ---------------- Struct Definitions + +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C + +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_crc64__ecma_hasher__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. + + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__hasher_u64; + wuffs_base__vtable null_vtable; + + uint64_t f_state; + + wuffs_base__empty_struct (*choosy_up)( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); + } private_impl; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; + + // On failure, the alloc_etc functions return nullptr. They don't throw. + + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_crc64__ecma_hasher__alloc()); + } + + static inline wuffs_base__hasher_u64::unique_ptr + alloc_as__wuffs_base__hasher_u64() { + return wuffs_base__hasher_u64::unique_ptr( + wuffs_crc64__ecma_hasher__alloc_as__wuffs_base__hasher_u64()); + } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_crc64__ecma_hasher__struct() = delete; + wuffs_crc64__ecma_hasher__struct(const wuffs_crc64__ecma_hasher__struct&) = delete; + wuffs_crc64__ecma_hasher__struct& operator=( + const wuffs_crc64__ecma_hasher__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) + + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_crc64__ecma_hasher__initialize( + this, sizeof_star_self, wuffs_version, options); + } + + inline wuffs_base__hasher_u64* + upcast_as__wuffs_base__hasher_u64() { + return (wuffs_base__hasher_u64*)this; + } + + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_crc64__ecma_hasher__get_quirk(this, a_key); + } + + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_crc64__ecma_hasher__set_quirk(this, a_key, a_value); + } + + inline wuffs_base__empty_struct + update( + wuffs_base__slice_u8 a_x) { + return wuffs_crc64__ecma_hasher__update(this, a_x); + } + + inline uint64_t + update_u64( + wuffs_base__slice_u8 a_x) { + return wuffs_crc64__ecma_hasher__update_u64(this, a_x); + } + + inline uint64_t + checksum_u64() const { + return wuffs_crc64__ecma_hasher__checksum_u64(this); + } + +#endif // __cplusplus +}; // struct wuffs_crc64__ecma_hasher__struct + +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) || defined(WUFFS_NONMONOLITHIC) + #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes @@ -8095,9 +8653,9 @@ extern const char wuffs_deflate__error__truncated_input[]; // ---------------- Public Consts -#define WUFFS_DEFLATE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_DEFLATE__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1 +#define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u // ---------------- Struct Declarations @@ -8171,8 +8729,8 @@ wuffs_deflate__decoder__set_quirk( uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_deflate__decoder__history_retain_length( +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_deflate__decoder__dst_history_retain_length( const wuffs_deflate__decoder* self); WUFFS_BASE__GENERATED_C_CODE @@ -8222,16 +8780,16 @@ struct wuffs_deflate__decoder__struct { uint32_t f_n_huffs_bits[2]; bool f_end_of_block; - uint32_t p_transform_io[1]; - uint32_t p_do_transform_io[1]; - uint32_t p_decode_blocks[1]; - uint32_t p_decode_uncompressed[1]; - uint32_t p_init_dynamic_huffman[1]; + uint32_t p_transform_io; + uint32_t p_do_transform_io; + uint32_t p_decode_blocks; + uint32_t p_decode_uncompressed; + uint32_t p_init_dynamic_huffman; wuffs_base__status (*choosy_decode_huffman_fast64)( wuffs_deflate__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src); - uint32_t p_decode_huffman_slow[1]; + uint32_t p_decode_huffman_slow; } private_impl; struct { @@ -8241,11 +8799,11 @@ struct wuffs_deflate__decoder__struct { struct { uint32_t v_final; - } s_decode_blocks[1]; + } s_decode_blocks; struct { uint32_t v_length; uint64_t scratch; - } s_decode_uncompressed[1]; + } s_decode_uncompressed; struct { uint32_t v_bits; uint32_t v_n_bits; @@ -8257,7 +8815,7 @@ struct wuffs_deflate__decoder__struct { uint32_t v_n_extra_bits; uint8_t v_rep_symbol; uint32_t v_rep_count; - } s_init_dynamic_huffman[1]; + } s_init_dynamic_huffman; struct { uint32_t v_bits; uint32_t v_n_bits; @@ -8269,7 +8827,7 @@ struct wuffs_deflate__decoder__struct { uint32_t v_length; uint32_t v_dist_minus_1; uint64_t scratch; - } s_decode_huffman_slow[1]; + } s_decode_huffman_slow; } private_data; #ifdef __cplusplus @@ -8353,9 +8911,9 @@ struct wuffs_deflate__decoder__struct { return wuffs_deflate__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_deflate__decoder__history_retain_length(this); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_deflate__decoder__dst_history_retain_length(this); } inline wuffs_base__range_ii_u64 @@ -8393,23 +8951,21 @@ extern const char wuffs_gif__error__truncated_input[]; // ---------------- Public Consts -#define WUFFS_GIF__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -#define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328u -#define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328 +#define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329u -#define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND 1041635329 +#define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330u -#define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330 +#define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331u -#define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331 +#define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332u -#define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332 +#define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333u -#define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333 - -#define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334 +#define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334u // ---------------- Struct Declarations @@ -8518,11 +9074,6 @@ WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 wuffs_gif__decoder__frame_dirty_rect( const wuffs_gif__decoder* self); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gif__decoder__history_retain_length( - const wuffs_gif__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_gif__decoder__workbuf_len( @@ -8627,25 +9178,25 @@ struct wuffs_gif__decoder__struct { uint32_t f_lzw_read_from_return_value; uint16_t f_lzw_prefixes[4096]; - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_tell_me_more[1]; - uint32_t p_do_tell_me_more[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_skip_frame[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; - uint32_t p_decode_up_to_id_part1[1]; - uint32_t p_decode_header[1]; - uint32_t p_decode_lsd[1]; - uint32_t p_decode_extension[1]; - uint32_t p_skip_blocks[1]; - uint32_t p_decode_ae[1]; - uint32_t p_decode_gc[1]; - uint32_t p_decode_id_part0[1]; - uint32_t p_decode_id_part1[1]; - uint32_t p_decode_id_part2[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_tell_me_more; + uint32_t p_do_tell_me_more; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_skip_frame; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_decode_up_to_id_part1; + uint32_t p_decode_header; + uint32_t p_decode_lsd; + uint32_t p_decode_extension; + uint32_t p_skip_blocks; + uint32_t p_decode_ae; + uint32_t p_decode_gc; + uint32_t p_decode_id_part0; + uint32_t p_decode_id_part1; + uint32_t p_decode_id_part2; } private_impl; struct { @@ -8658,24 +9209,23 @@ struct wuffs_gif__decoder__struct { struct { uint32_t v_background_color; - } s_do_decode_frame_config[1]; + } s_do_decode_frame_config; struct { uint64_t scratch; - } s_skip_frame[1]; + } s_skip_frame; struct { - uint8_t v_c[6]; - uint32_t v_i; - } s_decode_header[1]; + uint64_t scratch; + } s_decode_header; struct { uint8_t v_flags; uint8_t v_background_color_index; uint32_t v_num_palette_entries; uint32_t v_i; uint64_t scratch; - } s_decode_lsd[1]; + } s_decode_lsd; struct { uint64_t scratch; - } s_skip_blocks[1]; + } s_skip_blocks; struct { uint8_t v_block_size; bool v_is_animexts; @@ -8683,24 +9233,24 @@ struct wuffs_gif__decoder__struct { bool v_is_iccp; bool v_is_xmp; uint64_t scratch; - } s_decode_ae[1]; + } s_decode_ae; struct { uint64_t scratch; - } s_decode_gc[1]; + } s_decode_gc; struct { uint64_t scratch; - } s_decode_id_part0[1]; + } s_decode_id_part0; struct { uint8_t v_which_palette; uint32_t v_num_palette_entries; uint32_t v_i; uint64_t scratch; - } s_decode_id_part1[1]; + } s_decode_id_part1; struct { uint64_t v_block_size; bool v_need_block_size; uint64_t scratch; - } s_decode_id_part2[1]; + } s_decode_id_part2; } private_data; #ifdef __cplusplus @@ -8820,11 +9370,6 @@ struct wuffs_gif__decoder__struct { return wuffs_gif__decoder__frame_dirty_rect(this); } - inline uint64_t - history_retain_length() const { - return wuffs_gif__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_gif__decoder__workbuf_len(this); @@ -8873,9 +9418,9 @@ extern const char wuffs_gzip__error__truncated_input[]; // ---------------- Public Consts -#define WUFFS_GZIP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_GZIP__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1 +#define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u // ---------------- Struct Declarations @@ -8943,8 +9488,8 @@ wuffs_gzip__decoder__set_quirk( uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gzip__decoder__history_retain_length( +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_gzip__decoder__dst_history_retain_length( const wuffs_gzip__decoder* self); WUFFS_BASE__GENERATED_C_CODE @@ -8989,8 +9534,8 @@ struct wuffs_gzip__decoder__struct { bool f_ignore_checksum; - uint32_t p_transform_io[1]; - uint32_t p_do_transform_io[1]; + uint32_t p_transform_io; + uint32_t p_do_transform_io; } private_impl; struct { @@ -8999,11 +9544,11 @@ struct wuffs_gzip__decoder__struct { struct { uint8_t v_flags; - uint32_t v_checksum_got; - uint32_t v_decoded_length_got; + uint32_t v_checksum_have; + uint32_t v_decoded_length_have; uint32_t v_checksum_want; uint64_t scratch; - } s_do_transform_io[1]; + } s_do_transform_io; } private_data; #ifdef __cplusplus @@ -9081,9 +9626,9 @@ struct wuffs_gzip__decoder__struct { return wuffs_gzip__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_gzip__decoder__history_retain_length(this); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_gzip__decoder__dst_history_retain_length(this); } inline wuffs_base__range_ii_u64 @@ -9117,8 +9662,10 @@ 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__rejected_progressive_jpeg[]; extern const char wuffs_jpeg__error__truncated_input[]; extern const char wuffs_jpeg__error__unsupported_arithmetic_coding[]; extern const char wuffs_jpeg__error__unsupported_color_model[]; @@ -9134,9 +9681,9 @@ extern const char wuffs_jpeg__error__unsupported_scan_count[]; // ---------------- Public Consts -#define WUFFS_JPEG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 51552191232u -#define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 51552191232 +#define WUFFS_JPEG__QUIRK_REJECT_PROGRESSIVE_JPEGS 1220532224u // ---------------- Struct Declarations @@ -9269,11 +9816,6 @@ wuffs_jpeg__decoder__tell_me_more( wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_jpeg__decoder__history_retain_length( - const wuffs_jpeg__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_jpeg__decoder__workbuf_len( @@ -9368,6 +9910,13 @@ 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_reject_progressive_jpegs; + 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]; @@ -9381,28 +9930,29 @@ struct wuffs_jpeg__decoder__struct { wuffs_base__slice_u8 a_dst_buffer, uint64_t a_dst_stride, uint32_t a_q); - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_dqt[1]; - uint32_t p_decode_dri[1]; - uint32_t p_decode_appn[1]; - uint32_t p_decode_sof[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; - uint32_t p_decode_dht[1]; - uint32_t p_decode_sos[1]; - uint32_t p_prepare_scan[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_dqt; + uint32_t p_decode_dri; + uint32_t p_decode_appn; + uint32_t p_decode_sof; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_decode_dht; + uint32_t p_decode_sos; + uint32_t p_prepare_scan; wuffs_base__empty_struct (*choosy_load_mcu_blocks_for_single_component)( wuffs_jpeg__decoder* self, uint32_t a_mx, uint32_t a_my, wuffs_base__slice_u8 a_workbuf, uint32_t a_csel); - uint32_t p_skip_past_the_next_restart_marker[1]; + 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); @@ -9411,6 +9961,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]; @@ -9420,38 +9971,38 @@ struct wuffs_jpeg__decoder__struct { struct { uint8_t v_marker; uint64_t scratch; - } s_do_decode_image_config[1]; + } s_do_decode_image_config; struct { uint8_t v_q; uint32_t v_i; - } s_decode_dqt[1]; + } s_decode_dqt; struct { uint64_t scratch; - } s_decode_dri[1]; + } s_decode_dri; struct { uint64_t scratch; - } s_decode_appn[1]; + } s_decode_appn; struct { uint32_t v_i; uint64_t scratch; - } s_decode_sof[1]; + } s_decode_sof; struct { uint8_t v_marker; uint64_t scratch; - } s_do_decode_frame[1]; + } s_do_decode_frame; struct { uint8_t v_tc4_th; uint32_t v_total_count; uint32_t v_i; - } s_decode_dht[1]; + } s_decode_dht; struct { uint32_t v_my; uint32_t v_mx; - } s_decode_sos[1]; + } s_decode_sos; struct { uint32_t v_i; uint64_t scratch; - } s_prepare_scan[1]; + } s_prepare_scan; } private_data; #ifdef __cplusplus @@ -9595,11 +10146,6 @@ struct wuffs_jpeg__decoder__struct { return wuffs_jpeg__decoder__tell_me_more(this, a_dst, a_minfo, a_src); } - inline uint64_t - history_retain_length() const { - return wuffs_jpeg__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_jpeg__decoder__workbuf_len(this); @@ -9627,55 +10173,53 @@ extern const char wuffs_json__error__unsupported_recursion_depth[]; // ---------------- Public Consts -#define WUFFS_JSON__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 - -#define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -#define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024 +#define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024u -#define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1 +#define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1u -#define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100 +#define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100u -#define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480 +#define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489u -#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490 +#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490u -#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491 +#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491u -#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492 +#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492u -#define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493 +#define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493u -#define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494 +#define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494u -#define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495 +#define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495u -#define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496 +#define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496u -#define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497 +#define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497u -#define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498 +#define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498u -#define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499 +#define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499u -#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500 +#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500u // ---------------- Struct Declarations @@ -9742,11 +10286,6 @@ wuffs_json__decoder__set_quirk( uint32_t a_key, uint64_t a_value); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_json__decoder__history_retain_length( - const wuffs_json__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_json__decoder__workbuf_len( @@ -9794,11 +10333,11 @@ struct wuffs_json__decoder__struct { uint8_t f_trailer_stop; uint8_t f_comment_type; - uint32_t p_decode_tokens[1]; - uint32_t p_decode_leading[1]; - uint32_t p_decode_comment[1]; - uint32_t p_decode_inf_nan[1]; - uint32_t p_decode_trailer[1]; + uint32_t p_decode_tokens; + uint32_t p_decode_leading; + uint32_t p_decode_comment; + uint32_t p_decode_inf_nan; + uint32_t p_decode_trailer; } private_impl; struct { @@ -9808,7 +10347,7 @@ struct wuffs_json__decoder__struct { uint32_t v_depth; uint32_t v_expect; uint32_t v_expect_after_value; - } s_decode_tokens[1]; + } s_decode_tokens; } private_data; #ifdef __cplusplus @@ -9886,11 +10425,6 @@ struct wuffs_json__decoder__struct { return wuffs_json__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_json__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_json__decoder__workbuf_len(this); @@ -9911,24 +10445,33 @@ struct wuffs_json__decoder__struct { #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes -extern const char wuffs_lzw__error__bad_code[]; -extern const char wuffs_lzw__error__truncated_input[]; +extern const char wuffs_lzma__error__bad_lzma2_header[]; +extern const char wuffs_lzma__error__bad_bitstream_trailer[]; +extern const char wuffs_lzma__error__bad_code[]; +extern const char wuffs_lzma__error__bad_decoded_length[]; +extern const char wuffs_lzma__error__bad_distance[]; +extern const char wuffs_lzma__error__bad_header[]; +extern const char wuffs_lzma__error__truncated_input[]; +extern const char wuffs_lzma__error__unsupported_decoded_length[]; +extern const char wuffs_lzma__error__unsupported_properties[]; // ---------------- Public Consts -#define WUFFS_LZW__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_LZMA__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_LZMA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u -#define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624 +#define WUFFS_LZMA__QUIRK_ALLOW_NON_ZERO_INITIAL_BYTE 1348001792u + +#define WUFFS_LZMA__QUIRK_FORMAT_EXTENSION 1348001793u // ---------------- Struct Declarations -typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder; +typedef struct wuffs_lzma__decoder__struct wuffs_lzma__decoder; #ifdef __cplusplus extern "C" { @@ -9943,14 +10486,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_lzw__decoder__initialize( - wuffs_lzw__decoder* self, +wuffs_lzma__decoder__initialize( + wuffs_lzma__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_lzw__decoder(void); +sizeof__wuffs_lzma__decoder(void); // ---------------- Allocs @@ -9960,19 +10503,19 @@ sizeof__wuffs_lzw__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_lzw__decoder* -wuffs_lzw__decoder__alloc(void); +wuffs_lzma__decoder* +wuffs_lzma__decoder__alloc(void); static inline wuffs_base__io_transformer* -wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void) { - return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc()); +wuffs_lzma__decoder__alloc_as__wuffs_base__io_transformer(void) { + return (wuffs_base__io_transformer*)(wuffs_lzma__decoder__alloc()); } // ---------------- Upcasts static inline wuffs_base__io_transformer* -wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer( - wuffs_lzw__decoder* p) { +wuffs_lzma__decoder__upcast_as__wuffs_base__io_transformer( + wuffs_lzma__decoder* p) { return (wuffs_base__io_transformer*)p; } @@ -9980,40 +10523,35 @@ wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer( WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_lzw__decoder__get_quirk( - const wuffs_lzw__decoder* self, +wuffs_lzma__decoder__get_quirk( + const wuffs_lzma__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_lzw__decoder__set_quirk( - wuffs_lzw__decoder* self, +wuffs_lzma__decoder__set_quirk( + wuffs_lzma__decoder* self, uint32_t a_key, uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_lzw__decoder__history_retain_length( - const wuffs_lzw__decoder* self); +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzma__decoder__dst_history_retain_length( + const wuffs_lzma__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_lzw__decoder__workbuf_len( - const wuffs_lzw__decoder* self); +wuffs_lzma__decoder__workbuf_len( + const wuffs_lzma__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_lzw__decoder__transform_io( - wuffs_lzw__decoder* self, +wuffs_lzma__decoder__transform_io( + wuffs_lzma__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8 -wuffs_lzw__decoder__flush( - wuffs_lzw__decoder* self); - #ifdef __cplusplus } // extern "C" #endif @@ -10027,7 +10565,7 @@ wuffs_lzw__decoder__flush( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_lzw__decoder__struct { +struct wuffs_lzma__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -10041,45 +10579,113 @@ struct wuffs_lzw__decoder__struct { wuffs_base__vtable vtable_for__wuffs_base__io_transformer; wuffs_base__vtable null_vtable; - uint32_t f_pending_literal_width_plus_one; - uint32_t f_literal_width; - uint32_t f_clear_code; - uint32_t f_end_code; - uint32_t f_save_code; - uint32_t f_prev_code; - uint32_t f_width; - uint32_t f_bits; - uint32_t f_n_bits; - uint32_t f_output_ri; - uint32_t f_output_wi; - uint32_t f_read_from_return_value; - uint16_t f_prefixes[4096]; - - uint32_t p_transform_io[1]; - uint32_t p_write_to[1]; + uint32_t f_lc; + uint32_t f_lp; + uint32_t f_pb; + uint32_t f_format_extension; + uint32_t f_dict_size; + uint32_t f_dict_workbuf_index; + uint32_t f_dict_seen; + uint64_t f_decoded_length; + uint64_t f_lzma2_encoded_length_have; + uint64_t f_lzma2_encoded_length_want; + bool f_lzma2_need_prob_reset; + bool f_lzma2_need_properties; + bool f_lzma2_need_dict_reset; + bool f_prev_lzma2_chunk_was_uncompressed; + bool f_allow_non_zero_initial_byte; + bool f_end_of_chunk; + uint8_t f_stashed_bytes[2]; + uint32_t f_stashed_bits; + uint32_t f_stashed_range; + uint32_t f_stashed_state; + uint32_t f_stashed_rep0; + uint32_t f_stashed_rep1; + uint32_t f_stashed_rep2; + uint32_t f_stashed_rep3; + uint64_t f_stashed_pos; + uint64_t f_stashed_pos_end; + + uint32_t p_decode_bitstream_slow; + uint32_t p_transform_io; + uint32_t p_do_transform_io; + uint32_t p_decode_bitstream; + uint32_t p_update_stashed_bytes; + uint32_t p_decode_optional_end_of_stream; } private_impl; struct { - uint8_t f_suffixes[4096][8]; - uint16_t f_lm1s[4096]; - uint8_t f_output[8199]; + uint16_t f_probs_ao00[192]; + uint16_t f_probs_ao20[12]; + uint16_t f_probs_ao40[12]; + uint16_t f_probs_ao41[192]; + uint16_t f_probs_ao60[12]; + uint16_t f_probs_ao63[12]; + uint16_t f_probs_match_len_low[16][8]; + uint16_t f_probs_match_len_mid[16][8]; + uint16_t f_probs_match_len_high[1][256]; + uint16_t f_probs_longrep_len_low[16][8]; + uint16_t f_probs_longrep_len_mid[16][8]; + uint16_t f_probs_longrep_len_high[1][256]; + uint16_t f_probs_slot[4][64]; + uint16_t f_probs_small_dist[128]; + uint16_t f_probs_large_dist[16]; + uint16_t f_probs_lit[16][768]; + + struct { + uint32_t v_bits; + uint32_t v_range; + uint32_t v_state; + uint32_t v_rep0; + uint32_t v_rep1; + uint32_t v_rep2; + uint32_t v_rep3; + uint32_t v_rep; + uint64_t v_pos; + uint64_t v_pos_end; + uint32_t v_lc; + uint64_t v_lp_mask; + uint64_t v_pb_mask; + uint32_t v_tree_node; + uint8_t v_prev_byte; + uint32_t v_match_byte; + uint32_t v_len_state; + uint32_t v_slot; + uint32_t v_len; + uint32_t v_lanl_offset; + uint32_t v_num_extra_bits; + uint32_t v_dist_extra_bits; + uint32_t v_i; + uint32_t v_index_lit; + uint32_t v_index_len; + uint32_t v_index_small_dist_base; + uint32_t v_index_small_dist_extra; + uint32_t v_index_large_dist; + uint32_t v_dist; + uint64_t scratch; + } s_decode_bitstream_slow; + struct { + uint8_t v_header_byte; + uint32_t v_length; + uint64_t scratch; + } s_do_transform_io; } private_data; #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_lzw__decoder__alloc()); + return unique_ptr(wuffs_lzma__decoder__alloc()); } static inline wuffs_base__io_transformer::unique_ptr alloc_as__wuffs_base__io_transformer() { return wuffs_base__io_transformer::unique_ptr( - wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer()); + wuffs_lzma__decoder__alloc_as__wuffs_base__io_transformer()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -10095,10 +10701,10 @@ struct wuffs_lzw__decoder__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_lzw__decoder__struct() = delete; - wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete; - wuffs_lzw__decoder__struct& operator=( - const wuffs_lzw__decoder__struct&) = delete; + wuffs_lzma__decoder__struct() = delete; + wuffs_lzma__decoder__struct(const wuffs_lzma__decoder__struct&) = delete; + wuffs_lzma__decoder__struct& operator=( + const wuffs_lzma__decoder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -10118,7 +10724,7 @@ struct wuffs_lzw__decoder__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_lzw__decoder__initialize( + return wuffs_lzma__decoder__initialize( this, sizeof_star_self, wuffs_version, options); } @@ -10130,24 +10736,24 @@ struct wuffs_lzw__decoder__struct { inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_lzw__decoder__get_quirk(this, a_key); + return wuffs_lzma__decoder__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_lzw__decoder__set_quirk(this, a_key, a_value); + return wuffs_lzma__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_lzw__decoder__history_retain_length(this); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_lzma__decoder__dst_history_retain_length(this); } inline wuffs_base__range_ii_u64 workbuf_len() const { - return wuffs_lzw__decoder__workbuf_len(this); + return wuffs_lzma__decoder__workbuf_len(this); } inline wuffs_base__status @@ -10155,38 +10761,34 @@ struct wuffs_lzw__decoder__struct { wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf) { - return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf); - } - - inline wuffs_base__slice_u8 - flush() { - return wuffs_lzw__decoder__flush(this); + return wuffs_lzma__decoder__transform_io(this, a_dst, a_src, a_workbuf); } #endif // __cplusplus -}; // struct wuffs_lzw__decoder__struct +}; // struct wuffs_lzma__decoder__struct #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes -extern const char wuffs_netpbm__error__bad_header[]; -extern const char wuffs_netpbm__error__truncated_input[]; -extern const char wuffs_netpbm__error__unsupported_netpbm_file[]; +extern const char wuffs_lzip__error__bad_checksum[]; +extern const char wuffs_lzip__error__bad_footer[]; +extern const char wuffs_lzip__error__bad_header[]; +extern const char wuffs_lzip__error__truncated_input[]; // ---------------- Public Consts -#define WUFFS_NETPBM__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_LZIP__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#define WUFFS_NETPBM__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_LZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u // ---------------- Struct Declarations -typedef struct wuffs_netpbm__decoder__struct wuffs_netpbm__decoder; +typedef struct wuffs_lzip__decoder__struct wuffs_lzip__decoder; #ifdef __cplusplus extern "C" { @@ -10201,14 +10803,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_netpbm__decoder__initialize( - wuffs_netpbm__decoder* self, +wuffs_lzip__decoder__initialize( + wuffs_lzip__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_netpbm__decoder(void); +sizeof__wuffs_lzip__decoder(void); // ---------------- Allocs @@ -10218,112 +10820,54 @@ sizeof__wuffs_netpbm__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_netpbm__decoder* -wuffs_netpbm__decoder__alloc(void); +wuffs_lzip__decoder* +wuffs_lzip__decoder__alloc(void); -static inline wuffs_base__image_decoder* -wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void) { - return (wuffs_base__image_decoder*)(wuffs_netpbm__decoder__alloc()); +static inline wuffs_base__io_transformer* +wuffs_lzip__decoder__alloc_as__wuffs_base__io_transformer(void) { + return (wuffs_base__io_transformer*)(wuffs_lzip__decoder__alloc()); } // ---------------- Upcasts -static inline wuffs_base__image_decoder* -wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder( - wuffs_netpbm__decoder* p) { - return (wuffs_base__image_decoder*)p; +static inline wuffs_base__io_transformer* +wuffs_lzip__decoder__upcast_as__wuffs_base__io_transformer( + wuffs_lzip__decoder* p) { + return (wuffs_base__io_transformer*)p; } // ---------------- Public Function Prototypes WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__get_quirk( - const wuffs_netpbm__decoder* self, +wuffs_lzip__decoder__get_quirk( + const wuffs_lzip__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__set_quirk( - wuffs_netpbm__decoder* self, +wuffs_lzip__decoder__set_quirk( + wuffs_lzip__decoder* self, uint32_t a_key, uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_image_config( - wuffs_netpbm__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_frame_config( - wuffs_netpbm__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_frame( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_netpbm__decoder__frame_dirty_rect( - const wuffs_netpbm__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_netpbm__decoder__num_animation_loops( - const wuffs_netpbm__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__num_decoded_frame_configs( - const wuffs_netpbm__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__num_decoded_frames( - const wuffs_netpbm__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__restart_frame( - wuffs_netpbm__decoder* self, - uint64_t a_index, - uint64_t a_io_position); +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzip__decoder__dst_history_retain_length( + const wuffs_lzip__decoder* self); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_netpbm__decoder__set_report_metadata( - wuffs_netpbm__decoder* self, - uint32_t a_fourcc, - bool a_report); +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_lzip__decoder__workbuf_len( + const wuffs_lzip__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__tell_me_more( - wuffs_netpbm__decoder* self, +wuffs_lzip__decoder__transform_io( + wuffs_lzip__decoder* self, wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__history_retain_length( - const wuffs_netpbm__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_netpbm__decoder__workbuf_len( - const wuffs_netpbm__decoder* self); + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); #ifdef __cplusplus } // extern "C" @@ -10338,7 +10882,7 @@ wuffs_netpbm__decoder__workbuf_len( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_netpbm__decoder__struct { +struct wuffs_lzip__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -10349,42 +10893,41 @@ struct wuffs_netpbm__decoder__struct { struct { uint32_t magic; uint32_t active_coroutine; - wuffs_base__vtable vtable_for__wuffs_base__image_decoder; + wuffs_base__vtable vtable_for__wuffs_base__io_transformer; wuffs_base__vtable null_vtable; - uint32_t f_pixfmt; - uint32_t f_width; - uint32_t f_height; - uint32_t f_max_value; - uint8_t f_call_sequence; - uint64_t f_frame_config_io_position; - uint32_t f_dst_x; - uint32_t f_dst_y; - wuffs_base__pixel_swizzler f_swizzler; + bool f_ignore_checksum; + uint64_t f_dsize_have; + uint64_t f_ssize_have; - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; + uint32_t p_transform_io; + uint32_t p_do_transform_io; } private_impl; + struct { + wuffs_crc32__ieee_hasher f_crc32; + wuffs_lzma__decoder f_lzma; + + struct { + uint64_t scratch; + } s_do_transform_io; + } private_data; + #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_netpbm__decoder__alloc()); + return unique_ptr(wuffs_lzip__decoder__alloc()); } - static inline wuffs_base__image_decoder::unique_ptr - alloc_as__wuffs_base__image_decoder() { - return wuffs_base__image_decoder::unique_ptr( - wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder()); + static inline wuffs_base__io_transformer::unique_ptr + alloc_as__wuffs_base__io_transformer() { + return wuffs_base__io_transformer::unique_ptr( + wuffs_lzip__decoder__alloc_as__wuffs_base__io_transformer()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -10400,10 +10943,10 @@ struct wuffs_netpbm__decoder__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_netpbm__decoder__struct() = delete; - wuffs_netpbm__decoder__struct(const wuffs_netpbm__decoder__struct&) = delete; - wuffs_netpbm__decoder__struct& operator=( - const wuffs_netpbm__decoder__struct&) = delete; + wuffs_lzip__decoder__struct() = delete; + wuffs_lzip__decoder__struct(const wuffs_lzip__decoder__struct&) = delete; + wuffs_lzip__decoder__struct& operator=( + const wuffs_lzip__decoder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -10423,128 +10966,327 @@ struct wuffs_netpbm__decoder__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_netpbm__decoder__initialize( + return wuffs_lzip__decoder__initialize( this, sizeof_star_self, wuffs_version, options); } - inline wuffs_base__image_decoder* - upcast_as__wuffs_base__image_decoder() { - return (wuffs_base__image_decoder*)this; + inline wuffs_base__io_transformer* + upcast_as__wuffs_base__io_transformer() { + return (wuffs_base__io_transformer*)this; } inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_netpbm__decoder__get_quirk(this, a_key); + return wuffs_lzip__decoder__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_netpbm__decoder__set_quirk(this, a_key, a_value); + return wuffs_lzip__decoder__set_quirk(this, a_key, a_value); } - inline wuffs_base__status - decode_image_config( - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - return wuffs_netpbm__decoder__decode_image_config(this, a_dst, a_src); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_lzip__decoder__dst_history_retain_length(this); } - inline wuffs_base__status - decode_frame_config( - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - return wuffs_netpbm__decoder__decode_frame_config(this, a_dst, a_src); + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_lzip__decoder__workbuf_len(this); } inline wuffs_base__status - decode_frame( - wuffs_base__pixel_buffer* a_dst, + transform_io( + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - return wuffs_netpbm__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); - } - - inline wuffs_base__rect_ie_u32 - frame_dirty_rect() const { - return wuffs_netpbm__decoder__frame_dirty_rect(this); + wuffs_base__slice_u8 a_workbuf) { + return wuffs_lzip__decoder__transform_io(this, a_dst, a_src, a_workbuf); } - inline uint32_t - num_animation_loops() const { - return wuffs_netpbm__decoder__num_animation_loops(this); - } +#endif // __cplusplus +}; // struct wuffs_lzip__decoder__struct - inline uint64_t - num_decoded_frame_configs() const { - return wuffs_netpbm__decoder__num_decoded_frame_configs(this); - } +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - inline uint64_t - num_decoded_frames() const { - return wuffs_netpbm__decoder__num_decoded_frames(this); - } +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) || defined(WUFFS_NONMONOLITHIC) - inline wuffs_base__status - restart_frame( - uint64_t a_index, - uint64_t a_io_position) { - return wuffs_netpbm__decoder__restart_frame(this, a_index, a_io_position); - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC) - inline wuffs_base__empty_struct - set_report_metadata( - uint32_t a_fourcc, - bool a_report) { - return wuffs_netpbm__decoder__set_report_metadata(this, a_fourcc, a_report); - } +// ---------------- Status Codes - inline wuffs_base__status - tell_me_more( - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - return wuffs_netpbm__decoder__tell_me_more(this, a_dst, a_minfo, a_src); - } +extern const char wuffs_lzw__error__bad_code[]; +extern const char wuffs_lzw__error__truncated_input[]; - inline uint64_t - history_retain_length() const { - return wuffs_netpbm__decoder__history_retain_length(this); - } +// ---------------- Public Consts - inline wuffs_base__range_ii_u64 - workbuf_len() const { - return wuffs_netpbm__decoder__workbuf_len(this); - } +#define WUFFS_LZW__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -#endif // __cplusplus -}; // struct wuffs_netpbm__decoder__struct +#define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) +#define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624u -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC) +// ---------------- Struct Declarations -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC) +typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder; -// ---------------- Status Codes +#ifdef __cplusplus +extern "C" { +#endif -extern const char wuffs_nie__error__bad_header[]; -extern const char wuffs_nie__error__truncated_input[]; -extern const char wuffs_nie__error__unsupported_nie_file[]; +// ---------------- Public Initializer Prototypes -// ---------------- Public Consts +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_lzw__decoder__initialize( + wuffs_lzw__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); + +size_t +sizeof__wuffs_lzw__decoder(void); + +// ---------------- Allocs + +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. + +wuffs_lzw__decoder* +wuffs_lzw__decoder__alloc(void); + +static inline wuffs_base__io_transformer* +wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void) { + return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc()); +} + +// ---------------- Upcasts + +static inline wuffs_base__io_transformer* +wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer( + wuffs_lzw__decoder* p) { + return (wuffs_base__io_transformer*)p; +} + +// ---------------- Public Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_lzw__decoder__get_quirk( + const wuffs_lzw__decoder* self, + uint32_t a_key); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzw__decoder__set_quirk( + wuffs_lzw__decoder* self, + uint32_t a_key, + uint64_t a_value); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzw__decoder__dst_history_retain_length( + const wuffs_lzw__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_lzw__decoder__workbuf_len( + const wuffs_lzw__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzw__decoder__transform_io( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8 +wuffs_lzw__decoder__flush( + wuffs_lzw__decoder* self); + +#ifdef __cplusplus +} // extern "C" +#endif + +// ---------------- Struct Definitions + +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C + +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_lzw__decoder__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. + + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__io_transformer; + wuffs_base__vtable null_vtable; + + uint32_t f_pending_literal_width_plus_one; + uint32_t f_literal_width; + uint32_t f_clear_code; + uint32_t f_end_code; + uint32_t f_save_code; + uint32_t f_prev_code; + uint32_t f_width; + uint32_t f_bits; + uint32_t f_n_bits; + uint32_t f_output_ri; + uint32_t f_output_wi; + uint32_t f_read_from_return_value; + uint16_t f_prefixes[4096]; + + uint32_t p_transform_io; + uint32_t p_write_to; + } private_impl; + + struct { + uint8_t f_suffixes[4096][8]; + uint16_t f_lm1s[4096]; + uint8_t f_output[8199]; + } private_data; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; + + // On failure, the alloc_etc functions return nullptr. They don't throw. + + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_lzw__decoder__alloc()); + } + + static inline wuffs_base__io_transformer::unique_ptr + alloc_as__wuffs_base__io_transformer() { + return wuffs_base__io_transformer::unique_ptr( + wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer()); + } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_lzw__decoder__struct() = delete; + wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete; + wuffs_lzw__decoder__struct& operator=( + const wuffs_lzw__decoder__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) + + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_lzw__decoder__initialize( + this, sizeof_star_self, wuffs_version, options); + } + + inline wuffs_base__io_transformer* + upcast_as__wuffs_base__io_transformer() { + return (wuffs_base__io_transformer*)this; + } + + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_lzw__decoder__get_quirk(this, a_key); + } + + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_lzw__decoder__set_quirk(this, a_key, a_value); + } + + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_lzw__decoder__dst_history_retain_length(this); + } + + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_lzw__decoder__workbuf_len(this); + } + + inline wuffs_base__status + transform_io( + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf); + } + + inline wuffs_base__slice_u8 + flush() { + return wuffs_lzw__decoder__flush(this); + } + +#endif // __cplusplus +}; // struct wuffs_lzw__decoder__struct + +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC) + +// ---------------- Status Codes + +extern const char wuffs_netpbm__error__bad_header[]; +extern const char wuffs_netpbm__error__truncated_input[]; +extern const char wuffs_netpbm__error__unsupported_netpbm_file[]; -#define WUFFS_NIE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +// ---------------- Public Consts -#define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_NETPBM__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u // ---------------- Struct Declarations -typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder; +typedef struct wuffs_netpbm__decoder__struct wuffs_netpbm__decoder; #ifdef __cplusplus extern "C" { @@ -10559,14 +11301,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_nie__decoder__initialize( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__initialize( + wuffs_netpbm__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_nie__decoder(void); +sizeof__wuffs_netpbm__decoder(void); // ---------------- Allocs @@ -10576,19 +11318,19 @@ sizeof__wuffs_nie__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_nie__decoder* -wuffs_nie__decoder__alloc(void); +wuffs_netpbm__decoder* +wuffs_netpbm__decoder__alloc(void); static inline wuffs_base__image_decoder* -wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void) { - return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc()); +wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_netpbm__decoder__alloc()); } // ---------------- Upcasts static inline wuffs_base__image_decoder* -wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder( - wuffs_nie__decoder* p) { +wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_netpbm__decoder* p) { return (wuffs_base__image_decoder*)p; } @@ -10596,35 +11338,35 @@ wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder( WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__get_quirk( - const wuffs_nie__decoder* self, +wuffs_netpbm__decoder__get_quirk( + const wuffs_netpbm__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__set_quirk( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__set_quirk( + wuffs_netpbm__decoder* self, uint32_t a_key, uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_image_config( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__decode_image_config( + wuffs_netpbm__decoder* self, wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_frame_config( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__decode_frame_config( + wuffs_netpbm__decoder* self, wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_frame( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__decode_frame( + wuffs_netpbm__decoder* self, wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__pixel_blend a_blend, @@ -10633,55 +11375,50 @@ wuffs_nie__decoder__decode_frame( WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_nie__decoder__frame_dirty_rect( - const wuffs_nie__decoder* self); +wuffs_netpbm__decoder__frame_dirty_rect( + const wuffs_netpbm__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_nie__decoder__num_animation_loops( - const wuffs_nie__decoder* self); +wuffs_netpbm__decoder__num_animation_loops( + const wuffs_netpbm__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__num_decoded_frame_configs( - const wuffs_nie__decoder* self); +wuffs_netpbm__decoder__num_decoded_frame_configs( + const wuffs_netpbm__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__num_decoded_frames( - const wuffs_nie__decoder* self); +wuffs_netpbm__decoder__num_decoded_frames( + const wuffs_netpbm__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__restart_frame( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__restart_frame( + wuffs_netpbm__decoder* self, uint64_t a_index, uint64_t a_io_position); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_nie__decoder__set_report_metadata( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__set_report_metadata( + wuffs_netpbm__decoder* self, uint32_t a_fourcc, bool a_report); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__tell_me_more( - wuffs_nie__decoder* self, +wuffs_netpbm__decoder__tell_me_more( + wuffs_netpbm__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__history_retain_length( - const wuffs_nie__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_nie__decoder__workbuf_len( - const wuffs_nie__decoder* self); +wuffs_netpbm__decoder__workbuf_len( + const wuffs_netpbm__decoder* self); #ifdef __cplusplus } // extern "C" @@ -10696,7 +11433,7 @@ wuffs_nie__decoder__workbuf_len( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_nie__decoder__struct { +struct wuffs_netpbm__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -10713,40 +11450,36 @@ struct wuffs_nie__decoder__struct { uint32_t f_pixfmt; uint32_t f_width; uint32_t f_height; + uint32_t f_max_value; uint8_t f_call_sequence; + uint64_t f_frame_config_io_position; uint32_t f_dst_x; uint32_t f_dst_y; wuffs_base__pixel_swizzler f_swizzler; - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; } private_impl; - struct { - struct { - uint64_t scratch; - } s_do_decode_image_config[1]; - } private_data; - #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_nie__decoder__alloc()); + return unique_ptr(wuffs_netpbm__decoder__alloc()); } static inline wuffs_base__image_decoder::unique_ptr alloc_as__wuffs_base__image_decoder() { return wuffs_base__image_decoder::unique_ptr( - wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder()); + wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -10762,10 +11495,10 @@ struct wuffs_nie__decoder__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_nie__decoder__struct() = delete; - wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete; - wuffs_nie__decoder__struct& operator=( - const wuffs_nie__decoder__struct&) = delete; + wuffs_netpbm__decoder__struct() = delete; + wuffs_netpbm__decoder__struct(const wuffs_netpbm__decoder__struct&) = delete; + wuffs_netpbm__decoder__struct& operator=( + const wuffs_netpbm__decoder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -10785,7 +11518,7 @@ struct wuffs_nie__decoder__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_nie__decoder__initialize( + return wuffs_netpbm__decoder__initialize( this, sizeof_star_self, wuffs_version, options); } @@ -10797,28 +11530,28 @@ struct wuffs_nie__decoder__struct { inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_nie__decoder__get_quirk(this, a_key); + return wuffs_netpbm__decoder__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_nie__decoder__set_quirk(this, a_key, a_value); + return wuffs_netpbm__decoder__set_quirk(this, a_key, a_value); } inline wuffs_base__status decode_image_config( wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { - return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src); + return wuffs_netpbm__decoder__decode_image_config(this, a_dst, a_src); } inline wuffs_base__status decode_frame_config( wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src) { - return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src); + return wuffs_netpbm__decoder__decode_frame_config(this, a_dst, a_src); } inline wuffs_base__status @@ -10828,41 +11561,41 @@ struct wuffs_nie__decoder__struct { wuffs_base__pixel_blend a_blend, wuffs_base__slice_u8 a_workbuf, wuffs_base__decode_frame_options* a_opts) { - return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + return wuffs_netpbm__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); } inline wuffs_base__rect_ie_u32 frame_dirty_rect() const { - return wuffs_nie__decoder__frame_dirty_rect(this); + return wuffs_netpbm__decoder__frame_dirty_rect(this); } inline uint32_t num_animation_loops() const { - return wuffs_nie__decoder__num_animation_loops(this); + return wuffs_netpbm__decoder__num_animation_loops(this); } inline uint64_t num_decoded_frame_configs() const { - return wuffs_nie__decoder__num_decoded_frame_configs(this); + return wuffs_netpbm__decoder__num_decoded_frame_configs(this); } inline uint64_t num_decoded_frames() const { - return wuffs_nie__decoder__num_decoded_frames(this); + return wuffs_netpbm__decoder__num_decoded_frames(this); } inline wuffs_base__status restart_frame( uint64_t a_index, uint64_t a_io_position) { - return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position); + return wuffs_netpbm__decoder__restart_frame(this, a_index, a_io_position); } inline wuffs_base__empty_struct set_report_metadata( uint32_t a_fourcc, bool a_report) { - return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report); + return wuffs_netpbm__decoder__set_report_metadata(this, a_fourcc, a_report); } inline wuffs_base__status @@ -10870,49 +11603,36 @@ struct wuffs_nie__decoder__struct { wuffs_base__io_buffer* a_dst, wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src) { - return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src); - } - - inline uint64_t - history_retain_length() const { - return wuffs_nie__decoder__history_retain_length(this); + return wuffs_netpbm__decoder__tell_me_more(this, a_dst, a_minfo, a_src); } inline wuffs_base__range_ii_u64 workbuf_len() const { - return wuffs_nie__decoder__workbuf_len(this); + return wuffs_netpbm__decoder__workbuf_len(this); } #endif // __cplusplus -}; // struct wuffs_nie__decoder__struct +}; // struct wuffs_netpbm__decoder__struct #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes -extern const char wuffs_zlib__note__dictionary_required[]; -extern const char wuffs_zlib__error__bad_checksum[]; -extern const char wuffs_zlib__error__bad_compression_method[]; -extern const char wuffs_zlib__error__bad_compression_window_size[]; -extern const char wuffs_zlib__error__bad_parity_check[]; -extern const char wuffs_zlib__error__incorrect_dictionary[]; -extern const char wuffs_zlib__error__truncated_input[]; +extern const char wuffs_nie__error__bad_header[]; +extern const char wuffs_nie__error__truncated_input[]; +extern const char wuffs_nie__error__unsupported_nie_file[]; // ---------------- Public Consts -#define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976 - -#define WUFFS_ZLIB__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 - -#define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1 +#define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u // ---------------- Struct Declarations -typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder; +typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder; #ifdef __cplusplus extern "C" { @@ -10927,14 +11647,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_zlib__decoder__initialize( - wuffs_zlib__decoder* self, +wuffs_nie__decoder__initialize( + wuffs_nie__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_zlib__decoder(void); +sizeof__wuffs_nie__decoder(void); // ---------------- Allocs @@ -10944,65 +11664,107 @@ sizeof__wuffs_zlib__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_zlib__decoder* -wuffs_zlib__decoder__alloc(void); +wuffs_nie__decoder* +wuffs_nie__decoder__alloc(void); -static inline wuffs_base__io_transformer* -wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void) { - return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc()); +static inline wuffs_base__image_decoder* +wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc()); } // ---------------- Upcasts -static inline wuffs_base__io_transformer* -wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer( - wuffs_zlib__decoder* p) { - return (wuffs_base__io_transformer*)p; +static inline wuffs_base__image_decoder* +wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_nie__decoder* p) { + return (wuffs_base__image_decoder*)p; } // ---------------- Public Function Prototypes -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_zlib__decoder__dictionary_id( - const wuffs_zlib__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_zlib__decoder__add_dictionary( - wuffs_zlib__decoder* self, - wuffs_base__slice_u8 a_dict); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_zlib__decoder__get_quirk( - const wuffs_zlib__decoder* self, +wuffs_nie__decoder__get_quirk( + const wuffs_nie__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_zlib__decoder__set_quirk( - wuffs_zlib__decoder* self, +wuffs_nie__decoder__set_quirk( + wuffs_nie__decoder* self, uint32_t a_key, uint64_t a_value); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_image_config( + wuffs_nie__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_frame_config( + wuffs_nie__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_frame( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_nie__decoder__frame_dirty_rect( + const wuffs_nie__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_nie__decoder__num_animation_loops( + const wuffs_nie__decoder* self); + WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_zlib__decoder__history_retain_length( - const wuffs_zlib__decoder* self); +wuffs_nie__decoder__num_decoded_frame_configs( + const wuffs_nie__decoder* self); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_zlib__decoder__workbuf_len( - const wuffs_zlib__decoder* self); +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_nie__decoder__num_decoded_frames( + const wuffs_nie__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_zlib__decoder__transform_io( - wuffs_zlib__decoder* self, +wuffs_nie__decoder__restart_frame( + wuffs_nie__decoder* self, + uint64_t a_index, + uint64_t a_io_position); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_nie__decoder__set_report_metadata( + wuffs_nie__decoder* self, + uint32_t a_fourcc, + bool a_report); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__tell_me_more( + wuffs_nie__decoder* self, wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_nie__decoder__workbuf_len( + const wuffs_nie__decoder* self); #ifdef __cplusplus } // extern "C" @@ -11017,7 +11779,7 @@ wuffs_zlib__decoder__transform_io( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_zlib__decoder__struct { +struct wuffs_nie__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -11028,20 +11790,336 @@ struct wuffs_zlib__decoder__struct { struct { uint32_t magic; uint32_t active_coroutine; - wuffs_base__vtable vtable_for__wuffs_base__io_transformer; + wuffs_base__vtable vtable_for__wuffs_base__image_decoder; wuffs_base__vtable null_vtable; - bool f_bad_call_sequence; - bool f_header_complete; + uint32_t f_pixfmt; + uint32_t f_width; + uint32_t f_height; + uint8_t f_call_sequence; + uint32_t f_dst_x; + uint32_t f_dst_y; + wuffs_base__pixel_swizzler f_swizzler; + + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + } private_impl; + + struct { + struct { + uint64_t scratch; + } s_do_decode_image_config; + } private_data; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; + + // On failure, the alloc_etc functions return nullptr. They don't throw. + + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_nie__decoder__alloc()); + } + + static inline wuffs_base__image_decoder::unique_ptr + alloc_as__wuffs_base__image_decoder() { + return wuffs_base__image_decoder::unique_ptr( + wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder()); + } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_nie__decoder__struct() = delete; + wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete; + wuffs_nie__decoder__struct& operator=( + const wuffs_nie__decoder__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) + + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_nie__decoder__initialize( + this, sizeof_star_self, wuffs_version, options); + } + + inline wuffs_base__image_decoder* + upcast_as__wuffs_base__image_decoder() { + return (wuffs_base__image_decoder*)this; + } + + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_nie__decoder__get_quirk(this, a_key); + } + + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_nie__decoder__set_quirk(this, a_key, a_value); + } + + inline wuffs_base__status + decode_image_config( + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src); + } + + inline wuffs_base__status + decode_frame_config( + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src); + } + + inline wuffs_base__status + decode_frame( + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + } + + inline wuffs_base__rect_ie_u32 + frame_dirty_rect() const { + return wuffs_nie__decoder__frame_dirty_rect(this); + } + + inline uint32_t + num_animation_loops() const { + return wuffs_nie__decoder__num_animation_loops(this); + } + + inline uint64_t + num_decoded_frame_configs() const { + return wuffs_nie__decoder__num_decoded_frame_configs(this); + } + + inline uint64_t + num_decoded_frames() const { + return wuffs_nie__decoder__num_decoded_frames(this); + } + + inline wuffs_base__status + restart_frame( + uint64_t a_index, + uint64_t a_io_position) { + return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position); + } + + inline wuffs_base__empty_struct + set_report_metadata( + uint32_t a_fourcc, + bool a_report) { + return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report); + } + + inline wuffs_base__status + tell_me_more( + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src); + } + + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_nie__decoder__workbuf_len(this); + } + +#endif // __cplusplus +}; // struct wuffs_nie__decoder__struct + +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC) + +// ---------------- Status Codes + +extern const char wuffs_zlib__note__dictionary_required[]; +extern const char wuffs_zlib__error__bad_checksum[]; +extern const char wuffs_zlib__error__bad_compression_method[]; +extern const char wuffs_zlib__error__bad_compression_window_size[]; +extern const char wuffs_zlib__error__bad_parity_check[]; +extern const char wuffs_zlib__error__incorrect_dictionary[]; +extern const char wuffs_zlib__error__truncated_input[]; + +// ---------------- Public Consts + +#define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976u + +#define WUFFS_ZLIB__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u + +#define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1u + +// ---------------- Struct Declarations + +typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder; + +#ifdef __cplusplus +extern "C" { +#endif + +// ---------------- Public Initializer Prototypes + +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_zlib__decoder__initialize( + wuffs_zlib__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); + +size_t +sizeof__wuffs_zlib__decoder(void); + +// ---------------- Allocs + +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. + +wuffs_zlib__decoder* +wuffs_zlib__decoder__alloc(void); + +static inline wuffs_base__io_transformer* +wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void) { + return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc()); +} + +// ---------------- Upcasts + +static inline wuffs_base__io_transformer* +wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer( + wuffs_zlib__decoder* p) { + return (wuffs_base__io_transformer*)p; +} + +// ---------------- Public Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_zlib__decoder__dictionary_id( + const wuffs_zlib__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_zlib__decoder__add_dictionary( + wuffs_zlib__decoder* self, + wuffs_base__slice_u8 a_dict); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_zlib__decoder__get_quirk( + const wuffs_zlib__decoder* self, + uint32_t a_key); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_zlib__decoder__set_quirk( + wuffs_zlib__decoder* self, + uint32_t a_key, + uint64_t a_value); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_zlib__decoder__dst_history_retain_length( + const wuffs_zlib__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_zlib__decoder__workbuf_len( + const wuffs_zlib__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_zlib__decoder__transform_io( + wuffs_zlib__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +#ifdef __cplusplus +} // extern "C" +#endif + +// ---------------- Struct Definitions + +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C + +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_zlib__decoder__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. + + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__io_transformer; + wuffs_base__vtable null_vtable; + + bool f_bad_call_sequence; + bool f_header_complete; bool f_got_dictionary; bool f_want_dictionary; bool f_quirks[1]; bool f_ignore_checksum; - uint32_t f_dict_id_got; + uint32_t f_dict_id_have; uint32_t f_dict_id_want; - uint32_t p_transform_io[1]; - uint32_t p_do_transform_io[1]; + uint32_t p_transform_io; + uint32_t p_do_transform_io; } private_impl; struct { @@ -11050,9 +12128,9 @@ struct wuffs_zlib__decoder__struct { wuffs_deflate__decoder f_flate; struct { - uint32_t v_checksum_got; + uint32_t v_checksum_have; uint64_t scratch; - } s_do_transform_io[1]; + } s_do_transform_io; } private_data; #ifdef __cplusplus @@ -11141,9 +12219,9 @@ struct wuffs_zlib__decoder__struct { return wuffs_zlib__decoder__set_quirk(this, a_key, a_value); } - inline uint64_t - history_retain_length() const { - return wuffs_zlib__decoder__history_retain_length(this); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_zlib__decoder__dst_history_retain_length(this); } inline wuffs_base__range_ii_u64 @@ -11184,11 +12262,9 @@ extern const char wuffs_png__error__unsupported_png_file[]; // ---------------- Public Consts -#define WUFFS_PNG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 +#define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 2251799562027015u -#define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 2251799562027015 - -#define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8 +#define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8u // ---------------- Struct Declarations @@ -11321,11 +12397,6 @@ wuffs_png__decoder__tell_me_more( wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_png__decoder__history_retain_length( - const wuffs_png__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 wuffs_png__decoder__workbuf_len( @@ -11438,26 +12509,26 @@ struct wuffs_png__decoder__struct { wuffs_png__decoder* self, wuffs_base__slice_u8 a_curr, wuffs_base__slice_u8 a_prev); - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_ihdr[1]; - uint32_t p_decode_other_chunk[1]; - uint32_t p_decode_actl[1]; - uint32_t p_decode_chrm[1]; - uint32_t p_decode_fctl[1]; - uint32_t p_decode_gama[1]; - uint32_t p_decode_iccp[1]; - uint32_t p_decode_plte[1]; - uint32_t p_decode_srgb[1]; - uint32_t p_decode_trns[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_skip_frame[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; - uint32_t p_decode_pass[1]; - uint32_t p_tell_me_more[1]; - uint32_t p_do_tell_me_more[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_ihdr; + uint32_t p_decode_other_chunk; + uint32_t p_decode_actl; + uint32_t p_decode_chrm; + uint32_t p_decode_fctl; + uint32_t p_decode_gama; + uint32_t p_decode_iccp; + uint32_t p_decode_plte; + uint32_t p_decode_srgb; + uint32_t p_decode_trns; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_skip_frame; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_decode_pass; + uint32_t p_tell_me_more; + uint32_t p_do_tell_me_more; wuffs_base__status (*choosy_filter_and_swizzle)( wuffs_png__decoder* self, wuffs_base__pixel_buffer* a_dst, @@ -11473,54 +12544,54 @@ struct wuffs_png__decoder__struct { struct { uint32_t v_checksum_have; uint64_t scratch; - } s_do_decode_image_config[1]; + } s_do_decode_image_config; struct { uint64_t scratch; - } s_decode_ihdr[1]; + } s_decode_ihdr; struct { uint64_t scratch; - } s_decode_other_chunk[1]; + } s_decode_other_chunk; struct { uint64_t scratch; - } s_decode_actl[1]; + } s_decode_actl; struct { uint64_t scratch; - } s_decode_chrm[1]; + } s_decode_chrm; struct { uint32_t v_x0; uint32_t v_x1; uint32_t v_y1; uint64_t scratch; - } s_decode_fctl[1]; + } s_decode_fctl; struct { uint64_t scratch; - } s_decode_gama[1]; + } s_decode_gama; struct { uint32_t v_num_entries; uint32_t v_i; uint64_t scratch; - } s_decode_plte[1]; + } s_decode_plte; struct { uint32_t v_i; uint32_t v_n; uint64_t scratch; - } s_decode_trns[1]; + } s_decode_trns; struct { uint64_t scratch; - } s_do_decode_frame_config[1]; + } s_do_decode_frame_config; struct { uint64_t scratch; - } s_skip_frame[1]; + } s_skip_frame; struct { uint64_t scratch; - } s_do_decode_frame[1]; + } s_do_decode_frame; struct { uint64_t scratch; - } s_decode_pass[1]; + } s_decode_pass; struct { wuffs_base__status v_zlib_status; uint64_t scratch; - } s_do_tell_me_more[1]; + } s_do_tell_me_more; } private_data; #ifdef __cplusplus @@ -11664,11 +12735,6 @@ struct wuffs_png__decoder__struct { return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src); } - inline uint64_t - history_retain_length() const { - return wuffs_png__decoder__history_retain_length(this); - } - inline wuffs_base__range_ii_u64 workbuf_len() const { return wuffs_png__decoder__workbuf_len(this); @@ -11681,24 +12747,21 @@ struct wuffs_png__decoder__struct { #endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes -extern const char wuffs_tga__error__bad_header[]; -extern const char wuffs_tga__error__bad_run_length_encoding[]; -extern const char wuffs_tga__error__truncated_input[]; -extern const char wuffs_tga__error__unsupported_tga_file[]; +extern const char wuffs_qoi__error__bad_footer[]; +extern const char wuffs_qoi__error__bad_header[]; +extern const char wuffs_qoi__error__truncated_input[]; // ---------------- Public Consts -#define WUFFS_TGA__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 - -#define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 +#define WUFFS_QOI__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u // ---------------- Struct Declarations -typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder; +typedef struct wuffs_qoi__decoder__struct wuffs_qoi__decoder; #ifdef __cplusplus extern "C" { @@ -11713,14 +12776,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_tga__decoder__initialize( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__initialize( + wuffs_qoi__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_tga__decoder(void); +sizeof__wuffs_qoi__decoder(void); // ---------------- Allocs @@ -11730,19 +12793,19 @@ sizeof__wuffs_tga__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_tga__decoder* -wuffs_tga__decoder__alloc(void); +wuffs_qoi__decoder* +wuffs_qoi__decoder__alloc(void); static inline wuffs_base__image_decoder* -wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void) { - return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc()); +wuffs_qoi__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_qoi__decoder__alloc()); } // ---------------- Upcasts static inline wuffs_base__image_decoder* -wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder( - wuffs_tga__decoder* p) { +wuffs_qoi__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_qoi__decoder* p) { return (wuffs_base__image_decoder*)p; } @@ -11750,35 +12813,35 @@ wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder( WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__get_quirk( - const wuffs_tga__decoder* self, +wuffs_qoi__decoder__get_quirk( + const wuffs_qoi__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__set_quirk( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__set_quirk( + wuffs_qoi__decoder* self, uint32_t a_key, uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_image_config( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__decode_image_config( + wuffs_qoi__decoder* self, wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_frame_config( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__decode_frame_config( + wuffs_qoi__decoder* self, wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_frame( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__decode_frame( + wuffs_qoi__decoder* self, wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__pixel_blend a_blend, @@ -11787,55 +12850,50 @@ wuffs_tga__decoder__decode_frame( WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_tga__decoder__frame_dirty_rect( - const wuffs_tga__decoder* self); +wuffs_qoi__decoder__frame_dirty_rect( + const wuffs_qoi__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_tga__decoder__num_animation_loops( - const wuffs_tga__decoder* self); +wuffs_qoi__decoder__num_animation_loops( + const wuffs_qoi__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__num_decoded_frame_configs( - const wuffs_tga__decoder* self); +wuffs_qoi__decoder__num_decoded_frame_configs( + const wuffs_qoi__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__num_decoded_frames( - const wuffs_tga__decoder* self); +wuffs_qoi__decoder__num_decoded_frames( + const wuffs_qoi__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__restart_frame( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__restart_frame( + wuffs_qoi__decoder* self, uint64_t a_index, uint64_t a_io_position); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_tga__decoder__set_report_metadata( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__set_report_metadata( + wuffs_qoi__decoder* self, uint32_t a_fourcc, bool a_report); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__tell_me_more( - wuffs_tga__decoder* self, +wuffs_qoi__decoder__tell_me_more( + wuffs_qoi__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__history_retain_length( - const wuffs_tga__decoder* self); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_tga__decoder__workbuf_len( - const wuffs_tga__decoder* self); +wuffs_qoi__decoder__workbuf_len( + const wuffs_qoi__decoder* self); #ifdef __cplusplus } // extern "C" @@ -11850,7 +12908,7 @@ wuffs_tga__decoder__workbuf_len( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_tga__decoder__struct { +struct wuffs_qoi__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -11864,69 +12922,58 @@ struct wuffs_tga__decoder__struct { wuffs_base__vtable vtable_for__wuffs_base__image_decoder; wuffs_base__vtable null_vtable; + uint32_t f_pixfmt; uint32_t f_width; uint32_t f_height; + uint64_t f_remaining_pixels_times_4; uint8_t f_call_sequence; - uint8_t f_header_id_length; - uint8_t f_header_color_map_type; - uint8_t f_header_image_type; - uint16_t f_header_color_map_first_entry_index; - uint16_t f_header_color_map_length; - uint8_t f_header_color_map_entry_size; - uint8_t f_header_pixel_depth; - uint8_t f_header_image_descriptor; - bool f_opaque; - uint32_t f_scratch_bytes_per_pixel; - uint32_t f_src_bytes_per_pixel; - uint32_t f_src_pixfmt; - uint64_t f_frame_config_io_position; + uint32_t f_buffer_index; + uint32_t f_dst_x; + uint32_t f_dst_y; wuffs_base__pixel_swizzler f_swizzler; - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_from_src_to_buffer; } private_impl; struct { - uint8_t f_dst_palette[1024]; - uint8_t f_src_palette[1024]; - uint8_t f_scratch[4]; + uint8_t f_pixel[4]; + uint8_t f_cache[256]; + uint8_t f_buffer[8196]; struct { - uint32_t v_i; uint64_t scratch; - } s_do_decode_image_config[1]; + } s_do_decode_image_config; struct { - uint64_t v_dst_bytes_per_pixel; - uint32_t v_dst_x; - uint32_t v_dst_y; - uint64_t v_mark; - uint32_t v_num_pixels32; - uint32_t v_lit_length; - uint32_t v_run_length; - uint64_t v_num_dst_bytes; uint64_t scratch; - } s_do_decode_frame[1]; + } s_do_decode_frame; + struct { + uint8_t v_dg; + uint32_t v_bi; + uint32_t v_bk; + } s_from_src_to_buffer; } private_data; #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_tga__decoder__alloc()); + return unique_ptr(wuffs_qoi__decoder__alloc()); } static inline wuffs_base__image_decoder::unique_ptr alloc_as__wuffs_base__image_decoder() { return wuffs_base__image_decoder::unique_ptr( - wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder()); + wuffs_qoi__decoder__alloc_as__wuffs_base__image_decoder()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -11942,10 +12989,10 @@ struct wuffs_tga__decoder__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_tga__decoder__struct() = delete; - wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete; - wuffs_tga__decoder__struct& operator=( - const wuffs_tga__decoder__struct&) = delete; + wuffs_qoi__decoder__struct() = delete; + wuffs_qoi__decoder__struct(const wuffs_qoi__decoder__struct&) = delete; + wuffs_qoi__decoder__struct& operator=( + const wuffs_qoi__decoder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -11965,7 +13012,7 @@ struct wuffs_tga__decoder__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_tga__decoder__initialize( + return wuffs_qoi__decoder__initialize( this, sizeof_star_self, wuffs_version, options); } @@ -11977,28 +13024,28 @@ struct wuffs_tga__decoder__struct { inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_tga__decoder__get_quirk(this, a_key); + return wuffs_qoi__decoder__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_tga__decoder__set_quirk(this, a_key, a_value); + return wuffs_qoi__decoder__set_quirk(this, a_key, a_value); } inline wuffs_base__status decode_image_config( wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { - return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src); + return wuffs_qoi__decoder__decode_image_config(this, a_dst, a_src); } inline wuffs_base__status decode_frame_config( wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src) { - return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src); + return wuffs_qoi__decoder__decode_frame_config(this, a_dst, a_src); } inline wuffs_base__status @@ -12008,41 +13055,41 @@ struct wuffs_tga__decoder__struct { wuffs_base__pixel_blend a_blend, wuffs_base__slice_u8 a_workbuf, wuffs_base__decode_frame_options* a_opts) { - return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + return wuffs_qoi__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); } inline wuffs_base__rect_ie_u32 frame_dirty_rect() const { - return wuffs_tga__decoder__frame_dirty_rect(this); + return wuffs_qoi__decoder__frame_dirty_rect(this); } inline uint32_t num_animation_loops() const { - return wuffs_tga__decoder__num_animation_loops(this); + return wuffs_qoi__decoder__num_animation_loops(this); } inline uint64_t num_decoded_frame_configs() const { - return wuffs_tga__decoder__num_decoded_frame_configs(this); + return wuffs_qoi__decoder__num_decoded_frame_configs(this); } inline uint64_t num_decoded_frames() const { - return wuffs_tga__decoder__num_decoded_frames(this); + return wuffs_qoi__decoder__num_decoded_frames(this); } inline wuffs_base__status restart_frame( uint64_t a_index, uint64_t a_io_position) { - return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position); + return wuffs_qoi__decoder__restart_frame(this, a_index, a_io_position); } inline wuffs_base__empty_struct set_report_metadata( uint32_t a_fourcc, bool a_report) { - return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report); + return wuffs_qoi__decoder__set_report_metadata(this, a_fourcc, a_report); } inline wuffs_base__status @@ -12050,42 +13097,30 @@ struct wuffs_tga__decoder__struct { wuffs_base__io_buffer* a_dst, wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src) { - return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src); - } - - inline uint64_t - history_retain_length() const { - return wuffs_tga__decoder__history_retain_length(this); + return wuffs_qoi__decoder__tell_me_more(this, a_dst, a_minfo, a_src); } inline wuffs_base__range_ii_u64 workbuf_len() const { - return wuffs_tga__decoder__workbuf_len(this); + return wuffs_qoi__decoder__workbuf_len(this); } #endif // __cplusplus -}; // struct wuffs_tga__decoder__struct +}; // struct wuffs_qoi__decoder__struct #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes -extern const char wuffs_wbmp__error__bad_header[]; -extern const char wuffs_wbmp__error__truncated_input[]; - // ---------------- Public Consts -#define WUFFS_WBMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0 - -#define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 - // ---------------- Struct Declarations -typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder; +typedef struct wuffs_sha256__hasher__struct wuffs_sha256__hasher; #ifdef __cplusplus extern "C" { @@ -12100,14 +13135,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_wbmp__decoder__initialize( - wuffs_wbmp__decoder* self, +wuffs_sha256__hasher__initialize( + wuffs_sha256__hasher* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_wbmp__decoder(void); +sizeof__wuffs_sha256__hasher(void); // ---------------- Allocs @@ -12117,112 +13152,53 @@ sizeof__wuffs_wbmp__decoder(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_wbmp__decoder* -wuffs_wbmp__decoder__alloc(void); +wuffs_sha256__hasher* +wuffs_sha256__hasher__alloc(void); -static inline wuffs_base__image_decoder* -wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void) { - return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc()); +static inline wuffs_base__hasher_bitvec256* +wuffs_sha256__hasher__alloc_as__wuffs_base__hasher_bitvec256(void) { + return (wuffs_base__hasher_bitvec256*)(wuffs_sha256__hasher__alloc()); } // ---------------- Upcasts -static inline wuffs_base__image_decoder* -wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder( - wuffs_wbmp__decoder* p) { - return (wuffs_base__image_decoder*)p; +static inline wuffs_base__hasher_bitvec256* +wuffs_sha256__hasher__upcast_as__wuffs_base__hasher_bitvec256( + wuffs_sha256__hasher* p) { + return (wuffs_base__hasher_bitvec256*)p; } // ---------------- Public Function Prototypes WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__get_quirk( - const wuffs_wbmp__decoder* self, +wuffs_sha256__hasher__get_quirk( + const wuffs_sha256__hasher* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__set_quirk( - wuffs_wbmp__decoder* self, +wuffs_sha256__hasher__set_quirk( + wuffs_sha256__hasher* self, uint32_t a_key, uint64_t a_value); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_image_config( - wuffs_wbmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_frame_config( - wuffs_wbmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_frame( - wuffs_wbmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_wbmp__decoder__frame_dirty_rect( - const wuffs_wbmp__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_wbmp__decoder__num_animation_loops( - const wuffs_wbmp__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__num_decoded_frame_configs( - const wuffs_wbmp__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__num_decoded_frames( - const wuffs_wbmp__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__restart_frame( - wuffs_wbmp__decoder* self, - uint64_t a_index, - uint64_t a_io_position); - WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_wbmp__decoder__set_report_metadata( - wuffs_wbmp__decoder* self, - uint32_t a_fourcc, - bool a_report); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__tell_me_more( - wuffs_wbmp__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src); +wuffs_sha256__hasher__update( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__history_retain_length( - const wuffs_wbmp__decoder* self); +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_sha256__hasher__update_bitvec256( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_wbmp__decoder__workbuf_len( - const wuffs_wbmp__decoder* self); +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_sha256__hasher__checksum_bitvec256( + const wuffs_sha256__hasher* self); #ifdef __cplusplus } // extern "C" @@ -12237,7 +13213,7 @@ wuffs_wbmp__decoder__workbuf_len( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_wbmp__decoder__struct { +struct wuffs_sha256__hasher__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -12248,52 +13224,41 @@ struct wuffs_wbmp__decoder__struct { struct { uint32_t magic; uint32_t active_coroutine; - wuffs_base__vtable vtable_for__wuffs_base__image_decoder; + wuffs_base__vtable vtable_for__wuffs_base__hasher_bitvec256; wuffs_base__vtable null_vtable; - uint32_t f_width; - uint32_t f_height; - uint8_t f_call_sequence; - uint64_t f_frame_config_io_position; - wuffs_base__pixel_swizzler f_swizzler; - - uint32_t p_decode_image_config[1]; - uint32_t p_do_decode_image_config[1]; - uint32_t p_decode_frame_config[1]; - uint32_t p_do_decode_frame_config[1]; - uint32_t p_decode_frame[1]; - uint32_t p_do_decode_frame[1]; + uint64_t f_length_modulo_u64; + bool f_length_overflows_u64; + uint8_t f_padding0; + uint8_t f_padding1; + uint8_t f_padding2; + uint32_t f_buf_len; + uint8_t f_buf_data[64]; + uint32_t f_h0; + uint32_t f_h1; + uint32_t f_h2; + uint32_t f_h3; + uint32_t f_h4; + uint32_t f_h5; + uint32_t f_h6; + uint32_t f_h7; } private_impl; - struct { - struct { - uint32_t v_i; - uint32_t v_p; - } s_do_decode_image_config[1]; - struct { - uint64_t v_dst_bytes_per_pixel; - uint32_t v_dst_x; - uint32_t v_dst_y; - uint8_t v_src[1]; - uint8_t v_c; - } s_do_decode_frame[1]; - } private_data; - #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_wbmp__decoder__alloc()); + return unique_ptr(wuffs_sha256__hasher__alloc()); } - static inline wuffs_base__image_decoder::unique_ptr - alloc_as__wuffs_base__image_decoder() { - return wuffs_base__image_decoder::unique_ptr( - wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder()); + static inline wuffs_base__hasher_bitvec256::unique_ptr + alloc_as__wuffs_base__hasher_bitvec256() { + return wuffs_base__hasher_bitvec256::unique_ptr( + wuffs_sha256__hasher__alloc_as__wuffs_base__hasher_bitvec256()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -12309,10 +13274,10 @@ struct wuffs_wbmp__decoder__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_wbmp__decoder__struct() = delete; - wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete; - wuffs_wbmp__decoder__struct& operator=( - const wuffs_wbmp__decoder__struct&) = delete; + wuffs_sha256__hasher__struct() = delete; + wuffs_sha256__hasher__struct(const wuffs_sha256__hasher__struct&) = delete; + wuffs_sha256__hasher__struct& operator=( + const wuffs_sha256__hasher__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -12332,120 +13297,68 @@ struct wuffs_wbmp__decoder__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_wbmp__decoder__initialize( + return wuffs_sha256__hasher__initialize( this, sizeof_star_self, wuffs_version, options); } - inline wuffs_base__image_decoder* - upcast_as__wuffs_base__image_decoder() { - return (wuffs_base__image_decoder*)this; + inline wuffs_base__hasher_bitvec256* + upcast_as__wuffs_base__hasher_bitvec256() { + return (wuffs_base__hasher_bitvec256*)this; } inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_wbmp__decoder__get_quirk(this, a_key); + return wuffs_sha256__hasher__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_wbmp__decoder__set_quirk(this, a_key, a_value); - } - - inline wuffs_base__status - decode_image_config( - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src); - } - - inline wuffs_base__status - decode_frame_config( - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src); - } - - inline wuffs_base__status - decode_frame( - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); - } - - inline wuffs_base__rect_ie_u32 - frame_dirty_rect() const { - return wuffs_wbmp__decoder__frame_dirty_rect(this); - } - - inline uint32_t - num_animation_loops() const { - return wuffs_wbmp__decoder__num_animation_loops(this); - } - - inline uint64_t - num_decoded_frame_configs() const { - return wuffs_wbmp__decoder__num_decoded_frame_configs(this); - } - - inline uint64_t - num_decoded_frames() const { - return wuffs_wbmp__decoder__num_decoded_frames(this); - } - - inline wuffs_base__status - restart_frame( - uint64_t a_index, - uint64_t a_io_position) { - return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position); + return wuffs_sha256__hasher__set_quirk(this, a_key, a_value); } inline wuffs_base__empty_struct - set_report_metadata( - uint32_t a_fourcc, - bool a_report) { - return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report); - } - - inline wuffs_base__status - tell_me_more( - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src); + update( + wuffs_base__slice_u8 a_x) { + return wuffs_sha256__hasher__update(this, a_x); } - inline uint64_t - history_retain_length() const { - return wuffs_wbmp__decoder__history_retain_length(this); + inline wuffs_base__bitvec256 + update_bitvec256( + wuffs_base__slice_u8 a_x) { + return wuffs_sha256__hasher__update_bitvec256(this, a_x); } - inline wuffs_base__range_ii_u64 - workbuf_len() const { - return wuffs_wbmp__decoder__workbuf_len(this); + inline wuffs_base__bitvec256 + checksum_bitvec256() const { + return wuffs_sha256__hasher__checksum_bitvec256(this); } #endif // __cplusplus -}; // struct wuffs_wbmp__decoder__struct +}; // struct wuffs_sha256__hasher__struct #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes +extern const char wuffs_tga__error__bad_header[]; +extern const char wuffs_tga__error__bad_run_length_encoding[]; +extern const char wuffs_tga__error__truncated_input[]; +extern const char wuffs_tga__error__unsupported_tga_file[]; + // ---------------- Public Consts +#define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u + // ---------------- Struct Declarations -typedef struct wuffs_xxhash32__hasher__struct wuffs_xxhash32__hasher; +typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder; #ifdef __cplusplus extern "C" { @@ -12460,14 +13373,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_xxhash32__hasher__initialize( - wuffs_xxhash32__hasher* self, +wuffs_tga__decoder__initialize( + wuffs_tga__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_xxhash32__hasher(void); +sizeof__wuffs_tga__decoder(void); // ---------------- Allocs @@ -12477,53 +13390,107 @@ sizeof__wuffs_xxhash32__hasher(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_xxhash32__hasher* -wuffs_xxhash32__hasher__alloc(void); +wuffs_tga__decoder* +wuffs_tga__decoder__alloc(void); -static inline wuffs_base__hasher_u32* -wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void) { - return (wuffs_base__hasher_u32*)(wuffs_xxhash32__hasher__alloc()); +static inline wuffs_base__image_decoder* +wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc()); } // ---------------- Upcasts -static inline wuffs_base__hasher_u32* -wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32( - wuffs_xxhash32__hasher* p) { - return (wuffs_base__hasher_u32*)p; +static inline wuffs_base__image_decoder* +wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_tga__decoder* p) { + return (wuffs_base__image_decoder*)p; } // ---------------- Public Function Prototypes WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash32__hasher__get_quirk( - const wuffs_xxhash32__hasher* self, +wuffs_tga__decoder__get_quirk( + const wuffs_tga__decoder* self, uint32_t a_key); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_xxhash32__hasher__set_quirk( - wuffs_xxhash32__hasher* self, +wuffs_tga__decoder__set_quirk( + wuffs_tga__decoder* self, uint32_t a_key, uint64_t a_value); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_xxhash32__hasher__update( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x); +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_image_config( + wuffs_tga__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_xxhash32__hasher__update_u32( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x); +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_frame_config( + wuffs_tga__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_frame( + wuffs_tga__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_tga__decoder__frame_dirty_rect( + const wuffs_tga__decoder* self); WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_xxhash32__hasher__checksum_u32( - const wuffs_xxhash32__hasher* self); +wuffs_tga__decoder__num_animation_loops( + const wuffs_tga__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_tga__decoder__num_decoded_frame_configs( + const wuffs_tga__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_tga__decoder__num_decoded_frames( + const wuffs_tga__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__restart_frame( + wuffs_tga__decoder* self, + uint64_t a_index, + uint64_t a_io_position); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_tga__decoder__set_report_metadata( + wuffs_tga__decoder* self, + uint32_t a_fourcc, + bool a_report); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__tell_me_more( + wuffs_tga__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_tga__decoder__workbuf_len( + const wuffs_tga__decoder* self); #ifdef __cplusplus } // extern "C" @@ -12538,7 +13505,7 @@ wuffs_xxhash32__hasher__checksum_u32( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_xxhash32__hasher__struct { +struct wuffs_tga__decoder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -12549,36 +13516,72 @@ struct wuffs_xxhash32__hasher__struct { struct { uint32_t magic; uint32_t active_coroutine; - wuffs_base__vtable vtable_for__wuffs_base__hasher_u32; + wuffs_base__vtable vtable_for__wuffs_base__image_decoder; wuffs_base__vtable null_vtable; - uint32_t f_length_modulo_u32; - bool f_length_overflows_u32; - uint8_t f_padding0; - uint8_t f_padding1; - uint8_t f_buf_len; - uint8_t f_buf_data[16]; - uint32_t f_v0; - uint32_t f_v1; - uint32_t f_v2; - uint32_t f_v3; + uint32_t f_width; + uint32_t f_height; + uint8_t f_call_sequence; + uint8_t f_header_id_length; + uint8_t f_header_color_map_type; + uint8_t f_header_image_type; + uint16_t f_header_color_map_first_entry_index; + uint16_t f_header_color_map_length; + uint8_t f_header_color_map_entry_size; + uint8_t f_header_pixel_depth; + uint8_t f_header_image_descriptor; + bool f_opaque; + uint32_t f_scratch_bytes_per_pixel; + uint32_t f_src_bytes_per_pixel; + uint32_t f_src_pixfmt; + uint64_t f_frame_config_io_position; + wuffs_base__pixel_swizzler f_swizzler; + + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; } private_impl; + struct { + uint8_t f_dst_palette[1024]; + uint8_t f_src_palette[1024]; + uint8_t f_scratch[4]; + + struct { + uint32_t v_i; + uint64_t scratch; + } s_do_decode_image_config; + struct { + uint64_t v_dst_bytes_per_pixel; + uint32_t v_dst_x; + uint32_t v_dst_y; + uint64_t v_mark; + uint32_t v_num_pixels32; + uint32_t v_lit_length; + uint32_t v_run_length; + uint64_t v_num_dst_bytes; + uint64_t scratch; + } s_do_decode_frame; + } private_data; + #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_xxhash32__hasher__alloc()); + return unique_ptr(wuffs_tga__decoder__alloc()); } - static inline wuffs_base__hasher_u32::unique_ptr - alloc_as__wuffs_base__hasher_u32() { - return wuffs_base__hasher_u32::unique_ptr( - wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32()); + static inline wuffs_base__image_decoder::unique_ptr + alloc_as__wuffs_base__image_decoder() { + return wuffs_base__image_decoder::unique_ptr( + wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -12594,10 +13597,10 @@ struct wuffs_xxhash32__hasher__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_xxhash32__hasher__struct() = delete; - wuffs_xxhash32__hasher__struct(const wuffs_xxhash32__hasher__struct&) = delete; - wuffs_xxhash32__hasher__struct& operator=( - const wuffs_xxhash32__hasher__struct&) = delete; + wuffs_tga__decoder__struct() = delete; + wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete; + wuffs_tga__decoder__struct& operator=( + const wuffs_tga__decoder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -12617,53 +13620,107 @@ struct wuffs_xxhash32__hasher__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_xxhash32__hasher__initialize( + return wuffs_tga__decoder__initialize( this, sizeof_star_self, wuffs_version, options); } - inline wuffs_base__hasher_u32* - upcast_as__wuffs_base__hasher_u32() { - return (wuffs_base__hasher_u32*)this; + inline wuffs_base__image_decoder* + upcast_as__wuffs_base__image_decoder() { + return (wuffs_base__image_decoder*)this; } inline uint64_t get_quirk( uint32_t a_key) const { - return wuffs_xxhash32__hasher__get_quirk(this, a_key); + return wuffs_tga__decoder__get_quirk(this, a_key); } inline wuffs_base__status set_quirk( uint32_t a_key, uint64_t a_value) { - return wuffs_xxhash32__hasher__set_quirk(this, a_key, a_value); + return wuffs_tga__decoder__set_quirk(this, a_key, a_value); } - inline wuffs_base__empty_struct - update( - wuffs_base__slice_u8 a_x) { - return wuffs_xxhash32__hasher__update(this, a_x); + inline wuffs_base__status + decode_image_config( + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src); } - inline uint32_t - update_u32( - wuffs_base__slice_u8 a_x) { - return wuffs_xxhash32__hasher__update_u32(this, a_x); + inline wuffs_base__status + decode_frame_config( + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src); + } + + inline wuffs_base__status + decode_frame( + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + } + + inline wuffs_base__rect_ie_u32 + frame_dirty_rect() const { + return wuffs_tga__decoder__frame_dirty_rect(this); } inline uint32_t - checksum_u32() const { - return wuffs_xxhash32__hasher__checksum_u32(this); + num_animation_loops() const { + return wuffs_tga__decoder__num_animation_loops(this); + } + + inline uint64_t + num_decoded_frame_configs() const { + return wuffs_tga__decoder__num_decoded_frame_configs(this); + } + + inline uint64_t + num_decoded_frames() const { + return wuffs_tga__decoder__num_decoded_frames(this); + } + + inline wuffs_base__status + restart_frame( + uint64_t a_index, + uint64_t a_io_position) { + return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position); + } + + inline wuffs_base__empty_struct + set_report_metadata( + uint32_t a_fourcc, + bool a_report) { + return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report); + } + + inline wuffs_base__status + tell_me_more( + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src); + } + + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_tga__decoder__workbuf_len(this); } #endif // __cplusplus -}; // struct wuffs_xxhash32__hasher__struct +}; // struct wuffs_tga__decoder__struct #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) || defined(WUFFS_NONMONOLITHIC) // ---------------- Status Codes @@ -12671,7 +13728,7 @@ struct wuffs_xxhash32__hasher__struct { // ---------------- Struct Declarations -typedef struct wuffs_xxhash64__hasher__struct wuffs_xxhash64__hasher; +typedef struct wuffs_vp8__placeholder__struct wuffs_vp8__placeholder; #ifdef __cplusplus extern "C" { @@ -12686,14 +13743,14 @@ extern "C" { // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_xxhash64__hasher__initialize( - wuffs_xxhash64__hasher* self, +wuffs_vp8__placeholder__initialize( + wuffs_vp8__placeholder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options); size_t -sizeof__wuffs_xxhash64__hasher(void); +sizeof__wuffs_vp8__placeholder(void); // ---------------- Allocs @@ -12703,54 +13760,13 @@ sizeof__wuffs_xxhash64__hasher(void); // calling free on the returned pointer. That pointer is effectively a C++ // std::unique_ptr. -wuffs_xxhash64__hasher* -wuffs_xxhash64__hasher__alloc(void); - -static inline wuffs_base__hasher_u64* -wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void) { - return (wuffs_base__hasher_u64*)(wuffs_xxhash64__hasher__alloc()); -} +wuffs_vp8__placeholder* +wuffs_vp8__placeholder__alloc(void); // ---------------- Upcasts -static inline wuffs_base__hasher_u64* -wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64( - wuffs_xxhash64__hasher* p) { - return (wuffs_base__hasher_u64*)p; -} - // ---------------- Public Function Prototypes -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__get_quirk( - const wuffs_xxhash64__hasher* self, - uint32_t a_key); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_xxhash64__hasher__set_quirk( - wuffs_xxhash64__hasher* self, - uint32_t a_key, - uint64_t a_value); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_xxhash64__hasher__update( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__update_u64( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x); - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__checksum_u64( - const wuffs_xxhash64__hasher* self); - #ifdef __cplusplus } // extern "C" #endif @@ -12764,7 +13780,7 @@ wuffs_xxhash64__hasher__checksum_u64( #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -struct wuffs_xxhash64__hasher__struct { +struct wuffs_vp8__placeholder__struct { // Do not access the private_impl's or private_data's fields directly. There // is no API/ABI compatibility or safety guarantee if you do so. Instead, use // the wuffs_foo__bar__baz functions. @@ -12775,37 +13791,20 @@ struct wuffs_xxhash64__hasher__struct { struct { uint32_t magic; uint32_t active_coroutine; - wuffs_base__vtable vtable_for__wuffs_base__hasher_u64; wuffs_base__vtable null_vtable; - uint64_t f_length_modulo_u64; - bool f_length_overflows_u64; - uint8_t f_padding0; - uint8_t f_padding1; - uint8_t f_padding2; - uint32_t f_buf_len; - uint8_t f_buf_data[32]; - uint64_t f_v0; - uint64_t f_v1; - uint64_t f_v2; - uint64_t f_v3; + uint32_t f_placeholder; } private_impl; #ifdef __cplusplus #if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - using unique_ptr = std::unique_ptr; + using unique_ptr = std::unique_ptr; // On failure, the alloc_etc functions return nullptr. They don't throw. static inline unique_ptr alloc() { - return unique_ptr(wuffs_xxhash64__hasher__alloc()); - } - - static inline wuffs_base__hasher_u64::unique_ptr - alloc_as__wuffs_base__hasher_u64() { - return wuffs_base__hasher_u64::unique_ptr( - wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64()); + return unique_ptr(wuffs_vp8__placeholder__alloc()); } #endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -12821,10 +13820,10 @@ struct wuffs_xxhash64__hasher__struct { // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in // order to provide convenience methods. These forward on "this", so that you // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". - wuffs_xxhash64__hasher__struct() = delete; - wuffs_xxhash64__hasher__struct(const wuffs_xxhash64__hasher__struct&) = delete; - wuffs_xxhash64__hasher__struct& operator=( - const wuffs_xxhash64__hasher__struct&) = delete; + wuffs_vp8__placeholder__struct() = delete; + wuffs_vp8__placeholder__struct(const wuffs_vp8__placeholder__struct&) = delete; + wuffs_vp8__placeholder__struct& operator=( + const wuffs_vp8__placeholder__struct&) = delete; #endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) #if !defined(WUFFS_IMPLEMENTATION) @@ -12844,9372 +13843,9377 @@ struct wuffs_xxhash64__hasher__struct { size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options) { - return wuffs_xxhash64__hasher__initialize( + return wuffs_vp8__placeholder__initialize( this, sizeof_star_self, wuffs_version, options); } - inline wuffs_base__hasher_u64* - upcast_as__wuffs_base__hasher_u64() { - return (wuffs_base__hasher_u64*)this; - } +#endif // __cplusplus +}; // struct wuffs_vp8__placeholder__struct - inline uint64_t - get_quirk( - uint32_t a_key) const { - return wuffs_xxhash64__hasher__get_quirk(this, a_key); - } +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - inline wuffs_base__status - set_quirk( - uint32_t a_key, - uint64_t a_value) { - return wuffs_xxhash64__hasher__set_quirk(this, a_key, a_value); - } +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) || defined(WUFFS_NONMONOLITHIC) - inline wuffs_base__empty_struct - update( - wuffs_base__slice_u8 a_x) { - return wuffs_xxhash64__hasher__update(this, a_x); - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC) - inline uint64_t - update_u64( - wuffs_base__slice_u8 a_x) { - return wuffs_xxhash64__hasher__update_u64(this, a_x); - } +// ---------------- Status Codes - inline uint64_t - checksum_u64() const { - return wuffs_xxhash64__hasher__checksum_u64(this); - } +extern const char wuffs_wbmp__error__bad_header[]; +extern const char wuffs_wbmp__error__truncated_input[]; -#endif // __cplusplus -}; // struct wuffs_xxhash64__hasher__struct +// ---------------- Public Consts -#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) +#define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC) +// ---------------- Struct Declarations -#if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR) +typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder; -// ---------------- Auxiliary - Base +#ifdef __cplusplus +extern "C" { +#endif -// Auxiliary code is discussed at -// https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md +// ---------------- Public Initializer Prototypes -#include +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. -#include +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_wbmp__decoder__initialize( + wuffs_wbmp__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); -namespace wuffs_aux { +size_t +sizeof__wuffs_wbmp__decoder(void); -using IOBuffer = wuffs_base__io_buffer; +// ---------------- Allocs -// MemOwner represents ownership of some memory. Dynamically allocated memory -// (e.g. from malloc or new) is typically paired with free or delete, invoked -// when the std::unique_ptr is destroyed. Statically allocated memory might use -// MemOwner(nullptr, &free), even if that statically allocated memory is not -// nullptr, since calling free(nullptr) is a no-op. -using MemOwner = std::unique_ptr; +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. -namespace sync_io { +wuffs_wbmp__decoder* +wuffs_wbmp__decoder__alloc(void); -// -------- +static inline wuffs_base__image_decoder* +wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc()); +} -// DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array. -// It owns that backing array and will free it in its destructor. -// -// The array size can be explicitly extended (by calling the grow method) but, -// unlike a C++ std::vector, there is no implicit extension (e.g. by calling -// std::vector::insert) and its maximum size is capped by the max_incl -// constructor argument. -// -// It contains an IOBuffer-typed field whose reader side provides access to -// previously written bytes and whose writer side provides access to the -// allocated but not-yet-written-to slack space. For Go programmers, this slack -// space is roughly analogous to the s[len(s):cap(s)] space of a slice s. -class DynIOBuffer { - public: - enum GrowResult { - OK = 0, - FailedMaxInclExceeded = 1, - FailedOutOfMemory = 2, - }; +// ---------------- Upcasts - // m_buf holds the dynamically sized byte array and its read/write indexes: - // - m_buf.meta.wi is roughly analogous to a Go slice's length. - // - m_buf.data.len is roughly analogous to a Go slice's capacity. It is - // also equal to the m_buf.data.ptr malloc/realloc size. - // - // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as - // they are conceptually private to this class), but they can modify the - // bytes referenced by that pointer-length pair (e.g. compactions). - IOBuffer m_buf; +static inline wuffs_base__image_decoder* +wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_wbmp__decoder* p) { + return (wuffs_base__image_decoder*)p; +} - // m_max_incl is an inclusive upper bound on the backing array size. - const uint64_t m_max_incl; +// ---------------- Public Function Prototypes - // Constructor and destructor. - explicit DynIOBuffer(uint64_t max_incl); - ~DynIOBuffer(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_wbmp__decoder__get_quirk( + const wuffs_wbmp__decoder* self, + uint32_t a_key); - // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be - // used after a drop call. It just restarts from zero. - void drop(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__set_quirk( + wuffs_wbmp__decoder* self, + uint32_t a_key, + uint64_t a_value); - // grow ensures that the byte array size is at least min_incl and at most - // max_incl. It returns FailedMaxInclExceeded if that would require - // allocating more than max_incl bytes, including the case where (min_incl > - // max_incl). It returns FailedOutOfMemory if memory allocation failed. - GrowResult grow(uint64_t min_incl); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__decode_image_config( + wuffs_wbmp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); - private: - // Delete the copy and assign constructors. - DynIOBuffer(const DynIOBuffer&) = delete; - DynIOBuffer& operator=(const DynIOBuffer&) = delete; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__decode_frame_config( + wuffs_wbmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); - static uint64_t round_up(uint64_t min_incl, uint64_t max_incl); -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__decode_frame( + wuffs_wbmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); -// -------- +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_wbmp__decoder__frame_dirty_rect( + const wuffs_wbmp__decoder* self); -class Input { - public: - virtual ~Input(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_wbmp__decoder__num_animation_loops( + const wuffs_wbmp__decoder* self); - virtual IOBuffer* BringsItsOwnIOBuffer(); - virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length) = 0; -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_wbmp__decoder__num_decoded_frame_configs( + const wuffs_wbmp__decoder* self); -// -------- +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_wbmp__decoder__num_decoded_frames( + const wuffs_wbmp__decoder* self); -// FileInput is an Input that reads from a file source. -// -// It does not take responsibility for closing the file when done. -class FileInput : public Input { - public: - FileInput(FILE* f); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__restart_frame( + wuffs_wbmp__decoder* self, + uint64_t a_index, + uint64_t a_io_position); - virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_wbmp__decoder__set_report_metadata( + wuffs_wbmp__decoder* self, + uint32_t a_fourcc, + bool a_report); - private: - FILE* m_f; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__tell_me_more( + wuffs_wbmp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); - // Delete the copy and assign constructors. - FileInput(const FileInput&) = delete; - FileInput& operator=(const FileInput&) = delete; -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_wbmp__decoder__workbuf_len( + const wuffs_wbmp__decoder* self); -// -------- +#ifdef __cplusplus +} // extern "C" +#endif -// MemoryInput is an Input that reads from an in-memory source. +// ---------------- Struct Definitions + +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. // -// It does not take responsibility for freeing the memory when done. -class MemoryInput : public Input { - public: - MemoryInput(const char* ptr, size_t len); - MemoryInput(const uint8_t* ptr, size_t len); +// See https://en.wikipedia.org/wiki/Opaque_pointer#C - virtual IOBuffer* BringsItsOwnIOBuffer(); - virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length); +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - private: - IOBuffer m_io; +struct wuffs_wbmp__decoder__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. - // Delete the copy and assign constructors. - MemoryInput(const MemoryInput&) = delete; - MemoryInput& operator=(const MemoryInput&) = delete; -}; + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__image_decoder; + wuffs_base__vtable null_vtable; -// -------- + uint32_t f_width; + uint32_t f_height; + uint8_t f_call_sequence; + uint64_t f_frame_config_io_position; + wuffs_base__pixel_swizzler f_swizzler; -} // namespace sync_io + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + } private_impl; -} // namespace wuffs_aux + struct { + struct { + uint32_t v_i; + uint32_t v_p; + } s_do_decode_image_config; + struct { + uint64_t v_dst_bytes_per_pixel; + uint32_t v_dst_x; + uint32_t v_dst_y; + uint8_t v_src[1]; + uint8_t v_c8; + } s_do_decode_frame; + } private_data; -// ---------------- Auxiliary - CBOR +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; -namespace wuffs_aux { + // On failure, the alloc_etc functions return nullptr. They don't throw. -struct DecodeCborResult { - DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0); + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_wbmp__decoder__alloc()); + } - std::string error_message; - uint64_t cursor_position; -}; + static inline wuffs_base__image_decoder::unique_ptr + alloc_as__wuffs_base__image_decoder() { + return wuffs_base__image_decoder::unique_ptr( + wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder()); + } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) -class DecodeCborCallbacks { - public: - virtual ~DecodeCborCallbacks(); +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_wbmp__decoder__struct() = delete; + wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete; + wuffs_wbmp__decoder__struct& operator=( + const wuffs_wbmp__decoder__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) - // AppendXxx are called for leaf nodes: literals, numbers, strings, etc. +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) - virtual std::string AppendNull() = 0; - virtual std::string AppendUndefined() = 0; - virtual std::string AppendBool(bool val) = 0; - virtual std::string AppendF64(double val) = 0; - virtual std::string AppendI64(int64_t val) = 0; - virtual std::string AppendU64(uint64_t val) = 0; - virtual std::string AppendByteString(std::string&& val) = 0; - virtual std::string AppendTextString(std::string&& val) = 0; - virtual std::string AppendMinus1MinusX(uint64_t val) = 0; - virtual std::string AppendCborSimpleValue(uint8_t val) = 0; - virtual std::string AppendCborTag(uint64_t val) = 0; + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_wbmp__decoder__initialize( + this, sizeof_star_self, wuffs_version, options); + } - // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR - // maps (dictionaries). - // - // The flags bits combine exactly one of: - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT - // and exactly one of: - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT + inline wuffs_base__image_decoder* + upcast_as__wuffs_base__image_decoder() { + return (wuffs_base__image_decoder*)this; + } - virtual std::string Push(uint32_t flags) = 0; - virtual std::string Pop(uint32_t flags) = 0; + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_wbmp__decoder__get_quirk(this, a_key); + } - // Done is always the last Callback method called by DecodeCbor, whether or - // not parsing the input as CBOR encountered an error. Even when successful, - // trailing data may remain in input and buffer. - // - // Do not keep a reference to buffer or buffer.data.ptr after Done returns, - // as DecodeCbor may then de-allocate the backing array. - // - // The default Done implementation is a no-op. - virtual void // - Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer); -}; + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_wbmp__decoder__set_quirk(this, a_key, a_value); + } -// The FooArgBar types add structure to Foo's optional arguments. They wrap -// inner representations for several reasons: -// - It provides a home for the DefaultValue static method, for Foo callers -// that want to override some but not all optional arguments. -// - It provides the "Bar" name at Foo call sites, which can help self- -// document Foo calls with many arguemnts. -// - It provides some type safety against accidentally transposing or omitting -// adjacent fundamentally-numeric-typed optional arguments. + inline wuffs_base__status + decode_image_config( + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src); + } -// DecodeCborArgQuirks wraps an optional argument to DecodeCbor. -struct DecodeCborArgQuirks { - explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len); + inline wuffs_base__status + decode_frame_config( + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src); + } - // DefaultValue returns an empty slice. - static DecodeCborArgQuirks DefaultValue(); + inline wuffs_base__status + decode_frame( + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + } - wuffs_base__slice_u32 repr; -}; + inline wuffs_base__rect_ie_u32 + frame_dirty_rect() const { + return wuffs_wbmp__decoder__frame_dirty_rect(this); + } -// DecodeCbor calls callbacks based on the CBOR-formatted data in input. -// -// On success, the returned error_message is empty and cursor_position counts -// the number of bytes consumed. On failure, error_message is non-empty and -// cursor_position is the location of the error. That error may be a content -// error (invalid CBOR) or an input error (e.g. network failure). -DecodeCborResult // -DecodeCbor(DecodeCborCallbacks& callbacks, - sync_io::Input& input, - DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue()); + inline uint32_t + num_animation_loops() const { + return wuffs_wbmp__decoder__num_animation_loops(this); + } -} // namespace wuffs_aux + inline uint64_t + num_decoded_frame_configs() const { + return wuffs_wbmp__decoder__num_decoded_frame_configs(this); + } -// ---------------- Auxiliary - Image + inline uint64_t + num_decoded_frames() const { + return wuffs_wbmp__decoder__num_decoded_frames(this); + } -namespace wuffs_aux { + inline wuffs_base__status + restart_frame( + uint64_t a_index, + uint64_t a_io_position) { + return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position); + } -struct DecodeImageResult { - DecodeImageResult(MemOwner&& pixbuf_mem_owner0, - wuffs_base__pixel_buffer pixbuf0, - std::string&& error_message0); - DecodeImageResult(std::string&& error_message0); + inline wuffs_base__empty_struct + set_report_metadata( + uint32_t a_fourcc, + bool a_report) { + return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report); + } - MemOwner pixbuf_mem_owner; - wuffs_base__pixel_buffer pixbuf; - std::string error_message; -}; + inline wuffs_base__status + tell_me_more( + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src); + } -// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always -// called in this order: -// 1. SelectDecoder -// 2. HandleMetadata -// 3. SelectPixfmt -// 4. AllocPixbuf -// 5. AllocWorkbuf -// 6. Done -// -// It may return early - the third callback might not be invoked if the second -// one fails - but the final callback (Done) is always invoked. -class DecodeImageCallbacks { - public: - // AllocPixbufResult holds a memory allocation (the result of malloc or new, - // a statically allocated pointer, etc), or an error message. The memory is - // de-allocated when mem_owner goes out of scope and is destroyed. - struct AllocPixbufResult { - AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0); - AllocPixbufResult(std::string&& error_message0); + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_wbmp__decoder__workbuf_len(this); + } - MemOwner mem_owner; - wuffs_base__pixel_buffer pixbuf; - std::string error_message; - }; +#endif // __cplusplus +}; // struct wuffs_wbmp__decoder__struct - // AllocWorkbufResult holds a memory allocation (the result of malloc or new, - // a statically allocated pointer, etc), or an error message. The memory is - // de-allocated when mem_owner goes out of scope and is destroyed. - struct AllocWorkbufResult { - AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0); - AllocWorkbufResult(std::string&& error_message0); +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - MemOwner mem_owner; - wuffs_base__slice_u8 workbuf; - std::string error_message; - }; +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC) - virtual ~DecodeImageCallbacks(); +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) || defined(WUFFS_NONMONOLITHIC) - // SelectDecoder returns the image decoder for the input data's file format. - // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat). - // - // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF], - // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs' - // standard library did not recognize the image format but if SelectDecoder - // was overridden, it may examine the input data's starting bytes and still - // provide its own image decoder, e.g. for an exotic image file format that's - // not in Wuffs' standard library. The prefix_etc fields have the same - // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder - // implementations should not modify prefix_data's contents. - // - // SelectDecoder might be called more than once, since some image file - // formats can wrap others. For example, a nominal BMP file can actually - // contain a JPEG or a PNG. - // - // The default SelectDecoder accepts the FOURCC codes listed below. For - // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance - // of the ETC file format is optional (for each value of ETC) and depends on - // the corresponding module to be enabled at compile time (i.e. #define'ing - // WUFFS_CONFIG__MODULE__ETC). - // - WUFFS_BASE__FOURCC__BMP - // - WUFFS_BASE__FOURCC__GIF - // - WUFFS_BASE__FOURCC__JPEG - // - WUFFS_BASE__FOURCC__NIE - // - WUFFS_BASE__FOURCC__NPBM - // - WUFFS_BASE__FOURCC__PNG - // - WUFFS_BASE__FOURCC__TGA - // - WUFFS_BASE__FOURCC__WBMP - virtual wuffs_base__image_decoder::unique_ptr // - SelectDecoder(uint32_t fourcc, - wuffs_base__slice_u8 prefix_data, - bool prefix_closed); - - // HandleMetadata acknowledges image metadata. minfo.flavor will be one of: - // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH - // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED - // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those - // bytes should not be retained beyond the the HandleMetadata call. - // - // minfo.metadata__fourcc() will typically match one of the - // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM | - // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC - // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA. - // - // It returns an error message, or an empty string on success. - virtual std::string // - HandleMetadata(const wuffs_base__more_information& minfo, - wuffs_base__slice_u8 raw); - - // SelectPixfmt returns the destination pixel format for AllocPixbuf. It - // should return wuffs_base__make_pixel_format(etc) called with one of: - // - WUFFS_BASE__PIXEL_FORMAT__BGR_565 - // - WUFFS_BASE__PIXEL_FORMAT__BGR - // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL - // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE - // - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL - // - WUFFS_BASE__PIXEL_FORMAT__RGB - // - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL - // - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL - // or return image_config.pixcfg.pixel_format(). The latter means to use the - // image file's natural pixel format. For example, GIF images' natural pixel - // format is an indexed one. - // - // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat). - // - // The default SelectPixfmt implementation returns - // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which - // is 4 bytes per pixel (8 bits per channel × 4 channels). - virtual wuffs_base__pixel_format // - SelectPixfmt(const wuffs_base__image_config& image_config); +// ---------------- Status Codes - // AllocPixbuf allocates the pixel buffer. - // - // allow_uninitialized_memory will be true if a valid background_color was - // passed to DecodeImage, since the pixel buffer's contents will be - // overwritten with that color after AllocPixbuf returns. - // - // The default AllocPixbuf implementation allocates either uninitialized or - // zeroed memory. Zeroed memory typically corresponds to filling with opaque - // black or transparent black, depending on the pixel format. - virtual AllocPixbufResult // - AllocPixbuf(const wuffs_base__image_config& image_config, - bool allow_uninitialized_memory); +extern const char wuffs_webp__error__bad_huffman_code_over_subscribed[]; +extern const char wuffs_webp__error__bad_huffman_code_under_subscribed[]; +extern const char wuffs_webp__error__bad_huffman_code[]; +extern const char wuffs_webp__error__bad_back_reference[]; +extern const char wuffs_webp__error__bad_color_cache[]; +extern const char wuffs_webp__error__bad_header[]; +extern const char wuffs_webp__error__bad_transform[]; +extern const char wuffs_webp__error__short_chunk[]; +extern const char wuffs_webp__error__truncated_input[]; +extern const char wuffs_webp__error__unsupported_number_of_huffman_groups[]; +extern const char wuffs_webp__error__unsupported_transform_after_color_indexing_transform[]; +extern const char wuffs_webp__error__unsupported_webp_file[]; - // AllocWorkbuf allocates the work buffer. The allocated buffer's length - // should be at least len_range.min_incl, but larger allocations (up to - // len_range.max_incl) may have better performance (by using more memory). - // - // The default AllocWorkbuf implementation allocates len_range.max_incl bytes - // of either uninitialized or zeroed memory. - virtual AllocWorkbufResult // - AllocWorkbuf(wuffs_base__range_ii_u64 len_range, - bool allow_uninitialized_memory); +// ---------------- Public Consts - // Done is always the last Callback method called by DecodeImage, whether or - // not parsing the input encountered an error. Even when successful, trailing - // data may remain in input and buffer. - // - // The image_decoder is the one returned by SelectDecoder (if SelectDecoder - // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr, - // ownership moves to the Done implementation. - // - // Do not keep a reference to buffer or buffer.data.ptr after Done returns, - // as DecodeImage may then de-allocate the backing array. - // - // The default Done implementation is a no-op, other than running the - // image_decoder unique_ptr destructor. - virtual void // - Done(DecodeImageResult& result, - sync_io::Input& input, - IOBuffer& buffer, - wuffs_base__image_decoder::unique_ptr image_decoder); -}; +#define WUFFS_WEBP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0u -extern const char DecodeImage_BufferIsTooShort[]; -extern const char DecodeImage_MaxInclDimensionExceeded[]; -extern const char DecodeImage_MaxInclMetadataLengthExceeded[]; -extern const char DecodeImage_OutOfMemory[]; -extern const char DecodeImage_UnexpectedEndOfFile[]; -extern const char DecodeImage_UnsupportedImageFormat[]; -extern const char DecodeImage_UnsupportedMetadata[]; -extern const char DecodeImage_UnsupportedPixelBlend[]; -extern const char DecodeImage_UnsupportedPixelConfiguration[]; -extern const char DecodeImage_UnsupportedPixelFormat[]; +// ---------------- Struct Declarations -// The FooArgBar types add structure to Foo's optional arguments. They wrap -// inner representations for several reasons: -// - It provides a home for the DefaultValue static method, for Foo callers -// that want to override some but not all optional arguments. -// - It provides the "Bar" name at Foo call sites, which can help self- -// document Foo calls with many arguemnts. -// - It provides some type safety against accidentally transposing or omitting -// adjacent fundamentally-numeric-typed optional arguments. +typedef struct wuffs_webp__decoder__struct wuffs_webp__decoder; -// DecodeImageArgQuirks wraps an optional argument to DecodeImage. -struct DecodeImageArgQuirks { - explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len); +#ifdef __cplusplus +extern "C" { +#endif - // DefaultValue returns an empty slice. - static DecodeImageArgQuirks DefaultValue(); +// ---------------- Public Initializer Prototypes - wuffs_base__slice_u32 repr; -}; +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. -// DecodeImageArgFlags wraps an optional argument to DecodeImage. -struct DecodeImageArgFlags { - explicit DecodeImageArgFlags(uint64_t repr0); +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_webp__decoder__initialize( + wuffs_webp__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); - // DefaultValue returns 0. - static DecodeImageArgFlags DefaultValue(); +size_t +sizeof__wuffs_webp__decoder(void); - // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF, - // GAMA, ICCP, KVP, SRGB and XMP. +// ---------------- Allocs - // Background Color. - static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001; - // Primary Chromaticities and White Point. - static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002; - // Exchangeable Image File Format. - static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004; - // Gamma Correction. - static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008; - // International Color Consortium Profile. - static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010; - // Key-Value Pair. - // - // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the - // HandleMetadata callback, the raw argument contains UTF-8 strings. - static constexpr uint64_t REPORT_METADATA_KVP = 0x0020; - // Modification Time. - static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040; - // Offset (2-Dimensional). - static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080; - // Physical Dimensions. - static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100; - // Standard Red Green Blue (Rendering Intent). - static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200; - // Extensible Metadata Platform. - static constexpr uint64_t REPORT_METADATA_XMP = 0x0400; +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. - uint64_t repr; -}; +wuffs_webp__decoder* +wuffs_webp__decoder__alloc(void); -// DecodeImageArgPixelBlend wraps an optional argument to DecodeImage. -struct DecodeImageArgPixelBlend { - explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0); +static inline wuffs_base__image_decoder* +wuffs_webp__decoder__alloc_as__wuffs_base__image_decoder(void) { + return (wuffs_base__image_decoder*)(wuffs_webp__decoder__alloc()); +} - // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC. - static DecodeImageArgPixelBlend DefaultValue(); +// ---------------- Upcasts - wuffs_base__pixel_blend repr; -}; +static inline wuffs_base__image_decoder* +wuffs_webp__decoder__upcast_as__wuffs_base__image_decoder( + wuffs_webp__decoder* p) { + return (wuffs_base__image_decoder*)p; +} -// DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage. -struct DecodeImageArgBackgroundColor { - explicit DecodeImageArgBackgroundColor( - wuffs_base__color_u32_argb_premul repr0); +// ---------------- Public Function Prototypes - // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul. - static DecodeImageArgBackgroundColor DefaultValue(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_webp__decoder__get_quirk( + const wuffs_webp__decoder* self, + uint32_t a_key); - wuffs_base__color_u32_argb_premul repr; -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__set_quirk( + wuffs_webp__decoder* self, + uint32_t a_key, + uint64_t a_value); -// DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage. -struct DecodeImageArgMaxInclDimension { - explicit DecodeImageArgMaxInclDimension(uint32_t repr0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__decode_image_config( + wuffs_webp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); - // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels. - static DecodeImageArgMaxInclDimension DefaultValue(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__decode_frame_config( + wuffs_webp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); - uint32_t repr; -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__decode_frame( + wuffs_webp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); -// DecodeImageArgMaxInclMetadataLength wraps an optional argument to -// DecodeImage. -struct DecodeImageArgMaxInclMetadataLength { - explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_webp__decoder__frame_dirty_rect( + const wuffs_webp__decoder* self); - // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB. - static DecodeImageArgMaxInclMetadataLength DefaultValue(); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_webp__decoder__num_animation_loops( + const wuffs_webp__decoder* self); - uint64_t repr; -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_webp__decoder__num_decoded_frame_configs( + const wuffs_webp__decoder* self); -// DecodeImage decodes the image data in input. A variety of image file formats -// can be decoded, depending on what callbacks.SelectDecoder returns. -// -// For animated formats, only the first frame is returned, since the API is -// simpler for synchronous I/O and having DecodeImage only return when -// completely done, but rendering animation often involves handling other -// events in between animation frames. To decode multiple frames of animated -// images, or for asynchronous I/O (e.g. when decoding an image streamed over -// the network), use Wuffs' lower level C API instead of its higher level, -// simplified C++ API (the wuffs_aux API). -// -// The DecodeImageResult's fields depend on whether decoding succeeded: -// - On total success, the error_message is empty and pixbuf.pixcfg.is_valid() -// is true. -// - On partial success (e.g. the input file was truncated but we are still -// able to decode some of the pixels), error_message is non-empty but -// pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to -// accept or reject partial success. -// - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid() -// is false. -// -// The callbacks allocate the pixel buffer memory and work buffer memory. On -// success, pixel buffer memory ownership is passed to the DecodeImage caller -// as the returned pixbuf_mem_owner. Regardless of success or failure, the work -// buffer memory is deleted. -// -// The pixel_blend (one of the constants listed below) determines how to -// composite the decoded image over the pixel buffer's original pixels (as -// returned by callbacks.AllocPixbuf): -// - WUFFS_BASE__PIXEL_BLEND__SRC -// - WUFFS_BASE__PIXEL_BLEND__SRC_OVER -// -// The background_color is used to fill the pixel buffer after -// callbacks.AllocPixbuf returns, if it is valid in the -// wuffs_base__color_u32_argb_premul__is_valid sense. The default value, -// 0x0000_0001, is not valid since its Blue channel value (0x01) is greater -// than its Alpha channel value (0x00). A valid background_color will typically -// be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might -// still be visible on partial (not total) success or when pixel_blend is -// WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque. -// -// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's -// width or height is greater than max_incl_dimension or if any opted-in (via -// flags bits) metadata is longer than max_incl_metadata_length. -DecodeImageResult // -DecodeImage(DecodeImageCallbacks& callbacks, - sync_io::Input& input, - DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(), - DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(), - DecodeImageArgPixelBlend pixel_blend = - DecodeImageArgPixelBlend::DefaultValue(), - DecodeImageArgBackgroundColor background_color = - DecodeImageArgBackgroundColor::DefaultValue(), - DecodeImageArgMaxInclDimension max_incl_dimension = - DecodeImageArgMaxInclDimension::DefaultValue(), - DecodeImageArgMaxInclMetadataLength max_incl_metadata_length = - DecodeImageArgMaxInclMetadataLength::DefaultValue()); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_webp__decoder__num_decoded_frames( + const wuffs_webp__decoder* self); -} // namespace wuffs_aux +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__restart_frame( + wuffs_webp__decoder* self, + uint64_t a_index, + uint64_t a_io_position); -// ---------------- Auxiliary - JSON +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_webp__decoder__set_report_metadata( + wuffs_webp__decoder* self, + uint32_t a_fourcc, + bool a_report); -namespace wuffs_aux { +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_webp__decoder__tell_me_more( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); -struct DecodeJsonResult { - DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_webp__decoder__workbuf_len( + const wuffs_webp__decoder* self); - std::string error_message; - uint64_t cursor_position; -}; +#ifdef __cplusplus +} // extern "C" +#endif -class DecodeJsonCallbacks { - public: - virtual ~DecodeJsonCallbacks(); +// ---------------- Struct Definitions - // AppendXxx are called for leaf nodes: literals, numbers and strings. For - // strings, the Callbacks implementation is responsible for tracking map keys - // versus other values. +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C - virtual std::string AppendNull() = 0; - virtual std::string AppendBool(bool val) = 0; - virtual std::string AppendF64(double val) = 0; - virtual std::string AppendI64(int64_t val) = 0; - virtual std::string AppendTextString(std::string&& val) = 0; +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - // Push and Pop are called for container nodes: JSON arrays (lists) and JSON - // objects (dictionaries). +struct wuffs_webp__decoder__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. // - // The flags bits combine exactly one of: - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT - // and exactly one of: - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST - // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. - virtual std::string Push(uint32_t flags) = 0; - virtual std::string Pop(uint32_t flags) = 0; + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__image_decoder; + wuffs_base__vtable null_vtable; - // Done is always the last Callback method called by DecodeJson, whether or - // not parsing the input as JSON encountered an error. Even when successful, - // trailing data may remain in input and buffer. See "Unintuitive JSON - // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON - // parsing and when it stops. - // - // Do not keep a reference to buffer or buffer.data.ptr after Done returns, - // as DecodeJson may then de-allocate the backing array. - // - // The default Done implementation is a no-op. - virtual void // - Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer); -}; + uint32_t f_pixfmt; + uint32_t f_width; + uint32_t f_height; + uint8_t f_call_sequence; + uint8_t f_code_length_code_lengths[19]; + bool f_sub_chunk_has_padding; + uint64_t f_frame_config_io_position; + uint32_t f_riff_chunk_length; + uint32_t f_sub_chunk_length; + uint32_t f_bits; + uint32_t f_n_bits; + bool f_seen_transform[4]; + uint8_t f_transform_type[4]; + uint8_t f_transform_tile_size_log2[4]; + uint32_t f_n_transforms; + uint32_t f_color_cache_bits; + uint32_t f_overall_color_cache_bits; + uint32_t f_overall_tile_size_log2; + uint32_t f_overall_n_huffman_groups; + uint32_t f_ht_n_symbols; + uint32_t f_ht_code_lengths_remaining; + uint32_t f_color_indexing_palette_size; + uint32_t f_color_indexing_width; + uint32_t f_workbuf_offset_for_transform[4]; + uint32_t f_workbuf_offset_for_color_indexing; + wuffs_base__pixel_swizzler f_swizzler; -extern const char DecodeJson_BadJsonPointer[]; -extern const char DecodeJson_NoMatch[]; + uint32_t p_decode_huffman_groups; + uint32_t p_decode_huffman_tree; + uint32_t p_decode_huffman_tree_simple; + uint32_t p_decode_code_length_code_lengths; + uint32_t p_build_code_lengths; + uint32_t p_decode_pixels_slow; + uint32_t p_decode_image_config; + uint32_t p_do_decode_image_config; + uint32_t p_do_decode_image_config_limited; + uint32_t p_do_decode_image_config_limited_vp8l; + uint32_t p_decode_frame_config; + uint32_t p_do_decode_frame_config; + uint32_t p_decode_frame; + uint32_t p_do_decode_frame; + uint32_t p_decode_transform; + uint32_t p_decode_color_cache_parameters; + uint32_t p_decode_hg_table; + uint32_t p_decode_pixels; + } private_impl; -// The FooArgBar types add structure to Foo's optional arguments. They wrap -// inner representations for several reasons: -// - It provides a home for the DefaultValue static method, for Foo callers -// that want to override some but not all optional arguments. -// - It provides the "Bar" name at Foo call sites, which can help self- -// document Foo calls with many arguemnts. -// - It provides some type safety against accidentally transposing or omitting -// adjacent fundamentally-numeric-typed optional arguments. + struct { + uint8_t f_palette[1024]; + uint32_t f_color_cache[2048]; + uint16_t f_codes[2328]; + uint16_t f_code_lengths[2328]; + uint16_t f_code_lengths_huffman_nodes[37]; + uint16_t f_huffman_nodes[256][6267]; -// DecodeJsonArgQuirks wraps an optional argument to DecodeJson. -struct DecodeJsonArgQuirks { - explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0); - explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len); + struct { + uint32_t v_hg; + uint32_t v_ht; + } s_decode_huffman_groups; + struct { + uint32_t v_use_second_symbol; + uint32_t v_first_symbol_n_bits; + uint32_t v_symbol0; + uint32_t v_base_offset; + } s_decode_huffman_tree_simple; + struct { + uint32_t v_n_codes; + uint32_t v_i; + } s_decode_code_length_code_lengths; + struct { + uint32_t v_length_n_bits; + uint16_t v_prev_code_length; + uint32_t v_s; + uint32_t v_s_max; + uint16_t v_node; + uint16_t v_repeat_value; + uint32_t v_repeat_n_bits; + } s_build_code_lengths; + struct { + uint64_t v_p; + uint64_t v_p_max; + uint32_t v_tile_size_log2; + uint32_t v_width_in_tiles; + uint32_t v_x; + uint32_t v_y; + uint32_t v_hg; + uint16_t v_node; + uint32_t v_color; + uint32_t v_back_ref_len_n_bits; + uint32_t v_back_ref_len_minus_1; + uint32_t v_back_ref_dist_n_bits; + uint32_t v_back_ref_dist_premap_minus_1; + uint64_t v_color_cache_p; + } s_decode_pixels_slow; + struct { + uint64_t scratch; + } s_do_decode_image_config; + struct { + uint64_t scratch; + } s_do_decode_image_config_limited; + struct { + uint64_t scratch; + } s_do_decode_image_config_limited_vp8l; + struct { + uint32_t v_width; + } s_do_decode_frame; + struct { + uint32_t v_transform_type; + uint32_t v_tile_size_log2; + } s_decode_transform; + struct { + uint32_t v_tile_size_log2; + } s_decode_hg_table; + } private_data; - // DefaultValue returns an empty slice. - static DecodeJsonArgQuirks DefaultValue(); +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; - wuffs_base__slice_u32 repr; -}; + // On failure, the alloc_etc functions return nullptr. They don't throw. -// DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson. -struct DecodeJsonArgJsonPointer { - explicit DecodeJsonArgJsonPointer(std::string repr0); + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_webp__decoder__alloc()); + } - // DefaultValue returns an empty string. - static DecodeJsonArgJsonPointer DefaultValue(); + static inline wuffs_base__image_decoder::unique_ptr + alloc_as__wuffs_base__image_decoder() { + return wuffs_base__image_decoder::unique_ptr( + wuffs_webp__decoder__alloc_as__wuffs_base__image_decoder()); + } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - std::string repr; -}; +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_webp__decoder__struct() = delete; + wuffs_webp__decoder__struct(const wuffs_webp__decoder__struct&) = delete; + wuffs_webp__decoder__struct& operator=( + const wuffs_webp__decoder__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) -// DecodeJson calls callbacks based on the JSON-formatted data in input. -// -// On success, the returned error_message is empty and cursor_position counts -// the number of bytes consumed. On failure, error_message is non-empty and -// cursor_position is the location of the error. That error may be a content -// error (invalid JSON) or an input error (e.g. network failure). -// -// json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks -// run for the input's sub-node that matches the query. DecodeJson_NoMatch is -// returned if no matching sub-node was found. The empty query matches the -// input's root node, consistent with JSON Pointer semantics. -// -// The JSON Pointer implementation is greedy: duplicate keys are not rejected -// but only the first match for each '/'-separated fragment is followed. -DecodeJsonResult // -DecodeJson(DecodeJsonCallbacks& callbacks, - sync_io::Input& input, - DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(), - DecodeJsonArgJsonPointer json_pointer = - DecodeJsonArgJsonPointer::DefaultValue()); +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) -} // namespace wuffs_aux + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_webp__decoder__initialize( + this, sizeof_star_self, wuffs_version, options); + } -#endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + inline wuffs_base__image_decoder* + upcast_as__wuffs_base__image_decoder() { + return (wuffs_base__image_decoder*)this; + } -// ‼ WUFFS C HEADER ENDS HERE. -#ifdef WUFFS_IMPLEMENTATION + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_webp__decoder__get_quirk(this, a_key); + } -#ifdef __cplusplus -extern "C" { -#endif + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_webp__decoder__set_quirk(this, a_key, a_value); + } -// ---------------- Fundamentals + inline wuffs_base__status + decode_image_config( + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_webp__decoder__decode_image_config(this, a_dst, a_src); + } -// WUFFS_BASE__MAGIC is a magic number to check that initializers are called. -// It's not foolproof, given C doesn't automatically zero memory before use, -// but it should catch 99.99% of cases. -// -// Its (non-zero) value is arbitrary, based on md5sum("wuffs"). -#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71) + inline wuffs_base__status + decode_frame_config( + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + return wuffs_webp__decoder__decode_frame_config(this, a_dst, a_src); + } -// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable -// error was previously encountered. -// -// Its (non-zero) value is arbitrary, based on md5sum("disabled"). -#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2) + inline wuffs_base__status + decode_frame( + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + return wuffs_webp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts); + } -// Use switch cases for coroutine suspension points, similar to the technique -// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html -// -// The implicit fallthrough is intentional. -// -// We use trivial macros instead of an explicit assignment and case statement -// so that clang-format doesn't get confused by the unusual "case"s. -#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:; -#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \ - coro_susp_point = n; \ - case n:; + inline wuffs_base__rect_ie_u32 + frame_dirty_rect() const { + return wuffs_webp__decoder__frame_dirty_rect(this); + } -#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \ - if (!status.repr) { \ - goto ok; \ - } else if (*status.repr != '$') { \ - goto exit; \ - } \ - coro_susp_point = n; \ - goto suspend; \ - case n:; + inline uint32_t + num_animation_loops() const { + return wuffs_webp__decoder__num_animation_loops(this); + } -// The "defined(__clang__)" isn't redundant. While vanilla clang defines -// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not. -#if defined(__GNUC__) || defined(__clang__) -#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1)) -#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0)) -#else -#define WUFFS_BASE__LIKELY(expr) (expr) -#define WUFFS_BASE__UNLIKELY(expr) (expr) -#endif + inline uint64_t + num_decoded_frame_configs() const { + return wuffs_webp__decoder__num_decoded_frame_configs(this); + } -// -------- + inline uint64_t + num_decoded_frames() const { + return wuffs_webp__decoder__num_decoded_frames(this); + } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif -static inline uint8_t* // -wuffs_base__strip_const_from_u8_ptr(const uint8_t* ptr) { - return (uint8_t*)ptr; -} -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif + inline wuffs_base__status + restart_frame( + uint64_t a_index, + uint64_t a_io_position) { + return wuffs_webp__decoder__restart_frame(this, a_index, a_io_position); + } -// -------- + inline wuffs_base__empty_struct + set_report_metadata( + uint32_t a_fourcc, + bool a_report) { + return wuffs_webp__decoder__set_report_metadata(this, a_fourcc, a_report); + } -static inline wuffs_base__empty_struct // -wuffs_base__ignore_status(wuffs_base__status z) { - return wuffs_base__make_empty_struct(); -} + inline wuffs_base__status + tell_me_more( + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + return wuffs_webp__decoder__tell_me_more(this, a_dst, a_minfo, a_src); + } -static inline wuffs_base__status // -wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) { - if (z.repr && (*z.repr == '$')) { - z.repr = wuffs_base__error__cannot_return_a_suspension; + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_webp__decoder__workbuf_len(this); } - return z; -} -// -------- +#endif // __cplusplus +}; // struct wuffs_webp__decoder__struct -// wuffs_base__iterate_total_advance returns the exclusive pointer-offset at -// which iteration should stop. The overall slice has length total_len, each -// iteration's sub-slice has length iter_len and are placed iter_advance apart. -// -// The iter_advance may not be larger than iter_len. The iter_advance may be -// smaller than iter_len, in which case the sub-slices will overlap. -// -// The return value r satisfies ((0 <= r) && (r <= total_len)). -// -// For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are -// four iterations at offsets 0, 3, 6 and 9. This function returns 12. -// -// 0123456789012345 -// [....] -// [....] -// [....] -// [....] -// $ -// 0123456789012345 -// -// For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are -// three iterations at offsets 0, 5 and 10. This function returns 15. +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) || defined(WUFFS_NONMONOLITHIC) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC) + +// ---------------- Status Codes + +// ---------------- Public Consts + +// ---------------- Struct Declarations + +typedef struct wuffs_xxhash32__hasher__struct wuffs_xxhash32__hasher; + +#ifdef __cplusplus +extern "C" { +#endif + +// ---------------- Public Initializer Prototypes + +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". // -// 0123456789012345 -// [....] -// [....] -// [....] -// $ -// 0123456789012345 -static inline size_t // -wuffs_base__iterate_total_advance(size_t total_len, - size_t iter_len, - size_t iter_advance) { - if (total_len >= iter_len) { - size_t n = total_len - iter_len; - return ((n / iter_advance) * iter_advance) + iter_advance; - } - return 0; -} +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. -// ---------------- Numeric Types +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_xxhash32__hasher__initialize( + wuffs_xxhash32__hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); -extern const uint8_t wuffs_base__low_bits_mask__u8[8]; -extern const uint16_t wuffs_base__low_bits_mask__u16[16]; -extern const uint32_t wuffs_base__low_bits_mask__u32[32]; -extern const uint64_t wuffs_base__low_bits_mask__u64[64]; +size_t +sizeof__wuffs_xxhash32__hasher(void); -#define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n]) -#define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n]) -#define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n]) -#define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n]) +// ---------------- Allocs -// -------- +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. -static inline void // -wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) { - *x = wuffs_base__u8__sat_add(*x, y); -} +wuffs_xxhash32__hasher* +wuffs_xxhash32__hasher__alloc(void); -static inline void // -wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) { - *x = wuffs_base__u8__sat_sub(*x, y); +static inline wuffs_base__hasher_u32* +wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void) { + return (wuffs_base__hasher_u32*)(wuffs_xxhash32__hasher__alloc()); } -static inline void // -wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) { - *x = wuffs_base__u16__sat_add(*x, y); -} +// ---------------- Upcasts -static inline void // -wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) { - *x = wuffs_base__u16__sat_sub(*x, y); +static inline wuffs_base__hasher_u32* +wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32( + wuffs_xxhash32__hasher* p) { + return (wuffs_base__hasher_u32*)p; } -static inline void // -wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) { - *x = wuffs_base__u32__sat_add(*x, y); -} +// ---------------- Public Function Prototypes -static inline void // -wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) { - *x = wuffs_base__u32__sat_sub(*x, y); -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xxhash32__hasher__get_quirk( + const wuffs_xxhash32__hasher* self, + uint32_t a_key); -static inline void // -wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) { - *x = wuffs_base__u64__sat_add(*x, y); -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_xxhash32__hasher__set_quirk( + wuffs_xxhash32__hasher* self, + uint32_t a_key, + uint64_t a_value); -static inline void // -wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) { - *x = wuffs_base__u64__sat_sub(*x, y); -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_xxhash32__hasher__update( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x); -// ---------------- Numeric Types (Utility) +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_xxhash32__hasher__update_u32( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x); -#define wuffs_base__utility__sign_extend_convert_u16_u32(a) \ - ((uint32_t)(int32_t)(int16_t)(a)) +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_xxhash32__hasher__checksum_u32( + const wuffs_xxhash32__hasher* self); -#define wuffs_base__utility__sign_extend_rshift_u32(a, n) \ - ((uint32_t)(((int32_t)(a)) >> (n))) +#ifdef __cplusplus +} // extern "C" +#endif -#define wuffs_base__utility__sign_extend_rshift_u64(a, n) \ - ((uint64_t)(((int64_t)(a)) >> (n))) +// ---------------- Struct Definitions -// ---------------- Slices and Tables +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C -// wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s. -static inline wuffs_base__slice_u8 // -wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) { - if (((uint64_t)(s.len)) > up_to) { - s.len = ((size_t)up_to); +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_xxhash32__hasher__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. + + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__hasher_u32; + wuffs_base__vtable null_vtable; + + uint32_t f_length_modulo_u32; + bool f_length_overflows_u32; + uint8_t f_padding0; + uint8_t f_padding1; + uint8_t f_buf_len; + uint8_t f_buf_data[16]; + uint32_t f_v0; + uint32_t f_v1; + uint32_t f_v2; + uint32_t f_v3; + } private_impl; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; + + // On failure, the alloc_etc functions return nullptr. They don't throw. + + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_xxhash32__hasher__alloc()); } - return s; -} -// wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s. -static inline wuffs_base__slice_u8 // -wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) { - if (((uint64_t)(s.len)) > up_to) { - s.ptr += ((uint64_t)(s.len)) - up_to; - s.len = ((size_t)up_to); + static inline wuffs_base__hasher_u32::unique_ptr + alloc_as__wuffs_base__hasher_u32() { + return wuffs_base__hasher_u32::unique_ptr( + wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32()); } - return s; -} +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) -// wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len) -// where len is the minimum of dst.len and src.len. -// -// Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty -// slice) is valid and results in a no-op. -static inline uint64_t // -wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src) { - size_t len = dst.len < src.len ? dst.len : src.len; - if (len > 0) { - memmove(dst.ptr, src.ptr, len); +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_xxhash32__hasher__struct() = delete; + wuffs_xxhash32__hasher__struct(const wuffs_xxhash32__hasher__struct&) = delete; + wuffs_xxhash32__hasher__struct& operator=( + const wuffs_xxhash32__hasher__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) + + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_xxhash32__hasher__initialize( + this, sizeof_star_self, wuffs_version, options); } - return len; -} -static inline wuffs_base__empty_struct // -wuffs_base__bulk_load_host_endian(void* ptr, - size_t len, - wuffs_base__slice_u8 src) { - if (len && (len <= src.len)) { - memmove(ptr, src.ptr, len); + inline wuffs_base__hasher_u32* + upcast_as__wuffs_base__hasher_u32() { + return (wuffs_base__hasher_u32*)this; } - return wuffs_base__make_empty_struct(); -} -static inline wuffs_base__empty_struct // -wuffs_base__bulk_memset(void* ptr, size_t len, uint8_t byte_value) { - if (len) { - memset(ptr, byte_value, len); + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_xxhash32__hasher__get_quirk(this, a_key); } - return wuffs_base__make_empty_struct(); -} -static inline wuffs_base__empty_struct // -wuffs_base__bulk_save_host_endian(void* ptr, - size_t len, - wuffs_base__slice_u8 dst) { - if (len && (len <= dst.len)) { - memmove(dst.ptr, ptr, len); + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_xxhash32__hasher__set_quirk(this, a_key, a_value); } - return wuffs_base__make_empty_struct(); -} -// -------- + inline wuffs_base__empty_struct + update( + wuffs_base__slice_u8 a_x) { + return wuffs_xxhash32__hasher__update(this, a_x); + } -static inline wuffs_base__slice_u8 // -wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) { - if (y < t.height) { - return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width); + inline uint32_t + update_u32( + wuffs_base__slice_u8 a_x) { + return wuffs_xxhash32__hasher__update_u32(this, a_x); } - return wuffs_base__make_slice_u8(NULL, 0); -} -// ---------------- Slices and Tables (Utility) + inline uint32_t + checksum_u32() const { + return wuffs_xxhash32__hasher__checksum_u32(this); + } -#define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8 +#endif // __cplusplus +}; // struct wuffs_xxhash32__hasher__struct -// ---------------- Ranges and Rects +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -static inline uint32_t // -wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) { - return r->min_incl; -} +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC) -static inline uint32_t // -wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) { - return r->max_incl; -} +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC) -static inline uint32_t // -wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) { - return r->min_incl; -} +// ---------------- Status Codes -static inline uint32_t // -wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) { - return r->max_excl; -} +// ---------------- Public Consts -static inline uint64_t // -wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) { - return r->min_incl; -} +// ---------------- Struct Declarations -static inline uint64_t // -wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) { - return r->max_incl; -} +typedef struct wuffs_xxhash64__hasher__struct wuffs_xxhash64__hasher; -static inline uint64_t // -wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) { - return r->min_incl; -} +#ifdef __cplusplus +extern "C" { +#endif -static inline uint64_t // -wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) { - return r->max_excl; -} +// ---------------- Public Initializer Prototypes -// ---------------- Ranges and Rects (Utility) +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. -#define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32 -#define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32 -#define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64 -#define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64 -#define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32 -#define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32 -#define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32 -#define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32 -#define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64 -#define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64 -#define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32 -#define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32 +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_xxhash64__hasher__initialize( + wuffs_xxhash64__hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); -// ---------------- I/O +size_t +sizeof__wuffs_xxhash64__hasher(void); -static inline uint64_t // -wuffs_base__io__count_since(uint64_t mark, uint64_t index) { - if (index >= mark) { - return index - mark; - } - return 0; -} +// ---------------- Allocs -// TODO: drop the "const" in "const uint8_t* ptr". Some though required about -// the base.io_reader.since method returning a mutable "slice base.u8". -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif -static inline wuffs_base__slice_u8 // -wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) { - if (index >= mark) { - return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark, - ((size_t)(index - mark))); - } - return wuffs_base__make_slice_u8(NULL, 0); -} -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. -// -------- +wuffs_xxhash64__hasher* +wuffs_xxhash64__hasher__alloc(void); -static inline void // -wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r, - const uint8_t* iop_r, - uint64_t limit) { - if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) { - *ptr_io2_r = iop_r + limit; - } +static inline wuffs_base__hasher_u64* +wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void) { + return (wuffs_base__hasher_u64*)(wuffs_xxhash64__hasher__alloc()); } -static inline uint32_t // -wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r, - const uint8_t* io2_r, - uint32_t length, - wuffs_base__slice_u8 dst) { - const uint8_t* iop_r = *ptr_iop_r; - size_t n = dst.len; - if (n > length) { - n = length; - } - if (n > ((size_t)(io2_r - iop_r))) { - n = (size_t)(io2_r - iop_r); - } - if (n > 0) { - memmove(dst.ptr, iop_r, n); - *ptr_iop_r += n; - } - return (uint32_t)(n); +// ---------------- Upcasts + +static inline wuffs_base__hasher_u64* +wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64( + wuffs_xxhash64__hasher* p) { + return (wuffs_base__hasher_u64*)p; } -// wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes -// start with the given prefix (up to 7 bytes long). It is peek-like, not -// read-like, in that there are no side-effects. -// -// The low 3 bits of a hold the prefix length, n. -// -// The high 56 bits of a hold the prefix itself, in little-endian order. The -// first prefix byte is in bits 8..=15, the second prefix byte is in bits -// 16..=23, etc. The high (8 * (7 - n)) bits are ignored. -// -// There are three possible return values: -// - 0 means success. -// - 1 means inconclusive, equivalent to "$short read". -// - 2 means failure. -static inline uint32_t // -wuffs_base__io_reader__match7(const uint8_t* iop_r, - const uint8_t* io2_r, - wuffs_base__io_buffer* r, - uint64_t a) { - uint32_t n = a & 7; - a >>= 8; - if ((io2_r - iop_r) >= 8) { - uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r); - uint32_t shift = 8 * (8 - n); - return ((a << shift) == (x << shift)) ? 0 : 2; - } - for (; n > 0; n--) { - if (iop_r >= io2_r) { - return (r && r->meta.closed) ? 2 : 1; - } else if (*iop_r != ((uint8_t)(a))) { - return 2; - } - iop_r++; - a >>= 8; - } - return 0; -} +// ---------------- Public Function Prototypes -static inline wuffs_base__io_buffer* // -wuffs_base__io_reader__set(wuffs_base__io_buffer* b, - const uint8_t** ptr_iop_r, - const uint8_t** ptr_io0_r, - const uint8_t** ptr_io1_r, - const uint8_t** ptr_io2_r, - wuffs_base__slice_u8 data, - uint64_t history_position) { - b->data = data; - b->meta.wi = data.len; - b->meta.ri = 0; - b->meta.pos = history_position; - b->meta.closed = false; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xxhash64__hasher__get_quirk( + const wuffs_xxhash64__hasher* self, + uint32_t a_key); - *ptr_iop_r = data.ptr; - *ptr_io0_r = data.ptr; - *ptr_io1_r = data.ptr; - *ptr_io2_r = data.ptr + data.len; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_xxhash64__hasher__set_quirk( + wuffs_xxhash64__hasher* self, + uint32_t a_key, + uint64_t a_value); - return b; -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_xxhash64__hasher__update( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x); -// -------- +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xxhash64__hasher__update_u64( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x); -static inline uint64_t // -wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w, - uint8_t* io2_w, - wuffs_base__slice_u8 src) { - uint8_t* iop_w = *ptr_iop_w; - size_t n = src.len; - if (n > ((size_t)(io2_w - iop_w))) { - n = (size_t)(io2_w - iop_w); - } - if (n > 0) { - memmove(iop_w, src.ptr, n); - *ptr_iop_w += n; - } - return (uint64_t)(n); -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xxhash64__hasher__checksum_u64( + const wuffs_xxhash64__hasher* self); -static inline void // -wuffs_base__io_writer__limit(uint8_t** ptr_io2_w, - uint8_t* iop_w, - uint64_t limit) { - if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) { - *ptr_io2_w = iop_w + limit; - } -} +#ifdef __cplusplus +} // extern "C" +#endif -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w, - uint8_t* io0_w, - uint8_t* io2_w, - uint32_t length, - uint32_t distance) { - if (!distance) { - return 0; - } - uint8_t* p = *ptr_iop_w; - if ((size_t)(p - io0_w) < (size_t)(distance)) { - return 0; - } - uint8_t* q = p - distance; - size_t n = (size_t)(io2_w - p); - if ((size_t)(length) > n) { - length = (uint32_t)(n); - } else { - n = (size_t)(length); - } - // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that - // is mostly because 3 is the minimum length for the deflate format. This - // function implementation shouldn't overfit to that one format. Perhaps the - // limited_copy_u32_from_history Wuffs method should also take an unroll hint - // argument, and the cgen can look if that argument is the constant - // expression '3'. - // - // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below. - for (; n >= 3; n -= 3) { - *p++ = *q++; - *p++ = *q++; - *p++ = *q++; - } - for (; n; n--) { - *p++ = *q++; - } - *ptr_iop_w = p; - return length; -} +// ---------------- Struct Definitions -// wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the -// wuffs_base__io_writer__limited_copy_u32_from_history function above, but has -// stronger pre-conditions. +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. // -// The caller needs to prove that: -// - length <= (io2_w - *ptr_iop_w) -// - distance >= 1 -// - distance <= (*ptr_iop_w - io0_w) -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w, - uint8_t* io0_w, - uint8_t* io2_w, - uint32_t length, - uint32_t distance) { - uint8_t* p = *ptr_iop_w; - uint8_t* q = p - distance; - uint32_t n = length; - for (; n >= 3; n -= 3) { - *p++ = *q++; - *p++ = *q++; - *p++ = *q++; - } - for (; n; n--) { - *p++ = *q++; +// See https://en.wikipedia.org/wiki/Opaque_pointer#C + +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) + +struct wuffs_xxhash64__hasher__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. + + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__hasher_u64; + wuffs_base__vtable null_vtable; + + uint64_t f_length_modulo_u64; + bool f_length_overflows_u64; + uint8_t f_padding0; + uint8_t f_padding1; + uint8_t f_padding2; + uint32_t f_buf_len; + uint8_t f_buf_data[32]; + uint64_t f_v0; + uint64_t f_v1; + uint64_t f_v2; + uint64_t f_v3; + } private_impl; + +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; + + // On failure, the alloc_etc functions return nullptr. They don't throw. + + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_xxhash64__hasher__alloc()); } - *ptr_iop_w = p; - return length; -} -// wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast -// copies the previous byte (the one immediately before *ptr_iop_w), copying 8 -// byte chunks at a time. Each chunk contains 8 repetitions of the same byte. -// -// In terms of number of bytes copied, length is rounded up to a multiple of 8. -// As a special case, a zero length rounds up to 8 (even though 0 is already a -// multiple of 8), since there is always at least one 8 byte chunk copied. -// -// In terms of advancing *ptr_iop_w, length is not rounded up. -// -// The caller needs to prove that: -// - (length + 8) <= (io2_w - *ptr_iop_w) -// - distance == 1 -// - distance <= (*ptr_iop_w - io0_w) -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( - uint8_t** ptr_iop_w, - uint8_t* io0_w, - uint8_t* io2_w, - uint32_t length, - uint32_t distance) { - uint8_t* p = *ptr_iop_w; - uint64_t x = p[-1]; - x |= x << 8; - x |= x << 16; - x |= x << 32; - uint32_t n = length; - while (1) { - wuffs_base__poke_u64le__no_bounds_check(p, x); - if (n <= 8) { - p += n; - break; - } - p += 8; - n -= 8; + static inline wuffs_base__hasher_u64::unique_ptr + alloc_as__wuffs_base__hasher_u64() { + return wuffs_base__hasher_u64::unique_ptr( + wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64()); } - *ptr_iop_w = p; - return length; -} +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) -// wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is -// like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function -// above, but copies 8 byte chunks at a time. -// -// In terms of number of bytes copied, length is rounded up to a multiple of 8. -// As a special case, a zero length rounds up to 8 (even though 0 is already a -// multiple of 8), since there is always at least one 8 byte chunk copied. -// -// In terms of advancing *ptr_iop_w, length is not rounded up. -// -// The caller needs to prove that: -// - (length + 8) <= (io2_w - *ptr_iop_w) -// - distance >= 8 -// - distance <= (*ptr_iop_w - io0_w) -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( - uint8_t** ptr_iop_w, - uint8_t* io0_w, - uint8_t* io2_w, - uint32_t length, - uint32_t distance) { - uint8_t* p = *ptr_iop_w; - uint8_t* q = p - distance; - uint32_t n = length; - while (1) { - memcpy(p, q, 8); - if (n <= 8) { - p += n; - break; - } - p += 8; - q += 8; - n -= 8; +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_xxhash64__hasher__struct() = delete; + wuffs_xxhash64__hasher__struct(const wuffs_xxhash64__hasher__struct&) = delete; + wuffs_xxhash64__hasher__struct& operator=( + const wuffs_xxhash64__hasher__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) + + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_xxhash64__hasher__initialize( + this, sizeof_star_self, wuffs_version, options); } - *ptr_iop_w = p; - return length; -} -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w, - uint8_t* io2_w, - uint32_t length, - const uint8_t** ptr_iop_r, - const uint8_t* io2_r) { - uint8_t* iop_w = *ptr_iop_w; - size_t n = length; - if (n > ((size_t)(io2_w - iop_w))) { - n = (size_t)(io2_w - iop_w); + inline wuffs_base__hasher_u64* + upcast_as__wuffs_base__hasher_u64() { + return (wuffs_base__hasher_u64*)this; } - const uint8_t* iop_r = *ptr_iop_r; - if (n > ((size_t)(io2_r - iop_r))) { - n = (size_t)(io2_r - iop_r); + + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_xxhash64__hasher__get_quirk(this, a_key); } - if (n > 0) { - memmove(iop_w, iop_r, n); - *ptr_iop_w += n; - *ptr_iop_r += n; + + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_xxhash64__hasher__set_quirk(this, a_key, a_value); } - return (uint32_t)(n); -} -static inline uint32_t // -wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w, - uint8_t* io2_w, - uint32_t length, - wuffs_base__slice_u8 src) { - uint8_t* iop_w = *ptr_iop_w; - size_t n = src.len; - if (n > length) { - n = length; + inline wuffs_base__empty_struct + update( + wuffs_base__slice_u8 a_x) { + return wuffs_xxhash64__hasher__update(this, a_x); } - if (n > ((size_t)(io2_w - iop_w))) { - n = (size_t)(io2_w - iop_w); + + inline uint64_t + update_u64( + wuffs_base__slice_u8 a_x) { + return wuffs_xxhash64__hasher__update_u64(this, a_x); } - if (n > 0) { - memmove(iop_w, src.ptr, n); - *ptr_iop_w += n; + + inline uint64_t + checksum_u64() const { + return wuffs_xxhash64__hasher__checksum_u64(this); } - return (uint32_t)(n); -} -static inline wuffs_base__io_buffer* // -wuffs_base__io_writer__set(wuffs_base__io_buffer* b, - uint8_t** ptr_iop_w, - uint8_t** ptr_io0_w, - uint8_t** ptr_io1_w, - uint8_t** ptr_io2_w, - wuffs_base__slice_u8 data, - uint64_t history_position) { - b->data = data; - b->meta.wi = 0; - b->meta.ri = 0; - b->meta.pos = history_position; - b->meta.closed = false; +#endif // __cplusplus +}; // struct wuffs_xxhash64__hasher__struct - *ptr_iop_w = data.ptr; - *ptr_io0_w = data.ptr; - *ptr_io1_w = data.ptr; - *ptr_io2_w = data.ptr + data.len; +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - return b; -} +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC) -// ---------------- I/O (Utility) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) || defined(WUFFS_NONMONOLITHIC) -#define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader -#define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer +// ---------------- Status Codes -// ---------------- Tokens +extern const char wuffs_xz__error__bad_bcj_offset[]; +extern const char wuffs_xz__error__bad_block_header[]; +extern const char wuffs_xz__error__bad_checksum[]; +extern const char wuffs_xz__error__bad_filter[]; +extern const char wuffs_xz__error__bad_footer[]; +extern const char wuffs_xz__error__bad_header[]; +extern const char wuffs_xz__error__bad_header_concatenated_stream[]; +extern const char wuffs_xz__error__bad_index[]; +extern const char wuffs_xz__error__bad_padding[]; +extern const char wuffs_xz__error__truncated_input[]; +extern const char wuffs_xz__error__unsupported_checksum_algorithm[]; +extern const char wuffs_xz__error__unsupported_filter[]; +extern const char wuffs_xz__error__unsupported_filter_combination[]; -// ---------------- Tokens (Utility) +// ---------------- Public Consts -// ---------------- Memory Allocation +#define WUFFS_XZ__QUIRK_DECODE_STANDALONE_CONCATENATED_STREAMS 2021322752u -// ---------------- Images +#define WUFFS_XZ__DECODER_DST_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0u -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( - const wuffs_base__pixel_swizzler* p, - uint32_t up_to_num_pixels, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - const uint8_t** ptr_iop_r, - const uint8_t* io2_r); +#define WUFFS_XZ__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 4294967568u -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( - const wuffs_base__pixel_swizzler* p, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - const uint8_t** ptr_iop_r, - const uint8_t* io2_r); +// ---------------- Struct Declarations -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black( - const wuffs_base__pixel_swizzler* p, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - uint64_t num_pixels); +typedef struct wuffs_xz__decoder__struct wuffs_xz__decoder; -WUFFS_BASE__MAYBE_STATIC wuffs_base__status // -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, - wuffs_base__slice_u8 src0, - wuffs_base__slice_u8 src1, - wuffs_base__slice_u8 src2, - wuffs_base__slice_u8 src3, - uint32_t width0, - uint32_t width1, - uint32_t width2, - uint32_t width3, - uint32_t height0, - uint32_t height1, - uint32_t height2, - uint32_t height3, - uint32_t stride0, - uint32_t stride1, - uint32_t stride2, - uint32_t stride3, - uint8_t h0, - uint8_t h1, - uint8_t h2, - uint8_t h3, - uint8_t v0, - uint8_t v1, - uint8_t v2, - uint8_t v3, - bool is_rgb_or_cmyk, - bool triangle_filter_for_2to1, - wuffs_base__slice_u8 scratch_buffer_2k); +#ifdef __cplusplus +extern "C" { +#endif -// ---------------- Images (Utility) +// ---------------- Public Initializer Prototypes -#define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format +// For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, +// etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". +// +// Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. +// Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for options. -// ---------------- String Conversions +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_xz__decoder__initialize( + wuffs_xz__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options); -// ---------------- Unicode and UTF-8 +size_t +sizeof__wuffs_xz__decoder(void); -// ---------------- +// ---------------- Allocs -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__CORE) +// These functions allocate and initialize Wuffs structs. They return NULL if +// memory allocation fails. If they return non-NULL, there is no need to call +// wuffs_foo__bar__initialize, but the caller is responsible for eventually +// calling free on the returned pointer. That pointer is effectively a C++ +// std::unique_ptr. -const uint8_t wuffs_base__low_bits_mask__u8[8] = { - 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, -}; +wuffs_xz__decoder* +wuffs_xz__decoder__alloc(void); -const uint16_t wuffs_base__low_bits_mask__u16[16] = { - 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, - 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, -}; +static inline wuffs_base__io_transformer* +wuffs_xz__decoder__alloc_as__wuffs_base__io_transformer(void) { + return (wuffs_base__io_transformer*)(wuffs_xz__decoder__alloc()); +} -const uint32_t wuffs_base__low_bits_mask__u32[32] = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, - 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, - 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, - 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, - 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, - 0x3FFFFFFF, 0x7FFFFFFF, -}; +// ---------------- Upcasts -const uint64_t wuffs_base__low_bits_mask__u64[64] = { - 0x0000000000000000, 0x0000000000000001, 0x0000000000000003, - 0x0000000000000007, 0x000000000000000F, 0x000000000000001F, - 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF, - 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF, - 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF, - 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF, - 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF, - 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF, - 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF, - 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF, - 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF, - 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF, - 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF, - 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF, - 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF, - 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF, - 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF, - 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF, - 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF, - 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF, - 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, - 0x7FFFFFFFFFFFFFFF, -}; +static inline wuffs_base__io_transformer* +wuffs_xz__decoder__upcast_as__wuffs_base__io_transformer( + wuffs_xz__decoder* p) { + return (wuffs_base__io_transformer*)p; +} -const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, -}; +// ---------------- Public Function Prototypes -const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect"; -const char wuffs_base__note__end_of_data[] = "@base: end of data"; -const char wuffs_base__note__metadata_reported[] = "@base: metadata reported"; -const char wuffs_base__suspension__even_more_information[] = "$base: even more information"; -const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read"; -const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write"; -const char wuffs_base__suspension__short_read[] = "$base: short read"; -const char wuffs_base__suspension__short_write[] = "$base: short write"; -const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position"; -const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)"; -const char wuffs_base__error__bad_argument[] = "#base: bad argument"; -const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence"; -const char wuffs_base__error__bad_data[] = "#base: bad data"; -const char wuffs_base__error__bad_receiver[] = "#base: bad receiver"; -const char wuffs_base__error__bad_restart[] = "#base: bad restart"; -const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver"; -const char wuffs_base__error__bad_vtable[] = "#base: bad vtable"; -const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length"; -const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version"; -const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension"; -const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error"; -const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed"; -const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called"; -const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls"; -const char wuffs_base__error__no_more_information[] = "#base: no more information"; -const char wuffs_base__error__not_enough_data[] = "#base: not enough data"; -const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds"; -const char wuffs_base__error__unsupported_image_dimension[] = "#base: unsupported image dimension"; -const char wuffs_base__error__unsupported_method[] = "#base: unsupported method"; -const char wuffs_base__error__unsupported_option[] = "#base: unsupported option"; -const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option"; -const char wuffs_base__error__too_much_data[] = "#base: too much data"; - -const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32"; -const char wuffs_base__hasher_u64__vtable_name[] = "{vtable}wuffs_base__hasher_u64"; -const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder"; -const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer"; -const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder"; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xz__decoder__get_quirk( + const wuffs_xz__decoder* self, + uint32_t a_key); -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__CORE) +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_xz__decoder__set_quirk( + wuffs_xz__decoder* self, + uint32_t a_key, + uint64_t a_value); -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES) +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_xz__decoder__dst_history_retain_length( + const wuffs_xz__decoder* self); -// ---------------- Interface Definitions. +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_xz__decoder__workbuf_len( + const wuffs_xz__decoder* self); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_base__hasher_u32__checksum_u32( - const wuffs_base__hasher_u32* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_xz__decoder__transform_io( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { - const wuffs_base__hasher_u32__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); - return (*func_ptrs->checksum_u32)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#ifdef __cplusplus +} // extern "C" +#endif - return 0; -} +// ---------------- Struct Definitions -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__hasher_u32__get_quirk( - const wuffs_base__hasher_u32* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +// These structs' fields, and the sizeof them, are private implementation +// details that aren't guaranteed to be stable across Wuffs versions. +// +// See https://en.wikipedia.org/wiki/Opaque_pointer#C - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { - const wuffs_base__hasher_u32__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); - return (*func_ptrs->get_quirk)(self, a_key); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) - return 0; -} +struct wuffs_xz__decoder__struct { + // Do not access the private_impl's or private_data's fields directly. There + // is no API/ABI compatibility or safety guarantee if you do so. Instead, use + // the wuffs_foo__bar__baz functions. + // + // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct + // can be stack allocated when WUFFS_IMPLEMENTATION is defined. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__hasher_u32__set_quirk( - wuffs_base__hasher_u32* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } + struct { + uint32_t magic; + uint32_t active_coroutine; + wuffs_base__vtable vtable_for__wuffs_base__io_transformer; + wuffs_base__vtable null_vtable; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { - const wuffs_base__hasher_u32__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_quirk)(self, a_key, a_value); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + uint32_t f_filters[3]; + uint32_t f_num_non_final_filters; + uint8_t f_checksummer; + bool f_ignore_checksum; + bool f_standalone_format; + bool f_lzma_needs_reset; + bool f_block_has_compressed_size; + bool f_block_has_uncompressed_size; + uint8_t f_bcj_undo_index; + uint32_t f_bcj_pos; + uint32_t f_bcj_x86_prev_mask; + uint64_t f_block_compressed_size; + uint64_t f_block_uncompressed_size; + uint64_t f_compressed_size_for_index; + uint32_t f_verification_have_hashed_sizes[2]; + uint32_t f_verification_want_hashed_sizes[2]; + uint64_t f_verification_have_total_sizes[2]; + uint64_t f_verification_want_total_sizes[2]; + uint64_t f_num_actual_blocks; + uint64_t f_num_index_blocks; + uint64_t f_index_block_compressed_size; + uint64_t f_index_block_uncompressed_size; + uint64_t f_backwards_size; + bool f_started_verify_index; + uint16_t f_flags; + + uint8_t (*choosy_apply_non_final_filters)( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + uint32_t p_transform_io; + uint32_t p_do_transform_io; + uint32_t p_decode_block_header_with_padding; + uint32_t p_decode_block_header_sans_padding; + uint32_t p_verify_index; + uint32_t p_verify_footer; + } private_impl; - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + struct { + uint8_t f_filter_data[3][256]; + wuffs_crc32__ieee_hasher f_crc32; + wuffs_crc64__ecma_hasher f_crc64; + wuffs_sha256__hasher f_sha256; + wuffs_lzma__decoder f_lzma; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_base__hasher_u32__update( - wuffs_base__hasher_u32* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); - } + struct { + uint32_t v_checksum32_have; + uint32_t v_checksum32_want; + wuffs_base__bitvec256 v_checksum256_have; + uint64_t v_compressed_size; + uint64_t v_uncompressed_size; + uint64_t scratch; + } s_do_transform_io; + struct { + uint64_t v_padded_size_have; + uint64_t v_padded_size_want; + } s_decode_block_header_with_padding; + struct { + uint8_t v_flags; + uint8_t v_filter_id; + uint32_t v_shift; + uint32_t v_f; + uint64_t scratch; + } s_decode_block_header_sans_padding; + struct { + uint32_t v_shift; + } s_verify_index; + struct { + uint64_t scratch; + } s_verify_footer; + } private_data; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { - const wuffs_base__hasher_u32__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); - return (*func_ptrs->update)(self, a_x); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#ifdef __cplusplus +#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR) + using unique_ptr = std::unique_ptr; - return wuffs_base__make_empty_struct(); -} + // On failure, the alloc_etc functions return nullptr. They don't throw. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_base__hasher_u32__update_u32( - wuffs_base__hasher_u32* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return 0; - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; + static inline unique_ptr + alloc() { + return unique_ptr(wuffs_xz__decoder__alloc()); } - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { - const wuffs_base__hasher_u32__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); - return (*func_ptrs->update_u32)(self, a_x); - } else if (v->vtable_name == NULL) { - break; - } - v++; + static inline wuffs_base__io_transformer::unique_ptr + alloc_as__wuffs_base__io_transformer() { + return wuffs_base__io_transformer::unique_ptr( + wuffs_xz__decoder__alloc_as__wuffs_base__io_transformer()); } +#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - return 0; -} +#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) + // Disallow constructing or copying an object via standard C++ mechanisms, + // e.g. the "new" operator, as this struct is intentionally opaque. Its total + // size and field layout is not part of the public, stable, memory-safe API. + // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and + // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as + // their first argument) rather than tweaking bar.private_impl.qux fields. + // + // In C, we can just leave wuffs_foo__bar as an incomplete type (unless + // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in + // order to provide convenience methods. These forward on "this", so that you + // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". + wuffs_xz__decoder__struct() = delete; + wuffs_xz__decoder__struct(const wuffs_xz__decoder__struct&) = delete; + wuffs_xz__decoder__struct& operator=( + const wuffs_xz__decoder__struct&) = delete; +#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION) -// -------- +#if !defined(WUFFS_IMPLEMENTATION) + // As above, the size of the struct is not part of the public API, and unless + // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap + // allocated, not stack allocated. Its size is not intended to be known at + // compile time, but it is unfortunately divulged as a side effect of + // defining C++ convenience methods. Use "sizeof__T()", calling the function, + // instead of "sizeof T", invoking the operator. To make the two values + // different, so that passing the latter will be rejected by the initialize + // function, we add an arbitrary amount of dead weight. + uint8_t dead_weight[123000000]; // 123 MB. +#endif // !defined(WUFFS_IMPLEMENTATION) -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__hasher_u64__checksum_u64( - const wuffs_base__hasher_u64* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT + initialize( + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options) { + return wuffs_xz__decoder__initialize( + this, sizeof_star_self, wuffs_version, options); } - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { - const wuffs_base__hasher_u64__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); - return (*func_ptrs->checksum_u64)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; + inline wuffs_base__io_transformer* + upcast_as__wuffs_base__io_transformer() { + return (wuffs_base__io_transformer*)this; } - return 0; -} - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__hasher_u64__get_quirk( - const wuffs_base__hasher_u64* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + inline uint64_t + get_quirk( + uint32_t a_key) const { + return wuffs_xz__decoder__get_quirk(this, a_key); } - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { - const wuffs_base__hasher_u64__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); - return (*func_ptrs->get_quirk)(self, a_key); - } else if (v->vtable_name == NULL) { - break; - } - v++; + inline wuffs_base__status + set_quirk( + uint32_t a_key, + uint64_t a_value) { + return wuffs_xz__decoder__set_quirk(this, a_key, a_value); } - return 0; -} - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__hasher_u64__set_quirk( - wuffs_base__hasher_u64* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + inline wuffs_base__optional_u63 + dst_history_retain_length() const { + return wuffs_xz__decoder__dst_history_retain_length(this); } - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { - const wuffs_base__hasher_u64__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_quirk)(self, a_key, a_value); - } else if (v->vtable_name == NULL) { - break; - } - v++; + inline wuffs_base__range_ii_u64 + workbuf_len() const { + return wuffs_xz__decoder__workbuf_len(this); } - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_base__hasher_u64__update( - wuffs_base__hasher_u64* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + inline wuffs_base__status + transform_io( + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + return wuffs_xz__decoder__transform_io(this, a_dst, a_src, a_workbuf); } - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { - const wuffs_base__hasher_u64__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); - return (*func_ptrs->update)(self, a_x); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#endif // __cplusplus +}; // struct wuffs_xz__decoder__struct - return wuffs_base__make_empty_struct(); -} +#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__hasher_u64__update_u64( - wuffs_base__hasher_u64* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return 0; - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; - } +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) || defined(WUFFS_NONMONOLITHIC) - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { - const wuffs_base__hasher_u64__func_ptrs* func_ptrs = - (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); - return (*func_ptrs->update_u64)(self, a_x); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR) - return 0; -} +// ---------------- Auxiliary - Base -// -------- +// Auxiliary code is discussed at +// https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__decode_frame( - wuffs_base__image_decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +#include - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +#include +#include - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} +namespace wuffs_aux { -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__decode_frame_config( - wuffs_base__image_decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +using IOBuffer = wuffs_base__io_buffer; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->decode_frame_config)(self, a_dst, a_src); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +// MemOwner represents ownership of some memory. Dynamically allocated memory +// (e.g. from malloc or new) is typically paired with free or delete, invoked +// when the std::unique_ptr is destroyed. Statically allocated memory might use +// MemOwner(nullptr, &free), even if that statically allocated memory is not +// nullptr, since calling free(nullptr) is a no-op. +using MemOwner = std::unique_ptr; - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} +using QuirkKeyValuePair = std::pair; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__decode_image_config( - wuffs_base__image_decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +namespace sync_io { - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->decode_image_config)(self, a_dst, a_src); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +// -------- - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} +// DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array. +// It owns that backing array and will free it in its destructor. +// +// The array size can be explicitly extended (by calling the grow method) but, +// unlike a C++ std::vector, there is no implicit extension (e.g. by calling +// std::vector::insert) and its maximum size is capped by the max_incl +// constructor argument. +// +// It contains an IOBuffer-typed field whose reader side provides access to +// previously written bytes and whose writer side provides access to the +// allocated but not-yet-written-to slack space. For Go programmers, this slack +// space is roughly analogous to the s[len(s):cap(s)] space of a slice s. +class DynIOBuffer { + public: + enum GrowResult { + OK = 0, + FailedMaxInclExceeded = 1, + FailedOutOfMemory = 2, + }; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_base__image_decoder__frame_dirty_rect( - const wuffs_base__image_decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); - } + // m_buf holds the dynamically sized byte array and its read/write indexes: + // - m_buf.meta.wi is roughly analogous to a Go slice's length. + // - m_buf.data.len is roughly analogous to a Go slice's capacity. It is + // also equal to the m_buf.data.ptr malloc/realloc size. + // + // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as + // they are conceptually private to this class), but they can modify the + // bytes referenced by that pointer-length pair (e.g. compactions). + IOBuffer m_buf; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->frame_dirty_rect)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // m_max_incl is an inclusive upper bound on the backing array size. + const uint64_t m_max_incl; - return wuffs_base__utility__empty_rect_ie_u32(); -} + // Constructor and destructor. + explicit DynIOBuffer(uint64_t max_incl); + ~DynIOBuffer(); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__image_decoder__get_quirk( - const wuffs_base__image_decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be + // used after a drop call. It just restarts from zero. + void drop(); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->get_quirk)(self, a_key); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // grow ensures that the byte array size is at least min_incl and at most + // max_incl. It returns FailedMaxInclExceeded if that would require + // allocating more than max_incl bytes, including the case where (min_incl > + // max_incl). It returns FailedOutOfMemory if memory allocation failed. + GrowResult grow(uint64_t min_incl); - return 0; -} + private: + // Delete the copy and assign constructors. + DynIOBuffer(const DynIOBuffer&) = delete; + DynIOBuffer& operator=(const DynIOBuffer&) = delete; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__image_decoder__history_retain_length( - const wuffs_base__image_decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + static uint64_t round_up(uint64_t min_incl, uint64_t max_incl); +}; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->history_retain_length)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +// -------- - return 0; -} +class Input { + public: + virtual ~Input(); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_base__image_decoder__num_animation_loops( - const wuffs_base__image_decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + virtual IOBuffer* BringsItsOwnIOBuffer(); + virtual std::string CopyIn(IOBuffer* dst) = 0; +}; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->num_animation_loops)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +// -------- - return 0; -} +// FileInput is an Input that reads from a file source. +// +// It does not take responsibility for closing the file when done. +class FileInput : public Input { + public: + FileInput(FILE* f); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__image_decoder__num_decoded_frame_configs( - const wuffs_base__image_decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + virtual std::string CopyIn(IOBuffer* dst); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->num_decoded_frame_configs)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + private: + FILE* m_f; - return 0; -} + // Delete the copy and assign constructors. + FileInput(const FileInput&) = delete; + FileInput& operator=(const FileInput&) = delete; +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__image_decoder__num_decoded_frames( - const wuffs_base__image_decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +// -------- - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->num_decoded_frames)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +// MemoryInput is an Input that reads from an in-memory source. +// +// It does not take responsibility for freeing the memory when done. +class MemoryInput : public Input { + public: + MemoryInput(const char* ptr, size_t len); + MemoryInput(const uint8_t* ptr, size_t len); - return 0; -} + virtual IOBuffer* BringsItsOwnIOBuffer(); + virtual std::string CopyIn(IOBuffer* dst); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__restart_frame( - wuffs_base__image_decoder* self, - uint64_t a_index, - uint64_t a_io_position) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } + private: + IOBuffer m_io; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->restart_frame)(self, a_index, a_io_position); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // Delete the copy and assign constructors. + MemoryInput(const MemoryInput&) = delete; + MemoryInput& operator=(const MemoryInput&) = delete; +}; - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} +// -------- -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__set_quirk( - wuffs_base__image_decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +} // namespace sync_io - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_quirk)(self, a_key, a_value); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +} // namespace wuffs_aux - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} +// ---------------- Auxiliary - CBOR -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_base__image_decoder__set_report_metadata( - wuffs_base__image_decoder* self, - uint32_t a_fourcc, - bool a_report) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); - } +namespace wuffs_aux { - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +struct DecodeCborResult { + DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0); - return wuffs_base__make_empty_struct(); -} + std::string error_message; + uint64_t cursor_position; +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__image_decoder__tell_me_more( - wuffs_base__image_decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +class DecodeCborCallbacks { + public: + virtual ~DecodeCborCallbacks(); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // AppendXxx are called for leaf nodes: literals, numbers, strings, etc. - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + virtual std::string AppendNull() = 0; + virtual std::string AppendUndefined() = 0; + virtual std::string AppendBool(bool val) = 0; + virtual std::string AppendF64(double val) = 0; + virtual std::string AppendI64(int64_t val) = 0; + virtual std::string AppendU64(uint64_t val) = 0; + virtual std::string AppendByteString(std::string&& val) = 0; + virtual std::string AppendTextString(std::string&& val) = 0; + virtual std::string AppendMinus1MinusX(uint64_t val) = 0; + virtual std::string AppendCborSimpleValue(uint8_t val) = 0; + virtual std::string AppendCborTag(uint64_t val) = 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_base__image_decoder__workbuf_len( - const wuffs_base__image_decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } + // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR + // maps (dictionaries). + // + // The flags bits combine exactly one of: + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT + // and exactly one of: + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { - const wuffs_base__image_decoder__func_ptrs* func_ptrs = - (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->workbuf_len)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + virtual std::string Push(uint32_t flags) = 0; + virtual std::string Pop(uint32_t flags) = 0; - return wuffs_base__utility__empty_range_ii_u64(); -} + // Done is always the last Callback method called by DecodeCbor, whether or + // not parsing the input as CBOR encountered an error. Even when successful, + // trailing data may remain in input and buffer. + // + // Do not keep a reference to buffer or buffer.data.ptr after Done returns, + // as DecodeCbor may then de-allocate the backing array. + // + // The default Done implementation is a no-op. + virtual void // + Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer); +}; -// -------- +// The FooArgBar types add structure to Foo's optional arguments. They wrap +// inner representations for several reasons: +// - It provides a home for the DefaultValue static method, for Foo callers +// that want to override some but not all optional arguments. +// - It provides the "Bar" name at Foo call sites, which can help self- +// document Foo calls with many arguemnts. +// - It provides some type safety against accidentally transposing or omitting +// adjacent fundamentally-numeric-typed optional arguments. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__io_transformer__get_quirk( - const wuffs_base__io_transformer* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +// DecodeCborArgQuirks wraps an optional argument to DecodeCbor. +struct DecodeCborArgQuirks { + explicit DecodeCborArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { - const wuffs_base__io_transformer__func_ptrs* func_ptrs = - (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); - return (*func_ptrs->get_quirk)(self, a_key); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // DefaultValue returns an empty slice. + static DecodeCborArgQuirks DefaultValue(); - return 0; -} + const QuirkKeyValuePair* ptr; + const size_t len; +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__io_transformer__history_retain_length( - const wuffs_base__io_transformer* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +// DecodeCbor calls callbacks based on the CBOR-formatted data in input. +// +// On success, the returned error_message is empty and cursor_position counts +// the number of bytes consumed. On failure, error_message is non-empty and +// cursor_position is the location of the error. That error may be a content +// error (invalid CBOR) or an input error (e.g. network failure). +DecodeCborResult // +DecodeCbor(DecodeCborCallbacks& callbacks, + sync_io::Input& input, + DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue()); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { - const wuffs_base__io_transformer__func_ptrs* func_ptrs = - (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); - return (*func_ptrs->history_retain_length)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +} // namespace wuffs_aux - return 0; -} +// ---------------- Auxiliary - Image -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__io_transformer__set_quirk( - wuffs_base__io_transformer* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +namespace wuffs_aux { - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { - const wuffs_base__io_transformer__func_ptrs* func_ptrs = - (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_quirk)(self, a_key, a_value); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +struct DecodeImageResult { + DecodeImageResult(MemOwner&& pixbuf_mem_owner0, + wuffs_base__pixel_buffer pixbuf0, + std::string&& error_message0); + DecodeImageResult(std::string&& error_message0); - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + MemOwner pixbuf_mem_owner; + wuffs_base__pixel_buffer pixbuf; + std::string error_message; +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__io_transformer__transform_io( - wuffs_base__io_transformer* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always +// called in this order: +// 1. SelectDecoder +// 2. HandleMetadata +// 3. SelectPixfmt +// 4. AllocPixbuf +// 5. AllocWorkbuf +// 6. Done +// +// It may return early - the third callback might not be invoked if the second +// one fails - but the final callback (Done) is always invoked. +class DecodeImageCallbacks { + public: + // AllocPixbufResult holds a memory allocation (the result of malloc or new, + // a statically allocated pointer, etc), or an error message. The memory is + // de-allocated when mem_owner goes out of scope and is destroyed. + struct AllocPixbufResult { + AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0); + AllocPixbufResult(std::string&& error_message0); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { - const wuffs_base__io_transformer__func_ptrs* func_ptrs = - (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); - return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + MemOwner mem_owner; + wuffs_base__pixel_buffer pixbuf; + std::string error_message; + }; - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + // AllocWorkbufResult holds a memory allocation (the result of malloc or new, + // a statically allocated pointer, etc), or an error message. The memory is + // de-allocated when mem_owner goes out of scope and is destroyed. + struct AllocWorkbufResult { + AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0); + AllocWorkbufResult(std::string&& error_message0); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_base__io_transformer__workbuf_len( - const wuffs_base__io_transformer* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } + MemOwner mem_owner; + wuffs_base__slice_u8 workbuf; + std::string error_message; + }; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { - const wuffs_base__io_transformer__func_ptrs* func_ptrs = - (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); - return (*func_ptrs->workbuf_len)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + virtual ~DecodeImageCallbacks(); - return wuffs_base__utility__empty_range_ii_u64(); -} + // SelectDecoder returns the image decoder for the input data's file format. + // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat). + // + // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF], + // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs' + // standard library did not recognize the image format but if SelectDecoder + // was overridden, it may examine the input data's starting bytes and still + // provide its own image decoder, e.g. for an exotic image file format that's + // not in Wuffs' standard library. The prefix_etc fields have the same + // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder + // implementations should not modify prefix_data's contents. + // + // SelectDecoder might be called more than once, since some image file + // formats can wrap others. For example, a nominal BMP file can actually + // contain a JPEG or a PNG. + // + // The default SelectDecoder accepts the FOURCC codes listed below. For + // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance + // of the ETC file format is optional (for each value of ETC) and depends on + // the corresponding module to be enabled at compile time (i.e. #define'ing + // WUFFS_CONFIG__MODULE__ETC). + // - WUFFS_BASE__FOURCC__BMP + // - WUFFS_BASE__FOURCC__GIF + // - WUFFS_BASE__FOURCC__JPEG + // - WUFFS_BASE__FOURCC__NIE + // - WUFFS_BASE__FOURCC__NPBM + // - WUFFS_BASE__FOURCC__PNG + // - WUFFS_BASE__FOURCC__QOI + // - WUFFS_BASE__FOURCC__TGA + // - WUFFS_BASE__FOURCC__WBMP + // - WUFFS_BASE__FOURCC__WEBP + virtual wuffs_base__image_decoder::unique_ptr // + SelectDecoder(uint32_t fourcc, + wuffs_base__slice_u8 prefix_data, + bool prefix_closed); -// -------- + // HandleMetadata acknowledges image metadata. minfo.flavor will be one of: + // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH + // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED + // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those + // bytes should not be retained beyond the the HandleMetadata call. + // + // minfo.metadata__fourcc() will typically match one of the + // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM | + // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC + // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA. + // + // It returns an error message, or an empty string on success. + virtual std::string // + HandleMetadata(const wuffs_base__more_information& minfo, + wuffs_base__slice_u8 raw); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__token_decoder__decode_tokens( - wuffs_base__token_decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } + // SelectPixfmt returns the destination pixel format for AllocPixbuf. It + // should return wuffs_base__make_pixel_format(etc) called with one of: + // - WUFFS_BASE__PIXEL_FORMAT__BGR_565 + // - WUFFS_BASE__PIXEL_FORMAT__BGR + // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL + // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE + // - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL + // - WUFFS_BASE__PIXEL_FORMAT__RGB + // - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL + // - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL + // or return image_config.pixcfg.pixel_format(). The latter means to use the + // image file's natural pixel format. For example, GIF images' natural pixel + // format is an indexed one. + // + // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat). + // + // The default SelectPixfmt implementation returns + // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which + // is 4 bytes per pixel (8 bits per channel × 4 channels). + virtual wuffs_base__pixel_format // + SelectPixfmt(const wuffs_base__image_config& image_config); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { - const wuffs_base__token_decoder__func_ptrs* func_ptrs = - (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // AllocPixbuf allocates the pixel buffer. + // + // allow_uninitialized_memory will be true if a valid background_color was + // passed to DecodeImage, since the pixel buffer's contents will be + // overwritten with that color after AllocPixbuf returns. + // + // The default AllocPixbuf implementation allocates either uninitialized or + // zeroed memory. Zeroed memory typically corresponds to filling with opaque + // black or transparent black, depending on the pixel format. + virtual AllocPixbufResult // + AllocPixbuf(const wuffs_base__image_config& image_config, + bool allow_uninitialized_memory); - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + // AllocWorkbuf allocates the work buffer. The allocated buffer's length + // should be at least len_range.min_incl, but larger allocations (up to + // len_range.max_incl) may have better performance (by using more memory). + // + // The default AllocWorkbuf implementation allocates len_range.max_incl bytes + // of either uninitialized or zeroed memory. + virtual AllocWorkbufResult // + AllocWorkbuf(wuffs_base__range_ii_u64 len_range, + bool allow_uninitialized_memory); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__token_decoder__get_quirk( - const wuffs_base__token_decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + // Done is always the last Callback method called by DecodeImage, whether or + // not parsing the input encountered an error. Even when successful, trailing + // data may remain in input and buffer. + // + // The image_decoder is the one returned by SelectDecoder (if SelectDecoder + // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr, + // ownership moves to the Done implementation. + // + // Do not keep a reference to buffer or buffer.data.ptr after Done returns, + // as DecodeImage may then de-allocate the backing array. + // + // The default Done implementation is a no-op, other than running the + // image_decoder unique_ptr destructor. + virtual void // + Done(DecodeImageResult& result, + sync_io::Input& input, + IOBuffer& buffer, + wuffs_base__image_decoder::unique_ptr image_decoder); +}; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { - const wuffs_base__token_decoder__func_ptrs* func_ptrs = - (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->get_quirk)(self, a_key); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } +extern const char DecodeImage_BufferIsTooShort[]; +extern const char DecodeImage_MaxInclDimensionExceeded[]; +extern const char DecodeImage_MaxInclMetadataLengthExceeded[]; +extern const char DecodeImage_OutOfMemory[]; +extern const char DecodeImage_UnexpectedEndOfFile[]; +extern const char DecodeImage_UnsupportedImageFormat[]; +extern const char DecodeImage_UnsupportedMetadata[]; +extern const char DecodeImage_UnsupportedPixelBlend[]; +extern const char DecodeImage_UnsupportedPixelConfiguration[]; +extern const char DecodeImage_UnsupportedPixelFormat[]; - return 0; -} +// The FooArgBar types add structure to Foo's optional arguments. They wrap +// inner representations for several reasons: +// - It provides a home for the DefaultValue static method, for Foo callers +// that want to override some but not all optional arguments. +// - It provides the "Bar" name at Foo call sites, which can help self- +// document Foo calls with many arguemnts. +// - It provides some type safety against accidentally transposing or omitting +// adjacent fundamentally-numeric-typed optional arguments. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_base__token_decoder__history_retain_length( - const wuffs_base__token_decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +// DecodeImageArgQuirks wraps an optional argument to DecodeImage. +struct DecodeImageArgQuirks { + explicit DecodeImageArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { - const wuffs_base__token_decoder__func_ptrs* func_ptrs = - (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->history_retain_length)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // DefaultValue returns an empty slice. + static DecodeImageArgQuirks DefaultValue(); - return 0; -} + const QuirkKeyValuePair* ptr; + const size_t len; +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_base__token_decoder__set_quirk( - wuffs_base__token_decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +// DecodeImageArgFlags wraps an optional argument to DecodeImage. +struct DecodeImageArgFlags { + explicit DecodeImageArgFlags(uint64_t repr0); - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { - const wuffs_base__token_decoder__func_ptrs* func_ptrs = - (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->set_quirk)(self, a_key, a_value); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + // DefaultValue returns 0. + static DecodeImageArgFlags DefaultValue(); - return wuffs_base__make_status(wuffs_base__error__bad_vtable); -} + // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF, + // GAMA, ICCP, KVP, SRGB and XMP. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_base__token_decoder__workbuf_len( - const wuffs_base__token_decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } + // Background Color. + static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001; + // Primary Chromaticities and White Point. + static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002; + // Exchangeable Image File Format. + static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004; + // Gamma Correction. + static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008; + // International Color Consortium Profile. + static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010; + // Key-Value Pair. + // + // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the + // HandleMetadata callback, the raw argument contains UTF-8 strings. + static constexpr uint64_t REPORT_METADATA_KVP = 0x0020; + // Modification Time. + static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040; + // Offset (2-Dimensional). + static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080; + // Physical Dimensions. + static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100; + // Standard Red Green Blue (Rendering Intent). + static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200; + // Extensible Metadata Platform. + static constexpr uint64_t REPORT_METADATA_XMP = 0x0400; - const wuffs_base__vtable* v = &self->private_impl.first_vtable; - int i; - for (i = 0; i < 63; i++) { - if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { - const wuffs_base__token_decoder__func_ptrs* func_ptrs = - (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); - return (*func_ptrs->workbuf_len)(self); - } else if (v->vtable_name == NULL) { - break; - } - v++; - } + uint64_t repr; +}; - return wuffs_base__utility__empty_range_ii_u64(); -} +// DecodeImageArgPixelBlend wraps an optional argument to DecodeImage. +struct DecodeImageArgPixelBlend { + explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0); -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES) + // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC. + static DecodeImageArgPixelBlend DefaultValue(); -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV) + wuffs_base__pixel_blend repr; +}; -// ---------------- IEEE 754 Floating Point +// DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage. +struct DecodeImageArgBackgroundColor { + explicit DecodeImageArgBackgroundColor( + wuffs_base__color_u32_argb_premul repr0); -// The etc__hpd_left_shift and etc__powers_of_5 tables were printed by -// script/print-hpd-left-shift.go. That script has an optional -comments flag, -// whose output is not copied here, which prints further detail. -// -// These tables are used in -// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits. + // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul. + static DecodeImageArgBackgroundColor DefaultValue(); + + wuffs_base__color_u32_argb_premul repr; +}; + +// DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage. +struct DecodeImageArgMaxInclDimension { + explicit DecodeImageArgMaxInclDimension(uint32_t repr0); + + // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels. + static DecodeImageArgMaxInclDimension DefaultValue(); + + uint32_t repr; +}; + +// DecodeImageArgMaxInclMetadataLength wraps an optional argument to +// DecodeImage. +struct DecodeImageArgMaxInclMetadataLength { + explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0); + + // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB. + static DecodeImageArgMaxInclMetadataLength DefaultValue(); + + uint64_t repr; +}; -// wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of -// new digits created after multiplying a positive integer by (1 << i): the -// additional length in the decimal representation. For example, shifting "234" -// by 3 (equivalent to multiplying by 8) will produce "1872". Going from a -// 3-length string to a 4-length string means that 1 new digit was added (and -// existing digits may have changed). +// DecodeImage decodes the image data in input. A variety of image file formats +// can be decoded, depending on what callbacks.SelectDecoder returns. // -// Shifting by i can add either N or N-1 new digits, depending on whether the -// original positive integer compares >= or < to the i'th power of 5 (as 10 -// equals 2 * 5). Comparison is lexicographic, not numerical. +// For animated formats, only the first frame is returned, since the API is +// simpler for synchronous I/O and having DecodeImage only return when +// completely done, but rendering animation often involves handling other +// events in between animation frames. To decode multiple frames of animated +// images, or for asynchronous I/O (e.g. when decoding an image streamed over +// the network), use Wuffs' lower level C API instead of its higher level, +// simplified C++ API (the wuffs_aux API). // -// For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new -// digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625": -// - ("1" << 4) is "16", which adds 1 new digit. -// - ("5678" << 4) is "90848", which adds 1 new digit. -// - ("624" << 4) is "9984", which adds 1 new digit. -// - ("62498" << 4) is "999968", which adds 1 new digit. -// - ("625" << 4) is "10000", which adds 2 new digits. -// - ("625001" << 4) is "10000016", which adds 2 new digits. -// - ("7008" << 4) is "112128", which adds 2 new digits. -// - ("99" << 4) is "1584", which adds 2 new digits. +// The DecodeImageResult's fields depend on whether decoding succeeded: +// - On total success, the error_message is empty and pixbuf.pixcfg.is_valid() +// is true. +// - On partial success (e.g. the input file was truncated but we are still +// able to decode some of the pixels), error_message is non-empty but +// pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to +// accept or reject partial success. +// - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid() +// is false. // -// Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift -// array encodes this as: -// - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006. -// - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009. -// where the ? isn't relevant for i == 4. +// The callbacks allocate the pixel buffer memory and work buffer memory. On +// success, pixel buffer memory ownership is passed to the DecodeImage caller +// as the returned pixbuf_mem_owner. Regardless of success or failure, the work +// buffer memory is deleted. // -// The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two -// possible number of new digits. The low 11 bits are an offset into the -// etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i -// is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9] -// is the string "\x06\x02\x05", so the relevant power of 5 is "625". +// The pixel_blend (one of the constants listed below) determines how to +// composite the decoded image over the pixel buffer's original pixels (as +// returned by callbacks.AllocPixbuf): +// - WUFFS_BASE__PIXEL_BLEND__SRC +// - WUFFS_BASE__PIXEL_BLEND__SRC_OVER // -// Thanks to Ken Thompson for the original idea. -static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = { - 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, - 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, - 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, - 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0, - 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA, - 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, - 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, - 0x051C, 0x051C, -}; - -// wuffs_base__private_implementation__powers_of_5 contains the powers of 5, -// concatenated together: "5", "25", "125", "625", "3125", etc. -static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = { - 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, - 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, - 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, - 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0, - 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5, - 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1, - 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, - 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, - 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, - 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, - 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, - 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6, - 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, - 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, - 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, - 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8, - 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, - 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, - 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, - 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, - 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, - 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, - 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, - 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5, - 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, - 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, - 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, - 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8, - 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4, - 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0, - 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, - 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, - 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, - 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, - 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4, - 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3, - 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, - 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, - 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, - 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, - 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, - 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, - 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, - 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, - 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, - 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, - 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6, - 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1, - 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, - 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, - 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, - 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3, - 6, 9, 1, 4, 0, 6, 2, 5, -}; +// The background_color is used to fill the pixel buffer after +// callbacks.AllocPixbuf returns, if it is valid in the +// wuffs_base__color_u32_argb_premul__is_valid sense. The default value, +// 0x0000_0001, is not valid since its Blue channel value (0x01) is greater +// than its Alpha channel value (0x00). A valid background_color will typically +// be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might +// still be visible on partial (not total) success or when pixel_blend is +// WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque. +// +// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's +// width or height is greater than max_incl_dimension or if any opted-in (via +// flags bits) metadata is longer than max_incl_metadata_length. +DecodeImageResult // +DecodeImage(DecodeImageCallbacks& callbacks, + sync_io::Input& input, + DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(), + DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(), + DecodeImageArgPixelBlend pixel_blend = + DecodeImageArgPixelBlend::DefaultValue(), + DecodeImageArgBackgroundColor background_color = + DecodeImageArgBackgroundColor::DefaultValue(), + DecodeImageArgMaxInclDimension max_incl_dimension = + DecodeImageArgMaxInclDimension::DefaultValue(), + DecodeImageArgMaxInclMetadataLength max_incl_metadata_length = + DecodeImageArgMaxInclMetadataLength::DefaultValue()); -// -------- +} // namespace wuffs_aux -// wuffs_base__private_implementation__powers_of_10 contains truncated -// approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive, -// as 596 pairs of uint64_t values (a 128-bit mantissa). -// -// There's also an implicit third column (implied by a linear formula involving -// the base-10 exponent) that is the base-2 exponent, biased by a magic -// constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias -// for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and -// wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with -// multiples-of-64-bit mantissas. -// -// For example, the third row holds the approximation to 1e-305: -// 0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE)) -// -// Similarly, 1e+4 is approximated by: -// 0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE)) -// -// Similarly, 1e+68 is approximated by: -// 0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE)) -// -// This table was generated by by script/print-mpb-powers-of-10.go -static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] = - { - {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307 - {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306 - {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305 - {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304 - {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303 - {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302 - {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301 - {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300 - {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299 - {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298 - {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297 - {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296 - {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295 - {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294 - {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293 - {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292 - {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291 - {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290 - {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289 - {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288 - {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287 - {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286 - {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285 - {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284 - {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283 - {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282 - {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281 - {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280 - {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279 - {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278 - {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277 - {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276 - {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275 - {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274 - {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273 - {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272 - {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271 - {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270 - {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269 - {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268 - {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267 - {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266 - {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265 - {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264 - {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263 - {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262 - {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261 - {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260 - {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259 - {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258 - {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257 - {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256 - {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255 - {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254 - {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253 - {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252 - {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251 - {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250 - {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249 - {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248 - {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247 - {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246 - {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245 - {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244 - {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243 - {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242 - {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241 - {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240 - {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239 - {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238 - {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237 - {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236 - {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235 - {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234 - {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233 - {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232 - {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231 - {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230 - {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229 - {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228 - {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227 - {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226 - {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225 - {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224 - {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223 - {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222 - {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221 - {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220 - {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219 - {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218 - {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217 - {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216 - {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215 - {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214 - {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213 - {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212 - {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211 - {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210 - {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209 - {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208 - {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207 - {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206 - {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205 - {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204 - {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203 - {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202 - {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201 - {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200 - {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199 - {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198 - {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197 - {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196 - {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195 - {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194 - {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193 - {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192 - {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191 - {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190 - {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189 - {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188 - {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187 - {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186 - {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185 - {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184 - {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183 - {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182 - {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181 - {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180 - {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179 - {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178 - {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177 - {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176 - {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175 - {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174 - {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173 - {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172 - {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171 - {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170 - {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169 - {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168 - {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167 - {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166 - {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165 - {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164 - {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163 - {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162 - {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161 - {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160 - {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159 - {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158 - {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157 - {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156 - {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155 - {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154 - {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153 - {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152 - {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151 - {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150 - {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149 - {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148 - {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147 - {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146 - {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145 - {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144 - {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143 - {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142 - {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141 - {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140 - {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139 - {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138 - {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137 - {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136 - {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135 - {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134 - {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133 - {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132 - {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131 - {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130 - {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129 - {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128 - {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127 - {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126 - {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125 - {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124 - {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123 - {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122 - {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121 - {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120 - {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119 - {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118 - {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117 - {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116 - {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115 - {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114 - {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113 - {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112 - {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111 - {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110 - {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109 - {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108 - {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107 - {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106 - {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105 - {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104 - {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103 - {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102 - {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101 - {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100 - {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99 - {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98 - {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97 - {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96 - {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95 - {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94 - {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93 - {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92 - {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91 - {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90 - {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89 - {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88 - {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87 - {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86 - {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85 - {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84 - {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83 - {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82 - {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81 - {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80 - {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79 - {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78 - {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77 - {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76 - {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75 - {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74 - {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73 - {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72 - {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71 - {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70 - {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69 - {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68 - {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67 - {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66 - {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65 - {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64 - {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63 - {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62 - {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61 - {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60 - {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59 - {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58 - {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57 - {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56 - {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55 - {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54 - {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53 - {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52 - {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51 - {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50 - {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49 - {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48 - {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47 - {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46 - {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45 - {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44 - {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43 - {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42 - {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41 - {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40 - {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39 - {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38 - {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37 - {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36 - {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35 - {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34 - {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33 - {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32 - {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31 - {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30 - {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29 - {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28 - {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27 - {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26 - {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25 - {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24 - {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23 - {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22 - {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21 - {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20 - {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19 - {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18 - {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17 - {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16 - {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15 - {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14 - {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13 - {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12 - {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11 - {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10 - {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9 - {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8 - {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7 - {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6 - {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5 - {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4 - {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3 - {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2 - {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1 - {0x0000000000000000, 0x8000000000000000}, // 1e0 - {0x0000000000000000, 0xA000000000000000}, // 1e1 - {0x0000000000000000, 0xC800000000000000}, // 1e2 - {0x0000000000000000, 0xFA00000000000000}, // 1e3 - {0x0000000000000000, 0x9C40000000000000}, // 1e4 - {0x0000000000000000, 0xC350000000000000}, // 1e5 - {0x0000000000000000, 0xF424000000000000}, // 1e6 - {0x0000000000000000, 0x9896800000000000}, // 1e7 - {0x0000000000000000, 0xBEBC200000000000}, // 1e8 - {0x0000000000000000, 0xEE6B280000000000}, // 1e9 - {0x0000000000000000, 0x9502F90000000000}, // 1e10 - {0x0000000000000000, 0xBA43B74000000000}, // 1e11 - {0x0000000000000000, 0xE8D4A51000000000}, // 1e12 - {0x0000000000000000, 0x9184E72A00000000}, // 1e13 - {0x0000000000000000, 0xB5E620F480000000}, // 1e14 - {0x0000000000000000, 0xE35FA931A0000000}, // 1e15 - {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16 - {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17 - {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18 - {0x0000000000000000, 0x8AC7230489E80000}, // 1e19 - {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20 - {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21 - {0x0000000000000000, 0x878678326EAC9000}, // 1e22 - {0x0000000000000000, 0xA968163F0A57B400}, // 1e23 - {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24 - {0x0000000000000000, 0x84595161401484A0}, // 1e25 - {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26 - {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27 - {0x4000000000000000, 0x813F3978F8940984}, // 1e28 - {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29 - {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30 - {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31 - {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32 - {0x6C28000000000000, 0xC5371912364CE305}, // 1e33 - {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34 - {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35 - {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36 - {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37 - {0x1314448000000000, 0x96769950B50D88F4}, // 1e38 - {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39 - {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40 - {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41 - {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42 - {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43 - {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44 - {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45 - {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46 - {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47 - {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48 - {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49 - {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50 - {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51 - {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52 - {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53 - {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54 - {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55 - {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56 - {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57 - {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58 - {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59 - {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60 - {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61 - {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62 - {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63 - {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64 - {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65 - {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66 - {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67 - {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68 - {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69 - {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70 - {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71 - {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72 - {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73 - {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74 - {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75 - {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76 - {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77 - {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78 - {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79 - {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80 - {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81 - {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82 - {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83 - {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84 - {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85 - {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86 - {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87 - {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88 - {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89 - {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90 - {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91 - {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92 - {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93 - {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94 - {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95 - {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96 - {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97 - {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98 - {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99 - {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100 - {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101 - {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102 - {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103 - {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104 - {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105 - {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106 - {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107 - {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108 - {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109 - {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110 - {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111 - {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112 - {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113 - {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114 - {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115 - {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116 - {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117 - {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118 - {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119 - {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120 - {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121 - {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122 - {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123 - {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124 - {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125 - {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126 - {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127 - {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128 - {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129 - {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130 - {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131 - {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132 - {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133 - {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134 - {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135 - {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136 - {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137 - {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138 - {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139 - {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140 - {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141 - {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142 - {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143 - {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144 - {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145 - {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146 - {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147 - {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148 - {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149 - {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150 - {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151 - {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152 - {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153 - {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154 - {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155 - {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156 - {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157 - {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158 - {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159 - {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160 - {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161 - {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162 - {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163 - {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164 - {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165 - {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166 - {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167 - {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168 - {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169 - {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170 - {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171 - {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172 - {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173 - {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174 - {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175 - {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176 - {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177 - {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178 - {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179 - {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180 - {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181 - {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182 - {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183 - {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184 - {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185 - {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186 - {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187 - {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188 - {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189 - {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190 - {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191 - {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192 - {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193 - {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194 - {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195 - {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196 - {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197 - {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198 - {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199 - {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200 - {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201 - {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202 - {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203 - {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204 - {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205 - {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206 - {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207 - {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208 - {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209 - {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210 - {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211 - {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212 - {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213 - {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214 - {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215 - {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216 - {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217 - {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218 - {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219 - {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220 - {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221 - {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222 - {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223 - {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224 - {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225 - {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226 - {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227 - {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228 - {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229 - {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230 - {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231 - {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232 - {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233 - {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234 - {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235 - {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236 - {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237 - {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238 - {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239 - {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240 - {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241 - {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242 - {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243 - {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244 - {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245 - {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246 - {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247 - {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248 - {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249 - {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250 - {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251 - {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252 - {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253 - {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254 - {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255 - {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256 - {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257 - {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258 - {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259 - {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260 - {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261 - {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262 - {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263 - {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264 - {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265 - {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266 - {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267 - {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268 - {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269 - {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270 - {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271 - {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272 - {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273 - {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274 - {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275 - {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276 - {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277 - {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278 - {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279 - {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280 - {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281 - {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282 - {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283 - {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284 - {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285 - {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286 - {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287 - {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288 -}; +// ---------------- Auxiliary - JSON -// wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that -// can be exactly represented by a float64 (what C calls a double). -static const double wuffs_base__private_implementation__f64_powers_of_10[23] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, - 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, +namespace wuffs_aux { + +struct DecodeJsonResult { + DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0); + + std::string error_message; + uint64_t cursor_position; }; -// ---------------- IEEE 754 Floating Point +class DecodeJsonCallbacks { + public: + virtual ~DecodeJsonCallbacks(); -WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 // -wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) { - uint64_t u = 0; - if (sizeof(uint64_t) == sizeof(double)) { - memcpy(&u, &f, sizeof(uint64_t)); - } - uint16_t neg = ((uint16_t)((u >> 63) << 15)); - u &= 0x7FFFFFFFFFFFFFFF; - uint64_t exp = u >> 52; - uint64_t man = u & 0x000FFFFFFFFFFFFF; + // AppendXxx are called for leaf nodes: literals, numbers and strings. For + // strings, the Callbacks implementation is responsible for tracking map keys + // versus other values. - if (exp == 0x7FF) { - if (man == 0) { // Infinity. - wuffs_base__lossy_value_u16 ret; - ret.value = neg | 0x7C00; - ret.lossy = false; - return ret; - } - // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most - // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9 - // bits of ret.value so that the 10-bit mantissa is non-zero. - wuffs_base__lossy_value_u16 ret; - ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42)); - ret.lossy = false; - return ret; + virtual std::string AppendNull() = 0; + virtual std::string AppendBool(bool val) = 0; + virtual std::string AppendF64(double val) = 0; + virtual std::string AppendI64(int64_t val) = 0; + virtual std::string AppendTextString(std::string&& val) = 0; - } else if (exp > 0x40E) { // Truncate to the largest finite f16. - wuffs_base__lossy_value_u16 ret; - ret.value = neg | 0x7BFF; - ret.lossy = true; - return ret; + // Push and Pop are called for container nodes: JSON arrays (lists) and JSON + // objects (dictionaries). + // + // The flags bits combine exactly one of: + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT + // and exactly one of: + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST + // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT - } else if (exp <= 0x3E6) { // Truncate to zero. - wuffs_base__lossy_value_u16 ret; - ret.value = neg; - ret.lossy = (u != 0); - return ret; + virtual std::string Push(uint32_t flags) = 0; + virtual std::string Pop(uint32_t flags) = 0; - } else if (exp <= 0x3F0) { // Normal f64, subnormal f16. - // Convert from a 53-bit mantissa (after realizing the implicit bit) to a - // 10-bit mantissa and then adjust for the exponent. - man |= 0x0010000000000000; - uint32_t shift = ((uint32_t)(1051 - exp)); // 1051 = 0x3F0 + 53 - 10. - uint64_t shifted_man = man >> shift; - wuffs_base__lossy_value_u16 ret; - ret.value = neg | ((uint16_t)shifted_man); - ret.lossy = (shifted_man << shift) != man; - return ret; - } + // Done is always the last Callback method called by DecodeJson, whether or + // not parsing the input as JSON encountered an error. Even when successful, + // trailing data may remain in input and buffer. See "Unintuitive JSON + // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON + // parsing and when it stops. + // + // Do not keep a reference to buffer or buffer.data.ptr after Done returns, + // as DecodeJson may then de-allocate the backing array. + // + // The default Done implementation is a no-op. + virtual void // + Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer); +}; - // Normal f64, normal f16. +extern const char DecodeJson_BadJsonPointer[]; +extern const char DecodeJson_NoMatch[]; - // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits. - exp = (exp - 1008) << 10; // 1008 = 1023 - 15 = 0x3FF - 0xF. +// The FooArgBar types add structure to Foo's optional arguments. They wrap +// inner representations for several reasons: +// - It provides a home for the DefaultValue static method, for Foo callers +// that want to override some but not all optional arguments. +// - It provides the "Bar" name at Foo call sites, which can help self- +// document Foo calls with many arguemnts. +// - It provides some type safety against accidentally transposing or omitting +// adjacent fundamentally-numeric-typed optional arguments. - // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit - // mantissa (again excluding the implicit bit). We lose some information if - // any of the bottom 42 bits are non-zero. - wuffs_base__lossy_value_u16 ret; - ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42)); - ret.lossy = (man << 22) != 0; - return ret; -} +// DecodeJsonArgQuirks wraps an optional argument to DecodeJson. +struct DecodeJsonArgQuirks { + explicit DecodeJsonArgQuirks(const QuirkKeyValuePair* ptr0, + const size_t len0); -WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 // -wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) { - uint64_t u = 0; - if (sizeof(uint64_t) == sizeof(double)) { - memcpy(&u, &f, sizeof(uint64_t)); - } - uint32_t neg = ((uint32_t)(u >> 63)) << 31; - u &= 0x7FFFFFFFFFFFFFFF; - uint64_t exp = u >> 52; - uint64_t man = u & 0x000FFFFFFFFFFFFF; + // DefaultValue returns an empty slice. + static DecodeJsonArgQuirks DefaultValue(); - if (exp == 0x7FF) { - if (man == 0) { // Infinity. - wuffs_base__lossy_value_u32 ret; - ret.value = neg | 0x7F800000; - ret.lossy = false; - return ret; - } - // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most - // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22 - // bits of ret.value so that the 23-bit mantissa is non-zero. - wuffs_base__lossy_value_u32 ret; - ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29)); - ret.lossy = false; - return ret; + const QuirkKeyValuePair* ptr; + const size_t len; +}; - } else if (exp > 0x47E) { // Truncate to the largest finite f32. - wuffs_base__lossy_value_u32 ret; - ret.value = neg | 0x7F7FFFFF; - ret.lossy = true; - return ret; +// DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson. +struct DecodeJsonArgJsonPointer { + explicit DecodeJsonArgJsonPointer(std::string repr0); - } else if (exp <= 0x369) { // Truncate to zero. - wuffs_base__lossy_value_u32 ret; - ret.value = neg; - ret.lossy = (u != 0); - return ret; + // DefaultValue returns an empty string. + static DecodeJsonArgJsonPointer DefaultValue(); - } else if (exp <= 0x380) { // Normal f64, subnormal f32. - // Convert from a 53-bit mantissa (after realizing the implicit bit) to a - // 23-bit mantissa and then adjust for the exponent. - man |= 0x0010000000000000; - uint32_t shift = ((uint32_t)(926 - exp)); // 926 = 0x380 + 53 - 23. - uint64_t shifted_man = man >> shift; - wuffs_base__lossy_value_u32 ret; - ret.value = neg | ((uint32_t)shifted_man); - ret.lossy = (shifted_man << shift) != man; - return ret; - } + std::string repr; +}; - // Normal f64, normal f32. +// DecodeJson calls callbacks based on the JSON-formatted data in input. +// +// On success, the returned error_message is empty and cursor_position counts +// the number of bytes consumed. On failure, error_message is non-empty and +// cursor_position is the location of the error. That error may be a content +// error (invalid JSON) or an input error (e.g. network failure). +// +// json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks +// run for the input's sub-node that matches the query. DecodeJson_NoMatch is +// returned if no matching sub-node was found. The empty query matches the +// input's root node, consistent with JSON Pointer semantics. +// +// The JSON Pointer implementation is greedy: duplicate keys are not rejected +// but only the first match for each '/'-separated fragment is followed. +DecodeJsonResult // +DecodeJson(DecodeJsonCallbacks& callbacks, + sync_io::Input& input, + DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(), + DecodeJsonArgJsonPointer json_pointer = + DecodeJsonArgJsonPointer::DefaultValue()); - // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits. - exp = (exp - 896) << 23; // 896 = 1023 - 127 = 0x3FF - 0x7F. +} // namespace wuffs_aux - // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit - // mantissa (again excluding the implicit bit). We lose some information if - // any of the bottom 29 bits are non-zero. - wuffs_base__lossy_value_u32 ret; - ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29)); - ret.lossy = (man << 35) != 0; - return ret; -} +#endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR) -// -------- +// ‼ WUFFS C HEADER ENDS HERE. +#ifdef WUFFS_IMPLEMENTATION -#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047 -#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800 +#ifdef __cplusplus +extern "C" { +#endif -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N -// such that ((10 << N) < (1 << 64)). -#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60 +// ---------------- Fundamentals -// wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a -// fixed precision floating point decimal number, augmented with ±infinity -// values, but it cannot represent NaN (Not a Number). +// WUFFS_BASE__MAGIC is a magic number to check that initializers are called. +// It's not foolproof, given C doesn't automatically zero memory before use, +// but it should catch 99.99% of cases. // -// "High precision" means that the mantissa holds 800 decimal digits. 800 is -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION. +// Its (non-zero) value is arbitrary, based on md5sum("wuffs"). +#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71) + +// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable +// error was previously encountered. // -// An HPD isn't for general purpose arithmetic, only for conversions to and -// from IEEE 754 double-precision floating point, where the largest and -// smallest positive, finite values are approximately 1.8e+308 and 4.9e-324. -// HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047 -// bounds are further away from zero than ±(324 + 800), where 800 and 2047 is -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE. +// Its (non-zero) value is arbitrary, based on md5sum("disabled"). +#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2) + +// Use switch cases for coroutine suspension points, similar to the technique +// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html // -// digits[.. num_digits] are the number's digits in big-endian order. The -// uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7' -// is the ASCII value 0x37. +// The implicit fallthrough is intentional. // -// decimal_point is the index (within digits) of the decimal point. It may be -// negative or be larger than num_digits, in which case the explicit digits are -// padded with implicit zeroes. +// We use trivial macros instead of an explicit assignment and case statement +// so that clang-format doesn't get confused by the unusual "case"s. +#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:; +#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \ + coro_susp_point = n; \ + case n:; + +#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \ + if (!status.repr) { \ + goto ok; \ + } else if (*status.repr != '$') { \ + goto exit; \ + } \ + coro_susp_point = n; \ + goto suspend; \ + case n:; + +// The "defined(__clang__)" isn't redundant. While vanilla clang defines +// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not. +#if defined(__GNUC__) || defined(__clang__) +#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1)) +#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0)) +#else +#define WUFFS_BASE__LIKELY(expr) (expr) +#define WUFFS_BASE__UNLIKELY(expr) (expr) +#endif + +// -------- + +static inline wuffs_base__empty_struct // +wuffs_private_impl__ignore_status(wuffs_base__status z) { + return wuffs_base__make_empty_struct(); +} + +static inline wuffs_base__status // +wuffs_private_impl__status__ensure_not_a_suspension(wuffs_base__status z) { + if (z.repr && (*z.repr == '$')) { + z.repr = wuffs_base__error__cannot_return_a_suspension; + } + return z; +} + +// -------- + +// wuffs_private_impl__iterate_total_advance returns the exclusive +// pointer-offset at which iteration should stop. The overall slice has length +// total_len, each iteration's sub-slice has length iter_len and are placed +// iter_advance apart. // -// For example, if num_digits is 3 and digits is "\x07\x08\x09": -// - A decimal_point of -2 means ".00789" -// - A decimal_point of -1 means ".0789" -// - A decimal_point of +0 means ".789" -// - A decimal_point of +1 means "7.89" -// - A decimal_point of +2 means "78.9" -// - A decimal_point of +3 means "789." -// - A decimal_point of +4 means "7890." -// - A decimal_point of +5 means "78900." +// The iter_advance may not be larger than iter_len. The iter_advance may be +// smaller than iter_len, in which case the sub-slices will overlap. // -// As above, a decimal_point higher than +2047 means that the overall value is -// infinity, lower than -2047 means zero. +// The return value r satisfies ((0 <= r) && (r <= total_len)). // -// negative is a sign bit. An HPD can distinguish positive and negative zero. +// For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are +// four iterations at offsets 0, 3, 6 and 9. This function returns 12. // -// truncated is whether there are more than -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at -// least one of those extra digits are non-zero. The existence of long-tail -// digits can affect rounding. +// 0123456789012345 +// [....] +// [....] +// [....] +// [....] +// $ +// 0123456789012345 // -// The "all fields are zero" value is valid, and represents the number +0. -typedef struct wuffs_base__private_implementation__high_prec_dec__struct { - uint32_t num_digits; - int32_t decimal_point; - bool negative; - bool truncated; - uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION]; -} wuffs_base__private_implementation__high_prec_dec; - -// wuffs_base__private_implementation__high_prec_dec__trim trims trailing -// zeroes from the h->digits[.. h->num_digits] slice. They have no benefit, -// since we explicitly track h->decimal_point. +// For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are +// three iterations at offsets 0, 5 and 10. This function returns 15. // -// Preconditions: -// - h is non-NULL. -static inline void // -wuffs_base__private_implementation__high_prec_dec__trim( - wuffs_base__private_implementation__high_prec_dec* h) { - while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) { - h->num_digits--; +// 0123456789012345 +// [....] +// [....] +// [....] +// $ +// 0123456789012345 +static inline size_t // +wuffs_private_impl__iterate_total_advance(size_t total_len, + size_t iter_len, + size_t iter_advance) { + if (total_len >= iter_len) { + size_t n = total_len - iter_len; + return ((n / iter_advance) * iter_advance) + iter_advance; } + return 0; } -// wuffs_base__private_implementation__high_prec_dec__assign sets h to -// represent the number x. -// -// Preconditions: -// - h is non-NULL. -static void // -wuffs_base__private_implementation__high_prec_dec__assign( - wuffs_base__private_implementation__high_prec_dec* h, - uint64_t x, - bool negative) { - uint32_t n = 0; +// ---------------- Numeric Types - // Set h->digits. - if (x > 0) { - // Calculate the digits, working right-to-left. After we determine n (how - // many digits there are), copy from buf to h->digits. - // - // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to - // copy a constant number of bytes than a variable number (20 instead of - // n). Make buf large enough (and start writing to it from the middle) so - // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)]. - uint8_t buf[40] = {0}; - uint8_t* ptr = &buf[20]; - do { - uint64_t remaining = x / 10; - x -= remaining * 10; - ptr--; - *ptr = (uint8_t)x; - n++; - x = remaining; - } while (x > 0); - memcpy(h->digits, ptr, 20); - } +extern const uint8_t wuffs_private_impl__low_bits_mask__u8[8]; +extern const uint16_t wuffs_private_impl__low_bits_mask__u16[16]; +extern const uint32_t wuffs_private_impl__low_bits_mask__u32[32]; +extern const uint64_t wuffs_private_impl__low_bits_mask__u64[64]; - // Set h's other fields. - h->num_digits = n; - h->decimal_point = (int32_t)n; - h->negative = negative; - h->truncated = false; - wuffs_base__private_implementation__high_prec_dec__trim(h); +#define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U8(n) \ + (wuffs_private_impl__low_bits_mask__u8[n]) +#define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U16(n) \ + (wuffs_private_impl__low_bits_mask__u16[n]) +#define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(n) \ + (wuffs_private_impl__low_bits_mask__u32[n]) +#define WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(n) \ + (wuffs_private_impl__low_bits_mask__u64[n]) + +// -------- + +static inline void // +wuffs_private_impl__u8__sat_add_indirect(uint8_t* x, uint8_t y) { + *x = wuffs_base__u8__sat_add(*x, y); } -static wuffs_base__status // -wuffs_base__private_implementation__high_prec_dec__parse( - wuffs_base__private_implementation__high_prec_dec* h, - wuffs_base__slice_u8 s, - uint32_t options) { - if (!h) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - h->num_digits = 0; - h->decimal_point = 0; - h->negative = false; - h->truncated = false; +static inline void // +wuffs_private_impl__u8__sat_sub_indirect(uint8_t* x, uint8_t y) { + *x = wuffs_base__u8__sat_sub(*x, y); +} - uint8_t* p = s.ptr; - uint8_t* q = s.ptr + s.len; +static inline void // +wuffs_private_impl__u16__sat_add_indirect(uint16_t* x, uint16_t y) { + *x = wuffs_base__u16__sat_add(*x, y); +} - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (;; p++) { - if (p >= q) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } else if (*p != '_') { - break; - } - } - } +static inline void // +wuffs_private_impl__u16__sat_sub_indirect(uint16_t* x, uint16_t y) { + *x = wuffs_base__u16__sat_sub(*x, y); +} - // Parse sign. - do { - if (*p == '+') { - p++; - } else if (*p == '-') { - h->negative = true; - p++; - } else { - break; - } - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (;; p++) { - if (p >= q) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } else if (*p != '_') { - break; - } - } - } - } while (0); +static inline void // +wuffs_private_impl__u32__sat_add_indirect(uint32_t* x, uint32_t y) { + *x = wuffs_base__u32__sat_add(*x, y); +} - // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each - // limb in this if-else chain: - // - "0.789" - // - "1002.789" - // - ".789" - // - Other (invalid input). - uint32_t nd = 0; - int32_t dp = 0; - bool no_digits_before_separator = false; - if (('0' == *p) && - !(options & - WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) { - p++; - for (;; p++) { - if (p >= q) { - goto after_all; - } else if (*p == - ((options & - WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.')) { - p++; - goto after_sep; - } else if ((*p == 'E') || (*p == 'e')) { - p++; - goto after_exp; - } else if ((*p != '_') || - !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - } +static inline void // +wuffs_private_impl__u32__sat_sub_indirect(uint32_t* x, uint32_t y) { + *x = wuffs_base__u32__sat_sub(*x, y); +} - } else if (('0' <= *p) && (*p <= '9')) { - if (*p == '0') { - for (; (p < q) && (*p == '0'); p++) { - } - } else { - h->digits[nd++] = (uint8_t)(*p - '0'); - dp = (int32_t)nd; - p++; - } +static inline void // +wuffs_private_impl__u64__sat_add_indirect(uint64_t* x, uint64_t y) { + *x = wuffs_base__u64__sat_add(*x, y); +} - for (;; p++) { - if (p >= q) { - goto after_all; - } else if (('0' <= *p) && (*p <= '9')) { - if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[nd++] = (uint8_t)(*p - '0'); - dp = (int32_t)nd; - } else if ('0' != *p) { - // Long-tail non-zeroes set the truncated bit. - h->truncated = true; - } - } else if (*p == - ((options & - WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.')) { - p++; - goto after_sep; - } else if ((*p == 'E') || (*p == 'e')) { - p++; - goto after_exp; - } else if ((*p != '_') || - !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - } +static inline void // +wuffs_private_impl__u64__sat_sub_indirect(uint64_t* x, uint64_t y) { + *x = wuffs_base__u64__sat_sub(*x, y); +} - } else if (*p == ((options & - WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.')) { - p++; - no_digits_before_separator = true; +// ---------------- Numeric Types (Utility) - } else { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } +#define wuffs_base__utility__sign_extend_convert_u8_u32(a) \ + ((uint32_t)(int32_t)(int8_t)(a)) -after_sep: - for (;; p++) { - if (p >= q) { - goto after_all; - } else if ('0' == *p) { - if (nd == 0) { - // Track leading zeroes implicitly. - dp--; - } else if (nd < - WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[nd++] = (uint8_t)(*p - '0'); - } - } else if (('0' < *p) && (*p <= '9')) { - if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[nd++] = (uint8_t)(*p - '0'); - } else { - // Long-tail non-zeroes set the truncated bit. - h->truncated = true; - } - } else if ((*p == 'E') || (*p == 'e')) { - p++; - goto after_exp; - } else if ((*p != '_') || - !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - } +#define wuffs_base__utility__sign_extend_convert_u16_u32(a) \ + ((uint32_t)(int32_t)(int16_t)(a)) -after_exp: - do { - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (;; p++) { - if (p >= q) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } else if (*p != '_') { - break; - } - } - } +#define wuffs_base__utility__sign_extend_rshift_u32(a, n) \ + ((uint32_t)(((int32_t)(a)) >> (n))) - int32_t exp_sign = +1; - if (*p == '+') { - p++; - } else if (*p == '-') { - exp_sign = -1; - p++; - } +#define wuffs_base__utility__sign_extend_rshift_u64(a, n) \ + ((uint64_t)(((int64_t)(a)) >> (n))) - int32_t exp = 0; - const int32_t exp_large = - WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + - WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION; - bool saw_exp_digits = false; - for (; p < q; p++) { - if ((*p == '_') && - (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - // No-op. - } else if (('0' <= *p) && (*p <= '9')) { - saw_exp_digits = true; - if (exp < exp_large) { - exp = (10 * exp) + ((int32_t)(*p - '0')); - } - } else { - break; - } - } - if (!saw_exp_digits) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - dp += exp_sign * exp; - } while (0); +#define wuffs_base__utility__make_bitvec256(e00, e01, e02, e03) \ + wuffs_base__make_bitvec256(e00, e01, e02, e03) -after_all: - if (p != q) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - h->num_digits = nd; - if (nd == 0) { - if (no_digits_before_separator) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - h->decimal_point = 0; - } else if (dp < - -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) { - h->decimal_point = - -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1; - } else if (dp > - +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) { - h->decimal_point = - +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1; - } else { - h->decimal_point = dp; - } - wuffs_base__private_implementation__high_prec_dec__trim(h); - return wuffs_base__make_status(NULL); -} +#define wuffs_base__utility__make_optional_u63(h, v) \ + wuffs_base__make_optional_u63(h, v) -// -------- +// ---------------- Slices and Tables -// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits -// returns the number of additional decimal digits when left-shifting by shift. +// This function basically returns (ptr + len), except that that expression is +// Undefined Behavior in C (but not C++) when ptr is NULL, even if len is zero. // -// See below for preconditions. -static uint32_t // -wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits( - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t shift) { - // Masking with 0x3F should be unnecessary (assuming the preconditions) but - // it's cheap and ensures that we don't overflow the - // wuffs_base__private_implementation__hpd_left_shift array. - shift &= 63; +// Precondition: (ptr != NULL) || (len == 0). +static inline const uint8_t* // +wuffs_private_impl__ptr_u8_plus_len(const uint8_t* ptr, size_t len) { + return ptr ? (ptr + len) : NULL; +} - uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift]; - uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1]; - uint32_t num_new_digits = x_a >> 11; - uint32_t pow5_a = 0x7FF & x_a; - uint32_t pow5_b = 0x7FF & x_b; +// -------- - const uint8_t* pow5 = - &wuffs_base__private_implementation__powers_of_5[pow5_a]; - uint32_t i = 0; - uint32_t n = pow5_b - pow5_a; - for (; i < n; i++) { - if (i >= h->num_digits) { - return num_new_digits - 1; - } else if (h->digits[i] == pow5[i]) { - continue; - } else if (h->digits[i] < pow5[i]) { - return num_new_digits - 1; - } else { - return num_new_digits; - } +// wuffs_private_impl__slice_u8__prefix returns up to the first up_to bytes of +// s. +static inline wuffs_base__slice_u8 // +wuffs_private_impl__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) { + if (((uint64_t)(s.len)) > up_to) { + s.len = ((size_t)up_to); } - return num_new_digits; + return s; } -// -------- +// wuffs_private_impl__slice_u8__suffix returns up to the last up_to bytes of +// s. +static inline wuffs_base__slice_u8 // +wuffs_private_impl__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) { + if (((uint64_t)(s.len)) > up_to) { + s.ptr += ((uint64_t)(s.len)) - up_to; + s.len = ((size_t)up_to); + } + return s; +} -// wuffs_base__private_implementation__high_prec_dec__rounded_integer returns -// the integral (non-fractional) part of h, provided that it is 18 or fewer -// decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that: -// - (1 << 53) is 9007199254740992, which has 16 decimal digits. -// - (1 << 56) is 72057594037927936, which has 17 decimal digits. -// - (1 << 59) is 576460752303423488, which has 18 decimal digits. -// - (1 << 63) is 9223372036854775808, which has 19 decimal digits. -// and that IEEE 754 double precision has 52 mantissa bits. +// wuffs_private_impl__slice_u8__copy_from_slice calls memmove(dst.ptr, +// src.ptr, len) where len is the minimum of dst.len and src.len. // -// That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8. -// -// h's negative bit is ignored: rounding -8.6 returns 9. -// -// See below for preconditions. -static uint64_t // -wuffs_base__private_implementation__high_prec_dec__rounded_integer( - wuffs_base__private_implementation__high_prec_dec* h) { - if ((h->num_digits == 0) || (h->decimal_point < 0)) { - return 0; - } else if (h->decimal_point > 18) { - return UINT64_MAX; +// Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty +// slice) is valid and results in a no-op. +static inline uint64_t // +wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src) { + size_t len = dst.len < src.len ? dst.len : src.len; + if (len > 0) { + memmove(dst.ptr, src.ptr, len); } + return len; +} - uint32_t dp = (uint32_t)(h->decimal_point); - uint64_t n = 0; - uint32_t i = 0; - for (; i < dp; i++) { - n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0); +static inline wuffs_base__empty_struct // +wuffs_private_impl__bulk_load_host_endian(void* ptr, + size_t len, + wuffs_base__slice_u8 src) { + if (len && (len <= src.len)) { + memmove(ptr, src.ptr, len); } + return wuffs_base__make_empty_struct(); +} - bool round_up = false; - if (dp < h->num_digits) { - round_up = h->digits[dp] >= 5; - if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) { - // We are exactly halfway. If we're truncated, round up, otherwise round - // to even. - round_up = h->truncated || // - ((dp > 0) && (1 & h->digits[dp - 1])); - } - } - if (round_up) { - n++; +static inline wuffs_base__empty_struct // +wuffs_private_impl__bulk_memset(void* ptr, size_t len, uint8_t byte_value) { + if (len) { + memset(ptr, byte_value, len); } + return wuffs_base__make_empty_struct(); +} - return n; +static inline wuffs_base__empty_struct // +wuffs_private_impl__bulk_save_host_endian(void* ptr, + size_t len, + wuffs_base__slice_u8 dst) { + if (len && (len <= dst.len)) { + memmove(dst.ptr, ptr, len); + } + return wuffs_base__make_empty_struct(); } -// wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's -// number (where 'x' is 'l' or 'r' for left or right) by a small shift value. -// -// Preconditions: -// - h is non-NULL. -// - h->decimal_point is "not extreme". -// - shift is non-zero. -// - shift is "a small shift". -// -// "Not extreme" means within -// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE. -// -// "A small shift" means not more than -// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL. -// -// wuffs_base__private_implementation__high_prec_dec__rounded_integer and -// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits -// have the same preconditions. -// -// wuffs_base__private_implementation__high_prec_dec__lshift keeps the first -// two preconditions but not the last two. Its shift argument is signed and -// does not need to be "small": zero is a no-op, positive means left shift and -// negative means right shift. +// -------- -static void // -wuffs_base__private_implementation__high_prec_dec__small_lshift( - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t shift) { - if (h->num_digits == 0) { - return; +static inline wuffs_base__slice_u8 // +wuffs_private_impl__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) { + if (t.ptr && (y < t.height)) { + return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width); } - uint32_t num_new_digits = - wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits( - h, shift); - uint32_t rx = h->num_digits - 1; // Read index. - uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index. - uint64_t n = 0; + return wuffs_base__empty_slice_u8(); +} - // Repeat: pick up a digit, put down a digit, right to left. - while (((int32_t)rx) >= 0) { - n += ((uint64_t)(h->digits[rx])) << shift; - uint64_t quo = n / 10; - uint64_t rem = n - (10 * quo); - if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[wx] = (uint8_t)rem; - } else if (rem > 0) { - h->truncated = true; - } - n = quo; - wx--; - rx--; - } +// ---------------- Slices and Tables (Utility) - // Put down leading digits, right to left. - while (n > 0) { - uint64_t quo = n / 10; - uint64_t rem = n - (10 * quo); - if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[wx] = (uint8_t)rem; - } else if (rem > 0) { - h->truncated = true; - } - n = quo; - wx--; - } +#define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8 - // Finish. - h->num_digits += num_new_digits; - if (h->num_digits > - WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION; - } - h->decimal_point += (int32_t)num_new_digits; - wuffs_base__private_implementation__high_prec_dec__trim(h); +// ---------------- Ranges and Rects + +static inline uint32_t // +wuffs_private_impl__range_ii_u32__get_min_incl( + const wuffs_base__range_ii_u32* r) { + return r->min_incl; } -static void // -wuffs_base__private_implementation__high_prec_dec__small_rshift( - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t shift) { - uint32_t rx = 0; // Read index. - uint32_t wx = 0; // Write index. - uint64_t n = 0; +static inline uint32_t // +wuffs_private_impl__range_ii_u32__get_max_incl( + const wuffs_base__range_ii_u32* r) { + return r->max_incl; +} - // Pick up enough leading digits to cover the first shift. - while ((n >> shift) == 0) { - if (rx < h->num_digits) { - // Read a digit. - n = (10 * n) + h->digits[rx++]; - } else if (n == 0) { - // h's number used to be zero and remains zero. - return; - } else { - // Read sufficient implicit trailing zeroes. - while ((n >> shift) == 0) { - n = 10 * n; - rx++; - } - break; - } - } - h->decimal_point -= ((int32_t)(rx - 1)); - if (h->decimal_point < - -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) { - // After the shift, h's number is effectively zero. - h->num_digits = 0; - h->decimal_point = 0; - h->truncated = false; - return; - } +static inline uint32_t // +wuffs_private_impl__range_ie_u32__get_min_incl( + const wuffs_base__range_ie_u32* r) { + return r->min_incl; +} - // Repeat: pick up a digit, put down a digit, left to right. - uint64_t mask = (((uint64_t)(1)) << shift) - 1; - while (rx < h->num_digits) { - uint8_t new_digit = ((uint8_t)(n >> shift)); - n = (10 * (n & mask)) + h->digits[rx++]; - h->digits[wx++] = new_digit; - } +static inline uint32_t // +wuffs_private_impl__range_ie_u32__get_max_excl( + const wuffs_base__range_ie_u32* r) { + return r->max_excl; +} - // Put down trailing digits, left to right. - while (n > 0) { - uint8_t new_digit = ((uint8_t)(n >> shift)); - n = 10 * (n & mask); - if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) { - h->digits[wx++] = new_digit; - } else if (new_digit > 0) { - h->truncated = true; - } - } +static inline uint64_t // +wuffs_private_impl__range_ii_u64__get_min_incl( + const wuffs_base__range_ii_u64* r) { + return r->min_incl; +} - // Finish. - h->num_digits = wx; - wuffs_base__private_implementation__high_prec_dec__trim(h); +static inline uint64_t // +wuffs_private_impl__range_ii_u64__get_max_incl( + const wuffs_base__range_ii_u64* r) { + return r->max_incl; } -static void // -wuffs_base__private_implementation__high_prec_dec__lshift( - wuffs_base__private_implementation__high_prec_dec* h, - int32_t shift) { - if (shift > 0) { - while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) { - wuffs_base__private_implementation__high_prec_dec__small_lshift( - h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL); - shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL; - } - wuffs_base__private_implementation__high_prec_dec__small_lshift( - h, ((uint32_t)(+shift))); - } else if (shift < 0) { - while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) { - wuffs_base__private_implementation__high_prec_dec__small_rshift( - h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL); - shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL; - } - wuffs_base__private_implementation__high_prec_dec__small_rshift( - h, ((uint32_t)(-shift))); - } +static inline uint64_t // +wuffs_private_impl__range_ie_u64__get_min_incl( + const wuffs_base__range_ie_u64* r) { + return r->min_incl; } -// -------- +static inline uint64_t // +wuffs_private_impl__range_ie_u64__get_max_excl( + const wuffs_base__range_ie_u64* r) { + return r->max_excl; +} -// wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's -// number. For those functions that take an n argument, rounding produces at -// most n digits (which is not necessarily at most n decimal places). Negative -// n values are ignored, as well as any n greater than or equal to h's number -// of digits. The etc__round_just_enough function implicitly chooses an n to -// implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION. -// -// Preconditions: -// - h is non-NULL. -// - h->decimal_point is "not extreme". -// -// "Not extreme" means within -// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE. +// ---------------- Ranges and Rects (Utility) -static void // -wuffs_base__private_implementation__high_prec_dec__round_down( - wuffs_base__private_implementation__high_prec_dec* h, - int32_t n) { - if ((n < 0) || (h->num_digits <= (uint32_t)n)) { - return; +#define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32 +#define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32 +#define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64 +#define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64 +#define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32 +#define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32 +#define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32 +#define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32 +#define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64 +#define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64 +#define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32 +#define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32 + +// ---------------- I/O + +static inline uint64_t // +wuffs_private_impl__io__count_since(uint64_t mark, uint64_t index) { + if (index >= mark) { + return index - mark; } - h->num_digits = (uint32_t)(n); - wuffs_base__private_implementation__high_prec_dec__trim(h); + return 0; } -static void // -wuffs_base__private_implementation__high_prec_dec__round_up( - wuffs_base__private_implementation__high_prec_dec* h, - int32_t n) { - if ((n < 0) || (h->num_digits <= (uint32_t)n)) { - return; +// TODO: drop the "const" in "const uint8_t* ptr". Some though required about +// the base.io_reader.since method returning a mutable "slice base.u8". +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +static inline wuffs_base__slice_u8 // +wuffs_private_impl__io__since(uint64_t mark, + uint64_t index, + const uint8_t* ptr) { + if (index >= mark) { + return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark, + ((size_t)(index - mark))); } + return wuffs_base__empty_slice_u8(); +} +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif - for (n--; n >= 0; n--) { - if (h->digits[n] < 9) { - h->digits[n]++; - h->num_digits = (uint32_t)(n + 1); - return; - } - } +// -------- - // The number is all 9s. Change to a single 1 and adjust the decimal point. - h->digits[0] = 1; - h->num_digits = 1; - h->decimal_point++; +static inline void // +wuffs_private_impl__io_reader__limit(const uint8_t** ptr_io2_r, + const uint8_t* iop_r, + uint64_t limit) { + if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) { + *ptr_io2_r = iop_r + limit; + } } -static void // -wuffs_base__private_implementation__high_prec_dec__round_nearest( - wuffs_base__private_implementation__high_prec_dec* h, - int32_t n) { - if ((n < 0) || (h->num_digits <= (uint32_t)n)) { - return; +static inline uint32_t // +wuffs_private_impl__io_reader__limited_copy_u32_to_slice( + const uint8_t** ptr_iop_r, + const uint8_t* io2_r, + uint32_t length, + wuffs_base__slice_u8 dst) { + const uint8_t* iop_r = *ptr_iop_r; + size_t n = dst.len; + if (n > length) { + n = length; } - bool up = h->digits[n] >= 5; - if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) { - up = h->truncated || // - ((n > 0) && ((h->digits[n - 1] & 1) != 0)); + if (n > ((size_t)(io2_r - iop_r))) { + n = (size_t)(io2_r - iop_r); } - - if (up) { - wuffs_base__private_implementation__high_prec_dec__round_up(h, n); - } else { - wuffs_base__private_implementation__high_prec_dec__round_down(h, n); + if (n > 0) { + memmove(dst.ptr, iop_r, n); + *ptr_iop_r += n; } + return (uint32_t)(n); } -static void // -wuffs_base__private_implementation__high_prec_dec__round_just_enough( - wuffs_base__private_implementation__high_prec_dec* h, - int32_t exp2, - uint64_t mantissa) { - // The magic numbers 52 and 53 in this function are because IEEE 754 double - // precision has 52 mantissa bits. - // - // Let f be the floating point number represented by exp2 and mantissa (and - // also the number in h): the number (mantissa * (2 ** (exp2 - 52))). - // - // If f is zero or a small integer, we can return early. - if ((mantissa == 0) || - ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) { - return; +// wuffs_private_impl__io_reader__match7 returns whether the io_reader's +// upcoming bytes start with the given prefix (up to 7 bytes long). It is +// peek-like, not read-like, in that there are no side-effects. +// +// The low 3 bits of a hold the prefix length, n. +// +// The high 56 bits of a hold the prefix itself, in little-endian order. The +// first prefix byte is in bits 8..=15, the second prefix byte is in bits +// 16..=23, etc. The high (8 * (7 - n)) bits are ignored. +// +// There are three possible return values: +// - 0 means success. +// - 1 means inconclusive, equivalent to "$short read". +// - 2 means failure. +static inline uint32_t // +wuffs_private_impl__io_reader__match7(const uint8_t* iop_r, + const uint8_t* io2_r, + wuffs_base__io_buffer* r, + uint64_t a) { + uint32_t n = a & 7; + a >>= 8; + if ((io2_r - iop_r) >= 8) { + uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r); + uint32_t shift = 8 * (8 - n); + return ((a << shift) == (x << shift)) ? 0 : 2; + } + for (; n > 0; n--) { + if (iop_r >= io2_r) { + return (r && r->meta.closed) ? 2 : 1; + } else if (*iop_r != ((uint8_t)(a))) { + return 2; + } + iop_r++; + a >>= 8; } + return 0; +} - // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52). - // Subnormal numbers have the same exp2 but a smaller mantissa. - static const int32_t min_incl_normal_exp2 = -1022; - static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul; +static inline wuffs_base__io_buffer* // +wuffs_private_impl__io_reader__set(wuffs_base__io_buffer* b, + const uint8_t** ptr_iop_r, + const uint8_t** ptr_io0_r, + const uint8_t** ptr_io1_r, + const uint8_t** ptr_io2_r, + wuffs_base__slice_u8 data, + uint64_t history_position) { + b->data = data; + b->meta.wi = data.len; + b->meta.ri = 0; + b->meta.pos = history_position; + b->meta.closed = false; - // Compute lower and upper bounds such that any number between them (possibly - // inclusive) will round to f. First, the lower bound. Our number f is: - // ((mantissa + 0) * (2 ** ( exp2 - 52))) - // - // The next lowest floating point number is: - // ((mantissa - 1) * (2 ** ( exp2 - 52))) - // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the - // min_incl_normal_exp2. Either way, call it: - // ((l_mantissa) * (2 ** (l_exp2 - 52))) - // - // The lower bound is halfway between them (noting that 52 became 53): - // (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53))) - int32_t l_exp2 = exp2; - uint64_t l_mantissa = mantissa - 1; - if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) { - l_exp2 = exp2 - 1; - l_mantissa = (2 * mantissa) - 1; - } - wuffs_base__private_implementation__high_prec_dec lower; - wuffs_base__private_implementation__high_prec_dec__assign( - &lower, (2 * l_mantissa) + 1, false); - wuffs_base__private_implementation__high_prec_dec__lshift(&lower, - l_exp2 - 53); + *ptr_iop_r = data.ptr; + *ptr_io0_r = data.ptr; + *ptr_io1_r = data.ptr; + *ptr_io2_r = data.ptr + data.len; - // Next, the upper bound. Our number f is: - // ((mantissa + 0) * (2 ** (exp2 - 52))) - // - // The next highest floating point number is: - // ((mantissa + 1) * (2 ** (exp2 - 52))) - // - // The upper bound is halfway between them (noting that 52 became 53): - // (((2 * mantissa) + 1) * (2 ** (exp2 - 53))) - wuffs_base__private_implementation__high_prec_dec upper; - wuffs_base__private_implementation__high_prec_dec__assign( - &upper, (2 * mantissa) + 1, false); - wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53); + return b; +} - // The lower and upper bounds are possible outputs only if the original - // mantissa is even, so that IEEE round-to-even would round to the original - // mantissa and not its neighbors. - bool inclusive = (mantissa & 1) == 0; +// -------- - // As we walk the digits, we want to know whether rounding up would fall - // within the upper bound. This is tracked by upper_delta: - // - When -1, the digits of h and upper are the same so far. - // - When +0, we saw a difference of 1 between h and upper on a previous - // digit and subsequently only 9s for h and 0s for upper. Thus, rounding - // up may fall outside of the bound if !inclusive. - // - When +1, the difference is greater than 1 and we know that rounding up - // falls within the bound. - // - // This is a state machine with three states. The numerical value for each - // state (-1, +0 or +1) isn't important, other than their order. - int upper_delta = -1; +static inline uint64_t // +wuffs_private_impl__io_writer__copy_from_slice(uint8_t** ptr_iop_w, + uint8_t* io2_w, + wuffs_base__slice_u8 src) { + uint8_t* iop_w = *ptr_iop_w; + size_t n = src.len; + if (n > ((size_t)(io2_w - iop_w))) { + n = (size_t)(io2_w - iop_w); + } + if (n > 0) { + memmove(iop_w, src.ptr, n); + *ptr_iop_w += n; + } + return (uint64_t)(n); +} - // We can now figure out the shortest number of digits required. Walk the - // digits until h has distinguished itself from lower or upper. - // - // The zi and zd variables are indexes and digits, for z in l (lower), h (the - // number) and u (upper). +static inline void // +wuffs_private_impl__io_writer__limit(uint8_t** ptr_io2_w, + uint8_t* iop_w, + uint64_t limit) { + if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) { + *ptr_io2_w = iop_w + limit; + } +} + +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + if (!distance) { + return 0; + } + uint8_t* p = *ptr_iop_w; + if ((size_t)(p - io0_w) < (size_t)(distance)) { + return 0; + } + uint8_t* q = p - distance; + size_t n = (size_t)(io2_w - p); + if ((size_t)(length) > n) { + length = (uint32_t)(n); + } else { + n = (size_t)(length); + } + // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that + // is mostly because 3 is the minimum length for the deflate format. This + // function implementation shouldn't overfit to that one format. Perhaps the + // limited_copy_u32_from_history Wuffs method should also take an unroll hint + // argument, and the cgen can look if that argument is the constant + // expression '3'. // - // The lower, h and upper numbers may have their decimal points at different - // places. In this case, upper is the longest, so we iterate ui starting from - // 0 and iterate li and hi starting from either 0 or -1. - int32_t ui = 0; - for (;; ui++) { - // Calculate hd, the middle number's digit. - int32_t hi = ui - upper.decimal_point + h->decimal_point; - if (hi >= ((int32_t)(h->num_digits))) { - break; - } - uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0; + // See also wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast + // below. + for (; n >= 3; n -= 3) { + *p++ = *q++; + *p++ = *q++; + *p++ = *q++; + } + for (; n; n--) { + *p++ = *q++; + } + *ptr_iop_w = p; + return length; +} - // Calculate ld, the lower bound's digit. - int32_t li = ui - upper.decimal_point + lower.decimal_point; - uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0; +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast is like +// the wuffs_private_impl__io_writer__limited_copy_u32_from_history function +// above, but has stronger pre-conditions. +// +// The caller needs to prove that: +// - length >= 1 +// - length <= (io2_w - *ptr_iop_w) +// - distance >= 1 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint8_t* q = p - distance; + uint32_t n = length; + for (; n >= 3; n -= 3) { + *p++ = *q++; + *p++ = *q++; + *p++ = *q++; + } + for (; n; n--) { + *p++ = *q++; + } + *ptr_iop_w = p; + return length; +} - // We can round down (truncate) if lower has a different digit than h or if - // lower is inclusive and is exactly the result of rounding down (i.e. we - // have reached the final digit of lower). - bool can_round_down = - (ld != hd) || // - (inclusive && ((li + 1) == ((int32_t)(lower.num_digits)))); +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp +// is like the +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function, +// but also returns the cusp: a byte pair (as a u16le) being the last byte of +// and next byte after the copied history. +// +// For example, if history was [10, 11, 12, 13, 14, 15, 16, 17, 18] then: +// - copying l=3, d=8 produces [11, 12, 13] and the cusp is (13, 14). +// - copying l=3, d=2 produces [17, 18, 17] and the cusp is (17, 18). +// +// The caller needs to prove that: +// - length >= 1 +// - length <= (io2_w - *ptr_iop_w) +// - distance >= 1 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint8_t* q = p - distance; + uint32_t n = length; + for (; n >= 3; n -= 3) { + *p++ = *q++; + *p++ = *q++; + *p++ = *q++; + } + for (; n; n--) { + *p++ = *q++; + } + *ptr_iop_w = p; + return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1); +} - // Calculate ud, the upper bound's digit, and update upper_delta. - uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0; - if (upper_delta < 0) { - if ((hd + 1) < ud) { - // For example: - // h = 12345??? - // upper = 12347??? - upper_delta = +1; - } else if (hd != ud) { - // For example: - // h = 12345??? - // upper = 12346??? - upper_delta = +0; - } - } else if (upper_delta == 0) { - if ((hd != 9) || (ud != 0)) { - // For example: - // h = 1234598? - // upper = 1234600? - upper_delta = +1; - } +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast +// copies the previous byte (the one immediately before *ptr_iop_w), copying 8 +// byte chunks at a time. Each chunk contains 8 repetitions of the same byte. +// +// In terms of number of bytes copied, length is rounded up to a multiple of 8. +// As a special case, a zero length rounds up to 8 (even though 0 is already a +// multiple of 8), since there is always at least one 8 byte chunk copied. +// +// In terms of advancing *ptr_iop_w, length is not rounded up. +// +// The caller needs to prove that: +// - length >= 1 +// - (length + 8) <= (io2_w - *ptr_iop_w) +// - distance == 1 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint64_t x = p[-1]; + x |= x << 8; + x |= x << 16; + x |= x << 32; + uint32_t n = length; + while (1) { + wuffs_base__poke_u64le__no_bounds_check(p, x); + if (n <= 8) { + p += n; + break; } + p += 8; + n -= 8; + } + *ptr_iop_w = p; + return length; +} - // We can round up if upper has a different digit than h and either upper - // is inclusive or upper is bigger than the result of rounding up. - bool can_round_up = - (upper_delta > 0) || // - ((upper_delta == 0) && // - (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits))))); - - // If we can round either way, round to nearest. If we can round only one - // way, do it. If we can't round, continue the loop. - if (can_round_down) { - if (can_round_up) { - wuffs_base__private_implementation__high_prec_dec__round_nearest( - h, hi + 1); - return; - } else { - wuffs_base__private_implementation__high_prec_dec__round_down(h, - hi + 1); - return; - } - } else { - if (can_round_up) { - wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1); - return; - } +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast_return_cusp +// copies the previous byte (the one immediately before *ptr_iop_w), copying 8 +// byte chunks at a time. Each chunk contains 8 repetitions of the same byte. +// It also returns the cusp: a byte pair (as a u16le) being the last byte of +// and next byte after the copied history. +// +// In terms of number of bytes copied, length is rounded up to a multiple of 8. +// As a special case, a zero length rounds up to 8 (even though 0 is already a +// multiple of 8), since there is always at least one 8 byte chunk copied. +// +// In terms of advancing *ptr_iop_w, length is not rounded up. +// +// The caller needs to prove that: +// - length >= 1 +// - (length + 8) <= (io2_w - *ptr_iop_w) +// - distance == 1 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast_return_cusp( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint8_t* q = p - distance; + uint64_t x = p[-1]; + x |= x << 8; + x |= x << 16; + x |= x << 32; + uint32_t n = length; + while (1) { + wuffs_base__poke_u64le__no_bounds_check(p, x); + if (n <= 8) { + p += n; + q += n; + break; } + p += 8; + q += 8; + n -= 8; } + *ptr_iop_w = p; + return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1); } -// -------- - -// wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces -// the IEEE 754 double-precision value for an exact mantissa and base-10 -// exponent. For example: -// - when parsing "12345.678e+02", man is 12345678 and exp10 is -1. -// - when parsing "-12", man is 12 and exp10 is 0. Processing the leading -// minus sign is the responsibility of the caller, not this function. +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast +// is like the +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function +// above, but copies 8 byte chunks at a time. // -// On success, it returns a non-negative int64_t such that the low 63 bits hold -// the 11-bit exponent and 52-bit mantissa. +// In terms of number of bytes copied, length is rounded up to a multiple of 8. +// As a special case, a zero length rounds up to 8 (even though 0 is already a +// multiple of 8), since there is always at least one 8 byte chunk copied. // -// On failure, it returns a negative value. +// In terms of advancing *ptr_iop_w, length is not rounded up. // -// The algorithm is based on an original idea by Michael Eisel that was refined -// by Daniel Lemire. See -// https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/ -// and -// https://nigeltao.github.io/blog/2020/eisel-lemire.html +// The caller needs to prove that: +// - length >= 1 +// - (length + 8) <= (io2_w - *ptr_iop_w) +// - distance >= 8 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint8_t* q = p - distance; + uint32_t n = length; + while (1) { + memcpy(p, q, 8); + if (n <= 8) { + p += n; + break; + } + p += 8; + q += 8; + n -= 8; + } + *ptr_iop_w = p; + return length; +} + +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp +// is like the +// wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast function +// above, but copies 8 byte chunks at a time. It also returns the cusp: a byte +// pair (as a u16le) being the last byte of and next byte after the copied +// history. // -// Preconditions: -// - man is non-zero. -// - exp10 is in the range [-307 ..= 288], the same range of the -// wuffs_base__private_implementation__powers_of_10 array. +// In terms of number of bytes copied, length is rounded up to a multiple of 8. +// As a special case, a zero length rounds up to 8 (even though 0 is already a +// multiple of 8), since there is always at least one 8 byte chunk copied. // -// The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX], -// approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the -// range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal -// (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are -// approximately 2.23e–308 and 1.80e+308. -static int64_t // -wuffs_base__private_implementation__parse_number_f64_eisel_lemire( - uint64_t man, - int32_t exp10) { - // Look up the (possibly truncated) base-2 representation of (10 ** exp10). - // The look-up table was constructed so that it is already normalized: the - // table entry's mantissa's MSB (most significant bit) is on. - const uint64_t* po10 = - &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0]; +// In terms of advancing *ptr_iop_w, length is not rounded up. +// +// The caller needs to prove that: +// - length >= 1 +// - (length + 8) <= (io2_w - *ptr_iop_w) +// - distance >= 8 +// - distance <= (*ptr_iop_w - io0_w) +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp( + uint8_t** ptr_iop_w, + uint8_t* io0_w, + uint8_t* io2_w, + uint32_t length, + uint32_t distance) { + uint8_t* p = *ptr_iop_w; + uint8_t* q = p - distance; + uint32_t n = length; + while (1) { + memcpy(p, q, 8); + if (n <= 8) { + p += n; + q += n; + break; + } + p += 8; + q += 8; + n -= 8; + } + *ptr_iop_w = p; + return (uint32_t)wuffs_base__peek_u16le__no_bounds_check(q - 1); +} - // Normalize the man argument. The (man != 0) precondition means that a - // non-zero bit exists. - uint32_t clz = wuffs_base__count_leading_zeroes_u64(man); - man <<= clz; +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_reader( + uint8_t** ptr_iop_w, + uint8_t* io2_w, + uint32_t length, + const uint8_t** ptr_iop_r, + const uint8_t* io2_r) { + uint8_t* iop_w = *ptr_iop_w; + size_t n = length; + if (n > ((size_t)(io2_w - iop_w))) { + n = (size_t)(io2_w - iop_w); + } + const uint8_t* iop_r = *ptr_iop_r; + if (n > ((size_t)(io2_r - iop_r))) { + n = (size_t)(io2_r - iop_r); + } + if (n > 0) { + memmove(iop_w, iop_r, n); + *ptr_iop_w += n; + *ptr_iop_r += n; + } + return (uint32_t)(n); +} - // Calculate the return value's base-2 exponent. We might tweak it by ±1 - // later, but its initial value comes from a linear scaling of exp10, - // converting from power-of-10 to power-of-2, and adjusting by clz. - // - // The magic constants are: - // - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because - // the look-up table uses 64-bit mantissas. - // - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough - // (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928. - // - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift. - // - // Equality of the linearly-scaled value and the actual power-of-2, over the - // range of exp10 arguments that this function accepts, is confirmed by - // script/print-mpb-powers-of-10.go - uint64_t ret_exp2 = - ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz); +static inline uint32_t // +wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + uint8_t** ptr_iop_w, + uint8_t* io2_w, + uint32_t length, + wuffs_base__slice_u8 src) { + uint8_t* iop_w = *ptr_iop_w; + size_t n = src.len; + if (n > length) { + n = length; + } + if (n > ((size_t)(io2_w - iop_w))) { + n = (size_t)(io2_w - iop_w); + } + if (n > 0) { + memmove(iop_w, src.ptr, n); + *ptr_iop_w += n; + } + return (uint32_t)(n); +} - // Multiply the two mantissas. Normalization means that both mantissas are at - // least (1<<63), so the 128-bit product must be at least (1<<126). The high - // 64 bits of the product, x_hi, must therefore be at least (1<<62). - // - // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi - // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore - // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. - wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]); - uint64_t x_hi = x.hi; - uint64_t x_lo = x.lo; +static inline wuffs_base__io_buffer* // +wuffs_private_impl__io_writer__set(wuffs_base__io_buffer* b, + uint8_t** ptr_iop_w, + uint8_t** ptr_io0_w, + uint8_t** ptr_io1_w, + uint8_t** ptr_io2_w, + wuffs_base__slice_u8 data, + uint64_t history_position) { + b->data = data; + b->meta.wi = 0; + b->meta.ri = 0; + b->meta.pos = history_position; + b->meta.closed = false; - // Before we shift right by at least 9 bits, recall that the look-up table - // entry was possibly truncated. We have so far only calculated a lower bound - // for the product (man * e), where e is (10 ** exp10). The upper bound would - // add a further (man * 1) to the 128-bit product, which overflows the lower - // 64-bit limb if ((x_lo + man) < man). - // - // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right - // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit - // limb's low 9 bits are all on. - // - // For example, parsing "9999999999999999999" will take the if-true branch - // here, since: - // - x_hi = 0x4563918244F3FFFF - // - x_lo = 0x8000000000000000 - // - man = 0x8AC7230489E7FFFF - if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) { - // Refine our calculation of (man * e). Before, our approximation of e used - // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit - // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e). - // Now calculate y = (man * bits_64_to_127_incl_of_e). - wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]); - uint64_t y_hi = y.hi; - uint64_t y_lo = y.lo; + *ptr_iop_w = data.ptr; + *ptr_io0_w = data.ptr; + *ptr_io1_w = data.ptr; + *ptr_io2_w = data.ptr + data.len; - // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to - // calculate the 192-bit product of the 64-bit man by the 128-bit e. - // As we exit this if-block, we only care about the high 128 bits - // (merged_hi and merged_lo) of that 192-bit product. - // - // For example, parsing "1.234e-45" will take the if-true branch here, - // since: - // - x_hi = 0x70B7E3696DB29FFF - // - x_lo = 0xE040000000000000 - // - y_hi = 0x33718BBEAB0E0D7A - // - y_lo = 0xA880000000000000 - uint64_t merged_hi = x_hi; - uint64_t merged_lo = x_lo + y_hi; - if (merged_lo < x_lo) { - merged_hi++; // Carry the overflow bit. - } + return b; +} - // The "high resolution" approximation of e is still a lower bound. Once - // again, see if the upper bound is large enough to produce a different - // result. This time, if it does, give up instead of reaching for an even - // more precise approximation to e. - // - // This three-part check is similar to the two-part check that guarded the - // if block that we're now in, but it has an extra term for the middle 64 - // bits (checking that adding 1 to merged_lo would overflow). - // - // For example, parsing "5.9604644775390625e-8" will take the if-true - // branch here, since: - // - merged_hi = 0x7FFFFFFFFFFFFFFF - // - merged_lo = 0xFFFFFFFFFFFFFFFF - // - y_lo = 0x4DB3FFC120988200 - // - man = 0xD3C21BCECCEDA100 - if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) && - (y_lo + man < man)) { - return -1; - } +// ---------------- I/O (Utility) - // Replace the 128-bit x with merged. - x_hi = merged_hi; - x_lo = merged_lo; - } +#define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader +#define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer - // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave - // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the - // MSB (before shifting) was on, adjust ret_exp2 for the larger shift. - // - // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit - // number. - uint64_t msb = x_hi >> 63; - uint64_t ret_mantissa = x_hi >> (msb + 9); - ret_exp2 -= 1 ^ msb; +// ---------------- Tokens - // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can - // be tricky. If we're half-way between two exactly representable numbers - // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give - // up instead of trying to pick the winner. - // - // Technically, we could tighten the condition by changing "73" to "73 or 74, - // depending on msb", but a flat "73" is simpler. - // - // For example, parsing "1e+23" will take the if-true branch here, since: - // - x_hi = 0x54B40B1F852BDA00 - // - ret_mantissa = 0x002A5A058FC295ED - if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) { - return -1; - } +// ---------------- Tokens (Utility) - // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit - // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether - // it was on or off, shifting right by one then produces a 53-bit number. If - // carrying up overflowed, shift again. - ret_mantissa += ret_mantissa & 1; - ret_mantissa >>= 1; - // This if block is equivalent to (but benchmarks slightly faster than) the - // following branchless form: - // uint64_t overflow_adjustment = ret_mantissa >> 53; - // ret_mantissa >>= overflow_adjustment; - // ret_exp2 += overflow_adjustment; - // - // For example, parsing "7.2057594037927933e+16" will take the if-true - // branch here, since: - // - x_hi = 0x7FFFFFFFFFFFFE80 - // - ret_mantissa = 0x0020000000000000 - if ((ret_mantissa >> 53) > 0) { - ret_mantissa >>= 1; - ret_exp2++; - } +// ---------------- Memory Allocation - // Starting with a 53-bit number, IEEE 754 double-precision normal numbers - // have an implicit mantissa bit. Mask that away and keep the low 52 bits. - ret_mantissa &= 0x000FFFFFFFFFFFFF; +// ---------------- Images - // Pack the bits and return. - return ((int64_t)(ret_mantissa | (ret_exp2 << 52))); -} +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( + const wuffs_base__pixel_swizzler* p, + uint32_t up_to_num_pixels, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + const uint8_t** ptr_iop_r, + const uint8_t* io2_r); -// -------- +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( + const wuffs_base__pixel_swizzler* p, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + const uint8_t** ptr_iop_r, + const uint8_t* io2_r); -static wuffs_base__result_f64 // -wuffs_base__private_implementation__parse_number_f64_special( - wuffs_base__slice_u8 s, - uint32_t options) { - do { - if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) { - goto fail; - } +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black( + const wuffs_base__pixel_swizzler* p, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + uint64_t num_pixels); - uint8_t* p = s.ptr; - uint8_t* q = s.ptr + s.len; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status // +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 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, + wuffs_base__slice_u8 src3, + uint32_t width0, + uint32_t width1, + uint32_t width2, + uint32_t width3, + uint32_t height0, + uint32_t height1, + uint32_t height2, + uint32_t height3, + uint32_t stride0, + uint32_t stride1, + uint32_t stride2, + uint32_t stride3, + uint8_t h0, + uint8_t h1, + uint8_t h2, + uint8_t h3, + uint8_t v0, + uint8_t v1, + uint8_t v2, + uint8_t v3, + bool is_rgb_or_cmyk, + bool triangle_filter_for_2to1, + wuffs_base__slice_u8 scratch_buffer_2k); - for (; (p < q) && (*p == '_'); p++) { - } - if (p >= q) { - goto fail; - } +// ---------------- Images (Utility) - // Parse sign. - bool negative = false; - do { - if (*p == '+') { - p++; - } else if (*p == '-') { - negative = true; - p++; - } else { - break; - } - for (; (p < q) && (*p == '_'); p++) { - } - } while (0); - if (p >= q) { - goto fail; - } +#define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format - bool nan = false; - switch (p[0]) { - case 'I': - case 'i': - if (((q - p) < 3) || // - ((p[1] != 'N') && (p[1] != 'n')) || // - ((p[2] != 'F') && (p[2] != 'f'))) { - goto fail; - } - p += 3; +// ---------------- String Conversions - if ((p >= q) || (*p == '_')) { - break; - } else if (((q - p) < 5) || // - ((p[0] != 'I') && (p[0] != 'i')) || // - ((p[1] != 'N') && (p[1] != 'n')) || // - ((p[2] != 'I') && (p[2] != 'i')) || // - ((p[3] != 'T') && (p[3] != 't')) || // - ((p[4] != 'Y') && (p[4] != 'y'))) { - goto fail; - } - p += 5; +// ---------------- Unicode and UTF-8 - if ((p >= q) || (*p == '_')) { - break; - } - goto fail; +// ---------------- - case 'N': - case 'n': - if (((q - p) < 3) || // - ((p[1] != 'A') && (p[1] != 'a')) || // - ((p[2] != 'N') && (p[2] != 'n'))) { - goto fail; - } - p += 3; +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__CORE) - if ((p >= q) || (*p == '_')) { - nan = true; - break; - } - goto fail; +const uint8_t wuffs_private_impl__low_bits_mask__u8[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, +}; - default: - goto fail; - } +const uint16_t wuffs_private_impl__low_bits_mask__u16[16] = { + 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, + 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, +}; - // Finish. - for (; (p < q) && (*p == '_'); p++) { - } - if (p != q) { - goto fail; - } - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( - (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) | - (negative ? 0x8000000000000000 : 0)); - return ret; - } while (0); +const uint32_t wuffs_private_impl__low_bits_mask__u32[32] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, + 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, + 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF, + 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, + 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF, +}; -fail: - do { - wuffs_base__result_f64 ret; - ret.status.repr = wuffs_base__error__bad_argument; - ret.value = 0; - return ret; - } while (0); -} +const uint64_t wuffs_private_impl__low_bits_mask__u64[64] = { + 0x0000000000000000, 0x0000000000000001, 0x0000000000000003, + 0x0000000000000007, 0x000000000000000F, 0x000000000000001F, + 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF, + 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF, + 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF, + 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF, + 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF, + 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF, + 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF, + 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF, + 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF, + 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF, + 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF, + 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF, + 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF, + 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF, + 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF, + 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF, + 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF, + 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF, + 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF, + 0x7FFFFFFFFFFFFFFF, +}; -WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 // -wuffs_base__private_implementation__high_prec_dec__to_f64( - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t options) { - do { - // powers converts decimal powers of 10 to binary powers of 2. For example, - // (10000 >> 13) is 1. It stops before the elements exceed 60, also known - // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL. - // - // This rounds down (1<<13 is a lower bound for 1e4). Adding 1 to the array - // element value rounds up (1<<14 is an upper bound for 1e4) while staying - // at or below WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL. - // - // When starting in the range [1e+1 .. 1e+2] (i.e. h->decimal_point == +2), - // powers[2] == 6 and so: - // - Right shifting by 6+0 produces the range [10/64 .. 100/64] = - // [0.156250 .. 1.56250]. The resultant h->decimal_point is +0 or +1. - // - Right shifting by 6+1 produces the range [10/128 .. 100/128] = - // [0.078125 .. 0.78125]. The resultant h->decimal_point is -1 or -0. - // - // When starting in the range [1e-3 .. 1e-2] (i.e. h->decimal_point == -2), - // powers[2] == 6 and so: - // - Left shifting by 6+0 produces the range [0.001*64 .. 0.01*64] = - // [0.064 .. 0.64]. The resultant h->decimal_point is -1 or -0. - // - Left shifting by 6+1 produces the range [0.001*128 .. 0.01*128] = - // [0.128 .. 1.28]. The resultant h->decimal_point is +0 or +1. - // - // Thus, when targeting h->decimal_point being +0 or +1, use (powers[n]+0) - // when right shifting but (powers[n]+1) when left shifting. - static const uint32_t num_powers = 19; - static const uint8_t powers[19] = { - 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, // - 33, 36, 39, 43, 46, 49, 53, 56, 59, // - }; +const uint32_t wuffs_private_impl__pixel_format__bits_per_channel[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, +}; - // Handle zero and obvious extremes. The largest and smallest positive - // finite f64 values are approximately 1.8e+308 and 4.9e-324. - if ((h->num_digits == 0) || (h->decimal_point < -326)) { - goto zero; - } else if (h->decimal_point > 310) { - goto infinity; - } +const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect"; +const char wuffs_base__note__end_of_data[] = "@base: end of data"; +const char wuffs_base__note__metadata_reported[] = "@base: metadata reported"; +const char wuffs_base__suspension__even_more_information[] = "$base: even more information"; +const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read"; +const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write"; +const char wuffs_base__suspension__short_read[] = "$base: short read"; +const char wuffs_base__suspension__short_workbuf[] = "$base: short workbuf"; +const char wuffs_base__suspension__short_write[] = "$base: short write"; +const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position"; +const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)"; +const char wuffs_base__error__bad_argument[] = "#base: bad argument"; +const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence"; +const char wuffs_base__error__bad_data[] = "#base: bad data"; +const char wuffs_base__error__bad_receiver[] = "#base: bad receiver"; +const char wuffs_base__error__bad_restart[] = "#base: bad restart"; +const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver"; +const char wuffs_base__error__bad_vtable[] = "#base: bad vtable"; +const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length"; +const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version"; +const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension"; +const char wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist[] = "#base: disabled by WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST"; +const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error"; +const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed"; +const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called"; +const char wuffs_base__error__insufficient_history[] = "#base: insufficient history"; +const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls"; +const char wuffs_base__error__no_more_information[] = "#base: no more information"; +const char wuffs_base__error__not_enough_data[] = "#base: not enough data"; +const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds"; +const char wuffs_base__error__unsupported_image_dimension[] = "#base: unsupported image dimension"; +const char wuffs_base__error__unsupported_method[] = "#base: unsupported method"; +const char wuffs_base__error__unsupported_option[] = "#base: unsupported option"; +const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option"; +const char wuffs_base__error__too_much_data[] = "#base: too much data"; - // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10) - // pair from the high_prec_dec h is more correct but slower than the - // approach taken in wuffs_base__parse_number_f64. The latter is optimized - // for the common cases (e.g. assuming no underscores or a leading '+' - // sign) rather than the full set of cases allowed by the Wuffs API. - // - // When we have 19 or fewer mantissa digits, run Eisel-Lemire once (trying - // for an exact result). When we have more than 19 mantissa digits, run it - // twice to get a lower and upper bound. We still have an exact result - // (within f64's rounding margin) if both bounds are equal (and valid). - uint32_t i_max = h->num_digits; - if (i_max > 19) { - i_max = 19; - } - int32_t exp10 = h->decimal_point - ((int32_t)i_max); - if ((-307 <= exp10) && (exp10 <= 288)) { - uint64_t man = 0; - uint32_t i; - for (i = 0; i < i_max; i++) { - man = (10 * man) + h->digits[i]; - } - while (man != 0) { // The 'while' is just an 'if' that we can 'break'. - int64_t r0 = - wuffs_base__private_implementation__parse_number_f64_eisel_lemire( - man + 0, exp10); - if (r0 < 0) { - break; - } else if (h->num_digits > 19) { - int64_t r1 = - wuffs_base__private_implementation__parse_number_f64_eisel_lemire( - man + 1, exp10); - if (r1 != r0) { - break; - } - } - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( - ((uint64_t)r0) | (((uint64_t)(h->negative)) << 63)); - return ret; - } - } +const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32"; +const char wuffs_base__hasher_u64__vtable_name[] = "{vtable}wuffs_base__hasher_u64"; +const char wuffs_base__hasher_bitvec256__vtable_name[] = "{vtable}wuffs_base__hasher_bitvec256"; +const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder"; +const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer"; +const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder"; - // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See - // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html - // - // Scale by powers of 2 until we're in the range [0.1 .. 10]. Equivalently, - // that h->decimal_point is +0 or +1. - // - // First we shift right while at or above 10... - const int32_t f64_bias = -1023; - int32_t exp2 = 0; - while (h->decimal_point > 1) { - uint32_t n = (uint32_t)(+h->decimal_point); - uint32_t shift = - (n < num_powers) - ? powers[n] - : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL; - - wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift); - if (h->decimal_point < - -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) { - goto zero; - } - exp2 += (int32_t)shift; - } - // ...then we shift left while below 0.1. - while (h->decimal_point < 0) { - uint32_t shift; - uint32_t n = (uint32_t)(-h->decimal_point); - shift = (n < num_powers) - // The +1 is per "when targeting h->decimal_point being +0 or - // +1... when left shifting" in the powers comment above. - ? (powers[n] + 1) - : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL; +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__CORE) - wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift); - if (h->decimal_point > - +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) { - goto infinity; - } - exp2 -= (int32_t)shift; - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES) - // To get from "in the range [0.1 .. 10]" to "in the range [1 .. 2]" (which - // will give us our exponent in base-2), the mantissa's first 3 digits will - // determine the final left shift, equal to 52 (the number of explicit f64 - // bits) plus an additional adjustment. - int man3 = (100 * h->digits[0]) + - ((h->num_digits > 1) ? (10 * h->digits[1]) : 0) + - ((h->num_digits > 2) ? h->digits[2] : 0); - int32_t additional_lshift = 0; - if (h->decimal_point == 0) { // The value is in [0.1 .. 1]. - if (man3 < 125) { - additional_lshift = +4; - } else if (man3 < 250) { - additional_lshift = +3; - } else if (man3 < 500) { - additional_lshift = +2; - } else { - additional_lshift = +1; - } - } else { // The value is in [1 .. 10]. - if (man3 < 200) { - additional_lshift = -0; - } else if (man3 < 400) { - additional_lshift = -1; - } else if (man3 < 800) { - additional_lshift = -2; - } else { - additional_lshift = -3; - } - } - exp2 -= additional_lshift; - uint32_t final_lshift = (uint32_t)(52 + additional_lshift); +// ---------------- Interface Definitions. - // The minimum normal exponent is (f64_bias + 1). - while ((f64_bias + 1) > exp2) { - uint32_t n = (uint32_t)((f64_bias + 1) - exp2); - if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) { - n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL; - } - wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n); - exp2 += (int32_t)n; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_base__hasher_u32__checksum_u32( + const wuffs_base__hasher_u32* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - // Check for overflow. - if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1. - goto infinity; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { + const wuffs_base__hasher_u32__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); + return (*func_ptrs->checksum_u32)(self); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - // Extract 53 bits for the mantissa (in base-2). - wuffs_base__private_implementation__high_prec_dec__small_lshift( - h, final_lshift); - uint64_t man2 = - wuffs_base__private_implementation__high_prec_dec__rounded_integer(h); + return 0; +} - // Rounding might have added one bit. If so, shift and re-check overflow. - if ((man2 >> 53) != 0) { - man2 >>= 1; - exp2++; - if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1. - goto infinity; - } - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_u32__get_quirk( + const wuffs_base__hasher_u32* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - // Handle subnormal numbers. - if ((man2 >> 52) == 0) { - exp2 = f64_bias; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { + const wuffs_base__hasher_u32__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - // Pack the bits and return. - uint64_t exp2_bits = - (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1. - uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1. - (exp2_bits << 52) | // - (h->negative ? 0x8000000000000000 : 0); // (1 << 63). - - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); - return ret; - } while (0); - -zero: - do { - uint64_t bits = h->negative ? 0x8000000000000000 : 0; + return 0; +} - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); - return ret; - } while (0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__hasher_u32__set_quirk( + wuffs_base__hasher_u32* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -infinity: - do { - if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) { - wuffs_base__result_f64 ret; - ret.status.repr = wuffs_base__error__bad_argument; - ret.value = 0; - return ret; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { + const wuffs_base__hasher_u32__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000; - - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); - return ret; - } while (0); + return wuffs_base__make_status(wuffs_base__error__bad_vtable); } -static inline bool // -wuffs_base__private_implementation__is_decimal_digit(uint8_t c) { - return ('0' <= c) && (c <= '9'); -} +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_base__hasher_u32__update( + wuffs_base__hasher_u32* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } -WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 // -wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) { - // In practice, almost all "dd.ddddE±xxx" numbers can be represented - // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10 - // exponent, adjusting "xxx" for the position (if present) of the decimal - // separator '.' or ','. - // - // This (u64 man, i32 exp10) data structure is superficially similar to the - // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent - // here is base-10, not base-2. - // - // If s's number fits in a (man, exp10), parse that pair with the - // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with - // the fallback algorithm is slower but comprehensive. - // - // † "Printing Floating-Point Numbers Quickly and Accurately with Integers" - // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf). - // Florian Loitsch is also the primary contributor to - // https://github.com/google/double-conversion - do { - // Calculating that (man, exp10) pair needs to stay within s's bounds. - // Provided that s isn't extremely long, work on a NUL-terminated copy of - // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx". - // - // As the pointer p walks the contents, it's faster to repeatedly check "is - // *p a valid digit" than "is p within bounds and *p a valid digit". - if (s.len >= 256) { - goto fallback; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { + const wuffs_base__hasher_u32__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update)(self, a_x); + } else if (v->vtable_name == NULL) { + break; } - uint8_t z[256]; - memcpy(&z[0], s.ptr, s.len); - z[s.len] = 0; - const uint8_t* p = &z[0]; + v++; + } - // Look for a leading minus sign. Technically, we could also look for an - // optional plus sign, but the "script/process-json-numbers.c with -p" - // benchmark is noticably slower if we do. It's optional and, in practice, - // usually absent. Let the fallback catch it. - bool negative = (*p == '-'); - if (negative) { - p++; - } + return wuffs_base__make_empty_struct(); +} - // After walking "dd.dddd", comparing p later with p now will produce the - // number of "d"s and "."s. - const uint8_t* const start_of_digits_ptr = p; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_base__hasher_u32__update_u32( + wuffs_base__hasher_u32* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return 0; + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return 0; + } - // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0', - // it must be a single '0'. If it starts with a non-zero decimal digit, it - // can be a sequence of decimal digits. - // - // Update the man variable during the walk. It's OK if man overflows now. - // We'll detect that later. - uint64_t man; - if (*p == '0') { - man = 0; - p++; - if (wuffs_base__private_implementation__is_decimal_digit(*p)) { - goto fallback; - } - } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) { - man = ((uint8_t)(*p - '0')); - p++; - for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) { - man = (10 * man) + ((uint8_t)(*p - '0')); - } - } else { - goto fallback; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) { + const wuffs_base__hasher_u32__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update_u32)(self, a_x); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - // Walk the "d"s after the optional decimal separator ('.' or ','), - // updating the man and exp10 variables. - int32_t exp10 = 0; - if (*p == - ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.')) { - p++; - const uint8_t* first_after_separator_ptr = p; - if (!wuffs_base__private_implementation__is_decimal_digit(*p)) { - goto fallback; - } - man = (10 * man) + ((uint8_t)(*p - '0')); - p++; - for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) { - man = (10 * man) + ((uint8_t)(*p - '0')); - } - exp10 = ((int32_t)(first_after_separator_ptr - p)); - } + return 0; +} - // Count the number of digits: - // - for an input of "314159", digit_count is 6. - // - for an input of "3.14159", digit_count is 7. - // - // This is off-by-one if there is a decimal separator. That's OK for now. - // We'll correct for that later. The "script/process-json-numbers.c with - // -p" benchmark is noticably slower if we try to correct for that now. - uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr); +// -------- - // Update exp10 for the optional exponent, starting with 'E' or 'e'. - if ((*p | 0x20) == 'e') { - p++; - int32_t exp_sign = +1; - if (*p == '-') { - p++; - exp_sign = -1; - } else if (*p == '+') { - p++; - } - if (!wuffs_base__private_implementation__is_decimal_digit(*p)) { - goto fallback; - } - int32_t exp_num = ((uint8_t)(*p - '0')); - p++; - // The rest of the exp_num walking has a peculiar control flow but, once - // again, the "script/process-json-numbers.c with -p" benchmark is - // sensitive to alternative formulations. - if (wuffs_base__private_implementation__is_decimal_digit(*p)) { - exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); - p++; - } - if (wuffs_base__private_implementation__is_decimal_digit(*p)) { - exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); - p++; - } - while (wuffs_base__private_implementation__is_decimal_digit(*p)) { - if (exp_num > 0x1000000) { - goto fallback; - } - exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); - p++; - } - exp10 += exp_sign * exp_num; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_u64__checksum_u64( + const wuffs_base__hasher_u64* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - // The Wuffs API is that the original slice has no trailing data. It also - // allows underscores, which we don't catch here but the fallback should. - if (p != &z[s.len]) { - goto fallback; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { + const wuffs_base__hasher_u64__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); + return (*func_ptrs->checksum_u64)(self); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - // Check that the uint64_t typed man variable has not overflowed, based on - // digit_count. - // - // For reference: - // - (1 << 63) is 9223372036854775808, which has 19 decimal digits. - // - (1 << 64) is 18446744073709551616, which has 20 decimal digits. - // - 19 nines, 9999999999999999999, is 0x8AC7230489E7FFFF, which has 64 - // bits and 16 hexadecimal digits. - // - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67 - // bits and 17 hexadecimal digits. - if (digit_count > 19) { - // Even if we have more than 19 pseudo-digits, it's not yet definitely an - // overflow. Recall that digit_count might be off-by-one (too large) if - // there's a decimal separator. It will also over-report the number of - // meaningful digits if the input looks something like "0.000dddExxx". - // - // We adjust by the number of leading '0's and '.'s and re-compare to 19. - // Once again, technically, we could skip ','s too, but that perturbs the - // "script/process-json-numbers.c with -p" benchmark. - const uint8_t* q = start_of_digits_ptr; - for (; (*q == '0') || (*q == '.'); q++) { - } - digit_count -= (uint32_t)(q - start_of_digits_ptr); - if (digit_count > 19) { - goto fallback; - } - } + return 0; +} - // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire - // preconditions include that exp10 is in the range [-307 ..= 288]. - if ((exp10 < -307) || (288 < exp10)) { - goto fallback; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_u64__get_quirk( + const wuffs_base__hasher_u64* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - // If both man and (10 ** exp10) are exactly representable by a double, we - // don't need to run the Eisel-Lemire algorithm. - if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) { - double d = (double)man; - if (exp10 >= 0) { - d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10]; - } else { - d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10]; - } - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = negative ? -d : +d; - return ret; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { + const wuffs_base__hasher_u64__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire - // preconditions include that man is non-zero. Parsing "0" should be caught - // by the "If both man and (10 ** exp10)" above, but "0e99" might not. - if (man == 0) { - goto fallback; - } + return 0; +} - // Our man and exp10 are in range. Run the Eisel-Lemire algorithm. - int64_t r = - wuffs_base__private_implementation__parse_number_f64_eisel_lemire( - man, exp10); - if (r < 0) { - goto fallback; - } - wuffs_base__result_f64 ret; - ret.status.repr = NULL; - ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( - ((uint64_t)r) | (((uint64_t)negative) << 63)); - return ret; - } while (0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__hasher_u64__set_quirk( + wuffs_base__hasher_u64* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -fallback: - do { - wuffs_base__private_implementation__high_prec_dec h; - wuffs_base__status status = - wuffs_base__private_implementation__high_prec_dec__parse(&h, s, - options); - if (status.repr) { - return wuffs_base__private_implementation__parse_number_f64_special( - s, options); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { + const wuffs_base__hasher_u64__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; } - return wuffs_base__private_implementation__high_prec_dec__to_f64(&h, - options); - } while (0); -} + v++; + } -// -------- + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} -static inline size_t // -wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst, - bool neg, - uint32_t options) { - if (neg) { - if (dst.len < 4) { - return 0; - } - wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D); // '-Inf'le. - return 4; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_base__hasher_u64__update( + wuffs_base__hasher_u64* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); } - if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { - if (dst.len < 4) { - return 0; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { + const wuffs_base__hasher_u64__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update)(self, a_x); + } else if (v->vtable_name == NULL) { + break; } - wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B); // '+Inf'le. - return 4; + v++; } - if (dst.len < 3) { - return 0; - } - wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49); // 'Inf'le. - return 3; + return wuffs_base__make_empty_struct(); } -static inline size_t // -wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) { - if (dst.len < 3) { +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_u64__update_u64( + wuffs_base__hasher_u64* self, + wuffs_base__slice_u8 a_x) { + if (!self) { return 0; } - wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E); // 'NaN'le. - return 3; -} - -static size_t // -wuffs_base__private_implementation__high_prec_dec__render_exponent_absent( - wuffs_base__slice_u8 dst, - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t precision, - uint32_t options) { - size_t n = (h->negative || - (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN)) - ? 1 - : 0; - if (h->decimal_point <= 0) { - n += 1; - } else { - n += (size_t)(h->decimal_point); - } - if (precision > 0) { - n += precision + 1; // +1 for the '.'. + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return 0; } - // Don't modify dst if the formatted number won't fit. - if (n > dst.len) { - return 0; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) { + const wuffs_base__hasher_u64__func_ptrs* func_ptrs = + (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update_u64)(self, a_x); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - // Align-left or align-right. - uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) - ? &dst.ptr[dst.len - n] - : &dst.ptr[0]; + return 0; +} - // Leading "±". - if (h->negative) { - *ptr++ = '-'; - } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { - *ptr++ = '+'; - } +// -------- - // Integral digits. - if (h->decimal_point <= 0) { - *ptr++ = '0'; - } else { - uint32_t m = - wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point)); - uint32_t i = 0; - for (; i < m; i++) { - *ptr++ = (uint8_t)('0' | h->digits[i]); - } - for (; i < (uint32_t)(h->decimal_point); i++) { - *ptr++ = '0'; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_base__hasher_bitvec256__checksum_bitvec256( + const wuffs_base__hasher_bitvec256* self) { + if (!self) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); } - // Separator and then fractional digits. - if (precision > 0) { - *ptr++ = - (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.'; - uint32_t i = 0; - for (; i < precision; i++) { - uint32_t j = ((uint32_t)(h->decimal_point)) + i; - *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0)); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) { + const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs = + (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers); + return (*func_ptrs->checksum_bitvec256)(self); + } else if (v->vtable_name == NULL) { + break; } + v++; } - return n; + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); } -static size_t // -wuffs_base__private_implementation__high_prec_dec__render_exponent_present( - wuffs_base__slice_u8 dst, - wuffs_base__private_implementation__high_prec_dec* h, - uint32_t precision, - uint32_t options) { - int32_t exp = 0; - if (h->num_digits > 0) { - exp = h->decimal_point - 1; - } - bool negative_exp = exp < 0; - if (negative_exp) { - exp = -exp; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__hasher_bitvec256__get_quirk( + const wuffs_base__hasher_bitvec256* self, + uint32_t a_key) { + if (!self) { + return 0; } - - size_t n = (h->negative || - (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN)) - ? 4 - : 3; // Mininum 3 bytes: first digit and then "e±". - if (precision > 0) { - n += precision + 1; // +1 for the '.'. + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - n += (exp < 100) ? 2 : 3; - // Don't modify dst if the formatted number won't fit. - if (n > dst.len) { - return 0; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) { + const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs = + (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - // Align-left or align-right. - uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) - ? &dst.ptr[dst.len - n] - : &dst.ptr[0]; + return 0; +} - // Leading "±". - if (h->negative) { - *ptr++ = '-'; - } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { - *ptr++ = '+'; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__hasher_bitvec256__set_quirk( + wuffs_base__hasher_bitvec256* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - - // Integral digit. - if (h->num_digits > 0) { - *ptr++ = (uint8_t)('0' | h->digits[0]); - } else { - *ptr++ = '0'; + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - // Separator and then fractional digits. - if (precision > 0) { - *ptr++ = - (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) - ? ',' - : '.'; - uint32_t i = 1; - uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1); - for (; i < j; i++) { - *ptr++ = (uint8_t)('0' | h->digits[i]); - } - for (; i <= precision; i++) { - *ptr++ = '0'; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) { + const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs = + (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; } + v++; } - // Exponent: "e±" and then 2 or 3 digits. - *ptr++ = 'e'; - *ptr++ = negative_exp ? '-' : '+'; - if (exp < 10) { - *ptr++ = '0'; - *ptr++ = (uint8_t)('0' | exp); - } else if (exp < 100) { - *ptr++ = (uint8_t)('0' | (exp / 10)); - *ptr++ = (uint8_t)('0' | (exp % 10)); - } else { - int32_t e = exp / 100; - exp -= e * 100; - *ptr++ = (uint8_t)('0' | e); - *ptr++ = (uint8_t)('0' | (exp / 10)); - *ptr++ = (uint8_t)('0' | (exp % 10)); - } - - return n; + return wuffs_base__make_status(wuffs_base__error__bad_vtable); } -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__render_number_f64(wuffs_base__slice_u8 dst, - double x, - uint32_t precision, - uint32_t options) { - // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits - // with a -1023 bias) and mantissa (52 bits). - uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x); - bool neg = (bits >> 63) != 0; - int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF; - uint64_t man = bits & 0x000FFFFFFFFFFFFFul; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_base__hasher_bitvec256__update( + wuffs_base__hasher_bitvec256* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } - // Apply the exponent bias and set the implicit top bit of the mantissa, - // unless x is subnormal. Also take care of Inf and NaN. - if (exp2 == 0x7FF) { - if (man != 0) { - return wuffs_base__private_implementation__render_nan(dst); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) { + const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs = + (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update)(self, a_x); + } else if (v->vtable_name == NULL) { + break; } - return wuffs_base__private_implementation__render_inf(dst, neg, options); - } else if (exp2 == 0) { - exp2 = -1022; - } else { - exp2 -= 1023; - man |= 0x0010000000000000ul; + v++; } - // Ensure that precision isn't too large. - if (precision > 4095) { - precision = 4095; + return wuffs_base__make_empty_struct(); +} + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_base__hasher_bitvec256__update_bitvec256( + wuffs_base__hasher_bitvec256* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); } - // Convert from the (neg, exp2, man) tuple to an HPD. - wuffs_base__private_implementation__high_prec_dec h; - wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg); - if (h.num_digits > 0) { - wuffs_base__private_implementation__high_prec_dec__lshift( - &h, exp2 - 52); // 52 mantissa bits. + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__hasher_bitvec256__vtable_name) { + const wuffs_base__hasher_bitvec256__func_ptrs* func_ptrs = + (const wuffs_base__hasher_bitvec256__func_ptrs*)(v->function_pointers); + return (*func_ptrs->update_bitvec256)(self, a_x); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - // Handle the "%e" and "%f" formats. - switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT | - WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) { - case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT: // The "%"f" format. - if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { - wuffs_base__private_implementation__high_prec_dec__round_just_enough( - &h, exp2, man); - int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point; - precision = ((uint32_t)(wuffs_base__i32__max(0, p))); - } else { - wuffs_base__private_implementation__high_prec_dec__round_nearest( - &h, ((int32_t)precision) + h.decimal_point); - } - return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent( - dst, &h, precision, options); + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); +} - case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT: // The "%e" format. - if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { - wuffs_base__private_implementation__high_prec_dec__round_just_enough( - &h, exp2, man); - precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0; - } else { - wuffs_base__private_implementation__high_prec_dec__round_nearest( - &h, ((int32_t)precision) + 1); - } - return wuffs_base__private_implementation__high_prec_dec__render_exponent_present( - dst, &h, precision, options); +// -------- + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__decode_frame( + wuffs_base__image_decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - // We have the "%g" format and so precision means the number of significant - // digits, not the number of digits after the decimal separator. Perform - // rounding and determine whether to use "%e" or "%f". - int32_t e_threshold = 0; - if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { - wuffs_base__private_implementation__high_prec_dec__round_just_enough( - &h, exp2, man); - precision = h.num_digits; - e_threshold = 6; - } else { - if (precision == 0) { - precision = 1; - } - wuffs_base__private_implementation__high_prec_dec__round_nearest( - &h, ((int32_t)precision)); - e_threshold = ((int32_t)precision); - int32_t nd = ((int32_t)(h.num_digits)); - if ((e_threshold > nd) && (nd >= h.decimal_point)) { - e_threshold = nd; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts); + } else if (v->vtable_name == NULL) { + break; } + v++; } - // Use the "%e" format if the exponent is large. - int32_t e = h.decimal_point - 1; - if ((e < -4) || (e_threshold <= e)) { - uint32_t p = wuffs_base__u32__min(precision, h.num_digits); - return wuffs_base__private_implementation__high_prec_dec__render_exponent_present( - dst, &h, (p > 0) ? (p - 1) : 0, options); + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__decode_frame_config( + wuffs_base__image_decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - // Use the "%f" format otherwise. - int32_t p = ((int32_t)precision); - if (p > h.decimal_point) { - p = ((int32_t)(h.num_digits)); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->decode_frame_config)(self, a_dst, a_src); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point))); - return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent( - dst, &h, precision, options); + + return wuffs_base__make_status(wuffs_base__error__bad_vtable); } -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV) +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__decode_image_config( + wuffs_base__image_decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__INTCONV) + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->decode_image_config)(self, a_dst, a_src); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } -// ---------------- Integer + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} -// wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits, -// and (0x80 | v) for valid digits, where v is the 4 bit value. +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_base__image_decoder__frame_dirty_rect( + const wuffs_base__image_decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } -static const uint8_t wuffs_base__parse_number__decimal_digits[256] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'. - 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'. + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->frame_dirty_rect)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. + return wuffs_base__utility__empty_rect_ie_u32(); +} - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF. +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__image_decoder__get_quirk( + const wuffs_base__image_decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF. - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F -}; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } -static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'. - 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'. + return 0; +} - 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. - 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_base__image_decoder__num_animation_loops( + const wuffs_base__image_decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF. + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->num_animation_loops)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF. - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F -}; + return 0; +} -static const uint8_t wuffs_base__private_implementation__encode_base16[16] = { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x00 ..= 0x07. - 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 0x08 ..= 0x0F. -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__image_decoder__num_decoded_frame_configs( + const wuffs_base__image_decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -// -------- + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->num_decoded_frame_configs)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } -WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 // -wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) { - uint8_t* p = s.ptr; - uint8_t* q = s.ptr + s.len; + return 0; +} - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (; (p < q) && (*p == '_'); p++) { - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__image_decoder__num_decoded_frames( + const wuffs_base__image_decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - bool negative = false; - if (p >= q) { - goto fail_bad_argument; - } else if (*p == '-') { - p++; - negative = true; - } else if (*p == '+') { - p++; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->num_decoded_frames)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - do { - wuffs_base__result_u64 r = wuffs_base__parse_number_u64( - wuffs_base__make_slice_u8(p, (size_t)(q - p)), options); - if (r.status.repr != NULL) { - wuffs_base__result_i64 ret; - ret.status.repr = r.status.repr; - ret.value = 0; - return ret; - } else if (negative) { - if (r.value < 0x8000000000000000) { - wuffs_base__result_i64 ret; - ret.status.repr = NULL; - ret.value = -(int64_t)(r.value); - return ret; - } else if (r.value == 0x8000000000000000) { - wuffs_base__result_i64 ret; - ret.status.repr = NULL; - ret.value = INT64_MIN; - return ret; - } - goto fail_out_of_bounds; - } else if (r.value > 0x7FFFFFFFFFFFFFFF) { - goto fail_out_of_bounds; - } else { - wuffs_base__result_i64 ret; - ret.status.repr = NULL; - ret.value = +(int64_t)(r.value); - return ret; - } - } while (0); - -fail_bad_argument: - do { - wuffs_base__result_i64 ret; - ret.status.repr = wuffs_base__error__bad_argument; - ret.value = 0; - return ret; - } while (0); - -fail_out_of_bounds: - do { - wuffs_base__result_i64 ret; - ret.status.repr = wuffs_base__error__out_of_bounds; - ret.value = 0; - return ret; - } while (0); + return 0; } -WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 // -wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) { - uint8_t* p = s.ptr; - uint8_t* q = s.ptr + s.len; - - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (; (p < q) && (*p == '_'); p++) { - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__restart_frame( + wuffs_base__image_decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - if (p >= q) { - goto fail_bad_argument; - - } else if (*p == '0') { - p++; - if (p >= q) { - goto ok_zero; - } - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - if (*p == '_') { - p++; - for (; p < q; p++) { - if (*p != '_') { - if (options & - WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) { - goto decimal; - } - goto fail_bad_argument; - } - } - goto ok_zero; - } + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->restart_frame)(self, a_index, a_io_position); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - if ((*p == 'x') || (*p == 'X')) { - p++; - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (; (p < q) && (*p == '_'); p++) { - } - } - if (p < q) { - goto hexadecimal; - } + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} - } else if ((*p == 'd') || (*p == 'D')) { - p++; - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { - for (; (p < q) && (*p == '_'); p++) { - } - } - if (p < q) { - goto decimal; - } - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__set_quirk( + wuffs_base__image_decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } - if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) { - goto decimal; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; } - goto fail_bad_argument; + v++; } -decimal: - do { - uint64_t v = wuffs_base__parse_number__decimal_digits[*p++]; - if (v == 0) { - goto fail_bad_argument; - } - v &= 0x0F; + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} - // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1). - const uint64_t max10 = 1844674407370955161u; - const uint8_t max1 = 5; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_base__image_decoder__set_report_metadata( + wuffs_base__image_decoder* self, + uint32_t a_fourcc, + bool a_report) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } - for (; p < q; p++) { - if ((*p == '_') && - (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - continue; - } - uint8_t digit = wuffs_base__parse_number__decimal_digits[*p]; - if (digit == 0) { - goto fail_bad_argument; - } - digit &= 0x0F; - if ((v > max10) || ((v == max10) && (digit > max1))) { - goto fail_out_of_bounds; - } - v = (10 * v) + ((uint64_t)(digit)); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - wuffs_base__result_u64 ret; - ret.status.repr = NULL; - ret.value = v; - return ret; - } while (0); + return wuffs_base__make_empty_struct(); +} -hexadecimal: - do { - uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++]; - if (v == 0) { - goto fail_bad_argument; - } - v &= 0x0F; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__image_decoder__tell_me_more( + wuffs_base__image_decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } - for (; p < q; p++) { - if ((*p == '_') && - (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { - continue; - } - uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p]; - if (digit == 0) { - goto fail_bad_argument; - } - digit &= 0x0F; - if ((v >> 60) != 0) { - goto fail_out_of_bounds; - } - v = (v << 4) | ((uint64_t)(digit)); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src); + } else if (v->vtable_name == NULL) { + break; } + v++; + } - wuffs_base__result_u64 ret; - ret.status.repr = NULL; - ret.value = v; - return ret; - } while (0); + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} -ok_zero: - do { - wuffs_base__result_u64 ret; - ret.status.repr = NULL; - ret.value = 0; - return ret; - } while (0); +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_base__image_decoder__workbuf_len( + const wuffs_base__image_decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } -fail_bad_argument: - do { - wuffs_base__result_u64 ret; - ret.status.repr = wuffs_base__error__bad_argument; - ret.value = 0; - return ret; - } while (0); + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__image_decoder__vtable_name) { + const wuffs_base__image_decoder__func_ptrs* func_ptrs = + (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->workbuf_len)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } -fail_out_of_bounds: - do { - wuffs_base__result_u64 ret; - ret.status.repr = wuffs_base__error__out_of_bounds; - ret.value = 0; - return ret; - } while (0); + return wuffs_base__utility__empty_range_ii_u64(); } // -------- -// wuffs_base__render_number__first_hundred contains the decimal encodings of -// the first one hundred numbers [0 ..= 99]. -static const uint8_t wuffs_base__render_number__first_hundred[200] = { - '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', // - '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', // - '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', // - '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', // - '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', // - '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', // - '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', // - '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', // - '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', // - '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', // - '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', // - '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', // - '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', // - '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', // - '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', // - '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', // - '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', // - '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', // - '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', // - '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', // -}; - -static size_t // -wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst, - uint64_t x, - uint32_t options, - bool neg) { - uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL]; - uint8_t* ptr = &buf[0] + sizeof(buf); - - while (x >= 100) { - size_t index = ((size_t)((x % 100) * 2)); - x /= 100; - uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0]; - uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1]; - ptr -= 2; - ptr[0] = s0; - ptr[1] = s1; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_base__io_transformer__dst_history_retain_length( + const wuffs_base__io_transformer* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); } - - if (x < 10) { - ptr -= 1; - ptr[0] = (uint8_t)('0' + x); - } else { - size_t index = ((size_t)(x * 2)); - uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0]; - uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1]; - ptr -= 2; - ptr[0] = s0; - ptr[1] = s1; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); } - if (neg) { - ptr -= 1; - ptr[0] = '-'; - } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { - ptr -= 1; - ptr[0] = '+'; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { + const wuffs_base__io_transformer__func_ptrs* func_ptrs = + (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); + return (*func_ptrs->dst_history_retain_length)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0])); - if (n > dst.len) { + return wuffs_base__utility__make_optional_u63(false, 0u); +} + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__io_transformer__get_quirk( + const wuffs_base__io_transformer* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { return 0; } - memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) - ? (dst.len - n) - : 0), - ptr, n); - return n; -} -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__render_number_i64(wuffs_base__slice_u8 dst, - int64_t x, - uint32_t options) { - uint64_t u = (uint64_t)x; - bool neg = x < 0; - if (neg) { - u = 1 + ~u; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { + const wuffs_base__io_transformer__func_ptrs* func_ptrs = + (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - return wuffs_base__private_implementation__render_number_u64(dst, u, options, - neg); -} -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__render_number_u64(wuffs_base__slice_u8 dst, - uint64_t x, - uint32_t options) { - return wuffs_base__private_implementation__render_number_u64(dst, x, options, - false); + return 0; } -// ---------------- Base-16 +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__io_transformer__set_quirk( + wuffs_base__io_transformer* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - wuffs_base__transform__output o; - size_t src_len2 = src.len / 2; - size_t len; - if (dst.len < src_len2) { - len = dst.len; - o.status.repr = wuffs_base__suspension__short_write; - } else { - len = src_len2; - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - } else if (src.len & 1) { - o.status.repr = wuffs_base__error__bad_data; - } else { - o.status.repr = NULL; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { + const wuffs_base__io_transformer__func_ptrs* func_ptrs = + (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; } + v++; } - uint8_t* d = dst.ptr; - uint8_t* s = src.ptr; - size_t n = len; + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} - while (n--) { - *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) | - (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F)); - d += 1; - s += 2; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__io_transformer__transform_io( + wuffs_base__io_transformer* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - o.num_dst = len; - o.num_src = len * 2; - return o; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { + const wuffs_base__io_transformer__func_ptrs* func_ptrs = + (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); + return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } + + return wuffs_base__make_status(wuffs_base__error__bad_vtable); } -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - wuffs_base__transform__output o; - size_t src_len4 = src.len / 4; - size_t len = dst.len < src_len4 ? dst.len : src_len4; - if (dst.len < src_len4) { - len = dst.len; - o.status.repr = wuffs_base__suspension__short_write; - } else { - len = src_len4; - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - } else if (src.len & 1) { - o.status.repr = wuffs_base__error__bad_data; - } else { - o.status.repr = NULL; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_base__io_transformer__workbuf_len( + const wuffs_base__io_transformer* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); } - uint8_t* d = dst.ptr; - uint8_t* s = src.ptr; - size_t n = len; - - while (n--) { - *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) | - (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F)); - d += 1; - s += 4; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__io_transformer__vtable_name) { + const wuffs_base__io_transformer__func_ptrs* func_ptrs = + (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers); + return (*func_ptrs->workbuf_len)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - o.num_dst = len; - o.num_src = len * 4; - return o; + return wuffs_base__utility__empty_range_ii_u64(); } -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - wuffs_base__transform__output o; - size_t dst_len2 = dst.len / 2; - size_t len; - if (dst_len2 < src.len) { - len = dst_len2; - o.status.repr = wuffs_base__suspension__short_write; - } else { - len = src.len; - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - } else { - o.status.repr = NULL; - } - } +// -------- - uint8_t* d = dst.ptr; - uint8_t* s = src.ptr; - size_t n = len; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__token_decoder__decode_tokens( + wuffs_base__token_decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } - while (n--) { - uint8_t c = *s; - d[0] = wuffs_base__private_implementation__encode_base16[c >> 4]; - d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F]; - d += 2; - s += 1; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { + const wuffs_base__token_decoder__func_ptrs* func_ptrs = + (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - o.num_dst = len * 2; - o.num_src = len; - return o; + return wuffs_base__make_status(wuffs_base__error__bad_vtable); } -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - wuffs_base__transform__output o; - size_t dst_len4 = dst.len / 4; - size_t len; - if (dst_len4 < src.len) { - len = dst_len4; - o.status.repr = wuffs_base__suspension__short_write; - } else { - len = src.len; - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - } else { - o.status.repr = NULL; - } +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_base__token_decoder__get_quirk( + const wuffs_base__token_decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - uint8_t* d = dst.ptr; - uint8_t* s = src.ptr; - size_t n = len; - - while (n--) { - uint8_t c = *s; - d[0] = '\\'; - d[1] = 'x'; - d[2] = wuffs_base__private_implementation__encode_base16[c >> 4]; - d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F]; - d += 4; - s += 1; + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { + const wuffs_base__token_decoder__func_ptrs* func_ptrs = + (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->get_quirk)(self, a_key); + } else if (v->vtable_name == NULL) { + break; + } + v++; } - o.num_dst = len * 4; - o.num_src = len; - return o; + return 0; } -// ---------------- Base-64 +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_base__token_decoder__set_quirk( + wuffs_base__token_decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -// The two base-64 alphabets, std and url, differ only in the last two codes. -// - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" -// - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { + const wuffs_base__token_decoder__func_ptrs* func_ptrs = + (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->set_quirk)(self, a_key, a_value); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } -static const uint8_t wuffs_base__base_64__decode_std[256] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27. - 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, // 0x28 ..= 0x2F. - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37. - 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F. + return wuffs_base__make_status(wuffs_base__error__bad_vtable); +} - 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47. - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F. - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57. - 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x58 ..= 0x5F. - 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67. - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F. - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77. - 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F. +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_base__token_decoder__workbuf_len( + const wuffs_base__token_decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF. + const wuffs_base__vtable* v = &self->private_impl.first_vtable; + int i; + for (i = 0; i < 63; i++) { + if (v->vtable_name == wuffs_base__token_decoder__vtable_name) { + const wuffs_base__token_decoder__func_ptrs* func_ptrs = + (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers); + return (*func_ptrs->workbuf_len)(self); + } else if (v->vtable_name == NULL) { + break; + } + v++; + } - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F -}; + return wuffs_base__utility__empty_range_ii_u64(); +} -static const uint8_t wuffs_base__base_64__decode_url[256] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, // 0x28 ..= 0x2F. - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37. - 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F. +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES) - 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47. - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F. - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57. - 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F, // 0x58 ..= 0x5F. - 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67. - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F. - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77. - 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F. +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV) - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF. +// ---------------- IEEE 754 Floating Point - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F +// The etc__hpd_left_shift and etc__powers_of_5 tables were printed by +// script/print-hpd-left-shift.go. That script has an optional -comments flag, +// whose output is not copied here, which prints further detail. +// +// These tables are used in +// wuffs_private_impl__high_prec_dec__lshift_num_new_digits. + +// wuffs_private_impl__hpd_left_shift[i] encodes the number of new digits +// created after multiplying a positive integer by (1 << i): the additional +// length in the decimal representation. For example, shifting "234" by 3 +// (equivalent to multiplying by 8) will produce "1872". Going from a 3-length +// string to a 4-length string means that 1 new digit was added (and existing +// digits may have changed). +// +// Shifting by i can add either N or N-1 new digits, depending on whether the +// original positive integer compares >= or < to the i'th power of 5 (as 10 +// equals 2 * 5). Comparison is lexicographic, not numerical. +// +// For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new +// digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625": +// - ("1" << 4) is "16", which adds 1 new digit. +// - ("5678" << 4) is "90848", which adds 1 new digit. +// - ("624" << 4) is "9984", which adds 1 new digit. +// - ("62498" << 4) is "999968", which adds 1 new digit. +// - ("625" << 4) is "10000", which adds 2 new digits. +// - ("625001" << 4) is "10000016", which adds 2 new digits. +// - ("7008" << 4) is "112128", which adds 2 new digits. +// - ("99" << 4) is "1584", which adds 2 new digits. +// +// Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift +// array encodes this as: +// - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006. +// - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009. +// where the ? isn't relevant for i == 4. +// +// The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two +// possible number of new digits. The low 11 bits are an offset into the +// etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i +// is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9] +// is the string "\x06\x02\x05", so the relevant power of 5 is "625". +// +// Thanks to Ken Thompson for the original idea. +static const uint16_t wuffs_private_impl__hpd_left_shift[65] = { + 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, + 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, + 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, + 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0, + 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA, + 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, + 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, + 0x051C, 0x051C, }; -static const uint8_t wuffs_base__base_64__encode_std[64] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07. - 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F. - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17. - 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F. - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27. - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F. - 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37. - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, // 0x38 ..= 0x3F. +// wuffs_private_impl__powers_of_5 contains the powers of 5, concatenated +// together: "5", "25", "125", "625", "3125", etc. +static const uint8_t wuffs_private_impl__powers_of_5[0x051C] = { + 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, + 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, + 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, + 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0, + 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5, + 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1, + 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, + 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, + 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, + 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, + 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, + 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6, + 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, + 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, + 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, + 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8, + 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, + 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, + 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, + 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, + 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, + 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, + 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, + 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5, + 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, + 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, + 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, + 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8, + 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4, + 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0, + 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, + 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, + 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, + 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, + 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4, + 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3, + 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, + 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, + 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, + 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, + 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, + 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, + 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, + 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, + 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, + 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, + 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6, + 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1, + 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, + 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, + 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, + 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3, + 6, 9, 1, 4, 0, 6, 2, 5, }; -static const uint8_t wuffs_base__base_64__encode_url[64] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07. - 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F. - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17. - 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F. - 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27. - 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F. - 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37. - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F, // 0x38 ..= 0x3F. +// -------- + +// wuffs_private_impl__powers_of_10 contains truncated approximations to the +// powers of 10, ranging from 1e-307 to 1e+288 inclusive, as 596 pairs of +// uint64_t values (a 128-bit mantissa). +// +// There's also an implicit third column (implied by a linear formula involving +// the base-10 exponent) that is the base-2 exponent, biased by a magic +// constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias +// for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and +// wuffs_private_impl__parse_number_f64_eisel_lemire works with +// multiples-of-64-bit mantissas. +// +// For example, the third row holds the approximation to 1e-305: +// 0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE)) +// +// Similarly, 1e+4 is approximated by: +// 0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE)) +// +// Similarly, 1e+68 is approximated by: +// 0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE)) +// +// This table was generated by by script/print-mpb-powers-of-10.go +static const uint64_t wuffs_private_impl__powers_of_10[596][2] = { + {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307 + {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306 + {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305 + {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304 + {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303 + {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302 + {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301 + {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300 + {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299 + {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298 + {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297 + {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296 + {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295 + {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294 + {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293 + {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292 + {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291 + {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290 + {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289 + {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288 + {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287 + {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286 + {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285 + {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284 + {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283 + {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282 + {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281 + {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280 + {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279 + {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278 + {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277 + {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276 + {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275 + {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274 + {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273 + {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272 + {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271 + {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270 + {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269 + {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268 + {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267 + {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266 + {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265 + {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264 + {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263 + {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262 + {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261 + {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260 + {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259 + {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258 + {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257 + {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256 + {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255 + {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254 + {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253 + {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252 + {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251 + {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250 + {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249 + {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248 + {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247 + {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246 + {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245 + {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244 + {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243 + {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242 + {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241 + {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240 + {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239 + {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238 + {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237 + {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236 + {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235 + {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234 + {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233 + {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232 + {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231 + {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230 + {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229 + {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228 + {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227 + {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226 + {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225 + {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224 + {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223 + {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222 + {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221 + {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220 + {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219 + {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218 + {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217 + {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216 + {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215 + {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214 + {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213 + {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212 + {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211 + {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210 + {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209 + {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208 + {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207 + {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206 + {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205 + {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204 + {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203 + {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202 + {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201 + {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200 + {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199 + {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198 + {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197 + {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196 + {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195 + {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194 + {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193 + {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192 + {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191 + {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190 + {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189 + {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188 + {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187 + {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186 + {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185 + {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184 + {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183 + {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182 + {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181 + {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180 + {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179 + {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178 + {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177 + {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176 + {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175 + {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174 + {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173 + {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172 + {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171 + {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170 + {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169 + {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168 + {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167 + {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166 + {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165 + {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164 + {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163 + {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162 + {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161 + {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160 + {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159 + {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158 + {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157 + {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156 + {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155 + {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154 + {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153 + {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152 + {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151 + {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150 + {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149 + {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148 + {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147 + {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146 + {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145 + {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144 + {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143 + {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142 + {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141 + {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140 + {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139 + {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138 + {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137 + {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136 + {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135 + {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134 + {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133 + {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132 + {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131 + {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130 + {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129 + {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128 + {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127 + {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126 + {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125 + {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124 + {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123 + {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122 + {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121 + {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120 + {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119 + {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118 + {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117 + {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116 + {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115 + {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114 + {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113 + {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112 + {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111 + {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110 + {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109 + {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108 + {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107 + {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106 + {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105 + {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104 + {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103 + {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102 + {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101 + {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100 + {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99 + {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98 + {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97 + {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96 + {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95 + {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94 + {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93 + {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92 + {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91 + {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90 + {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89 + {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88 + {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87 + {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86 + {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85 + {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84 + {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83 + {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82 + {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81 + {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80 + {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79 + {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78 + {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77 + {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76 + {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75 + {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74 + {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73 + {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72 + {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71 + {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70 + {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69 + {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68 + {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67 + {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66 + {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65 + {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64 + {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63 + {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62 + {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61 + {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60 + {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59 + {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58 + {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57 + {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56 + {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55 + {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54 + {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53 + {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52 + {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51 + {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50 + {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49 + {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48 + {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47 + {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46 + {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45 + {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44 + {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43 + {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42 + {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41 + {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40 + {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39 + {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38 + {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37 + {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36 + {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35 + {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34 + {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33 + {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32 + {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31 + {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30 + {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29 + {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28 + {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27 + {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26 + {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25 + {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24 + {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23 + {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22 + {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21 + {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20 + {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19 + {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18 + {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17 + {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16 + {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15 + {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14 + {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13 + {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12 + {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11 + {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10 + {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9 + {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8 + {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7 + {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6 + {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5 + {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4 + {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3 + {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2 + {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1 + {0x0000000000000000, 0x8000000000000000}, // 1e0 + {0x0000000000000000, 0xA000000000000000}, // 1e1 + {0x0000000000000000, 0xC800000000000000}, // 1e2 + {0x0000000000000000, 0xFA00000000000000}, // 1e3 + {0x0000000000000000, 0x9C40000000000000}, // 1e4 + {0x0000000000000000, 0xC350000000000000}, // 1e5 + {0x0000000000000000, 0xF424000000000000}, // 1e6 + {0x0000000000000000, 0x9896800000000000}, // 1e7 + {0x0000000000000000, 0xBEBC200000000000}, // 1e8 + {0x0000000000000000, 0xEE6B280000000000}, // 1e9 + {0x0000000000000000, 0x9502F90000000000}, // 1e10 + {0x0000000000000000, 0xBA43B74000000000}, // 1e11 + {0x0000000000000000, 0xE8D4A51000000000}, // 1e12 + {0x0000000000000000, 0x9184E72A00000000}, // 1e13 + {0x0000000000000000, 0xB5E620F480000000}, // 1e14 + {0x0000000000000000, 0xE35FA931A0000000}, // 1e15 + {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16 + {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17 + {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18 + {0x0000000000000000, 0x8AC7230489E80000}, // 1e19 + {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20 + {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21 + {0x0000000000000000, 0x878678326EAC9000}, // 1e22 + {0x0000000000000000, 0xA968163F0A57B400}, // 1e23 + {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24 + {0x0000000000000000, 0x84595161401484A0}, // 1e25 + {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26 + {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27 + {0x4000000000000000, 0x813F3978F8940984}, // 1e28 + {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29 + {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30 + {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31 + {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32 + {0x6C28000000000000, 0xC5371912364CE305}, // 1e33 + {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34 + {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35 + {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36 + {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37 + {0x1314448000000000, 0x96769950B50D88F4}, // 1e38 + {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39 + {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40 + {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41 + {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42 + {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43 + {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44 + {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45 + {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46 + {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47 + {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48 + {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49 + {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50 + {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51 + {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52 + {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53 + {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54 + {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55 + {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56 + {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57 + {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58 + {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59 + {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60 + {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61 + {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62 + {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63 + {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64 + {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65 + {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66 + {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67 + {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68 + {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69 + {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70 + {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71 + {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72 + {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73 + {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74 + {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75 + {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76 + {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77 + {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78 + {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79 + {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80 + {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81 + {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82 + {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83 + {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84 + {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85 + {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86 + {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87 + {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88 + {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89 + {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90 + {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91 + {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92 + {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93 + {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94 + {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95 + {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96 + {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97 + {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98 + {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99 + {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100 + {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101 + {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102 + {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103 + {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104 + {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105 + {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106 + {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107 + {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108 + {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109 + {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110 + {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111 + {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112 + {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113 + {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114 + {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115 + {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116 + {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117 + {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118 + {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119 + {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120 + {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121 + {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122 + {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123 + {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124 + {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125 + {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126 + {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127 + {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128 + {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129 + {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130 + {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131 + {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132 + {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133 + {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134 + {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135 + {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136 + {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137 + {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138 + {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139 + {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140 + {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141 + {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142 + {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143 + {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144 + {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145 + {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146 + {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147 + {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148 + {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149 + {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150 + {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151 + {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152 + {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153 + {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154 + {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155 + {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156 + {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157 + {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158 + {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159 + {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160 + {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161 + {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162 + {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163 + {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164 + {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165 + {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166 + {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167 + {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168 + {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169 + {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170 + {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171 + {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172 + {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173 + {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174 + {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175 + {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176 + {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177 + {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178 + {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179 + {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180 + {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181 + {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182 + {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183 + {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184 + {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185 + {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186 + {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187 + {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188 + {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189 + {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190 + {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191 + {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192 + {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193 + {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194 + {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195 + {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196 + {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197 + {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198 + {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199 + {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200 + {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201 + {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202 + {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203 + {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204 + {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205 + {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206 + {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207 + {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208 + {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209 + {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210 + {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211 + {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212 + {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213 + {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214 + {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215 + {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216 + {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217 + {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218 + {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219 + {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220 + {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221 + {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222 + {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223 + {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224 + {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225 + {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226 + {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227 + {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228 + {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229 + {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230 + {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231 + {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232 + {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233 + {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234 + {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235 + {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236 + {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237 + {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238 + {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239 + {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240 + {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241 + {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242 + {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243 + {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244 + {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245 + {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246 + {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247 + {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248 + {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249 + {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250 + {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251 + {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252 + {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253 + {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254 + {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255 + {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256 + {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257 + {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258 + {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259 + {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260 + {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261 + {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262 + {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263 + {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264 + {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265 + {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266 + {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267 + {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268 + {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269 + {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270 + {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271 + {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272 + {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273 + {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274 + {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275 + {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276 + {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277 + {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278 + {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279 + {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280 + {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281 + {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282 + {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283 + {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284 + {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285 + {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286 + {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287 + {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288 }; -// -------- +// wuffs_private_impl__f64_powers_of_10 holds powers of 10 that can be exactly +// represented by a float64 (what C calls a double). +static const double wuffs_private_impl__f64_powers_of_10[23] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, +}; -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_64__decode(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET) - ? wuffs_base__base_64__decode_url - : wuffs_base__base_64__decode_std; - wuffs_base__transform__output o; - uint8_t* d_ptr = dst.ptr; - size_t d_len = dst.len; - const uint8_t* s_ptr = src.ptr; - size_t s_len = src.len; - bool pad = false; +// ---------------- IEEE 754 Floating Point - while (s_len >= 4) { - uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr); - uint32_t s0 = alphabet[0xFF & (s >> 0)]; - uint32_t s1 = alphabet[0xFF & (s >> 8)]; - uint32_t s2 = alphabet[0xFF & (s >> 16)]; - uint32_t s3 = alphabet[0xFF & (s >> 24)]; +WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 // +wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) { + uint64_t u = 0; + if (sizeof(uint64_t) == sizeof(double)) { + memcpy(&u, &f, sizeof(uint64_t)); + } + uint16_t neg = ((uint16_t)((u >> 63) << 15)); + u &= 0x7FFFFFFFFFFFFFFF; + uint64_t exp = u >> 52; + uint64_t man = u & 0x000FFFFFFFFFFFFF; - if (((s0 | s1 | s2 | s3) & 0xC0) != 0) { - if (s_len > 4) { - o.status.repr = wuffs_base__error__bad_data; - goto done; - } else if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - goto done; - } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) && - (s_ptr[3] == '=')) { - pad = true; - if (s_ptr[2] == '=') { - goto src2; - } - goto src3; - } - o.status.repr = wuffs_base__error__bad_data; - goto done; + if (exp == 0x7FF) { + if (man == 0) { // Infinity. + wuffs_base__lossy_value_u16 ret; + ret.value = neg | 0x7C00; + ret.lossy = false; + return ret; } + // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most + // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9 + // bits of ret.value so that the 10-bit mantissa is non-zero. + wuffs_base__lossy_value_u16 ret; + ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42)); + ret.lossy = false; + return ret; - if (d_len < 3) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } + } else if (exp > 0x40E) { // Truncate to the largest finite f16. + wuffs_base__lossy_value_u16 ret; + ret.value = neg | 0x7BFF; + ret.lossy = true; + return ret; - s_ptr += 4; - s_len -= 4; - s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0); - *d_ptr++ = (uint8_t)(s >> 16); - *d_ptr++ = (uint8_t)(s >> 8); - *d_ptr++ = (uint8_t)(s >> 0); - d_len -= 3; - } - - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - goto done; - } + } else if (exp <= 0x3E6) { // Truncate to zero. + wuffs_base__lossy_value_u16 ret; + ret.value = neg; + ret.lossy = (u != 0); + return ret; - if (s_len == 0) { - o.status.repr = NULL; - goto done; - } else if (s_len == 1) { - o.status.repr = wuffs_base__error__bad_data; - goto done; - } else if (s_len == 2) { - goto src2; + } else if (exp <= 0x3F0) { // Normal f64, subnormal f16. + // Convert from a 53-bit mantissa (after realizing the implicit bit) to a + // 10-bit mantissa and then adjust for the exponent. + man |= 0x0010000000000000; + uint32_t shift = ((uint32_t)(1051 - exp)); // 1051 = 0x3F0 + 53 - 10. + uint64_t shifted_man = man >> shift; + wuffs_base__lossy_value_u16 ret; + ret.value = neg | ((uint16_t)shifted_man); + ret.lossy = (shifted_man << shift) != man; + return ret; } -src3: - do { - uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr); - uint32_t s0 = alphabet[0xFF & (s >> 0)]; - uint32_t s1 = alphabet[0xFF & (s >> 8)]; - uint32_t s2 = alphabet[0xFF & (s >> 16)]; - if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) { - o.status.repr = wuffs_base__error__bad_data; - goto done; - } - if (d_len < 2) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } - s_ptr += pad ? 4 : 3; - s = (s0 << 18) | (s1 << 12) | (s2 << 6); - *d_ptr++ = (uint8_t)(s >> 16); - *d_ptr++ = (uint8_t)(s >> 8); - o.status.repr = NULL; - goto done; - } while (0); + // Normal f64, normal f16. -src2: - do { - uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr); - uint32_t s0 = alphabet[0xFF & (s >> 0)]; - uint32_t s1 = alphabet[0xFF & (s >> 8)]; - if ((s0 & 0xC0) || (s1 & 0xCF)) { - o.status.repr = wuffs_base__error__bad_data; - goto done; - } - if (d_len < 1) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } - s_ptr += pad ? 4 : 2; - s = (s0 << 18) | (s1 << 12); - *d_ptr++ = (uint8_t)(s >> 16); - o.status.repr = NULL; - goto done; - } while (0); + // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits. + exp = (exp - 1008) << 10; // 1008 = 1023 - 15 = 0x3FF - 0xF. -done: - o.num_dst = (size_t)(d_ptr - dst.ptr); - o.num_src = (size_t)(s_ptr - src.ptr); - return o; + // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit + // mantissa (again excluding the implicit bit). We lose some information if + // any of the bottom 42 bits are non-zero. + wuffs_base__lossy_value_u16 ret; + ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42)); + ret.lossy = (man << 22) != 0; + return ret; } -WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // -wuffs_base__base_64__encode(wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 src, - bool src_closed, - uint32_t options) { - const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET) - ? wuffs_base__base_64__encode_url - : wuffs_base__base_64__encode_std; - wuffs_base__transform__output o; - uint8_t* d_ptr = dst.ptr; - size_t d_len = dst.len; - const uint8_t* s_ptr = src.ptr; - size_t s_len = src.len; +WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 // +wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) { + uint64_t u = 0; + if (sizeof(uint64_t) == sizeof(double)) { + memcpy(&u, &f, sizeof(uint64_t)); + } + uint32_t neg = ((uint32_t)(u >> 63)) << 31; + u &= 0x7FFFFFFFFFFFFFFF; + uint64_t exp = u >> 52; + uint64_t man = u & 0x000FFFFFFFFFFFFF; - do { - while (s_len >= 3) { - if (d_len < 4) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } - uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr); - s_ptr += 3; - s_len -= 3; - *d_ptr++ = alphabet[0x3F & (s >> 18)]; - *d_ptr++ = alphabet[0x3F & (s >> 12)]; - *d_ptr++ = alphabet[0x3F & (s >> 6)]; - *d_ptr++ = alphabet[0x3F & (s >> 0)]; - d_len -= 4; + if (exp == 0x7FF) { + if (man == 0) { // Infinity. + wuffs_base__lossy_value_u32 ret; + ret.value = neg | 0x7F800000; + ret.lossy = false; + return ret; } + // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most + // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22 + // bits of ret.value so that the 23-bit mantissa is non-zero. + wuffs_base__lossy_value_u32 ret; + ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29)); + ret.lossy = false; + return ret; - if (!src_closed) { - o.status.repr = wuffs_base__suspension__short_read; - goto done; - } + } else if (exp > 0x47E) { // Truncate to the largest finite f32. + wuffs_base__lossy_value_u32 ret; + ret.value = neg | 0x7F7FFFFF; + ret.lossy = true; + return ret; - if (s_len == 2) { - if (d_len < - ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } - uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr))) - << 8; - s_ptr += 2; - *d_ptr++ = alphabet[0x3F & (s >> 18)]; - *d_ptr++ = alphabet[0x3F & (s >> 12)]; - *d_ptr++ = alphabet[0x3F & (s >> 6)]; - if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) { - *d_ptr++ = '='; - } - o.status.repr = NULL; - goto done; + } else if (exp <= 0x369) { // Truncate to zero. + wuffs_base__lossy_value_u32 ret; + ret.value = neg; + ret.lossy = (u != 0); + return ret; - } else if (s_len == 1) { - if (d_len < - ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) { - o.status.repr = wuffs_base__suspension__short_write; - goto done; - } - uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr))) - << 16; - s_ptr += 1; - *d_ptr++ = alphabet[0x3F & (s >> 18)]; - *d_ptr++ = alphabet[0x3F & (s >> 12)]; - if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) { - *d_ptr++ = '='; - *d_ptr++ = '='; - } - o.status.repr = NULL; - goto done; + } else if (exp <= 0x380) { // Normal f64, subnormal f32. + // Convert from a 53-bit mantissa (after realizing the implicit bit) to a + // 23-bit mantissa and then adjust for the exponent. + man |= 0x0010000000000000; + uint32_t shift = ((uint32_t)(926 - exp)); // 926 = 0x380 + 53 - 23. + uint64_t shifted_man = man >> shift; + wuffs_base__lossy_value_u32 ret; + ret.value = neg | ((uint32_t)shifted_man); + ret.lossy = (shifted_man << shift) != man; + return ret; + } - } else { - o.status.repr = NULL; - goto done; - } - } while (0); + // Normal f64, normal f32. -done: - o.num_dst = (size_t)(d_ptr - dst.ptr); - o.num_src = (size_t)(s_ptr - src.ptr); - return o; + // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits. + exp = (exp - 896) << 23; // 896 = 1023 - 127 = 0x3FF - 0x7F. + + // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit + // mantissa (again excluding the implicit bit). We lose some information if + // any of the bottom 29 bits are non-zero. + wuffs_base__lossy_value_u32 ret; + ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29)); + ret.lossy = (man << 35) != 0; + return ret; } -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV) +// -------- -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__MAGIC) +#define WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE 2047 +#define WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION 800 -// ---------------- Magic Numbers +// WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL is the largest N such that +// ((10 << N) < (1 << 64)). +#define WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL 60 -// ICO doesn't start with a magic identifier. Instead, see if the opening bytes -// are plausibly ICO. +// wuffs_private_impl__high_prec_dec (abbreviated as HPD) is a fixed precision +// floating point decimal number, augmented with ±infinity values, but it +// cannot represent NaN (Not a Number). // -// Callers should have already verified that (prefix_data.len >= 2) and the -// first two bytes are 0x00. +// "High precision" means that the mantissa holds 800 decimal digits. 800 is +// WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION. // -// See: -// - https://docs.fileformat.com/image/ico/ -static int32_t // -wuffs_base__magic_number_guess_fourcc__maybe_ico( - wuffs_base__slice_u8 prefix_data, - bool prefix_closed) { - // Allow-list for the Image Type field. - if (prefix_data.len < 4) { - return prefix_closed ? 0 : -1; - } else if (prefix_data.ptr[3] != 0) { - return 0; - } - switch (prefix_data.ptr[2]) { - case 0x01: // ICO - case 0x02: // CUR - break; - default: - return 0; - } - - // The Number Of Images should be positive. - if (prefix_data.len < 6) { - return prefix_closed ? 0 : -1; - } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) { - return 0; - } +// An HPD isn't for general purpose arithmetic, only for conversions to and +// from IEEE 754 double-precision floating point, where the largest and +// smallest positive, finite values are approximately 1.8e+308 and 4.9e-324. +// HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047 +// bounds are further away from zero than ±(324 + 800), where 800 and 2047 is +// WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION and +// WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE. +// +// digits[.. num_digits] are the number's digits in big-endian order. The +// uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7' +// is the ASCII value 0x37. +// +// decimal_point is the index (within digits) of the decimal point. It may be +// negative or be larger than num_digits, in which case the explicit digits are +// padded with implicit zeroes. +// +// For example, if num_digits is 3 and digits is "\x07\x08\x09": +// - A decimal_point of -2 means ".00789" +// - A decimal_point of -1 means ".0789" +// - A decimal_point of +0 means ".789" +// - A decimal_point of +1 means "7.89" +// - A decimal_point of +2 means "78.9" +// - A decimal_point of +3 means "789." +// - A decimal_point of +4 means "7890." +// - A decimal_point of +5 means "78900." +// +// As above, a decimal_point higher than +2047 means that the overall value is +// infinity, lower than -2047 means zero. +// +// negative is a sign bit. An HPD can distinguish positive and negative zero. +// +// truncated is whether there are more than +// WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION digits, and at least one of those +// extra digits are non-zero. The existence of long-tail digits can affect +// rounding. +// +// The "all fields are zero" value is valid, and represents the number +0. +typedef struct wuffs_private_impl__high_prec_dec__struct { + uint32_t num_digits; + int32_t decimal_point; + bool negative; + bool truncated; + uint8_t digits[WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION]; +} wuffs_private_impl__high_prec_dec; - // The first ICONDIRENTRY's fourth byte should be zero. - if (prefix_data.len < 10) { - return prefix_closed ? 0 : -1; - } else if (prefix_data.ptr[9] != 0) { - return 0; +// wuffs_private_impl__high_prec_dec__trim trims trailing zeroes from the +// h->digits[.. h->num_digits] slice. They have no benefit, since we explicitly +// track h->decimal_point. +// +// Preconditions: +// - h is non-NULL. +static inline void // +wuffs_private_impl__high_prec_dec__trim(wuffs_private_impl__high_prec_dec* h) { + while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) { + h->num_digits--; } - - // TODO: have a separate FourCC for CUR? - return 0x49434F20; // 'ICO 'be } -// TGA doesn't start with a magic identifier. Instead, see if the opening bytes -// are plausibly TGA. +// wuffs_private_impl__high_prec_dec__assign sets h to represent the number x. // -// Callers should have already verified that (prefix_data.len >= 2) and the -// second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or -// 0x01. -// -// See: -// - https://docs.fileformat.com/image/tga/ -// - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf -static int32_t // -wuffs_base__magic_number_guess_fourcc__maybe_tga( - wuffs_base__slice_u8 prefix_data, - bool prefix_closed) { - // Allow-list for the Image Type field. - if (prefix_data.len < 3) { - return prefix_closed ? 0 : -1; - } - switch (prefix_data.ptr[2]) { - case 0x01: - case 0x02: - case 0x03: - case 0x09: - case 0x0A: - case 0x0B: - break; - default: - // TODO: 0x20 and 0x21 are invalid, according to the spec, but are - // apparently unofficial extensions. - return 0; - } - - // Allow-list for the Color Map Entry Size field (if the Color Map Type field - // is non-zero) or else all the Color Map fields should be zero. - if (prefix_data.len < 8) { - return prefix_closed ? 0 : -1; - } else if (prefix_data.ptr[1] != 0x00) { - switch (prefix_data.ptr[7]) { - case 0x0F: - case 0x10: - case 0x18: - case 0x20: - break; - default: - return 0; - } - } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] | - prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) { - return 0; - } +// Preconditions: +// - h is non-NULL. +static void // +wuffs_private_impl__high_prec_dec__assign(wuffs_private_impl__high_prec_dec* h, + uint64_t x, + bool negative) { + uint32_t n = 0; - // Allow-list for the Pixel Depth field. - if (prefix_data.len < 17) { - return prefix_closed ? 0 : -1; - } - switch (prefix_data.ptr[16]) { - case 0x01: - case 0x08: - case 0x0F: - case 0x10: - case 0x18: - case 0x20: - break; - default: - return 0; + // Set h->digits. + if (x > 0) { + // Calculate the digits, working right-to-left. After we determine n (how + // many digits there are), copy from buf to h->digits. + // + // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to + // copy a constant number of bytes than a variable number (20 instead of + // n). Make buf large enough (and start writing to it from the middle) so + // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)]. + uint8_t buf[40] = {0}; + uint8_t* ptr = &buf[20]; + do { + uint64_t remaining = x / 10; + x -= remaining * 10; + ptr--; + *ptr = (uint8_t)x; + n++; + x = remaining; + } while (x > 0); + memcpy(h->digits, ptr, 20); } - return 0x54474120; // 'TGA 'be + // Set h's other fields. + h->num_digits = n; + h->decimal_point = (int32_t)n; + h->negative = negative; + h->truncated = false; + wuffs_private_impl__high_prec_dec__trim(h); } -WUFFS_BASE__MAYBE_STATIC int32_t // -wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data, - bool prefix_closed) { - // This is similar to (but different from): - // - the magic/Magdir tables under https://github.com/file/file - // - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/ - - // table holds the 'magic numbers' (which are actually variable length - // strings). The strings may contain NUL bytes, so the "const char* magic" - // value starts with the length-minus-1 of the 'magic number'. - // - // Keep it sorted by magic[1], then magic[0] descending (prioritizing longer - // matches) and finally by magic[2:]. When multiple entries match, the - // longest one wins. - // - // The fourcc field might be negated, in which case there's further - // specialization (see § below). - static struct { - int32_t fourcc; - const char* magic; - } table[] = { - {-0x30302020, "\x01\x00\x00"}, // '00 'be - {+0x475A2020, "\x02\x1F\x8B\x08"}, // GZ - {+0x5A535444, "\x03\x28\xB5\x2F\xFD"}, // ZSTD - {+0x425A3220, "\x02\x42\x5A\x68"}, // BZ2 - {+0x424D5020, "\x01\x42\x4D"}, // BMP - {+0x47494620, "\x03\x47\x49\x46\x38"}, // GIF - {+0x54494646, "\x03\x49\x49\x2A\x00"}, // TIFF (little-endian) - {+0x54494646, "\x03\x4D\x4D\x00\x2A"}, // TIFF (big-endian) - {+0x4E50424D, "\x02\x50\x35\x0A"}, // NPBM (P5; *.pgm) - {+0x4E50424D, "\x02\x50\x36\x0A"}, // NPBM (P6; *.ppm) - {-0x52494646, "\x03\x52\x49\x46\x46"}, // RIFF - {+0x4C5A4D41, "\x04\x5D\x00\x10\x00\x00"}, // LZMA - {+0x4C5A4D41, "\x02\x5D\x00\x00"}, // LZMA - {+0x4E494520, "\x02\x6E\xC3\xAF"}, // NIE - {+0x514F4920, "\x03\x71\x6F\x69\x66"}, // QOI - {+0x5A4C4942, "\x01\x78\x9C"}, // ZLIB - {+0x504E4720, "\x03\x89\x50\x4E\x47"}, // PNG - {+0x585A2020, "\x04\xFD\x37\x7A\x58\x5A"}, // XZ - {+0x4A504547, "\x01\xFF\xD8"}, // JPEG - }; - static const size_t table_len = sizeof(table) / sizeof(table[0]); - - if (prefix_data.len == 0) { - return prefix_closed ? 0 : -1; +static wuffs_base__status // +wuffs_private_impl__high_prec_dec__parse(wuffs_private_impl__high_prec_dec* h, + wuffs_base__slice_u8 s, + uint32_t options) { + if (!h) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - uint8_t pre_first_byte = prefix_data.ptr[0]; + h->num_digits = 0; + h->decimal_point = 0; + h->negative = false; + h->truncated = false; - int32_t fourcc = 0; - size_t i; - for (i = 0; i < table_len; i++) { - uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1])); - if (pre_first_byte < mag_first_byte) { - break; - } else if (pre_first_byte > mag_first_byte) { - continue; - } - fourcc = table[i].fourcc; + uint8_t* p = s.ptr; + uint8_t* q = s.ptr + s.len; - uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0])); - if (mag_remaining_len == 0) { - goto match; + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (;; p++) { + if (p >= q) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } else if (*p != '_') { + break; + } } + } - const char* mag_remaining_ptr = table[i].magic + 2; - uint8_t* pre_remaining_ptr = prefix_data.ptr + 1; - size_t pre_remaining_len = prefix_data.len - 1; - if (pre_remaining_len < mag_remaining_len) { - if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) { - return prefix_closed ? 0 : -1; - } + // Parse sign. + do { + if (*p == '+') { + p++; + } else if (*p == '-') { + h->negative = true; + p++; } else { - if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) { - goto match; + break; + } + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (;; p++) { + if (p >= q) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } else if (*p != '_') { + break; + } } } - } - - if (prefix_data.len < 2) { - return prefix_closed ? 0 : -1; - } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) { - return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data, - prefix_closed); - } - - return 0; - -match: - // Negative FourCC values (see § above) are further specialized. - if (fourcc < 0) { - fourcc = -fourcc; + } while (0); - if (fourcc == 0x52494646) { // 'RIFF'be - if (prefix_data.len < 12) { - return prefix_closed ? 0 : -1; + // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each + // limb in this if-else chain: + // - "0.789" + // - "1002.789" + // - ".789" + // - Other (invalid input). + uint32_t nd = 0; + int32_t dp = 0; + bool no_digits_before_separator = false; + if (('0' == *p) && + !(options & + WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) { + p++; + for (;; p++) { + if (p >= q) { + goto after_all; + } else if (*p == + ((options & + WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.')) { + p++; + goto after_sep; + } else if ((*p == 'E') || (*p == 'e')) { + p++; + goto after_exp; + } else if ((*p != '_') || + !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); } - uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8); - if (x == 0x57454250) { // 'WEBP'be - return 0x57454250; // 'WEBP'be + } + + } else if (('0' <= *p) && (*p <= '9')) { + if (*p == '0') { + for (; (p < q) && (*p == '0'); p++) { } + } else { + h->digits[nd++] = (uint8_t)(*p - '0'); + dp = (int32_t)nd; + p++; + } - } else if (fourcc == 0x30302020) { // '00 'be - // Binary data starting with multiple 0x00 NUL bytes is quite common. - // Unfortunately, some file formats also don't start with a magic - // identifier, so we have to use heuristics (where the order matters, the - // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe - // it's TGA, ICO/CUR, etc. Maybe it's something else. - int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga( - prefix_data, prefix_closed); - if (tga != 0) { - return tga; + for (;; p++) { + if (p >= q) { + goto after_all; + } else if (('0' <= *p) && (*p <= '9')) { + if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[nd++] = (uint8_t)(*p - '0'); + dp = (int32_t)nd; + } else if ('0' != *p) { + // Long-tail non-zeroes set the truncated bit. + h->truncated = true; + } + } else if (*p == + ((options & + WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.')) { + p++; + goto after_sep; + } else if ((*p == 'E') || (*p == 'e')) { + p++; + goto after_exp; + } else if ((*p != '_') || + !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); } - int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico( - prefix_data, prefix_closed); - if (ico != 0) { - return ico; + } + + } else if (*p == ((options & + WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.')) { + p++; + no_digits_before_separator = true; + + } else { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + +after_sep: + for (;; p++) { + if (p >= q) { + goto after_all; + } else if ('0' == *p) { + if (nd == 0) { + // Track leading zeroes implicitly. + dp--; + } else if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[nd++] = (uint8_t)(*p - '0'); } - if (prefix_data.len < 4) { - return prefix_closed ? 0 : -1; - } else if ((prefix_data.ptr[2] != 0x00) && - ((prefix_data.ptr[2] >= 0x80) || - (prefix_data.ptr[3] != 0x00))) { - // Roughly speaking, this could be a non-degenerate (non-0-width and - // non-0-height) WBMP image. - return 0x57424D50; // 'WBMP'be + } else if (('0' < *p) && (*p <= '9')) { + if (nd < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[nd++] = (uint8_t)(*p - '0'); + } else { + // Long-tail non-zeroes set the truncated bit. + h->truncated = true; } - return 0; + } else if ((*p == 'E') || (*p == 'e')) { + p++; + goto after_exp; + } else if ((*p != '_') || + !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); } } - return fourcc; -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV) -// ---------------- Pixel Swizzler +after_exp: + do { + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (;; p++) { + if (p >= q) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } else if (*p != '_') { + break; + } + } + } -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -static uint64_t // -wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len); + int32_t exp_sign = +1; + if (*p == '+') { + p++; + } else if (*p == '-') { + exp_sign = -1; + p++; + } -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -static uint64_t // -wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len); + int32_t exp = 0; + const int32_t exp_large = WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE + + WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION; + bool saw_exp_digits = false; + for (; p < q; p++) { + if ((*p == '_') && + (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + // No-op. + } else if (('0' <= *p) && (*p <= '9')) { + saw_exp_digits = true; + if (exp < exp_large) { + exp = (10 * exp) + ((int32_t)(*p - '0')); + } + } else { + break; + } + } + if (!saw_exp_digits) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + dp += exp_sign * exp; + } while (0); -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -static uint64_t // -wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +after_all: + if (p != q) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + h->num_digits = nd; + if (nd == 0) { + if (no_digits_before_separator) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + h->decimal_point = 0; + } else if (dp < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) { + h->decimal_point = -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE - 1; + } else if (dp > +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) { + h->decimal_point = +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE + 1; + } else { + h->decimal_point = dp; + } + wuffs_private_impl__high_prec_dec__trim(h); + return wuffs_base__make_status(NULL); +} // -------- -static inline uint32_t // -wuffs_base__swap_u32_argb_abgr(uint32_t u) { - uint32_t o = u & 0xFF00FF00ul; - uint32_t r = u & 0x00FF0000ul; - uint32_t b = u & 0x000000FFul; - return o | (r >> 16) | (b << 16); -} +// wuffs_private_impl__high_prec_dec__lshift_num_new_digits returns the number +// of additional decimal digits when left-shifting by shift. +// +// See below for preconditions. +static uint32_t // +wuffs_private_impl__high_prec_dec__lshift_num_new_digits( + wuffs_private_impl__high_prec_dec* h, + uint32_t shift) { + // Masking with 0x3F should be unnecessary (assuming the preconditions) but + // it's cheap and ensures that we don't overflow the + // wuffs_private_impl__hpd_left_shift array. + shift &= 63; -static inline uint64_t // -wuffs_base__swap_u64_argb_abgr(uint64_t u) { - uint64_t o = u & 0xFFFF0000FFFF0000ull; - uint64_t r = u & 0x0000FFFF00000000ull; - uint64_t b = u & 0x000000000000FFFFull; - return o | (r >> 32) | (b << 32); -} + uint32_t x_a = wuffs_private_impl__hpd_left_shift[shift]; + uint32_t x_b = wuffs_private_impl__hpd_left_shift[shift + 1]; + uint32_t num_new_digits = x_a >> 11; + uint32_t pow5_a = 0x7FF & x_a; + uint32_t pow5_b = 0x7FF & x_b; -static inline uint32_t // -wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) { - uint32_t a = ((uint32_t)(0xFF & (c >> 56))); - uint32_t r = ((uint32_t)(0xFF & (c >> 40))); - uint32_t g = ((uint32_t)(0xFF & (c >> 24))); - uint32_t b = ((uint32_t)(0xFF & (c >> 8))); - return (a << 24) | (b << 16) | (g << 8) | (r << 0); + const uint8_t* pow5 = &wuffs_private_impl__powers_of_5[pow5_a]; + uint32_t i = 0; + uint32_t n = pow5_b - pow5_a; + for (; i < n; i++) { + if (i >= h->num_digits) { + return num_new_digits - 1; + } else if (h->digits[i] == pow5[i]) { + continue; + } else if (h->digits[i] < pow5[i]) { + return num_new_digits - 1; + } else { + return num_new_digits; + } + } + return num_new_digits; } // -------- -WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul // -wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb, - uint32_t x, - uint32_t y) { - if (!pb || (x >= pb->pixcfg.private_impl.width) || - (y >= pb->pixcfg.private_impl.height)) { +// wuffs_private_impl__high_prec_dec__rounded_integer returns the integral +// (non-fractional) part of h, provided that it is 18 or fewer decimal digits. +// For 19 or more digits, it returns UINT64_MAX. Note that: +// - (1 << 53) is 9007199254740992, which has 16 decimal digits. +// - (1 << 56) is 72057594037927936, which has 17 decimal digits. +// - (1 << 59) is 576460752303423488, which has 18 decimal digits. +// - (1 << 63) is 9223372036854775808, which has 19 decimal digits. +// and that IEEE 754 double precision has 52 mantissa bits. +// +// That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8. +// +// h's negative bit is ignored: rounding -8.6 returns 9. +// +// See below for preconditions. +static uint64_t // +wuffs_private_impl__high_prec_dec__rounded_integer( + wuffs_private_impl__high_prec_dec* h) { + if ((h->num_digits == 0) || (h->decimal_point < 0)) { return 0; + } else if (h->decimal_point > 18) { + return UINT64_MAX; } - if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { - // TODO: support planar formats. - return 0; + uint32_t dp = (uint32_t)(h->decimal_point); + uint64_t n = 0; + uint32_t i = 0; + for (; i < dp; i++) { + n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0); } - size_t stride = pb->private_impl.planes[0].stride; - const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)); + bool round_up = false; + if (dp < h->num_digits) { + round_up = h->digits[dp] >= 5; + if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) { + // We are exactly halfway. If we're truncated, round up, otherwise round + // to even. + round_up = h->truncated || // + ((dp > 0) && (1 & h->digits[dp - 1])); + } + } + if (round_up) { + n++; + } - switch (pb->pixcfg.private_impl.pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))); + return n; +} - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: { - uint8_t* palette = pb->private_impl.planes[3].ptr; - return wuffs_base__peek_u32le__no_bounds_check(palette + - (4 * ((size_t)row[x]))); - } +// wuffs_private_impl__high_prec_dec__small_xshift shifts h's number (where 'x' +// is 'l' or 'r' for left or right) by a small shift value. +// +// Preconditions: +// - h is non-NULL. +// - h->decimal_point is "not extreme". +// - shift is non-zero. +// - shift is "a small shift". +// +// "Not extreme" means within ±WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE. +// +// "A small shift" means not more than +// WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL. +// +// wuffs_private_impl__high_prec_dec__rounded_integer and +// wuffs_private_impl__high_prec_dec__lshift_num_new_digits have the same +// preconditions. +// +// wuffs_private_impl__high_prec_dec__lshift keeps the first two preconditions +// but not the last two. Its shift argument is signed and does not need to be +// "small": zero is a no-op, positive means left shift and negative means right +// shift. - // Common formats above. Rarer formats below. +static void // +wuffs_private_impl__high_prec_dec__small_lshift( + wuffs_private_impl__high_prec_dec* h, + uint32_t shift) { + if (h->num_digits == 0) { + return; + } + uint32_t num_new_digits = + wuffs_private_impl__high_prec_dec__lshift_num_new_digits(h, shift); + uint32_t rx = h->num_digits - 1; // Read index. + uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index. + uint64_t n = 0; - case WUFFS_BASE__PIXEL_FORMAT__Y: - return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x]))); - case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: - return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1]))); - case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: - return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0]))); + // Repeat: pick up a digit, put down a digit, right to left. + while (((int32_t)rx) >= 0) { + n += ((uint64_t)(h->digits[rx])) << shift; + uint64_t quo = n / 10; + uint64_t rem = n - (10 * quo); + if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[wx] = (uint8_t)rem; + } else if (rem > 0) { + h->truncated = true; + } + n = quo; + wx--; + rx--; + } - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: { - uint8_t* palette = pb->private_impl.planes[3].ptr; - return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(palette + - (4 * ((size_t)row[x])))); + // Put down leading digits, right to left. + while (n > 0) { + uint64_t quo = n / 10; + uint64_t rem = n - (10 * quo); + if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[wx] = (uint8_t)rem; + } else if (rem > 0) { + h->truncated = true; } + n = quo; + wx--; + } - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x)))); - case WUFFS_BASE__PIXEL_FORMAT__BGR: - return 0xFF000000 | - wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x)))); - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - return 0xFF000000 | - wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))); + // Finish. + h->num_digits += num_new_digits; + if (h->num_digits > WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->num_digits = WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION; + } + h->decimal_point += (int32_t)num_new_digits; + wuffs_private_impl__high_prec_dec__trim(h); +} - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__swap_u32_argb_abgr( - 0xFF000000 | - wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)))); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - return wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(row + - (4 * ((size_t)x))))); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - return wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - return wuffs_base__swap_u32_argb_abgr( - 0xFF000000 | - wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); +static void // +wuffs_private_impl__high_prec_dec__small_rshift( + wuffs_private_impl__high_prec_dec* h, + uint32_t shift) { + uint32_t rx = 0; // Read index. + uint32_t wx = 0; // Write index. + uint64_t n = 0; - default: - // TODO: support more formats. + // Pick up enough leading digits to cover the first shift. + while ((n >> shift) == 0) { + if (rx < h->num_digits) { + // Read a digit. + n = (10 * n) + h->digits[rx++]; + } else if (n == 0) { + // h's number used to be zero and remains zero. + return; + } else { + // Read sufficient implicit trailing zeroes. + while ((n >> shift) == 0) { + n = 10 * n; + rx++; + } break; + } + } + h->decimal_point -= ((int32_t)(rx - 1)); + if (h->decimal_point < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) { + // After the shift, h's number is effectively zero. + h->num_digits = 0; + h->decimal_point = 0; + h->truncated = false; + return; } - return 0; + // Repeat: pick up a digit, put down a digit, left to right. + uint64_t mask = (((uint64_t)(1)) << shift) - 1; + while (rx < h->num_digits) { + uint8_t new_digit = ((uint8_t)(n >> shift)); + n = (10 * (n & mask)) + h->digits[rx++]; + h->digits[wx++] = new_digit; + } + + // Put down trailing digits, left to right. + while (n > 0) { + uint8_t new_digit = ((uint8_t)(n >> shift)); + n = 10 * (n & mask); + if (wx < WUFFS_PRIVATE_IMPL__HPD__DIGITS_PRECISION) { + h->digits[wx++] = new_digit; + } else if (new_digit > 0) { + h->truncated = true; + } + } + + // Finish. + h->num_digits = wx; + wuffs_private_impl__high_prec_dec__trim(h); +} + +static void // +wuffs_private_impl__high_prec_dec__lshift(wuffs_private_impl__high_prec_dec* h, + int32_t shift) { + if (shift > 0) { + while (shift > +WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) { + wuffs_private_impl__high_prec_dec__small_lshift( + h, WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL); + shift -= WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL; + } + wuffs_private_impl__high_prec_dec__small_lshift(h, ((uint32_t)(+shift))); + } else if (shift < 0) { + while (shift < -WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) { + wuffs_private_impl__high_prec_dec__small_rshift( + h, WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL); + shift += WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL; + } + wuffs_private_impl__high_prec_dec__small_rshift(h, ((uint32_t)(-shift))); + } } // -------- -WUFFS_BASE__MAYBE_STATIC wuffs_base__status // -wuffs_base__pixel_buffer__set_color_u32_at( - wuffs_base__pixel_buffer* pb, - uint32_t x, - uint32_t y, - wuffs_base__color_u32_argb_premul color) { - if (!pb) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); +// wuffs_private_impl__high_prec_dec__round_etc rounds h's number. For those +// functions that take an n argument, rounding produces at most n digits (which +// is not necessarily at most n decimal places). Negative n values are ignored, +// as well as any n greater than or equal to h's number of digits. The +// etc__round_just_enough function implicitly chooses an n to implement +// WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION. +// +// Preconditions: +// - h is non-NULL. +// - h->decimal_point is "not extreme". +// +// "Not extreme" means within ±WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE. + +static void // +wuffs_private_impl__high_prec_dec__round_down( + wuffs_private_impl__high_prec_dec* h, + int32_t n) { + if ((n < 0) || (h->num_digits <= (uint32_t)n)) { + return; } - if ((x >= pb->pixcfg.private_impl.width) || - (y >= pb->pixcfg.private_impl.height)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + h->num_digits = (uint32_t)(n); + wuffs_private_impl__high_prec_dec__trim(h); +} + +static void // +wuffs_private_impl__high_prec_dec__round_up( + wuffs_private_impl__high_prec_dec* h, + int32_t n) { + if ((n < 0) || (h->num_digits <= (uint32_t)n)) { + return; } - if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { - // TODO: support planar formats. - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + for (n--; n >= 0; n--) { + if (h->digits[n] < 9) { + h->digits[n]++; + h->num_digits = (uint32_t)(n + 1); + return; + } } - size_t stride = pb->private_impl.planes[0].stride; - uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)); + // The number is all 9s. Change to a single 1 and adjust the decimal point. + h->digits[0] = 1; + h->num_digits = 1; + h->decimal_point++; +} - switch (pb->pixcfg.private_impl.pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color); - break; +static void // +wuffs_private_impl__high_prec_dec__round_nearest( + wuffs_private_impl__high_prec_dec* h, + int32_t n) { + if ((n < 0) || (h->num_digits <= (uint32_t)n)) { + return; + } + bool up = h->digits[n] >= 5; + if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) { + up = h->truncated || // + ((n > 0) && ((h->digits[n - 1] & 1) != 0)); + } - // Common formats above. Rarer formats below. - - case WUFFS_BASE__PIXEL_FORMAT__Y: - wuffs_base__poke_u8__no_bounds_check( - row + ((size_t)x), - wuffs_base__color_u32_argb_premul__as__color_u8_gray(color)); - break; - case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: - wuffs_base__poke_u16le__no_bounds_check( - row + (2 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u16_gray(color)); - break; - case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: - wuffs_base__poke_u16be__no_bounds_check( - row + (2 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u16_gray(color)); - break; - - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: - wuffs_base__poke_u8__no_bounds_check( - row + ((size_t)x), wuffs_base__pixel_palette__closest_element( - wuffs_base__pixel_buffer__palette(pb), - pb->pixcfg.private_impl.pixfmt, color)); - break; - - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - wuffs_base__poke_u16le__no_bounds_check( - row + (2 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color)); - break; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color); - break; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - wuffs_base__poke_u32le__no_bounds_check( - row + (4 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - color)); - break; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - wuffs_base__poke_u64le__no_bounds_check( - row + (8 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul( - color)); - break; - - case WUFFS_BASE__PIXEL_FORMAT__RGB: - wuffs_base__poke_u24le__no_bounds_check( - row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color)); - break; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - wuffs_base__poke_u32le__no_bounds_check( - row + (4 * ((size_t)x)), - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - wuffs_base__swap_u32_argb_abgr(color))); - break; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - wuffs_base__poke_u32le__no_bounds_check( - row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color)); - break; - - default: - // TODO: support more formats. - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + if (up) { + wuffs_private_impl__high_prec_dec__round_up(h, n); + } else { + wuffs_private_impl__high_prec_dec__round_down(h, n); } - - return wuffs_base__make_status(NULL); } -// -------- - -static inline void // -wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx( - wuffs_base__pixel_buffer* pb, - wuffs_base__rect_ie_u32 rect, - uint16_t color) { - size_t stride = pb->private_impl.planes[0].stride; - uint32_t width = wuffs_base__rect_ie_u32__width(&rect); - if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { - uint8_t* ptr = - pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); - uint32_t height = wuffs_base__rect_ie_u32__height(&rect); - size_t n; - for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { - wuffs_base__poke_u16le__no_bounds_check(ptr, color); - ptr += 2; - } +static void // +wuffs_private_impl__high_prec_dec__round_just_enough( + wuffs_private_impl__high_prec_dec* h, + int32_t exp2, + uint64_t mantissa) { + // The magic numbers 52 and 53 in this function are because IEEE 754 double + // precision has 52 mantissa bits. + // + // Let f be the floating point number represented by exp2 and mantissa (and + // also the number in h): the number (mantissa * (2 ** (exp2 - 52))). + // + // If f is zero or a small integer, we can return early. + if ((mantissa == 0) || + ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) { return; } - uint32_t y; - for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { - uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + - (2 * ((size_t)rect.min_incl_x)); - uint32_t n; - for (n = width; n > 0; n--) { - wuffs_base__poke_u16le__no_bounds_check(ptr, color); - ptr += 2; - } - } -} + // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52). + // Subnormal numbers have the same exp2 but a smaller mantissa. + static const int32_t min_incl_normal_exp2 = -1022; + static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul; -static inline void // -wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx( - wuffs_base__pixel_buffer* pb, - wuffs_base__rect_ie_u32 rect, - uint32_t color) { - size_t stride = pb->private_impl.planes[0].stride; - uint32_t width = wuffs_base__rect_ie_u32__width(&rect); - if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { - uint8_t* ptr = - pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); - uint32_t height = wuffs_base__rect_ie_u32__height(&rect); - size_t n; - for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { - wuffs_base__poke_u24le__no_bounds_check(ptr, color); - ptr += 3; - } - return; + // Compute lower and upper bounds such that any number between them (possibly + // inclusive) will round to f. First, the lower bound. Our number f is: + // ((mantissa + 0) * (2 ** ( exp2 - 52))) + // + // The next lowest floating point number is: + // ((mantissa - 1) * (2 ** ( exp2 - 52))) + // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the + // min_incl_normal_exp2. Either way, call it: + // ((l_mantissa) * (2 ** (l_exp2 - 52))) + // + // The lower bound is halfway between them (noting that 52 became 53): + // (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53))) + int32_t l_exp2 = exp2; + uint64_t l_mantissa = mantissa - 1; + if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) { + l_exp2 = exp2 - 1; + l_mantissa = (2 * mantissa) - 1; } + wuffs_private_impl__high_prec_dec lower; + wuffs_private_impl__high_prec_dec__assign(&lower, (2 * l_mantissa) + 1, + false); + wuffs_private_impl__high_prec_dec__lshift(&lower, l_exp2 - 53); - uint32_t y; - for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { - uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + - (3 * ((size_t)rect.min_incl_x)); - uint32_t n; - for (n = width; n > 0; n--) { - wuffs_base__poke_u24le__no_bounds_check(ptr, color); - ptr += 3; - } - } -} + // Next, the upper bound. Our number f is: + // ((mantissa + 0) * (2 ** (exp2 - 52))) + // + // The next highest floating point number is: + // ((mantissa + 1) * (2 ** (exp2 - 52))) + // + // The upper bound is halfway between them (noting that 52 became 53): + // (((2 * mantissa) + 1) * (2 ** (exp2 - 53))) + wuffs_private_impl__high_prec_dec upper; + wuffs_private_impl__high_prec_dec__assign(&upper, (2 * mantissa) + 1, false); + wuffs_private_impl__high_prec_dec__lshift(&upper, exp2 - 53); -static inline void // -wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx( - wuffs_base__pixel_buffer* pb, - wuffs_base__rect_ie_u32 rect, - uint32_t color) { - size_t stride = pb->private_impl.planes[0].stride; - uint32_t width = wuffs_base__rect_ie_u32__width(&rect); - if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { - uint8_t* ptr = - pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); - uint32_t height = wuffs_base__rect_ie_u32__height(&rect); - size_t n; - for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { - wuffs_base__poke_u32le__no_bounds_check(ptr, color); - ptr += 4; - } - return; - } + // The lower and upper bounds are possible outputs only if the original + // mantissa is even, so that IEEE round-to-even would round to the original + // mantissa and not its neighbors. + bool inclusive = (mantissa & 1) == 0; - uint32_t y; - for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { - uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + - (4 * ((size_t)rect.min_incl_x)); - uint32_t n; - for (n = width; n > 0; n--) { - wuffs_base__poke_u32le__no_bounds_check(ptr, color); - ptr += 4; - } - } -} + // As we walk the digits, we want to know whether rounding up would fall + // within the upper bound. This is tracked by upper_delta: + // - When -1, the digits of h and upper are the same so far. + // - When +0, we saw a difference of 1 between h and upper on a previous + // digit and subsequently only 9s for h and 0s for upper. Thus, rounding + // up may fall outside of the bound if !inclusive. + // - When +1, the difference is greater than 1 and we know that rounding up + // falls within the bound. + // + // This is a state machine with three states. The numerical value for each + // state (-1, +0 or +1) isn't important, other than their order. + int upper_delta = -1; -static inline void // -wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx( - wuffs_base__pixel_buffer* pb, - wuffs_base__rect_ie_u32 rect, - uint64_t color) { - size_t stride = pb->private_impl.planes[0].stride; - uint32_t width = wuffs_base__rect_ie_u32__width(&rect); - if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { - uint8_t* ptr = - pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); - uint32_t height = wuffs_base__rect_ie_u32__height(&rect); - size_t n; - for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { - wuffs_base__poke_u64le__no_bounds_check(ptr, color); - ptr += 8; + // We can now figure out the shortest number of digits required. Walk the + // digits until h has distinguished itself from lower or upper. + // + // The zi and zd variables are indexes and digits, for z in l (lower), h (the + // number) and u (upper). + // + // The lower, h and upper numbers may have their decimal points at different + // places. In this case, upper is the longest, so we iterate ui starting from + // 0 and iterate li and hi starting from either 0 or -1. + int32_t ui = 0; + for (;; ui++) { + // Calculate hd, the middle number's digit. + int32_t hi = ui - upper.decimal_point + h->decimal_point; + if (hi >= ((int32_t)(h->num_digits))) { + break; } - return; - } + uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0; - uint32_t y; - for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { - uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + - (8 * ((size_t)rect.min_incl_x)); - uint32_t n; - for (n = width; n > 0; n--) { - wuffs_base__poke_u64le__no_bounds_check(ptr, color); - ptr += 8; + // Calculate ld, the lower bound's digit. + int32_t li = ui - upper.decimal_point + lower.decimal_point; + uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0; + + // We can round down (truncate) if lower has a different digit than h or if + // lower is inclusive and is exactly the result of rounding down (i.e. we + // have reached the final digit of lower). + bool can_round_down = + (ld != hd) || // + (inclusive && ((li + 1) == ((int32_t)(lower.num_digits)))); + + // Calculate ud, the upper bound's digit, and update upper_delta. + uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0; + if (upper_delta < 0) { + if ((hd + 1) < ud) { + // For example: + // h = 12345??? + // upper = 12347??? + upper_delta = +1; + } else if (hd != ud) { + // For example: + // h = 12345??? + // upper = 12346??? + upper_delta = +0; + } + } else if (upper_delta == 0) { + if ((hd != 9) || (ud != 0)) { + // For example: + // h = 1234598? + // upper = 1234600? + upper_delta = +1; + } } - } -} -WUFFS_BASE__MAYBE_STATIC wuffs_base__status // -wuffs_base__pixel_buffer__set_color_u32_fill_rect( - wuffs_base__pixel_buffer* pb, - wuffs_base__rect_ie_u32 rect, - wuffs_base__color_u32_argb_premul color) { - if (!pb) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) { - return wuffs_base__make_status(NULL); - } - wuffs_base__rect_ie_u32 bounds = - wuffs_base__pixel_config__bounds(&pb->pixcfg); - if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } + // We can round up if upper has a different digit than h and either upper + // is inclusive or upper is bigger than the result of rounding up. + bool can_round_up = + (upper_delta > 0) || // + ((upper_delta == 0) && // + (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits))))); - if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { - // TODO: support planar formats. - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + // If we can round either way, round to nearest. If we can round only one + // way, do it. If we can't round, continue the loop. + if (can_round_down) { + if (can_round_up) { + wuffs_private_impl__high_prec_dec__round_nearest(h, hi + 1); + return; + } else { + wuffs_private_impl__high_prec_dec__round_down(h, hi + 1); + return; + } + } else { + if (can_round_up) { + wuffs_private_impl__high_prec_dec__round_up(h, hi + 1); + return; + } + } } +} - switch (pb->pixcfg.private_impl.pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color); - return wuffs_base__make_status(NULL); - - // Common formats above. Rarer formats below. +// -------- - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx( - pb, rect, - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color)); - return wuffs_base__make_status(NULL); +// wuffs_private_impl__parse_number_f64_eisel_lemire produces the IEEE 754 +// double-precision value for an exact mantissa and base-10 exponent. For +// example: +// - when parsing "12345.678e+02", man is 12345678 and exp10 is -1. +// - when parsing "-12", man is 12 and exp10 is 0. Processing the leading +// minus sign is the responsibility of the caller, not this function. +// +// On success, it returns a non-negative int64_t such that the low 63 bits hold +// the 11-bit exponent and 52-bit mantissa. +// +// On failure, it returns a negative value. +// +// The algorithm is based on an original idea by Michael Eisel that was refined +// by Daniel Lemire. See +// https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/ +// and +// https://nigeltao.github.io/blog/2020/eisel-lemire.html +// +// Preconditions: +// - man is non-zero. +// - exp10 is in the range [-307 ..= 288], the same range of the +// wuffs_private_impl__powers_of_10 array. +// +// The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX], +// approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the +// range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal +// (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are +// approximately 2.23e–308 and 1.80e+308. +static int64_t // +wuffs_private_impl__parse_number_f64_eisel_lemire(uint64_t man, int32_t exp10) { + // Look up the (possibly truncated) base-2 representation of (10 ** exp10). + // The look-up table was constructed so that it is already normalized: the + // table entry's mantissa's MSB (most significant bit) is on. + const uint64_t* po10 = &wuffs_private_impl__powers_of_10[exp10 + 307][0]; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color); - return wuffs_base__make_status(NULL); + // Normalize the man argument. The (man != 0) precondition means that a + // non-zero bit exists. + uint32_t clz = wuffs_base__count_leading_zeroes_u64(man); + man <<= clz; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx( - pb, rect, - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - color)); - return wuffs_base__make_status(NULL); + // Calculate the return value's base-2 exponent. We might tweak it by ±1 + // later, but its initial value comes from a linear scaling of exp10, + // converting from power-of-10 to power-of-2, and adjusting by clz. + // + // The magic constants are: + // - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because + // the look-up table uses 64-bit mantissas. + // - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough + // (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928. + // - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift. + // + // Equality of the linearly-scaled value and the actual power-of-2, over the + // range of exp10 arguments that this function accepts, is confirmed by + // script/print-mpb-powers-of-10.go + uint64_t ret_exp2 = + ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx( - pb, rect, - wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul( - color)); - return wuffs_base__make_status(NULL); + // Multiply the two mantissas. Normalization means that both mantissas are at + // least (1<<63), so the 128-bit product must be at least (1<<126). The high + // 64 bits of the product, x_hi, must therefore be at least (1<<62). + // + // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi + // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore + // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. + wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]); + uint64_t x_hi = x.hi; + uint64_t x_lo = x.lo; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx( - pb, rect, - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - wuffs_base__swap_u32_argb_abgr(color))); - return wuffs_base__make_status(NULL); + // Before we shift right by at least 9 bits, recall that the look-up table + // entry was possibly truncated. We have so far only calculated a lower bound + // for the product (man * e), where e is (10 ** exp10). The upper bound would + // add a further (man * 1) to the 128-bit product, which overflows the lower + // 64-bit limb if ((x_lo + man) < man). + // + // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right + // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit + // limb's low 9 bits are all on. + // + // For example, parsing "9999999999999999999" will take the if-true branch + // here, since: + // - x_hi = 0x4563918244F3FFFF + // - x_lo = 0x8000000000000000 + // - man = 0x8AC7230489E7FFFF + if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) { + // Refine our calculation of (man * e). Before, our approximation of e used + // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit + // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e). + // Now calculate y = (man * bits_64_to_127_incl_of_e). + wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]); + uint64_t y_hi = y.hi; + uint64_t y_lo = y.lo; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx( - pb, rect, wuffs_base__swap_u32_argb_abgr(color)); - return wuffs_base__make_status(NULL); - } + // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to + // calculate the 192-bit product of the 64-bit man by the 128-bit e. + // As we exit this if-block, we only care about the high 128 bits + // (merged_hi and merged_lo) of that 192-bit product. + // + // For example, parsing "1.234e-45" will take the if-true branch here, + // since: + // - x_hi = 0x70B7E3696DB29FFF + // - x_lo = 0xE040000000000000 + // - y_hi = 0x33718BBEAB0E0D7A + // - y_lo = 0xA880000000000000 + uint64_t merged_hi = x_hi; + uint64_t merged_lo = x_lo + y_hi; + if (merged_lo < x_lo) { + merged_hi++; // Carry the overflow bit. + } - uint32_t y; - for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { - uint32_t x; - for (x = rect.min_incl_x; x < rect.max_excl_x; x++) { - wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color); + // The "high resolution" approximation of e is still a lower bound. Once + // again, see if the upper bound is large enough to produce a different + // result. This time, if it does, give up instead of reaching for an even + // more precise approximation to e. + // + // This three-part check is similar to the two-part check that guarded the + // if block that we're now in, but it has an extra term for the middle 64 + // bits (checking that adding 1 to merged_lo would overflow). + // + // For example, parsing "5.9604644775390625e-8" will take the if-true + // branch here, since: + // - merged_hi = 0x7FFFFFFFFFFFFFFF + // - merged_lo = 0xFFFFFFFFFFFFFFFF + // - y_lo = 0x4DB3FFC120988200 + // - man = 0xD3C21BCECCEDA100 + if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) && + (y_lo + man < man)) { + return -1; } + + // Replace the 128-bit x with merged. + x_hi = merged_hi; + x_lo = merged_lo; } - return wuffs_base__make_status(NULL); -} -// -------- + // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave + // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the + // MSB (before shifting) was on, adjust ret_exp2 for the larger shift. + // + // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit + // number. + uint64_t msb = x_hi >> 63; + uint64_t ret_mantissa = x_hi >> (msb + 9); + ret_exp2 -= 1 ^ msb; -WUFFS_BASE__MAYBE_STATIC uint8_t // -wuffs_base__pixel_palette__closest_element( - wuffs_base__slice_u8 palette_slice, - wuffs_base__pixel_format palette_format, - wuffs_base__color_u32_argb_premul c) { - size_t n = palette_slice.len / 4; - if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4); + // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can + // be tricky. If we're half-way between two exactly representable numbers + // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give + // up instead of trying to pick the winner. + // + // Technically, we could tighten the condition by changing "73" to "73 or 74, + // depending on msb", but a flat "73" is simpler. + // + // For example, parsing "1e+23" will take the if-true branch here, since: + // - x_hi = 0x54B40B1F852BDA00 + // - ret_mantissa = 0x002A5A058FC295ED + if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) { + return -1; } - size_t best_index = 0; - uint64_t best_score = 0xFFFFFFFFFFFFFFFF; - // Work in 16-bit color. - uint32_t ca = 0x101 * (0xFF & (c >> 24)); - uint32_t cr = 0x101 * (0xFF & (c >> 16)); - uint32_t cg = 0x101 * (0xFF & (c >> 8)); - uint32_t cb = 0x101 * (0xFF & (c >> 0)); - - switch (palette_format.repr) { - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: { - bool nonpremul = palette_format.repr == - WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL; - - size_t i; - for (i = 0; i < n; i++) { - // Work in 16-bit color. - uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0])); - uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1])); - uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2])); - uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3])); - - // Convert to premultiplied alpha. - if (nonpremul && (pa != 0xFFFF)) { - pb = (pb * pa) / 0xFFFF; - pg = (pg * pa) / 0xFFFF; - pr = (pr * pa) / 0xFFFF; - } - - // These deltas are conceptually int32_t (signed) but after squaring, - // it's equivalent to work in uint32_t (unsigned). - pb -= cb; - pg -= cg; - pr -= cr; - pa -= ca; - uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) + - ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa)); - if (best_score > score) { - best_score = score; - best_index = i; - } - } - break; - } + // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit + // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether + // it was on or off, shifting right by one then produces a 53-bit number. If + // carrying up overflowed, shift again. + ret_mantissa += ret_mantissa & 1; + ret_mantissa >>= 1; + // This if block is equivalent to (but benchmarks slightly faster than) the + // following branchless form: + // uint64_t overflow_adjustment = ret_mantissa >> 53; + // ret_mantissa >>= overflow_adjustment; + // ret_exp2 += overflow_adjustment; + // + // For example, parsing "7.2057594037927933e+16" will take the if-true + // branch here, since: + // - x_hi = 0x7FFFFFFFFFFFFE80 + // - ret_mantissa = 0x0020000000000000 + if ((ret_mantissa >> 53) > 0) { + ret_mantissa >>= 1; + ret_exp2++; } - return (uint8_t)best_index; + // Starting with a 53-bit number, IEEE 754 double-precision normal numbers + // have an implicit mantissa bit. Mask that away and keep the low 52 bits. + ret_mantissa &= 0x000FFFFFFFFFFFFF; + + // Pack the bits and return. + return ((int64_t)(ret_mantissa | (ret_exp2 << 52))); } // -------- -static inline uint32_t // -wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul, - uint32_t src_nonpremul) { - // Extract 16-bit color components. - // - // If the destination is transparent then SRC_OVER is equivalent to SRC: just - // return src_nonpremul. This isn't just an optimization (skipping the rest - // of the function's computation). It also preserves the nonpremul - // distinction between e.g. transparent red and transparent blue that would - // otherwise be lost by converting from nonpremul to premul and back. - uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24)); - if (da == 0) { - return src_nonpremul; - } - uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16)); - uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8)); - uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0)); - uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24)); - uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16)); - uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8)); - uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0)); - - // Convert dst from nonpremul to premul. - dr = (dr * da) / 0xFFFF; - dg = (dg * da) / 0xFFFF; - db = (db * da) / 0xFFFF; +static wuffs_base__result_f64 // +wuffs_private_impl__parse_number_f64_special(wuffs_base__slice_u8 s, + uint32_t options) { + do { + if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) { + goto fail; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + uint8_t* p = s.ptr; + uint8_t* q = s.ptr + s.len; - // Composite src (nonpremul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + for (; (p < q) && (*p == '_'); p++) { + } + if (p >= q) { + goto fail; + } - // Convert dst from premul to nonpremul. - if (da != 0) { - dr = (dr * 0xFFFF) / da; - dg = (dg * 0xFFFF) / da; - db = (db * 0xFFFF) / da; - } + // Parse sign. + bool negative = false; + do { + if (*p == '+') { + p++; + } else if (*p == '-') { + negative = true; + p++; + } else { + break; + } + for (; (p < q) && (*p == '_'); p++) { + } + } while (0); + if (p >= q) { + goto fail; + } - // Convert from 16-bit color to 8-bit color. - da >>= 8; - dr >>= 8; - dg >>= 8; - db >>= 8; + bool nan = false; + switch (p[0]) { + case 'I': + case 'i': + if (((q - p) < 3) || // + ((p[1] != 'N') && (p[1] != 'n')) || // + ((p[2] != 'F') && (p[2] != 'f'))) { + goto fail; + } + p += 3; - // Combine components. - return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); -} + if ((p >= q) || (*p == '_')) { + break; + } else if (((q - p) < 5) || // + ((p[0] != 'I') && (p[0] != 'i')) || // + ((p[1] != 'N') && (p[1] != 'n')) || // + ((p[2] != 'I') && (p[2] != 'i')) || // + ((p[3] != 'T') && (p[3] != 't')) || // + ((p[4] != 'Y') && (p[4] != 'y'))) { + goto fail; + } + p += 5; -static inline uint64_t // -wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul, - uint64_t src_nonpremul) { - // Extract components. - // - // If the destination is transparent then SRC_OVER is equivalent to SRC: just - // return src_nonpremul. This isn't just an optimization (skipping the rest - // of the function's computation). It also preserves the nonpremul - // distinction between e.g. transparent red and transparent blue that would - // otherwise be lost by converting from nonpremul to premul and back. - uint64_t da = 0xFFFF & (dst_nonpremul >> 48); - if (da == 0) { - return src_nonpremul; - } - uint64_t dr = 0xFFFF & (dst_nonpremul >> 32); - uint64_t dg = 0xFFFF & (dst_nonpremul >> 16); - uint64_t db = 0xFFFF & (dst_nonpremul >> 0); - uint64_t sa = 0xFFFF & (src_nonpremul >> 48); - uint64_t sr = 0xFFFF & (src_nonpremul >> 32); - uint64_t sg = 0xFFFF & (src_nonpremul >> 16); - uint64_t sb = 0xFFFF & (src_nonpremul >> 0); + if ((p >= q) || (*p == '_')) { + break; + } + goto fail; - // Convert dst from nonpremul to premul. - dr = (dr * da) / 0xFFFF; - dg = (dg * da) / 0xFFFF; - db = (db * da) / 0xFFFF; + case 'N': + case 'n': + if (((q - p) < 3) || // + ((p[1] != 'A') && (p[1] != 'a')) || // + ((p[2] != 'N') && (p[2] != 'n'))) { + goto fail; + } + p += 3; - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint64_t ia = 0xFFFF - sa; + if ((p >= q) || (*p == '_')) { + nan = true; + break; + } + goto fail; - // Composite src (nonpremul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + default: + goto fail; + } - // Convert dst from premul to nonpremul. - if (da != 0) { - dr = (dr * 0xFFFF) / da; - dg = (dg * 0xFFFF) / da; - db = (db * 0xFFFF) / da; - } + // Finish. + for (; (p < q) && (*p == '_'); p++) { + } + if (p != q) { + goto fail; + } + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( + (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) | + (negative ? 0x8000000000000000 : 0)); + return ret; + } while (0); - // Combine components. - return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); +fail: + do { + wuffs_base__result_f64 ret; + ret.status.repr = wuffs_base__error__bad_argument; + ret.value = 0; + return ret; + } while (0); } -static inline uint32_t // -wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul, - uint32_t src_premul) { - // Extract 16-bit color components. - uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24)); - uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16)); - uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8)); - uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0)); - uint32_t sa = 0x101 * (0xFF & (src_premul >> 24)); - uint32_t sr = 0x101 * (0xFF & (src_premul >> 16)); - uint32_t sg = 0x101 * (0xFF & (src_premul >> 8)); - uint32_t sb = 0x101 * (0xFF & (src_premul >> 0)); +WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 // +wuffs_private_impl__high_prec_dec__to_f64(wuffs_private_impl__high_prec_dec* h, + uint32_t options) { + do { + // powers converts decimal powers of 10 to binary powers of 2. For example, + // (10000 >> 13) is 1. It stops before the elements exceed 60, also known + // as WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL. + // + // This rounds down (1<<13 is a lower bound for 1e4). Adding 1 to the array + // element value rounds up (1<<14 is an upper bound for 1e4) while staying + // at or below WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL. + // + // When starting in the range [1e+1 .. 1e+2] (i.e. h->decimal_point == +2), + // powers[2] == 6 and so: + // - Right shifting by 6+0 produces the range [10/64 .. 100/64] = + // [0.156250 .. 1.56250]. The resultant h->decimal_point is +0 or +1. + // - Right shifting by 6+1 produces the range [10/128 .. 100/128] = + // [0.078125 .. 0.78125]. The resultant h->decimal_point is -1 or -0. + // + // When starting in the range [1e-3 .. 1e-2] (i.e. h->decimal_point == -2), + // powers[2] == 6 and so: + // - Left shifting by 6+0 produces the range [0.001*64 .. 0.01*64] = + // [0.064 .. 0.64]. The resultant h->decimal_point is -1 or -0. + // - Left shifting by 6+1 produces the range [0.001*128 .. 0.01*128] = + // [0.128 .. 1.28]. The resultant h->decimal_point is +0 or +1. + // + // Thus, when targeting h->decimal_point being +0 or +1, use (powers[n]+0) + // when right shifting but (powers[n]+1) when left shifting. + static const uint32_t num_powers = 19; + static const uint8_t powers[19] = { + 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, // + 33, 36, 39, 43, 46, 49, 53, 56, 59, // + }; - // Convert dst from nonpremul to premul. - dr = (dr * da) / 0xFFFF; - dg = (dg * da) / 0xFFFF; - db = (db * da) / 0xFFFF; + // Handle zero and obvious extremes. The largest and smallest positive + // finite f64 values are approximately 1.8e+308 and 4.9e-324. + if ((h->num_digits == 0) || (h->decimal_point < -326)) { + goto zero; + } else if (h->decimal_point > 310) { + goto infinity; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10) + // pair from the high_prec_dec h is more correct but slower than the + // approach taken in wuffs_base__parse_number_f64. The latter is optimized + // for the common cases (e.g. assuming no underscores or a leading '+' + // sign) rather than the full set of cases allowed by the Wuffs API. + // + // When we have 19 or fewer mantissa digits, run Eisel-Lemire once (trying + // for an exact result). When we have more than 19 mantissa digits, run it + // twice to get a lower and upper bound. We still have an exact result + // (within f64's rounding margin) if both bounds are equal (and valid). + uint32_t i_max = h->num_digits; + if (i_max > 19) { + i_max = 19; + } + int32_t exp10 = h->decimal_point - ((int32_t)i_max); + if ((-307 <= exp10) && (exp10 <= 288)) { + uint64_t man = 0; + uint32_t i; + for (i = 0; i < i_max; i++) { + man = (10 * man) + h->digits[i]; + } + while (man != 0) { // The 'while' is just an 'if' that we can 'break'. + int64_t r0 = + wuffs_private_impl__parse_number_f64_eisel_lemire(man + 0, exp10); + if (r0 < 0) { + break; + } else if (h->num_digits > 19) { + int64_t r1 = + wuffs_private_impl__parse_number_f64_eisel_lemire(man + 1, exp10); + if (r1 != r0) { + break; + } + } + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( + ((uint64_t)r0) | (((uint64_t)(h->negative)) << 63)); + return ret; + } + } - // Composite src (premul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); + // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See + // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html + // + // Scale by powers of 2 until we're in the range [0.1 .. 10]. Equivalently, + // that h->decimal_point is +0 or +1. + // + // First we shift right while at or above 10... + const int32_t f64_bias = -1023; + int32_t exp2 = 0; + while (h->decimal_point > 1) { + uint32_t n = (uint32_t)(+h->decimal_point); + uint32_t shift = (n < num_powers) + ? powers[n] + : WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL; - // Convert dst from premul to nonpremul. - if (da != 0) { - dr = (dr * 0xFFFF) / da; - dg = (dg * 0xFFFF) / da; - db = (db * 0xFFFF) / da; - } + wuffs_private_impl__high_prec_dec__small_rshift(h, shift); + if (h->decimal_point < -WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) { + goto zero; + } + exp2 += (int32_t)shift; + } + // ...then we shift left while below 0.1. + while (h->decimal_point < 0) { + uint32_t shift; + uint32_t n = (uint32_t)(-h->decimal_point); + shift = (n < num_powers) + // The +1 is per "when targeting h->decimal_point being +0 or + // +1... when left shifting" in the powers comment above. + ? (powers[n] + 1u) + : WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL; - // Convert from 16-bit color to 8-bit color. - da >>= 8; - dr >>= 8; - dg >>= 8; - db >>= 8; + wuffs_private_impl__high_prec_dec__small_lshift(h, shift); + if (h->decimal_point > +WUFFS_PRIVATE_IMPL__HPD__DECIMAL_POINT__RANGE) { + goto infinity; + } + exp2 -= (int32_t)shift; + } - // Combine components. - return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); -} + // To get from "in the range [0.1 .. 10]" to "in the range [1 .. 2]" (which + // will give us our exponent in base-2), the mantissa's first 3 digits will + // determine the final left shift, equal to 52 (the number of explicit f64 + // bits) plus an additional adjustment. + int man3 = (100 * h->digits[0]) + + ((h->num_digits > 1) ? (10 * h->digits[1]) : 0) + + ((h->num_digits > 2) ? h->digits[2] : 0); + int32_t additional_lshift = 0; + if (h->decimal_point == 0) { // The value is in [0.1 .. 1]. + if (man3 < 125) { + additional_lshift = +4; + } else if (man3 < 250) { + additional_lshift = +3; + } else if (man3 < 500) { + additional_lshift = +2; + } else { + additional_lshift = +1; + } + } else { // The value is in [1 .. 10]. + if (man3 < 200) { + additional_lshift = -0; + } else if (man3 < 400) { + additional_lshift = -1; + } else if (man3 < 800) { + additional_lshift = -2; + } else { + additional_lshift = -3; + } + } + exp2 -= additional_lshift; + uint32_t final_lshift = (uint32_t)(52 + additional_lshift); -static inline uint64_t // -wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul, - uint64_t src_premul) { - // Extract components. - uint64_t da = 0xFFFF & (dst_nonpremul >> 48); - uint64_t dr = 0xFFFF & (dst_nonpremul >> 32); - uint64_t dg = 0xFFFF & (dst_nonpremul >> 16); - uint64_t db = 0xFFFF & (dst_nonpremul >> 0); - uint64_t sa = 0xFFFF & (src_premul >> 48); - uint64_t sr = 0xFFFF & (src_premul >> 32); - uint64_t sg = 0xFFFF & (src_premul >> 16); - uint64_t sb = 0xFFFF & (src_premul >> 0); + // The minimum normal exponent is (f64_bias + 1). + while ((f64_bias + 1) > exp2) { + uint32_t n = (uint32_t)((f64_bias + 1) - exp2); + if (n > WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL) { + n = WUFFS_PRIVATE_IMPL__HPD__SHIFT__MAX_INCL; + } + wuffs_private_impl__high_prec_dec__small_rshift(h, n); + exp2 += (int32_t)n; + } - // Convert dst from nonpremul to premul. - dr = (dr * da) / 0xFFFF; - dg = (dg * da) / 0xFFFF; - db = (db * da) / 0xFFFF; + // Check for overflow. + if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1. + goto infinity; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint64_t ia = 0xFFFF - sa; + // Extract 53 bits for the mantissa (in base-2). + wuffs_private_impl__high_prec_dec__small_lshift(h, final_lshift); + uint64_t man2 = wuffs_private_impl__high_prec_dec__rounded_integer(h); - // Composite src (premul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); + // Rounding might have added one bit. If so, shift and re-check overflow. + if ((man2 >> 53) != 0) { + man2 >>= 1; + exp2++; + if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1. + goto infinity; + } + } - // Convert dst from premul to nonpremul. - if (da != 0) { - dr = (dr * 0xFFFF) / da; - dg = (dg * 0xFFFF) / da; - db = (db * 0xFFFF) / da; - } + // Handle subnormal numbers. + if ((man2 >> 52) == 0) { + exp2 = f64_bias; + } - // Combine components. - return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); -} + // Pack the bits and return. + uint64_t exp2_bits = + (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1. + uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1. + (exp2_bits << 52) | // + (h->negative ? 0x8000000000000000 : 0); // (1 << 63). -static inline uint32_t // -wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul, - uint32_t src_nonpremul) { - // Extract 16-bit color components. - uint32_t da = 0x101 * (0xFF & (dst_premul >> 24)); - uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16)); - uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8)); - uint32_t db = 0x101 * (0xFF & (dst_premul >> 0)); - uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24)); - uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16)); - uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8)); - uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0)); + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); + return ret; + } while (0); - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; +zero: + do { + uint64_t bits = h->negative ? 0x8000000000000000 : 0; - // Composite src (nonpremul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); + return ret; + } while (0); - // Convert from 16-bit color to 8-bit color. - da >>= 8; - dr >>= 8; - dg >>= 8; - db >>= 8; +infinity: + do { + if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) { + wuffs_base__result_f64 ret; + ret.status.repr = wuffs_base__error__bad_argument; + ret.value = 0; + return ret; + } - // Combine components. - return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); -} + uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000; -static inline uint64_t // -wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul, - uint64_t src_nonpremul) { - // Extract components. - uint64_t da = 0xFFFF & (dst_premul >> 48); - uint64_t dr = 0xFFFF & (dst_premul >> 32); - uint64_t dg = 0xFFFF & (dst_premul >> 16); - uint64_t db = 0xFFFF & (dst_premul >> 0); - uint64_t sa = 0xFFFF & (src_nonpremul >> 48); - uint64_t sr = 0xFFFF & (src_nonpremul >> 32); - uint64_t sg = 0xFFFF & (src_nonpremul >> 16); - uint64_t sb = 0xFFFF & (src_nonpremul >> 0); - - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint64_t ia = 0xFFFF - sa; - - // Composite src (nonpremul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; - - // Combine components. - return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits); + return ret; + } while (0); } -static inline uint32_t // -wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul, - uint32_t src_premul) { - // Extract 16-bit color components. - uint32_t da = 0x101 * (0xFF & (dst_premul >> 24)); - uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16)); - uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8)); - uint32_t db = 0x101 * (0xFF & (dst_premul >> 0)); - uint32_t sa = 0x101 * (0xFF & (src_premul >> 24)); - uint32_t sr = 0x101 * (0xFF & (src_premul >> 16)); - uint32_t sg = 0x101 * (0xFF & (src_premul >> 8)); - uint32_t sb = 0x101 * (0xFF & (src_premul >> 0)); - - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; - - // Composite src (premul) over dst (premul). - da = sa + ((da * ia) / 0xFFFF); - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); - - // Convert from 16-bit color to 8-bit color. - da >>= 8; - dr >>= 8; - dg >>= 8; - db >>= 8; - - // Combine components. - return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); +static inline bool // +wuffs_private_impl__is_decimal_digit(uint8_t c) { + return ('0' <= c) && (c <= '9'); } -// -------- +WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 // +wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) { + // In practice, almost all "dd.ddddE±xxx" numbers can be represented + // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10 + // exponent, adjusting "xxx" for the position (if present) of the decimal + // separator '.' or ','. + // + // This (u64 man, i32 exp10) data structure is superficially similar to the + // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent + // here is base-10, not base-2. + // + // If s's number fits in a (man, exp10), parse that pair with the + // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with + // the fallback algorithm is slower but comprehensive. + // + // † "Printing Floating-Point Numbers Quickly and Accurately with Integers" + // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf). + // Florian Loitsch is also the primary contributor to + // https://github.com/google/double-conversion + do { + // Calculating that (man, exp10) pair needs to stay within s's bounds. + // Provided that s isn't extremely long, work on a NUL-terminated copy of + // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx". + // + // As the pointer p walks the contents, it's faster to repeatedly check "is + // *p a valid digit" than "is p within bounds and *p a valid digit". + if (s.len >= 256) { + goto fallback; + } + uint8_t z[256]; + memcpy(&z[0], s.ptr, s.len); + z[s.len] = 0; + const uint8_t* p = &z[0]; -static uint64_t // -wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr, - size_t dst_len, - const uint8_t* src_ptr, - size_t src_len, - bool nonpremul) { - size_t len = (dst_len < src_len ? dst_len : src_len) / 4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; + // Look for a leading minus sign. Technically, we could also look for an + // optional plus sign, but the "script/process-json-numbers.c with -p" + // benchmark is noticably slower if we do. It's optional and, in practice, + // usually absent. Let the fallback catch it. + bool negative = (*p == '-'); + if (negative) { + p++; + } - size_t n = len; - while (n--) { - uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s); - if (nonpremul) { - argb = - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb); + // After walking "dd.dddd", comparing p later with p now will produce the + // number of "d"s and "."s. + const uint8_t* const start_of_digits_ptr = p; + + // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0', + // it must be a single '0'. If it starts with a non-zero decimal digit, it + // can be a sequence of decimal digits. + // + // Update the man variable during the walk. It's OK if man overflows now. + // We'll detect that later. + uint64_t man; + if (*p == '0') { + man = 0; + p++; + if (wuffs_private_impl__is_decimal_digit(*p)) { + goto fallback; + } + } else if (wuffs_private_impl__is_decimal_digit(*p)) { + man = ((uint8_t)(*p - '0')); + p++; + for (; wuffs_private_impl__is_decimal_digit(*p); p++) { + man = (10 * man) + ((uint8_t)(*p - '0')); + } + } else { + goto fallback; } - uint32_t b5 = 0x1F & (argb >> (8 - 5)); - uint32_t g6 = 0x3F & (argb >> (16 - 6)); - uint32_t r5 = 0x1F & (argb >> (24 - 5)); - uint32_t alpha = argb & 0xFF000000; - wuffs_base__poke_u32le__no_bounds_check( - d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0)); - s += 4; - d += 4; - } - return len; -} -// -------- + // Walk the "d"s after the optional decimal separator ('.' or ','), + // updating the man and exp10 variables. + int32_t exp10 = 0; + if (*p == + ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.')) { + p++; + const uint8_t* first_after_separator_ptr = p; + if (!wuffs_private_impl__is_decimal_digit(*p)) { + goto fallback; + } + man = (10 * man) + ((uint8_t)(*p - '0')); + p++; + for (; wuffs_private_impl__is_decimal_digit(*p); p++) { + man = (10 * man) + ((uint8_t)(*p - '0')); + } + exp10 = ((int32_t)(first_after_separator_ptr - p)); + } -static uint64_t // -wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t len = (dst_len < src_len ? dst_len : src_len) / 3; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; + // Count the number of digits: + // - for an input of "314159", digit_count is 6. + // - for an input of "3.14159", digit_count is 7. + // + // This is off-by-one if there is a decimal separator. That's OK for now. + // We'll correct for that later. The "script/process-json-numbers.c with + // -p" benchmark is noticably slower if we try to correct for that now. + uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr); - size_t n = len; - while (n--) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s2; - d[1] = s1; - d[2] = s0; - s += 3; - d += 3; - } - return len; -} + // Update exp10 for the optional exponent, starting with 'E' or 'e'. + if ((*p | 0x20) == 'e') { + p++; + int32_t exp_sign = +1; + if (*p == '-') { + p++; + exp_sign = -1; + } else if (*p == '+') { + p++; + } + if (!wuffs_private_impl__is_decimal_digit(*p)) { + goto fallback; + } + int32_t exp_num = ((uint8_t)(*p - '0')); + p++; + // The rest of the exp_num walking has a peculiar control flow but, once + // again, the "script/process-json-numbers.c with -p" benchmark is + // sensitive to alternative formulations. + if (wuffs_private_impl__is_decimal_digit(*p)) { + exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); + p++; + } + if (wuffs_private_impl__is_decimal_digit(*p)) { + exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); + p++; + } + while (wuffs_private_impl__is_decimal_digit(*p)) { + if (exp_num > 0x1000000) { + goto fallback; + } + exp_num = (10 * exp_num) + ((uint8_t)(*p - '0')); + p++; + } + exp10 += exp_sign * exp_num; + } -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -static uint64_t // -wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t len = (dst_len < src_len ? dst_len : src_len) / 4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // The Wuffs API is that the original slice has no trailing data. It also + // allows underscores, which we don't catch here but the fallback should. + if (p != &z[s.len]) { + goto fallback; + } - __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E, // - +0x0B, +0x08, +0x09, +0x0A, // - +0x07, +0x04, +0x05, +0x06, // - +0x03, +0x00, +0x01, +0x02); + // Check that the uint64_t typed man variable has not overflowed, based on + // digit_count. + // + // For reference: + // - (1 << 63) is 9223372036854775808, which has 19 decimal digits. + // - (1 << 64) is 18446744073709551616, which has 20 decimal digits. + // - 19 nines, 9999999999999999999, is 0x8AC7230489E7FFFF, which has 64 + // bits and 16 hexadecimal digits. + // - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67 + // bits and 17 hexadecimal digits. + if (digit_count > 19) { + // Even if we have more than 19 pseudo-digits, it's not yet definitely an + // overflow. Recall that digit_count might be off-by-one (too large) if + // there's a decimal separator. It will also over-report the number of + // meaningful digits if the input looks something like "0.000dddExxx". + // + // We adjust by the number of leading '0's and '.'s and re-compare to 19. + // Once again, technically, we could skip ','s too, but that perturbs the + // "script/process-json-numbers.c with -p" benchmark. + const uint8_t* q = start_of_digits_ptr; + for (; (*q == '0') || (*q == '.'); q++) { + } + digit_count -= (uint32_t)(q - start_of_digits_ptr); + if (digit_count > 19) { + goto fallback; + } + } - while (n >= 4) { - __m128i x; - x = _mm_lddqu_si128((const __m128i*)(const void*)s); - x = _mm_shuffle_epi8(x, shuffle); - _mm_storeu_si128((__m128i*)(void*)d, x); + // The wuffs_private_impl__parse_number_f64_eisel_lemire preconditions + // include that exp10 is in the range [-307 ..= 288]. + if ((exp10 < -307) || (288 < exp10)) { + goto fallback; + } - s += 4 * 4; - d += 4 * 4; - n -= 4; - } + // If both man and (10 ** exp10) are exactly representable by a double, we + // don't need to run the Eisel-Lemire algorithm. + if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) { + double d = (double)man; + if (exp10 >= 0) { + d *= wuffs_private_impl__f64_powers_of_10[+exp10]; + } else { + d /= wuffs_private_impl__f64_powers_of_10[-exp10]; + } + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = negative ? -d : +d; + return ret; + } - while (n--) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - uint8_t s3 = s[3]; - d[0] = s2; - d[1] = s1; - d[2] = s0; - d[3] = s3; - s += 4; - d += 4; - } - return len; -} -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 + // The wuffs_private_impl__parse_number_f64_eisel_lemire preconditions + // include that man is non-zero. Parsing "0" should be caught by the "If + // both man and (10 ** exp10)" above, but "0e99" might not. + if (man == 0) { + goto fallback; + } -static uint64_t // -wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t len = (dst_len < src_len ? dst_len : src_len) / 4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; + // Our man and exp10 are in range. Run the Eisel-Lemire algorithm. + int64_t r = wuffs_private_impl__parse_number_f64_eisel_lemire(man, exp10); + if (r < 0) { + goto fallback; + } + wuffs_base__result_f64 ret; + ret.status.repr = NULL; + ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64( + ((uint64_t)r) | (((uint64_t)negative) << 63)); + return ret; + } while (0); - size_t n = len; - while (n--) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - uint8_t s3 = s[3]; - d[0] = s2; - d[1] = s1; - d[2] = s0; - d[3] = s3; - s += 4; - d += 4; - } - return len; +fallback: + do { + wuffs_private_impl__high_prec_dec h; + wuffs_base__status status = + wuffs_private_impl__high_prec_dec__parse(&h, s, options); + if (status.repr) { + return wuffs_private_impl__parse_number_f64_special(s, options); + } + return wuffs_private_impl__high_prec_dec__to_f64(&h, options); + } while (0); } // -------- -static uint64_t // -wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t len = (dst_len < src_len) ? dst_len : src_len; - if (len > 0) { - memmove(dst_ptr, src_ptr, len); +static inline size_t // +wuffs_private_impl__render_inf(wuffs_base__slice_u8 dst, + bool neg, + uint32_t options) { + if (neg) { + if (dst.len < 4) { + return 0; + } + wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D); // '-Inf'le. + return 4; } - return len; -} -static uint64_t // -wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len2 = src_len / 2; - size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; - if (len > 0) { - memmove(dst_ptr, src_ptr, len * 2); + if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { + if (dst.len < 4) { + return 0; + } + wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B); // '+Inf'le. + return 4; } - return len; -} -static uint64_t // -wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len3 = src_len / 3; - size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3; - if (len > 0) { - memmove(dst_ptr, src_ptr, len * 3); + if (dst.len < 3) { + return 0; } - return len; + wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49); // 'Inf'le. + return 3; } -static uint64_t // -wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - if (len > 0) { - memmove(dst_ptr, src_ptr, len * 4); +static inline size_t // +wuffs_private_impl__render_nan(wuffs_base__slice_u8 dst) { + if (dst.len < 3) { + return 0; } - return len; + wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E); // 'NaN'le. + return 3; } -static uint64_t // -wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len8 = src_len / 8; - size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8; - if (len > 0) { - memmove(dst_ptr, src_ptr, len * 8); +static size_t // +wuffs_private_impl__high_prec_dec__render_exponent_absent( + wuffs_base__slice_u8 dst, + wuffs_private_impl__high_prec_dec* h, + uint32_t precision, + uint32_t options) { + size_t n = (h->negative || + (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN)) + ? 1 + : 0; + if (h->decimal_point <= 0) { + n += 1; + } else { + n += (size_t)(h->decimal_point); + } + if (precision > 0) { + n += precision + 1; // +1 for the '.'. } - return len; -} -// -------- + // Don't modify dst if the formatted number won't fit. + if (n > dst.len) { + return 0; + } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len3 = src_len / 3; - size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // Align-left or align-right. + uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) + ? &dst.ptr[dst.len - n] + : &dst.ptr[0]; - // TODO: unroll. + // Leading "±". + if (h->negative) { + *ptr++ = '-'; + } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { + *ptr++ = '+'; + } - while (n >= 1) { - uint32_t b5 = s[0] >> 3; - uint32_t g6 = s[1] >> 2; - uint32_t r5 = s[2] >> 3; - uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); + // Integral digits. + if (h->decimal_point <= 0) { + *ptr++ = '0'; + } else { + uint32_t m = + wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point)); + uint32_t i = 0; + for (; i < m; i++) { + *ptr++ = (uint8_t)('0' | h->digits[i]); + } + for (; i < (uint32_t)(h->decimal_point); i++) { + *ptr++ = '0'; + } + } - s += 1 * 3; - d += 1 * 2; - n -= 1; + // Separator and then fractional digits. + if (precision > 0) { + *ptr++ = + (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.'; + uint32_t i = 0; + for (; i < precision; i++) { + uint32_t j = ((uint32_t)(h->decimal_point)) + i; + *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0)); + } } - return len; + return n; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - // TODO: unroll. +static size_t // +wuffs_private_impl__high_prec_dec__render_exponent_present( + wuffs_base__slice_u8 dst, + wuffs_private_impl__high_prec_dec* h, + uint32_t precision, + uint32_t options) { + int32_t exp = 0; + if (h->num_digits > 0) { + exp = h->decimal_point - 1; + } + bool negative_exp = exp < 0; + if (negative_exp) { + exp = -exp; + } - while (n >= 1) { - uint32_t b5 = s[0] >> 3; - uint32_t g6 = s[1] >> 2; - uint32_t r5 = s[2] >> 3; - uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); + size_t n = (h->negative || + (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN)) + ? 4 + : 3; // Mininum 3 bytes: first digit and then "e±". + if (precision > 0) { + n += precision + 1; // +1 for the '.'. + } + n += (exp < 100) ? 2 : 3; - s += 1 * 4; - d += 1 * 2; - n -= 1; + // Don't modify dst if the formatted number won't fit. + if (n > dst.len) { + return 0; } - return len; -} + // Align-left or align-right. + uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) + ? &dst.ptr[dst.len - n] + : &dst.ptr[0]; -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // Leading "±". + if (h->negative) { + *ptr++ = '-'; + } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { + *ptr++ = '+'; + } - // TODO: unroll. + // Integral digit. + if (h->num_digits > 0) { + *ptr++ = (uint8_t)('0' | h->digits[0]); + } else { + *ptr++ = '0'; + } - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); + // Separator and then fractional digits. + if (precision > 0) { + *ptr++ = + (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA) + ? ',' + : '.'; + uint32_t i = 1; + uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1); + for (; i < j; i++) { + *ptr++ = (uint8_t)('0' | h->digits[i]); + } + for (; i <= precision; i++) { + *ptr++ = '0'; + } + } - s += 1 * 4; - d += 1 * 2; - n -= 1; + // Exponent: "e±" and then 2 or 3 digits. + *ptr++ = 'e'; + *ptr++ = negative_exp ? '-' : '+'; + if (exp < 10) { + *ptr++ = '0'; + *ptr++ = (uint8_t)('0' | exp); + } else if (exp < 100) { + *ptr++ = (uint8_t)('0' | (exp / 10)); + *ptr++ = (uint8_t)('0' | (exp % 10)); + } else { + int32_t e = exp / 100; + exp -= e * 100; + *ptr++ = (uint8_t)('0' | e); + *ptr++ = (uint8_t)('0' | (exp / 10)); + *ptr++ = (uint8_t)('0' | (exp % 10)); } - return len; + return n; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len8 = src_len / 8; - size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__render_number_f64(wuffs_base__slice_u8 dst, + double x, + uint32_t precision, + uint32_t options) { + // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits + // with a -1023 bias) and mantissa (52 bits). + uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x); + bool neg = (bits >> 63) != 0; + int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF; + uint64_t man = bits & 0x000FFFFFFFFFFFFFul; - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))))); + // Apply the exponent bias and set the implicit top bit of the mantissa, + // unless x is subnormal. Also take care of Inf and NaN. + if (exp2 == 0x7FF) { + if (man != 0) { + return wuffs_private_impl__render_nan(dst); + } + return wuffs_private_impl__render_inf(dst, neg, options); + } else if (exp2 == 0) { + exp2 = -1022; + } else { + exp2 -= 1023; + man |= 0x0010000000000000ul; + } - s += 1 * 8; - d += 1 * 2; - n -= 1; + // Ensure that precision isn't too large. + if (precision > 4095) { + precision = 4095; } - return len; -} + // Convert from the (neg, exp2, man) tuple to an HPD. + wuffs_private_impl__high_prec_dec h; + wuffs_private_impl__high_prec_dec__assign(&h, man, neg); + if (h.num_digits > 0) { + wuffs_private_impl__high_prec_dec__lshift(&h, + exp2 - 52); // 52 mantissa bits. + } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // Handle the "%e" and "%f" formats. + switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT | + WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) { + case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT: // The "%"f" format. + if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { + wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man); + int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point; + precision = ((uint32_t)(wuffs_base__i32__max(0, p))); + } else { + wuffs_private_impl__high_prec_dec__round_nearest( + &h, ((int32_t)precision) + h.decimal_point); + } + return wuffs_private_impl__high_prec_dec__render_exponent_absent( + dst, &h, precision, options); - // TODO: unroll. + case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT: // The "%e" format. + if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { + wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man); + precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0; + } else { + wuffs_private_impl__high_prec_dec__round_nearest( + &h, ((int32_t)precision) + 1); + } + return wuffs_private_impl__high_prec_dec__render_exponent_present( + dst, &h, precision, options); + } - while (n >= 1) { - // Extract 16-bit color components. - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sr = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sb = 0x101 * ((uint32_t)s[0]); + // We have the "%g" format and so precision means the number of significant + // digits, not the number of digits after the decimal separator. Perform + // rounding and determine whether to use "%e" or "%f". + int32_t e_threshold = 0; + if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) { + wuffs_private_impl__high_prec_dec__round_just_enough(&h, exp2, man); + precision = h.num_digits; + e_threshold = 6; + } else { + if (precision == 0) { + precision = 1; + } + wuffs_private_impl__high_prec_dec__round_nearest(&h, ((int32_t)precision)); + e_threshold = ((int32_t)precision); + int32_t nd = ((int32_t)(h.num_digits)); + if ((e_threshold > nd) && (nd >= h.decimal_point)) { + e_threshold = nd; + } + } - // Convert from 565 color to 16-bit color. - uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); - uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); - uint32_t dr = (0x8421 * old_r5) >> 4; - uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); - uint32_t dg = (0x1041 * old_g6) >> 2; - uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); - uint32_t db = (0x8421 * old_b5) >> 4; + // Use the "%e" format if the exponent is large. + int32_t e = h.decimal_point - 1; + if ((e < -4) || (e_threshold <= e)) { + uint32_t p = wuffs_base__u32__min(precision, h.num_digits); + return wuffs_private_impl__high_prec_dec__render_exponent_present( + dst, &h, (p > 0) ? (p - 1) : 0, options); + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + // Use the "%f" format otherwise. + int32_t p = ((int32_t)precision); + if (p > h.decimal_point) { + p = ((int32_t)(h.num_digits)); + } + precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point))); + return wuffs_private_impl__high_prec_dec__render_exponent_absent( + dst, &h, precision, options); +} - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV) - // Convert from 16-bit color to 565 color and combine the components. - uint32_t new_r5 = 0x1F & (dr >> 11); - uint32_t new_g6 = 0x3F & (dg >> 10); - uint32_t new_b5 = 0x1F & (db >> 11); - uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__INTCONV) - s += 1 * 4; - d += 1 * 2; - n -= 1; - } +// ---------------- Integer - return len; -} +// wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits, +// and (0x80 | v) for valid digits, where v is the 4 bit value. -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len8 = src_len / 8; - size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static const uint8_t wuffs_base__parse_number__decimal_digits[256] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'. + 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'. - // TODO: unroll. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. - while (n >= 1) { - // Extract 16-bit color components. - uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); - uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); - uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); - uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF. - // Convert from 565 color to 16-bit color. - uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); - uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); - uint32_t dr = (0x8421 * old_r5) >> 4; - uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); - uint32_t dg = (0x1041 * old_g6) >> 2; - uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); - uint32_t db = (0x8421 * old_b5) >> 4; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF. + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F +}; - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; +static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'. + 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'. - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. + 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. - // Convert from 16-bit color to 565 color and combine the components. - uint32_t new_r5 = 0x1F & (dr >> 11); - uint32_t new_g6 = 0x3F & (dg >> 10); - uint32_t new_b5 = 0x1F & (db >> 11); - uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF. - s += 1 * 8; - d += 1 * 2; - n -= 1; - } + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF. + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F +}; - return len; -} +static const uint8_t wuffs_private_impl__encode_base16[16] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x00 ..= 0x07. + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 0x08 ..= 0x0F. +}; -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// -------- - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 // +wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) { + uint8_t* p = s.ptr; + uint8_t* q = s.ptr + s.len; - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (; (p < q) && (*p == '_'); p++) { + } + } - s += 1 * 4; - d += 1 * 2; - n -= 1; + bool negative = false; + if (p >= q) { + goto fail_bad_argument; + } else if (*p == '-') { + p++; + negative = true; + } else if (*p == '+') { + p++; } - return len; -} + do { + wuffs_base__result_u64 r = wuffs_base__parse_number_u64( + wuffs_base__make_slice_u8(p, (size_t)(q - p)), options); + if (r.status.repr != NULL) { + wuffs_base__result_i64 ret; + ret.status.repr = r.status.repr; + ret.value = 0; + return ret; + } else if (negative) { + if (r.value < 0x8000000000000000) { + wuffs_base__result_i64 ret; + ret.status.repr = NULL; + ret.value = -(int64_t)(r.value); + return ret; + } else if (r.value == 0x8000000000000000) { + wuffs_base__result_i64 ret; + ret.status.repr = NULL; + ret.value = INT64_MIN; + return ret; + } + goto fail_out_of_bounds; + } else if (r.value > 0x7FFFFFFFFFFFFFFF) { + goto fail_out_of_bounds; + } else { + wuffs_base__result_i64 ret; + ret.status.repr = NULL; + ret.value = +(int64_t)(r.value); + return ret; + } + } while (0); -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +fail_bad_argument: + do { + wuffs_base__result_i64 ret; + ret.status.repr = wuffs_base__error__bad_argument; + ret.value = 0; + return ret; + } while (0); - // TODO: unroll. +fail_out_of_bounds: + do { + wuffs_base__result_i64 ret; + ret.status.repr = wuffs_base__error__out_of_bounds; + ret.value = 0; + return ret; + } while (0); +} - while (n >= 1) { - // Extract 16-bit color components. - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sr = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sb = 0x101 * ((uint32_t)s[0]); +WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 // +wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) { + uint8_t* p = s.ptr; + uint8_t* q = s.ptr + s.len; - // Convert from 565 color to 16-bit color. - uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); - uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); - uint32_t dr = (0x8421 * old_r5) >> 4; - uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); - uint32_t dg = (0x1041 * old_g6) >> 2; - uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); - uint32_t db = (0x8421 * old_b5) >> 4; - - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; - - // Composite src (premul) over dst (premul). - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); - - // Convert from 16-bit color to 565 color and combine the components. - uint32_t new_r5 = 0x1F & (dr >> 11); - uint32_t new_g6 = 0x3F & (dg >> 10); - uint32_t new_b5 = 0x1F & (db >> 11); - uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); - - s += 1 * 4; - d += 1 * 2; - n -= 1; + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (; (p < q) && (*p == '_'); p++) { + } } - return len; -} + if (p >= q) { + goto fail_bad_argument; -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len3 = src_len / 3; - size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + } else if (*p == '0') { + p++; + if (p >= q) { + goto ok_zero; + } + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + if (*p == '_') { + p++; + for (; p < q; p++) { + if (*p != '_') { + if (options & + WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) { + goto decimal; + } + goto fail_bad_argument; + } + } + goto ok_zero; + } + } - // TODO: unroll. + if ((*p == 'x') || (*p == 'X')) { + p++; + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (; (p < q) && (*p == '_'); p++) { + } + } + if (p < q) { + goto hexadecimal; + } - while (n >= 1) { - uint32_t r5 = s[0] >> 3; - uint32_t g6 = s[1] >> 2; - uint32_t b5 = s[2] >> 3; - uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); + } else if ((*p == 'd') || (*p == 'D')) { + p++; + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) { + for (; (p < q) && (*p == '_'); p++) { + } + } + if (p < q) { + goto decimal; + } + } - s += 1 * 3; - d += 1 * 2; - n -= 1; + if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) { + goto decimal; + } + goto fail_bad_argument; } - return len; -} +decimal: + do { + uint64_t v = wuffs_base__parse_number__decimal_digits[*p++]; + if (v == 0) { + goto fail_bad_argument; + } + v &= 0x0F; -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1). + const uint64_t max10 = 1844674407370955161u; + const uint8_t max1 = 5; - // TODO: unroll. + for (; p < q; p++) { + if ((*p == '_') && + (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + continue; + } + uint8_t digit = wuffs_base__parse_number__decimal_digits[*p]; + if (digit == 0) { + goto fail_bad_argument; + } + digit &= 0x0F; + if ((v > max10) || ((v == max10) && (digit > max1))) { + goto fail_out_of_bounds; + } + v = (10 * v) + ((uint64_t)(digit)); + } - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))))); + wuffs_base__result_u64 ret; + ret.status.repr = NULL; + ret.value = v; + return ret; + } while (0); - s += 1 * 4; - d += 1 * 2; - n -= 1; - } +hexadecimal: + do { + uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++]; + if (v == 0) { + goto fail_bad_argument; + } + v &= 0x0F; - return len; -} + for (; p < q; p++) { + if ((*p == '_') && + (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) { + continue; + } + uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p]; + if (digit == 0) { + goto fail_bad_argument; + } + digit &= 0x0F; + if ((v >> 60) != 0) { + goto fail_out_of_bounds; + } + v = (v << 4) | ((uint64_t)(digit)); + } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + wuffs_base__result_u64 ret; + ret.status.repr = NULL; + ret.value = v; + return ret; + } while (0); - // TODO: unroll. +ok_zero: + do { + wuffs_base__result_u64 ret; + ret.status.repr = NULL; + ret.value = 0; + return ret; + } while (0); - while (n >= 1) { - // Extract 16-bit color components. - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sb = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sr = 0x101 * ((uint32_t)s[0]); +fail_bad_argument: + do { + wuffs_base__result_u64 ret; + ret.status.repr = wuffs_base__error__bad_argument; + ret.value = 0; + return ret; + } while (0); - // Convert from 565 color to 16-bit color. - uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); - uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); - uint32_t dr = (0x8421 * old_r5) >> 4; - uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); - uint32_t dg = (0x1041 * old_g6) >> 2; - uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); - uint32_t db = (0x8421 * old_b5) >> 4; +fail_out_of_bounds: + do { + wuffs_base__result_u64 ret; + ret.status.repr = wuffs_base__error__out_of_bounds; + ret.value = 0; + return ret; + } while (0); +} - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; +// -------- - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; +// wuffs_base__render_number__first_hundred contains the decimal encodings of +// the first one hundred numbers [0 ..= 99]. +static const uint8_t wuffs_base__render_number__first_hundred[200] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', // + '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', // + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', // + '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', // + '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', // + '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', // + '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', // + '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', // + '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', // + '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', // + '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', // + '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', // + '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', // + '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', // + '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', // + '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', // + '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', // + '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', // + '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', // + '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', // +}; - // Convert from 16-bit color to 565 color and combine the components. - uint32_t new_r5 = 0x1F & (dr >> 11); - uint32_t new_g6 = 0x3F & (dg >> 10); - uint32_t new_b5 = 0x1F & (db >> 11); - uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); +static size_t // +wuffs_private_impl__render_number_u64(wuffs_base__slice_u8 dst, + uint64_t x, + uint32_t options, + bool neg) { + uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL]; + uint8_t* ptr = &buf[0] + sizeof(buf); - s += 1 * 4; - d += 1 * 2; - n -= 1; + while (x >= 100) { + size_t index = ((size_t)((x % 100) * 2)); + x /= 100; + uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0]; + uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1]; + ptr -= 2; + ptr[0] = s0; + ptr[1] = s1; } - return len; -} - -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + if (x < 10) { + ptr -= 1; + ptr[0] = (uint8_t)('0' + x); + } else { + size_t index = ((size_t)(x * 2)); + uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0]; + uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1]; + ptr -= 2; + ptr[0] = s0; + ptr[1] = s1; + } - // TODO: unroll. + if (neg) { + ptr -= 1; + ptr[0] = '-'; + } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) { + ptr -= 1; + ptr[0] = '+'; + } - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); + size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0])); + if (n > dst.len) { + return 0; + } + memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT) + ? (dst.len - n) + : 0), + ptr, n); + return n; +} - s += 1 * 4; - d += 1 * 2; - n -= 1; +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__render_number_i64(wuffs_base__slice_u8 dst, + int64_t x, + uint32_t options) { + uint64_t u = (uint64_t)x; + bool neg = x < 0; + if (neg) { + u = 1 + ~u; } + return wuffs_private_impl__render_number_u64(dst, u, options, neg); +} - return len; +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__render_number_u64(wuffs_base__slice_u8 dst, + uint64_t x, + uint32_t options) { + return wuffs_private_impl__render_number_u64(dst, x, options, false); } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len4 = src_len / 4; - size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// ---------------- Base-16 - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + wuffs_base__transform__output o; + size_t src_len2 = src.len / 2; + size_t len; + if (dst.len < src_len2) { + len = dst.len; + o.status.repr = wuffs_base__suspension__short_write; + } else { + len = src_len2; + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + } else if (src.len & 1) { + o.status.repr = wuffs_base__error__bad_data; + } else { + o.status.repr = NULL; + } + } - while (n >= 1) { - // Extract 16-bit color components. - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sb = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sr = 0x101 * ((uint32_t)s[0]); + uint8_t* d = dst.ptr; + uint8_t* s = src.ptr; + size_t n = len; - // Convert from 565 color to 16-bit color. - uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); - uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); - uint32_t dr = (0x8421 * old_r5) >> 4; - uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); - uint32_t dg = (0x1041 * old_g6) >> 2; - uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); - uint32_t db = (0x8421 * old_b5) >> 4; + while (n--) { + *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) | + (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F)); + d += 1; + s += 2; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + o.num_dst = len; + o.num_src = len * 2; + return o; +} - // Composite src (premul) over dst (premul). - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + wuffs_base__transform__output o; + size_t src_len4 = src.len / 4; + size_t len = dst.len < src_len4 ? dst.len : src_len4; + if (dst.len < src_len4) { + len = dst.len; + o.status.repr = wuffs_base__suspension__short_write; + } else { + len = src_len4; + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + } else if (src.len & 1) { + o.status.repr = wuffs_base__error__bad_data; + } else { + o.status.repr = NULL; + } + } - // Convert from 16-bit color to 565 color and combine the components. - uint32_t new_r5 = 0x1F & (dr >> 11); - uint32_t new_g6 = 0x3F & (dg >> 10); - uint32_t new_b5 = 0x1F & (db >> 11); - uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); + uint8_t* d = dst.ptr; + uint8_t* s = src.ptr; + size_t n = len; - s += 1 * 4; - d += 1 * 2; - n -= 1; + while (n--) { + *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) | + (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F)); + d += 1; + s += 4; } - return len; + o.num_dst = len; + o.num_src = len * 4; + return o; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + wuffs_base__transform__output o; + size_t dst_len2 = dst.len / 2; + size_t len; + if (dst_len2 < src.len) { + len = dst_len2; + o.status.repr = wuffs_base__suspension__short_write; + } else { + len = src.len; + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + } else { + o.status.repr = NULL; + } + } - while (n >= 1) { - uint32_t y5 = s[0] >> 3; - uint32_t y6 = s[0] >> 2; - uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); + uint8_t* d = dst.ptr; + uint8_t* s = src.ptr; + size_t n = len; - s += 1 * 1; - d += 1 * 2; - n -= 1; + while (n--) { + uint8_t c = *s; + d[0] = wuffs_private_impl__encode_base16[c >> 4]; + d[1] = wuffs_private_impl__encode_base16[c & 0x0F]; + d += 2; + s += 1; } - return len; + o.num_dst = len * 2; + o.num_src = len; + return o; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; - size_t src_len2 = src_len / 2; - size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + wuffs_base__transform__output o; + size_t dst_len4 = dst.len / 4; + size_t len; + if (dst_len4 < src.len) { + len = dst_len4; + o.status.repr = wuffs_base__suspension__short_write; + } else { + len = src.len; + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + } else { + o.status.repr = NULL; + } + } - while (n >= 1) { - uint32_t y5 = s[0] >> 3; - uint32_t y6 = s[0] >> 2; - uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0); - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); + uint8_t* d = dst.ptr; + uint8_t* s = src.ptr; + size_t n = len; - s += 1 * 2; - d += 1 * 2; - n -= 1; + while (n--) { + uint8_t c = *s; + d[0] = '\\'; + d[1] = 'x'; + d[2] = wuffs_private_impl__encode_base16[c >> 4]; + d[3] = wuffs_private_impl__encode_base16[c & 0x0F]; + d += 4; + s += 1; } - return len; + o.num_dst = len * 4; + o.num_src = len; + return o; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len2 = dst_len / 2; - size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// ---------------- Base-64 - const size_t loop_unroll_count = 4; +// The two base-64 alphabets, std and url, differ only in the last two codes. +// - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +// - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" - while (n >= loop_unroll_count) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4))); - wuffs_base__poke_u16le__no_bounds_check( - d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check( - dst_palette_ptr + ((size_t)s[1] * 4))); - wuffs_base__poke_u16le__no_bounds_check( - d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check( - dst_palette_ptr + ((size_t)s[2] * 4))); - wuffs_base__poke_u16le__no_bounds_check( - d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check( - dst_palette_ptr + ((size_t)s[3] * 4))); +static const uint8_t wuffs_base__base_64__decode_std[256] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27. + 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, // 0x28 ..= 0x2F. + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37. + 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F. - s += loop_unroll_count * 1; - d += loop_unroll_count * 2; - n -= loop_unroll_count; - } + 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47. + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F. + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57. + 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x58 ..= 0x5F. + 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67. + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F. + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77. + 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F. - while (n >= 1) { - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4))); + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF. - s += 1 * 1; - d += 1 * 2; - n -= 1; - } + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F +}; - return len; -} +static const uint8_t wuffs_base__base_64__decode_url[256] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, // 0x28 ..= 0x2F. + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37. + 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F. -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len2 = dst_len / 2; - size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47. + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F. + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57. + 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F, // 0x58 ..= 0x5F. + 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67. + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F. + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77. + 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F. - // TODO: unroll. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF. - while (n >= 1) { - uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2))); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - wuffs_base__poke_u16le__no_bounds_check( - d + (0 * 2), - wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( - wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0))); + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F +}; - s += 1 * 1; - d += 1 * 2; - n -= 1; - } +static const uint8_t wuffs_base__base_64__encode_std[64] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07. + 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F. + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17. + 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F. + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27. + 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F. + 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37. + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, // 0x38 ..= 0x3F. +}; - return len; -} +static const uint8_t wuffs_base__base_64__encode_url[64] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07. + 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F. + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17. + 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F. + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27. + 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F. + 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37. + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F, // 0x38 ..= 0x3F. +}; -static uint64_t // -wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len2 = dst_len / 2; - size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// -------- - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_64__decode(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET) + ? wuffs_base__base_64__decode_url + : wuffs_base__base_64__decode_std; + wuffs_base__transform__output o; + uint8_t* d_ptr = dst.ptr; + size_t d_len = dst.len; + const uint8_t* s_ptr = src.ptr; + size_t s_len = src.len; + bool pad = false; - while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0); - } + while (s_len >= 4) { + uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr); + uint32_t s0 = alphabet[0xFF & (s >> 0)]; + uint32_t s1 = alphabet[0xFF & (s >> 8)]; + uint32_t s2 = alphabet[0xFF & (s >> 16)]; + uint32_t s3 = alphabet[0xFF & (s >> 24)]; - s += 1 * 1; - d += 1 * 2; - n -= 1; - } + if (((s0 | s1 | s2 | s3) & 0xC0) != 0) { + if (s_len > 4) { + o.status.repr = wuffs_base__error__bad_data; + goto done; + } else if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + goto done; + } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) && + (s_ptr[3] == '=')) { + pad = true; + if (s_ptr[2] == '=') { + goto src2; + } + goto src3; + } + o.status.repr = wuffs_base__error__bad_data; + goto done; + } - return len; -} + if (d_len < 3) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } -// -------- + s_ptr += 4; + s_len -= 4; + s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0); + *d_ptr++ = (uint8_t)(s >> 16); + *d_ptr++ = (uint8_t)(s >> 8); + *d_ptr++ = (uint8_t)(s >> 0); + d_len -= 3; + } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len2 = src_len / 2; - size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + goto done; + } - // TODO: unroll. + if (s_len == 0) { + o.status.repr = NULL; + goto done; + } else if (s_len == 1) { + o.status.repr = wuffs_base__error__bad_data; + goto done; + } else if (s_len == 2) { + goto src2; + } - while (n >= 1) { - uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))); - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); +src3: + do { + uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr); + uint32_t s0 = alphabet[0xFF & (s >> 0)]; + uint32_t s1 = alphabet[0xFF & (s >> 8)]; + uint32_t s2 = alphabet[0xFF & (s >> 16)]; + if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) { + o.status.repr = wuffs_base__error__bad_data; + goto done; + } + if (d_len < 2) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } + s_ptr += pad ? 4 : 3; + s = (s0 << 18) | (s1 << 12) | (s2 << 6); + *d_ptr++ = (uint8_t)(s >> 16); + *d_ptr++ = (uint8_t)(s >> 8); + o.status.repr = NULL; + goto done; + } while (0); - s += 1 * 2; - d += 1 * 3; - n -= 1; - } +src2: + do { + uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr); + uint32_t s0 = alphabet[0xFF & (s >> 0)]; + uint32_t s1 = alphabet[0xFF & (s >> 8)]; + if ((s0 & 0xC0) || (s1 & 0xCF)) { + o.status.repr = wuffs_base__error__bad_data; + goto done; + } + if (d_len < 1) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } + s_ptr += pad ? 4 : 2; + s = (s0 << 18) | (s1 << 12); + *d_ptr++ = (uint8_t)(s >> 16); + o.status.repr = NULL; + goto done; + } while (0); - return len; +done: + o.num_dst = (size_t)(d_ptr - dst.ptr); + o.num_src = (size_t)(s_ptr - src.ptr); + return o; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output // +wuffs_base__base_64__encode(wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 src, + bool src_closed, + uint32_t options) { + const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET) + ? wuffs_base__base_64__encode_url + : wuffs_base__base_64__encode_std; + wuffs_base__transform__output o; + uint8_t* d_ptr = dst.ptr; + size_t d_len = dst.len; + const uint8_t* s_ptr = src.ptr; + size_t s_len = src.len; - // TODO: unroll. + do { + while (s_len >= 3) { + if (d_len < 4) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } + uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr); + s_ptr += 3; + s_len -= 3; + *d_ptr++ = alphabet[0x3F & (s >> 18)]; + *d_ptr++ = alphabet[0x3F & (s >> 12)]; + *d_ptr++ = alphabet[0x3F & (s >> 6)]; + *d_ptr++ = alphabet[0x3F & (s >> 0)]; + d_len -= 4; + } - while (n >= 1) { - uint32_t s0 = - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); + if (!src_closed) { + o.status.repr = wuffs_base__suspension__short_read; + goto done; + } - s += 1 * 4; - d += 1 * 3; - n -= 1; - } + if (s_len == 2) { + if (d_len < + ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } + uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr))) + << 8; + s_ptr += 2; + *d_ptr++ = alphabet[0x3F & (s >> 18)]; + *d_ptr++ = alphabet[0x3F & (s >> 12)]; + *d_ptr++ = alphabet[0x3F & (s >> 6)]; + if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) { + *d_ptr++ = '='; + } + o.status.repr = NULL; + goto done; - return len; -} + } else if (s_len == 1) { + if (d_len < + ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) { + o.status.repr = wuffs_base__suspension__short_write; + goto done; + } + uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr))) + << 16; + s_ptr += 1; + *d_ptr++ = alphabet[0x3F & (s >> 18)]; + *d_ptr++ = alphabet[0x3F & (s >> 12)]; + if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) { + *d_ptr++ = '='; + *d_ptr++ = '='; + } + o.status.repr = NULL; + goto done; -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len8 = src_len / 8; - size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + } else { + o.status.repr = NULL; + goto done; + } + } while (0); - // TODO: unroll. +done: + o.num_dst = (size_t)(d_ptr - dst.ptr); + o.num_src = (size_t)(s_ptr - src.ptr); + return o; +} - while (n >= 1) { - uint32_t s0 = - wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV) - s += 1 * 8; - d += 1 * 3; - n -= 1; - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__MAGIC) - return len; -} +// ---------------- Magic Numbers -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// ICO doesn't start with a magic identifier. Instead, see if the opening bytes +// are plausibly ICO. +// +// Callers should have already verified that (prefix_data.len >= 2) and the +// first two bytes are 0x00. +// +// See: +// - https://docs.fileformat.com/image/ico/ +static int32_t // +wuffs_base__magic_number_guess_fourcc__maybe_ico( + wuffs_base__slice_u8 prefix_data, + bool prefix_closed) { + // Allow-list for the Image Type field. + if (prefix_data.len < 4) { + return prefix_closed ? 0 : -1; + } else if (prefix_data.ptr[3] != 0) { + return 0; + } + switch (prefix_data.ptr[2]) { + case 0x01: // ICO + case 0x02: // CUR + break; + default: + return 0; + } - // TODO: unroll. + // The Number Of Images should be positive. + if (prefix_data.len < 6) { + return prefix_closed ? 0 : -1; + } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) { + return 0; + } - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sr = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sb = 0x101 * ((uint32_t)s[0]); + // The first ICONDIRENTRY's fourth byte should be zero. + if (prefix_data.len < 10) { + return prefix_closed ? 0 : -1; + } else if (prefix_data.ptr[9] != 0) { + return 0; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + // TODO: have a separate FourCC for CUR? + return 0x49434F20; // 'ICO 'be +} - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; +// TGA doesn't start with a magic identifier. Instead, see if the opening bytes +// are plausibly TGA. +// +// Callers should have already verified that (prefix_data.len >= 2) and the +// second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or +// 0x01. +// +// See: +// - https://docs.fileformat.com/image/tga/ +// - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf +static int32_t // +wuffs_base__magic_number_guess_fourcc__maybe_tga( + wuffs_base__slice_u8 prefix_data, + bool prefix_closed) { + // Allow-list for the Image Type field. + if (prefix_data.len < 3) { + return prefix_closed ? 0 : -1; + } + switch (prefix_data.ptr[2]) { + case 0x01: + case 0x02: + case 0x03: + case 0x09: + case 0x0A: + case 0x0B: + break; + default: + // TODO: 0x20 and 0x21 are invalid, according to the spec, but are + // apparently unofficial extensions. + return 0; + } - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); + // Allow-list for the Color Map Entry Size field (if the Color Map Type field + // is non-zero) or else all the Color Map fields should be zero. + if (prefix_data.len < 8) { + return prefix_closed ? 0 : -1; + } else if (prefix_data.ptr[1] != 0x00) { + switch (prefix_data.ptr[7]) { + case 0x0F: + case 0x10: + case 0x18: + case 0x20: + break; + default: + return 0; + } + } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] | + prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) { + return 0; + } - s += 1 * 4; - d += 1 * 3; - n -= 1; + // Allow-list for the Pixel Depth field. + if (prefix_data.len < 17) { + return prefix_closed ? 0 : -1; + } + switch (prefix_data.ptr[16]) { + case 0x01: + case 0x08: + case 0x0F: + case 0x10: + case 0x18: + case 0x20: + break; + default: + return 0; } - return len; + return 0x54474120; // 'TGA 'be } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len8 = src_len / 8; - size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +WUFFS_BASE__MAYBE_STATIC int32_t // +wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data, + bool prefix_closed) { + // This is similar to (but different from): + // - the magic/Magdir tables under https://github.com/file/file + // - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/ - // TODO: unroll. + // table holds the 'magic numbers' (which are actually variable length + // strings). The strings may contain NUL bytes, so the "const char* magic" + // value starts with the length-minus-1 of the 'magic number'. + // + // Keep it sorted by magic[1], then magic[0] descending (prioritizing longer + // matches) and finally by magic[2:]. When multiple entries match, the + // longest one wins. + // + // The fourcc field might be negated, in which case there's further + // specialization (see § below). + static struct { + int32_t fourcc; + const char* magic; + } table[] = { + {-0x30302020, "\x01\x00\x00"}, // '00 'be + {+0x475A2020, "\x02\x1F\x8B\x08"}, // GZ + {+0x5A535444, "\x03\x28\xB5\x2F\xFD"}, // ZSTD + {+0x425A3220, "\x02\x42\x5A\x68"}, // BZ2 + {+0x424D5020, "\x01\x42\x4D"}, // BMP + {+0x47494620, "\x03\x47\x49\x46\x38"}, // GIF + {+0x54494646, "\x03\x49\x49\x2A\x00"}, // TIFF (little-endian) + {+0x4C5A4950, "\x04\x4C\x5A\x49\x50\x01"}, // LZIP + {+0x54494646, "\x03\x4D\x4D\x00\x2A"}, // TIFF (big-endian) + {+0x4E50424D, "\x02\x50\x35\x0A"}, // NPBM (P5; *.pgm) + {+0x4E50424D, "\x02\x50\x36\x0A"}, // NPBM (P6; *.ppm) + {-0x52494646, "\x03\x52\x49\x46\x46"}, // RIFF + {+0x4C5A4D41, "\x04\x5D\x00\x10\x00\x00"}, // LZMA + {+0x4C5A4D41, "\x02\x5D\x00\x00"}, // LZMA + {+0x4E494520, "\x02\x6E\xC3\xAF"}, // NIE + {+0x514F4920, "\x03\x71\x6F\x69\x66"}, // QOI + {+0x5A4C4942, "\x01\x78\x9C"}, // ZLIB + {+0x504E4720, "\x03\x89\x50\x4E\x47"}, // PNG + {+0x585A2020, "\x04\xFD\x37\x7A\x58\x5A"}, // XZ + {+0x4A504547, "\x01\xFF\xD8"}, // JPEG + }; + static const size_t table_len = sizeof(table) / sizeof(table[0]); - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); - uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); - uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); - uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); + if (prefix_data.len == 0) { + return prefix_closed ? 0 : -1; + } + uint8_t pre_first_byte = prefix_data.ptr[0]; - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + int32_t fourcc = 0; + size_t i; + for (i = 0; i < table_len; i++) { + uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1])); + if (pre_first_byte < mag_first_byte) { + break; + } else if (pre_first_byte > mag_first_byte) { + continue; + } + fourcc = table[i].fourcc; - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0])); + if (mag_remaining_len == 0) { + goto match; + } - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); + const char* mag_remaining_ptr = table[i].magic + 2; + uint8_t* pre_remaining_ptr = prefix_data.ptr + 1; + size_t pre_remaining_len = prefix_data.len - 1; + if (pre_remaining_len < mag_remaining_len) { + if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) { + return prefix_closed ? 0 : -1; + } + } else { + if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) { + goto match; + } + } + } - s += 1 * 8; - d += 1 * 3; - n -= 1; + if (prefix_data.len < 2) { + return prefix_closed ? 0 : -1; + } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) { + return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data, + prefix_closed); } - return len; -} + return 0; -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +match: + // Negative FourCC values (see § above) are further specialized. + if (fourcc < 0) { + fourcc = -fourcc; - while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s0; - d[1] = s1; - d[2] = s2; + if (fourcc == 0x52494646) { // 'RIFF'be + if (prefix_data.len < 12) { + return prefix_closed ? 0 : -1; + } + uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8); + if (x == 0x57454250) { // 'WEBP'be + return 0x57454250; // 'WEBP'be + } - s += 1 * 4; - d += 1 * 3; - n -= 1; + } else if (fourcc == 0x30302020) { // '00 'be + // Binary data starting with multiple 0x00 NUL bytes is quite common. + // Unfortunately, some file formats also don't start with a magic + // identifier, so we have to use heuristics (where the order matters, the + // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe + // it's TGA, ICO/CUR, etc. Maybe it's something else. + int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga( + prefix_data, prefix_closed); + if (tga != 0) { + return tga; + } + int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico( + prefix_data, prefix_closed); + if (ico != 0) { + return ico; + } + if (prefix_data.len < 4) { + return prefix_closed ? 0 : -1; + } else if ((prefix_data.ptr[2] != 0x00) && + ((prefix_data.ptr[2] >= 0x80) || + (prefix_data.ptr[3] != 0x00))) { + // Roughly speaking, this could be a non-degenerate (non-0-width and + // non-0-height) WBMP image. + return 0x57424D50; // 'WBMP'be + } + return 0; + } } - - return len; + return fourcc; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sr = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sb = 0x101 * ((uint32_t)s[0]); - - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC) - // Composite src (premul) over dst (premul). - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV) - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); +// ---------------- Pixel Swizzler - s += 1 * 4; - d += 1 * 3; - n -= 1; - } +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +static uint64_t // +wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len); - return len; -} +static uint64_t // +wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len); +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len); - // TODO: unroll. +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +static uint64_t // +wuffs_private_impl__swizzle_xxxx__y__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) - while (n >= 1) { - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); +// -------- - s += 1 * 4; - d += 1 * 3; - n -= 1; - } +static inline uint32_t // +wuffs_private_impl__swap_u32_argb_abgr(uint32_t u) { + uint32_t o = u & 0xFF00FF00ul; + uint32_t r = u & 0x00FF0000ul; + uint32_t b = u & 0x000000FFul; + return o | (r >> 16) | (b << 16); +} - return len; +static inline uint64_t // +wuffs_private_impl__swap_u64_argb_abgr(uint64_t u) { + uint64_t o = u & 0xFFFF0000FFFF0000ull; + uint64_t r = u & 0x0000FFFF00000000ull; + uint64_t b = u & 0x000000000000FFFFull; + return o | (r >> 32) | (b << 32); } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len8 = src_len / 8; - size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static inline uint32_t // +wuffs_private_impl__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) { + uint32_t a = ((uint32_t)(0xFF & (c >> 56))); + uint32_t r = ((uint32_t)(0xFF & (c >> 40))); + uint32_t g = ((uint32_t)(0xFF & (c >> 24))); + uint32_t b = ((uint32_t)(0xFF & (c >> 8))); + return (a << 24) | (b << 16) | (g << 8) | (r << 0); +} - // TODO: unroll. +// -------- - while (n >= 1) { - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); +WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul // +wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb, + uint32_t x, + uint32_t y) { + if (!pb || (x >= pb->pixcfg.private_impl.width) || + (y >= pb->pixcfg.private_impl.height)) { + return 0; + } - s += 1 * 8; - d += 1 * 3; - n -= 1; + if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { + // TODO: support planar formats. + return 0; } - return len; -} + size_t stride = pb->private_impl.planes[0].stride; + const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)); -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + switch (pb->pixcfg.private_impl.pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))); - // TODO: unroll. + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: { + uint8_t* palette = pb->private_impl.planes[3].ptr; + return wuffs_base__peek_u32le__no_bounds_check(palette + + (4 * ((size_t)row[x]))); + } - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sb = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sr = 0x101 * ((uint32_t)s[0]); + // Common formats above. Rarer formats below. - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + case WUFFS_BASE__PIXEL_FORMAT__Y: + return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x]))); + case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: + return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1]))); + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0]))); + case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL: + return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + (((uint32_t)(row[(2 * x) + 1])) << 24) | + (((uint32_t)(row[(2 * x) + 0])) * 0x00010101)); - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: { + uint8_t* palette = pb->private_impl.planes[3].ptr; + return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(palette + + (4 * ((size_t)row[x])))); + } - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x)))); + case WUFFS_BASE__PIXEL_FORMAT__BGR: + return 0xFF000000 | + wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x)))); + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + return 0xFF000000 | + wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))); - s += 1 * 4; - d += 1 * 3; - n -= 1; + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swap_u32_argb_abgr( + 0xFF000000 | + wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)))); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + return wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(row + + (4 * ((size_t)x))))); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + return wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + return wuffs_private_impl__swap_u32_argb_abgr( + 0xFF000000 | + wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)))); + + default: + // TODO: support more formats. + break; } - return len; + return 0; } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len8 = src_len / 8; - size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// -------- - // TODO: unroll. +WUFFS_BASE__MAYBE_STATIC wuffs_base__status // +wuffs_base__pixel_buffer__set_color_u32_at( + wuffs_base__pixel_buffer* pb, + uint32_t x, + uint32_t y, + wuffs_base__color_u32_argb_premul color) { + if (!pb) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if ((x >= pb->pixcfg.private_impl.width) || + (y >= pb->pixcfg.private_impl.height)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); - uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); - uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); - uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); + if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { + // TODO: support planar formats. + return wuffs_base__make_status(wuffs_base__error__unsupported_option); + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + size_t stride = pb->private_impl.planes[0].stride; + uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)); - // Composite src (nonpremul) over dst (premul). - dr = ((sr * sa) + (dr * ia)) / 0xFFFF; - dg = ((sg * sa) + (dg * ia)) / 0xFFFF; - db = ((sb * sa) + (db * ia)) / 0xFFFF; + switch (pb->pixcfg.private_impl.pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color); + break; - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); + // Common formats above. Rarer formats below. - s += 1 * 8; - d += 1 * 3; - n -= 1; - } + case WUFFS_BASE__PIXEL_FORMAT__Y: + wuffs_base__poke_u8__no_bounds_check( + row + ((size_t)x), + wuffs_base__color_u32_argb_premul__as__color_u8_gray(color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: + wuffs_base__poke_u16le__no_bounds_check( + row + (2 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u16_gray(color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + wuffs_base__poke_u16be__no_bounds_check( + row + (2 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u16_gray(color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL: + wuffs_base__poke_u16le__no_bounds_check( + row + (2 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u16_alpha_gray_nonpremul( + color)); + break; - return len; -} + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: + wuffs_base__poke_u8__no_bounds_check( + row + ((size_t)x), wuffs_base__pixel_palette__closest_element( + wuffs_base__pixel_buffer__palette(pb), + pb->pixcfg.private_impl.pixfmt, color)); + break; -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + wuffs_base__poke_u16le__no_bounds_check( + row + (2 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__BGR: + wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color); + break; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + wuffs_base__poke_u32le__no_bounds_check( + row + (4 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + wuffs_base__poke_u64le__no_bounds_check( + row + (8 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul( + color)); + break; - while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s2; - d[1] = s1; - d[2] = s0; + case WUFFS_BASE__PIXEL_FORMAT__RGB: + wuffs_base__poke_u24le__no_bounds_check( + row + (3 * ((size_t)x)), + wuffs_private_impl__swap_u32_argb_abgr(color)); + break; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + wuffs_base__poke_u32le__no_bounds_check( + row + (4 * ((size_t)x)), + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + wuffs_private_impl__swap_u32_argb_abgr(color))); + break; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + wuffs_base__poke_u32le__no_bounds_check( + row + (4 * ((size_t)x)), + wuffs_private_impl__swap_u32_argb_abgr(color)); + break; - s += 1 * 4; - d += 1 * 3; - n -= 1; + default: + // TODO: support more formats. + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } - return len; + return wuffs_base__make_status(NULL); } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// -------- - while (n >= 1) { - // Extract 16-bit color components. - uint32_t dr = 0x101 * ((uint32_t)d[2]); - uint32_t dg = 0x101 * ((uint32_t)d[1]); - uint32_t db = 0x101 * ((uint32_t)d[0]); - uint32_t sa = 0x101 * ((uint32_t)s[3]); - uint32_t sb = 0x101 * ((uint32_t)s[2]); - uint32_t sg = 0x101 * ((uint32_t)s[1]); - uint32_t sr = 0x101 * ((uint32_t)s[0]); +static inline void // +wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xx( + wuffs_base__pixel_buffer* pb, + wuffs_base__rect_ie_u32 rect, + uint16_t color) { + size_t stride = pb->private_impl.planes[0].stride; + uint32_t width = wuffs_base__rect_ie_u32__width(&rect); + if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { + uint8_t* ptr = + pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); + uint32_t height = wuffs_base__rect_ie_u32__height(&rect); + size_t n; + for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { + wuffs_base__poke_u16le__no_bounds_check(ptr, color); + ptr += 2; + } + return; + } - // Calculate the inverse of the src-alpha: how much of the dst to keep. - uint32_t ia = 0xFFFF - sa; + uint32_t y; + for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { + uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + + (2 * ((size_t)rect.min_incl_x)); + uint32_t n; + for (n = width; n > 0; n--) { + wuffs_base__poke_u16le__no_bounds_check(ptr, color); + ptr += 2; + } + } +} - // Composite src (premul) over dst (premul). - dr = sr + ((dr * ia) / 0xFFFF); - dg = sg + ((dg * ia) / 0xFFFF); - db = sb + ((db * ia) / 0xFFFF); +static inline void // +wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxx( + wuffs_base__pixel_buffer* pb, + wuffs_base__rect_ie_u32 rect, + uint32_t color) { + size_t stride = pb->private_impl.planes[0].stride; + uint32_t width = wuffs_base__rect_ie_u32__width(&rect); + if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { + uint8_t* ptr = + pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); + uint32_t height = wuffs_base__rect_ie_u32__height(&rect); + size_t n; + for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { + wuffs_base__poke_u24le__no_bounds_check(ptr, color); + ptr += 3; + } + return; + } - // Convert from 16-bit color to 8-bit color. - d[0] = (uint8_t)(db >> 8); - d[1] = (uint8_t)(dg >> 8); - d[2] = (uint8_t)(dr >> 8); + uint32_t y; + for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { + uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + + (3 * ((size_t)rect.min_incl_x)); + uint32_t n; + for (n = width; n > 0; n--) { + wuffs_base__poke_u24le__no_bounds_check(ptr, color); + ptr += 3; + } + } +} - s += 1 * 4; - d += 1 * 3; - n -= 1; +static inline void // +wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx( + wuffs_base__pixel_buffer* pb, + wuffs_base__rect_ie_u32 rect, + uint32_t color) { + size_t stride = pb->private_impl.planes[0].stride; + uint32_t width = wuffs_base__rect_ie_u32__width(&rect); + if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { + uint8_t* ptr = + pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); + uint32_t height = wuffs_base__rect_ie_u32__height(&rect); + size_t n; + for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { + wuffs_base__poke_u32le__no_bounds_check(ptr, color); + ptr += 4; + } + return; } - return len; + uint32_t y; + for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { + uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + + (4 * ((size_t)rect.min_incl_x)); + uint32_t n; + for (n = width; n > 0; n--) { + wuffs_base__poke_u32le__no_bounds_check(ptr, color); + ptr += 4; + } + } } -static uint64_t // -wuffs_base__pixel_swizzler__bgr__rgbx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static inline void // +wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx( + wuffs_base__pixel_buffer* pb, + wuffs_base__rect_ie_u32 rect, + uint64_t color) { + size_t stride = pb->private_impl.planes[0].stride; + uint32_t width = wuffs_base__rect_ie_u32__width(&rect); + if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) { + uint8_t* ptr = + pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y)); + uint32_t height = wuffs_base__rect_ie_u32__height(&rect); + size_t n; + for (n = ((size_t)width) * ((size_t)height); n > 0; n--) { + wuffs_base__poke_u64le__no_bounds_check(ptr, color); + ptr += 8; + } + return; + } - // TODO: unroll. + uint32_t y; + for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { + uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) + + (8 * ((size_t)rect.min_incl_x)); + uint32_t n; + for (n = width; n > 0; n--) { + wuffs_base__poke_u64le__no_bounds_check(ptr, color); + ptr += 8; + } + } +} - while (n >= 1) { - uint8_t b0 = s[0]; - uint8_t b1 = s[1]; - uint8_t b2 = s[2]; - d[0] = b2; - d[1] = b1; - d[2] = b0; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status // +wuffs_base__pixel_buffer__set_color_u32_fill_rect( + wuffs_base__pixel_buffer* pb, + wuffs_base__rect_ie_u32 rect, + wuffs_base__color_u32_argb_premul color) { + if (!pb) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) { + return wuffs_base__make_status(NULL); + } + wuffs_base__rect_ie_u32 bounds = + wuffs_base__pixel_config__bounds(&pb->pixcfg); + if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } - s += 1 * 4; - d += 1 * 3; - n -= 1; + if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) { + // TODO: support planar formats. + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } - return len; -} + switch (pb->pixcfg.private_impl.pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, + color); + return wuffs_base__make_status(NULL); -// -------- + // Common formats above. Rarer formats below. -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xx( + pb, rect, + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color)); + return wuffs_base__make_status(NULL); - while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); + case WUFFS_BASE__PIXEL_FORMAT__BGR: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, + color); + return wuffs_base__make_status(NULL); - s += 1 * 4; - d += 1 * 4; - n -= 1; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx( + pb, rect, + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + color)); + return wuffs_base__make_status(NULL); - return len; -} + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx( + pb, rect, + wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul( + color)); + return wuffs_base__make_status(NULL); -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx( + pb, rect, + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + wuffs_private_impl__swap_u32_argb_abgr(color))); + return wuffs_base__make_status(NULL); - size_t n = len; - while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__color_u64__as__color_u32( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + wuffs_private_impl__pixel_buffer__set_color_u32_fill_rect__xxxx( + pb, rect, wuffs_private_impl__swap_u32_argb_abgr(color)); + return wuffs_base__make_status(NULL); + } - s += 1 * 8; - d += 1 * 4; - n -= 1; + uint32_t y; + for (y = rect.min_incl_y; y < rect.max_excl_y; y++) { + uint32_t x; + for (x = rect.min_incl_x; x < rect.max_excl_x; x++) { + wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color); + } } - return len; + return wuffs_base__make_status(NULL); } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - while (n >= 1) { - uint64_t d0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); - uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u64__as__color_u32( - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0))); +// -------- - s += 1 * 8; - d += 1 * 4; - n -= 1; +WUFFS_BASE__MAYBE_STATIC uint8_t // +wuffs_base__pixel_palette__closest_element( + wuffs_base__slice_u8 palette_slice, + wuffs_base__pixel_format palette_format, + wuffs_base__color_u32_argb_premul c) { + size_t n = palette_slice.len / 4; + if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4); } + size_t best_index = 0; + uint64_t best_score = 0xFFFFFFFFFFFFFFFF; - return len; -} - -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // Work in 16-bit color. + uint32_t ca = 0x101 * (0xFF & (c >> 24)); + uint32_t cr = 0x101 * (0xFF & (c >> 16)); + uint32_t cg = 0x101 * (0xFF & (c >> 8)); + uint32_t cb = 0x101 * (0xFF & (c >> 0)); - while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0)); + switch (palette_format.repr) { + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: { + bool nonpremul = palette_format.repr == + WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL; - s += 1 * 4; - d += 1 * 4; - n -= 1; + size_t i; + for (i = 0; i < n; i++) { + // Work in 16-bit color. + uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0])); + uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1])); + uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2])); + uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3])); + + // Convert to premultiplied alpha. + if (nonpremul && (pa != 0xFFFF)) { + pb = (pb * pa) / 0xFFFF; + pg = (pg * pa) / 0xFFFF; + pr = (pr * pa) / 0xFFFF; + } + + // These deltas are conceptually int32_t (signed) but after squaring, + // it's equivalent to work in uint32_t (unsigned). + pb -= cb; + pg -= cg; + pr -= cr; + pa -= ca; + uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) + + ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa)); + if (best_score > score) { + best_score = score; + best_index = i; + } + } + break; + } } - return len; + return (uint8_t)best_index; } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +// -------- - while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0)); +static inline uint32_t // +wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx( + uint32_t dst_nonpremul, + uint32_t src_nonpremul) { + // Extract 16-bit color components. + // + // If the destination is transparent then SRC_OVER is equivalent to SRC: just + // return src_nonpremul. This isn't just an optimization (skipping the rest + // of the function's computation). It also preserves the nonpremul + // distinction between e.g. transparent red and transparent blue that would + // otherwise be lost by converting from nonpremul to premul and back. + uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24)); + if (da == 0) { + return src_nonpremul; + } + uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16)); + uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8)); + uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0)); + uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24)); + uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16)); + uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8)); + uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0)); - s += 1 * 4; - d += 1 * 4; - n -= 1; + // Convert dst from nonpremul to premul. + dr = (dr * da) / 0xFFFF; + dg = (dg * da) / 0xFFFF; + db = (db * da) / 0xFFFF; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert dst from premul to nonpremul. + if (da != 0) { + dr = (dr * 0xFFFF) / da; + dg = (dg * 0xFFFF) / da; + db = (db * 0xFFFF) / da; } - return len; + // Convert from 16-bit color to 8-bit color. + da >>= 8; + dr >>= 8; + dg >>= 8; + db >>= 8; + + // Combine components. + return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; +static inline uint64_t // +wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx( + uint64_t dst_nonpremul, + uint64_t src_nonpremul) { + // Extract components. + // + // If the destination is transparent then SRC_OVER is equivalent to SRC: just + // return src_nonpremul. This isn't just an optimization (skipping the rest + // of the function's computation). It also preserves the nonpremul + // distinction between e.g. transparent red and transparent blue that would + // otherwise be lost by converting from nonpremul to premul and back. + uint64_t da = 0xFFFF & (dst_nonpremul >> 48); + if (da == 0) { + return src_nonpremul; } - size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + uint64_t dr = 0xFFFF & (dst_nonpremul >> 32); + uint64_t dg = 0xFFFF & (dst_nonpremul >> 16); + uint64_t db = 0xFFFF & (dst_nonpremul >> 0); + uint64_t sa = 0xFFFF & (src_nonpremul >> 48); + uint64_t sr = 0xFFFF & (src_nonpremul >> 32); + uint64_t sg = 0xFFFF & (src_nonpremul >> 16); + uint64_t sb = 0xFFFF & (src_nonpremul >> 0); - // TODO: unroll. + // Convert dst from nonpremul to premul. + dr = (dr * da) / 0xFFFF; + dg = (dg * da) / 0xFFFF; + db = (db * da) / 0xFFFF; - while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint64_t ia = 0xFFFF - sa; - s += 1 * 1; - d += 1 * 4; - n -= 1; + // Composite src (nonpremul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert dst from premul to nonpremul. + if (da != 0) { + dr = (dr * 0xFFFF) / da; + dg = (dg * 0xFFFF) / da; + db = (db * 0xFFFF) / da; } - return len; + // Combine components. + return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static inline uint32_t // +wuffs_private_impl__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul, + uint32_t src_premul) { + // Extract 16-bit color components. + uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24)); + uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16)); + uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8)); + uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0)); + uint32_t sa = 0x101 * (0xFF & (src_premul >> 24)); + uint32_t sr = 0x101 * (0xFF & (src_premul >> 16)); + uint32_t sg = 0x101 * (0xFF & (src_premul >> 8)); + uint32_t sb = 0x101 * (0xFF & (src_premul >> 0)); - while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); + // Convert dst from nonpremul to premul. + dr = (dr * da) / 0xFFFF; + dg = (dg * da) / 0xFFFF; + db = (db * da) / 0xFFFF; - s += 1 * 4; - d += 1 * 4; - n -= 1; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert dst from premul to nonpremul. + if (da != 0) { + dr = (dr * 0xFFFF) / da; + dg = (dg * 0xFFFF) / da; + db = (db * 0xFFFF) / da; } - return len; + // Convert from 16-bit color to 8-bit color. + da >>= 8; + dr >>= 8; + dg >>= 8; + db >>= 8; + + // Combine components. + return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static inline uint64_t // +wuffs_private_impl__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul, + uint64_t src_premul) { + // Extract components. + uint64_t da = 0xFFFF & (dst_nonpremul >> 48); + uint64_t dr = 0xFFFF & (dst_nonpremul >> 32); + uint64_t dg = 0xFFFF & (dst_nonpremul >> 16); + uint64_t db = 0xFFFF & (dst_nonpremul >> 0); + uint64_t sa = 0xFFFF & (src_premul >> 48); + uint64_t sr = 0xFFFF & (src_premul >> 32); + uint64_t sg = 0xFFFF & (src_premul >> 16); + uint64_t sb = 0xFFFF & (src_premul >> 0); - while (n >= 1) { - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0)); + // Convert dst from nonpremul to premul. + dr = (dr * da) / 0xFFFF; + dg = (dg * da) / 0xFFFF; + db = (db * da) / 0xFFFF; - s += 1 * 4; - d += 1 * 4; - n -= 1; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint64_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert dst from premul to nonpremul. + if (da != 0) { + dr = (dr * 0xFFFF) / da; + dg = (dg * 0xFFFF) / da; + db = (db * 0xFFFF) / da; } - return len; + // Combine components. + return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; +static inline uint32_t // +wuffs_private_impl__composite_premul_nonpremul_u32_axxx( + uint32_t dst_premul, + uint32_t src_nonpremul) { + // Extract 16-bit color components. + uint32_t da = 0x101 * (0xFF & (dst_premul >> 24)); + uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16)); + uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8)); + uint32_t db = 0x101 * (0xFF & (dst_premul >> 0)); + uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24)); + uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16)); + uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8)); + uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0)); - while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0)); + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; - s += 1 * 4; - d += 1 * 4; - n -= 1; - } + // Composite src (nonpremul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; - return len; + // Convert from 16-bit color to 8-bit color. + da >>= 8; + dr >>= 8; + dg >>= 8; + db >>= 8; + + // Combine components. + return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); +} + +static inline uint64_t // +wuffs_private_impl__composite_premul_nonpremul_u64_axxx( + uint64_t dst_premul, + uint64_t src_nonpremul) { + // Extract components. + uint64_t da = 0xFFFF & (dst_premul >> 48); + uint64_t dr = 0xFFFF & (dst_premul >> 32); + uint64_t dg = 0xFFFF & (dst_premul >> 16); + uint64_t db = 0xFFFF & (dst_premul >> 0); + uint64_t sa = 0xFFFF & (src_nonpremul >> 48); + uint64_t sr = 0xFFFF & (src_nonpremul >> 32); + uint64_t sg = 0xFFFF & (src_nonpremul >> 16); + uint64_t sb = 0xFFFF & (src_nonpremul >> 0); + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint64_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Combine components. + return (db << 0) | (dg << 16) | (dr << 32) | (da << 48); +} + +static inline uint32_t // +wuffs_private_impl__composite_premul_premul_u32_axxx(uint32_t dst_premul, + uint32_t src_premul) { + // Extract 16-bit color components. + uint32_t da = 0x101 * (0xFF & (dst_premul >> 24)); + uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16)); + uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8)); + uint32_t db = 0x101 * (0xFF & (dst_premul >> 0)); + uint32_t sa = 0x101 * (0xFF & (src_premul >> 24)); + uint32_t sr = 0x101 * (0xFF & (src_premul >> 16)); + uint32_t sg = 0x101 * (0xFF & (src_premul >> 8)); + uint32_t sb = 0x101 * (0xFF & (src_premul >> 0)); + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + da = sa + ((da * ia) / 0xFFFF); + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert from 16-bit color to 8-bit color. + da >>= 8; + dr >>= 8; + dg >>= 8; + db >>= 8; + + // Combine components. + return (db << 0) | (dg << 8) | (dr << 16) | (da << 24); } // -------- static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; +wuffs_private_impl__swizzle_squash_align4_bgr_565_8888(uint8_t* dst_ptr, + size_t dst_len, + const uint8_t* src_ptr, + size_t src_len, + bool nonpremul) { + size_t len = (dst_len < src_len ? dst_len : src_len) / 4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - uint8_t s3 = s[3]; - d[0] = s0; - d[1] = s0; - d[2] = s1; - d[3] = s1; - d[4] = s2; - d[5] = s2; - d[6] = s3; - d[7] = s3; - - s += 1 * 4; - d += 1 * 8; - n -= 1; + while (n--) { + uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s); + if (nonpremul) { + argb = + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb); + } + uint32_t b5 = 0x1F & (argb >> (8 - 5)); + uint32_t g6 = 0x3F & (argb >> (16 - 6)); + uint32_t r5 = 0x1F & (argb >> (24 - 5)); + uint32_t alpha = argb & 0xFF000000; + wuffs_base__poke_u32le__no_bounds_check( + d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0)); + s += 4; + d += 4; } return len; } +// -------- + static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; +wuffs_private_impl__swizzle_swap_rgb_bgr(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t len = (dst_len < src_len ? dst_len : src_len) / 3; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - - s += 1 * 4; - d += 1 * 8; - n -= 1; + while (n--) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s2; + d[1] = s1; + d[2] = s0; + s += 3; + d += 3; } return len; } +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len8 = src_len / 8; - size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8; +wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t len = (dst_len < src_len ? dst_len : src_len) / 4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; - size_t n = len; - while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - s += 1 * 8; - d += 1 * 8; - n -= 1; + __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E, // + +0x0B, +0x08, +0x09, +0x0A, // + +0x07, +0x04, +0x05, +0x06, // + +0x03, +0x00, +0x01, +0x02); + + while (n >= 4) { + __m128i x; + x = _mm_lddqu_si128((const __m128i*)(const void*)s); + x = _mm_shuffle_epi8(x, shuffle); + _mm_storeu_si128((__m128i*)(void*)d, x); + + s += 4 * 4; + d += 4 * 4; + n -= 4; + } + + while (n--) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + uint8_t s3 = s[3]; + d[0] = s2; + d[1] = s1; + d[2] = s0; + d[3] = s3; + s += 4; + d += 4; } return len; } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; +wuffs_private_impl__swizzle_swap_rgbx_bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t len = (dst_len < src_len ? dst_len : src_len) / 4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - while (n >= 1) { - uint64_t s0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); - wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0); - - s += 1 * 4; - d += 1 * 8; - n -= 1; + while (n--) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + uint8_t s3 = s[3]; + d[0] = s2; + d[1] = s1; + d[2] = s0; + d[3] = s3; + s += 4; + d += 4; } return len; } -static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - - size_t n = len; - while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0)); +// -------- - s += 1 * 4; - d += 1 * 8; - n -= 1; +static uint64_t // +wuffs_private_impl__swizzle_copy_1_1(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t len = (dst_len < src_len) ? dst_len : src_len; + if (len > 0) { + memmove(dst_ptr, src_ptr, len); } return len; } static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; +wuffs_private_impl__swizzle_copy_2_2(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len2 = src_len / 2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; + if (len > 0) { + memmove(dst_ptr, src_ptr, len * 2); } - size_t dst_len8 = dst_len / 8; - size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; - - while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); + return len; +} - s += 1 * 1; - d += 1 * 8; - n -= 1; +static uint64_t // +wuffs_private_impl__swizzle_copy_3_3(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len3 = src_len / 3; + size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3; + if (len > 0) { + memmove(dst_ptr, src_ptr, len * 3); } - return len; } static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; +wuffs_private_impl__swizzle_copy_4_4(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - - size_t n = len; - while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - uint8_t s3 = s[3]; - d[0] = s2; - d[1] = s2; - d[2] = s1; - d[3] = s1; - d[4] = s0; - d[5] = s0; - d[6] = s3; - d[7] = s3; - - s += 1 * 4; - d += 1 * 8; - n -= 1; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + if (len > 0) { + memmove(dst_ptr, src_ptr, len * 4); } return len; } static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_copy_8_8(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - - size_t n = len; - while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = - wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - - s += 1 * 4; - d += 1 * 8; - n -= 1; + size_t src_len8 = src_len / 8; + size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8; + if (len > 0) { + memmove(dst_ptr, src_ptr, len * 8); } return len; } +// -------- + static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; +wuffs_private_impl__swizzle_bgr_565__bgr(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len3 = src_len / 3; + size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; - size_t n = len; + + // TODO: unroll. + while (n >= 1) { - uint64_t s0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( - wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); - wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0); + uint32_t b5 = (uint32_t)(s[0] >> 3); + uint32_t g6 = (uint32_t)(s[1] >> 2); + uint32_t r5 = (uint32_t)(s[2] >> 3); + uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); - s += 1 * 4; - d += 1 * 8; + s += 1 * 3; + d += 1 * 2; n -= 1; } + return len; } static uint64_t // -wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; +wuffs_private_impl__swizzle_bgr_565__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; - size_t n = len; + + // TODO: unroll. + while (n >= 1) { - uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); - uint64_t s0 = - wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0)); + uint32_t b5 = (uint32_t)(s[0] >> 3); + uint32_t g6 = (uint32_t)(s[1] >> 2); + uint32_t r5 = (uint32_t)(s[2] >> 3); + uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); s += 1 * 4; - d += 1 * 8; + d += 1 * 2; n -= 1; } + return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src( +wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22217,13 +23221,14 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src( // TODO: unroll. while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); s += 1 * 4; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22231,16 +23236,16 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src( +wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22248,13 +23253,14 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src( // TODO: unroll. while (n >= 1) { - uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0)); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))))); s += 1 * 8; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22262,16 +23268,16 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over( +wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22279,13 +23285,38 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over( // TODO: unroll. while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)); + // Extract 16-bit color components. + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sr = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sb = 0x101 * ((uint32_t)s[0]); + + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); s += 1 * 4; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22293,16 +23324,16 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over( +wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22310,16 +23341,38 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over( // TODO: unroll. while (n >= 1) { - uint64_t d0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); - uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u64__as__color_u32( - wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0))); + // Extract 16-bit color components. + uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); + uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); + uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); + uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); + + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); s += 1 * 8; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22327,16 +23380,15 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; +wuffs_private_impl__swizzle_bgr_565__bgra_premul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22344,13 +23396,12 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over( // TODO: unroll. while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0)); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); s += 1 * 4; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22358,19 +23409,16 @@ wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over( +wuffs_private_impl__swizzle_bgr_565__bgra_premul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + size_t dst_len2 = dst_len / 2; + size_t src_len4 = src_len / 4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22378,14 +23426,38 @@ wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over( // TODO: unroll. while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)); + // Extract 16-bit color components. + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sr = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sb = 0x101 * ((uint32_t)s[0]); - s += 1 * 1; - d += 1 * 4; + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); + + s += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22393,16 +23465,15 @@ wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; +wuffs_private_impl__swizzle_bgr_565__rgb(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len3 = src_len / 3; + size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22410,14 +23481,14 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src( // TODO: unroll. while (n >= 1) { - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); + uint32_t r5 = (uint32_t)(s[0] >> 3); + uint32_t g6 = (uint32_t)(s[1] >> 2); + uint32_t b5 = (uint32_t)(s[2] >> 3); + uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); - s += 1 * 4; - d += 1 * 4; + s += 1 * 3; + d += 1 * 2; n -= 1; } @@ -22425,16 +23496,16 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over( +wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22442,14 +23513,15 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over( // TODO: unroll. while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))))); s += 1 * 4; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22457,16 +23529,16 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src( +wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + size_t dst_len2 = dst_len / 2; + size_t src_len4 = src_len / 4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22474,32 +23546,54 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src( // TODO: unroll. while (n >= 1) { - uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( - s0))); - - s += 1 * 8; - d += 1 * 4; - n -= 1; + // Extract 16-bit color components. + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sb = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sr = 0x101 * ((uint32_t)s[0]); + + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); + + s += 1 * 4; + d += 1 * 2; + n -= 1; } return len; } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over( - uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; +wuffs_private_impl__swizzle_bgr_565__rgba_premul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len4 = src_len / 4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22507,17 +23601,14 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over( // TODO: unroll. while (n >= 1) { - uint64_t d0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); - uint64_t s0 = wuffs_base__swap_u64_argb_abgr( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u64__as__color_u32( - wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0))); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); - s += 1 * 8; - d += 1 * 4; + s += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22525,47 +23616,70 @@ wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over( +wuffs_private_impl__swizzle_bgr_565__rgba_premul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len2 = dst_len / 2; size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); - uint32_t s0 = wuffs_base__swap_u32_argb_abgr( - wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0)); + // Extract 16-bit color components. + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sb = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sr = 0x101 * ((uint32_t)s[0]); + + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); s += 1 * 4; - d += 1 * 4; + d += 1 * 2; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len3 = src_len / 3; - size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; +wuffs_private_impl__swizzle_bgr_565__y(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22573,12 +23687,13 @@ wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - 0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3))); + uint32_t y5 = (uint32_t)(s[0] >> 3); + uint32_t y6 = (uint32_t)(s[0] >> 2); + uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); - s += 1 * 3; - d += 1 * 4; + s += 1 * 1; + d += 1 * 2; n -= 1; } @@ -22586,15 +23701,15 @@ wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; +wuffs_private_impl__swizzle_bgr_565__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; size_t src_len2 = src_len / 2; - size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22602,12 +23717,13 @@ wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))); + uint32_t y5 = (uint32_t)(s[0] >> 3); + uint32_t y6 = (uint32_t)(s[0] >> 2); + uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565); s += 1 * 2; - d += 1 * 4; + d += 1 * 2; n -= 1; } @@ -22615,15 +23731,15 @@ wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; +wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len2 = src_len / 2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22631,100 +23747,121 @@ wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); - s += 1 * 4; - d += 1 * 4; + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + s0))); + + s += 1 * 2; + d += 1 * 2; n -= 1; } return len; } -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") static uint64_t // -wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len3 = src_len / 3; - size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; +wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len2 = src_len / 2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B, // - +0x00, +0x06, +0x07, +0x08, // - +0x00, +0x03, +0x04, +0x05, // - +0x00, +0x00, +0x01, +0x02); - __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00); + // TODO: unroll. - while (n >= 6) { - __m128i x; - x = _mm_lddqu_si128((const __m128i*)(const void*)s); - x = _mm_shuffle_epi8(x, shuffle); - x = _mm_or_si128(x, or_ff); - _mm_storeu_si128((__m128i*)(void*)d, x); + while (n >= 1) { + // Extract 16-bit color components. + uint32_t sa = 0x101 * ((uint32_t)s[1]); + uint32_t sy = 0x101 * ((uint32_t)s[0]); - s += 4 * 3; - d += 4 * 4; - n -= 4; - } + // Convert from 565 color to 16-bit color. + uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)); + uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11); + uint32_t dr = (0x8421 * old_r5) >> 4; + uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5); + uint32_t dg = (0x1041 * old_g6) >> 2; + uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0); + uint32_t db = (0x8421 * old_b5) >> 4; - while (n >= 1) { - uint8_t b0 = s[0]; - uint8_t b1 = s[1]; - uint8_t b2 = s[2]; - d[0] = b2; - d[1] = b1; - d[2] = b0; - d[3] = 0xFF; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; - s += 1 * 3; - d += 1 * 4; + // Composite src (nonpremul) over dst (premul). + dr = ((sy * sa) + (dr * ia)) / 0xFFFF; + dg = ((sy * sa) + (dg * ia)) / 0xFFFF; + db = ((sy * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 565 color and combine the components. + uint32_t new_r5 = 0x1F & (dr >> 11); + uint32_t new_g6 = 0x3F & (dg >> 10); + uint32_t new_b5 = 0x1F & (db >> 11); + uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565); + + s += 1 * 2; + d += 1 * 2; n -= 1; } return len; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 static uint64_t // -wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len3 = src_len / 3; - size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; +wuffs_private_impl__swizzle_bgr_565__index__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len2 = dst_len / 2; + size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + const size_t loop_unroll_count = 4; + + while (n >= loop_unroll_count) { + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4))); + wuffs_base__poke_u16le__no_bounds_check( + d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check( + dst_palette_ptr + ((size_t)s[1] * 4))); + wuffs_base__poke_u16le__no_bounds_check( + d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check( + dst_palette_ptr + ((size_t)s[2] * 4))); + wuffs_base__poke_u16le__no_bounds_check( + d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check( + dst_palette_ptr + ((size_t)s[3] * 4))); + + s += loop_unroll_count * 1; + d += loop_unroll_count * 2; + n -= loop_unroll_count; + } + while (n >= 1) { - uint8_t b0 = s[0]; - uint8_t b1 = s[1]; - uint8_t b2 = s[2]; - d[0] = b2; - d[1] = b1; - d[2] = b0; - d[3] = 0xFF; + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4))); - s += 1 * 3; - d += 1 * 4; + s += 1 * 1; + d += 1 * 2; n -= 1; } @@ -22732,15 +23869,19 @@ wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len4 = src_len / 4; - size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; +wuffs_private_impl__swizzle_bgr_565__index_bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len2 = dst_len / 2; + size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22748,82 +23889,83 @@ wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - uint8_t b0 = s[0]; - uint8_t b1 = s[1]; - uint8_t b2 = s[2]; - d[0] = b2; - d[1] = b1; - d[2] = b0; - d[3] = 0xFF; + uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2))); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + wuffs_base__poke_u16le__no_bounds_check( + d + (0 * 2), + wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565( + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0))); - s += 1 * 4; - d += 1 * 4; + s += 1 * 1; + d += 1 * 2; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len3 = src_len / 3; - size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3; +wuffs_private_impl__swizzle_bgr_565__index_binary_alpha__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len2 = dst_len / 2; + size_t len = (dst_len2 < src_len) ? dst_len2 : src_len; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s0; - d[1] = s0; - d[2] = s1; - d[3] = s1; - d[4] = s2; - d[5] = s2; - d[6] = 0xFF; - d[7] = 0xFF; + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0); + } - s += 1 * 3; - d += 1 * 8; + s += 1 * 1; + d += 1 * 2; n -= 1; } return len; } +// -------- + static uint64_t // -wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; +wuffs_private_impl__swizzle_bgr__bgr_565(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; size_t src_len2 = src_len / 2; - size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; + size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), - wuffs_base__color_u32__as__color_u64( - wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); + uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))); + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); s += 1 * 2; - d += 1 * 8; + d += 1 * 3; n -= 1; } @@ -22831,87 +23973,46 @@ wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; +wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; size_t src_len4 = src_len / 4; - size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s0; - d[1] = s0; - d[2] = s1; - d[3] = s1; - d[4] = s2; - d[5] = s2; - d[6] = 0xFF; - d[7] = 0xFF; - - s += 1 * 4; - d += 1 * 8; - n -= 1; - } - - return len; -} - -static uint64_t // -wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len3 = src_len / 3; - size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3; - uint8_t* d = dst_ptr; - const uint8_t* s = src_ptr; - size_t n = len; + // TODO: unroll. while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - uint8_t s2 = s[2]; - d[0] = s2; - d[1] = s2; - d[2] = s1; - d[3] = s1; - d[4] = s0; - d[5] = s0; - d[6] = 0xFF; - d[7] = 0xFF; + uint32_t s0 = + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - s += 1 * 3; - d += 1 * 8; + s += 1 * 4; + d += 1 * 3; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len3 = dst_len / 3; - size_t src_len2 = src_len / 2; - size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + size_t src_len8 = src_len / 8; + size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -22919,13 +24020,12 @@ wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u24le__no_bounds_check( - d + (0 * 3), - wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); + uint32_t s0 = + wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - s += 1 * 2; + s += 1 * 8; d += 1 * 3; n -= 1; } @@ -22933,154 +24033,200 @@ wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t* dst_ptr, return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src( +wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + size_t dst_len3 = dst_len / 3; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; - size_t n = len; + + // TODO: unroll. + while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sr = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sb = 0x101 * ((uint32_t)s[0]); - s += 1 * 8; - d += 1 * 4; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); + + s += 1 * 4; + d += 1 * 3; n -= 1; } + return len; } static uint64_t // -wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over( +wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - size_t dst_len4 = dst_len / 4; + size_t dst_len3 = dst_len / 3; size_t src_len8 = src_len / 8; - size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - uint64_t d0 = wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); - uint64_t s0 = wuffs_base__swap_u64_argb_abgr( - wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__color_u64__as__color_u32( - wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0))); + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); + uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); + uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); + uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); + + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); s += 1 * 8; - d += 1 * 4; + d += 1 * 3; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len4 = dst_len / 4; - size_t src_len2 = src_len / 2; - size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; +wuffs_private_impl__swizzle_bgr__bgra_premul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - // TODO: unroll. - while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), - wuffs_base__swap_u32_argb_abgr( - wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( - wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s0; + d[1] = s1; + d[2] = s2; - s += 1 * 2; - d += 1 * 4; + s += 1 * 4; + d += 1 * 3; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } +wuffs_private_impl__swizzle_bgr__bgra_premul__src_over(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len3 = dst_len / 3; - size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - const size_t loop_unroll_count = 4; + while (n >= 1) { + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sr = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sb = 0x101 * ((uint32_t)s[0]); - // The comparison in the while condition is ">", not ">=", because with - // ">=", the last 4-byte store could write past the end of the dst slice. - // - // Each 4-byte store writes one too many bytes, but a subsequent store - // will overwrite that with the correct byte. There is always another - // store, whether a 4-byte store in this loop or a 1-byte store in the - // next loop. - while (n > loop_unroll_count) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[1] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[2] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[3] * 4))); + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; - s += loop_unroll_count * 1; - d += loop_unroll_count * 3; - n -= loop_unroll_count; + // Composite src (premul) over dst (premul). + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); + + s += 1 * 4; + d += 1 * 3; + n -= 1; } + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + // TODO: unroll. + while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - s += 1 * 1; + s += 1 * 4; d += 1 * 3; n -= 1; } @@ -23089,19 +24235,16 @@ wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over( +wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } size_t dst_len3 = dst_len / 3; - size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + size_t src_len8 = src_len / 8; + size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -23109,14 +24252,12 @@ wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over( // TODO: unroll. while (n >= 1) { - uint32_t d0 = - wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000; - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - wuffs_base__poke_u24le__no_bounds_check( - d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - s += 1 * 1; + s += 1 * 8; d += 1 * 3; n -= 1; } @@ -23125,60 +24266,46 @@ wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over( +wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } size_t dst_len3 = dst_len / 3; - size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - const size_t loop_unroll_count = 4; + // TODO: unroll. - while (n >= loop_unroll_count) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - } - uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[1] * 4)); - if (s1) { - wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1); - } - uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[2] * 4)); - if (s2) { - wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2); - } - uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[3] * 4)); - if (s3) { - wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3); - } + while (n >= 1) { + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sb = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sr = 0x101 * ((uint32_t)s[0]); - s += loop_unroll_count * 1; - d += loop_unroll_count * 3; - n -= loop_unroll_count; - } + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; - while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - } + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; - s += 1 * 1; + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); + + s += 1 * 4; d += 1 * 3; n -= 1; } @@ -23187,15 +24314,16 @@ wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len3 = dst_len / 3; - size_t src_len4 = src_len / 4; - size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; @@ -23203,10 +24331,29 @@ wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr, // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u24le__no_bounds_check( - d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6)); + uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4)); + uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2)); + uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0)); - s += 1 * 4; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (nonpremul) over dst (premul). + dr = ((sr * sa) + (dr * ia)) / 0xFFFF; + dg = ((sg * sa) + (dg * ia)) / 0xFFFF; + db = ((sb * sa) + (db * ia)) / 0xFFFF; + + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); + + s += 1 * 8; d += 1 * 3; n -= 1; } @@ -23215,27 +24362,28 @@ wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgr__rgba_premul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len3 = dst_len / 3; - size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - // TODO: unroll. - while (n >= 1) { uint8_t s0 = s[0]; - d[0] = s0; - d[1] = s0; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s2; + d[1] = s1; d[2] = s0; - s += 1 * 1; + s += 1 * 4; d += 1 * 3; n -= 1; } @@ -23244,28 +24392,43 @@ wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgr__rgba_premul__src_over(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len3 = dst_len / 3; - size_t src_len2 = src_len / 2; - size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - // TODO: unroll. - while (n >= 1) { - uint8_t s0 = s[0]; - d[0] = s0; - d[1] = s0; - d[2] = s0; + // Extract 16-bit color components. + uint32_t dr = 0x101 * ((uint32_t)d[2]); + uint32_t dg = 0x101 * ((uint32_t)d[1]); + uint32_t db = 0x101 * ((uint32_t)d[0]); + uint32_t sa = 0x101 * ((uint32_t)s[3]); + uint32_t sb = 0x101 * ((uint32_t)s[2]); + uint32_t sg = 0x101 * ((uint32_t)s[1]); + uint32_t sr = 0x101 * ((uint32_t)s[0]); - s += 1 * 2; + // Calculate the inverse of the src-alpha: how much of the dst to keep. + uint32_t ia = 0xFFFF - sa; + + // Composite src (premul) over dst (premul). + dr = sr + ((dr * ia) / 0xFFFF); + dg = sg + ((dg * ia) / 0xFFFF); + db = sb + ((db * ia) / 0xFFFF); + + // Convert from 16-bit color to 8-bit color. + d[0] = (uint8_t)(db >> 8); + d[1] = (uint8_t)(dg >> 8); + d[2] = (uint8_t)(dr >> 8); + + s += 1 * 4; d += 1 * 3; n -= 1; } @@ -23273,114 +24436,63 @@ wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr, return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; +wuffs_private_impl__swizzle_bgr__rgbx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - const size_t loop_unroll_count = 4; - - while (n >= loop_unroll_count) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[1] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[2] * 4))); - wuffs_base__poke_u32le__no_bounds_check( - d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[3] * 4))); - - s += loop_unroll_count * 1; - d += loop_unroll_count * 4; - n -= loop_unroll_count; - } + // TODO: unroll. while (n >= 1) { - wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4))); + uint8_t b0 = s[0]; + uint8_t b1 = s[1]; + uint8_t b2 = s[2]; + d[0] = b2; + d[1] = b1; + d[2] = b0; - s += 1 * 1; - d += 1 * 4; + s += 1 * 4; + d += 1 * 3; n -= 1; } return len; } +// -------- + static uint64_t // -wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over( +wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; - const size_t loop_unroll_count = 4; - - while (n >= loop_unroll_count) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0); - } - uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[1] * 4)); - if (s1) { - wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1); - } - uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[2] * 4)); - if (s2) { - wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2); - } - uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[3] * 4)); - if (s3) { - wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3); - } - - s += loop_unroll_count * 1; - d += loop_unroll_count * 4; - n -= loop_unroll_count; - } - while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0); - } + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); - s += 1 * 1; + s += 1 * 4; d += 1 * 4; n -= 1; } @@ -23388,75 +24500,88 @@ wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over( return len; } -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") static uint64_t // -wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; + size_t n = len; + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), wuffs_base__color_u64__as__color_u32( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); - __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03, // - +0x02, +0x02, +0x02, +0x02, // - +0x01, +0x01, +0x01, +0x01, // - +0x00, +0x00, +0x00, +0x00); - __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00, // - -0x01, +0x00, +0x00, +0x00); - - while (n >= 4) { - __m128i x; - x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s))); - x = _mm_shuffle_epi8(x, shuffle); - x = _mm_or_si128(x, or_ff); - _mm_storeu_si128((__m128i*)(void*)d, x); - - s += 4 * 1; - d += 4 * 4; - n -= 4; + s += 1 * 8; + d += 1 * 4; + n -= 1; } + return len; +} + +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; while (n >= 1) { + uint64_t d0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); + uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); + d + (0 * 4), + wuffs_base__color_u64__as__color_u32( + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, + s0))); - s += 1 * 1; + s += 1 * 8; d += 1 * 4; n -= 1; } return len; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 static uint64_t // -wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len4 = dst_len / 4; - size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); + d + (0 * 4), + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0)); - s += 1 * 1; + s += 1 * 4; d += 1 * 4; n -= 1; } @@ -23465,24 +24590,28 @@ wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { size_t dst_len4 = dst_len / 4; - size_t src_len2 = src_len / 2; - size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); wuffs_base__poke_u32le__no_bounds_check( - d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_premul_u32_axxx(d0, s0)); - s += 1 * 2; + s += 1 * 4; d += 1 * 4; n -= 1; } @@ -23490,33 +24619,36 @@ wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr, return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { if (dst_palette_len != WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { return 0; } - size_t dst_len8 = dst_len / 8; - size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), wuffs_base__color_u32__as__color_u64( - wuffs_base__peek_u32le__no_bounds_check( - dst_palette_ptr + ((size_t)s[0] * 4)))); + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); s += 1 * 1; - d += 1 * 8; + d += 1 * 4; n -= 1; } @@ -23524,33 +24656,30 @@ wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over( +wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, const uint8_t* src_ptr, size_t src_len) { - if (dst_palette_len != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return 0; - } - size_t dst_len8 = dst_len / 8; - size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; while (n >= 1) { - uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + - ((size_t)s[0] * 4)); - if (s0) { - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0)); - } + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); - s += 1 * 1; - d += 1 * 8; + s += 1 * 4; + d += 1 * 4; n -= 1; } @@ -23558,24 +24687,29 @@ wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over( } static uint64_t // -wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; +wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; while (n >= 1) { - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0])); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0)); - s += 1 * 1; - d += 1 * 8; + s += 1 * 4; + d += 1 * 4; n -= 1; } @@ -23583,53 +24717,59 @@ wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len8 = dst_len / 8; - size_t src_len2 = src_len / 2; - size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; +wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; while (n >= 1) { - uint64_t s0 = - ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2)))); - wuffs_base__poke_u64le__no_bounds_check( - d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0)); + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_premul_u32_axxx(d0, s0)); - s += 1 * 2; - d += 1 * 8; + s += 1 * 4; + d += 1 * 4; n -= 1; } return len; } -// -------- - static uint64_t // -wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { +wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; size_t src_len2 = src_len / 2; - size_t len = (dst_len < src_len2) ? dst_len : src_len2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - d[0] = s[0]; + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0); s += 1 * 2; - d += 1 * 1; + d += 1 * 4; n -= 1; } @@ -23637,27 +24777,31 @@ wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr, } static uint64_t // -wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr, - size_t dst_len, - uint8_t* dst_palette_ptr, - size_t dst_palette_len, - const uint8_t* src_ptr, - size_t src_len) { - size_t dst_len2 = dst_len / 2; +wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; size_t src_len2 = src_len / 2; - size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; uint8_t* d = dst_ptr; const uint8_t* s = src_ptr; size_t n = len; + // TODO: unroll. + while (n >= 1) { - uint8_t s0 = s[0]; - uint8_t s1 = s[1]; - d[0] = s1; - d[1] = s0; + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0)); s += 1 * 2; - d += 1 * 2; + d += 1 * 4; n -= 1; } @@ -23667,6862 +24811,6000 @@ wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr, // -------- static uint64_t // -wuffs_base__pixel_swizzler__transparent_black_src( +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, - uint64_t num_pixels, - uint32_t dst_pixfmt_bytes_per_pixel) { - uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel; - if (n > num_pixels) { - n = num_pixels; + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + + size_t n = len; + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + uint8_t s3 = s[3]; + d[0] = s0; + d[1] = s0; + d[2] = s1; + d[3] = s1; + d[4] = s2; + d[5] = s2; + d[6] = s3; + d[7] = s3; + + s += 1 * 4; + d += 1 * 8; + n -= 1; } - memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel))); - return n; + return len; } static uint64_t // -wuffs_base__pixel_swizzler__transparent_black_src_over( +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src_over( uint8_t* dst_ptr, size_t dst_len, uint8_t* dst_palette_ptr, size_t dst_palette_len, - uint64_t num_pixels, - uint32_t dst_pixfmt_bytes_per_pixel) { - uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel; - if (n > num_pixels) { - n = num_pixels; + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); + + s += 1 * 4; + d += 1 * 8; + n -= 1; } - return n; + return len; } -// -------- +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len8 = src_len / 8; + size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__Y: - return wuffs_base__pixel_swizzler__copy_1_1; + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__bgr_565__y; + s += 1 * 8; + d += 1 * 8; + n -= 1; + } + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR: - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__xxx__y; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__xxxx__y__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__xxxx__y; + size_t n = len; + while (n >= 1) { + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); + wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE: - return wuffs_base__pixel_swizzler__xxxxxxxx__y; + s += 1 * 4; + d += 1 * 8; + n -= 1; } - return NULL; + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__Y: - return wuffs_base__pixel_swizzler__y__y_16be; - - case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: - return wuffs_base__pixel_swizzler__y_16le__y_16be; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: - return wuffs_base__pixel_swizzler__copy_2_2; + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_premul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__bgr_565__y_16be; + s += 1 * 4; + d += 1 * 8; + n -= 1; + } + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR: - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__xxx__y_16be; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len8 = dst_len / 8; + size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - return wuffs_base__pixel_swizzler__xxxx__y_16be; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE: - return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be; + s += 1 * 1; + d += 1 * 8; + n -= 1; } - return NULL; -} -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_1_1; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888( - dst_palette.ptr, dst_palette.len, src_palette.ptr, - src_palette.len, true) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__bgr_565__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over; - } - return NULL; + size_t n = len; + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + uint8_t s3 = s[3]; + d[0] = s2; + d[1] = s2; + d[2] = s1; + d[3] = s1; + d[4] = s0; + d[5] = s0; + d[6] = s3; + d[7] = s3; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over; - } - return NULL; - - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxxxxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over; - } - return NULL; - - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over; - } - return NULL; - - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over; - } - return NULL; + s += 1 * 4; + d += 1 * 8; + n -= 1; + } + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over; - } - return NULL; + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - // TODO. - break; + s += 1 * 4; + d += 1 * 8; + n -= 1; } - return NULL; + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_1_1; - } - return NULL; - - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888( - dst_palette.ptr, dst_palette.len, src_palette.ptr, - src_palette.len, false) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over; - } - return NULL; + size_t n = len; + while (n >= 1) { + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul( + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))); + wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over; - } - return NULL; + s += 1 * 4; + d += 1 * 8; + n -= 1; + } + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: - if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) != - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxxxxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__RGB: - if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over; - } - return NULL; + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = wuffs_base__color_u32__as__color_u64( + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_premul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx( - dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, - src_palette.len) != - (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { - return NULL; - } - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__xxxx__index__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over; - } - return NULL; + s += 1 * 4; + d += 1 * 8; + n -= 1; } - return NULL; + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgr_565( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__copy_2_2; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len2 = src_len / 2; + size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - return wuffs_base__pixel_swizzler__bgr__bgr_565; + size_t n = len; + while (n >= 1) { + uint64_t s0 = ((uint64_t)(s[1]) * 0x0101000000000000) | + ((uint64_t)(s[0]) * 0x0000010101010101); + wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - return wuffs_base__pixel_swizzler__bgrw__bgr_565; + s += 1 * 2; + d += 1 * 8; + n -= 1; + } + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: - return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565; +static uint64_t // +wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len2 = src_len / 2; + size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__rgb__bgr_565; + size_t n = len; + while (n >= 1) { + uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8)); + uint64_t s0 = ((uint64_t)(s[1]) * 0x0101000000000000) | + ((uint64_t)(s[0]) * 0x0000010101010101); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - return wuffs_base__pixel_swizzler__rgbw__bgr_565; + s += 1 * 2; + d += 1 * 8; + n -= 1; } - return NULL; + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__bgr_565__bgr; - - case WUFFS_BASE__PIXEL_FORMAT__BGR: - return wuffs_base__pixel_swizzler__copy_3_3; +// -------- - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - return wuffs_base__pixel_swizzler__bgrw__bgr; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: - return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__swap_rgb_bgr; + while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__bgrw__rgb; + s += 1 * 4; + d += 1 * 4; + n -= 1; } - return NULL; -} -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgra_nonpremul( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_4_4; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over; - } - return NULL; + while (n >= 1) { + uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over; - } - return NULL; + s += 1 * 8; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - // TODO. - break; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over; - } - return NULL; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - // TODO. - break; + s += 1 * 4; + d += 1 * 4; + n -= 1; } - return NULL; + + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over; - } - return NULL; + while (n >= 1) { + uint64_t d0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); + uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u64__as__color_u32( + wuffs_private_impl__composite_premul_nonpremul_u64_axxx(d0, s0))); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_8_8; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over; - } - return NULL; - - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over; - } - return NULL; + s += 1 * 8; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - // TODO. - break; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over; - } - break; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over; - } - return NULL; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_premul_u32_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - // TODO. - break; + s += 1 * 4; + d += 1 * 4; + n -= 1; } - return NULL; -} -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgra_premul( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over; - } - return NULL; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_4_4; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over; - } - return NULL; + s += 1 * 1; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over; - } - return NULL; - } - return NULL; -} + // TODO: unroll. -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__bgr_565__bgrx; + while (n >= 1) { + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGR: - return wuffs_base__pixel_swizzler__xxx__xxxx; + s += 1 * 4; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - return wuffs_base__pixel_swizzler__bgrw__bgrx; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - return wuffs_base__pixel_swizzler__copy_4_4; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__bgr__rgbx; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - return wuffs_base__pixel_swizzler__bgrw__rgbx; + s += 1 * 4; + d += 1 * 4; + n -= 1; } - return NULL; -} -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - return wuffs_base__pixel_swizzler__bgr_565__rgb; - - case WUFFS_BASE__PIXEL_FORMAT__BGR: - return wuffs_base__pixel_swizzler__swap_rgb_bgr; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__bgrw__rgb; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGB: - return wuffs_base__pixel_swizzler__copy_3_3; + while (n >= 1) { + uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul( + s0))); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - return wuffs_base__pixel_swizzler__bgrw__bgr; + s += 1 * 8; + d += 1 * 4; + n -= 1; } - return NULL; -} - -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__rgba_nonpremul( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over; - } - return NULL; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over; - } - return NULL; + while (n >= 1) { + uint64_t d0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); + uint64_t s0 = wuffs_private_impl__swap_u64_argb_abgr( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u64__as__color_u32( + wuffs_private_impl__composite_premul_nonpremul_u64_axxx(d0, s0))); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - // TODO. - break; + s += 1 * 8; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_4_4; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over; - } - return NULL; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_premul_u32_axxx(d0, s0)); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - // TODO. - break; + s += 1 * 4; + d += 1 * 4; + n -= 1; } - return NULL; + + return len; } -static wuffs_base__pixel_swizzler__func // -wuffs_base__pixel_swizzler__prepare__rgba_premul( - wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - switch (dst_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len2 = src_len / 2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over; - } - return NULL; + while (n >= 1) { + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over; - } - return NULL; + s += 1 * 2; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - if (wuffs_base__cpu_arch__have_x86_sse42()) { - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42; - } -#endif - return wuffs_base__pixel_swizzler__swap_rgbx_bgrx; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over; - } - return NULL; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__RGB: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgr__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over; - } - return NULL; +static uint64_t // +wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len2 = src_len / 2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over; - } - return NULL; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - return wuffs_base__pixel_swizzler__copy_4_4; - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over; - } - return NULL; + while (n >= 1) { + uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)); + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); + + s += 1 * 2; + d += 1 * 4; + n -= 1; } - return NULL; + + return len; } // -------- -WUFFS_BASE__MAYBE_STATIC wuffs_base__status // -wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p, - wuffs_base__pixel_format dst_pixfmt, - wuffs_base__slice_u8 dst_palette, - wuffs_base__pixel_format src_pixfmt, - wuffs_base__slice_u8 src_palette, - wuffs_base__pixel_blend blend) { - if (!p) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - p->private_impl.func = NULL; - p->private_impl.transparent_black_func = NULL; - p->private_impl.dst_pixfmt_bytes_per_pixel = 0; - p->private_impl.src_pixfmt_bytes_per_pixel = 0; +static uint64_t // +wuffs_private_impl__swizzle_bgrw__bgr(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len3 = src_len / 3; + size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - wuffs_base__pixel_swizzler__func func = NULL; - wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func = - NULL; + // TODO: unroll. - uint32_t dst_pixfmt_bits_per_pixel = - wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt); - if ((dst_pixfmt_bits_per_pixel == 0) || - ((dst_pixfmt_bits_per_pixel & 7) != 0)) { - return wuffs_base__make_status( - wuffs_base__error__unsupported_pixel_swizzler_option); - } + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + 0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3))); - uint32_t src_pixfmt_bits_per_pixel = - wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt); - if ((src_pixfmt_bits_per_pixel == 0) || - ((src_pixfmt_bits_per_pixel & 7) != 0)) { - return wuffs_base__make_status( - wuffs_base__error__unsupported_pixel_swizzler_option); + s += 1 * 3; + d += 1 * 4; + n -= 1; } - // TODO: support many more formats. - - switch (blend) { - case WUFFS_BASE__PIXEL_BLEND__SRC: - transparent_black_func = - wuffs_base__pixel_swizzler__transparent_black_src; - break; + return len; +} - case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: - transparent_black_func = - wuffs_base__pixel_swizzler__transparent_black_src_over; - break; - } +static uint64_t // +wuffs_private_impl__swizzle_bgrw__bgr_565(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len2 = src_len / 2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - switch (src_pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__Y: - func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette, - src_palette, blend); - break; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: - func = wuffs_base__pixel_swizzler__prepare__y_16be( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))); - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + s += 1 * 2; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: - func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - func = wuffs_base__pixel_swizzler__prepare__bgr_565( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; +static uint64_t // +wuffs_private_impl__swizzle_bgrw__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__BGR: - func = wuffs_base__pixel_swizzler__prepare__bgr( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + // TODO: unroll. - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + s += 1 * 4; + d += 1 * 4; + n -= 1; + } - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - func = wuffs_base__pixel_swizzler__prepare__bgra_premul( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + return len; +} - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - func = wuffs_base__pixel_swizzler__prepare__bgrx( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +static uint64_t // +wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len3 = src_len / 3; + size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - case WUFFS_BASE__PIXEL_FORMAT__RGB: - func = wuffs_base__pixel_swizzler__prepare__rgb( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + __m128i shuffle = _mm_set_epi8(+0x00, +0x0B, +0x0A, +0x09, // + +0x00, +0x08, +0x07, +0x06, // + +0x00, +0x05, +0x04, +0x03, // + +0x00, +0x02, +0x01, +0x00); + __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + while (n >= 6) { + __m128i x; + x = _mm_lddqu_si128((const __m128i*)(const void*)s); + x = _mm_shuffle_epi8(x, shuffle); + x = _mm_or_si128(x, or_ff); + _mm_storeu_si128((__m128i*)(void*)d, x); - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - func = wuffs_base__pixel_swizzler__prepare__rgba_premul( - p, dst_pixfmt, dst_palette, src_palette, blend); - break; + s += 4 * 3; + d += 4 * 4; + n -= 4; } - p->private_impl.func = func; - p->private_impl.transparent_black_func = transparent_black_func; - p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8; - p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8; - return wuffs_base__make_status( - func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option); -} + while (n >= 1) { + uint8_t b0 = s[0]; + uint8_t b1 = s[1]; + uint8_t b2 = s[2]; + d[0] = b0; + d[1] = b1; + d[2] = b2; + d[3] = 0xFF; -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( - const wuffs_base__pixel_swizzler* p, - uint32_t up_to_num_pixels, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - const uint8_t** ptr_iop_r, - const uint8_t* io2_r) { - if (p && p->private_impl.func) { - const uint8_t* iop_r = *ptr_iop_r; - uint64_t src_len = wuffs_base__u64__min( - ((uint64_t)up_to_num_pixels) * - ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel), - ((uint64_t)(io2_r - iop_r))); - uint64_t n = - (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, - dst_palette.len, iop_r, (size_t)src_len); - *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel; - return n; + s += 1 * 3; + d += 1 * 4; + n -= 1; } - return 0; -} -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( - const wuffs_base__pixel_swizzler* p, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - const uint8_t** ptr_iop_r, - const uint8_t* io2_r) { - if (p && p->private_impl.func) { - const uint8_t* iop_r = *ptr_iop_r; - uint64_t src_len = ((uint64_t)(io2_r - iop_r)); - uint64_t n = - (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, - dst_palette.len, iop_r, (size_t)src_len); - *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel; - return n; - } - return 0; + return len; } -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice( - const wuffs_base__pixel_swizzler* p, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - wuffs_base__slice_u8 src) { - if (p && p->private_impl.func) { - return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, - dst_palette.len, src.ptr, src.len); - } - return 0; -} +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +static uint64_t // +wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len3 = src_len / 3; + size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -WUFFS_BASE__MAYBE_STATIC uint64_t // -wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black( - const wuffs_base__pixel_swizzler* p, - wuffs_base__slice_u8 dst, - wuffs_base__slice_u8 dst_palette, - uint64_t num_pixels) { - if (p && p->private_impl.transparent_black_func) { - return (*p->private_impl.transparent_black_func)( - dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels, - p->private_impl.dst_pixfmt_bytes_per_pixel); + __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B, // + +0x00, +0x06, +0x07, +0x08, // + +0x00, +0x03, +0x04, +0x05, // + +0x00, +0x00, +0x01, +0x02); + __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00); + + while (n >= 6) { + __m128i x; + x = _mm_lddqu_si128((const __m128i*)(const void*)s); + x = _mm_shuffle_epi8(x, shuffle); + x = _mm_or_si128(x, or_ff); + _mm_storeu_si128((__m128i*)(void*)d, x); + + s += 4 * 3; + d += 4 * 4; + n -= 4; } - return 0; -} -// -------- + while (n >= 1) { + uint8_t b0 = s[0]; + uint8_t b1 = s[1]; + uint8_t b2 = s[2]; + d[0] = b2; + d[1] = b1; + d[2] = b0; + d[3] = 0xFF; -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2); + s += 1 * 3; + d += 1 * 4; + n -= 1; + } -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2); + return len; +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -#if defined(__GNUC__) && !defined(__clang__) -// No-op. -#else -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column, - bool last_column); -#endif -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) +static uint64_t // +wuffs_private_impl__swizzle_bgrw__rgb(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len3 = src_len / 3; + size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -// -------- + while (n >= 1) { + uint8_t b0 = s[0]; + uint8_t b1 = s[1]; + uint8_t b2 = s[2]; + d[0] = b2; + d[1] = b1; + d[2] = b0; + d[3] = 0xFF; -static inline uint32_t // -wuffs_base__u32__max_of_4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { - return wuffs_base__u32__max( // - wuffs_base__u32__max(a, b), // - wuffs_base__u32__max(c, d)); -} + s += 1 * 3; + d += 1 * 4; + n -= 1; + } -static inline uint32_t // -wuffs_base__u32__min_of_5(uint32_t a, - uint32_t b, - uint32_t c, - uint32_t d, - uint32_t e) { - return wuffs_base__u32__min( // - wuffs_base__u32__min( // - wuffs_base__u32__min(a, b), // - wuffs_base__u32__min(c, d)), // - e); + return len; } -// -------- +static uint64_t // +wuffs_private_impl__swizzle_bgrw__rgbx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len4 = src_len / 4; + size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func)( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2, - const uint8_t* up3); + // TODO: unroll. -static void // -wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2, - const uint8_t* up3) { - for (; x < x_end; x++) { - // It's called CMYK but, but for Adobe CMYK JPEG images in practice, it's - // RGBW: 0xFFu means no ink instead of full ink. Note that a double - // inversion is a no-op, so inversions might be implicit in the code below. - uint32_t r = ((uint32_t)(*up0++)); - uint32_t g = ((uint32_t)(*up1++)); - uint32_t b = ((uint32_t)(*up2++)); - uint32_t w = ((uint32_t)(*up3++)); - r = ((r * w) + 0x7Fu) / 0xFFu; - g = ((g * w) + 0x7Fu) / 0xFFu; - b = ((b * w) + 0x7Fu) / 0xFFu; - wuffs_base__pixel_buffer__set_color_u32_at( - dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u)); - } -} + while (n >= 1) { + uint8_t b0 = s[0]; + uint8_t b1 = s[1]; + uint8_t b2 = s[2]; + d[0] = b2; + d[1] = b1; + d[2] = b0; + d[3] = 0xFF; -static void // -wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2, - const uint8_t* up3) { - for (; x < x_end; x++) { - // We invert once again: 0xFFu means no ink instead of full ink. - uint32_t color = // - wuffs_base__color_ycc__as__color_u32( // - *up0++, *up1++, *up2++); - uint32_t r = 0xFFu - (0xFFu & (color >> 16u)); - uint32_t g = 0xFFu - (0xFFu & (color >> 8u)); - uint32_t b = 0xFFu - (0xFFu & (color >> 0u)); - uint32_t w = ((uint32_t)(*up3++)); - r = ((r * w) + 0x7Fu) / 0xFFu; - g = ((g * w) + 0x7Fu) / 0xFFu; - b = ((b * w) + 0x7Fu) / 0xFFu; - wuffs_base__pixel_buffer__set_color_u32_at( - dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u)); + s += 1 * 4; + d += 1 * 4; + n -= 1; } + + return len; } // -------- -typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func)( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2); +static uint64_t // +wuffs_private_impl__swizzle_bgrw_4x16le__bgr(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len3 = src_len / 3; + size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -static void // -wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - for (; x < x_end; x++) { - uint32_t color = 0xFF000000u | // - (((uint32_t)(*up0++)) << 16u) | // - (((uint32_t)(*up1++)) << 8u) | // - (((uint32_t)(*up2++)) << 0u); - wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color); - } -} + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s0; + d[1] = s0; + d[2] = s1; + d[3] = s1; + d[4] = s2; + d[5] = s2; + d[6] = 0xFF; + d[7] = 0xFF; -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - for (; x < x_end; x++) { - uint32_t color = // - wuffs_base__color_ycc__as__color_u32( // - *up0++, *up1++, *up2++); - wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color); + s += 1 * 3; + d += 1 * 8; + n -= 1; } -} - -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - size_t dst_stride = dst->private_impl.planes[0].stride; - uint8_t* dst_iter = dst->private_impl.planes[0].ptr + - (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); - for (; x < x_end; x++) { - uint32_t color = // - wuffs_base__color_ycc__as__color_u32( // - *up0++, *up1++, *up2++); - wuffs_base__poke_u32le__no_bounds_check(dst_iter, color); - dst_iter += 4u; - } + return len; } -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - size_t dst_stride = dst->private_impl.planes[0].stride; - uint8_t* dst_iter = dst->private_impl.planes[0].ptr + - (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); +static uint64_t // +wuffs_private_impl__swizzle_bgrw_4x16le__bgr_565(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len2 = src_len / 2; + size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - for (; x < x_end; x++) { - uint32_t color = // - wuffs_base__color_ycc__as__color_u32_abgr( // - *up0++, *up1++, *up2++); - wuffs_base__poke_u32le__no_bounds_check(dst_iter, color); - dst_iter += 4u; + while (n >= 1) { + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), + wuffs_base__color_u32__as__color_u64( + wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); + + s += 1 * 2; + d += 1 * 8; + n -= 1; } + + return len; } -// -------- +static uint64_t // +wuffs_private_impl__swizzle_bgrw_4x16le__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len4 = src_len / 4; + size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -// wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upsamples to a -// destination slice at least 480 (YCCK) or 672 (YCC) bytes long and whose -// src_len (multiplied by 1, 2, 3 or 4) is positive but no more than that. This -// 480 or 672 length is just under 1/4 or 1/3 of the scratch_buffer_2k slice -// length. Both (480 * 4) = 1920 and (672 * 3) = 2016 are less than 2048. -// -// 480 and 672 are nice round numbers because a JPEG MCU is 1, 2, 3 or 4 blocks -// wide and each block is 8 pixels wide. We have: -// 480 = 1 * 8 * 60, 672 = 1 * 8 * 84 -// 480 = 2 * 8 * 30, 672 = 2 * 8 * 42 -// 480 = 3 * 8 * 20, 672 = 3 * 8 * 28 -// 480 = 4 * 8 * 15, 672 = 4 * 8 * 21 -// -// Box filters are equivalent to nearest neighbor upsampling. These ignore the -// src_ptr_minor, h1v2_bias, first_column and last_column arguments. -// -// Triangle filters use a 3:1 ratio (in 1 dimension), or 9:3:3:1 (in 2 -// dimensions), which is higher quality (less blocky) but also higher -// computational effort. -// -// In theory, we could use triangle filters for any (inv_h, inv_v) combination. -// In practice, matching libjpeg-turbo, we only implement it for the common -// chroma subsampling ratios (YCC420, YCC422 or YCC440), corresponding to an -// (inv_h, inv_v) pair of (2, 2), (2, 1) or (1, 2). -typedef const uint8_t* ( - *wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func)( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, // Nearest row. - const uint8_t* src_ptr_minor, // Adjacent row, alternating above or below. - size_t src_len, - uint32_t h1v2_bias, - bool first_column, - bool last_column); + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s0; + d[1] = s0; + d[2] = s1; + d[3] = s1; + d[4] = s2; + d[5] = s2; + d[6] = 0xFF; + d[7] = 0xFF; -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor_ignored, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column_ignored, - bool last_column_ignored) { - return src_ptr_major; + s += 1 * 4; + d += 1 * 8; + n -= 1; + } + + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor_ignored, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column_ignored, - bool last_column_ignored) { - uint8_t* dp = dst_ptr; - const uint8_t* sp = src_ptr_major; - while (src_len--) { - uint8_t sv = *sp++; - *dp++ = sv; - *dp++ = sv; +static uint64_t // +wuffs_private_impl__swizzle_bgrw_4x16le__rgb(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len3 = src_len / 3; + size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + uint8_t s2 = s[2]; + d[0] = s2; + d[1] = s2; + d[2] = s1; + d[3] = s1; + d[4] = s0; + d[5] = s0; + d[6] = 0xFF; + d[7] = 0xFF; + + s += 1 * 3; + d += 1 * 8; + n -= 1; } - return dst_ptr; + + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor_ignored, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column_ignored, - bool last_column_ignored) { - uint8_t* dp = dst_ptr; - const uint8_t* sp = src_ptr_major; - while (src_len--) { - uint8_t sv = *sp++; - *dp++ = sv; - *dp++ = sv; - *dp++ = sv; +// -------- + +static uint64_t // +wuffs_private_impl__swizzle_rgb__bgr_565(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len2 = src_len / 2; + size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + // TODO: unroll. + + while (n >= 1) { + wuffs_base__poke_u24le__no_bounds_check( + d + (0 * 3), + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); + + s += 1 * 2; + d += 1 * 3; + n -= 1; } - return dst_ptr; + + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box( +// -------- + +static uint64_t // +wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src( uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor_ignored, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column_ignored, - bool last_column_ignored) { - uint8_t* dp = dst_ptr; - const uint8_t* sp = src_ptr_major; - while (src_len--) { - uint8_t sv = *sp++; - *dp++ = sv; - *dp++ = sv; - *dp++ = sv; - *dp++ = sv; + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + + size_t n = len; + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__color_u64__as__color_u32__swap_u32_argb_abgr( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))); + + s += 1 * 8; + d += 1 * 4; + n -= 1; } - return dst_ptr; + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle( +static uint64_t // +wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src_over( uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor, - size_t src_len, - uint32_t h1v2_bias, - bool first_column, - bool last_column) { - uint8_t* dp = dst_ptr; - const uint8_t* sp_major = src_ptr_major; - const uint8_t* sp_minor = src_ptr_minor; - while (src_len--) { - *dp++ = (uint8_t)(((3u * ((uint32_t)(*sp_major++))) + // - (1u * ((uint32_t)(*sp_minor++))) + // - h1v2_bias) >> - 2u); + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len8 = src_len / 8; + size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; + + while (n >= 1) { + uint64_t d0 = wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4))); + uint64_t s0 = wuffs_private_impl__swap_u64_argb_abgr( + wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))); + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_base__color_u64__as__color_u32( + wuffs_private_impl__composite_nonpremul_nonpremul_u64_axxx(d0, + s0))); + + s += 1 * 8; + d += 1 * 4; + n -= 1; } - return dst_ptr; + + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column, - bool last_column) { - uint8_t* dp = dst_ptr; - const uint8_t* sp = src_ptr_major; +// -------- - if (first_column) { - src_len--; - if ((src_len <= 0u) && last_column) { - uint8_t sv = *sp++; - *dp++ = sv; - *dp++ = sv; - return dst_ptr; - } - uint32_t svp1 = sp[+1]; - uint8_t sv = *sp++; - *dp++ = sv; - *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svp1 + 2u) >> 2u); - if (src_len <= 0u) { - return dst_ptr; - } - } +static uint64_t // +wuffs_private_impl__swizzle_rgbw__bgr_565(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len2 = src_len / 2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - if (last_column) { - src_len--; - } + // TODO: unroll. - for (; src_len > 0u; src_len--) { - uint32_t svm1 = sp[-1]; - uint32_t svp1 = sp[+1]; - uint32_t sv3 = 3u * (uint32_t)(*sp++); - *dp++ = (uint8_t)((sv3 + svm1 + 1u) >> 2u); - *dp++ = (uint8_t)((sv3 + svp1 + 2u) >> 2u); - } + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), + wuffs_private_impl__swap_u32_argb_abgr( + wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul( + wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))))); - if (last_column) { - uint32_t svm1 = sp[-1]; - uint8_t sv = *sp++; - *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svm1 + 1u) >> 2u); - *dp++ = sv; + s += 1 * 2; + d += 1 * 4; + n -= 1; } - return dst_ptr; + return len; } -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column, - bool last_column) { - uint8_t* dp = dst_ptr; - const uint8_t* sp_major = src_ptr_major; - const uint8_t* sp_minor = src_ptr_minor; +// -------- - if (first_column) { - src_len--; - if ((src_len <= 0u) && last_column) { - uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + // - (4u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + 8u) >> 4u); - *dp++ = (uint8_t)((sv + 7u) >> 4u); - return dst_ptr; - } +static uint64_t // +wuffs_private_impl__swizzle_xxx__index__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len3 = dst_len / 3; + size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero. - uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero. - uint32_t sv_major_p1 = sp_major[+1]; - uint32_t sv_minor_p1 = sp_minor[+1]; + const size_t loop_unroll_count = 4; - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); - if (src_len <= 0u) { - return dst_ptr; - } - } + // The comparison in the while condition is ">", not ">=", because with + // ">=", the last 4-byte store could write past the end of the dst slice. + // + // Each 4-byte store writes one too many bytes, but a subsequent store + // will overwrite that with the correct byte. There is always another + // store, whether a 4-byte store in this loop or a 1-byte store in the + // next loop. + while (n > loop_unroll_count) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[1] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[2] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[3] * 4))); - if (last_column) { - src_len--; + s += loop_unroll_count * 1; + d += loop_unroll_count * 3; + n -= loop_unroll_count; } - for (; src_len > 0u; src_len--) { - uint32_t sv_major_m1 = sp_major[-1]; - uint32_t sv_minor_m1 = sp_minor[-1]; - uint32_t sv_major_p1 = sp_major[+1]; - uint32_t sv_minor_p1 = sp_minor[+1]; + while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + s += 1 * 1; + d += 1 * 3; + n -= 1; } - if (last_column) { - uint32_t sv_major_m1 = sp_major[-1]; - uint32_t sv_minor_m1 = sp_minor[-1]; - uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero. - uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero. + return len; +} - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); +static uint64_t // +wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; } + size_t dst_len3 = dst_len / 3; + size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - return dst_ptr; -} + // TODO: unroll. -// wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs is indexed by inv_h -// and then inv_v. -static const wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs[4][4] = { - { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box, - }, - { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box, - }, - { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box, - }, - { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box, - }, -}; + while (n >= 1) { + uint32_t d0 = + wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000; + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + wuffs_base__poke_u24le__no_bounds_check( + d + (0 * 3), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); -static inline uint32_t // -wuffs_base__pixel_swizzler__has_triangle_upsampler(uint32_t inv_h, - uint32_t inv_v) { - if (inv_h == 1u) { - return inv_v == 2u; - } else if (inv_h == 2u) { - return (inv_v == 1u) || (inv_v == 2u); + s += 1 * 1; + d += 1 * 3; + n -= 1; } - return false; + + return len; } -// -------- +static uint64_t // +wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len3 = dst_len / 3; + size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -// All of the wuffs_base__pixel_swizzler__swizzle_ycc__etc functions have -// preconditions. See all of the checks made in -// wuffs_base__pixel_swizzler__swizzle_ycck before calling these functions. For -// example, (width > 0) is a precondition, but there are many more. + const size_t loop_unroll_count = 4; -static void // -wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row( - wuffs_base__pixel_buffer* dst, - uint32_t width, - uint32_t y, - 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 h1v2_bias, - uint8_t* scratch_buffer_2k_ptr, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3, - wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) { - const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0); - const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1); - const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2); - const uint8_t* src3 = src_ptr3 + ((y / inv_v3) * (size_t)stride3); - uint32_t total_src_len0 = 0u; - uint32_t total_src_len1 = 0u; - uint32_t total_src_len2 = 0u; - uint32_t total_src_len3 = 0u; - - uint32_t x = 0u; - while (x < width) { - bool first_column = x == 0u; - uint32_t end = x + 480u; - if (end > width) { - end = width; + while (n >= loop_unroll_count) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); + } + uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[1] * 4)); + if (s1) { + wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1); + } + uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[2] * 4)); + if (s2) { + wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2); + } + uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[3] * 4)); + if (s3) { + wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3); } - 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; - total_src_len0 += src_len0; - total_src_len1 += src_len1; - total_src_len2 += src_len2; - total_src_len3 += src_len3; - - const uint8_t* src_ptr_x0 = src0 + (x / inv_h0); - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 480u), // - src_ptr_x0, // - src_ptr_x0, // - src_len0, // - h1v2_bias, // - first_column, // - (total_src_len0 >= half_width_for_2to1)); - - const uint8_t* src_ptr_x1 = src1 + (x / inv_h1); - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 480u), // - src_ptr_x1, // - src_ptr_x1, // - src_len1, // - h1v2_bias, // - first_column, // - (total_src_len1 >= half_width_for_2to1)); - - const uint8_t* src_ptr_x2 = src2 + (x / inv_h2); - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 480u), // - src_ptr_x2, // - src_ptr_x2, // - src_len2, // - h1v2_bias, // - first_column, // - (total_src_len2 >= half_width_for_2to1)); + s += loop_unroll_count * 1; + d += loop_unroll_count * 3; + n -= loop_unroll_count; + } - const uint8_t* src_ptr_x3 = src3 + (x / inv_h3); - const uint8_t* up3 = (*upfunc3)( // - scratch_buffer_2k_ptr + (3u * 480u), // - src_ptr_x3, // - src_ptr_x3, // - src_len3, // - h1v2_bias, // - first_column, // - (total_src_len3 >= half_width_for_2to1)); + while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0); + } - (*conv4func)(dst, x, end, y, up0, up1, up2, up3); - x = end; + s += 1 * 1; + d += 1 * 3; + n -= 1; } -} - -static void // -wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter( - 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, - 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_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4], - wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 = - (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 = - (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 = - (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3 = - (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u]; - // First row. - uint32_t h1v2_bias = 1u; - wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row( - dst, width, 0u, // - src_ptr0, src_ptr1, src_ptr2, src_ptr3, // - stride0, stride1, stride2, stride3, // - inv_h0, inv_h1, inv_h2, inv_h3, // - inv_v0, inv_v1, inv_v2, inv_v3, // - half_width_for_2to1, // - h1v2_bias, // - scratch_buffer_2k_ptr, // - upfunc0, upfunc1, upfunc2, upfunc3, conv4func); - h1v2_bias = 2u; + return len; +} - // Middle rows. - bool last_row = height == 2u * half_height_for_2to1; - uint32_t y_max_excl = last_row ? (height - 1u) : height; - uint32_t y; - for (y = 1u; y < 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) - ? src0_major - : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0)); - const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1); - const uint8_t* src1_minor = - (inv_v1 != 2u) - ? src1_major - : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1)); - const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2); - const uint8_t* src2_minor = - (inv_v2 != 2u) - ? src2_major - : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2)); - const uint8_t* src3_major = src_ptr3 + ((y / inv_v3) * (size_t)stride3); - const uint8_t* src3_minor = - (inv_v3 != 2u) - ? src3_major - : ((y & 1u) ? (src3_major + stride3) : (src3_major - stride3)); - uint32_t total_src_len0 = 0u; - uint32_t total_src_len1 = 0u; - uint32_t total_src_len2 = 0u; - uint32_t total_src_len3 = 0u; +static uint64_t // +wuffs_private_impl__swizzle_xxx__xxxx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len4 = src_len / 4; + size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - uint32_t x = 0u; - while (x < width) { - bool first_column = x == 0u; - uint32_t end = x + 480u; - if (end > width) { - end = width; - } + // TODO: unroll. - 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; - total_src_len0 += src_len0; - total_src_len1 += src_len1; - total_src_len2 += src_len2; - total_src_len3 += src_len3; + while (n >= 1) { + wuffs_base__poke_u24le__no_bounds_check( + d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 480u), // - src0_major + (x / inv_h0), // - src0_minor + (x / inv_h0), // - src_len0, // - h1v2_bias, // - first_column, // - (total_src_len0 >= half_width_for_2to1)); + s += 1 * 4; + d += 1 * 3; + n -= 1; + } - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 480u), // - src1_major + (x / inv_h1), // - src1_minor + (x / inv_h1), // - src_len1, // - h1v2_bias, // - first_column, // - (total_src_len1 >= half_width_for_2to1)); + return len; +} - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 480u), // - src2_major + (x / inv_h2), // - src2_minor + (x / inv_h2), // - src_len2, // - h1v2_bias, // - first_column, // - (total_src_len2 >= half_width_for_2to1)); +static uint64_t // +wuffs_private_impl__swizzle_xxx__y(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t len = (dst_len3 < src_len) ? dst_len3 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - const uint8_t* up3 = (*upfunc3)( // - scratch_buffer_2k_ptr + (3u * 480u), // - src3_major + (x / inv_h3), // - src3_minor + (x / inv_h3), // - src_len3, // - h1v2_bias, // - first_column, // - (total_src_len3 >= half_width_for_2to1)); + // TODO: unroll. - (*conv4func)(dst, x, end, y, up0, up1, up2, up3); - x = end; - } + while (n >= 1) { + uint8_t s0 = s[0]; + d[0] = s0; + d[1] = s0; + d[2] = s0; - h1v2_bias ^= 3u; + s += 1 * 1; + d += 1 * 3; + n -= 1; } - // Last row. - if (y_max_excl != height) { - wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row( - dst, width, height - 1u, // - src_ptr0, src_ptr1, src_ptr2, src_ptr3, // - stride0, stride1, stride2, stride3, // - inv_h0, inv_h1, inv_h2, inv_h3, // - inv_v0, inv_v1, inv_v2, inv_v3, // - half_width_for_2to1, // - h1v2_bias, // - scratch_buffer_2k_ptr, // - upfunc0, upfunc1, upfunc2, upfunc3, conv4func); - } + return len; } -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row( - wuffs_base__pixel_buffer* dst, - uint32_t width, - uint32_t y, - 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 h1v2_bias, - uint8_t* scratch_buffer_2k_ptr, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1, - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2, - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) { - const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0); - const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1); - const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2); - uint32_t total_src_len0 = 0u; - uint32_t total_src_len1 = 0u; - uint32_t total_src_len2 = 0u; - - uint32_t x = 0u; - while (x < width) { - bool first_column = x == 0u; - uint32_t end = x + 672u; - if (end > width) { - end = width; - } - - 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; - total_src_len0 += src_len0; - total_src_len1 += src_len1; - total_src_len2 += src_len2; - - const uint8_t* src_ptr_x0 = src0 + (x / inv_h0); - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 672u), // - src_ptr_x0, // - src_ptr_x0, // - src_len0, // - h1v2_bias, // - first_column, // - (total_src_len0 >= half_width_for_2to1)); +static uint64_t // +wuffs_private_impl__swizzle_xxx__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len2 = src_len / 2; + size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - const uint8_t* src_ptr_x1 = src1 + (x / inv_h1); - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 672u), // - src_ptr_x1, // - src_ptr_x1, // - src_len1, // - h1v2_bias, // - first_column, // - (total_src_len1 >= half_width_for_2to1)); + // TODO: unroll. - const uint8_t* src_ptr_x2 = src2 + (x / inv_h2); - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 672u), // - src_ptr_x2, // - src_ptr_x2, // - src_len2, // - h1v2_bias, // - first_column, // - (total_src_len2 >= half_width_for_2to1)); + while (n >= 1) { + uint8_t s0 = s[0]; + d[0] = s0; + d[1] = s0; + d[2] = s0; - (*conv3func)(dst, x, end, y, up0, up1, up2); - x = end; + s += 1 * 2; + d += 1 * 3; + n -= 1; } -} -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter( - 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_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4], - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 = - (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 = - (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 = - (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u]; + return len; +} - // First row. - uint32_t h1v2_bias = 1u; - wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row( - dst, width, 0u, // - 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); - h1v2_bias = 2u; +static uint64_t // +wuffs_private_impl__swizzle_xxx__ya_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len2 = src_len / 2; + size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // Middle rows. - bool last_row = height == 2u * half_height_for_2to1; - uint32_t y_max_excl = last_row ? (height - 1u) : height; - uint32_t y; - for (y = 1u; y < 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) - ? src0_major - : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0)); - const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1); - const uint8_t* src1_minor = - (inv_v1 != 2u) - ? src1_major - : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1)); - const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2); - const uint8_t* src2_minor = - (inv_v2 != 2u) - ? src2_major - : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2)); - uint32_t total_src_len0 = 0u; - uint32_t total_src_len1 = 0u; - uint32_t total_src_len2 = 0u; + // TODO: unroll. - uint32_t x = 0u; - while (x < width) { - bool first_column = x == 0u; - uint32_t end = x + 672u; - if (end > width) { - end = width; - } + while (n >= 1) { + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u24le__no_bounds_check( + d + (0 * 3), + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0)); - 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; - total_src_len0 += src_len0; - total_src_len1 += src_len1; - total_src_len2 += src_len2; + s += 1 * 2; + d += 1 * 3; + n -= 1; + } - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 672u), // - src0_major + (x / inv_h0), // - src0_minor + (x / inv_h0), // - src_len0, // - h1v2_bias, // - first_column, // - (total_src_len0 >= half_width_for_2to1)); + return len; +} - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 672u), // - src1_major + (x / inv_h1), // - src1_minor + (x / inv_h1), // - src_len1, // - h1v2_bias, // - first_column, // - (total_src_len1 >= half_width_for_2to1)); +static uint64_t // +wuffs_private_impl__swizzle_xxx__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len3 = dst_len / 3; + size_t src_len2 = src_len / 2; + size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 672u), // - src2_major + (x / inv_h2), // - src2_minor + (x / inv_h2), // - src_len2, // - h1v2_bias, // - first_column, // - (total_src_len2 >= half_width_for_2to1)); + // TODO: unroll. - (*conv3func)(dst, x, end, y, up0, up1, up2); - x = end; - } + while (n >= 1) { + uint32_t d0 = + wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000; + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + wuffs_base__poke_u24le__no_bounds_check( + d + (0 * 3), + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); - h1v2_bias ^= 3u; + s += 1 * 2; + d += 1 * 3; + n -= 1; } - // Last row. - if (y_max_excl != height) { - wuffs_base__pixel_swizzler__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, // - upfunc0, upfunc1, upfunc2, conv3func); - } + return len; } -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter( - 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_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4], - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) { - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 = - (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 = - (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u]; - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 = - (*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) { - uint32_t end = x + 672u; - if (end > width) { - end = width; - } +static uint64_t // +wuffs_private_impl__swizzle_xxxx__index__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - 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 size_t loop_unroll_count = 4; - const uint8_t* up0 = (*upfunc0)( // - scratch_buffer_2k_ptr + (0u * 672u), // - src0_major + (x / inv_h0), // - src0_major + (x / inv_h0), // - src_len0, // - 0u, false, false); + while (n >= loop_unroll_count) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[1] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[2] * 4))); + wuffs_base__poke_u32le__no_bounds_check( + d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[3] * 4))); - const uint8_t* up1 = (*upfunc1)( // - scratch_buffer_2k_ptr + (1u * 672u), // - src1_major + (x / inv_h1), // - src1_major + (x / inv_h1), // - src_len1, // - 0u, false, false); + s += loop_unroll_count * 1; + d += loop_unroll_count * 4; + n -= loop_unroll_count; + } - const uint8_t* up2 = (*upfunc2)( // - scratch_buffer_2k_ptr + (2u * 672u), // - src2_major + (x / inv_h2), // - src2_major + (x / inv_h2), // - src_len2, // - 0u, false, false); + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4))); - (*conv3func)(dst, x, end, y, up0, up1, up2); - x = end; - } + s += 1 * 1; + d += 1 * 4; + n -= 1; } -} -// -------- + return len; +} -// wuffs_base__pixel_swizzler__flattened_length is like -// wuffs_base__table__flattened_length but returns uint64_t (not size_t) and -// also accounts for subsampling. static uint64_t // -wuffs_base__pixel_swizzler__flattened_length(uint32_t width, - uint32_t height, - uint32_t stride, - uint32_t inv_h, - uint32_t inv_v) { - uint64_t scaled_width = (((uint64_t)width) + (inv_h - 1u)) / inv_h; - uint64_t scaled_height = (((uint64_t)height) + (inv_v - 1u)) / inv_v; - if (scaled_height <= 0u) { - return 0u; +wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; } - return ((scaled_height - 1u) * stride) + scaled_width; -} + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; -WUFFS_BASE__MAYBE_STATIC wuffs_base__status // -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, - wuffs_base__slice_u8 src0, - wuffs_base__slice_u8 src1, - wuffs_base__slice_u8 src2, - wuffs_base__slice_u8 src3, - uint32_t width0, - uint32_t width1, - uint32_t width2, - uint32_t width3, - uint32_t height0, - uint32_t height1, - uint32_t height2, - uint32_t height3, - uint32_t stride0, - uint32_t stride1, - uint32_t stride2, - uint32_t stride3, - uint8_t h0, - uint8_t h1, - uint8_t h2, - uint8_t h3, - uint8_t v0, - uint8_t v1, - uint8_t v2, - uint8_t v3, - bool is_rgb_or_cmyk, - bool triangle_filter_for_2to1, - 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)) || // - (scratch_buffer_2k.len < 2048u)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + const size_t loop_unroll_count = 4; + + while (n >= loop_unroll_count) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0); + } + uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[1] * 4)); + if (s1) { + wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1); + } + uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[2] * 4)); + if (s2) { + wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2); + } + uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[3] * 4)); + if (s3) { + wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3); + } + + s += loop_unroll_count * 1; + d += loop_unroll_count * 4; + n -= loop_unroll_count; } - if ((h3 != 0u) || (v3 != 0u)) { - if ((4u <= ((unsigned int)h3 - 1u)) || // - (4u <= ((unsigned int)v3 - 1u))) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + + while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0); } + + s += 1 * 1; + d += 1 * 4; + n -= 1; } - uint32_t max_incl_h = wuffs_base__u32__max_of_4(h0, h1, h2, h3); - uint32_t max_incl_v = wuffs_base__u32__max_of_4(v0, v1, v2, v3); + return len; +} - // Calculate the inverse h and v ratios. - // - // It also canonicalizes (h=2 and max_incl_h=4) as equivalent to (h=1 and - // max_incl_h=2). In both cases, the inv_h value is 2. - uint32_t inv_h0 = max_incl_h / h0; - uint32_t inv_h1 = max_incl_h / h1; - uint32_t inv_h2 = max_incl_h / h2; - uint32_t inv_h3 = h3 ? (max_incl_h / h3) : 0u; - uint32_t inv_v0 = max_incl_v / v0; - uint32_t inv_v1 = max_incl_v / v1; - uint32_t inv_v2 = max_incl_v / v2; - uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u; +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +static uint64_t // +wuffs_private_impl__swizzle_xxxx__y__x86_sse42(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - uint32_t half_width_for_2to1 = (width + 1u) / 2u; - uint32_t half_height_for_2to1 = (height + 1u) / 2u; - - width = wuffs_base__u32__min_of_5( // - width, // - width0 * inv_h0, // - width1 * inv_h1, // - width2 * inv_h2, // - wuffs_base__pixel_config__width(&dst->pixcfg)); - height = wuffs_base__u32__min_of_5( // - height, // - height0 * inv_v0, // - height1 * inv_v1, // - height2 * inv_v2, // - wuffs_base__pixel_config__height(&dst->pixcfg)); + __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03, // + +0x02, +0x02, +0x02, +0x02, // + +0x01, +0x01, +0x01, +0x01, // + +0x00, +0x00, +0x00, +0x00); + __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00, // + -0x01, +0x00, +0x00, +0x00); - if (((h0 * inv_h0) != max_incl_h) || // - ((h1 * inv_h1) != max_incl_h) || // - ((h2 * inv_h2) != max_incl_h) || // - ((v0 * inv_v0) != max_incl_v) || // - ((v1 * inv_v1) != max_incl_v) || // - ((v2 * inv_v2) != max_incl_v) || // - (src0.len < wuffs_base__pixel_swizzler__flattened_length( - width, height, stride0, inv_h0, inv_v0)) || - (src1.len < wuffs_base__pixel_swizzler__flattened_length( - width, height, stride1, inv_h1, inv_v1)) || - (src2.len < wuffs_base__pixel_swizzler__flattened_length( - width, height, stride2, inv_h2, inv_v2))) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((h3 != 0u) || (v3 != 0u)) { - if (((h3 * inv_h3) != max_incl_h) || // - ((v3 * inv_v3) != max_incl_v) || // - (src3.len < wuffs_base__pixel_swizzler__flattened_length( - width, height, stride3, inv_h3, inv_v3))) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - } + while (n >= 4) { + __m128i x; + x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s))); + x = _mm_shuffle_epi8(x, shuffle); + x = _mm_or_si128(x, or_ff); + _mm_storeu_si128((__m128i*)(void*)d, x); - if (wuffs_base__pixel_format__is_planar(&dst->pixcfg.private_impl.pixfmt)) { - // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO. - return wuffs_base__make_status( - wuffs_base__error__unsupported_pixel_swizzler_option); + s += 4 * 1; + d += 4 * 4; + n -= 4; } - switch (dst->pixcfg.private_impl.pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__Y: - case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: - case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: - case WUFFS_BASE__PIXEL_FORMAT__BGR_565: - case WUFFS_BASE__PIXEL_FORMAT__BGR: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: - case WUFFS_BASE__PIXEL_FORMAT__RGB: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: - break; + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); - default: - // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO. - return wuffs_base__make_status( - wuffs_base__error__unsupported_pixel_swizzler_option); + s += 1 * 1; + d += 1 * 4; + n -= 1; } - if ((width <= 0u) || (height <= 0u)) { - return wuffs_base__make_status(NULL); - } + return len; +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func = NULL; +static uint64_t // +wuffs_private_impl__swizzle_xxxx__y(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t len = (dst_len4 < src_len) ? dst_len4 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - if (is_rgb_or_cmyk) { - conv3func = &wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general; - } else { - switch (dst->pixcfg.private_impl.pixfmt.repr) { - case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__BGRX: -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) - if (wuffs_base__cpu_arch__have_x86_avx2()) { - conv3func = - &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2; - break; - } -#endif - conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx; - break; - case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: - case WUFFS_BASE__PIXEL_FORMAT__RGBX: -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) - if (wuffs_base__cpu_arch__have_x86_avx2()) { - conv3func = - &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2; - break; - } -#endif - conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx; - break; - default: - conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general; - break; - } + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); + + s += 1 * 1; + d += 1 * 4; + n -= 1; } - 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_base__pixel_swizzler__swizzle_ycc__upsample_func(*upfuncs)[4][4], - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) = - &wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter; - - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfuncs[4][4]; - memcpy(&upfuncs, &wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs, - sizeof upfuncs); + return len; +} - if (triangle_filter_for_2to1 && - (wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h0, inv_v0) || - wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h1, inv_v1) || - wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h2, inv_v2))) { - func = &wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter; - - upfuncs[0][1] = - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle; - upfuncs[1][0] = - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle; - upfuncs[1][1] = - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle; - -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -#if defined(__GNUC__) && !defined(__clang__) - // Don't use our AVX2 implementation for GCC (but do use it for clang). For - // some unknown reason, GCC performs noticably better on the non-SIMD - // version. Possibly because GCC's auto-vectorizer is smarter (just with - // SSE2, not AVX2) than our hand-written code, but that's just a guess. - // - // See commits 51bc60ef9298cb2efc1b29a9681191f66d49820d and - // cd769a0cdf1b5affee13f6089b995f3d39569cb4 for benchmark numbers. - // - // See also https://godbolt.org/z/MbhbPGEz4 for Debian Bullseye's clang 11 - // versus gcc 10, where only gcc auto-vectorizes, although later clang - // versions will also auto-vectorize. -#else - if (wuffs_base__cpu_arch__have_x86_avx2()) { - upfuncs[1][1] = - wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2; - } -#endif -#endif - } +static uint64_t // +wuffs_private_impl__swizzle_xxxx__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len4 = dst_len / 4; + size_t src_len2 = src_len / 2; + size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - if ((h3 != 0u) || (v3 != 0u)) { - wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func = - is_rgb_or_cmyk - ? &wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general - : &wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general; - wuffs_base__pixel_swizzler__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, // - scratch_buffer_2k.ptr, &upfuncs, conv4func); + while (n >= 1) { + wuffs_base__poke_u32le__no_bounds_check( + d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0])); - } 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, // - scratch_buffer_2k.ptr, &upfuncs, conv3func); + s += 1 * 2; + d += 1 * 4; + n -= 1; } - return wuffs_base__make_status(NULL); + return len; } // -------- -// ‼ WUFFS MULTI-FILE SECTION +x86_avx2 -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - if ((x + 32u) > x_end) { - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx( // - dst, x, x_end, y, up0, up1, up2); - return; +static uint64_t // +wuffs_private_impl__swizzle_xxxxxxxx__index__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; } + size_t dst_len8 = dst_len / 8; + size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - size_t dst_stride = dst->private_impl.planes[0].stride; - uint8_t* dst_iter = dst->private_impl.planes[0].ptr + - (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); - - // u0001 = u16x16 [0x0001 .. 0x0001] - // u00FF = u16x16 [0x00FF .. 0x00FF] - // uFF80 = u16x16 [0xFF80 .. 0xFF80] - // uFFFF = u16x16 [0xFFFF .. 0xFFFF] - const __m256i u0001 = _mm256_set1_epi16(+0x0001); - const __m256i u00FF = _mm256_set1_epi16(+0x00FF); - const __m256i uFF80 = _mm256_set1_epi16(-0x0080); - const __m256i uFFFF = _mm256_set1_epi16(-0x0001); + while (n >= 1) { + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), wuffs_base__color_u32__as__color_u64( + wuffs_base__peek_u32le__no_bounds_check( + dst_palette_ptr + ((size_t)s[0] * 4)))); - // p8000_p0000 = u16x16 [0x8000 0x0000 .. 0x8000 0x0000] - const __m256i p8000_p0000 = _mm256_set_epi16( // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000); + s += 1 * 1; + d += 1 * 8; + n -= 1; + } - // Per wuffs_base__color_ycc__as__color_u32, the formulae: - // - // R = Y + 1.40200 * Cr - // G = Y - 0.34414 * Cb - 0.71414 * Cr - // B = Y + 1.77200 * Cb - // - // When scaled by 1<<16: - // - // 0.34414 becomes 0x0581A = 22554. - // 0.71414 becomes 0x0B6D2 = 46802. - // 1.40200 becomes 0x166E9 = 91881. - // 1.77200 becomes 0x1C5A2 = 116130. - // - // Separate the integer and fractional parts, since we work with signed - // 16-bit SIMD lanes. The fractional parts range from -0.5 .. +0.5 (as - // floating-point) which is from -0x8000 .. +0x8000 (as fixed-point). - // - // -0x3A5E = -0x20000 + 0x1C5A2 The B:Cb factor. - // +0x66E9 = -0x10000 + 0x166E9 The R:Cr factor. - // -0x581A = +0x00000 - 0x0581A The G:Cb factor. - // +0x492E = +0x10000 - 0x0B6D2 The G:Cr factor. - const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E); - const __m256i p66E9 = _mm256_set1_epi16(+0x66E9); - const __m256i m581A_p492E = _mm256_set_epi16( // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A); + return len; +} - while (x < x_end) { - // Load chroma values in even and odd columns (the high 8 bits of each - // u16x16 element are zero) and then subtract 0x0080. - // - // cb_all = u8x32 [cb.00 cb.01 cb.02 cb.03 .. cb.1C cb.1D cb.1E cb.1F] - // cb_eve = i16x16 [cb.00-0x80 cb.02-0x80 .. cb.1C-0x80 cb.1E-0x80 ] - // cb_odd = i16x16 [cb.01-0x80 cb.03-0x80 .. cb.1D-0x80 cb.1F-0x80 ] - // - // Ditto for the cr_xxx Chroma-Red values. - __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1); - __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2); - __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF)); - __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF)); - __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8)); - __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8)); +static uint64_t // +wuffs_private_impl__swizzle_xxxxxxxx__index_binary_alpha__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + if (dst_palette_len != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return 0; + } + size_t dst_len8 = dst_len / 8; + size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // ---- + while (n >= 1) { + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr + + ((size_t)s[0] * 4)); + if (s0) { + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0)); + } - // Calculate: - // - // B-Y = (+1.77200 * Cb) as floating-point - // R-Y = (+1.40200 * Cr) as floating-point - // - // B-Y = ((0x2_0000 - 0x3A5E) * Cb) as fixed-point - // R-Y = ((0x1_0000 + 0x66E9) * Cr) as fixed-point - // - // B-Y = ((-0x3A5E * Cb) + ("2.0" * Cb)) - // R-Y = ((+0x66E9 * Cr) + ("1.0" * Cr)) + s += 1 * 1; + d += 1 * 8; + n -= 1; + } - // Multiply by m3A5E or p66E9, taking the high 16 bits. There's also a - // doubling (add x to itself), adding-of-1 and halving (shift right by 1). - // That makes multiply-and-take-high round to nearest (instead of down). - __m256i tmp_by_eve = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001), - 1); - __m256i tmp_by_odd = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001), - 1); - __m256i tmp_ry_eve = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001), - 1); - __m256i tmp_ry_odd = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001), - 1); + return len; +} - // Add (2 * Cb) and (1 * Cr). - __m256i by_eve = - _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve)); - __m256i by_odd = - _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd)); - __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve); - __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd); +static uint64_t // +wuffs_private_impl__swizzle_xxxxxxxx__y(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t len = (dst_len8 < src_len) ? dst_len8 : src_len; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // ---- + while (n >= 1) { + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0])); - // Calculate: - // - // G-Y = (-0.34414 * Cb) + - // (-0.71414 * Cr) as floating-point - // - // G-Y = ((+0x0_0000 - 0x581A) * Cb) + - // ((-0x1_0000 + 0x492E) * Cr) as fixed-point - // - // G-Y = (-0x581A * Cb) + - // (+0x492E * Cr) - ("1.0" * Cr) + s += 1 * 1; + d += 1 * 8; + n -= 1; + } - // Multiply-add to get ((-0x581A * Cb) + (+0x492E * Cr)). - __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( // - _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E); - __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( // - _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E); - __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( // - _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E); - __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( // - _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E); + return len; +} - // Divide the i32x8 vectors by (1 << 16), rounding to nearest. - __m256i tmp1_gy_eve_lo = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16); - __m256i tmp1_gy_eve_hi = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16); - __m256i tmp1_gy_odd_lo = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16); - __m256i tmp1_gy_odd_hi = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16); +static uint64_t // +wuffs_private_impl__swizzle_xxxxxxxx__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len8 = dst_len / 8; + size_t src_len2 = src_len / 2; + size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // Pack the ((-0x581A * Cb) + (+0x492E * Cr)) as i16x16 and subtract Cr. - __m256i gy_eve = _mm256_sub_epi16( - _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve); - __m256i gy_odd = _mm256_sub_epi16( - _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd); + while (n >= 1) { + uint64_t s0 = + ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2)))); + wuffs_base__poke_u64le__no_bounds_check( + d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0)); - // ---- + s += 1 * 2; + d += 1 * 8; + n -= 1; + } - // Add Y to (B-Y), (G-Y) and (R-Y) to produce B, G and R. - // - // For the resultant packed_x_xxx vectors, only elements 0 ..= 7 and 16 ..= - // 23 of the 32-element vectors matter (since we'll unpacklo but not - // unpackhi them). Let … denote 8 ignored consecutive u8 values and let % - // denote 0xFF. We'll end this section with: - // - // packed_b_eve = u8x32 [b00 b02 .. b0C b0E … b10 b12 .. b1C b1E …] - // packed_b_odd = u8x32 [b01 b03 .. b0D b0F … b11 b13 .. b1D b1F …] - // packed_g_eve = u8x32 [g00 g02 .. g0C g0E … g10 g12 .. g1C g1E …] - // packed_g_odd = u8x32 [g01 g03 .. g0D g0F … g11 g13 .. g1D g1F …] - // packed_r_eve = u8x32 [r00 r02 .. r0C r0E … r10 r12 .. r1C r1E …] - // packed_r_odd = u8x32 [r01 r03 .. r0D r0F … r11 r13 .. r1D r1F …] - // uFFFF = u8x32 [ % % .. % % … % % .. % % …] + return len; +} - __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0); - __m256i yy_eve = _mm256_and_si256(yy_all, u00FF); - __m256i yy_odd = _mm256_srli_epi16(yy_all, 8); +// -------- - __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve); - __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd); - __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve); - __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd); +static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve); - __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd); - __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve); - __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd); + while (n >= 1) { + uint32_t s0 = + wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul( + wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); - __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve); - __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd); - __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve); - __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd); + s += 1 * 4; + d += 1 * 1; + n -= 1; + } - // ---- + return len; +} - // Mix those values (unpacking in 8, 16 and then 32 bit units) to get the - // desired BGRX/RGBX order. - // - // From here onwards, all of our __m256i registers are u8x32. +static uint64_t // +wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // mix00 = [b00 g00 b02 g02 .. b0E g0E b10 g10 .. b1C g1C b1E g1E] - // mix01 = [b01 g01 b03 g03 .. b0F g0F b11 g11 .. b1D g1D b1F g1F] - // mix02 = [r00 % r02 % .. r0E % r10 % .. r1C % r1E %] - // mix03 = [r01 % r03 % .. r0F % r11 % .. r1D % r1F %] - // - // See also § below. - __m256i mix00 = _mm256_unpacklo_epi8(packed_b_eve, packed_g_eve); - __m256i mix01 = _mm256_unpacklo_epi8(packed_b_odd, packed_g_odd); - __m256i mix02 = _mm256_unpacklo_epi8(packed_r_eve, uFFFF); - __m256i mix03 = _mm256_unpacklo_epi8(packed_r_odd, uFFFF); + while (n >= 1) { + uint32_t d0 = 0xFF000000 | (0x00010101 * ((uint32_t)(d[0]))); + uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray( + wuffs_private_impl__composite_premul_nonpremul_u32_axxx(d0, s0)); - // mix10 = [b00 g00 r00 % b02 g02 r02 % b04 g04 r04 % b06 g06 r06 % - // b10 g10 r10 % b12 g12 r12 % b14 g14 r14 % b16 g16 r16 %] - // mix11 = [b01 g01 r01 % b03 g03 r03 % b05 g05 r05 % b07 g07 r07 % - // b11 g11 r11 % b13 g13 r13 % b15 g15 r15 % b17 g17 r17 %] - // mix12 = [b08 g08 r08 % b0A g0A r0A % b0C g0C r0C % b0E g0E r0E % - // b18 g18 r18 % b1A g1A r1A % b1C g1C r1C % b1E g1E r1E %] - // mix13 = [b09 g09 r09 % b0B g0B r0B % b0D g0D r0D % b0F g0F r0F % - // b19 g19 r19 % b1B g1B r1B % b1D g1D r1D % b1F g1F r1F %] - __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02); - __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03); - __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02); - __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03); + s += 1 * 4; + d += 1 * 1; + n -= 1; + } - // mix20 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 % - // b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %] - // mix21 = [b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 % - // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %] - // mix22 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B % - // b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %] - // mix23 = [b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F % - // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %] - __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11); - __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11); - __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13); - __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13); + return len; +} - // mix30 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 % - // b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %] - // mix31 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B % - // b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %] - // mix32 = [b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 % - // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %] - // mix33 = [b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B % - // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %] - __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20); - __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20); - __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31); - __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31); +static uint64_t // +wuffs_private_impl__swizzle_y__bgrx(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len4 = src_len / 4; + size_t len = (dst_len < src_len4) ? dst_len : src_len4; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - // Write out four u8x32 SIMD registers (128 bytes, 32 BGRX/RGBX pixels). - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33); + while (n >= 1) { + uint32_t s0 = + 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)); + d[0] = wuffs_base__color_u32_argb_premul__as__color_u8_gray(s0); - // Advance by up to 32 pixels. The first iteration might be smaller than 32 - // so that all of the remaining steps are exactly 32. - uint32_t n = 32u - (31u & (x - x_end)); - dst_iter += 4u * n; - up0 += n; - up1 += n; - up2 += n; - x += n; + s += 1 * 4; + d += 1 * 1; + n -= 1; } + + return len; } -// The rgbx flavor (below) is exactly the same as the bgrx flavor (above) -// except for the lines marked with a § and that comments were stripped. -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static void // -wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2( - wuffs_base__pixel_buffer* dst, - uint32_t x, - uint32_t x_end, - uint32_t y, - const uint8_t* up0, - const uint8_t* up1, - const uint8_t* up2) { - if ((x + 32u) > x_end) { - wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx( // - dst, x, x_end, y, up0, up1, up2); - return; - } +static uint64_t // +wuffs_private_impl__swizzle_y__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t src_len2 = src_len / 2; + size_t len = (dst_len < src_len2) ? dst_len : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - size_t dst_stride = dst->private_impl.planes[0].stride; - uint8_t* dst_iter = dst->private_impl.planes[0].ptr + - (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); + while (n >= 1) { + d[0] = s[0]; - const __m256i u0001 = _mm256_set1_epi16(+0x0001); - const __m256i u00FF = _mm256_set1_epi16(+0x00FF); - const __m256i uFF80 = _mm256_set1_epi16(-0x0080); - const __m256i uFFFF = _mm256_set1_epi16(-0x0001); + s += 1 * 2; + d += 1 * 1; + n -= 1; + } - const __m256i p8000_p0000 = _mm256_set_epi16( // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000, // - +0x0000, -0x8000, +0x0000, -0x8000); + return len; +} - const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E); - const __m256i p66E9 = _mm256_set1_epi16(+0x66E9); - const __m256i m581A_p492E = _mm256_set_epi16( // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A, // - +0x492E, -0x581A, +0x492E, -0x581A); +static uint64_t // +wuffs_private_impl__swizzle_y_16le__y_16be(uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len2 = src_len / 2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - while (x < x_end) { - __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1); - __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2); - __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF)); - __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF)); - __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8)); - __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8)); + while (n >= 1) { + uint8_t s0 = s[0]; + uint8_t s1 = s[1]; + d[0] = s1; + d[1] = s0; - __m256i tmp_by_eve = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001), - 1); - __m256i tmp_by_odd = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001), - 1); - __m256i tmp_ry_eve = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001), - 1); - __m256i tmp_ry_odd = _mm256_srai_epi16( - _mm256_add_epi16( - _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001), - 1); + s += 1 * 2; + d += 1 * 2; + n -= 1; + } - __m256i by_eve = - _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve)); - __m256i by_odd = - _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd)); - __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve); - __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd); + return len; +} - __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( // - _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E); - __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( // - _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E); - __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( // - _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E); - __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( // - _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E); +// -------- - __m256i tmp1_gy_eve_lo = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16); - __m256i tmp1_gy_eve_hi = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16); - __m256i tmp1_gy_odd_lo = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16); - __m256i tmp1_gy_odd_hi = - _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16); +static uint64_t // +wuffs_private_impl__swizzle_ya_nonpremul__ya_nonpremul__src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + const uint8_t* src_ptr, + size_t src_len) { + size_t dst_len2 = dst_len / 2; + size_t src_len2 = src_len / 2; + size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2; + uint8_t* d = dst_ptr; + const uint8_t* s = src_ptr; + size_t n = len; - __m256i gy_eve = _mm256_sub_epi16( - _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve); - __m256i gy_odd = _mm256_sub_epi16( - _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd); + while (n >= 1) { + uint32_t d0 = ((uint32_t)(d[1]) << 24) | ((uint32_t)(d[0]) * 0x010101); + uint32_t s0 = ((uint32_t)(s[1]) << 24) | ((uint32_t)(s[0]) * 0x010101); + uint32_t c0 = + wuffs_private_impl__composite_nonpremul_nonpremul_u32_axxx(d0, s0); + wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)(c0 >> 16)); - __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0); - __m256i yy_eve = _mm256_and_si256(yy_all, u00FF); - __m256i yy_odd = _mm256_srli_epi16(yy_all, 8); + s += 1 * 2; + d += 1 * 2; + n -= 1; + } - __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve); - __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd); - __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve); - __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd); + return len; +} - __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve); - __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd); - __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve); - __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd); +// -------- - __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve); - __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd); - __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve); - __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd); +static uint64_t // +wuffs_private_impl__swizzle_transparent_black_src( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + uint64_t num_pixels, + uint32_t dst_pixfmt_bytes_per_pixel) { + uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel; + if (n > num_pixels) { + n = num_pixels; + } + memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel))); + return n; +} - // § Note the swapped B and R channels. - __m256i mix00 = _mm256_unpacklo_epi8(packed_r_eve, packed_g_eve); - __m256i mix01 = _mm256_unpacklo_epi8(packed_r_odd, packed_g_odd); - __m256i mix02 = _mm256_unpacklo_epi8(packed_b_eve, uFFFF); - __m256i mix03 = _mm256_unpacklo_epi8(packed_b_odd, uFFFF); +static uint64_t // +wuffs_private_impl__swizzle_transparent_black_src_over( + uint8_t* dst_ptr, + size_t dst_len, + uint8_t* dst_palette_ptr, + size_t dst_palette_len, + uint64_t num_pixels, + uint32_t dst_pixfmt_bytes_per_pixel) { + uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel; + if (n > num_pixels) { + n = num_pixels; + } + return n; +} - __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02); - __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03); - __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02); - __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03); +// -------- - __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11); - __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11); - __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13); - __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13); +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__y( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + return wuffs_private_impl__swizzle_copy_1_1; - __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20); - __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20); - __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31); - __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31); + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_bgr_565__y; - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32); - _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33); + case WUFFS_BASE__PIXEL_FORMAT__BGR: + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_xxx__y; - uint32_t n = 32u - (31u & (x - x_end)); - dst_iter += 4u * n; - up0 += n; - up1 += n; - up2 += n; - x += n; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_xxxx__y__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_xxxx__y; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE: + return wuffs_private_impl__swizzle_xxxxxxxx__y; } + return NULL; } -#if defined(__GNUC__) && !defined(__clang__) -// No-op. -#else -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") -static const uint8_t* // -wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2( - uint8_t* dst_ptr, - const uint8_t* src_ptr_major, - const uint8_t* src_ptr_minor, - size_t src_len, - uint32_t h1v2_bias_ignored, - bool first_column, - bool last_column) { - uint8_t* dp = dst_ptr; - const uint8_t* sp_major = src_ptr_major; - const uint8_t* sp_minor = src_ptr_minor; - - if (first_column) { - src_len--; - if ((src_len <= 0u) && last_column) { - uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + // - (4u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + 8u) >> 4u); - *dp++ = (uint8_t)((sv + 7u) >> 4u); - return dst_ptr; - } - - uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero. - uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero. - uint32_t sv_major_p1 = sp_major[+1]; - uint32_t sv_minor_p1 = sp_minor[+1]; - - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); - if (src_len <= 0u) { - return dst_ptr; - } - } - - if (last_column) { - src_len--; - } - - if (src_len < 32) { - // This fallback is the same as the non-SIMD-capable code path. - for (; src_len > 0u; src_len--) { - uint32_t sv_major_m1 = sp_major[-1]; - uint32_t sv_minor_m1 = sp_minor[-1]; - uint32_t sv_major_p1 = sp_major[+1]; - uint32_t sv_minor_p1 = sp_minor[+1]; - - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); - } - - } else { - while (src_len > 0u) { - // Load 1+32+1 samples (six u8x32 vectors) from the major (jxx) and minor - // (nxx) rows. - // - // major_p0 = [j00 j01 j02 j03 .. j28 j29 j30 j31] // p0 = "plus 0" - // minor_p0 = [n00 n01 n02 n03 .. n28 n29 n30 n31] // p0 = "plus 0" - // major_m1 = [jm1 j00 j01 j02 .. j27 j28 j29 j30] // m1 = "minus 1" - // minor_m1 = [nm1 n00 n01 n02 .. n27 n28 n29 n30] // m1 = "minus 1" - // major_p1 = [j01 j02 j03 j04 .. j29 j30 j31 j32] // p1 = "plus 1" - // minor_p1 = [n01 n02 n03 n04 .. n29 n30 n31 n32] // p1 = "plus 1" - __m256i major_p0 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 0)); - __m256i minor_p0 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 0)); - __m256i major_m1 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major - 1)); - __m256i minor_m1 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor - 1)); - __m256i major_p1 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 1)); - __m256i minor_p1 = - _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 1)); - - // Unpack, staying with u8x32 vectors. - // - // step1_p0_lo = [j00 n00 j01 n01 .. j07 n07 j16 n16 j17 n17 .. j23 n23] - // step1_p0_hi = [j08 n08 j09 n09 .. j15 n15 j24 n24 j25 n25 .. j31 n31] - // step1_m1_lo = [jm1 nm1 j00 n00 .. j06 n06 j15 n15 j16 n16 .. j22 n22] - // step1_m1_hi = [j07 n07 j08 n08 .. j14 n14 j23 n23 j24 n24 .. j30 n30] - // step1_p1_lo = [j01 n01 j02 n02 .. j08 n08 j17 n17 j18 n18 .. j24 n24] - // step1_p1_hi = [j09 n09 j10 n10 .. j16 n16 j25 n25 j26 n26 .. j32 n32] - __m256i step1_p0_lo = _mm256_unpacklo_epi8(major_p0, minor_p0); - __m256i step1_p0_hi = _mm256_unpackhi_epi8(major_p0, minor_p0); - __m256i step1_m1_lo = _mm256_unpacklo_epi8(major_m1, minor_m1); - __m256i step1_m1_hi = _mm256_unpackhi_epi8(major_m1, minor_m1); - __m256i step1_p1_lo = _mm256_unpacklo_epi8(major_p1, minor_p1); - __m256i step1_p1_hi = _mm256_unpackhi_epi8(major_p1, minor_p1); - - // Multiply-add to get u16x16 vectors. - // - // step2_p0_lo = [9*j00+3*n00 9*j01+3*n01 .. 9*j23+3*n23] - // step2_p0_hi = [9*j08+3*n08 9*j09+3*n09 .. 9*j31+3*n31] - // step2_m1_lo = [3*jm1+1*nm1 3*j00+1*n00 .. 3*j22+1*n22] - // step2_m1_hi = [3*j07+1*n07 3*j08+1*n08 .. 3*j30+1*n30] - // step2_p1_lo = [3*j01+1*n01 3*j02+1*n02 .. 3*j24+1*n24] - // step2_p1_hi = [3*j09+1*n09 3*j10+1*n10 .. 3*j32+1*n32] - const __m256i k0309 = _mm256_set1_epi16(0x0309); - const __m256i k0103 = _mm256_set1_epi16(0x0103); - __m256i step2_p0_lo = _mm256_maddubs_epi16(step1_p0_lo, k0309); - __m256i step2_p0_hi = _mm256_maddubs_epi16(step1_p0_hi, k0309); - __m256i step2_m1_lo = _mm256_maddubs_epi16(step1_m1_lo, k0103); - __m256i step2_m1_hi = _mm256_maddubs_epi16(step1_m1_hi, k0103); - __m256i step2_p1_lo = _mm256_maddubs_epi16(step1_p1_lo, k0103); - __m256i step2_p1_hi = _mm256_maddubs_epi16(step1_p1_hi, k0103); - - // Compute the weighted sums of (p0, m1) and (p0, p1). For example: - // - // step3_m1_lo[00] = ((9*j00) + (3*n00) + (3*jm1) + (1*nm1)) as u16 - // step3_p1_hi[15] = ((9*j31) + (3*n31) + (3*j32) + (1*n32)) as u16 - __m256i step3_m1_lo = _mm256_add_epi16(step2_p0_lo, step2_m1_lo); - __m256i step3_m1_hi = _mm256_add_epi16(step2_p0_hi, step2_m1_hi); - __m256i step3_p1_lo = _mm256_add_epi16(step2_p0_lo, step2_p1_lo); - __m256i step3_p1_hi = _mm256_add_epi16(step2_p0_hi, step2_p1_hi); +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__y_16be( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + return wuffs_private_impl__swizzle_y__y_16be; - // Bias by 8 (on the left) or 7 (on the right) and then divide by 16 - // (which is 9+3+3+1) to get a weighted average. On the left (m1), shift - // the u16 right value by 4. On the right (p1), shift right by 4 and then - // shift left by 8 so that, when still in the u16x16 little-endian - // interpretation, we have: - // - m1_element = (etcetera + 8) >> 4 - // - p1_element = ((etcetera + 7) >> 4) << 8 - // - // step4_m1_lo = [0x00?? 0x00?? ... 0x00?? 0x00??] - // step4_p1_lo = [0x??00 0x??00 ... 0x??00 0x??00] - // step4_m1_hi = [0x00?? 0x00?? ... 0x00?? 0x00??] - // step4_p1_hi = [0x??00 0x??00 ... 0x??00 0x??00] - __m256i step4_m1_lo = _mm256_srli_epi16( - _mm256_add_epi16(step3_m1_lo, _mm256_set1_epi16(8)), 4); - __m256i step4_p1_lo = _mm256_slli_epi16( - _mm256_srli_epi16(_mm256_add_epi16(step3_p1_lo, _mm256_set1_epi16(7)), - 4), - 8); - __m256i step4_m1_hi = _mm256_srli_epi16( - _mm256_add_epi16(step3_m1_hi, _mm256_set1_epi16(8)), 4); - __m256i step4_p1_hi = _mm256_slli_epi16( - _mm256_srli_epi16(_mm256_add_epi16(step3_p1_hi, _mm256_set1_epi16(7)), - 4), - 8); + case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: + return wuffs_private_impl__swizzle_y_16le__y_16be; - // Bitwise-or two "0x00"-rich u16x16 vectors to get a u8x32 vector. Do - // that twice. Once for the low columns and once for the high columns. - // - // In terms of jxx (major row) or nxx (minor row) source samples: - // - low columns means ( 0 .. 8; 16 .. 24). - // - high columns means ( 8 .. 16; 24 .. 32). - // - // In terms of dxx destination samples (there are twice as many): - // - low columns means ( 0 .. 16; 32 .. 48). - // - high columns means (16 .. 32; 48 .. 64). - // - // step5_lo = [d00 d01 .. d14 d15 d32 d33 .. d46 d47] - // step5_hi = [d16 d17 .. d30 d31 d48 d49 .. d62 d63] - // - // The d00, d02 ... d62 even elements come from (p0, m1) weighted sums. - // The d01, d03 ... d63 odd elements come from (p0, p1) weighted sums. - __m256i step5_lo = _mm256_or_si256(step4_m1_lo, step4_p1_lo); - __m256i step5_hi = _mm256_or_si256(step4_m1_hi, step4_p1_hi); + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + return wuffs_private_impl__swizzle_copy_2_2; - // Permute and store. - // - // step6_00_31 = [d00 d01 .. d14 d15 d16 d17 .. d30 d31] - // step6_32_63 = [d32 d33 .. d46 d47 d48 d49 .. d62 d63] - __m256i step6_00_31 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x20); - __m256i step6_32_63 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x31); - _mm256_storeu_si256((__m256i*)(void*)(dp + 0x00), step6_00_31); - _mm256_storeu_si256((__m256i*)(void*)(dp + 0x20), step6_32_63); + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_bgr_565__y_16be; - // Advance by up to 32 source samples (64 destination samples). The first - // iteration might be smaller than 32 so that all of the remaining steps - // are exactly 32. - size_t n = 32u - (31u & (0u - src_len)); - dp += 2u * n; - sp_major += n; - sp_minor += n; - src_len -= n; - } - } + case WUFFS_BASE__PIXEL_FORMAT__BGR: + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_xxx__y_16be; - if (last_column) { - uint32_t sv_major_m1 = sp_major[-1]; - uint32_t sv_minor_m1 = sp_minor[-1]; - uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero. - uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero. + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + return wuffs_private_impl__swizzle_xxxx__y_16be; - uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // - (3u * ((uint32_t)(*sp_minor++))); - *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); - *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE: + return wuffs_private_impl__swizzle_xxxxxxxx__y_16be; } - - return dst_ptr; + return NULL; } -#endif -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) -// ‼ WUFFS MULTI-FILE SECTION -x86_avx2 -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ - defined(WUFFS_CONFIG__MODULE__BASE__UTF8) +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__ya_nonpremul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_2_2; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_ya_nonpremul__ya_nonpremul__src_over; + } + return NULL; -// ---------------- Unicode and UTF-8 + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__ya_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) { - if (code_point <= 0x7F) { - if (dst.len >= 1) { - dst.ptr[0] = (uint8_t)(code_point); - return 1; - } + case WUFFS_BASE__PIXEL_FORMAT__BGR: + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxx__ya_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxx__ya_nonpremul__src_over; + } + return NULL; - } else if (code_point <= 0x07FF) { - if (dst.len >= 2) { - dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6))); - dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); - return 2; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__ya_nonpremul__src_over; + } + return NULL; - } else if (code_point <= 0xFFFF) { - if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) { - dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12))); - dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F)); - dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); - return 3; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__ya_nonpremul__src_over; + } + return NULL; - } else if (code_point <= 0x10FFFF) { - if (dst.len >= 4) { - dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18))); - dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F)); - dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F)); - dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); - return 4; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__ya_nonpremul__src_over; + } + return NULL; } - - return 0; + return NULL; } -// wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a -// UTF-8 encoded code point, based on the encoding's initial byte. -// - 0x00 is 1-byte UTF-8 (ASCII). -// - 0x01 is the start of 2-byte UTF-8. -// - 0x02 is the start of 3-byte UTF-8. -// - 0x03 is the start of 4-byte UTF-8. -// - 0x40 is a UTF-8 tail byte. -// - 0x80 is invalid UTF-8. -// -// RFC 3629 (UTF-8) gives this grammar for valid UTF-8: -// UTF8-1 = %x00-7F -// UTF8-2 = %xC2-DF UTF8-tail -// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / -// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) -// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / -// %xF4 %x80-8F 2( UTF8-tail ) -// UTF8-tail = %x80-BF -static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = { - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. - - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7. - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF. +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_nonpremul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_1_1; + } + return NULL; - 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7. - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF. - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7. - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF. - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7. - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF. - 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. - // 0 1 2 3 4 5 6 7 - // 8 9 A B C D E F -}; + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + if (wuffs_private_impl__swizzle_squash_align4_bgr_565_8888( + dst_palette.ptr, dst_palette.len, src_palette.ptr, + src_palette.len, true) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_bgr_565__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + return wuffs_private_impl__swizzle_bgr_565__index_bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output // -wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) { - if (s_len == 0) { - return wuffs_base__make_utf_8__next__output(0, 0); - } - uint32_t c = s_ptr[0]; - switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) { - case 0: - return wuffs_base__make_utf_8__next__output(c, 1); + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + if (wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_xxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + return wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over; + } + return NULL; - case 1: - if (s_len < 2) { - break; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; } - c = wuffs_base__peek_u16le__no_bounds_check(s_ptr); - if ((c & 0xC000) != 0x8000) { - break; + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over; } - c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8)); - return wuffs_base__make_utf_8__next__output(c, 2); + return NULL; - case 2: - if (s_len < 3) { - break; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; } - c = wuffs_base__peek_u24le__no_bounds_check(s_ptr); - if ((c & 0xC0C000) != 0x808000) { - break; + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxxxxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over; } - c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) | - (0x00003F & (c >> 16)); - if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) { - break; + return NULL; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + if (wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + return wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over; } - return wuffs_base__make_utf_8__next__output(c, 3); + return NULL; - case 3: - if (s_len < 4) { - break; + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + if (wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_xxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + if (wuffs_private_impl__swizzle_swap_rgbx_bgrx( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_xxx__index_bgra_nonpremul__src_over; } - c = wuffs_base__peek_u32le__no_bounds_check(s_ptr); - if ((c & 0xC0C0C000) != 0x80808000) { - break; + return NULL; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + if (wuffs_private_impl__swizzle_swap_rgbx_bgrx( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; } - c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) | - (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24)); - if ((c <= 0xFFFF) || (0x110000 <= c)) { - break; + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__index_bgra_nonpremul__src_over; } - return wuffs_base__make_utf_8__next__output(c, 4); - } + return NULL; - return wuffs_base__make_utf_8__next__output( - WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1); -} + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + if (wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + if (wuffs_private_impl__swizzle_swap_rgbx_bgrx( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + return wuffs_private_impl__swizzle_bgra_premul__index_bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output // -wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) { - if (s_len == 0) { - return wuffs_base__make_utf_8__next__output(0, 0); + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + // TODO. + break; } - const uint8_t* ptr = &s_ptr[s_len - 1]; - if (*ptr < 0x80) { - return wuffs_base__make_utf_8__next__output(*ptr, 1); + return NULL; +} - } else if (*ptr < 0xC0) { - const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0]; - uint32_t n = 1; - while (ptr != too_far) { - ptr--; - n++; - if (*ptr < 0x80) { - break; - } else if (*ptr < 0xC0) { - continue; +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_binary( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; } - wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n); - if (o.byte_length != n) { - break; + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_1_1; } - return o; - } - } - - return wuffs_base__make_utf_8__next__output( - WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1); -} + return NULL; -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) { - // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time). - // - // TODO: possibly optimize this by manually inlining the - // wuffs_base__utf_8__next calls. - size_t original_len = s_len; - while (s_len > 0) { - wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len); - if ((o.code_point > 0x7F) && (o.byte_length == 1)) { - break; - } - s_ptr += o.byte_length; - s_len -= o.byte_length; - } - return original_len - s_len; -} + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + if (wuffs_private_impl__swizzle_squash_align4_bgr_565_8888( + dst_palette.ptr, dst_palette.len, src_palette.ptr, + src_palette.len, false) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__index_binary_alpha__src_over; + } + return NULL; -WUFFS_BASE__MAYBE_STATIC size_t // -wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) { - // TODO: possibly optimize this by checking 4 or 8 bytes at a time. - const uint8_t* original_ptr = s_ptr; - const uint8_t* p = s_ptr; - const uint8_t* q = s_ptr + s_len; - for (; (p != q) && ((*p & 0x80) == 0); p++) { - } - return (size_t)(p - original_ptr); -} + case WUFFS_BASE__PIXEL_FORMAT__BGR: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over; + } + return NULL; -#endif // !defined(WUFFS_CONFIG__MODULES) || - // defined(WUFFS_CONFIG__MODULE__BASE) || - // defined(WUFFS_CONFIG__MODULE__BASE__UTF8) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over; + } + return NULL; -#ifdef __cplusplus -} // extern "C" -#endif + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: + if (wuffs_private_impl__slice_u8__copy_from_slice(dst_palette, + src_palette) != + WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxxxxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxxxxxxx__index_binary_alpha__src_over; + } + return NULL; -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) + case WUFFS_BASE__PIXEL_FORMAT__RGB: + if (wuffs_private_impl__swizzle_swap_rgbx_bgrx( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxx__index_binary_alpha__src_over; + } + return NULL; -// ---------------- Status Codes Implementations + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + if (wuffs_private_impl__swizzle_swap_rgbx_bgrx( + dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr, + src_palette.len) != + (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) { + return NULL; + } + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_xxxx__index__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_xxxx__index_binary_alpha__src_over; + } + return NULL; + } + return NULL; +} -// ---------------- Private Consts +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgr_565( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_copy_2_2; -// ---------------- Private Initializer Prototypes + case WUFFS_BASE__PIXEL_FORMAT__BGR: + return wuffs_private_impl__swizzle_bgr__bgr_565; -// ---------------- Private Function Prototypes + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + return wuffs_private_impl__swizzle_bgrw__bgr_565; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: + return wuffs_private_impl__swizzle_bgrw_4x16le__bgr_565; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up__choosy_default( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x); + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_rgb__bgr_565; -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up_arm_neon( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + return wuffs_private_impl__swizzle_rgbw__bgr_565; + } + return NULL; +} -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up_x86_sse42( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgr( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_bgr_565__bgr; -// ---------------- VTables + case WUFFS_BASE__PIXEL_FORMAT__BGR: + return wuffs_private_impl__swizzle_copy_3_3; -const wuffs_base__hasher_u32__func_ptrs -wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = { - (uint32_t(*)(const void*))(&wuffs_adler32__hasher__checksum_u32), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_adler32__hasher__get_quirk), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_adler32__hasher__set_quirk), - (wuffs_base__empty_struct(*)(void*, - wuffs_base__slice_u8))(&wuffs_adler32__hasher__update), - (uint32_t(*)(void*, - wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32), -}; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_bgrw__bgr; -// ---------------- Initializer Implementations + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE: + return wuffs_private_impl__swizzle_bgrw_4x16le__bgr; -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_adler32__hasher__initialize( - wuffs_adler32__hasher* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_swap_rgb_bgr; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42; + } #endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } + return wuffs_private_impl__swizzle_bgrw__rgb; } + return NULL; +} - self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default; +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_y__bgra_nonpremul__src_over; + } + return NULL; - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = - wuffs_base__hasher_u32__vtable_name; - self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = - (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32); - return wuffs_base__make_status(NULL); -} + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul__src_over; + } + return NULL; -wuffs_adler32__hasher* -wuffs_adler32__hasher__alloc(void) { - wuffs_adler32__hasher* x = - (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1)); - if (!x) { - return NULL; - } - if (wuffs_adler32__hasher__initialize( - x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over; + } + return NULL; -size_t -sizeof__wuffs_adler32__hasher(void) { - return sizeof(wuffs_adler32__hasher); -} + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_4_4; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over; + } + return NULL; -// ---------------- Function Implementations + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul__src_over; + } + return NULL; -// -------- func adler32.hasher.get_quirk + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_adler32__hasher__get_quirk( - const wuffs_adler32__hasher* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + // TODO. + break; - return 0u; -} + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over; + } + return NULL; -// -------- func adler32.hasher.set_quirk + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_swap_rgbx_bgrx; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_adler32__hasher__set_quirk( - wuffs_adler32__hasher* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over; + } + return NULL; - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + // TODO. + break; + } + return NULL; } -// -------- func adler32.hasher.update +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul_4x16le( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__bgra_nonpremul_4x16le__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_adler32__hasher__update( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); - } + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul_4x16le__src_over; + } + return NULL; - if ( ! self->private_impl.f_started) { - self->private_impl.f_started = true; - self->private_impl.f_state = 1u; - self->private_impl.choosy_up = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 : -#endif - self->private_impl.choosy_up); - } - wuffs_adler32__hasher__up(self, a_x); - return wuffs_base__make_empty_struct(); -} + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul_4x16le__src_over; + } + return NULL; -// -------- func adler32.hasher.update_u32 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_8_8; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_adler32__hasher__update_u32( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return 0; - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; - } + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul_4x16le__src_over; + } + return NULL; - wuffs_adler32__hasher__update(self, a_x); - return self->private_impl.f_state; -} + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + // TODO. + break; -// -------- func adler32.hasher.up + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul_4x16le__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - return (*self->private_impl.choosy_up)(self, a_x); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_rgba_nonpremul__bgra_nonpremul_4x16le__src_over; + } + break; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul_4x16le__src_over; + } + return NULL; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + // TODO. + break; + } + return NULL; } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up__choosy_default( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s1 = 0; - uint32_t v_s2 = 0; - wuffs_base__slice_u8 v_remaining = {0}; - wuffs_base__slice_u8 v_p = {0}; - - v_s1 = ((self->private_impl.f_state) & 0xFFFFu); - v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); - while (((uint64_t)(a_x.len)) > 0u) { - v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); - if (((uint64_t)(a_x.len)) > 5552u) { - v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552u); - a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552u); - } - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8); - while (v_p.ptr < i_end0_p) { - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - } - v_p.len = 1; - uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end1_p) { - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgra_premul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__bgra_premul__src_over; } - v_p.len = 0; - } - v_s1 %= 65521u; - v_s2 %= 65521u; - a_x = v_remaining; - } - self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); - return wuffs_base__make_empty_struct(); -} - -// -------- func adler32.hasher.checksum_u32 - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_adler32__hasher__checksum_u32( - const wuffs_adler32__hasher* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return self->private_impl.f_state; -} - -// ‼ WUFFS MULTI-FILE SECTION +arm_neon -// -------- func adler32.hasher.up_arm_neon + return NULL; -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up_arm_neon( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s1 = 0; - uint32_t v_s2 = 0; - wuffs_base__slice_u8 v_remaining = {0}; - wuffs_base__slice_u8 v_p = {0}; - uint8x16_t v_p__left = {0}; - uint8x16_t v_p_right = {0}; - uint32x4_t v_v1 = {0}; - uint32x4_t v_v2 = {0}; - uint16x8_t v_col0 = {0}; - uint16x8_t v_col1 = {0}; - uint16x8_t v_col2 = {0}; - uint16x8_t v_col3 = {0}; - uint32x2_t v_sum1 = {0}; - uint32x2_t v_sum2 = {0}; - uint32x2_t v_sum12 = {0}; - uint32_t v_num_iterate_bytes = 0; - uint64_t v_tail_index = 0; + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__bgra_premul__src_over; + } + return NULL; - v_s1 = ((self->private_impl.f_state) & 0xFFFFu); - v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); - while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { - v_s1 += ((uint32_t)(a_x.ptr[0u])); - v_s2 += v_s1; - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); - } - v_s1 %= 65521u; - v_s2 %= 65521u; - while (((uint64_t)(a_x.len)) > 0u) { - v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); - if (((uint64_t)(a_x.len)) > 5536u) { - v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u); - a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u); - } - v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u))); - v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes)); - v_v1 = vdupq_n_u32(0u); - v_v2 = vdupq_n_u32(0u); - v_col0 = vdupq_n_u16(0u); - v_col1 = vdupq_n_u16(0u); - v_col2 = vdupq_n_u16(0u); - v_col3 = vdupq_n_u16(0u); - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 32; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32); - while (v_p.ptr < i_end0_p) { - v_p__left = vld1q_u8(v_p.ptr); - v_p_right = vld1q_u8(v_p.ptr + 16u); - v_v2 = vaddq_u32(v_v2, v_v1); - v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right)); - v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left)); - v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left)); - v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right)); - v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right)); - v_p.ptr += 32; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over; } - v_p.len = 0; - } - v_v2 = vshlq_n_u32(v_v2, 5u); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u})); - v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u})); - v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u})); - v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1)); - v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2)); - v_sum12 = vpadd_u32(v_sum1, v_sum2); - v_s1 += vget_lane_u32(v_sum12, 0u); - v_s2 += vget_lane_u32(v_sum12, 1u); - v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u); - if (v_tail_index < ((uint64_t)(a_x.len))) { - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - } - v_p.len = 0; + return NULL; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__bgra_premul__src_over; } - } - v_s1 %= 65521u; - v_s2 %= 65521u; - a_x = v_remaining; - } - self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -// ‼ WUFFS MULTI-FILE SECTION -arm_neon + return NULL; -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func adler32.hasher.up_x86_sse42 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_4_4; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over; + } + return NULL; -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_adler32__hasher__up_x86_sse42( - wuffs_adler32__hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s1 = 0; - uint32_t v_s2 = 0; - wuffs_base__slice_u8 v_remaining = {0}; - wuffs_base__slice_u8 v_p = {0}; - __m128i v_zeroes = {0}; - __m128i v_ones = {0}; - __m128i v_weights__left = {0}; - __m128i v_weights_right = {0}; - __m128i v_q__left = {0}; - __m128i v_q_right = {0}; - __m128i v_v1 = {0}; - __m128i v_v2 = {0}; - __m128i v_v2j = {0}; - __m128i v_v2k = {0}; - uint32_t v_num_iterate_bytes = 0; - uint64_t v_tail_index = 0; + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__rgba_premul__src_over; + } + return NULL; - v_zeroes = _mm_set1_epi16((int16_t)(0u)); - v_ones = _mm_set1_epi16((int16_t)(1u)); - v_weights__left = _mm_set_epi8((int8_t)(17u), (int8_t)(18u), (int8_t)(19u), (int8_t)(20u), (int8_t)(21u), (int8_t)(22u), (int8_t)(23u), (int8_t)(24u), (int8_t)(25u), (int8_t)(26u), (int8_t)(27u), (int8_t)(28u), (int8_t)(29u), (int8_t)(30u), (int8_t)(31u), (int8_t)(32u)); - v_weights_right = _mm_set_epi8((int8_t)(1u), (int8_t)(2u), (int8_t)(3u), (int8_t)(4u), (int8_t)(5u), (int8_t)(6u), (int8_t)(7u), (int8_t)(8u), (int8_t)(9u), (int8_t)(10u), (int8_t)(11u), (int8_t)(12u), (int8_t)(13u), (int8_t)(14u), (int8_t)(15u), (int8_t)(16u)); - v_s1 = ((self->private_impl.f_state) & 0xFFFFu); - v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); - while (((uint64_t)(a_x.len)) > 0u) { - v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); - if (((uint64_t)(a_x.len)) > 5536u) { - v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u); - a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u); - } - v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u))); - v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes)); - v_v1 = _mm_setzero_si128(); - v_v2j = _mm_setzero_si128(); - v_v2k = _mm_setzero_si128(); - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 32; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32); - while (v_p.ptr < i_end0_p) { - v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr)); - v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)); - v_v2j = _mm_add_epi32(v_v2j, v_v1); - v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes)); - v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes)); - v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left))); - v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right))); - v_p.ptr += 32; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over; } - v_p.len = 0; - } - v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177u))); - v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78u))); - v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1))); - v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5u))); - v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177u))); - v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78u))); - v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2))); - v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u); - if (v_tail_index < ((uint64_t)(a_x.len))) { - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s1 += ((uint32_t)(v_p.ptr[0u])); - v_s2 += v_s1; - v_p.ptr += 1; - } - v_p.len = 0; + return NULL; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_swap_rgbx_bgrx; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over; } - } - v_s1 %= 65521u; - v_s2 %= 65521u; - a_x = v_remaining; + return NULL; } - self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); - return wuffs_base__make_empty_struct(); + return NULL; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__bgrx( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + return wuffs_private_impl__swizzle_y__bgrx; -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_bgr_565__bgrx; -// ---------------- Status Codes Implementations + case WUFFS_BASE__PIXEL_FORMAT__BGR: + return wuffs_private_impl__swizzle_xxx__xxxx; -const char wuffs_bmp__error__bad_header[] = "#bmp: bad header"; -const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression"; -const char wuffs_bmp__error__truncated_input[] = "#bmp: truncated input"; -const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file"; -const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read"; + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + return wuffs_private_impl__swizzle_bgrw__bgrx; -// ---------------- Private Consts + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + return wuffs_private_impl__swizzle_bgrw_4x16le__bgrx; -#define WUFFS_BMP__COMPRESSION_NONE 0 + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + return wuffs_private_impl__swizzle_copy_4_4; -#define WUFFS_BMP__COMPRESSION_RLE8 1 + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_bgr__rgbx; -#define WUFFS_BMP__COMPRESSION_RLE4 2 + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + return wuffs_private_impl__swizzle_bgrw__rgbx; + } + return NULL; +} -#define WUFFS_BMP__COMPRESSION_BITFIELDS 3 +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__rgb( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + return wuffs_private_impl__swizzle_bgr_565__rgb; -#define WUFFS_BMP__COMPRESSION_JPEG 4 + case WUFFS_BASE__PIXEL_FORMAT__BGR: + return wuffs_private_impl__swizzle_swap_rgb_bgr; -#define WUFFS_BMP__COMPRESSION_PNG 5 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_bgrw__rgb__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_bgrw__rgb; -#define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + return wuffs_private_impl__swizzle_bgrw_4x16le__rgb; -#define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256 + case WUFFS_BASE__PIXEL_FORMAT__RGB: + return wuffs_private_impl__swizzle_copy_3_3; -#define WUFFS_BMP__RLE_STATE_NEUTRAL 0 + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_bgrw__bgr__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_bgrw__bgr; + } + return NULL; +} -#define WUFFS_BMP__RLE_STATE_RUN 1 +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__rgba_nonpremul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__rgba_nonpremul__src_over; + } + return NULL; -#define WUFFS_BMP__RLE_STATE_ESCAPE 2 + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__rgba_nonpremul__src_over; + } + return NULL; -#define WUFFS_BMP__RLE_STATE_LITERAL 3 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_swap_rgbx_bgrx; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_nonpremul__src_over; + } + return NULL; -#define WUFFS_BMP__RLE_STATE_DELTA_X 4 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_nonpremul__src_over; + } + return NULL; -#define WUFFS_BMP__RLE_STATE_DELTA_Y 5 + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__rgba_nonpremul__src_over; + } + return NULL; -// ---------------- Private Initializer Prototypes + case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + // TODO. + break; -// ---------------- Private Function Prototypes + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_image_config( - wuffs_bmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_4_4; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_frame_config( - wuffs_bmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__bgra_nonpremul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_frame( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); + case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + // TODO. + break; + } + return NULL; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_none( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); +static inline WUFFS_BASE__FORCE_INLINE wuffs_base__pixel_swizzler__func // +wuffs_private_impl__pixel_swizzler__prepare__rgba_premul( + wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + switch (dst_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr_565__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr_565__rgba_premul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_rle( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__BGR: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__rgba_premul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_bitfields( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__rgba_premul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_low_bit_depth( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_tell_me_more( - wuffs_bmp__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul_4x16le__rgba_premul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__read_palette( - wuffs_bmp__decoder* self, - wuffs_base__io_buffer* a_src); + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + if (wuffs_base__cpu_arch__have_x86_sse42()) { + return wuffs_private_impl__swizzle_swap_rgbx_bgrx__x86_sse42; + } +#endif + return wuffs_private_impl__swizzle_swap_rgbx_bgrx; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__rgba_premul__src_over; + } + return NULL; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__process_masks( - wuffs_bmp__decoder* self); + case WUFFS_BASE__PIXEL_FORMAT__RGB: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgr__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgr__bgra_premul__src_over; + } + return NULL; -// ---------------- VTables + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_nonpremul__bgra_premul__src_over; + } + return NULL; -const wuffs_base__image_decoder__func_ptrs -wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_bmp__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_bmp__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_bmp__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_bmp__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_bmp__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len), -}; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + return wuffs_private_impl__swizzle_copy_4_4; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + return wuffs_private_impl__swizzle_bgra_premul__bgra_premul__src_over; + } + return NULL; + } + return NULL; +} -// ---------------- Initializer Implementations +// -------- -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_bmp__decoder__initialize( - wuffs_bmp__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__status // +wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p, + wuffs_base__pixel_format dst_pixfmt, + wuffs_base__slice_u8 dst_palette, + wuffs_base__pixel_format src_pixfmt, + wuffs_base__slice_u8 src_palette, + wuffs_base__pixel_blend blend) { + if (!p) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } + p->private_impl.func = NULL; + p->private_impl.transparent_black_func = NULL; + p->private_impl.dst_pixfmt_bytes_per_pixel = 0; + p->private_impl.src_pixfmt_bytes_per_pixel = 0; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + // ---- + +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST) + switch (dst_pixfmt.repr) { +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR_565) + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + break; #endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR) + case WUFFS_BASE__PIXEL_FORMAT__BGR: + break; #endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL_4X16LE) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_PREMUL) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGB) + case WUFFS_BASE__PIXEL_FORMAT__RGB: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_NONPREMUL) + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_PREMUL) + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + break; +#endif + default: + return wuffs_base__make_status( + wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist); } +#endif // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST) - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); -} + // ---- -wuffs_bmp__decoder* -wuffs_bmp__decoder__alloc(void) { - wuffs_bmp__decoder* x = - (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_bmp__decoder__initialize( - x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + wuffs_base__pixel_swizzler__func func = NULL; + wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func = + NULL; + + uint32_t dst_pixfmt_bits_per_pixel = + wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt); + if ((dst_pixfmt_bits_per_pixel == 0) || + ((dst_pixfmt_bits_per_pixel & 7) != 0)) { + return wuffs_base__make_status( + wuffs_base__error__unsupported_pixel_swizzler_option); } - return x; -} -size_t -sizeof__wuffs_bmp__decoder(void) { - return sizeof(wuffs_bmp__decoder); -} + uint32_t src_pixfmt_bits_per_pixel = + wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt); + if ((src_pixfmt_bits_per_pixel == 0) || + ((src_pixfmt_bits_per_pixel & 7) != 0)) { + return wuffs_base__make_status( + wuffs_base__error__unsupported_pixel_swizzler_option); + } -// ---------------- Function Implementations + // TODO: support many more formats. -// -------- func bmp.decoder.get_quirk + switch (blend) { + case WUFFS_BASE__PIXEL_BLEND__SRC: + transparent_black_func = + wuffs_private_impl__swizzle_transparent_black_src; + break; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bmp__decoder__get_quirk( - const wuffs_bmp__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + case WUFFS_BASE__PIXEL_BLEND__SRC_OVER: + transparent_black_func = + wuffs_private_impl__swizzle_transparent_black_src_over; + break; } - return 0u; -} + switch (src_pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + func = wuffs_private_impl__pixel_swizzler__prepare__y( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; -// -------- func bmp.decoder.set_quirk + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + func = wuffs_private_impl__pixel_swizzler__prepare__y_16be( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__set_quirk( - wuffs_bmp__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL: + func = wuffs_private_impl__pixel_swizzler__prepare__ya_nonpremul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + func = + wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_nonpremul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: + func = wuffs_private_impl__pixel_swizzler__prepare__indexed__bgra_binary( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + func = wuffs_private_impl__pixel_swizzler__prepare__bgr_565( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGR: + func = wuffs_private_impl__pixel_swizzler__prepare__bgr( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + func = wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + func = wuffs_private_impl__pixel_swizzler__prepare__bgra_nonpremul_4x16le( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + func = wuffs_private_impl__pixel_swizzler__prepare__bgra_premul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + func = wuffs_private_impl__pixel_swizzler__prepare__bgrx( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__RGB: + func = wuffs_private_impl__pixel_swizzler__prepare__rgb( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + func = wuffs_private_impl__pixel_swizzler__prepare__rgba_nonpremul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; + + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + func = wuffs_private_impl__pixel_swizzler__prepare__rgba_premul( + p, dst_pixfmt, dst_palette, src_palette, blend); + break; } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + p->private_impl.func = func; + p->private_impl.transparent_black_func = transparent_black_func; + p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8; + p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8; + return wuffs_base__make_status( + func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option); } -// -------- func bmp.decoder.decode_image_config - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__decode_image_config( - wuffs_bmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( + const wuffs_base__pixel_swizzler* p, + uint32_t up_to_num_pixels, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + const uint8_t** ptr_iop_r, + const uint8_t* io2_r) { + if (p && p->private_impl.func) { + const uint8_t* iop_r = *ptr_iop_r; + uint64_t src_len = wuffs_base__u64__min( + ((uint64_t)up_to_num_pixels) * + ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel), + ((uint64_t)(io2_r - iop_r))); + uint64_t n = + (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, + dst_palette.len, iop_r, (size_t)src_len); + *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel; + return n; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + return 0; +} + +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( + const wuffs_base__pixel_swizzler* p, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + const uint8_t** ptr_iop_r, + const uint8_t* io2_r) { + if (p && p->private_impl.func) { + const uint8_t* iop_r = *ptr_iop_r; + uint64_t src_len = ((uint64_t)(io2_r - iop_r)); + uint64_t n = + (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, + dst_palette.len, iop_r, (size_t)src_len); + *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel; + return n; } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); + return 0; +} + +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice( + const wuffs_base__pixel_swizzler* p, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + wuffs_base__slice_u8 src) { + if (p && p->private_impl.func) { + return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr, + dst_palette.len, src.ptr, src.len); } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + return 0; +} + +WUFFS_BASE__MAYBE_STATIC uint64_t // +wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black( + const wuffs_base__pixel_swizzler* p, + wuffs_base__slice_u8 dst, + wuffs_base__slice_u8 dst_palette, + uint64_t num_pixels) { + if (p && p->private_impl.transparent_black_func) { + return (*p->private_impl.transparent_black_func)( + dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels, + p->private_impl.dst_pixfmt_bytes_per_pixel); } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); + return 0; +} - wuffs_base__status v_status = wuffs_base__make_status(NULL); +// -------- - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static void // +wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2); - while (true) { - { - wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static void // +wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2); - ok: - self->private_impl.p_decode_image_config[0] = 0; - goto exit; - } +#if defined(__GNUC__) && !defined(__clang__) +// No-op. +#else +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column, + bool last_column); +#endif +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) - goto suspend; - suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; +// -------- - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; +static inline uint32_t // +wuffs_private_impl__u32__max_of_4(uint32_t a, + uint32_t b, + uint32_t c, + uint32_t d) { + return wuffs_base__u32__max( // + wuffs_base__u32__max(a, b), // + wuffs_base__u32__max(c, d)); } -// -------- func bmp.decoder.do_decode_image_config +static inline uint32_t // +wuffs_private_impl__u32__min_of_5(uint32_t a, + uint32_t b, + uint32_t c, + uint32_t d, + uint32_t e) { + return wuffs_base__u32__min( // + wuffs_base__u32__min( // + wuffs_base__u32__min(a, b), // + wuffs_base__u32__min(c, d)), // + e); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_image_config( - wuffs_bmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +// -------- - uint32_t v_magic = 0; - uint32_t v_width = 0; - uint32_t v_height = 0; - uint32_t v_planes = 0; - uint32_t v_dst_pixfmt = 0; - uint32_t v_byte_width = 0; +typedef void (*wuffs_private_impl__swizzle_ycc__convert_4_func)( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2, + const uint8_t* up3); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +static void // +wuffs_private_impl__swizzle_cmyk__convert_4_general( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2, + const uint8_t* up3) { + for (; x < x_end; x++) { + // It's called CMYK but, but for Adobe CMYK JPEG images in practice, it's + // RGBW: 0xFFu means no ink instead of full ink. Note that a double + // inversion is a no-op, so inversions might be implicit in the code below. + uint32_t r = ((uint32_t)(*up0++)); + uint32_t g = ((uint32_t)(*up1++)); + uint32_t b = ((uint32_t)(*up2++)); + uint32_t w = ((uint32_t)(*up3++)); + r = ((r * w) + 0x7Fu) / 0xFFu; + g = ((g * w) + 0x7Fu) / 0xFFu; + b = ((b * w) + 0x7Fu) / 0xFFu; + wuffs_base__pixel_buffer__set_color_u32_at( + dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u)); } +} - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +static void // +wuffs_private_impl__swizzle_ycck__convert_4_general( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2, + const uint8_t* up3) { + for (; x < x_end; x++) { + // We invert once again: 0xFFu means no ink instead of full ink. + uint32_t color = // + wuffs_base__color_ycc__as__color_u32( // + *up0++, *up1++, *up2++); + uint32_t r = 0xFFu - (0xFFu & (color >> 16u)); + uint32_t g = 0xFFu - (0xFFu & (color >> 8u)); + uint32_t b = 0xFFu - (0xFFu & (color >> 0u)); + uint32_t w = ((uint32_t)(*up3++)); + r = ((r * w) + 0x7Fu) / 0xFFu; + g = ((g * w) + 0x7Fu) / 0xFFu; + b = ((b * w) + 0x7Fu) / 0xFFu; + wuffs_base__pixel_buffer__set_color_u32_at( + dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u)); + } +} - if ((self->private_impl.f_call_sequence != 0u) || (self->private_impl.f_io_redirect_fourcc == 1u)) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if (self->private_impl.f_io_redirect_fourcc != 0u) { - status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); - goto ok; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 8) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; - } - } - v_magic = t_0; - } - if (v_magic != 19778u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } - self->private_data.s_do_decode_image_config[0].scratch = 8u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; +// -------- + +typedef void (*wuffs_private_impl__swizzle_ycc__convert_3_func)( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2); + +static void // +wuffs_private_impl__swizzle_rgb__convert_3_general( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + for (; x < x_end; x++) { + uint32_t color = 0xFF000000u | // + (((uint32_t)(*up0++)) << 16u) | // + (((uint32_t)(*up1++)) << 8u) | // + (((uint32_t)(*up2++)) << 0u); + wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color); + } +} + +static void // +wuffs_private_impl__swizzle_ycc__convert_3_general( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + for (; x < x_end; x++) { + uint32_t color = // + wuffs_base__color_ycc__as__color_u32( // + *up0++, *up1++, *up2++); + wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color); + } +} + +static void // +wuffs_private_impl__swizzle_ycc__convert_3_bgrx(wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + size_t dst_stride = dst->private_impl.planes[0].stride; + uint8_t* dst_iter = dst->private_impl.planes[0].ptr + + (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); + + for (; x < x_end; x++) { + uint32_t color = // + wuffs_base__color_ycc__as__color_u32( // + *up0++, *up1++, *up2++); + wuffs_base__poke_u32le__no_bounds_check(dst_iter, color); + dst_iter += 4u; + } +} + +static void // +wuffs_private_impl__swizzle_ycc__convert_3_rgbx(wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + size_t dst_stride = dst->private_impl.planes[0].stride; + uint8_t* dst_iter = dst->private_impl.planes[0].ptr + + (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); + + for (; x < x_end; x++) { + uint32_t color = // + wuffs_base__color_ycc__as__color_u32_abgr( // + *up0++, *up1++, *up2++); + wuffs_base__poke_u32le__no_bounds_check(dst_iter, color); + dst_iter += 4u; + } +} + +// -------- + +// wuffs_private_impl__swizzle_ycc__upsample_func upsamples to a destination +// slice at least 480 (YCCK) or 672 (YCC) bytes long and whose src_len +// (multiplied by 1, 2, 3 or 4) is positive but no more than that. This 480 or +// 672 length is just under 1/4 or 1/3 of the scratch_buffer_2k slice length. +// Both (480 * 4) = 1920 and (672 * 3) = 2016 are less than 2048. +// +// 480 and 672 are nice round numbers because a JPEG MCU is 1, 2, 3 or 4 blocks +// wide and each block is 8 pixels wide. We have: +// 480 = 1 * 8 * 60, 672 = 1 * 8 * 84 +// 480 = 2 * 8 * 30, 672 = 2 * 8 * 42 +// 480 = 3 * 8 * 20, 672 = 3 * 8 * 28 +// 480 = 4 * 8 * 15, 672 = 4 * 8 * 21 +// +// Box filters are equivalent to nearest neighbor upsampling. These ignore the +// src_ptr_minor, h1v2_bias, first_column and last_column arguments. +// +// Triangle filters use a 3:1 ratio (in 1 dimension), or 9:3:3:1 (in 2 +// dimensions), which is higher quality (less blocky) but also higher +// computational effort. +// +// In theory, we could use triangle filters for any (inv_h, inv_v) combination. +// In practice, matching libjpeg-turbo, we only implement it for the common +// chroma subsampling ratios (YCC420, YCC422 or YCC440), corresponding to an +// (inv_h, inv_v) pair of (2, 2), (2, 1) or (1, 2). +typedef const uint8_t* (*wuffs_private_impl__swizzle_ycc__upsample_func)( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, // Nearest row. + const uint8_t* src_ptr_minor, // Adjacent row, alternating above or below. + size_t src_len, + uint32_t h1v2_bias, + bool first_column, + bool last_column); + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor_ignored, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column_ignored, + bool last_column_ignored) { + return src_ptr_major; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor_ignored, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column_ignored, + bool last_column_ignored) { + uint8_t* dp = dst_ptr; + const uint8_t* sp = src_ptr_major; + while (src_len--) { + uint8_t sv = *sp++; + *dp++ = sv; + *dp++ = sv; + } + return dst_ptr; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor_ignored, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column_ignored, + bool last_column_ignored) { + uint8_t* dp = dst_ptr; + const uint8_t* sp = src_ptr_major; + while (src_len--) { + uint8_t sv = *sp++; + *dp++ = sv; + *dp++ = sv; + *dp++ = sv; + } + return dst_ptr; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor_ignored, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column_ignored, + bool last_column_ignored) { + uint8_t* dp = dst_ptr; + const uint8_t* sp = src_ptr_major; + while (src_len--) { + uint8_t sv = *sp++; + *dp++ = sv; + *dp++ = sv; + *dp++ = sv; + *dp++ = sv; + } + return dst_ptr; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h1v2_triangle( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor, + size_t src_len, + uint32_t h1v2_bias, + bool first_column, + bool last_column) { + uint8_t* dp = dst_ptr; + const uint8_t* sp_major = src_ptr_major; + const uint8_t* sp_minor = src_ptr_minor; + while (src_len--) { + *dp++ = (uint8_t)(((3u * ((uint32_t)(*sp_major++))) + // + (1u * ((uint32_t)(*sp_minor++))) + // + h1v2_bias) >> + 2u); + } + return dst_ptr; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h2v1_triangle( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column, + bool last_column) { + uint8_t* dp = dst_ptr; + const uint8_t* sp = src_ptr_major; + + if (first_column) { + src_len--; + if ((src_len <= 0u) && last_column) { + uint8_t sv = *sp++; + *dp++ = sv; + *dp++ = sv; + return dst_ptr; } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; - } - } - self->private_impl.f_padding = t_1; + uint32_t svp1 = sp[+1]; + uint8_t sv = *sp++; + *dp++ = sv; + *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svp1 + 2u) >> 2u); + if (src_len <= 0u) { + return dst_ptr; } - if (self->private_impl.f_padding < 14u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; + } + + if (last_column) { + src_len--; + } + + for (; src_len > 0u; src_len--) { + uint32_t svm1 = sp[-1]; + uint32_t svp1 = sp[+1]; + uint32_t sv3 = 3u * (uint32_t)(*sp++); + *dp++ = (uint8_t)((sv3 + svm1 + 1u) >> 2u); + *dp++ = (uint8_t)((sv3 + svp1 + 2u) >> 2u); + } + + if (last_column) { + uint32_t svm1 = sp[-1]; + uint8_t sv = *sp++; + *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svm1 + 1u) >> 2u); + *dp++ = sv; + } + + return dst_ptr; +} + +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column, + bool last_column) { + uint8_t* dp = dst_ptr; + const uint8_t* sp_major = src_ptr_major; + const uint8_t* sp_minor = src_ptr_minor; + + if (first_column) { + src_len--; + if ((src_len <= 0u) && last_column) { + uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + // + (4u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + 8u) >> 4u); + *dp++ = (uint8_t)((sv + 7u) >> 4u); + return dst_ptr; } - self->private_impl.f_padding -= 14u; - self->private_impl.f_io_redirect_pos = wuffs_base__u64__sat_add(((uint64_t)(self->private_impl.f_padding)), wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; - if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; - } - } - self->private_impl.f_bitmap_info_len = t_2; + + uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero. + uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero. + uint32_t sv_major_p1 = sp_major[+1]; + uint32_t sv_minor_p1 = sp_minor[+1]; + + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + if (src_len <= 0u) { + return dst_ptr; } - if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; + } + + if (last_column) { + src_len--; + } + + for (; src_len > 0u; src_len--) { + uint32_t sv_major_m1 = sp_major[-1]; + uint32_t sv_minor_m1 = sp_minor[-1]; + uint32_t sv_major_p1 = sp_major[+1]; + uint32_t sv_minor_p1 = sp_minor[+1]; + + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + } + + if (last_column) { + uint32_t sv_major_m1 = sp_major[-1]; + uint32_t sv_minor_m1 = sp_minor[-1]; + uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero. + uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero. + + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + } + + return dst_ptr; +} + +// wuffs_private_impl__swizzle_ycc__upsample_funcs is indexed by inv_h and then +// inv_v. +static const wuffs_private_impl__swizzle_ycc__upsample_func + wuffs_private_impl__swizzle_ycc__upsample_funcs[4][4] = { + { + wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h1vn_box, + }, + { + wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h2vn_box, + }, + { + wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h3vn_box, + }, + { + wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box, + wuffs_private_impl__swizzle_ycc__upsample_inv_h4vn_box, + }, +}; + +static inline uint32_t // +wuffs_private_impl__swizzle_has_triangle_upsampler(uint32_t inv_h, + uint32_t inv_v) { + if (inv_h == 1u) { + return inv_v == 2u; + } else if (inv_h == 2u) { + return (inv_v == 1u) || (inv_v == 2u); + } + return false; +} + +// -------- + +// All of the wuffs_private_impl__swizzle_ycc__etc functions have +// preconditions. See all of the checks made in +// wuffs_base__pixel_swizzler__swizzle_ycck before calling these functions. For +// example, (width > 0) is a precondition, but there are many more. + +static void // +wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( + wuffs_base__pixel_buffer* dst, + uint32_t width, + uint32_t y, + 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 h1v2_bias, + uint8_t* scratch_buffer_2k_ptr, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc0, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc1, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc2, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc3, + wuffs_private_impl__swizzle_ycc__convert_4_func conv4func) { + const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0); + const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1); + const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2); + const uint8_t* src3 = src_ptr3 + ((y / inv_v3) * (size_t)stride3); + uint32_t total_src_len0 = 0u; + uint32_t total_src_len1 = 0u; + uint32_t total_src_len2 = 0u; + uint32_t total_src_len3 = 0u; + + uint32_t x = 0u; + while (x < width) { + bool first_column = x == 0u; + uint32_t end = x + 480u; + if (end > width) { + end = width; } - self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len; - if (self->private_impl.f_bitmap_info_len == 12u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; - if (num_bits_3 == 8) { - t_3 = ((uint32_t)(*scratch)); - break; - } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)) << 56; - } - } - self->private_impl.f_width = t_3; + + 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; + total_src_len0 += src_len0; + total_src_len1 += src_len1; + total_src_len2 += src_len2; + total_src_len3 += src_len3; + + const uint8_t* src_ptr_x0 = src0 + (x / inv_h0); + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 480u), // + src_ptr_x0, // + src_ptr_x0, // + src_len0, // + h1v2_bias, // + first_column, // + (total_src_len0 >= half_width_for_2to1)); + + const uint8_t* src_ptr_x1 = src1 + (x / inv_h1); + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 480u), // + src_ptr_x1, // + src_ptr_x1, // + src_len1, // + h1v2_bias, // + first_column, // + (total_src_len1 >= half_width_for_2to1)); + + const uint8_t* src_ptr_x2 = src2 + (x / inv_h2); + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 480u), // + src_ptr_x2, // + src_ptr_x2, // + src_len2, // + h1v2_bias, // + first_column, // + (total_src_len2 >= half_width_for_2to1)); + + const uint8_t* src_ptr_x3 = src3 + (x / inv_h3); + const uint8_t* up3 = (*upfunc3)( // + scratch_buffer_2k_ptr + (3u * 480u), // + src_ptr_x3, // + src_ptr_x3, // + src_len3, // + h1v2_bias, // + first_column, // + (total_src_len3 >= half_width_for_2to1)); + + (*conv4func)(dst, x, end, y, up0, up1, up2, up3); + x = end; + } +} + +static void // +wuffs_private_impl__swizzle_ycck__general__triangle_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) { + 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 = + (*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]; + + // First row. + uint32_t h1v2_bias = 1u; + wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( + 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, // + inv_v0, inv_v1, inv_v2, inv_v3, // + half_width_for_2to1, // + h1v2_bias, // + scratch_buffer_2k_ptr, // + upfunc0, upfunc1, upfunc2, upfunc3, conv4func); + h1v2_bias = 2u; + + // Middle rows. + 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 < 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) + ? src0_major + : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0)); + const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1); + const uint8_t* src1_minor = + (inv_v1 != 2u) + ? src1_major + : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1)); + const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2); + const uint8_t* src2_minor = + (inv_v2 != 2u) + ? src2_major + : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2)); + const uint8_t* src3_major = src_ptr3 + ((y / inv_v3) * (size_t)stride3); + const uint8_t* src3_minor = + (inv_v3 != 2u) + ? src3_major + : ((y & 1u) ? (src3_major + stride3) : (src3_major - stride3)); + uint32_t total_src_len0 = 0u; + uint32_t total_src_len1 = 0u; + uint32_t total_src_len2 = 0u; + uint32_t total_src_len3 = 0u; + + uint32_t x = 0u; + while (x < x_max_excl) { + bool first_column = x == 0u; + uint32_t end = x + 480u; + if (end > x_max_excl) { + end = x_max_excl; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 8) { - t_4 = ((uint32_t)(*scratch)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; - } - } - self->private_impl.f_height = t_4; + + 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; + total_src_len0 += src_len0; + total_src_len1 += src_len1; + total_src_len2 += src_len2; + total_src_len3 += src_len3; + + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 480u), // + src0_major + (x / inv_h0), // + src0_minor + (x / inv_h0), // + src_len0, // + h1v2_bias, // + first_column, // + (total_src_len0 >= half_width_for_2to1)); + + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 480u), // + src1_major + (x / inv_h1), // + src1_minor + (x / inv_h1), // + src_len1, // + h1v2_bias, // + first_column, // + (total_src_len1 >= half_width_for_2to1)); + + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 480u), // + src2_major + (x / inv_h2), // + src2_minor + (x / inv_h2), // + src_len2, // + h1v2_bias, // + first_column, // + (total_src_len2 >= half_width_for_2to1)); + + const uint8_t* up3 = (*upfunc3)( // + scratch_buffer_2k_ptr + (3u * 480u), // + src3_major + (x / inv_h3), // + src3_minor + (x / inv_h3), // + src_len3, // + h1v2_bias, // + first_column, // + (total_src_len3 >= half_width_for_2to1)); + + (*conv4func)(dst, x, end, y, up0, up1, up2, up3); + x = end; + } + + h1v2_bias ^= 3u; + } + + // Last row. + if (middle_y_max_excl != y_max_excl) { + wuffs_private_impl__swizzle_ycck__general__triangle_filter_edge_row( + 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, // + inv_v0, inv_v1, inv_v2, inv_v3, // + half_width_for_2to1, // + h1v2_bias, // + scratch_buffer_2k_ptr, // + upfunc0, upfunc1, upfunc2, upfunc3, conv4func); + } +} + +static void // +wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( + wuffs_base__pixel_buffer* dst, + uint32_t width, + uint32_t y, + 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 h1v2_bias, + uint8_t* scratch_buffer_2k_ptr, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc0, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc1, + wuffs_private_impl__swizzle_ycc__upsample_func upfunc2, + wuffs_private_impl__swizzle_ycc__convert_3_func conv3func) { + const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0); + const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1); + const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2); + uint32_t total_src_len0 = 0u; + uint32_t total_src_len1 = 0u; + uint32_t total_src_len2 = 0u; + + uint32_t x = 0u; + while (x < width) { + bool first_column = x == 0u; + uint32_t end = x + 672u; + if (end > width) { + end = width; + } + + 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; + total_src_len0 += src_len0; + total_src_len1 += src_len1; + total_src_len2 += src_len2; + + const uint8_t* src_ptr_x0 = src0 + (x / inv_h0); + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 672u), // + src_ptr_x0, // + src_ptr_x0, // + src_len0, // + h1v2_bias, // + first_column, // + (total_src_len0 >= half_width_for_2to1)); + + const uint8_t* src_ptr_x1 = src1 + (x / inv_h1); + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 672u), // + src_ptr_x1, // + src_ptr_x1, // + src_len1, // + h1v2_bias, // + first_column, // + (total_src_len1 >= half_width_for_2to1)); + + const uint8_t* src_ptr_x2 = src2 + (x / inv_h2); + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 672u), // + src_ptr_x2, // + src_ptr_x2, // + src_len2, // + h1v2_bias, // + first_column, // + (total_src_len2 >= half_width_for_2to1)); + + (*conv3func)(dst, x, end, y, up0, up1, up2); + x = end; + } +} + +static void // +wuffs_private_impl__swizzle_ycc__general__triangle_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, + 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) { + 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 = + (*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]; + + // First row. + uint32_t h1v2_bias = 1u; + wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( + dst, x_max_excl, 0u, // + 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); + h1v2_bias = 2u; + + // Middle rows. + 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 < 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) + ? src0_major + : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0)); + const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1); + const uint8_t* src1_minor = + (inv_v1 != 2u) + ? src1_major + : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1)); + const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2); + const uint8_t* src2_minor = + (inv_v2 != 2u) + ? src2_major + : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2)); + uint32_t total_src_len0 = 0u; + uint32_t total_src_len1 = 0u; + uint32_t total_src_len2 = 0u; + + uint32_t x = 0u; + while (x < x_max_excl) { + bool first_column = x == 0u; + uint32_t end = x + 672u; + if (end > x_max_excl) { + end = x_max_excl; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - uint32_t t_5; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5; - if (num_bits_5 == 8) { - t_5 = ((uint32_t)(*scratch)); - break; - } - num_bits_5 += 8u; - *scratch |= ((uint64_t)(num_bits_5)) << 56; - } - } - v_planes = t_5; + + 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; + total_src_len0 += src_len0; + total_src_len1 += src_len1; + total_src_len2 += src_len2; + + const uint8_t* up0 = (*upfunc0)( // + scratch_buffer_2k_ptr + (0u * 672u), // + src0_major + (x / inv_h0), // + src0_minor + (x / inv_h0), // + src_len0, // + h1v2_bias, // + first_column, // + (total_src_len0 >= half_width_for_2to1)); + + const uint8_t* up1 = (*upfunc1)( // + scratch_buffer_2k_ptr + (1u * 672u), // + src1_major + (x / inv_h1), // + src1_minor + (x / inv_h1), // + src_len1, // + h1v2_bias, // + first_column, // + (total_src_len1 >= half_width_for_2to1)); + + const uint8_t* up2 = (*upfunc2)( // + scratch_buffer_2k_ptr + (2u * 672u), // + src2_major + (x / inv_h2), // + src2_minor + (x / inv_h2), // + src_len2, // + h1v2_bias, // + first_column, // + (total_src_len2 >= half_width_for_2to1)); + + (*conv3func)(dst, x, end, y, up0, up1, up2); + x = end; + } + + h1v2_bias ^= 3u; + } + + // Last row. + if (middle_y_max_excl != y_max_excl) { + wuffs_private_impl__swizzle_ycc__general__triangle_filter_edge_row( + 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); + } +} + +static void // +wuffs_private_impl__swizzle_ycc__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, + 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__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]; + + 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); + + uint32_t x = x_min_incl; + while (x < x_max_excl) { + uint32_t end = x + 672u; + if (end > x_max_excl) { + end = x_max_excl; } - if (v_planes != 1u) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; + + 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 - 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 - 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 - 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); + x = end; + } + } +} + +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; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); - uint32_t t_6; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6; - if (num_bits_6 == 8) { - t_6 = ((uint32_t)(*scratch)); - break; - } - num_bits_6 += 8u; - *scratch |= ((uint64_t)(num_bits_6)) << 56; - } - } - self->private_impl.f_bits_per_pixel = t_6; - } - } else if (self->private_impl.f_bitmap_info_len == 16u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - uint32_t t_7; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; - if (num_bits_7 == 24) { - t_7 = ((uint32_t)(*scratch)); - break; - } - num_bits_7 += 8u; - *scratch |= ((uint64_t)(num_bits_7)) << 56; - } - } - v_width = t_7; - } - if (v_width > 2147483647u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } else if (v_width > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_width = v_width; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); - uint32_t t_8; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8; - if (num_bits_8 == 24) { - t_8 = ((uint32_t)(*scratch)); - break; - } - num_bits_8 += 8u; - *scratch |= ((uint64_t)(num_bits_8)) << 56; - } - } - v_height = t_8; - } - if (v_height > 2147483647u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } else if (v_height > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_height = v_height; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); - uint32_t t_9; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9; - if (num_bits_9 == 8) { - t_9 = ((uint32_t)(*scratch)); - break; - } - num_bits_9 += 8u; - *scratch |= ((uint64_t)(num_bits_9)) << 56; - } - } - v_planes = t_9; - } - if (v_planes != 1u) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); - uint32_t t_10; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10; - if (num_bits_10 == 8) { - t_10 = ((uint32_t)(*scratch)); - break; - } - num_bits_10 += 8u; - *scratch |= ((uint64_t)(num_bits_10)) << 56; - } - } - self->private_impl.f_bits_per_pixel = t_10; - } - } else { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); - uint32_t t_11; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11; - if (num_bits_11 == 24) { - t_11 = ((uint32_t)(*scratch)); - break; - } - num_bits_11 += 8u; - *scratch |= ((uint64_t)(num_bits_11)) << 56; - } - } - v_width = t_11; - } - if (v_width > 2147483647u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } else if (v_width > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_width = v_width; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26); - uint32_t t_12; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12; - if (num_bits_12 == 24) { - t_12 = ((uint32_t)(*scratch)); - break; - } - num_bits_12 += 8u; - *scratch |= ((uint64_t)(num_bits_12)) << 56; - } - } - v_height = t_12; - } - if (v_height == 2147483648u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } else if (v_height > 2147483648u) { - v_height = ((uint32_t)(0u - v_height)); - if (v_height > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_height = v_height; - self->private_impl.f_top_down = true; - } else if (v_height > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } else { - self->private_impl.f_height = v_height; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28); - uint32_t t_13; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13; - if (num_bits_13 == 8) { - t_13 = ((uint32_t)(*scratch)); - break; - } - num_bits_13 += 8u; - *scratch |= ((uint64_t)(num_bits_13)) << 56; - } + + 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 +// wuffs_base__table__flattened_length but returns uint64_t (not size_t) and +// also accounts for subsampling. +static uint64_t // +wuffs_private_impl__swizzle_flattened_length(uint32_t width, + uint32_t height, + uint32_t stride, + uint32_t inv_h, + uint32_t inv_v) { + uint64_t scaled_width = (((uint64_t)width) + (inv_h - 1u)) / inv_h; + uint64_t scaled_height = (((uint64_t)height) + (inv_v - 1u)) / inv_v; + if (scaled_height <= 0u) { + return 0u; + } + return ((scaled_height - 1u) * stride) + scaled_width; +} + +WUFFS_BASE__MAYBE_STATIC wuffs_base__status // +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 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, + wuffs_base__slice_u8 src3, + uint32_t width0, + uint32_t width1, + uint32_t width2, + uint32_t width3, + uint32_t height0, + uint32_t height1, + uint32_t height2, + uint32_t height3, + uint32_t stride0, + uint32_t stride1, + uint32_t stride2, + uint32_t stride3, + uint8_t h0, + uint8_t h1, + uint8_t h2, + uint8_t h3, + uint8_t v0, + uint8_t v1, + uint8_t v2, + uint8_t v3, + bool is_rgb_or_cmyk, + bool triangle_filter_for_2to1, + wuffs_base__slice_u8 scratch_buffer_2k) { + if (!p) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } 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); + } + if ((h3 != 0u) || (v3 != 0u)) { + if ((4u <= ((unsigned int)h3 - 1u)) || // + (4u <= ((unsigned int)v3 - 1u))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + } + + uint32_t max_incl_h = wuffs_private_impl__u32__max_of_4(h0, h1, h2, h3); + uint32_t max_incl_v = wuffs_private_impl__u32__max_of_4(v0, v1, v2, v3); + + // Calculate the inverse h and v ratios. + // + // It also canonicalizes (h=2 and max_incl_h=4) as equivalent to (h=1 and + // max_incl_h=2). In both cases, the inv_h value is 2. + uint32_t inv_h0 = max_incl_h / h0; + uint32_t inv_h1 = max_incl_h / h1; + uint32_t inv_h2 = max_incl_h / h2; + uint32_t inv_h3 = h3 ? (max_incl_h / h3) : 0u; + uint32_t inv_v0 = max_incl_v / v0; + uint32_t inv_v1 = max_incl_v / v1; + uint32_t inv_v2 = max_incl_v / v2; + uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u; + + 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) || // + ((h2 * inv_h2) != max_incl_h) || // + ((v0 * inv_v0) != max_incl_v) || // + ((v1 * inv_v1) != max_incl_v) || // + ((v2 * inv_v2) != max_incl_v) || // + (src0.len < wuffs_private_impl__swizzle_flattened_length( + width, height, stride0, inv_h0, inv_v0)) || + (src1.len < wuffs_private_impl__swizzle_flattened_length( + width, height, stride1, inv_h1, inv_v1)) || + (src2.len < wuffs_private_impl__swizzle_flattened_length( + width, height, stride2, inv_h2, inv_v2))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((h3 != 0u) || (v3 != 0u)) { + if (((h3 * inv_h3) != max_incl_h) || // + ((v3 * inv_v3) != max_incl_v) || // + (src3.len < wuffs_private_impl__swizzle_flattened_length( + width, height, stride3, inv_h3, inv_v3))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + } + + if (wuffs_base__pixel_format__is_planar(&dst->pixcfg.private_impl.pixfmt)) { + // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO. + return wuffs_base__make_status( + wuffs_base__error__unsupported_pixel_swizzler_option); + } + + // ---- + +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST) + switch (dst->pixcfg.private_impl.pixfmt.repr) { +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR_565) + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGR) + case WUFFS_BASE__PIXEL_FORMAT__BGR: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_NONPREMUL_4X16LE) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_BGRA_PREMUL) + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGB) + case WUFFS_BASE__PIXEL_FORMAT__RGB: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_NONPREMUL) + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + break; +#endif +#if defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ALLOW_RGBA_PREMUL) + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + break; +#endif + default: + return wuffs_base__make_status( + wuffs_base__error__disabled_by_wuffs_config_dst_pixel_format_enable_allowlist); + } +#else // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST) + switch (dst->pixcfg.private_impl.pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__Y: + case WUFFS_BASE__PIXEL_FORMAT__Y_16LE: + case WUFFS_BASE__PIXEL_FORMAT__Y_16BE: + case WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: + case WUFFS_BASE__PIXEL_FORMAT__BGR_565: + case WUFFS_BASE__PIXEL_FORMAT__BGR: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: + case WUFFS_BASE__PIXEL_FORMAT__RGB: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: + break; + + default: + // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO. + return wuffs_base__make_status( + wuffs_base__error__unsupported_pixel_swizzler_option); + } +#endif // defined(WUFFS_CONFIG__DST_PIXEL_FORMAT__ENABLE_ALLOWLIST) + + // ---- + + wuffs_private_impl__swizzle_ycc__convert_3_func conv3func = NULL; + + if (is_rgb_or_cmyk) { + conv3func = &wuffs_private_impl__swizzle_rgb__convert_3_general; + } else { + switch (dst->pixcfg.private_impl.pixfmt.repr) { + case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__BGRX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) + if (wuffs_base__cpu_arch__have_x86_avx2()) { + conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2; + break; } - v_planes = t_13; - } - if (v_planes != 1u) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30); - uint32_t t_14; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14; - if (num_bits_14 == 8) { - t_14 = ((uint32_t)(*scratch)); - break; - } - num_bits_14 += 8u; - *scratch |= ((uint64_t)(num_bits_14)) << 56; - } +#endif + conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_bgrx; + break; + case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL: + case WUFFS_BASE__PIXEL_FORMAT__RGBX: +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) + if (wuffs_base__cpu_arch__have_x86_avx2()) { + conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2; + break; } - self->private_impl.f_bits_per_pixel = t_14; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32); - uint32_t t_15; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15; - if (num_bits_15 == 24) { - t_15 = ((uint32_t)(*scratch)); - break; - } - num_bits_15 += 8u; - *scratch |= ((uint64_t)(num_bits_15)) << 56; - } - } - self->private_impl.f_compression = t_15; - } - if (self->private_impl.f_bits_per_pixel == 0u) { - if (self->private_impl.f_compression == 4u) { - self->private_impl.f_io_redirect_fourcc = 1246774599u; - status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); - goto ok; - } else if (self->private_impl.f_compression == 5u) { - self->private_impl.f_io_redirect_fourcc = 1347307296u; - status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); - goto ok; - } - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - self->private_data.s_do_decode_image_config[0].scratch = 20u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - if (self->private_impl.f_bitmap_info_len == 40u) { - if (self->private_impl.f_bits_per_pixel >= 16u) { - if (self->private_impl.f_padding >= 16u) { - self->private_impl.f_bitmap_info_len = 56u; - self->private_impl.f_padding -= 16u; - } else if (self->private_impl.f_padding >= 12u) { - self->private_impl.f_bitmap_info_len = 52u; - self->private_impl.f_padding -= 12u; - } - } - } else if ((self->private_impl.f_bitmap_info_len != 52u) && - (self->private_impl.f_bitmap_info_len != 56u) && - (self->private_impl.f_bitmap_info_len != 64u) && - (self->private_impl.f_bitmap_info_len != 108u) && - (self->private_impl.f_bitmap_info_len != 124u)) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - if (self->private_impl.f_compression == 6u) { - self->private_impl.f_compression = 3u; - } - if (self->private_impl.f_compression == 3u) { - if (self->private_impl.f_bitmap_info_len >= 52u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35); - uint32_t t_16; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16; - if (num_bits_16 == 24) { - t_16 = ((uint32_t)(*scratch)); - break; - } - num_bits_16 += 8u; - *scratch |= ((uint64_t)(num_bits_16)) << 56; - } - } - self->private_impl.f_channel_masks[2u] = t_16; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37); - uint32_t t_17; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17; - if (num_bits_17 == 24) { - t_17 = ((uint32_t)(*scratch)); - break; - } - num_bits_17 += 8u; - *scratch |= ((uint64_t)(num_bits_17)) << 56; - } - } - self->private_impl.f_channel_masks[1u] = t_17; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39); - uint32_t t_18; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18; - if (num_bits_18 == 24) { - t_18 = ((uint32_t)(*scratch)); - break; - } - num_bits_18 += 8u; - *scratch |= ((uint64_t)(num_bits_18)) << 56; - } - } - self->private_impl.f_channel_masks[0u] = t_18; - } - if (self->private_impl.f_bitmap_info_len >= 56u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41); - uint32_t t_19; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19; - if (num_bits_19 == 24) { - t_19 = ((uint32_t)(*scratch)); - break; - } - num_bits_19 += 8u; - *scratch |= ((uint64_t)(num_bits_19)) << 56; - } - } - self->private_impl.f_channel_masks[3u] = t_19; - } - self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56u)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - } - if ((self->private_impl.f_channel_masks[0u] == 255u) && (self->private_impl.f_channel_masks[1u] == 65280u) && (self->private_impl.f_channel_masks[2u] == 16711680u)) { - if (self->private_impl.f_bits_per_pixel == 24u) { - self->private_impl.f_compression = 0u; - } else if (self->private_impl.f_bits_per_pixel == 32u) { - if ((self->private_impl.f_channel_masks[3u] == 0u) || (self->private_impl.f_channel_masks[3u] == 4278190080u)) { - self->private_impl.f_compression = 0u; - } - } - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44); - status = wuffs_bmp__decoder__process_masks(self); - if (status.repr) { - goto suspend; - } - } - } else if (self->private_impl.f_bitmap_info_len >= 40u) { - self->private_data.s_do_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40u); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - } - if (self->private_impl.f_compression != 3u) { - if (self->private_impl.f_bits_per_pixel < 16u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46); - status = wuffs_bmp__decoder__read_palette(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } - } - if (self->private_impl.f_compression == 0u) { - if ((self->private_impl.f_bits_per_pixel == 1u) || (self->private_impl.f_bits_per_pixel == 2u) || (self->private_impl.f_bits_per_pixel == 4u)) { - self->private_impl.f_src_pixfmt = 2198077448u; - self->private_impl.f_compression = 256u; - } else if (self->private_impl.f_bits_per_pixel == 8u) { - self->private_impl.f_src_pixfmt = 2198077448u; - } else if (self->private_impl.f_bits_per_pixel == 16u) { - self->private_impl.f_compression = 3u; - self->private_impl.f_channel_masks[0u] = 31u; - self->private_impl.f_channel_masks[1u] = 992u; - self->private_impl.f_channel_masks[2u] = 31744u; - self->private_impl.f_channel_masks[3u] = 0u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47); - status = wuffs_bmp__decoder__process_masks(self); - if (status.repr) { - goto suspend; - } - self->private_impl.f_src_pixfmt = 2164308923u; - } else if (self->private_impl.f_bits_per_pixel == 24u) { - self->private_impl.f_src_pixfmt = 2147485832u; - } else if (self->private_impl.f_bits_per_pixel == 32u) { - if (self->private_impl.f_channel_masks[3u] == 0u) { - self->private_impl.f_src_pixfmt = 2415954056u; - } else { - self->private_impl.f_src_pixfmt = 2164295816u; - } - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - } else if (self->private_impl.f_compression == 1u) { - if (self->private_impl.f_bits_per_pixel == 8u) { - self->private_impl.f_src_pixfmt = 2198077448u; - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - } else if (self->private_impl.f_compression == 2u) { - if (self->private_impl.f_bits_per_pixel == 4u) { - self->private_impl.f_src_pixfmt = 2198077448u; - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - } else if (self->private_impl.f_compression == 3u) { - if ((self->private_impl.f_bits_per_pixel == 16u) || (self->private_impl.f_bits_per_pixel == 32u)) { - self->private_impl.f_src_pixfmt = 2164308923u; - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - } else { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - if (((self->private_impl.f_bitmap_info_len < 40u) || (self->private_impl.f_bitmap_info_len == 64u)) && - (self->private_impl.f_bits_per_pixel != 1u) && - (self->private_impl.f_bits_per_pixel != 4u) && - (self->private_impl.f_bits_per_pixel != 8u) && - (self->private_impl.f_bits_per_pixel != 24u)) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } - if (self->private_impl.f_bits_per_pixel == 1u) { - v_byte_width = ((self->private_impl.f_width >> 3u) + (((self->private_impl.f_width & 7u) + 7u) >> 3u)); - self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); - } else if (self->private_impl.f_bits_per_pixel == 2u) { - v_byte_width = ((self->private_impl.f_width >> 2u) + (((self->private_impl.f_width & 3u) + 3u) >> 2u)); - self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); - } else if (self->private_impl.f_bits_per_pixel == 4u) { - v_byte_width = ((self->private_impl.f_width >> 1u) + (self->private_impl.f_width & 1u)); - self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); - } else if (self->private_impl.f_bits_per_pixel == 8u) { - self->private_impl.f_pad_per_row = ((4u - (self->private_impl.f_width & 3u)) & 3u); - } else if (self->private_impl.f_bits_per_pixel == 16u) { - self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1u) * 2u); - } else if (self->private_impl.f_bits_per_pixel == 24u) { - self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3u); - } else if (self->private_impl.f_bits_per_pixel == 32u) { - self->private_impl.f_pad_per_row = 0u; - } - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - if (a_dst != NULL) { - v_dst_pixfmt = 2164295816u; - if ((self->private_impl.f_channel_num_bits[0u] > 8u) || - (self->private_impl.f_channel_num_bits[1u] > 8u) || - (self->private_impl.f_channel_num_bits[2u] > 8u) || - (self->private_impl.f_channel_num_bits[3u] > 8u)) { - v_dst_pixfmt = 2164308923u; - } - wuffs_base__image_config__set( - a_dst, - v_dst_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - (self->private_impl.f_channel_masks[3u] == 0u)); +#endif + conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_rgbx; + break; + default: + conv3func = &wuffs_private_impl__swizzle_ycc__convert_3_general; + break; } - self->private_impl.f_call_sequence = 32u; - - ok: - self->private_impl.p_do_decode_image_config[0] = 0; - goto exit; } - goto suspend; - suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + 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); - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + 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) || + 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; + upfuncs[1][1] = wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle; + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +#if defined(__GNUC__) && !defined(__clang__) + // Don't use our AVX2 implementation for GCC (but do use it for clang). For + // some unknown reason, GCC performs noticably better on the non-SIMD + // version. Possibly because GCC's auto-vectorizer is smarter (just with + // SSE2, not AVX2) than our hand-written code, but that's just a guess. + // + // See commits 51bc60ef9298cb2efc1b29a9681191f66d49820d and + // cd769a0cdf1b5affee13f6089b995f3d39569cb4 for benchmark numbers. + // + // See also https://godbolt.org/z/MbhbPGEz4 for Debian Bullseye's clang 11 + // versus gcc 10, where only gcc auto-vectorizes, although later clang + // versions will also auto-vectorize. +#else + if (wuffs_base__cpu_arch__have_x86_avx2()) { + upfuncs[1][1] = + wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2; + } +#endif +#endif } - return status; -} - -// -------- func bmp.decoder.decode_frame_config + if ((h3 != 0u) || (v3 != 0u)) { + 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; + (*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); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__decode_frame_config( - wuffs_bmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } else { + (*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); } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + return wuffs_base__make_status(NULL); +} - while (true) { - { - wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +// -------- - ok: - self->private_impl.p_decode_frame_config[0] = 0; - goto exit; +// ‼ WUFFS MULTI-FILE SECTION +x86_avx2 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static void // +wuffs_private_impl__swizzle_ycc__convert_3_bgrx_x86_avx2( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + if ((x + 32u) > x_end) { + wuffs_private_impl__swizzle_ycc__convert_3_bgrx( // + dst, x, x_end, y, up0, up1, up2); + return; } - goto suspend; - suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + size_t dst_stride = dst->private_impl.planes[0].stride; + uint8_t* dst_iter = dst->private_impl.planes[0].ptr + + (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} + // u0001 = u16x16 [0x0001 .. 0x0001] + // u00FF = u16x16 [0x00FF .. 0x00FF] + // uFF80 = u16x16 [0xFF80 .. 0xFF80] + // uFFFF = u16x16 [0xFFFF .. 0xFFFF] + const __m256i u0001 = _mm256_set1_epi16(+0x0001); + const __m256i u00FF = _mm256_set1_epi16(+0x00FF); + const __m256i uFF80 = _mm256_set1_epi16(-0x0080); + const __m256i uFFFF = _mm256_set1_epi16(-0x0001); -// -------- func bmp.decoder.do_decode_frame_config + // p8000_p0000 = u16x16 [0x8000 0x0000 .. 0x8000 0x0000] + const __m256i p8000_p0000 = _mm256_set_epi16( // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_frame_config( - wuffs_bmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + // Per wuffs_base__color_ycc__as__color_u32, the formulae: + // + // R = Y + 1.40200 * Cr + // G = Y - 0.34414 * Cb - 0.71414 * Cr + // B = Y + 1.77200 * Cb + // + // When scaled by 1<<16: + // + // 0.34414 becomes 0x0581A = 22554. + // 0.71414 becomes 0x0B6D2 = 46802. + // 1.40200 becomes 0x166E9 = 91881. + // 1.77200 becomes 0x1C5A2 = 116130. + // + // Separate the integer and fractional parts, since we work with signed + // 16-bit SIMD lanes. The fractional parts range from -0.5 .. +0.5 (as + // floating-point) which is from -0x8000 .. +0x8000 (as fixed-point). + // + // -0x3A5E = -0x20000 + 0x1C5A2 The B:Cb factor. + // +0x66E9 = -0x10000 + 0x166E9 The R:Cr factor. + // -0x581A = +0x00000 - 0x0581A The G:Cb factor. + // +0x492E = +0x10000 - 0x0B6D2 The G:Cr factor. + const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E); + const __m256i p66E9 = _mm256_set1_epi16(+0x66E9); + const __m256i m581A_p492E = _mm256_set_epi16( // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + while (x < x_end) { + // Load chroma values in even and odd columns (the high 8 bits of each + // u16x16 element are zero) and then subtract 0x0080. + // + // cb_all = u8x32 [cb.00 cb.01 cb.02 cb.03 .. cb.1C cb.1D cb.1E cb.1F] + // cb_eve = i16x16 [cb.00-0x80 cb.02-0x80 .. cb.1C-0x80 cb.1E-0x80 ] + // cb_odd = i16x16 [cb.01-0x80 cb.03-0x80 .. cb.1D-0x80 cb.1F-0x80 ] + // + // Ditto for the cr_xxx Chroma-Red values. + __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1); + __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2); + __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF)); + __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF)); + __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8)); + __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8)); - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + // ---- - if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_bmp__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; - } - } else if (self->private_impl.f_call_sequence == 64u) { - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height), - ((wuffs_base__flicks)(0u)), - 0u, - self->private_impl.f_frame_config_io_position, - 0u, - true, - false, - 4278190080u); - } - self->private_impl.f_call_sequence = 64u; + // Calculate: + // + // B-Y = (+1.77200 * Cb) as floating-point + // R-Y = (+1.40200 * Cr) as floating-point + // + // B-Y = ((0x2_0000 - 0x3A5E) * Cb) as fixed-point + // R-Y = ((0x1_0000 + 0x66E9) * Cr) as fixed-point + // + // B-Y = ((-0x3A5E * Cb) + ("2.0" * Cb)) + // R-Y = ((+0x66E9 * Cr) + ("1.0" * Cr)) - ok: - self->private_impl.p_do_decode_frame_config[0] = 0; - goto exit; - } + // Multiply by m3A5E or p66E9, taking the high 16 bits. There's also a + // doubling (add x to itself), adding-of-1 and halving (shift right by 1). + // That makes multiply-and-take-high round to nearest (instead of down). + __m256i tmp_by_eve = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001), + 1); + __m256i tmp_by_odd = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001), + 1); + __m256i tmp_ry_eve = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001), + 1); + __m256i tmp_ry_odd = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001), + 1); - goto suspend; - suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + // Add (2 * Cb) and (1 * Cr). + __m256i by_eve = + _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve)); + __m256i by_odd = + _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd)); + __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve); + __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd); - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } + // ---- - return status; -} + // Calculate: + // + // G-Y = (-0.34414 * Cb) + + // (-0.71414 * Cr) as floating-point + // + // G-Y = ((+0x0_0000 - 0x581A) * Cb) + + // ((-0x1_0000 + 0x492E) * Cr) as fixed-point + // + // G-Y = (-0x581A * Cb) + + // (+0x492E * Cr) - ("1.0" * Cr) -// -------- func bmp.decoder.decode_frame + // Multiply-add to get ((-0x581A * Cb) + (+0x492E * Cr)). + __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( // + _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E); + __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( // + _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E); + __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( // + _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E); + __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( // + _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__decode_frame( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); + // Divide the i32x8 vectors by (1 << 16), rounding to nearest. + __m256i tmp1_gy_eve_lo = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16); + __m256i tmp1_gy_eve_hi = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16); + __m256i tmp1_gy_odd_lo = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16); + __m256i tmp1_gy_odd_hi = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16); - wuffs_base__status v_status = wuffs_base__make_status(NULL); + // Pack the ((-0x581A * Cb) + (+0x492E * Cr)) as i16x16 and subtract Cr. + __m256i gy_eve = _mm256_sub_epi16( + _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve); + __m256i gy_odd = _mm256_sub_epi16( + _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd); - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + // ---- - while (true) { - { - wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } + // Add Y to (B-Y), (G-Y) and (R-Y) to produce B, G and R. + // + // For the resultant packed_x_xxx vectors, only elements 0 ..= 7 and 16 ..= + // 23 of the 32-element vectors matter (since we'll unpacklo but not + // unpackhi them). Let … denote 8 ignored consecutive u8 values and let % + // denote 0xFF. We'll end this section with: + // + // packed_b_eve = u8x32 [b00 b02 .. b0C b0E … b10 b12 .. b1C b1E …] + // packed_b_odd = u8x32 [b01 b03 .. b0D b0F … b11 b13 .. b1D b1F …] + // packed_g_eve = u8x32 [g00 g02 .. g0C g0E … g10 g12 .. g1C g1E …] + // packed_g_odd = u8x32 [g01 g03 .. g0D g0F … g11 g13 .. g1D g1F …] + // packed_r_eve = u8x32 [r00 r02 .. r0C r0E … r10 r12 .. r1C r1E …] + // packed_r_odd = u8x32 [r01 r03 .. r0D r0F … r11 r13 .. r1D r1F …] + // uFFFF = u8x32 [ % % .. % % … % % .. % % …] - ok: - self->private_impl.p_decode_frame[0] = 0; - goto exit; - } + __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0); + __m256i yy_eve = _mm256_and_si256(yy_all, u00FF); + __m256i yy_odd = _mm256_srli_epi16(yy_all, 8); - goto suspend; - suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve); + __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd); + __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve); + __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd); - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} + __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve); + __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd); + __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve); + __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd); -// -------- func bmp.decoder.do_decode_frame + __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve); + __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd); + __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve); + __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_decode_frame( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - wuffs_base__status status = wuffs_base__make_status(NULL); + // ---- - wuffs_base__status v_status = wuffs_base__make_status(NULL); + // Mix those values (unpacking in 8, 16 and then 32 bit units) to get the + // desired BGRX/RGBX order. + // + // From here onwards, all of our __m256i registers are u8x32. - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + // mix00 = [b00 g00 b02 g02 .. b0E g0E b10 g10 .. b1C g1C b1E g1E] + // mix01 = [b01 g01 b03 g03 .. b0F g0F b11 g11 .. b1D g1D b1F g1F] + // mix02 = [r00 % r02 % .. r0E % r10 % .. r1C % r1E %] + // mix03 = [r01 % r03 % .. r0F % r11 % .. r1D % r1F %] + // + // See also § below. + __m256i mix00 = _mm256_unpacklo_epi8(packed_b_eve, packed_g_eve); + __m256i mix01 = _mm256_unpacklo_epi8(packed_b_odd, packed_g_odd); + __m256i mix02 = _mm256_unpacklo_epi8(packed_r_eve, uFFFF); + __m256i mix03 = _mm256_unpacklo_epi8(packed_r_odd, uFFFF); - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + // mix10 = [b00 g00 r00 % b02 g02 r02 % b04 g04 r04 % b06 g06 r06 % + // b10 g10 r10 % b12 g12 r12 % b14 g14 r14 % b16 g16 r16 %] + // mix11 = [b01 g01 r01 % b03 g03 r03 % b05 g05 r05 % b07 g07 r07 % + // b11 g11 r11 % b13 g13 r13 % b15 g15 r15 % b17 g17 r17 %] + // mix12 = [b08 g08 r08 % b0A g0A r0A % b0C g0C r0C % b0E g0E r0E % + // b18 g18 r18 % b1A g1A r1A % b1C g1C r1C % b1E g1E r1E %] + // mix13 = [b09 g09 r09 % b0B g0B r0B % b0D g0D r0D % b0F g0F r0F % + // b19 g19 r19 % b1B g1B r1B % b1D g1D r1D % b1F g1F r1F %] + __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02); + __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03); + __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02); + __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03); - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_bmp__decoder__do_decode_frame_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_padding; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame[0].scratch; - if ((self->private_impl.f_width > 0u) && (self->private_impl.f_height > 0u)) { - self->private_impl.f_dst_x = 0u; - if (self->private_impl.f_top_down) { - self->private_impl.f_dst_y = 0u; - self->private_impl.f_dst_y_inc = 1u; - } else { - self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1u)); - self->private_impl.f_dst_y_inc = 4294967295u; - } - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)), - wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), - wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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) { - if (self->private_impl.f_compression == 0u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } else if (self->private_impl.f_compression < 3u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } else if (self->private_impl.f_compression == 3u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } else { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - if (wuffs_base__status__is_ok(&v_status)) { - break; - } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) { - status = v_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; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - } - self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_pending_pad; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame[0].scratch; - self->private_impl.f_pending_pad = 0u; - } - self->private_impl.f_call_sequence = 96u; + // mix20 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 % + // b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %] + // mix21 = [b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 % + // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %] + // mix22 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B % + // b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %] + // mix23 = [b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F % + // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %] + __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11); + __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11); + __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13); + __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13); - ok: - self->private_impl.p_do_decode_frame[0] = 0; - goto exit; - } + // mix30 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 % + // b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %] + // mix31 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B % + // b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %] + // mix32 = [b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 % + // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %] + // mix33 = [b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B % + // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %] + __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20); + __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20); + __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31); + __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31); - goto suspend; - suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + // Write out four u8x32 SIMD registers (128 bytes, 32 BGRX/RGBX pixels). + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33); - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + // Advance by up to 32 pixels. The first iteration might be smaller than 32 + // so that all of the remaining steps are exactly 32. + uint32_t n = 32u - (31u & (x - x_end)); + dst_iter += 4u * n; + up0 += n; + up1 += n; + up2 += n; + x += n; } - - return status; } -// -------- func bmp.decoder.swizzle_none +// The rgbx flavor (below) is exactly the same as the bgrx flavor (above) +// except for the lines marked with a § and that comments were stripped. +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static void // +wuffs_private_impl__swizzle_ycc__convert_3_rgbx_x86_avx2( + wuffs_base__pixel_buffer* dst, + uint32_t x, + uint32_t x_end, + uint32_t y, + const uint8_t* up0, + const uint8_t* up1, + const uint8_t* up2) { + if ((x + 32u) > x_end) { + wuffs_private_impl__swizzle_ycc__convert_3_bgrx( // + dst, x, x_end, y, up0, up1, up2); + return; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_none( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + size_t dst_stride = dst->private_impl.planes[0].stride; + uint8_t* dst_iter = dst->private_impl.planes[0].ptr + + (dst_stride * ((size_t)y)) + (4u * ((size_t)x)); - 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_bytes_per_row = 0; - uint32_t v_src_bytes_per_pixel = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_j = 0; - uint64_t v_n = 0; + const __m256i u0001 = _mm256_set1_epi16(+0x0001); + const __m256i u00FF = _mm256_set1_epi16(+0x00FF); + const __m256i uFF80 = _mm256_set1_epi16(-0x0080); + const __m256i uFFFF = _mm256_set1_epi16(-0x0001); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + const __m256i p8000_p0000 = _mm256_set_epi16( // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000, // + +0x0000, -0x8000, +0x0000, -0x8000); - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - label__outer__continue:; - while (true) { - while (self->private_impl.f_pending_pad > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - self->private_impl.f_pending_pad -= 1u; - iop_a_src += 1u; - } - while (true) { - if (self->private_impl.f_dst_x == self->private_impl.f_width) { - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - if (self->private_impl.f_height > 0u) { - self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; - } - goto label__outer__break; - } else if (self->private_impl.f_pad_per_row != 0u) { - self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; - goto label__outer__continue; - } - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); - } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i >= ((uint64_t)(v_dst.len))) { - if (self->private_impl.f_bits_per_pixel > 32u) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - v_src_bytes_per_pixel = (self->private_impl.f_bits_per_pixel / 8u); - if (v_src_bytes_per_pixel == 0u) { - status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); - goto exit; - } - v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); - v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); - v_j = v_n; - while (v_j >= 8u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { - iop_a_src += (v_src_bytes_per_pixel * 8u); - } - v_j -= 8u; - } - while (v_j > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { - iop_a_src += (v_src_bytes_per_pixel * 1u); - } - v_j -= 1u; - } - } else { - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( - &self->private_impl.f_swizzler, - wuffs_base__slice_u8__subslice_i(v_dst, v_i), - v_dst_palette, - &iop_a_src, - io2_a_src); - } - if (v_n == 0u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - } - } - label__outer__break:; - status = wuffs_base__make_status(NULL); - goto ok; + const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E); + const __m256i p66E9 = _mm256_set1_epi16(+0x66E9); + const __m256i m581A_p492E = _mm256_set_epi16( // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A, // + +0x492E, -0x581A, +0x492E, -0x581A); - ok: - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } + while (x < x_end) { + __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1); + __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2); + __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF)); + __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF)); + __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8)); + __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8)); - return status; -} + __m256i tmp_by_eve = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001), + 1); + __m256i tmp_by_odd = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001), + 1); + __m256i tmp_ry_eve = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001), + 1); + __m256i tmp_ry_odd = _mm256_srai_epi16( + _mm256_add_epi16( + _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001), + 1); -// -------- func bmp.decoder.swizzle_rle + __m256i by_eve = + _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve)); + __m256i by_odd = + _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd)); + __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve); + __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_rle( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( // + _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E); + __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( // + _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E); + __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( // + _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E); + __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( // + _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E); - 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_bytes_per_row = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_row = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_n = 0; - uint32_t v_p0 = 0; - uint8_t v_code = 0; - uint8_t v_indexes[2] = {0}; - uint32_t v_rle_state = 0; - uint32_t v_chunk_bits = 0; - uint32_t v_chunk_count = 0; + __m256i tmp1_gy_eve_lo = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16); + __m256i tmp1_gy_eve_hi = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16); + __m256i tmp1_gy_odd_lo = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16); + __m256i tmp1_gy_odd_hi = + _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + __m256i gy_eve = _mm256_sub_epi16( + _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve); + __m256i gy_odd = _mm256_sub_epi16( + _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd); - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_rle_state = self->private_impl.f_rle_state; - label__outer__continue:; - while (true) { - v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { - v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); - } - label__middle__continue:; - while (true) { - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i <= ((uint64_t)(v_row.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i); - } else { - v_dst = wuffs_base__utility__empty_slice_u8(); - } - while (true) { - while (true) { - if (v_rle_state == 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - if (v_code == 0u) { - v_rle_state = 2u; - continue; - } - self->private_impl.f_rle_length = ((uint32_t)(v_code)); - v_rle_state = 1u; - continue; - } else if (v_rle_state == 1u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - if (self->private_impl.f_bits_per_pixel == 8u) { - v_p0 = 0u; - while (v_p0 < self->private_impl.f_rle_length) { - self->private_data.f_scratch[v_p0] = v_code; - v_p0 += 1u; - } - } else { - v_indexes[0u] = ((uint8_t)((v_code >> 4u))); - v_indexes[1u] = (v_code & 15u); - v_p0 = 0u; - while (v_p0 < self->private_impl.f_rle_length) { - self->private_data.f_scratch[(v_p0 + 0u)] = v_indexes[0u]; - self->private_data.f_scratch[(v_p0 + 1u)] = v_indexes[1u]; - v_p0 += 2u; - } - } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_rle_length)); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length); - v_rle_state = 0u; - goto label__middle__continue; - } else if (v_rle_state == 2u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - if (v_code < 2u) { - if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0u)) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); - goto exit; - } - wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u); - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - if (v_code > 0u) { - goto label__outer__break; - } - v_rle_state = 0u; - goto label__outer__continue; - } else if (v_code == 2u) { - v_rle_state = 4u; - continue; - } - self->private_impl.f_rle_length = ((uint32_t)(v_code)); - self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8u) && ((v_code & 1u) != 0u)); - v_rle_state = 3u; - continue; - } else if (v_rle_state == 3u) { - if (self->private_impl.f_bits_per_pixel == 8u) { - v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( - &self->private_impl.f_swizzler, - self->private_impl.f_rle_length, - v_dst, - v_dst_palette, - &iop_a_src, - io2_a_src); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)(v_n))); - } else { - v_chunk_count = ((self->private_impl.f_rle_length + 3u) / 4u); - v_p0 = 0u; - while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2u)) { - v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2u; - self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u)))); - self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u)))); - self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u)))); - self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u)))); - v_p0 = ((v_p0 & 255u) + 4u); - v_chunk_count -= 1u; - } - v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length); - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0)); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0); - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0); - } - if (self->private_impl.f_rle_length > 0u) { - goto label__goto_suspend__break; - } - if (self->private_impl.f_rle_padded) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - iop_a_src += 1u; - self->private_impl.f_rle_padded = false; - } - v_rle_state = 0u; - goto label__middle__continue; - } else if (v_rle_state == 4u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - v_rle_state = 5u; - continue; - } - if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { - goto label__goto_suspend__break; - } - v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - if (self->private_impl.f_rle_delta_x > 0u) { - wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, ((uint64_t)(self->private_impl.f_rle_delta_x))); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x))); - self->private_impl.f_rle_delta_x = 0u; - if (self->private_impl.f_dst_x > self->private_impl.f_width) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); - goto exit; - } - } - if (v_code > 0u) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_code -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - while (true) { - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); - goto exit; - } - v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { - v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); - } - if (v_code <= 0u) { - wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, ((uint64_t)(self->private_impl.f_dst_x))); - break; - } - wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u); -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_code -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } - } - v_rle_state = 0u; - goto label__middle__continue; - } - } - label__goto_suspend__break:; - self->private_impl.f_rle_state = v_rle_state; - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - } - label__outer__break:; - while (self->private_impl.f_dst_y < self->private_impl.f_height) { - v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { - v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); - } - wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u); - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - } - status = wuffs_base__make_status(NULL); - goto ok; + __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0); + __m256i yy_eve = _mm256_and_si256(yy_all, u00FF); + __m256i yy_odd = _mm256_srli_epi16(yy_all, 8); - ok: - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } + __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve); + __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd); + __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve); + __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd); - return status; -} + __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve); + __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd); + __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve); + __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd); -// -------- func bmp.decoder.swizzle_bitfields + __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve); + __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd); + __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve); + __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_bitfields( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + // § Note the swapped B and R channels. + __m256i mix00 = _mm256_unpacklo_epi8(packed_r_eve, packed_g_eve); + __m256i mix01 = _mm256_unpacklo_epi8(packed_r_odd, packed_g_odd); + __m256i mix02 = _mm256_unpacklo_epi8(packed_b_eve, uFFFF); + __m256i mix03 = _mm256_unpacklo_epi8(packed_b_odd, uFFFF); - 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_bytes_per_row = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_n = 0; - uint32_t v_p0 = 0; - uint32_t v_p1 = 0; - uint32_t v_p1_temp = 0; - uint32_t v_num_bits = 0; - uint32_t v_c = 0; - uint32_t v_c32 = 0; - uint32_t v_channel = 0; + __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02); + __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03); + __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02); + __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11); + __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11); + __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13); + __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13); - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - label__outer__continue:; - while (true) { - while (self->private_impl.f_pending_pad > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - self->private_impl.f_pending_pad -= 1u; - iop_a_src += 1u; - } - while (true) { - if (self->private_impl.f_dst_x == self->private_impl.f_width) { - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - if (self->private_impl.f_height > 0u) { - self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; - } - goto label__outer__break; - } else if (self->private_impl.f_pad_per_row != 0u) { - self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; - goto label__outer__continue; - } - } - v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)); - v_p1 = wuffs_base__u32__min(v_p1_temp, 256u); - v_p0 = 0u; - while (v_p0 < v_p1) { - if (self->private_impl.f_bits_per_pixel == 16u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - break; - } - v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2u; - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - break; - } - v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4u; - } - v_channel = 0u; - while (v_channel < 4u) { - if (self->private_impl.f_channel_num_bits[v_channel] == 0u) { - self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = 255u; - self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = 255u; - } else { - v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]); - v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel])); - while (v_num_bits < 16u) { - v_c |= ((uint32_t)(v_c << v_num_bits)); - v_num_bits *= 2u; - } - v_c >>= (v_num_bits - 16u); - self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = ((uint8_t)((v_c >> 0u))); - self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = ((uint8_t)((v_c >> 8u))); - } - v_channel += 1u; - } - v_p0 += 1u; - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); - } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i >= ((uint64_t)(v_dst.len))) { - v_n = ((uint64_t)(v_p0)); - } else { - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, (8u * v_p0))); - } - if (v_n == 0u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - } - } - label__outer__break:; - status = wuffs_base__make_status(NULL); - goto ok; + __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20); + __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20); + __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31); + __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31); - ok: - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32); + _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33); - return status; + uint32_t n = 32u - (31u & (x - x_end)); + dst_iter += 4u * n; + up0 += n; + up1 += n; + up2 += n; + x += n; + } } -// -------- func bmp.decoder.swizzle_low_bit_depth +#if defined(__GNUC__) && !defined(__clang__) +// No-op. +#else +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") +static const uint8_t* // +wuffs_private_impl__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2( + uint8_t* dst_ptr, + const uint8_t* src_ptr_major, + const uint8_t* src_ptr_minor, + size_t src_len, + uint32_t h1v2_bias_ignored, + bool first_column, + bool last_column) { + uint8_t* dp = dst_ptr; + const uint8_t* sp_major = src_ptr_major; + const uint8_t* sp_minor = src_ptr_minor; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__swizzle_low_bit_depth( - wuffs_bmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + if (first_column) { + src_len--; + if ((src_len <= 0u) && last_column) { + uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + // + (4u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + 8u) >> 4u); + *dp++ = (uint8_t)((sv + 7u) >> 4u); + return dst_ptr; + } - 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_bytes_per_row = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_n = 0; - uint32_t v_p0 = 0; - uint32_t v_chunk_bits = 0; - uint32_t v_chunk_count = 0; - uint32_t v_pixels_per_chunk = 0; + uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero. + uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero. + uint32_t sv_major_p1 = sp_major[+1]; + uint32_t sv_minor_p1 = sp_minor[+1]; - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + if (src_len <= 0u) { + return dst_ptr; + } } - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - while (true) { - if (self->private_impl.f_dst_x == self->private_impl.f_width) { - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - break; - } - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); - } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i >= ((uint64_t)(v_dst.len))) { - if (self->private_impl.f_bits_per_pixel == 1u) { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u); - v_pixels_per_chunk = 32u; - } else if (self->private_impl.f_bits_per_pixel == 2u) { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u); - v_pixels_per_chunk = 16u; - } else { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u); - v_pixels_per_chunk = 8u; - } - while ((v_chunk_count >= 64u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 256u)) { - iop_a_src += 256u; - self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 64u)))); - v_chunk_count -= 64u; - } - while ((v_chunk_count >= 8u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 32u)) { - iop_a_src += 32u; - self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 8u)))); - v_chunk_count -= 8u; - } - while (v_chunk_count > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - iop_a_src += 4u; - self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 1u)))); - v_chunk_count -= 1u; - } - continue; - } - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i); - v_p0 = 0u; - if (self->private_impl.f_bits_per_pixel == 1u) { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u); - v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16u); - while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { - v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4u; - self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((1u & (v_chunk_bits >> 31u)))); - self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((1u & (v_chunk_bits >> 30u)))); - self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((1u & (v_chunk_bits >> 29u)))); - self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((1u & (v_chunk_bits >> 28u)))); - self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((1u & (v_chunk_bits >> 27u)))); - self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((1u & (v_chunk_bits >> 26u)))); - self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((1u & (v_chunk_bits >> 25u)))); - self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((1u & (v_chunk_bits >> 24u)))); - self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((1u & (v_chunk_bits >> 23u)))); - self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((1u & (v_chunk_bits >> 22u)))); - self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((1u & (v_chunk_bits >> 21u)))); - self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((1u & (v_chunk_bits >> 20u)))); - self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((1u & (v_chunk_bits >> 19u)))); - self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((1u & (v_chunk_bits >> 18u)))); - self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((1u & (v_chunk_bits >> 17u)))); - self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((1u & (v_chunk_bits >> 16u)))); - self->private_data.f_scratch[(v_p0 + 16u)] = ((uint8_t)((1u & (v_chunk_bits >> 15u)))); - self->private_data.f_scratch[(v_p0 + 17u)] = ((uint8_t)((1u & (v_chunk_bits >> 14u)))); - self->private_data.f_scratch[(v_p0 + 18u)] = ((uint8_t)((1u & (v_chunk_bits >> 13u)))); - self->private_data.f_scratch[(v_p0 + 19u)] = ((uint8_t)((1u & (v_chunk_bits >> 12u)))); - self->private_data.f_scratch[(v_p0 + 20u)] = ((uint8_t)((1u & (v_chunk_bits >> 11u)))); - self->private_data.f_scratch[(v_p0 + 21u)] = ((uint8_t)((1u & (v_chunk_bits >> 10u)))); - self->private_data.f_scratch[(v_p0 + 22u)] = ((uint8_t)((1u & (v_chunk_bits >> 9u)))); - self->private_data.f_scratch[(v_p0 + 23u)] = ((uint8_t)((1u & (v_chunk_bits >> 8u)))); - self->private_data.f_scratch[(v_p0 + 24u)] = ((uint8_t)((1u & (v_chunk_bits >> 7u)))); - self->private_data.f_scratch[(v_p0 + 25u)] = ((uint8_t)((1u & (v_chunk_bits >> 6u)))); - self->private_data.f_scratch[(v_p0 + 26u)] = ((uint8_t)((1u & (v_chunk_bits >> 5u)))); - self->private_data.f_scratch[(v_p0 + 27u)] = ((uint8_t)((1u & (v_chunk_bits >> 4u)))); - self->private_data.f_scratch[(v_p0 + 28u)] = ((uint8_t)((1u & (v_chunk_bits >> 3u)))); - self->private_data.f_scratch[(v_p0 + 29u)] = ((uint8_t)((1u & (v_chunk_bits >> 2u)))); - self->private_data.f_scratch[(v_p0 + 30u)] = ((uint8_t)((1u & (v_chunk_bits >> 1u)))); - self->private_data.f_scratch[(v_p0 + 31u)] = ((uint8_t)((1u & (v_chunk_bits >> 0u)))); - v_p0 = ((v_p0 & 511u) + 32u); - v_chunk_count -= 1u; - } - } else if (self->private_impl.f_bits_per_pixel == 2u) { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u); - v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32u); - while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { - v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4u; - self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((3u & (v_chunk_bits >> 30u)))); - self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((3u & (v_chunk_bits >> 28u)))); - self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((3u & (v_chunk_bits >> 26u)))); - self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((3u & (v_chunk_bits >> 24u)))); - self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((3u & (v_chunk_bits >> 22u)))); - self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((3u & (v_chunk_bits >> 20u)))); - self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((3u & (v_chunk_bits >> 18u)))); - self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((3u & (v_chunk_bits >> 16u)))); - self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((3u & (v_chunk_bits >> 14u)))); - self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((3u & (v_chunk_bits >> 12u)))); - self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((3u & (v_chunk_bits >> 10u)))); - self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((3u & (v_chunk_bits >> 8u)))); - self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((3u & (v_chunk_bits >> 6u)))); - self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((3u & (v_chunk_bits >> 4u)))); - self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((3u & (v_chunk_bits >> 2u)))); - self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((3u & (v_chunk_bits >> 0u)))); - v_p0 = ((v_p0 & 511u) + 16u); - v_chunk_count -= 1u; - } - } else { - v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u); - v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64u); - while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { - v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4u; - self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 28u)))); - self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 24u)))); - self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 20u)))); - self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 16u)))); - self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u)))); - self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u)))); - self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u)))); - self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u)))); - v_p0 = ((v_p0 & 511u) + 8u); - v_chunk_count -= 1u; - } - } - v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x)); - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0)); - if (v_n == 0u) { - status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); - goto ok; - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - } - status = wuffs_base__make_status(NULL); - goto ok; - - ok: - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func bmp.decoder.frame_dirty_rect - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_bmp__decoder__frame_dirty_rect( - const wuffs_bmp__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); + if (last_column) { + src_len--; } - return wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height); -} + if (src_len < 32) { + // This fallback is the same as the non-SIMD-capable code path. + for (; src_len > 0u; src_len--) { + uint32_t sv_major_m1 = sp_major[-1]; + uint32_t sv_minor_m1 = sp_minor[-1]; + uint32_t sv_major_p1 = sp_major[+1]; + uint32_t sv_minor_p1 = sp_minor[+1]; -// -------- func bmp.decoder.num_animation_loops + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); + } -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_bmp__decoder__num_animation_loops( - const wuffs_bmp__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + } else { + while (src_len > 0u) { + // Load 1+32+1 samples (six u8x32 vectors) from the major (jxx) and minor + // (nxx) rows. + // + // major_p0 = [j00 j01 j02 j03 .. j28 j29 j30 j31] // p0 = "plus 0" + // minor_p0 = [n00 n01 n02 n03 .. n28 n29 n30 n31] // p0 = "plus 0" + // major_m1 = [jm1 j00 j01 j02 .. j27 j28 j29 j30] // m1 = "minus 1" + // minor_m1 = [nm1 n00 n01 n02 .. n27 n28 n29 n30] // m1 = "minus 1" + // major_p1 = [j01 j02 j03 j04 .. j29 j30 j31 j32] // p1 = "plus 1" + // minor_p1 = [n01 n02 n03 n04 .. n29 n30 n31 n32] // p1 = "plus 1" + __m256i major_p0 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 0)); + __m256i minor_p0 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 0)); + __m256i major_m1 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major - 1)); + __m256i minor_m1 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor - 1)); + __m256i major_p1 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 1)); + __m256i minor_p1 = + _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 1)); - return 0u; -} + // Unpack, staying with u8x32 vectors. + // + // step1_p0_lo = [j00 n00 j01 n01 .. j07 n07 j16 n16 j17 n17 .. j23 n23] + // step1_p0_hi = [j08 n08 j09 n09 .. j15 n15 j24 n24 j25 n25 .. j31 n31] + // step1_m1_lo = [jm1 nm1 j00 n00 .. j06 n06 j15 n15 j16 n16 .. j22 n22] + // step1_m1_hi = [j07 n07 j08 n08 .. j14 n14 j23 n23 j24 n24 .. j30 n30] + // step1_p1_lo = [j01 n01 j02 n02 .. j08 n08 j17 n17 j18 n18 .. j24 n24] + // step1_p1_hi = [j09 n09 j10 n10 .. j16 n16 j25 n25 j26 n26 .. j32 n32] + __m256i step1_p0_lo = _mm256_unpacklo_epi8(major_p0, minor_p0); + __m256i step1_p0_hi = _mm256_unpackhi_epi8(major_p0, minor_p0); + __m256i step1_m1_lo = _mm256_unpacklo_epi8(major_m1, minor_m1); + __m256i step1_m1_hi = _mm256_unpackhi_epi8(major_m1, minor_m1); + __m256i step1_p1_lo = _mm256_unpacklo_epi8(major_p1, minor_p1); + __m256i step1_p1_hi = _mm256_unpackhi_epi8(major_p1, minor_p1); -// -------- func bmp.decoder.num_decoded_frame_configs + // Multiply-add to get u16x16 vectors. + // + // step2_p0_lo = [9*j00+3*n00 9*j01+3*n01 .. 9*j23+3*n23] + // step2_p0_hi = [9*j08+3*n08 9*j09+3*n09 .. 9*j31+3*n31] + // step2_m1_lo = [3*jm1+1*nm1 3*j00+1*n00 .. 3*j22+1*n22] + // step2_m1_hi = [3*j07+1*n07 3*j08+1*n08 .. 3*j30+1*n30] + // step2_p1_lo = [3*j01+1*n01 3*j02+1*n02 .. 3*j24+1*n24] + // step2_p1_hi = [3*j09+1*n09 3*j10+1*n10 .. 3*j32+1*n32] + const __m256i k0309 = _mm256_set1_epi16(0x0309); + const __m256i k0103 = _mm256_set1_epi16(0x0103); + __m256i step2_p0_lo = _mm256_maddubs_epi16(step1_p0_lo, k0309); + __m256i step2_p0_hi = _mm256_maddubs_epi16(step1_p0_hi, k0309); + __m256i step2_m1_lo = _mm256_maddubs_epi16(step1_m1_lo, k0103); + __m256i step2_m1_hi = _mm256_maddubs_epi16(step1_m1_hi, k0103); + __m256i step2_p1_lo = _mm256_maddubs_epi16(step1_p1_lo, k0103); + __m256i step2_p1_hi = _mm256_maddubs_epi16(step1_p1_hi, k0103); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bmp__decoder__num_decoded_frame_configs( - const wuffs_bmp__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + // Compute the weighted sums of (p0, m1) and (p0, p1). For example: + // + // step3_m1_lo[00] = ((9*j00) + (3*n00) + (3*jm1) + (1*nm1)) as u16 + // step3_p1_hi[15] = ((9*j31) + (3*n31) + (3*j32) + (1*n32)) as u16 + __m256i step3_m1_lo = _mm256_add_epi16(step2_p0_lo, step2_m1_lo); + __m256i step3_m1_hi = _mm256_add_epi16(step2_p0_hi, step2_m1_hi); + __m256i step3_p1_lo = _mm256_add_epi16(step2_p0_lo, step2_p1_lo); + __m256i step3_p1_hi = _mm256_add_epi16(step2_p0_hi, step2_p1_hi); - if (self->private_impl.f_call_sequence > 32u) { - return 1u; - } - return 0u; -} + // Bias by 8 (on the left) or 7 (on the right) and then divide by 16 + // (which is 9+3+3+1) to get a weighted average. On the left (m1), shift + // the u16 right value by 4. On the right (p1), shift right by 4 and then + // shift left by 8 so that, when still in the u16x16 little-endian + // interpretation, we have: + // - m1_element = (etcetera + 8) >> 4 + // - p1_element = ((etcetera + 7) >> 4) << 8 + // + // step4_m1_lo = [0x00?? 0x00?? ... 0x00?? 0x00??] + // step4_p1_lo = [0x??00 0x??00 ... 0x??00 0x??00] + // step4_m1_hi = [0x00?? 0x00?? ... 0x00?? 0x00??] + // step4_p1_hi = [0x??00 0x??00 ... 0x??00 0x??00] + __m256i step4_m1_lo = _mm256_srli_epi16( + _mm256_add_epi16(step3_m1_lo, _mm256_set1_epi16(8)), 4); + __m256i step4_p1_lo = _mm256_slli_epi16( + _mm256_srli_epi16(_mm256_add_epi16(step3_p1_lo, _mm256_set1_epi16(7)), + 4), + 8); + __m256i step4_m1_hi = _mm256_srli_epi16( + _mm256_add_epi16(step3_m1_hi, _mm256_set1_epi16(8)), 4); + __m256i step4_p1_hi = _mm256_slli_epi16( + _mm256_srli_epi16(_mm256_add_epi16(step3_p1_hi, _mm256_set1_epi16(7)), + 4), + 8); -// -------- func bmp.decoder.num_decoded_frames + // Bitwise-or two "0x00"-rich u16x16 vectors to get a u8x32 vector. Do + // that twice. Once for the low columns and once for the high columns. + // + // In terms of jxx (major row) or nxx (minor row) source samples: + // - low columns means ( 0 .. 8; 16 .. 24). + // - high columns means ( 8 .. 16; 24 .. 32). + // + // In terms of dxx destination samples (there are twice as many): + // - low columns means ( 0 .. 16; 32 .. 48). + // - high columns means (16 .. 32; 48 .. 64). + // + // step5_lo = [d00 d01 .. d14 d15 d32 d33 .. d46 d47] + // step5_hi = [d16 d17 .. d30 d31 d48 d49 .. d62 d63] + // + // The d00, d02 ... d62 even elements come from (p0, m1) weighted sums. + // The d01, d03 ... d63 odd elements come from (p0, p1) weighted sums. + __m256i step5_lo = _mm256_or_si256(step4_m1_lo, step4_p1_lo); + __m256i step5_hi = _mm256_or_si256(step4_m1_hi, step4_p1_hi); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bmp__decoder__num_decoded_frames( - const wuffs_bmp__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + // Permute and store. + // + // step6_00_31 = [d00 d01 .. d14 d15 d16 d17 .. d30 d31] + // step6_32_63 = [d32 d33 .. d46 d47 d48 d49 .. d62 d63] + __m256i step6_00_31 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x20); + __m256i step6_32_63 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x31); + _mm256_storeu_si256((__m256i*)(void*)(dp + 0x00), step6_00_31); + _mm256_storeu_si256((__m256i*)(void*)(dp + 0x20), step6_32_63); - if (self->private_impl.f_call_sequence > 64u) { - return 1u; + // Advance by up to 32 source samples (64 destination samples). The first + // iteration might be smaller than 32 so that all of the remaining steps + // are exactly 32. + size_t n = 32u - (31u & (0u - src_len)); + dp += 2u * n; + sp_major += n; + sp_minor += n; + src_len -= n; + } } - return 0u; -} -// -------- func bmp.decoder.restart_frame + if (last_column) { + uint32_t sv_major_m1 = sp_major[-1]; + uint32_t sv_minor_m1 = sp_minor[-1]; + uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero. + uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero. -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__restart_frame( - wuffs_bmp__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + // + (3u * ((uint32_t)(*sp_minor++))); + *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u); + *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u); } - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } - if (a_index != 0u) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - self->private_impl.f_call_sequence = 40u; - self->private_impl.f_frame_config_io_position = a_io_position; - return wuffs_base__make_status(NULL); + return dst_ptr; } +#endif +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +// ‼ WUFFS MULTI-FILE SECTION -x86_avx2 -// -------- func bmp.decoder.set_report_metadata - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_bmp__decoder__set_report_metadata( - wuffs_bmp__decoder* self, - uint32_t a_fourcc, - bool a_report) { - return wuffs_base__make_empty_struct(); -} +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV) -// -------- func bmp.decoder.tell_me_more +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \ + defined(WUFFS_CONFIG__MODULE__BASE__UTF8) -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bmp__decoder__tell_me_more( - wuffs_bmp__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); +// ---------------- Unicode and UTF-8 - wuffs_base__status v_status = wuffs_base__make_status(NULL); +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) { + if (code_point <= 0x7F) { + if (dst.len >= 1) { + dst.ptr[0] = (uint8_t)(code_point); + return 1; + } - uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + } else if (code_point <= 0x07FF) { + if (dst.len >= 2) { + dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6))); + dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); + return 2; + } - while (true) { - { - wuffs_base__status t_0 = wuffs_bmp__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } else if (code_point <= 0xFFFF) { + if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) { + dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12))); + dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F)); + dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); + return 3; } - ok: - self->private_impl.p_tell_me_more[0] = 0; - goto exit; + } else if (code_point <= 0x10FFFF) { + if (dst.len >= 4) { + dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18))); + dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F)); + dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F)); + dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F)); + return 4; + } } - goto suspend; - suspend: - self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; + return 0; } -// -------- func bmp.decoder.do_tell_me_more - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__do_tell_me_more( - wuffs_bmp__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +// wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a +// UTF-8 encoded code point, based on the encoding's initial byte. +// - 0x00 is 1-byte UTF-8 (ASCII). +// - 0x01 is the start of 2-byte UTF-8. +// - 0x02 is the start of 3-byte UTF-8. +// - 0x03 is the start of 4-byte UTF-8. +// - 0x40 is a UTF-8 tail byte. +// - 0x80 is invalid UTF-8. +// +// RFC 3629 (UTF-8) gives this grammar for valid UTF-8: +// UTF8-1 = %x00-7F +// UTF8-2 = %xC2-DF UTF8-tail +// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / +// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail ) +// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / +// %xF4 %x80-8F 2( UTF8-tail ) +// UTF8-tail = %x80-BF +static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = { + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. - if (self->private_impl.f_io_redirect_fourcc <= 1u) { - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; - } - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - 1u, - self->private_impl.f_io_redirect_fourcc, - 0u, - self->private_impl.f_io_redirect_pos, - 18446744073709551615u); - } - self->private_impl.f_io_redirect_fourcc = 1u; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F. - goto ok; - ok: - goto exit; - exit: - return status; -} + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7. + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF. -// -------- func bmp.decoder.history_retain_length + 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7. + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF. + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7. + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF. + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7. + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF. + 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7. + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF. + // 0 1 2 3 4 5 6 7 + // 8 9 A B C D E F +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bmp__decoder__history_retain_length( - const wuffs_bmp__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; +WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output // +wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) { + if (s_len == 0) { + return wuffs_base__make_utf_8__next__output(0, 0); } + uint32_t c = s_ptr[0]; + switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) { + case 0: + return wuffs_base__make_utf_8__next__output(c, 1); - return 0u; -} + case 1: + if (s_len < 2) { + break; + } + c = wuffs_base__peek_u16le__no_bounds_check(s_ptr); + if ((c & 0xC000) != 0x8000) { + break; + } + c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8)); + return wuffs_base__make_utf_8__next__output(c, 2); -// -------- func bmp.decoder.workbuf_len + case 2: + if (s_len < 3) { + break; + } + c = wuffs_base__peek_u24le__no_bounds_check(s_ptr); + if ((c & 0xC0C000) != 0x808000) { + break; + } + c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) | + (0x00003F & (c >> 16)); + if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) { + break; + } + return wuffs_base__make_utf_8__next__output(c, 3); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_bmp__decoder__workbuf_len( - const wuffs_bmp__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + case 3: + if (s_len < 4) { + break; + } + c = wuffs_base__peek_u32le__no_bounds_check(s_ptr); + if ((c & 0xC0C0C000) != 0x80808000) { + break; + } + c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) | + (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24)); + if ((c <= 0xFFFF) || (0x110000 <= c)) { + break; + } + return wuffs_base__make_utf_8__next__output(c, 4); } - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + return wuffs_base__make_utf_8__next__output( + WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1); } -// -------- func bmp.decoder.read_palette - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__read_palette( - wuffs_bmp__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_i = 0; - uint32_t v_argb = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_read_palette[0]; - if (coro_susp_point) { - v_i = self->private_data.s_read_palette[0].v_i; +WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output // +wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) { + if (s_len == 0) { + return wuffs_base__make_utf_8__next__output(0, 0); } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + const uint8_t* ptr = &s_ptr[s_len - 1]; + if (*ptr < 0x80) { + return wuffs_base__make_utf_8__next__output(*ptr, 1); - if (self->private_impl.f_bitmap_info_len == 12u) { - while ((v_i < 256u) && (self->private_impl.f_padding >= 3u)) { - self->private_impl.f_padding -= 3u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { - t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); - iop_a_src += 3; - } else { - self->private_data.s_read_palette[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_read_palette[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 16) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; - } - } - v_argb = t_0; - } - v_argb |= 4278190080u; - self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); - self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); - self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); - self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); - v_i += 1u; + } else if (*ptr < 0xC0) { + const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0]; + uint32_t n = 1; + while (ptr != too_far) { + ptr--; + n++; + if (*ptr < 0x80) { + break; + } else if (*ptr < 0xC0) { + continue; } - } else { - while ((v_i < 256u) && (self->private_impl.f_padding >= 4u)) { - self->private_impl.f_padding -= 4u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_read_palette[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_read_palette[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; - } - } - v_argb = t_1; - } - v_argb |= 4278190080u; - self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); - self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); - self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); - self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); - v_i += 1u; + wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n); + if (o.byte_length != n) { + break; } + return o; } - while (v_i < 256u) { - self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u; - v_i += 1u; - } - - goto ok; - ok: - self->private_impl.p_read_palette[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_read_palette[0].v_i = v_i; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return status; + return wuffs_base__make_utf_8__next__output( + WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1); } -// -------- func bmp.decoder.process_masks - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bmp__decoder__process_masks( - wuffs_bmp__decoder* self) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_i = 0; - uint32_t v_mask = 0; - uint32_t v_n = 0; - - while (v_i < 4u) { - v_mask = self->private_impl.f_channel_masks[v_i]; - if (v_mask != 0u) { - v_n = 0u; - while ((v_mask & 1u) == 0u) { - v_n += 1u; - v_mask >>= 1u; - } - self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31u))); - v_n = 0u; - while ((v_mask & 1u) == 1u) { - v_n += 1u; - v_mask >>= 1u; - } - if ((v_mask != 0u) || (v_n > 32u)) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; - } - self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n)); - } else if (v_i != 3u) { - status = wuffs_base__make_status(wuffs_bmp__error__bad_header); - goto exit; +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) { + // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time). + // + // TODO: possibly optimize this by manually inlining the + // wuffs_base__utf_8__next calls. + size_t original_len = s_len; + while (s_len > 0) { + wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len); + if ((o.code_point > 0x7F) && (o.byte_length == 1)) { + break; } - v_i += 1u; + s_ptr += o.byte_length; + s_len -= o.byte_length; } + return original_len - s_len; +} - goto ok; - ok: - goto exit; - exit: - return status; +WUFFS_BASE__MAYBE_STATIC size_t // +wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) { + // TODO: possibly optimize this by checking 4 or 8 bytes at a time. + const uint8_t* original_ptr = s_ptr; + const uint8_t* p = s_ptr; + const uint8_t* q = s_ptr + s_len; + for (; (p != q) && ((*p & 0x80) == 0); p++) { + } + return (size_t)(p - original_ptr); } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) +#endif // !defined(WUFFS_CONFIG__MODULES) || + // defined(WUFFS_CONFIG__MODULE__BASE) || + // defined(WUFFS_CONFIG__MODULE__BASE__UTF8) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) +#ifdef __cplusplus +} // extern "C" +#endif -// ---------------- Status Codes Implementations +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) -const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[] = "#bzip2: bad Huffman code (over-subscribed)"; -const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[] = "#bzip2: bad Huffman code (under-subscribed)"; -const char wuffs_bzip2__error__bad_block_header[] = "#bzip2: bad block header"; -const char wuffs_bzip2__error__bad_block_length[] = "#bzip2: bad block length"; -const char wuffs_bzip2__error__bad_checksum[] = "#bzip2: bad checksum"; -const char wuffs_bzip2__error__bad_header[] = "#bzip2: bad header"; -const char wuffs_bzip2__error__bad_number_of_sections[] = "#bzip2: bad number of sections"; -const char wuffs_bzip2__error__truncated_input[] = "#bzip2: truncated input"; -const char wuffs_bzip2__error__unsupported_block_randomization[] = "#bzip2: unsupported block randomization"; -const char wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state[] = "#bzip2: internal error: inconsistent Huffman decoder state"; +// ---------------- Status Codes Implementations // ---------------- Private Consts -static const uint8_t -WUFFS_BZIP2__CLAMP_TO_5[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 1, 2, 3, 4, 5, 5, 5, -}; - -static const uint32_t -WUFFS_BZIP2__REV_CRC32_TABLE[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021, - 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013, - 1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509, - 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757, - 2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653, - 3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357, - 3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109, - 4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269, - 881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826, - 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010, - 2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778, - 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418, - 2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130, - 2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922, - 3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050, - 3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242, - 1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195, - 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299, - 622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531, - 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555, - 4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915, - 3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211, - 3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763, - 2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779, - 1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660, - 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964, - 295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308, - 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548, - 3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204, - 3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804, - 2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596, - 2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188, -}; - // ---------------- Private Initializer Prototypes // ---------------- Private Function Prototypes -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__do_transform_io( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__prepare_block( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__read_code_lengths( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__build_huffman_tree( - wuffs_bzip2__decoder* self, - uint32_t a_which); - WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_bzip2__decoder__build_huffman_table( - wuffs_bzip2__decoder* self, - uint32_t a_which); +wuffs_adler32__hasher__up( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_bzip2__decoder__invert_bwt( - wuffs_bzip2__decoder* self); +wuffs_adler32__hasher__up__choosy_default( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x); +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_bzip2__decoder__flush_fast( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__flush_slow( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__decode_huffman_fast( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src); +wuffs_adler32__hasher__up_arm_neon( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__decode_huffman_slow( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src); +static wuffs_base__empty_struct +wuffs_adler32__hasher__up_x86_sse42( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) // ---------------- VTables -const wuffs_base__io_transformer__func_ptrs -wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer = { +const wuffs_base__hasher_u32__func_ptrs +wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = { + (uint32_t(*)(const void*))(&wuffs_adler32__hasher__checksum_u32), (uint64_t(*)(const void*, - uint32_t))(&wuffs_bzip2__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_bzip2__decoder__history_retain_length), + uint32_t))(&wuffs_adler32__hasher__get_quirk), (wuffs_base__status(*)(void*, uint32_t, - uint64_t))(&wuffs_bzip2__decoder__set_quirk), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_bzip2__decoder__transform_io), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bzip2__decoder__workbuf_len), + uint64_t))(&wuffs_adler32__hasher__set_quirk), + (wuffs_base__empty_struct(*)(void*, + wuffs_base__slice_u8))(&wuffs_adler32__hasher__update), + (uint32_t(*)(void*, + wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32), }; // ---------------- Initializer Implementations wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_bzip2__decoder__initialize( - wuffs_bzip2__decoder* self, +wuffs_adler32__hasher__initialize( + wuffs_adler32__hasher* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options){ @@ -30559,23 +30841,25 @@ wuffs_bzip2__decoder__initialize( } } + self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default; + self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = - wuffs_base__io_transformer__vtable_name; - self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = - (const void*)(&wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer); + self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = + wuffs_base__hasher_u32__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = + (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32); return wuffs_base__make_status(NULL); } -wuffs_bzip2__decoder* -wuffs_bzip2__decoder__alloc(void) { - wuffs_bzip2__decoder* x = - (wuffs_bzip2__decoder*)(calloc(sizeof(wuffs_bzip2__decoder), 1)); +wuffs_adler32__hasher* +wuffs_adler32__hasher__alloc(void) { + wuffs_adler32__hasher* x = + (wuffs_adler32__hasher*)(calloc(1, sizeof(wuffs_adler32__hasher))); if (!x) { return NULL; } - if (wuffs_bzip2__decoder__initialize( - x, sizeof(wuffs_bzip2__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + if (wuffs_adler32__hasher__initialize( + x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { free(x); return NULL; } @@ -30583,18 +30867,18 @@ wuffs_bzip2__decoder__alloc(void) { } size_t -sizeof__wuffs_bzip2__decoder(void) { - return sizeof(wuffs_bzip2__decoder); +sizeof__wuffs_adler32__hasher(void) { + return sizeof(wuffs_adler32__hasher); } // ---------------- Function Implementations -// -------- func bzip2.decoder.get_quirk +// -------- func adler32.hasher.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bzip2__decoder__get_quirk( - const wuffs_bzip2__decoder* self, +wuffs_adler32__hasher__get_quirk( + const wuffs_adler32__hasher* self, uint32_t a_key) { if (!self) { return 0; @@ -30607,12 +30891,12 @@ wuffs_bzip2__decoder__get_quirk( return 0u; } -// -------- func bzip2.decoder.set_quirk +// -------- func adler32.hasher.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bzip2__decoder__set_quirk( - wuffs_bzip2__decoder* self, +wuffs_adler32__hasher__set_quirk( + wuffs_adler32__hasher* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -30625,369 +30909,699 @@ wuffs_bzip2__decoder__set_quirk( : wuffs_base__error__initialize_not_called); } - if (a_key == 1u) { - self->private_impl.f_ignore_checksum = (a_value > 0u); - return wuffs_base__make_status(NULL); - } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func bzip2.decoder.history_retain_length +// -------- func adler32.hasher.update WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_bzip2__decoder__history_retain_length( - const wuffs_bzip2__decoder* self) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_adler32__hasher__update( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return 0; + return wuffs_base__make_empty_struct(); } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); } - return 0u; + if ( ! self->private_impl.f_started) { + self->private_impl.f_started = true; + self->private_impl.f_state = 1u; + self->private_impl.choosy_up = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 : +#endif + self->private_impl.choosy_up); + } + wuffs_adler32__hasher__up(self, a_x); + return wuffs_base__make_empty_struct(); } -// -------- func bzip2.decoder.workbuf_len +// -------- func adler32.hasher.update_u32 WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_bzip2__decoder__workbuf_len( - const wuffs_bzip2__decoder* self) { +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_adler32__hasher__update_u32( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); + return 0; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return 0; } - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + wuffs_adler32__hasher__update(self, a_x); + return self->private_impl.f_state; } -// -------- func bzip2.decoder.transform_io +// -------- func adler32.hasher.up WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_bzip2__decoder__transform_io( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); +static wuffs_base__empty_struct +wuffs_adler32__hasher__up( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { + return (*self->private_impl.choosy_up)(self, a_x); +} - uint32_t coro_susp_point = self->private_impl.p_transform_io[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_adler32__hasher__up__choosy_default( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_s1 = 0; + uint32_t v_s2 = 0; + wuffs_base__slice_u8 v_remaining = {0}; + wuffs_base__slice_u8 v_p = {0}; - while (true) { - { - wuffs_base__status t_0 = wuffs_bzip2__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); - v_status = t_0; + v_s1 = ((self->private_impl.f_state) & 0xFFFFu); + v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); + while (((uint64_t)(a_x.len)) > 0u) { + v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); + if (((uint64_t)(a_x.len)) > 5552u) { + v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552u); + a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552u); + } + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 1; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8)); + while (v_p.ptr < i_end0_p) { + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_bzip2__error__truncated_input); - goto exit; + v_p.len = 1; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end1_p) { + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + v_p.len = 0; } - - ok: - self->private_impl.p_transform_io[0] = 0; - goto exit; + v_s1 %= 65521u; + v_s2 %= 65521u; + a_x = v_remaining; } + self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); + return wuffs_base__make_empty_struct(); +} - goto suspend; - suspend: - self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; +// -------- func adler32.hasher.checksum_u32 - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_adler32__hasher__checksum_u32( + const wuffs_adler32__hasher* self) { + if (!self) { + return 0; } - return status; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return self->private_impl.f_state; } -// -------- func bzip2.decoder.do_transform_io +// ‼ WUFFS MULTI-FILE SECTION +arm_neon +// -------- func adler32.hasher.up_arm_neon +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__do_transform_io( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - uint32_t v_i = 0; - uint64_t v_tag = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t v_final_checksum_want = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +static wuffs_base__empty_struct +wuffs_adler32__hasher__up_arm_neon( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_s1 = 0; + uint32_t v_s2 = 0; + wuffs_base__slice_u8 v_remaining = {0}; + wuffs_base__slice_u8 v_p = {0}; + uint8x16_t v_p__left = {0}; + uint8x16_t v_p_right = {0}; + uint32x4_t v_v1 = {0}; + uint32x4_t v_v2 = {0}; + uint16x8_t v_col0 = {0}; + uint16x8_t v_col1 = {0}; + uint16x8_t v_col2 = {0}; + uint16x8_t v_col3 = {0}; + uint32x2_t v_sum1 = {0}; + uint32x2_t v_sum2 = {0}; + uint32x2_t v_sum12 = {0}; + uint32_t v_num_iterate_bytes = 0; + uint64_t v_tail_index = 0; - uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0]; - if (coro_susp_point) { - v_i = self->private_data.s_do_transform_io[0].v_i; - v_tag = self->private_data.s_do_transform_io[0].v_tag; - v_final_checksum_want = self->private_data.s_do_transform_io[0].v_final_checksum_want; + v_s1 = ((self->private_impl.f_state) & 0xFFFFu); + v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); + while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { + v_s1 += ((uint32_t)(a_x.ptr[0u])); + v_s2 += v_s1; + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c != 66u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); - goto exit; + v_s1 %= 65521u; + v_s2 %= 65521u; + while (((uint64_t)(a_x.len)) > 0u) { + v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); + if (((uint64_t)(a_x.len)) > 5536u) { + v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u); + a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u); } + v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u))); + v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes)); + v_v1 = vdupq_n_u32(0u); + v_v2 = vdupq_n_u32(0u); + v_col0 = vdupq_n_u16(0u); + v_col1 = vdupq_n_u16(0u); + v_col2 = vdupq_n_u16(0u); + v_col3 = vdupq_n_u16(0u); { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 32; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32)); + while (v_p.ptr < i_end0_p) { + v_p__left = vld1q_u8(v_p.ptr); + v_p_right = vld1q_u8(v_p.ptr + 16u); + v_v2 = vaddq_u32(v_v2, v_v1); + v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right)); + v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left)); + v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left)); + v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right)); + v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right)); + v_p.ptr += 32; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - if (v_c != 90u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); - goto exit; + v_p.len = 0; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_v2 = vshlq_n_u32(v_v2, 5u); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u})); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u})); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u})); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u})); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u})); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u})); + v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u})); + v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u})); + v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1)); + v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2)); + v_sum12 = vpadd_u32(v_sum1, v_sum2); + v_s1 += vget_lane_u32(v_sum12, 0u); + v_s2 += vget_lane_u32(v_sum12, 1u); + v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u); + if (v_tail_index < ((uint64_t)(a_x.len))) { + { + wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); + v_p.ptr = i_slice_p.ptr; + v_p.len = 1; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end0_p) { + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; + } + v_p.len = 0; } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; } - if (v_c != 104u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); - goto exit; + v_s1 %= 65521u; + v_s2 %= 65521u; + a_x = v_remaining; + } + self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +// ‼ WUFFS MULTI-FILE SECTION -arm_neon + +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func adler32.hasher.up_x86_sse42 + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_adler32__hasher__up_x86_sse42( + wuffs_adler32__hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_s1 = 0; + uint32_t v_s2 = 0; + wuffs_base__slice_u8 v_remaining = {0}; + wuffs_base__slice_u8 v_p = {0}; + __m128i v_zeroes = {0}; + __m128i v_ones = {0}; + __m128i v_weights__left = {0}; + __m128i v_weights_right = {0}; + __m128i v_q__left = {0}; + __m128i v_q_right = {0}; + __m128i v_v1 = {0}; + __m128i v_v2 = {0}; + __m128i v_v2j = {0}; + __m128i v_v2k = {0}; + uint32_t v_num_iterate_bytes = 0; + uint64_t v_tail_index = 0; + + v_zeroes = _mm_set1_epi16((int16_t)(0u)); + v_ones = _mm_set1_epi16((int16_t)(1u)); + v_weights__left = _mm_set_epi8((int8_t)(17u), (int8_t)(18u), (int8_t)(19u), (int8_t)(20u), (int8_t)(21u), (int8_t)(22u), (int8_t)(23u), (int8_t)(24u), (int8_t)(25u), (int8_t)(26u), (int8_t)(27u), (int8_t)(28u), (int8_t)(29u), (int8_t)(30u), (int8_t)(31u), (int8_t)(32u)); + v_weights_right = _mm_set_epi8((int8_t)(1u), (int8_t)(2u), (int8_t)(3u), (int8_t)(4u), (int8_t)(5u), (int8_t)(6u), (int8_t)(7u), (int8_t)(8u), (int8_t)(9u), (int8_t)(10u), (int8_t)(11u), (int8_t)(12u), (int8_t)(13u), (int8_t)(14u), (int8_t)(15u), (int8_t)(16u)); + v_s1 = ((self->private_impl.f_state) & 0xFFFFu); + v_s2 = ((self->private_impl.f_state) >> (32u - 16u)); + while (((uint64_t)(a_x.len)) > 0u) { + v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); + if (((uint64_t)(a_x.len)) > 5536u) { + v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u); + a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u); } + v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u))); + v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes)); + v_v1 = _mm_setzero_si128(); + v_v2j = _mm_setzero_si128(); + v_v2k = _mm_setzero_si128(); { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; - } - if ((v_c < 49u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); - goto exit; - } - self->private_impl.f_max_incl_block_size = (((uint32_t)((v_c - 48u))) * 100000u); - while (true) { - v_tag = 0u; - v_i = 0u; - while (v_i < 48u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; - } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - v_tag <<= 1u; - v_tag |= ((uint64_t)((self->private_impl.f_bits >> 31u))); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - } - if (v_tag == 25779555029136u) { - break; - } else if (v_tag != 54156738319193u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - status = wuffs_bzip2__decoder__prepare_block(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_block_size = 0u; - self->private_impl.f_decode_huffman_finished = false; - self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[0u] & 7u)]; - self->private_impl.f_decode_huffman_ticks = 50u; - self->private_impl.f_decode_huffman_section = 0u; - self->private_impl.f_decode_huffman_run_shift = 0u; - while ( ! self->private_impl.f_decode_huffman_finished) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_bzip2__decoder__decode_huffman_fast(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; - goto exit; - } else if (self->private_impl.f_decode_huffman_finished) { - break; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - status = wuffs_bzip2__decoder__decode_huffman_slow(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } - wuffs_bzip2__decoder__invert_bwt(self); - self->private_impl.f_block_checksum_have = 4294967295u; - if (self->private_impl.f_original_pointer >= self->private_impl.f_block_size) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); - goto exit; - } - self->private_impl.f_flush_pointer = (self->private_data.f_bwt[self->private_impl.f_original_pointer] >> 12u); - self->private_impl.f_flush_repeat_count = 0u; - self->private_impl.f_flush_prev = 0u; - while (self->private_impl.f_block_size > 0u) { - wuffs_bzip2__decoder__flush_fast(self, a_dst); - if (self->private_impl.f_block_size <= 0u) { - break; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - status = wuffs_bzip2__decoder__flush_slow(self, a_dst); - if (status.repr) { - goto suspend; - } - } - self->private_impl.f_block_checksum_have ^= 4294967295u; - if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_block_checksum_have != self->private_impl.f_block_checksum_want)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum); - goto exit; + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 32; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32)); + while (v_p.ptr < i_end0_p) { + v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr)); + v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)); + v_v2j = _mm_add_epi32(v_v2j, v_v1); + v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes)); + v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes)); + v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left))); + v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right))); + v_p.ptr += 32; } - self->private_impl.f_final_checksum_have = (self->private_impl.f_block_checksum_have ^ ((self->private_impl.f_final_checksum_have >> 31u) | ((uint32_t)(self->private_impl.f_final_checksum_have << 1u)))); + v_p.len = 0; } - v_final_checksum_want = 0u; - v_i = 0u; - while (v_i < 32u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; + v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177u))); + v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78u))); + v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1))); + v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5u))); + v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177u))); + v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78u))); + v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2))); + v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u); + if (v_tail_index < ((uint64_t)(a_x.len))) { + { + wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); + v_p.ptr = i_slice_p.ptr; + v_p.len = 1; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end0_p) { + v_s1 += ((uint32_t)(v_p.ptr[0u])); + v_s2 += v_s1; + v_p.ptr += 1; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; + v_p.len = 0; } - v_final_checksum_want <<= 1u; - v_final_checksum_want |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; } - if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_final_checksum_have != v_final_checksum_want)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum); - goto exit; - } - - goto ok; - ok: - self->private_impl.p_do_transform_io[0] = 0; - goto exit; + v_s1 %= 65521u; + v_s2 %= 65521u; + a_x = v_remaining; } + self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u)); + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 - goto suspend; - suspend: - self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_transform_io[0].v_i = v_i; - self->private_data.s_do_transform_io[0].v_tag = v_tag; - self->private_data.s_do_transform_io[0].v_final_checksum_want = v_final_checksum_want; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) - return status; -} +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) -// -------- func bzip2.decoder.prepare_block +// ---------------- Status Codes Implementations -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__prepare_block( - wuffs_bzip2__decoder* self, +const char wuffs_bmp__error__bad_header[] = "#bmp: bad header"; +const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression"; +const char wuffs_bmp__error__truncated_input[] = "#bmp: truncated input"; +const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file"; +const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read"; + +// ---------------- Private Consts + +#define WUFFS_BMP__COMPRESSION_NONE 0u + +#define WUFFS_BMP__COMPRESSION_RLE8 1u + +#define WUFFS_BMP__COMPRESSION_RLE4 2u + +#define WUFFS_BMP__COMPRESSION_BITFIELDS 3u + +#define WUFFS_BMP__COMPRESSION_JPEG 4u + +#define WUFFS_BMP__COMPRESSION_PNG 5u + +#define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6u + +#define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256u + +#define WUFFS_BMP__RLE_STATE_NEUTRAL 0u + +#define WUFFS_BMP__RLE_STATE_RUN 1u + +#define WUFFS_BMP__RLE_STATE_ESCAPE 2u + +#define WUFFS_BMP__RLE_STATE_LITERAL 3u + +#define WUFFS_BMP__RLE_STATE_DELTA_X 4u + +#define WUFFS_BMP__RLE_STATE_DELTA_Y 5u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__do_decode_image_config( + wuffs_bmp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__do_decode_frame_config( + wuffs_bmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__do_decode_frame( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__swizzle_none( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__swizzle_rle( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__swizzle_bitfields( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__swizzle_low_bit_depth( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__do_tell_me_more( + wuffs_bmp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__read_palette( + wuffs_bmp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__process_masks( + wuffs_bmp__decoder* self); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_bmp__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_bmp__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_bmp__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_bmp__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_bmp__decoder__initialize( + wuffs_bmp__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_bmp__decoder* +wuffs_bmp__decoder__alloc(void) { + wuffs_bmp__decoder* x = + (wuffs_bmp__decoder*)(calloc(1, sizeof(wuffs_bmp__decoder))); + if (!x) { + return NULL; + } + if (wuffs_bmp__decoder__initialize( + x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_bmp__decoder(void) { + return sizeof(wuffs_bmp__decoder); +} + +// ---------------- Function Implementations + +// -------- func bmp.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_bmp__decoder__get_quirk( + const wuffs_bmp__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func bmp.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__set_quirk( + wuffs_bmp__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func bmp.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__decode_image_config( + wuffs_bmp__decoder* self, + wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint32_t v_i = 0; - uint32_t v_j = 0; - uint32_t v_selector = 0; - uint32_t v_sel_ff = 0; - uint8_t v_movee = 0; wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func bmp.decoder.do_decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__do_decode_image_config( + wuffs_bmp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_magic = 0; + 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; + const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -30999,797 +31613,1141 @@ wuffs_bzip2__decoder__prepare_block( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_prepare_block[0]; - if (coro_susp_point) { - v_i = self->private_data.s_prepare_block[0].v_i; - v_selector = self->private_data.s_prepare_block[0].v_selector; - } + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - self->private_impl.f_block_checksum_want = 0u; - v_i = 0u; - while (v_i < 32u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if ((self->private_impl.f_call_sequence != 0u) || (self->private_impl.f_io_redirect_fourcc == 1u)) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if (self->private_impl.f_io_redirect_fourcc != 0u) { + status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); + goto ok; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - self->private_impl.f_block_checksum_want <<= 1u; - self->private_impl.f_block_checksum_want |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - } - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 8) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; + v_magic = t_0; } - if ((self->private_impl.f_bits >> 31u) != 0u) { - status = wuffs_base__make_status(wuffs_bzip2__error__unsupported_block_randomization); + if (v_magic != 19778u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); goto exit; } - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - self->private_impl.f_original_pointer = 0u; - v_i = 0u; - while (v_i < 24u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + self->private_data.s_do_decode_image_config.scratch = 8u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; } - self->private_impl.f_original_pointer <<= 1u; - self->private_impl.f_original_pointer |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; + self->private_impl.f_padding = t_1; } - v_i = 0u; - while (v_i < 256u) { - self->private_data.f_presence[v_i] = 0u; - v_i += 1u; + if (self->private_impl.f_padding < 14u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; } - v_i = 0u; - while (v_i < 256u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + self->private_impl.f_padding -= 14u; + self->private_impl.f_io_redirect_pos = wuffs_base__u64__sat_add(((uint64_t)(self->private_impl.f_padding)), wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - if ((self->private_impl.f_bits >> 31u) != 0u) { - self->private_data.f_presence[v_i] = 1u; } - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 16u; + self->private_impl.f_bitmap_info_len = t_2; } - self->private_data.f_scratch = 0u; - v_i = 0u; - while (v_i < 256u) { - if (self->private_data.f_presence[v_i] == 0u) { - v_i += 16u; - continue; - } - while (true) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } + self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len; + if (self->private_impl.f_bitmap_info_len == 12u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 8) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - self->private_data.f_scratch += (self->private_impl.f_bits >> 31u); - self->private_data.f_presence[(v_i & 255u)] = ((uint8_t)((self->private_impl.f_bits >> 31u))); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - if ((v_i & 15u) == 0u) { - break; } + self->private_impl.f_width = t_3; } - } - if ((self->private_data.f_scratch < 1u) || (256u < self->private_data.f_scratch)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; - } - self->private_impl.f_num_symbols = (self->private_data.f_scratch + 2u); - self->private_data.f_scratch = 0u; - v_i = 0u; - while (v_i < 3u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 8) { + t_4 = ((uint32_t)(*scratch)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)) << 56; } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; + self->private_impl.f_height = t_4; } - self->private_data.f_scratch <<= 1u; - self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - } - if ((self->private_data.f_scratch < 2u) || (6u < self->private_data.f_scratch)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; - } - self->private_impl.f_num_huffman_codes = self->private_data.f_scratch; - self->private_data.f_scratch = 0u; - v_i = 0u; - while (v_i < 15u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + uint32_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5; + if (num_bits_5 == 8) { + t_5 = ((uint32_t)(*scratch)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)) << 56; } - uint8_t t_6 = *iop_a_src++; - v_c = t_6; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; + v_planes = t_5; } - self->private_data.f_scratch <<= 1u; - self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - } - if ((self->private_data.f_scratch < 1u) || (18001u < self->private_data.f_scratch)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; - } - self->private_impl.f_num_sections = self->private_data.f_scratch; - v_i = 0u; - while (v_i < self->private_impl.f_num_huffman_codes) { - self->private_data.f_mtft[v_i] = ((uint8_t)(v_i)); - v_i += 1u; - } - v_i = 0u; - while (v_i < self->private_impl.f_num_sections) { - v_selector = 0u; - while (true) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (v_planes != 1u) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + uint32_t t_6; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_7 = *iop_a_src++; - v_c = t_7; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6; + if (num_bits_6 == 8) { + t_6 = ((uint32_t)(*scratch)); + break; + } + num_bits_6 += 8u; + *scratch |= ((uint64_t)(num_bits_6)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - if ((self->private_impl.f_bits >> 31u) == 0u) { - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - break; } - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_selector += 1u; - if (v_selector >= self->private_impl.f_num_huffman_codes) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; + self->private_impl.f_bits_per_pixel = t_6; + } + } else if (self->private_impl.f_bitmap_info_len == 16u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + uint32_t t_7; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; + if (num_bits_7 == 24) { + t_7 = ((uint32_t)(*scratch)); + break; + } + num_bits_7 += 8u; + *scratch |= ((uint64_t)(num_bits_7)) << 56; + } } + v_width = t_7; } - if (v_selector == 0u) { - self->private_data.f_huffman_selectors[v_i] = self->private_data.f_mtft[0u]; - } else { - v_sel_ff = (v_selector & 255u); - v_movee = self->private_data.f_mtft[v_sel_ff]; - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_sel_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_sel_ff)); - self->private_data.f_mtft[0u] = v_movee; - self->private_data.f_huffman_selectors[v_i] = v_movee; + if (v_width > 2147483647u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } else if (v_width > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; } - v_i += 1u; - } - v_i = 0u; - while (v_i < self->private_impl.f_num_huffman_codes) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + self->private_impl.f_width = v_width; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); + uint32_t t_8; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8; + if (num_bits_8 == 24) { + t_8 = ((uint32_t)(*scratch)); + break; + } + num_bits_8 += 8u; + *scratch |= ((uint64_t)(num_bits_8)) << 56; + } + } + v_height = t_8; } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_bzip2__decoder__read_code_lengths(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + if (v_height > 2147483647u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } else if (v_height > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; } - if (status.repr) { - goto suspend; + self->private_impl.f_height = v_height; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); + uint32_t t_9; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9; + if (num_bits_9 == 8) { + t_9 = ((uint32_t)(*scratch)); + break; + } + num_bits_9 += 8u; + *scratch |= ((uint64_t)(num_bits_9)) << 56; + } + } + v_planes = t_9; } - v_status = wuffs_bzip2__decoder__build_huffman_tree(self, v_i); - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; + if (v_planes != 1u) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); goto exit; } - wuffs_bzip2__decoder__build_huffman_table(self, v_i); - v_i += 1u; - } - v_i = 0u; - v_j = 0u; - while (v_i < 256u) { - if (self->private_data.f_presence[v_i] != 0u) { - self->private_data.f_mtft[(v_j & 255u)] = ((uint8_t)(v_i)); - v_j += 1u; - } - v_i += 1u; - } - v_i = 0u; - while (v_i < 256u) { - self->private_data.f_letter_counts[v_i] = 0u; - v_i += 1u; - } - - goto ok; - ok: - self->private_impl.p_prepare_block[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_prepare_block[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_prepare_block[0].v_i = v_i; - self->private_data.s_prepare_block[0].v_selector = v_selector; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func bzip2.decoder.read_code_lengths - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__read_code_lengths( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - uint32_t v_i = 0; - uint32_t v_code_length = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_read_code_lengths[0]; - if (coro_susp_point) { - v_i = self->private_data.s_read_code_lengths[0].v_i; - v_code_length = self->private_data.s_read_code_lengths[0].v_code_length; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - self->private_impl.f_code_lengths_bitmask = 0u; - v_i = 0u; - while (v_i < 5u) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); + uint32_t t_10; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10; + if (num_bits_10 == 8) { + t_10 = ((uint32_t)(*scratch)); + break; + } + num_bits_10 += 8u; + *scratch |= ((uint64_t)(num_bits_10)) << 56; } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; + self->private_impl.f_bits_per_pixel = t_10; } - v_code_length <<= 1u; - v_code_length |= (self->private_impl.f_bits >> 31u); - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - v_i += 1u; - } - v_i = 0u; - while (v_i < self->private_impl.f_num_symbols) { - while (true) { - if ((v_code_length < 1u) || (20u < v_code_length)) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); - goto exit; - } - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + } else { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); + uint32_t t_11; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11; + if (num_bits_11 == 24) { + t_11 = ((uint32_t)(*scratch)); + break; + } + num_bits_11 += 8u; + *scratch |= ((uint64_t)(num_bits_11)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; } - if ((self->private_impl.f_bits >> 31u) == 0u) { - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - break; - } - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + v_width = t_11; + } + if (v_width > 2147483647u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } else if (v_width > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_width = v_width; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26); + uint32_t t_12; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12; + if (num_bits_12 == 24) { + t_12 = ((uint32_t)(*scratch)); + break; + } + num_bits_12 += 8u; + *scratch |= ((uint64_t)(num_bits_12)) << 56; } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; } - if ((self->private_impl.f_bits >> 31u) == 0u) { - v_code_length += 1u; + v_height = t_12; + } + if (v_height == 2147483648u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } else if (v_height > 2147483648u) { + v_height = ((uint32_t)(0u - v_height)); + if (v_height > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_height = v_height; + self->private_impl.f_top_down = true; + } else if (v_height > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } else { + self->private_impl.f_height = v_height; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28); + uint32_t t_13; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; } else { - v_code_length -= 1u; + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13; + if (num_bits_13 == 8) { + t_13 = ((uint32_t)(*scratch)); + break; + } + num_bits_13 += 8u; + *scratch |= ((uint64_t)(num_bits_13)) << 56; + } } - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; + v_planes = t_13; } - self->private_impl.f_code_lengths_bitmask |= (((uint32_t)(1u)) << (v_code_length & 31u)); - self->private_data.f_bwt[v_i] = v_code_length; - v_i += 1u; - } - - goto ok; - ok: - self->private_impl.p_read_code_lengths[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_read_code_lengths[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_read_code_lengths[0].v_i = v_i; - self->private_data.s_read_code_lengths[0].v_code_length = v_code_length; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func bzip2.decoder.build_huffman_tree - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__build_huffman_tree( - wuffs_bzip2__decoder* self, - uint32_t a_which) { - uint32_t v_code_length = 0; - uint32_t v_symbol_index = 0; - uint32_t v_num_branch_nodes = 0; - uint32_t v_stack_height = 0; - uint32_t v_stack_values[21] = {0}; - uint32_t v_node_index = 0; - uint16_t v_leaf_value = 0; - - self->private_data.f_huffman_trees[a_which][0u][0u] = 0u; - self->private_data.f_huffman_trees[a_which][0u][1u] = 0u; - v_num_branch_nodes = 1u; - v_stack_height = 1u; - v_stack_values[0u] = 0u; - v_code_length = 1u; - while (v_code_length <= 20u) { - if ((self->private_impl.f_code_lengths_bitmask & (((uint32_t)(1u)) << v_code_length)) == 0u) { - v_code_length += 1u; - continue; - } - v_symbol_index = 0u; - while (v_symbol_index < self->private_impl.f_num_symbols) { - if (self->private_data.f_bwt[v_symbol_index] != v_code_length) { - v_symbol_index += 1u; - continue; + if (v_planes != 1u) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; } - while (true) { - if (v_stack_height <= 0u) { - return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_over_subscribed); - } else if (v_stack_height >= v_code_length) { - break; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30); + uint32_t t_14; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14; + if (num_bits_14 == 8) { + t_14 = ((uint32_t)(*scratch)); + break; + } + num_bits_14 += 8u; + *scratch |= ((uint64_t)(num_bits_14)) << 56; + } } - v_node_index = v_stack_values[(v_stack_height - 1u)]; - if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) { - self->private_data.f_huffman_trees[a_which][v_node_index][0u] = ((uint16_t)(v_num_branch_nodes)); + self->private_impl.f_bits_per_pixel = t_14; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32); + uint32_t t_15; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - self->private_data.f_huffman_trees[a_which][v_node_index][1u] = ((uint16_t)(v_num_branch_nodes)); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15; + if (num_bits_15 == 24) { + t_15 = ((uint32_t)(*scratch)); + break; + } + num_bits_15 += 8u; + *scratch |= ((uint64_t)(num_bits_15)) << 56; + } } - if (v_num_branch_nodes >= 257u) { - return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed); + self->private_impl.f_compression = t_15; + } + if (self->private_impl.f_bits_per_pixel == 0u) { + if (self->private_impl.f_compression == 4u) { + self->private_impl.f_io_redirect_fourcc = 1246774599u; + status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); + goto ok; + } else if (self->private_impl.f_compression == 5u) { + self->private_impl.f_io_redirect_fourcc = 1347307296u; + status = wuffs_base__make_status(wuffs_base__note__i_o_redirect); + goto ok; } - v_stack_values[v_stack_height] = v_num_branch_nodes; - self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][0u] = 0u; - self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][1u] = 0u; - v_num_branch_nodes += 1u; - v_stack_height += 1u; + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; } - v_node_index = v_stack_values[(v_stack_height - 1u)]; - if (v_symbol_index < 2u) { - v_leaf_value = ((uint16_t)((769u + v_symbol_index))); - } else if ((v_symbol_index + 1u) < self->private_impl.f_num_symbols) { - v_leaf_value = ((uint16_t)((511u + v_symbol_index))); - } else { - v_leaf_value = 768u; + self->private_data.s_do_decode_image_config.scratch = 20u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) { - self->private_data.f_huffman_trees[a_which][v_node_index][0u] = v_leaf_value; - } else { - self->private_data.f_huffman_trees[a_which][v_node_index][1u] = v_leaf_value; - v_stack_height -= 1u; - while (v_stack_height > 0u) { - v_node_index = v_stack_values[(v_stack_height - 1u)]; - if (self->private_data.f_huffman_trees[a_which][v_node_index][1u] == 0u) { - break; + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + if (self->private_impl.f_bitmap_info_len == 40u) { + if (self->private_impl.f_bits_per_pixel >= 16u) { + if (self->private_impl.f_padding >= 16u) { + self->private_impl.f_bitmap_info_len = 56u; + self->private_impl.f_padding -= 16u; + } else if (self->private_impl.f_padding >= 12u) { + self->private_impl.f_bitmap_info_len = 52u; + self->private_impl.f_padding -= 12u; } - v_stack_height -= 1u; } + } else if ((self->private_impl.f_bitmap_info_len != 52u) && + (self->private_impl.f_bitmap_info_len != 56u) && + (self->private_impl.f_bitmap_info_len != 64u) && + (self->private_impl.f_bitmap_info_len != 108u) && + (self->private_impl.f_bitmap_info_len != 124u)) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + if (self->private_impl.f_compression == 6u) { + self->private_impl.f_compression = 3u; + } + if (self->private_impl.f_compression == 3u) { + if (self->private_impl.f_bitmap_info_len >= 52u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35); + uint32_t t_16; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16; + if (num_bits_16 == 24) { + t_16 = ((uint32_t)(*scratch)); + break; + } + num_bits_16 += 8u; + *scratch |= ((uint64_t)(num_bits_16)) << 56; + } + } + self->private_impl.f_channel_masks[2u] = t_16; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37); + uint32_t t_17; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17; + if (num_bits_17 == 24) { + t_17 = ((uint32_t)(*scratch)); + break; + } + num_bits_17 += 8u; + *scratch |= ((uint64_t)(num_bits_17)) << 56; + } + } + self->private_impl.f_channel_masks[1u] = t_17; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39); + uint32_t t_18; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18; + if (num_bits_18 == 24) { + t_18 = ((uint32_t)(*scratch)); + break; + } + num_bits_18 += 8u; + *scratch |= ((uint64_t)(num_bits_18)) << 56; + } + } + self->private_impl.f_channel_masks[0u] = t_18; + } + if (self->private_impl.f_bitmap_info_len >= 56u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41); + uint32_t t_19; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19; + if (num_bits_19 == 24) { + t_19 = ((uint32_t)(*scratch)); + break; + } + num_bits_19 += 8u; + *scratch |= ((uint64_t)(num_bits_19)) << 56; + } + } + self->private_impl.f_channel_masks[3u] = t_19; + } + self->private_data.s_do_decode_image_config.scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56u)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + } + if ((self->private_impl.f_channel_masks[0u] == 255u) && (self->private_impl.f_channel_masks[1u] == 65280u) && (self->private_impl.f_channel_masks[2u] == 16711680u)) { + if (self->private_impl.f_bits_per_pixel == 24u) { + self->private_impl.f_compression = 0u; + } else if (self->private_impl.f_bits_per_pixel == 32u) { + if ((self->private_impl.f_channel_masks[3u] == 0u) || (self->private_impl.f_channel_masks[3u] == 4278190080u)) { + self->private_impl.f_compression = 0u; + } + } + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44); + status = wuffs_bmp__decoder__process_masks(self); + if (status.repr) { + goto suspend; + } + } + } else if (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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; } - v_symbol_index += 1u; } - v_code_length += 1u; + if (self->private_impl.f_compression != 3u) { + if (self->private_impl.f_bits_per_pixel < 16u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46); + status = wuffs_bmp__decoder__read_palette(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + } + if (self->private_impl.f_compression == 0u) { + if ((self->private_impl.f_bits_per_pixel == 1u) || (self->private_impl.f_bits_per_pixel == 2u) || (self->private_impl.f_bits_per_pixel == 4u)) { + self->private_impl.f_src_pixfmt = 2198077448u; + self->private_impl.f_compression = 256u; + } else if (self->private_impl.f_bits_per_pixel == 8u) { + self->private_impl.f_src_pixfmt = 2198077448u; + } else if (self->private_impl.f_bits_per_pixel == 16u) { + self->private_impl.f_compression = 3u; + self->private_impl.f_channel_masks[0u] = 31u; + self->private_impl.f_channel_masks[1u] = 992u; + self->private_impl.f_channel_masks[2u] = 31744u; + self->private_impl.f_channel_masks[3u] = 0u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47); + status = wuffs_bmp__decoder__process_masks(self); + if (status.repr) { + goto suspend; + } + self->private_impl.f_src_pixfmt = 2164308923u; + } else if (self->private_impl.f_bits_per_pixel == 24u) { + self->private_impl.f_src_pixfmt = 2147485832u; + } else if (self->private_impl.f_bits_per_pixel == 32u) { + if (self->private_impl.f_channel_masks[3u] == 0u) { + self->private_impl.f_src_pixfmt = 2415954056u; + } else { + self->private_impl.f_src_pixfmt = 2164295816u; + } + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + } else if (self->private_impl.f_compression == 1u) { + if (self->private_impl.f_bits_per_pixel == 8u) { + self->private_impl.f_src_pixfmt = 2198077448u; + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + } else if (self->private_impl.f_compression == 2u) { + if (self->private_impl.f_bits_per_pixel == 4u) { + self->private_impl.f_src_pixfmt = 2198077448u; + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + } else if (self->private_impl.f_compression == 3u) { + if ((self->private_impl.f_bits_per_pixel == 16u) || (self->private_impl.f_bits_per_pixel == 32u)) { + self->private_impl.f_src_pixfmt = 2164308923u; + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + } else { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); + goto exit; + } + if (((self->private_impl.f_bitmap_info_len < 40u) || (self->private_impl.f_bitmap_info_len == 64u)) && + (self->private_impl.f_bits_per_pixel != 1u) && + (self->private_impl.f_bits_per_pixel != 4u) && + (self->private_impl.f_bits_per_pixel != 8u) && + (self->private_impl.f_bits_per_pixel != 24u)) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } + if (self->private_impl.f_bits_per_pixel == 1u) { + v_byte_width = ((self->private_impl.f_width >> 3u) + (((self->private_impl.f_width & 7u) + 7u) >> 3u)); + self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); + } else if (self->private_impl.f_bits_per_pixel == 2u) { + v_byte_width = ((self->private_impl.f_width >> 2u) + (((self->private_impl.f_width & 3u) + 3u) >> 2u)); + self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); + } else if (self->private_impl.f_bits_per_pixel == 4u) { + v_byte_width = ((self->private_impl.f_width >> 1u) + (self->private_impl.f_width & 1u)); + self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u); + } else if (self->private_impl.f_bits_per_pixel == 8u) { + self->private_impl.f_pad_per_row = ((4u - (self->private_impl.f_width & 3u)) & 3u); + } else if (self->private_impl.f_bits_per_pixel == 16u) { + self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1u) * 2u); + } else if (self->private_impl.f_bits_per_pixel == 24u) { + self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3u); + } else if (self->private_impl.f_bits_per_pixel == 32u) { + self->private_impl.f_pad_per_row = 0u; + } + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + v_dst_pixfmt = 2164295816u; + if ((self->private_impl.f_channel_num_bits[0u] > 8u) || + (self->private_impl.f_channel_num_bits[1u] > 8u) || + (self->private_impl.f_channel_num_bits[2u] > 8u) || + (self->private_impl.f_channel_num_bits[3u] > 8u)) { + v_dst_pixfmt = 2164308923u; + } else if (((self->private_impl.f_src_pixfmt == 2198077448u) || (self->private_impl.f_src_pixfmt == 2147485832u) || (self->private_impl.f_src_pixfmt == 2415954056u)) || ((self->private_impl.f_src_pixfmt == 2164308923u) && (self->private_impl.f_channel_masks[3u] == 0u))) { + v_dst_pixfmt = 2415954056u; + } + wuffs_base__image_config__set( + a_dst, + v_dst_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + (self->private_impl.f_channel_masks[3u] == 0u)); + } + self->private_impl.f_call_sequence = 32u; + + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; } - if (v_stack_height != 0u) { - return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed); + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__make_status(NULL); + + return status; } -// -------- func bzip2.decoder.build_huffman_table +// -------- func bmp.decoder.decode_frame_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_bzip2__decoder__build_huffman_table( - wuffs_bzip2__decoder* self, - uint32_t a_which) { - uint32_t v_i = 0; - uint32_t v_bits = 0; - uint16_t v_n_bits = 0; - uint16_t v_child = 0; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__decode_frame_config( + wuffs_bmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - while (v_i < 256u) { - v_bits = (v_i << 24u); - v_n_bits = 0u; - v_child = 0u; - while ((v_child < 257u) && (v_n_bits < 8u)) { - v_child = self->private_data.f_huffman_trees[a_which][v_child][(v_bits >> 31u)]; - v_bits <<= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_n_bits += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - self->private_data.f_huffman_tables[a_which][v_i] = ((uint16_t)((v_child | (v_n_bits << 12u)))); - v_i += 1u; + + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; } - return wuffs_base__make_empty_struct(); + + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; } -// -------- func bzip2.decoder.invert_bwt +// -------- func bmp.decoder.do_decode_frame_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_bzip2__decoder__invert_bwt( - wuffs_bzip2__decoder* self) { - uint32_t v_i = 0; - uint32_t v_letter = 0; - uint32_t v_sum = 0; - uint32_t v_old_sum = 0; +static wuffs_base__status +wuffs_bmp__decoder__do_decode_frame_config( + wuffs_bmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - v_sum = 0u; - v_i = 0u; - while (v_i < 256u) { - v_old_sum = v_sum; - v_sum += self->private_data.f_letter_counts[v_i]; - self->private_data.f_letter_counts[v_i] = v_old_sum; - v_i += 1u; - } - v_i = 0u; - while (v_i < self->private_impl.f_block_size) { - v_letter = (self->private_data.f_bwt[v_i] & 255u); - self->private_data.f_bwt[(self->private_data.f_letter_counts[v_letter] & 1048575u)] |= (v_i << 12u); - self->private_data.f_letter_counts[v_letter] += 1u; - v_i += 1u; + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - return wuffs_base__make_empty_struct(); -} - -// -------- func bzip2.decoder.flush_fast - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_bzip2__decoder__flush_fast( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst) { - uint32_t v_flush_pointer = 0; - uint32_t v_flush_repeat_count = 0; - uint8_t v_flush_prev = 0; - uint32_t v_block_checksum_have = 0; - uint32_t v_block_size = 0; - uint32_t v_entry = 0; - uint8_t v_curr = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - v_flush_pointer = self->private_impl.f_flush_pointer; - v_flush_repeat_count = self->private_impl.f_flush_repeat_count; - v_flush_prev = self->private_impl.f_flush_prev; - v_block_checksum_have = self->private_impl.f_block_checksum_have; - v_block_size = self->private_impl.f_block_size; - while ((v_block_size > 0u) && (((uint64_t)(io2_a_dst - iop_a_dst)) >= 255u)) { - if (v_flush_repeat_count < 4u) { - v_entry = self->private_data.f_bwt[v_flush_pointer]; - v_curr = ((uint8_t)(v_entry)); - v_flush_pointer = (v_entry >> 12u); - if (v_curr == v_flush_prev) { - v_flush_repeat_count += 1u; - } else { - v_flush_repeat_count = 1u; + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u))); - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_curr), iop_a_dst += 1); - v_flush_prev = v_curr; - v_block_size -= 1u; - } else { - v_entry = self->private_data.f_bwt[v_flush_pointer]; - v_curr = ((uint8_t)(v_entry)); - v_flush_pointer = (v_entry >> 12u); - v_flush_repeat_count = ((uint32_t)(v_curr)); - while (v_flush_repeat_count > 0u) { - v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u))); - if (((uint64_t)(io2_a_dst - iop_a_dst)) > 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_flush_prev), iop_a_dst += 1); - } - v_flush_repeat_count -= 1u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_bmp__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - v_flush_repeat_count = 0u; - v_flush_prev = v_curr; - v_block_size -= 1u; + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + self->private_impl.f_frame_config_io_position, + 0u, + true, + false, + 4278190080u); + } + self->private_impl.f_call_sequence = 64u; + + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; } - self->private_impl.f_flush_pointer = v_flush_pointer; - self->private_impl.f_flush_repeat_count = v_flush_repeat_count; - self->private_impl.f_flush_prev = v_flush_prev; - self->private_impl.f_block_checksum_have = v_block_checksum_have; - if (v_block_size <= 900000u) { - self->private_impl.f_block_size = v_block_size; - } - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__make_empty_struct(); + return status; } -// -------- func bzip2.decoder.flush_slow +// -------- func bmp.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_bzip2__decoder__flush_slow( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_dst) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__decode_frame( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_flush_pointer = 0; - uint32_t v_flush_repeat_count = 0; - uint8_t v_flush_prev = 0; - uint32_t v_block_checksum_have = 0; - uint32_t v_block_size = 0; - uint32_t v_entry = 0; - uint8_t v_curr = 0; - - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_flush_slow[0]; - if (coro_susp_point) { - v_flush_pointer = self->private_data.s_flush_slow[0].v_flush_pointer; - v_flush_repeat_count = self->private_data.s_flush_slow[0].v_flush_repeat_count; - v_flush_prev = self->private_data.s_flush_slow[0].v_flush_prev; - v_block_checksum_have = self->private_data.s_flush_slow[0].v_block_checksum_have; - v_block_size = self->private_data.s_flush_slow[0].v_block_size; - v_curr = self->private_data.s_flush_slow[0].v_curr; - } + uint32_t coro_susp_point = self->private_impl.p_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - v_flush_pointer = self->private_impl.f_flush_pointer; - v_flush_repeat_count = self->private_impl.f_flush_repeat_count; - v_flush_prev = self->private_impl.f_flush_prev; - v_block_checksum_have = self->private_impl.f_block_checksum_have; - v_block_size = self->private_impl.f_block_size; - while ((v_block_size > 0u) && ! (self->private_impl.p_flush_slow[0] != 0)) { - if (v_flush_repeat_count < 4u) { - v_entry = self->private_data.f_bwt[v_flush_pointer]; - v_curr = ((uint8_t)(v_entry)); - v_flush_pointer = (v_entry >> 12u); - if (v_curr == v_flush_prev) { - v_flush_repeat_count += 1u; - } else { - v_flush_repeat_count = 1u; - } - v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u))); - self->private_data.s_flush_slow[0].scratch = v_curr; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (iop_a_dst == io2_a_dst) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - goto suspend; - } - *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch)); - v_flush_prev = v_curr; - v_block_size -= 1u; - } else { - v_entry = self->private_data.f_bwt[v_flush_pointer]; - v_curr = ((uint8_t)(v_entry)); - v_flush_pointer = (v_entry >> 12u); - v_flush_repeat_count = ((uint32_t)(v_curr)); - while (v_flush_repeat_count > 0u) { - v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u))); - self->private_data.s_flush_slow[0].scratch = v_flush_prev; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (iop_a_dst == io2_a_dst) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - goto suspend; - } - *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch)); - v_flush_repeat_count -= 1u; - } - v_flush_repeat_count = 0u; - v_flush_prev = v_curr; - v_block_size -= 1u; + while (true) { + { + wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; } - } - self->private_impl.f_flush_pointer = v_flush_pointer; - self->private_impl.f_flush_repeat_count = v_flush_repeat_count; - self->private_impl.f_flush_prev = v_flush_prev; - self->private_impl.f_block_checksum_have = v_block_checksum_have; - if (v_block_size <= 900000u) { - self->private_impl.f_block_size = v_block_size; + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - goto ok; ok: - self->private_impl.p_flush_slow[0] = 0; + self->private_impl.p_decode_frame = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_flush_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_flush_slow[0].v_flush_pointer = v_flush_pointer; - self->private_data.s_flush_slow[0].v_flush_repeat_count = v_flush_repeat_count; - self->private_data.s_flush_slow[0].v_flush_prev = v_flush_prev; - self->private_data.s_flush_slow[0].v_block_checksum_have = v_block_checksum_have; - self->private_data.s_flush_slow[0].v_block_size = v_block_size; - self->private_data.s_flush_slow[0].v_curr = v_curr; + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return status; } -// -------- func bzip2.decoder.decode_huffman_fast +// -------- func bmp.decoder.do_decode_frame WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_bzip2__decoder__decode_huffman_fast( - wuffs_bzip2__decoder* self, - wuffs_base__io_buffer* a_src) { +wuffs_bmp__decoder__do_decode_frame( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_block_size = 0; - uint8_t v_which = 0; - uint32_t v_ticks = 0; - uint32_t v_section = 0; - uint32_t v_run_shift = 0; - uint16_t v_table_entry = 0; - uint16_t v_child = 0; - uint32_t v_child_ff = 0; - uint32_t v_i = 0; - uint32_t v_j = 0; - uint32_t v_output = 0; - uint32_t v_run = 0; - uint32_t v_mtft0 = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -31802,90 +32760,132 @@ wuffs_bzip2__decoder__decode_huffman_fast( io2_a_src = io0_a_src + a_src->meta.wi; } - v_bits = self->private_impl.f_bits; - v_n_bits = self->private_impl.f_n_bits; - v_block_size = self->private_impl.f_block_size; - v_which = self->private_impl.f_decode_huffman_which; - v_ticks = self->private_impl.f_decode_huffman_ticks; - v_section = self->private_impl.f_decode_huffman_section; - v_run_shift = self->private_impl.f_decode_huffman_run_shift; - while (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { - if (v_ticks > 0u) { - v_ticks -= 1u; - } else { - v_ticks = 49u; - v_section += 1u; - if (v_section >= self->private_impl.f_num_sections) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections); - goto exit; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(v_section & 32767u)] & 7u)]; - } - v_bits |= (wuffs_base__peek_u32be__no_bounds_check(iop_a_src) >> v_n_bits); - iop_a_src += ((31u - v_n_bits) >> 3u); - v_n_bits |= 24u; - v_table_entry = self->private_data.f_huffman_tables[v_which][(v_bits >> 24u)]; - v_bits <<= (v_table_entry >> 12u); - v_n_bits -= ((uint32_t)((v_table_entry >> 12u))); - v_child = (v_table_entry & 1023u); - while (v_child < 257u) { - v_child = self->private_data.f_huffman_trees[v_which][v_child][(v_bits >> 31u)]; - v_bits <<= 1u; - if (v_n_bits <= 0u) { - status = wuffs_base__make_status(wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_bmp__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - v_n_bits -= 1u; - } - if (v_child < 768u) { - v_child_ff = ((uint32_t)((v_child & 255u))); - v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff])); - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff)); - self->private_data.f_mtft[0u] = ((uint8_t)(v_output)); - self->private_data.f_letter_counts[v_output] += 1u; - self->private_data.f_bwt[v_block_size] = v_output; - if (v_block_size >= self->private_impl.f_max_incl_block_size) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); - goto exit; + if (status.repr) { + goto suspend; } - v_block_size += 1u; - v_run_shift = 0u; - continue; - } else if (v_child == 768u) { - self->private_impl.f_decode_huffman_finished = true; - break; - } - if (v_run_shift >= 23u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); - goto exit; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } - v_run = ((((uint32_t)(v_child)) & 3u) << v_run_shift); - v_run_shift += 1u; - v_i = v_block_size; - v_j = (v_run + v_block_size); - if (v_j > self->private_impl.f_max_incl_block_size) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); - goto exit; + self->private_data.s_do_decode_frame.scratch = self->private_impl.f_padding; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_block_size = v_j; - v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u])); - self->private_data.f_letter_counts[v_mtft0] += v_run; - while (v_i < v_j) { - self->private_data.f_bwt[v_i] = v_mtft0; - v_i += 1u; + iop_a_src += self->private_data.s_do_decode_frame.scratch; + if ((self->private_impl.f_width > 0u) && (self->private_impl.f_height > 0u)) { + self->private_impl.f_dst_x = 0u; + if (self->private_impl.f_top_down) { + self->private_impl.f_dst_y = 0u; + self->private_impl.f_dst_y_inc = 1u; + } else { + self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1u)); + self->private_impl.f_dst_y_inc = 4294967295u; + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)), + wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), + wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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) { + if (self->private_impl.f_compression == 0u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } else if (self->private_impl.f_compression < 3u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } else if (self->private_impl.f_compression == 3u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } else { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) { + status = v_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; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + } + self->private_data.s_do_decode_frame.scratch = self->private_impl.f_pending_pad; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame.scratch; + self->private_impl.f_pending_pad = 0u; } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; } - self->private_impl.f_bits = v_bits; - self->private_impl.f_n_bits = v_n_bits; - self->private_impl.f_block_size = v_block_size; - self->private_impl.f_decode_huffman_which = v_which; - self->private_impl.f_decode_huffman_ticks = v_ticks; - self->private_impl.f_decode_huffman_section = v_section; - self->private_impl.f_decode_huffman_run_shift = v_run_shift; - status = wuffs_base__make_status(NULL); - goto ok; - ok: + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + goto exit; exit: if (a_src && a_src->data.ptr) { @@ -31895,24 +32895,27 @@ wuffs_bzip2__decoder__decode_huffman_fast( return status; } -// -------- func bzip2.decoder.decode_huffman_slow +// -------- func bmp.decoder.swizzle_none WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_bzip2__decoder__decode_huffman_slow( - wuffs_bzip2__decoder* self, +wuffs_bmp__decoder__swizzle_none( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint32_t v_node_index = 0; - uint16_t v_child = 0; - uint32_t v_child_ff = 0; - uint32_t v_i = 0; - uint32_t v_j = 0; - uint32_t v_output = 0; - uint32_t v_run = 0; - uint32_t v_mtft0 = 0; + 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_bytes_per_row = 0; + uint32_t v_src_bytes_per_pixel = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_j = 0; + uint64_t v_n = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -31925,99 +32928,90 @@ wuffs_bzip2__decoder__decode_huffman_slow( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0]; - if (coro_susp_point) { - v_node_index = self->private_data.s_decode_huffman_slow[0].v_node_index; + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) { - if (self->private_impl.f_decode_huffman_ticks > 0u) { - self->private_impl.f_decode_huffman_ticks -= 1u; - } else { - self->private_impl.f_decode_huffman_ticks = 49u; - self->private_impl.f_decode_huffman_section += 1u; - if (self->private_impl.f_decode_huffman_section >= self->private_impl.f_num_sections) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections); - goto exit; - } - self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(self->private_impl.f_decode_huffman_section & 32767u)] & 7u)]; + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + label__outer__continue:; + while (true) { + while (self->private_impl.f_pending_pad > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; } - v_node_index = 0u; - while (true) { - if (self->private_impl.f_n_bits <= 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u); - self->private_impl.f_n_bits = 8u; - } - v_child = self->private_data.f_huffman_trees[self->private_impl.f_decode_huffman_which][v_node_index][(self->private_impl.f_bits >> 31u)]; - self->private_impl.f_bits <<= 1u; - self->private_impl.f_n_bits -= 1u; - if (v_child < 257u) { - v_node_index = ((uint32_t)(v_child)); - continue; - } else if (v_child < 768u) { - v_child_ff = ((uint32_t)((v_child & 255u))); - v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff])); - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff)); - self->private_data.f_mtft[0u] = ((uint8_t)(v_output)); - self->private_data.f_letter_counts[v_output] += 1u; - self->private_data.f_bwt[self->private_impl.f_block_size] = v_output; - if (self->private_impl.f_block_size >= self->private_impl.f_max_incl_block_size) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); - goto exit; + self->private_impl.f_pending_pad -= 1u; + iop_a_src += 1u; + } + while (true) { + if (self->private_impl.f_dst_x == self->private_impl.f_width) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + if (self->private_impl.f_height > 0u) { + self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; } - self->private_impl.f_block_size += 1u; - self->private_impl.f_decode_huffman_run_shift = 0u; - break; - } else if (v_child == 768u) { - self->private_impl.f_decode_huffman_finished = true; goto label__outer__break; + } else if (self->private_impl.f_pad_per_row != 0u) { + self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; + goto label__outer__continue; } - if (self->private_impl.f_decode_huffman_run_shift >= 23u) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); + } + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i >= ((uint64_t)(v_dst.len))) { + if (self->private_impl.f_bits_per_pixel > 32u) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); goto exit; } - v_run = ((((uint32_t)(v_child)) & 3u) << self->private_impl.f_decode_huffman_run_shift); - self->private_impl.f_decode_huffman_run_shift += 1u; - v_i = self->private_impl.f_block_size; - v_j = (v_run + self->private_impl.f_block_size); - if (v_j > self->private_impl.f_max_incl_block_size) { - status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); + v_src_bytes_per_pixel = (self->private_impl.f_bits_per_pixel / 8u); + if (v_src_bytes_per_pixel == 0u) { + status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file); goto exit; } - self->private_impl.f_block_size = v_j; - v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u])); - self->private_data.f_letter_counts[v_mtft0] += v_run; - while (v_i < v_j) { - self->private_data.f_bwt[v_i] = v_mtft0; - v_i += 1u; + v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); + v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); + v_j = v_n; + while (v_j >= 8u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { + iop_a_src += (v_src_bytes_per_pixel * 8u); + } + v_j -= 8u; } - break; + while (v_j > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { + iop_a_src += (v_src_bytes_per_pixel * 1u); + } + v_j -= 1u; + } + } else { + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( + &self->private_impl.f_swizzler, + wuffs_base__slice_u8__subslice_i(v_dst, v_i), + v_dst_palette, + &iop_a_src, + io2_a_src); + } + if (v_n == 0u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); } - label__outer__break:; - - goto ok; - ok: - self->private_impl.p_decode_huffman_slow[0] = 0; - goto exit; } + label__outer__break:; + status = wuffs_base__make_status(NULL); + goto ok; - goto suspend; - suspend: - self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_huffman_slow[0].v_node_index = v_node_index; - + ok: goto exit; exit: if (a_src && a_src->data.ptr) { @@ -32027,256 +33021,33 @@ wuffs_bzip2__decoder__decode_huffman_slow( return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) - -// ---------------- Status Codes Implementations - -const char wuffs_cbor__error__bad_input[] = "#cbor: bad input"; -const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth"; -const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O"; -const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length"; - -// ---------------- Private Consts - -static const uint32_t -WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = { - 8388612, 8388616, 8388610, 8388609, -}; - -static const uint8_t -WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 5, 9, 0, 0, 0, 1, -}; - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -// ---------------- VTables - -const wuffs_base__token_decoder__func_ptrs -wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__token_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_cbor__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_cbor__decoder__history_retain_length), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_cbor__decoder__set_quirk), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_cbor__decoder__initialize( - wuffs_cbor__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } - - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } - } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name = - wuffs_base__token_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers = - (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder); - return wuffs_base__make_status(NULL); -} - -wuffs_cbor__decoder* -wuffs_cbor__decoder__alloc(void) { - wuffs_cbor__decoder* x = - (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_cbor__decoder__initialize( - x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} - -size_t -sizeof__wuffs_cbor__decoder(void) { - return sizeof(wuffs_cbor__decoder); -} - -// ---------------- Function Implementations - -// -------- func cbor.decoder.get_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_cbor__decoder__get_quirk( - const wuffs_cbor__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func cbor.decoder.set_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_cbor__decoder__set_quirk( - wuffs_cbor__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - return wuffs_base__make_status(wuffs_base__error__unsupported_option); -} - -// -------- func cbor.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_cbor__decoder__history_retain_length( - const wuffs_cbor__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func cbor.decoder.workbuf_len - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_cbor__decoder__workbuf_len( - const wuffs_cbor__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } - - return wuffs_base__utility__empty_range_ii_u64(); -} - -// -------- func cbor.decoder.decode_tokens +// -------- func bmp.decoder.swizzle_rle WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_cbor__decoder__decode_tokens( - wuffs_cbor__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; +static wuffs_base__status +wuffs_bmp__decoder__swizzle_rle( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint64_t v_string_length = 0; - uint64_t v_n64 = 0; - uint32_t v_depth = 0; - uint32_t v_stack_byte = 0; - uint32_t v_stack_bit = 0; - uint32_t v_stack_val = 0; - uint32_t v_token_length = 0; - uint32_t v_vminor = 0; - uint32_t v_vminor_alt = 0; - uint32_t v_continued = 0; - uint8_t v_c = 0; - uint8_t v_c_major = 0; - uint8_t v_c_minor = 0; - bool v_tagged = false; - uint8_t v_indefinite_string_major_type = 0; + 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_bytes_per_row = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_row = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_n = 0; + uint32_t v_p0 = 0; + uint8_t v_code = 0; + uint8_t v_indexes[2] = {0}; + uint32_t v_rle_state = 0; + uint32_t v_chunk_bits = 0; + uint32_t v_chunk_count = 0; - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -32288,1231 +33059,590 @@ wuffs_cbor__decoder__decode_tokens( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0]; - if (coro_susp_point) { - v_string_length = self->private_data.s_decode_tokens[0].v_string_length; - v_depth = self->private_data.s_decode_tokens[0].v_depth; - v_tagged = self->private_data.s_decode_tokens[0].v_tagged; - v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type; + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if (self->private_impl.f_end_of_data) { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + v_rle_state = self->private_impl.f_rle_state; + label__outer__continue:; + while (true) { + v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { + v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); } - label__outer__continue:; + label__middle__continue:; while (true) { + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i <= ((uint64_t)(v_row.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i); + } else { + v_dst = wuffs_base__utility__empty_slice_u8(); + } while (true) { - do { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - goto label__outer__continue; + if (v_rle_state == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + if (v_code == 0u) { + v_rle_state = 2u; + continue; + } + self->private_impl.f_rle_length = ((uint32_t)(v_code)); + v_rle_state = 1u; + continue; + } else if (v_rle_state == 1u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; + } + v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + if (self->private_impl.f_bits_per_pixel == 8u) { + v_p0 = 0u; + while (v_p0 < self->private_impl.f_rle_length) { + self->private_data.f_scratch[v_p0] = v_code; + v_p0 += 1u; + } + } else { + v_indexes[0u] = ((uint8_t)(((uint8_t)(v_code >> 4u)))); + v_indexes[1u] = ((uint8_t)(v_code & 15u)); + v_p0 = 0u; + while (v_p0 < self->private_impl.f_rle_length) { + self->private_data.f_scratch[(v_p0 + 0u)] = v_indexes[0u]; + self->private_data.f_scratch[(v_p0 + 1u)] = v_indexes[1u]; + v_p0 += 2u; + } + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_rle_length)); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length); + v_rle_state = 0u; + goto label__middle__continue; + } else if (v_rle_state == 2u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; + } + v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + if (v_code < 2u) { + if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0u)) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); goto exit; } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u); + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + if (v_code > 0u) { + goto label__outer__break; + } + v_rle_state = 0u; goto label__outer__continue; + } else if (v_code == 2u) { + v_rle_state = 4u; + continue; } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if ((v_indefinite_string_major_type != 0u) && (v_indefinite_string_major_type != (v_c >> 5u))) { - if (v_c != 255u) { - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); - goto exit; + self->private_impl.f_rle_length = ((uint32_t)(v_code)); + self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8u) && (((uint8_t)(v_code & 1u)) != 0u)); + v_rle_state = 3u; + continue; + } else if (v_rle_state == 3u) { + if (self->private_impl.f_bits_per_pixel == 8u) { + v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader( + &self->private_impl.f_swizzler, + self->private_impl.f_rle_length, + v_dst, + v_dst_palette, + &iop_a_src, + io2_a_src); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)(v_n))); + } else { + v_chunk_count = ((self->private_impl.f_rle_length + 3u) / 4u); + v_p0 = 0u; + while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2u)) { + v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2u; + self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u)))); + self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u)))); + self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u)))); + self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u)))); + v_p0 = ((v_p0 & 255u) + 4u); + v_chunk_count -= 1u; } - v_vminor = 4194560u; - if (v_indefinite_string_major_type == 3u) { - v_vminor |= 19u; + v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length); + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0)); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0); + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0); + } + if (self->private_impl.f_rle_length > 0u) { + break; + } + if (self->private_impl.f_rle_padded) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; } - v_indefinite_string_major_type = 0u; iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; + self->private_impl.f_rle_padded = false; + } + v_rle_state = 0u; + goto label__middle__continue; + } else if (v_rle_state == 4u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; } + self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); iop_a_src += 1u; - v_c_major = ((uint8_t)((v_c >> 5u))); - v_c_minor = (v_c & 31u); - if (v_c_minor < 24u) { - v_string_length = ((uint64_t)(v_c_minor)); - } else { - while (true) { - if (v_c_minor == 24u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 1u) { - v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); - iop_a_src += 1u; - break; - } - } else if (v_c_minor == 25u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 2u) { - v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2u; - break; - } - } else if (v_c_minor == 26u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { - v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4u; - break; - } - } else if (v_c_minor == 27u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 8u) { - v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); - iop_a_src += 8u; - break; - } - } else { - v_string_length = 0u; - break; - } - if (iop_a_src > io1_a_src) { - iop_a_src--; - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - goto label__outer__continue; - } - status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); - goto exit; - } + v_rle_state = 5u; + continue; + } + if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) { + break; + } + v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + if (self->private_impl.f_rle_delta_x > 0u) { + wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, ((uint64_t)(self->private_impl.f_rle_delta_x))); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x))); + self->private_impl.f_rle_delta_x = 0u; + if (self->private_impl.f_dst_x > self->private_impl.f_width) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); + goto exit; } - if (v_c_major == 0u) { - if (v_c_minor < 26u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((14680064u | ((uint32_t)((v_string_length & 65535u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor < 28u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((14680064u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - *iop_a_dst++ = wuffs_base__make_token( - (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } - } else if (v_c_major == 1u) { - if (v_c_minor < 26u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length & 65535u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor < 28u) { - if (v_string_length < 9223372036854775808u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length >> 46u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - *iop_a_dst++ = wuffs_base__make_token( - (~((18446744073709551615u - v_string_length) & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } else { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | - (((uint64_t)(16777216u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - goto label__goto_parsed_a_leaf_value__break; - } - } else if (v_c_major == 2u) { - if (v_c_minor < 28u) { - if (v_string_length == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } else if (v_c_minor == 31u) { - if (v_indefinite_string_major_type != 0u) { - break; - } - v_indefinite_string_major_type = 2u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__outer__continue; - } else { - break; - } - while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - continue; - } - v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src))); - v_token_length = ((uint32_t)((v_n64 & 65535u))); - if (v_n64 > 65535u) { - v_token_length = 65535u; - } else if (v_token_length <= 0u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - continue; - } - if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) { - status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length); - goto exit; - } - v_string_length -= ((uint64_t)(v_token_length)); - v_continued = 0u; - if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) { - v_continued = 1u; - } - iop_a_src += v_token_length; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194816u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (v_string_length > 0u) { - continue; - } else if (v_indefinite_string_major_type > 0u) { - goto label__outer__continue; - } - goto label__goto_parsed_a_leaf_value__break; - } - } else if (v_c_major == 3u) { - if (v_c_minor < 28u) { - if (v_string_length == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } else if (v_c_minor == 31u) { - if (v_indefinite_string_major_type != 0u) { - break; - } - v_indefinite_string_major_type = 3u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__outer__continue; - } else { - break; - } - while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - continue; - } - v_n64 = wuffs_base__u64__min(v_string_length, 65535u); - v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src, - ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64)))))); - v_token_length = ((uint32_t)((v_n64 & 65535u))); - if (v_token_length <= 0u) { - if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); - continue; - } - if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) { - status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length); - goto exit; - } - v_string_length -= ((uint64_t)(v_token_length)); - v_continued = 0u; - if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) { - v_continued = 1u; - } - iop_a_src += v_token_length; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (v_string_length > 0u) { - continue; - } else if (v_indefinite_string_major_type > 0u) { - goto label__outer__continue; - } - goto label__goto_parsed_a_leaf_value__break; - } - } else if (v_c_major == 4u) { - if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) { - break; - } else if (v_depth >= 1024u) { - v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])); - while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) { - iop_a_src--; - v_token_length -= 1u; - } - status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth); - goto exit; - } - v_vminor = 2105361u; - v_vminor_alt = 2101282u; - if (v_depth > 0u) { - v_stack_byte = ((v_depth - 1u) / 16u); - v_stack_bit = (((v_depth - 1u) & 15u) * 2u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - v_vminor = 2105377u; - v_vminor_alt = 2105378u; - } else { - v_vminor = 2105409u; - v_vminor_alt = 2113570u; - } - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (v_c_minor == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } - v_stack_byte = (v_depth / 16u); - v_stack_bit = ((v_depth & 15u) * 2u); - self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(3u)) << v_stack_bit)); - self->private_data.f_container_num_remaining[v_depth] = v_string_length; - v_depth += 1u; - v_tagged = false; - goto label__outer__continue; - } else if (v_c_major == 5u) { - if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) { - break; - } else if (v_depth >= 1024u) { - v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])); - while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) { - iop_a_src--; - v_token_length -= 1u; - } - status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth); + } + if (v_code > 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_code -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + while (true) { + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression); goto exit; } - v_vminor = 2113553u; - v_vminor_alt = 2101314u; - if (v_depth > 0u) { - v_stack_byte = ((v_depth - 1u) / 16u); - v_stack_bit = (((v_depth - 1u) & 15u) * 2u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - v_vminor = 2113569u; - v_vminor_alt = 2105410u; - } else { - v_vminor = 2113601u; - v_vminor_alt = 2113602u; - } - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (v_c_minor == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; + v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { + v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); } - v_stack_byte = (v_depth / 16u); - v_stack_bit = ((v_depth & 15u) * 2u); - self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3u)) << v_stack_bit); - self->private_data.f_container_num_remaining[v_depth] = v_string_length; - v_depth += 1u; - v_tagged = false; - goto label__outer__continue; - } else if (v_c_major == 6u) { - if (v_c_minor >= 28u) { + if (v_code <= 0u) { + wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, ((uint64_t)(self->private_impl.f_dst_x))); break; } - if (v_string_length < 262144u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | - (((uint64_t)((4194304u | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } else { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | - (((uint64_t)((4194304u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - *iop_a_dst++ = wuffs_base__make_token( - (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - v_tagged = true; - goto label__outer__continue; - } else if (v_c_major == 7u) { - if (v_c_minor < 20u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | - (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor < 24u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3u)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor == 24u) { - if (v_string_length < 24u) { - if ( ! (iop_a_src > io1_a_src)) { - status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); - goto exit; - } - iop_a_src--; - break; - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | - (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor < 28u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(10490113u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } else if (v_c_minor == 31u) { - if (v_tagged || (v_depth <= 0u)) { - break; - } - v_depth -= 1u; - if (self->private_data.f_container_num_remaining[v_depth] != 0u) { - break; - } - v_stack_byte = (v_depth / 16u); - v_stack_bit = ((v_depth & 15u) * 2u); - v_stack_val = (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit)); - if (v_stack_val == 1u) { - break; - } - if (v_stack_val != 3u) { - v_vminor_alt = 2097186u; - } else { - v_vminor_alt = 2097218u; - } - if (v_depth <= 0u) { - v_vminor_alt |= 4096u; - } else { - v_stack_byte = ((v_depth - 1u) / 16u); - v_stack_bit = (((v_depth - 1u) & 15u) * 2u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - v_vminor_alt |= 8192u; - } else { - v_vminor_alt |= 16384u; - } - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__goto_parsed_a_leaf_value__break; - } - } - } while (0); - if (iop_a_src > io1_a_src) { - iop_a_src--; - status = wuffs_base__make_status(wuffs_cbor__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); - goto exit; - } - label__goto_parsed_a_leaf_value__break:; - v_tagged = false; - while (v_depth > 0u) { - v_stack_byte = ((v_depth - 1u) / 16u); - v_stack_bit = (((v_depth - 1u) & 15u) * 2u); - self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1u)) << (v_stack_bit + 1u)); - if (1u == (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) { - goto label__outer__continue; - } - if (self->private_data.f_container_num_remaining[(v_depth - 1u)] <= 0u) { - goto label__outer__continue; - } - self->private_data.f_container_num_remaining[(v_depth - 1u)] -= 1u; - if (self->private_data.f_container_num_remaining[(v_depth - 1u)] > 0u) { - goto label__outer__continue; - } - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - continue; - } - v_depth -= 1u; - v_stack_byte = (v_depth / 16u); - v_stack_bit = ((v_depth & 15u) * 2u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - v_vminor_alt = 2097186u; - } else { - v_vminor_alt = 2097218u; - } - if (v_depth <= 0u) { - v_vminor_alt |= 4096u; - } else { - v_stack_byte = ((v_depth - 1u) / 16u); - v_stack_bit = (((v_depth - 1u) & 15u) * 2u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - v_vminor_alt |= 8192u; - } else { - v_vminor_alt |= 16384u; + wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_code -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif } } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_rle_state = 0u; + goto label__middle__continue; } - break; + self->private_impl.f_rle_state = v_rle_state; + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; } - self->private_impl.f_end_of_data = true; - - ok: - self->private_impl.p_decode_tokens[0] = 0; - goto exit; } + label__outer__break:; + while (self->private_impl.f_dst_y < self->private_impl.f_height) { + v_row = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) { + v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row); + } + wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u); + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + } + status = wuffs_base__make_status(NULL); + goto ok; - goto suspend; - suspend: - self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - self->private_data.s_decode_tokens[0].v_string_length = v_string_length; - self->private_data.s_decode_tokens[0].v_depth = v_depth; - self->private_data.s_decode_tokens[0].v_tagged = v_tagged; - self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type; - + ok: goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) +// -------- func bmp.decoder.swizzle_bitfields -// ---------------- Status Codes Implementations +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bmp__decoder__swizzle_bitfields( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// ---------------- Private Consts + 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_bytes_per_row = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_n = 0; + uint32_t v_p0 = 0; + uint32_t v_p1 = 0; + uint32_t v_p1_temp = 0; + uint32_t v_num_bits = 0; + uint32_t v_c = 0; + uint32_t v_c32 = 0; + uint32_t v_channel = 0; -static const uint32_t -WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = { - { - 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, - 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, - 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, - 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, - 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, - 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, - 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, - 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, - 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, - 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, - 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, - 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, - 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, - 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, - 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, - 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, - 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, - 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, - 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, - 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, - 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, - 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, - 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, - 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, - 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, - 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, - 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, - 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, - 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, - 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897, - 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, - 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117, - }, { - 0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503, - 3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007, - 1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238, - 2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262, - 2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349, - 1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341, - 3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868, - 396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812, - 4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018, - 950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754, - 3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035, - 1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731, - 1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704, - 2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520, - 792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505, - 3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713, - 998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764, - 4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004, - 1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781, - 3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061, - 2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918, - 1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078, - 3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151, - 740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919, - 3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521, - 52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041, - 2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816, - 1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816, - 1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339, - 2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371, - 347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850, - 3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930, - }, { - 0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189, - 236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925, - 472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261, - 305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805, - 944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829, - 912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605, - 611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653, - 712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277, - 1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189, - 2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661, - 1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317, - 1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333, - 1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845, - 1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845, - 1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805, - 1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389, - 3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973, - 4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565, - 4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541, - 4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965, - 3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429, - 3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405, - 3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125, - 3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973, - 2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997, - 2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141, - 2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645, - 2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309, - 2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605, - 2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645, - 3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461, - 3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061, - }, { - 0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673, - 3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254, - 1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150, - 2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497, - 2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711, - 1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984, - 4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792, - 899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519, - 2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524, - 1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443, - 3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531, - 247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892, - 992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210, - 4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589, - 1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437, - 2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586, - 3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786, - 686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789, - 3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429, - 2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162, - 1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332, - 2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211, - 494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331, - 3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284, - 1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279, - 3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696, - 643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664, - 3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167, - 3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353, - 332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526, - 2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510, - 1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409, - }, { - 0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936, - 812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825, - 1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618, - 1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235, - 3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668, - 4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509, - 2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390, - 2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247, - 1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521, - 1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600, - 940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227, - 140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642, - 2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805, - 2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860, - 4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495, - 3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742, - 2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554, - 2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619, - 3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008, - 3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273, - 1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942, - 1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175, - 281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084, - 548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373, - 3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579, - 3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618, - 2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713, - 3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344, - 685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167, - 413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966, - 1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637, - 2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316, - }, { - 0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416, - 3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933, - 64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411, - 4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014, - 128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910, - 3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211, - 75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573, - 3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960, - 257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796, - 3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657, - 210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591, - 3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074, - 150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066, - 3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143, - 186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393, - 3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092, - 514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976, - 4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413, - 493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043, - 4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838, - 421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798, - 4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563, - 449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629, - 4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752, - 300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412, - 4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353, - 306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279, - 4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570, - 373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282, - 4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895, - 361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321, - 4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284, - }, { - 0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078, - 871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633, - 1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384, - 1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175, - 3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906, - 4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437, - 2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500, - 2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067, - 1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503, - 2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784, - 601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881, - 272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422, - 2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251, - 3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516, - 3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901, - 3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922, - 2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900, - 3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051, - 4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178, - 3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757, - 1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408, - 1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767, - 544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998, - 328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121, - 3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861, - 4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370, - 2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179, - 2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204, - 60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585, - 810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310, - 1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199, - 1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472, - }, { - 0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081, - 3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804, - 2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410, - 2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815, - 4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903, - 714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930, - 2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316, - 1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753, - 698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940, - 4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457, - 1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415, - 2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162, - 3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170, - 51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343, - 2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769, - 2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900, - 1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403, - 2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054, - 796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592, - 4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485, - 2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533, - 2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016, - 3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134, - 85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131, - 2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270, - 2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947, - 102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885, - 3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640, - 2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232, - 1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365, - 4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691, - 747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174, - }, - { - 0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697, - 3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529, - 2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712, - 387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952, - 2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154, - 958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506, - 775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179, - 2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795, - 3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790, - 1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702, - 1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543, - 3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847, - 1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693, - 3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229, - 4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524, - 1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164, - 1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342, - 3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606, - 3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647, - 1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455, - 3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461, - 1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061, - 1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556, - 4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988, - 3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785, - 52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161, - 336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368, - 2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272, - 976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386, - 2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138, - 2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835, - 758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259, - }, { - 0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769, - 332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389, - 665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225, - 880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573, - 1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825, - 1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757, - 1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233, - 2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709, - 2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841, - 2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445, - 3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097, - 2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941, - 3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585, - 3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981, - 4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857, - 3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741, - 3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904, - 4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604, - 3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120, - 3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244, - 2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472, - 3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324, - 2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768, - 2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468, - 2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920, - 1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876, - 1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640, - 1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988, - 937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880, - 607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924, - 273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336, - 60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716, - }, { - 0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987, - 3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342, - 2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616, - 339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981, - 2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820, - 1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641, - 678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855, - 2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762, - 3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900, - 1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953, - 2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151, - 3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002, - 1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963, - 3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046, - 4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128, - 1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941, - 2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372, - 3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145, - 3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007, - 1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514, - 4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179, - 1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566, - 1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216, - 3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101, - 2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467, - 459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694, - 257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632, - 3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501, - 657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156, - 2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129, - 2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911, - 855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042, - }, { - 0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319, - 101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769, - 202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667, - 169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581, - 405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831, - 507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881, - 338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835, - 304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717, - 811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415, - 913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017, - 1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179, - 980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509, - 676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327, - 777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897, - 608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587, - 575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381, - 1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655, - 1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961, - 1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779, - 1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213, - 2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511, - 2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801, - 1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411, - 1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525, - 1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639, - 1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345, - 1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355, - 1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053, - 1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935, - 1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153, - 1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571, - 1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093, - }, { - 0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264, - 1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037, - 3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682, - 3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215, - 3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349, - 3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112, - 125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991, - 1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098, - 3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515, - 3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438, - 160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105, - 1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860, - 250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774, - 1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019, - 3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796, - 3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105, - 2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175, - 4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570, - 342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957, - 1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824, - 320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778, - 1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919, - 2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376, - 4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149, - 501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860, - 1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433, - 2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766, - 4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883, - 2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761, - 4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356, - 446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803, - 1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750, - }, { - 0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408, - 861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230, - 1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292, - 1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706, - 3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656, - 4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390, - 2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012, - 2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530, - 1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809, - 1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247, - 655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309, - 340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251, - 2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609, - 3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543, - 3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253, - 3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115, - 2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218, - 2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140, - 3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134, - 3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712, - 1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002, - 2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564, - 681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782, - 469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576, - 3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603, - 4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613, - 2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247, - 2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769, - 263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683, - 1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645, - 1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695, - 1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977, - }, { - 0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882, - 3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117, - 1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181, - 2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642, - 2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836, - 1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563, - 3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515, - 53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188, - 3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295, - 91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096, - 2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208, - 1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359, - 1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833, - 2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734, - 106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470, - 3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793, - 1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273, - 2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750, - 182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342, - 3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865, - 3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471, - 164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320, - 2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264, - 1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895, - 2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708, - 1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235, - 3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331, - 261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428, - 213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922, - 3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677, - 1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909, - 2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322, - }, { - 0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717, - 1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522, - 3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747, - 2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292, - 390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216, - 1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455, - 4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726, - 2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065, - 780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663, - 1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200, - 3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513, - 3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958, - 960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154, - 1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277, - 3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876, - 2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843, - 1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425, - 804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222, - 3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135, - 3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120, - 1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348, - 953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867, - 2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866, - 3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637, - 1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515, - 26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508, - 2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333, - 3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490, - 1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734, - 380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721, - 2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392, - 4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183, - }, -}; + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -static const uint8_t -WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = { - 212, 43, 68, 84, 1, 0, 0, 0, - 150, 21, 228, 198, 1, 0, 0, 0, -}; - -static const uint8_t -WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = { - 208, 151, 25, 117, 1, 0, 0, 0, - 158, 0, 170, 204, 0, 0, 0, 0, -}; - -static const uint8_t -WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = { - 36, 97, 205, 99, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t -WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = { - 65, 6, 113, 219, 1, 0, 0, 0, - 65, 22, 1, 247, 1, 0, 0, 0, -}; - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x); + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + label__outer__continue:; + while (true) { + while (self->private_impl.f_pending_pad > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; + } + self->private_impl.f_pending_pad -= 1u; + iop_a_src += 1u; + } + while (true) { + if (self->private_impl.f_dst_x == self->private_impl.f_width) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + if (self->private_impl.f_height > 0u) { + self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; + } + goto label__outer__break; + } else if (self->private_impl.f_pad_per_row != 0u) { + self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row; + goto label__outer__continue; + } + } + v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)); + v_p1 = wuffs_base__u32__min(v_p1_temp, 256u); + v_p0 = 0u; + while (v_p0 < v_p1) { + if (self->private_impl.f_bits_per_pixel == 16u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + break; + } + v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2u; + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + break; + } + v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4u; + } + v_channel = 0u; + while (v_channel < 4u) { + if (self->private_impl.f_channel_num_bits[v_channel] == 0u) { + self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = 255u; + self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = 255u; + } else { + v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]); + v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel])); + while (v_num_bits < 16u) { + v_c |= ((uint32_t)(v_c << v_num_bits)); + v_num_bits *= 2u; + } + v_c >>= (v_num_bits - 16u); + self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = ((uint8_t)((v_c >> 0u))); + self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = ((uint8_t)((v_c >> 8u))); + } + v_channel += 1u; + } + v_p0 += 1u; + } + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i >= ((uint64_t)(v_dst.len))) { + v_n = ((uint64_t)(v_p0)); + } else { + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, (8u * v_p0))); + } + if (v_n == 0u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + } + } + label__outer__break:; + status = wuffs_base__make_status(NULL); + goto ok; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up__choosy_default( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x); + ok: + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } -#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_arm_crc32( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) + return status; +} -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_x86_avx2( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) +// -------- func bmp.decoder.swizzle_low_bit_depth -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_x86_sse42( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - -// ---------------- VTables - -const wuffs_base__hasher_u32__func_ptrs -wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = { - (uint32_t(*)(const void*))(&wuffs_crc32__ieee_hasher__checksum_u32), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_crc32__ieee_hasher__get_quirk), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_crc32__ieee_hasher__set_quirk), - (wuffs_base__empty_struct(*)(void*, - wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update), - (uint32_t(*)(void*, - wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32), -}; +static wuffs_base__status +wuffs_bmp__decoder__swizzle_low_bit_depth( + wuffs_bmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// ---------------- Initializer Implementations + 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_bytes_per_row = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_n = 0; + uint32_t v_p0 = 0; + uint32_t v_chunk_bits = 0; + uint32_t v_chunk_count = 0; + uint32_t v_pixels_per_chunk = 0; -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_crc32__ieee_hasher__initialize( - wuffs_crc32__ieee_hasher* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + while (true) { + if (self->private_impl.f_dst_x == self->private_impl.f_width) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + break; + } } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i >= ((uint64_t)(v_dst.len))) { + if (self->private_impl.f_bits_per_pixel == 1u) { + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u); + v_pixels_per_chunk = 32u; + } else if (self->private_impl.f_bits_per_pixel == 2u) { + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u); + v_pixels_per_chunk = 16u; + } else { + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u); + v_pixels_per_chunk = 8u; + } + while ((v_chunk_count >= 64u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 256u)) { + iop_a_src += 256u; + self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 64u)))); + v_chunk_count -= 64u; + } + while ((v_chunk_count >= 8u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 32u)) { + iop_a_src += 32u; + self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 8u)))); + v_chunk_count -= 8u; + } + while (v_chunk_count > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; + } + iop_a_src += 4u; + self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 1u)))); + v_chunk_count -= 1u; + } + continue; + } + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i); + v_p0 = 0u; + if (self->private_impl.f_bits_per_pixel == 1u) { + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u); + v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16u); + while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { + v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4u; + self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((1u & (v_chunk_bits >> 31u)))); + self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((1u & (v_chunk_bits >> 30u)))); + self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((1u & (v_chunk_bits >> 29u)))); + self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((1u & (v_chunk_bits >> 28u)))); + self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((1u & (v_chunk_bits >> 27u)))); + self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((1u & (v_chunk_bits >> 26u)))); + self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((1u & (v_chunk_bits >> 25u)))); + self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((1u & (v_chunk_bits >> 24u)))); + self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((1u & (v_chunk_bits >> 23u)))); + self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((1u & (v_chunk_bits >> 22u)))); + self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((1u & (v_chunk_bits >> 21u)))); + self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((1u & (v_chunk_bits >> 20u)))); + self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((1u & (v_chunk_bits >> 19u)))); + self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((1u & (v_chunk_bits >> 18u)))); + self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((1u & (v_chunk_bits >> 17u)))); + self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((1u & (v_chunk_bits >> 16u)))); + self->private_data.f_scratch[(v_p0 + 16u)] = ((uint8_t)((1u & (v_chunk_bits >> 15u)))); + self->private_data.f_scratch[(v_p0 + 17u)] = ((uint8_t)((1u & (v_chunk_bits >> 14u)))); + self->private_data.f_scratch[(v_p0 + 18u)] = ((uint8_t)((1u & (v_chunk_bits >> 13u)))); + self->private_data.f_scratch[(v_p0 + 19u)] = ((uint8_t)((1u & (v_chunk_bits >> 12u)))); + self->private_data.f_scratch[(v_p0 + 20u)] = ((uint8_t)((1u & (v_chunk_bits >> 11u)))); + self->private_data.f_scratch[(v_p0 + 21u)] = ((uint8_t)((1u & (v_chunk_bits >> 10u)))); + self->private_data.f_scratch[(v_p0 + 22u)] = ((uint8_t)((1u & (v_chunk_bits >> 9u)))); + self->private_data.f_scratch[(v_p0 + 23u)] = ((uint8_t)((1u & (v_chunk_bits >> 8u)))); + self->private_data.f_scratch[(v_p0 + 24u)] = ((uint8_t)((1u & (v_chunk_bits >> 7u)))); + self->private_data.f_scratch[(v_p0 + 25u)] = ((uint8_t)((1u & (v_chunk_bits >> 6u)))); + self->private_data.f_scratch[(v_p0 + 26u)] = ((uint8_t)((1u & (v_chunk_bits >> 5u)))); + self->private_data.f_scratch[(v_p0 + 27u)] = ((uint8_t)((1u & (v_chunk_bits >> 4u)))); + self->private_data.f_scratch[(v_p0 + 28u)] = ((uint8_t)((1u & (v_chunk_bits >> 3u)))); + self->private_data.f_scratch[(v_p0 + 29u)] = ((uint8_t)((1u & (v_chunk_bits >> 2u)))); + self->private_data.f_scratch[(v_p0 + 30u)] = ((uint8_t)((1u & (v_chunk_bits >> 1u)))); + self->private_data.f_scratch[(v_p0 + 31u)] = ((uint8_t)((1u & (v_chunk_bits >> 0u)))); + v_p0 = ((v_p0 & 511u) + 32u); + v_chunk_count -= 1u; + } + } else if (self->private_impl.f_bits_per_pixel == 2u) { + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u); + v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32u); + while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { + v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4u; + self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((3u & (v_chunk_bits >> 30u)))); + self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((3u & (v_chunk_bits >> 28u)))); + self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((3u & (v_chunk_bits >> 26u)))); + self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((3u & (v_chunk_bits >> 24u)))); + self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((3u & (v_chunk_bits >> 22u)))); + self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((3u & (v_chunk_bits >> 20u)))); + self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((3u & (v_chunk_bits >> 18u)))); + self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((3u & (v_chunk_bits >> 16u)))); + self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((3u & (v_chunk_bits >> 14u)))); + self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((3u & (v_chunk_bits >> 12u)))); + self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((3u & (v_chunk_bits >> 10u)))); + self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((3u & (v_chunk_bits >> 8u)))); + self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((3u & (v_chunk_bits >> 6u)))); + self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((3u & (v_chunk_bits >> 4u)))); + self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((3u & (v_chunk_bits >> 2u)))); + self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((3u & (v_chunk_bits >> 0u)))); + v_p0 = ((v_p0 & 511u) + 16u); + v_chunk_count -= 1u; + } } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u); + v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64u); + while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { + v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4u; + self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 28u)))); + self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 24u)))); + self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 20u)))); + self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 16u)))); + self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u)))); + self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u)))); + self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u)))); + self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u)))); + v_p0 = ((v_p0 & 511u) + 8u); + v_chunk_count -= 1u; + } + } + v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x)); + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0)); + if (v_n == 0u) { + status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read); + goto ok; } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); } + status = wuffs_base__make_status(NULL); + goto ok; - self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default; + ok: + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = - wuffs_base__hasher_u32__vtable_name; - self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = - (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32); - return wuffs_base__make_status(NULL); + return status; } -wuffs_crc32__ieee_hasher* -wuffs_crc32__ieee_hasher__alloc(void) { - wuffs_crc32__ieee_hasher* x = - (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1)); - if (!x) { - return NULL; +// -------- func bmp.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_bmp__decoder__frame_dirty_rect( + const wuffs_bmp__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); } - if (wuffs_crc32__ieee_hasher__initialize( - x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); } - return x; -} -size_t -sizeof__wuffs_crc32__ieee_hasher(void) { - return sizeof(wuffs_crc32__ieee_hasher); + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); } -// ---------------- Function Implementations - -// -------- func crc32.ieee_hasher.get_quirk +// -------- func bmp.decoder.num_animation_loops WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_crc32__ieee_hasher__get_quirk( - const wuffs_crc32__ieee_hasher* self, - uint32_t a_key) { +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_bmp__decoder__num_animation_loops( + const wuffs_bmp__decoder* self) { if (!self) { return 0; } @@ -33524,709 +33654,531 @@ wuffs_crc32__ieee_hasher__get_quirk( return 0u; } -// -------- func crc32.ieee_hasher.set_quirk +// -------- func bmp.decoder.num_decoded_frame_configs WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_crc32__ieee_hasher__set_quirk( - wuffs_crc32__ieee_hasher* self, - uint32_t a_key, - uint64_t a_value) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_bmp__decoder__num_decoded_frame_configs( + const wuffs_bmp__decoder* self) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return 0; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; } -// -------- func crc32.ieee_hasher.update +// -------- func bmp.decoder.num_decoded_frames WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__update( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_bmp__decoder__num_decoded_frames( + const wuffs_bmp__decoder* self) { if (!self) { - return wuffs_base__make_empty_struct(); + return 0; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - if (self->private_impl.f_state == 0u) { - self->private_impl.choosy_up = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) - wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) - wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 : -#endif - self->private_impl.choosy_up); + if (self->private_impl.f_call_sequence > 64u) { + return 1u; } - wuffs_crc32__ieee_hasher__up(self, a_x); - return wuffs_base__make_empty_struct(); + return 0u; } -// -------- func crc32.ieee_hasher.update_u32 +// -------- func bmp.decoder.restart_frame WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_crc32__ieee_hasher__update_u32( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__restart_frame( + wuffs_bmp__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { if (!self) { - return 0; + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - wuffs_crc32__ieee_hasher__update(self, a_x); - return self->private_impl.f_state; + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if (a_index != 0u) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + self->private_impl.f_frame_config_io_position = a_io_position; + return wuffs_base__make_status(NULL); } -// -------- func crc32.ieee_hasher.up +// -------- func bmp.decoder.set_report_metadata WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { - return (*self->private_impl.choosy_up)(self, a_x); +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_bmp__decoder__set_report_metadata( + wuffs_bmp__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); } +// -------- func bmp.decoder.tell_me_more + WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up__choosy_default( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s = 0; - wuffs_base__slice_u8 v_p = {0}; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_bmp__decoder__tell_me_more( + wuffs_bmp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - v_s = (4294967295u ^ self->private_impl.f_state); - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 16; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32); - while (v_p.ptr < i_end0_p) { - v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | - (((uint32_t)(v_p.ptr[1u])) << 8u) | - (((uint32_t)(v_p.ptr[2u])) << 16u) | - (((uint32_t)(v_p.ptr[3u])) << 24u)); - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ - WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ - WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ - WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ - WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ - WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ - WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ - WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ - WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ - WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ - WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ - WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ - WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ - WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ - WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ - WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); - v_p.ptr += 16; - v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | - (((uint32_t)(v_p.ptr[1u])) << 8u) | - (((uint32_t)(v_p.ptr[2u])) << 16u) | - (((uint32_t)(v_p.ptr[3u])) << 24u)); - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ - WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ - WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ - WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ - WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ - WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ - WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ - WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ - WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ - WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ - WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ - WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ - WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ - WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ - WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ - WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); - v_p.ptr += 16; - } - v_p.len = 16; - uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16); - while (v_p.ptr < i_end1_p) { - v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | - (((uint32_t)(v_p.ptr[1u])) << 8u) | - (((uint32_t)(v_p.ptr[2u])) << 16u) | - (((uint32_t)(v_p.ptr[3u])) << 24u)); - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ - WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ - WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ - WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ - WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ - WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ - WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ - WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ - WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ - WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ - WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ - WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ - WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ - WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ - WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ - WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); - v_p.ptr += 16; - } - v_p.len = 1; - uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end2_p) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u)); - v_p.ptr += 1; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_tell_me_more; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_bmp__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_bmp__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - v_p.len = 0; + + ok: + self->private_impl.p_tell_me_more = 0; + goto exit; } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); + + goto suspend; + suspend: + self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; } -// -------- func crc32.ieee_hasher.checksum_u32 +// -------- func bmp.decoder.do_tell_me_more WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_crc32__ieee_hasher__checksum_u32( - const wuffs_crc32__ieee_hasher* self) { - if (!self) { - return 0; +static wuffs_base__status +wuffs_bmp__decoder__do_tell_me_more( + wuffs_bmp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + if (self->private_impl.f_io_redirect_fourcc <= 1u) { + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + 1u, + self->private_impl.f_io_redirect_fourcc, + 0u, + self->private_impl.f_io_redirect_pos, + 18446744073709551615u); } + self->private_impl.f_io_redirect_fourcc = 1u; - return self->private_impl.f_state; + goto ok; + ok: + goto exit; + exit: + return status; } -// ‼ WUFFS MULTI-FILE SECTION +arm_crc32 -// -------- func crc32.ieee_hasher.up_arm_crc32 +// -------- func bmp.decoder.workbuf_len -#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_arm_crc32( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { - wuffs_base__slice_u8 v_p = {0}; - uint32_t v_s = 0; - - v_s = (4294967295u ^ self->private_impl.f_state); - while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { - v_s = __crc32b(v_s, a_x.ptr[0u]); - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_bmp__decoder__workbuf_len( + const wuffs_bmp__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); } - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 8; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128); - while (v_p.ptr < i_end0_p) { - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - } - v_p.len = 8; - uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8); - while (v_p.ptr < i_end1_p) { - v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); - v_p.ptr += 8; - } - v_p.len = 1; - uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end2_p) { - v_s = __crc32b(v_s, v_p.ptr[0u]); - v_p.ptr += 1; - } - v_p.len = 0; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); } -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32) -// ‼ WUFFS MULTI-FILE SECTION -arm_crc32 -// ‼ WUFFS MULTI-FILE SECTION +x86_avx2 -// -------- func crc32.ieee_hasher.up_x86_avx2 +// -------- func bmp.decoder.read_palette -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_x86_avx2( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s = 0; - wuffs_base__slice_u8 v_p = {0}; - __m128i v_k = {0}; - __m128i v_x0 = {0}; - __m128i v_x1 = {0}; - __m128i v_x2 = {0}; - __m128i v_x3 = {0}; - __m128i v_y0 = {0}; - __m128i v_y1 = {0}; - __m128i v_y2 = {0}; - __m128i v_y3 = {0}; - uint64_t v_tail_index = 0; +static wuffs_base__status +wuffs_bmp__decoder__read_palette( + wuffs_bmp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - v_s = (4294967295u ^ self->private_impl.f_state); - while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u)); - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); + uint32_t v_i = 0; + uint32_t v_argb = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (((uint64_t)(a_x.len)) < 64u) { - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u)); - v_p.ptr += 1; + + uint32_t coro_susp_point = self->private_impl.p_read_palette; + if (coro_susp_point) { + v_i = self->private_data.s_read_palette.v_i; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_bitmap_info_len == 12u) { + while ((v_i < 256u) && (self->private_impl.f_padding >= 3u)) { + self->private_impl.f_padding -= 3u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { + t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); + iop_a_src += 3; + } else { + self->private_data.s_read_palette.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_read_palette.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 16) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_argb = t_0; + } + v_argb |= 4278190080u; + self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); + self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); + self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); + self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); + v_i += 1u; + } + } else { + while ((v_i < 256u) && (self->private_impl.f_padding >= 4u)) { + self->private_impl.f_padding -= 4u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_read_palette.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_read_palette.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_argb = t_1; + } + v_argb |= 4278190080u; + self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); + self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); + self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); + self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); + v_i += 1u; } - v_p.len = 0; } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); - } - v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)); - v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); - v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)); - v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)); - v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s))); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2)); - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u); - v_p.ptr = i_slice_p.ptr; - v_p.len = 64; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64); - while (v_p.ptr < i_end0_p) { - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u)); - v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u)); - v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u)); - v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u)); - v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u))); - v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u))); - v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u))); - v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u))); - v_p.ptr += 64; + while (v_i < 256u) { + self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u; + v_i += 1u; } - v_p.len = 0; + + goto ok; + ok: + self->private_impl.p_read_palette = 0; + goto exit; } - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4)); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x2); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x3); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u)); - v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u)); - v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ)); - v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u)); - v_x0 = _mm_and_si128(v_x0, v_x2); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU)); - v_x1 = _mm_and_si128(v_x0, v_x2); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u)); - v_x1 = _mm_and_si128(v_x1, v_x2); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u)))); - v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u); - if (v_tail_index < ((uint64_t)(a_x.len))) { - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u)); - v_p.ptr += 1; - } - v_p.len = 0; - } + + goto suspend; + suspend: + self->private_impl.p_read_palette = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_read_palette.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); + + return status; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) -// ‼ WUFFS MULTI-FILE SECTION -x86_avx2 -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func crc32.ieee_hasher.up_x86_sse42 +// -------- func bmp.decoder.process_masks -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_crc32__ieee_hasher__up_x86_sse42( - wuffs_crc32__ieee_hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_s = 0; - wuffs_base__slice_u8 v_p = {0}; - __m128i v_k = {0}; - __m128i v_x0 = {0}; - __m128i v_x1 = {0}; - __m128i v_x2 = {0}; - __m128i v_x3 = {0}; - __m128i v_y0 = {0}; - __m128i v_y1 = {0}; - __m128i v_y2 = {0}; - __m128i v_y3 = {0}; - uint64_t v_tail_index = 0; +static wuffs_base__status +wuffs_bmp__decoder__process_masks( + wuffs_bmp__decoder* self) { + wuffs_base__status status = wuffs_base__make_status(NULL); - v_s = (4294967295u ^ self->private_impl.f_state); - while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u)); - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); - } - if (((uint64_t)(a_x.len)) < 64u) { - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u)); - v_p.ptr += 1; + uint32_t v_i = 0; + uint32_t v_mask = 0; + uint32_t v_n = 0; + + while (v_i < 4u) { + v_mask = self->private_impl.f_channel_masks[v_i]; + if (v_mask != 0u) { + v_n = 0u; + while ((v_mask & 1u) == 0u) { + v_n += 1u; + v_mask >>= 1u; } - v_p.len = 0; - } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); - } - v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)); - v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); - v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)); - v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)); - v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s))); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2)); - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u); - v_p.ptr = i_slice_p.ptr; - v_p.len = 64; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64); - while (v_p.ptr < i_end0_p) { - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u)); - v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u)); - v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u)); - v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u)); - v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u))); - v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u))); - v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u))); - v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u))); - v_p.ptr += 64; - } - v_p.len = 0; - } - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4)); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x2); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u)); - v_x0 = _mm_xor_si128(v_x0, v_x3); - v_x0 = _mm_xor_si128(v_x0, v_y0); - v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u)); - v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u)); - v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ)); - v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u)); - v_x0 = _mm_and_si128(v_x0, v_x2); - v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU)); - v_x1 = _mm_and_si128(v_x0, v_x2); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u)); - v_x1 = _mm_and_si128(v_x1, v_x2); - v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u)); - v_x0 = _mm_xor_si128(v_x0, v_x1); - v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u)))); - v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u); - if (v_tail_index < ((uint64_t)(a_x.len))) { - { - wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index); - v_p.ptr = i_slice_p.ptr; - v_p.len = 1; - uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end0_p) { - v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u)); - v_p.ptr += 1; + self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31u))); + v_n = 0u; + while ((v_mask & 1u) == 1u) { + v_n += 1u; + v_mask >>= 1u; } - v_p.len = 0; + if ((v_mask != 0u) || (v_n > 32u)) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; + } + self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n)); + } else if (v_i != 3u) { + status = wuffs_base__make_status(wuffs_bmp__error__bad_header); + goto exit; } + v_i += 1u; } - self->private_impl.f_state = (4294967295u ^ v_s); - return wuffs_base__make_empty_struct(); + + goto ok; + ok: + goto exit; + exit: + return status; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) // ---------------- Status Codes Implementations -const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)"; -const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)"; -const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count"; -const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition"; -const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code"; -const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length"; -const char wuffs_deflate__error__bad_block[] = "#deflate: bad block"; -const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance"; -const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count"; -const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count"; -const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length"; -const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code"; -const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes"; -const char wuffs_deflate__error__truncated_input[] = "#deflate: truncated input"; -const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state"; -const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O"; -const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance"; -const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits"; +const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[] = "#bzip2: bad Huffman code (over-subscribed)"; +const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[] = "#bzip2: bad Huffman code (under-subscribed)"; +const char wuffs_bzip2__error__bad_block_header[] = "#bzip2: bad block header"; +const char wuffs_bzip2__error__bad_block_length[] = "#bzip2: bad block length"; +const char wuffs_bzip2__error__bad_checksum[] = "#bzip2: bad checksum"; +const char wuffs_bzip2__error__bad_header[] = "#bzip2: bad header"; +const char wuffs_bzip2__error__bad_number_of_sections[] = "#bzip2: bad number of sections"; +const char wuffs_bzip2__error__truncated_input[] = "#bzip2: truncated input"; +const char wuffs_bzip2__error__unsupported_block_randomization[] = "#bzip2: unsupported block randomization"; +const char wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state[] = "#bzip2: internal error: inconsistent Huffman decoder state"; // ---------------- Private Consts static const uint8_t -WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = { - 16, 17, 18, 0, 8, 7, 9, 6, - 10, 5, 11, 4, 12, 3, 13, 2, - 14, 1, 15, -}; - -static const uint8_t -WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 128, 64, 192, 32, 160, 96, 224, - 16, 144, 80, 208, 48, 176, 112, 240, - 8, 136, 72, 200, 40, 168, 104, 232, - 24, 152, 88, 216, 56, 184, 120, 248, - 4, 132, 68, 196, 36, 164, 100, 228, - 20, 148, 84, 212, 52, 180, 116, 244, - 12, 140, 76, 204, 44, 172, 108, 236, - 28, 156, 92, 220, 60, 188, 124, 252, - 2, 130, 66, 194, 34, 162, 98, 226, - 18, 146, 82, 210, 50, 178, 114, 242, - 10, 138, 74, 202, 42, 170, 106, 234, - 26, 154, 90, 218, 58, 186, 122, 250, - 6, 134, 70, 198, 38, 166, 102, 230, - 22, 150, 86, 214, 54, 182, 118, 246, - 14, 142, 78, 206, 46, 174, 110, 238, - 30, 158, 94, 222, 62, 190, 126, 254, - 1, 129, 65, 193, 33, 161, 97, 225, - 17, 145, 81, 209, 49, 177, 113, 241, - 9, 137, 73, 201, 41, 169, 105, 233, - 25, 153, 89, 217, 57, 185, 121, 249, - 5, 133, 69, 197, 37, 165, 101, 229, - 21, 149, 85, 213, 53, 181, 117, 245, - 13, 141, 77, 205, 45, 173, 109, 237, - 29, 157, 93, 221, 61, 189, 125, 253, - 3, 131, 67, 195, 35, 163, 99, 227, - 19, 147, 83, 211, 51, 179, 115, 243, - 11, 139, 75, 203, 43, 171, 107, 235, - 27, 155, 91, 219, 59, 187, 123, 251, - 7, 135, 71, 199, 39, 167, 103, 231, - 23, 151, 87, 215, 55, 183, 119, 247, - 15, 143, 79, 207, 47, 175, 111, 239, - 31, 159, 95, 223, 63, 191, 127, 255, -}; - -static const uint32_t -WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616, - 1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024, - 1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560, - 1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728, +WUFFS_BZIP2__CLAMP_TO_5[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 1u, 2u, 3u, 4u, 5u, 5u, 5u, }; static const uint32_t -WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928, - 1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072, - 1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416, - 1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728, +WUFFS_BZIP2__REV_CRC32_TABLE[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 79764919u, 159529838u, 222504665u, 319059676u, 398814059u, 445009330u, 507990021u, + 638119352u, 583659535u, 797628118u, 726387553u, 890018660u, 835552979u, 1015980042u, 944750013u, + 1276238704u, 1221641927u, 1167319070u, 1095957929u, 1595256236u, 1540665371u, 1452775106u, 1381403509u, + 1780037320u, 1859660671u, 1671105958u, 1733955601u, 2031960084u, 2111593891u, 1889500026u, 1952343757u, + 2552477408u, 2632100695u, 2443283854u, 2506133561u, 2334638140u, 2414271883u, 2191915858u, 2254759653u, + 3190512472u, 3135915759u, 3081330742u, 3009969537u, 2905550212u, 2850959411u, 2762807018u, 2691435357u, + 3560074640u, 3505614887u, 3719321342u, 3648080713u, 3342211916u, 3287746299u, 3467911202u, 3396681109u, + 4063920168u, 4143685023u, 4223187782u, 4286162673u, 3779000052u, 3858754371u, 3904687514u, 3967668269u, + 881225847u, 809987520u, 1023691545u, 969234094u, 662832811u, 591600412u, 771767749u, 717299826u, + 311336399u, 374308984u, 453813921u, 533576470u, 25881363u, 88864420u, 134795389u, 214552010u, + 2023205639u, 2086057648u, 1897238633u, 1976864222u, 1804852699u, 1867694188u, 1645340341u, 1724971778u, + 1587496639u, 1516133128u, 1461550545u, 1406951526u, 1302016099u, 1230646740u, 1142491917u, 1087903418u, + 2896545431u, 2825181984u, 2770861561u, 2716262478u, 3215044683u, 3143675388u, 3055782693u, 3001194130u, + 2326604591u, 2389456536u, 2200899649u, 2280525302u, 2578013683u, 2640855108u, 2418763421u, 2498394922u, + 3769900519u, 3832873040u, 3912640137u, 3992402750u, 4088425275u, 4151408268u, 4197601365u, 4277358050u, + 3334271071u, 3263032808u, 3476998961u, 3422541446u, 3585640067u, 3514407732u, 3694837229u, 3640369242u, + 1762451694u, 1842216281u, 1619975040u, 1682949687u, 2047383090u, 2127137669u, 1938468188u, 2001449195u, + 1325665622u, 1271206113u, 1183200824u, 1111960463u, 1543535498u, 1489069629u, 1434599652u, 1363369299u, + 622672798u, 568075817u, 748617968u, 677256519u, 907627842u, 853037301u, 1067152940u, 995781531u, + 51762726u, 131386257u, 177728840u, 240578815u, 269590778u, 349224269u, 429104020u, 491947555u, + 4046411278u, 4126034873u, 4172115296u, 4234965207u, 3794477266u, 3874110821u, 3953728444u, 4016571915u, + 3609705398u, 3555108353u, 3735388376u, 3664026991u, 3290680682u, 3236090077u, 3449943556u, 3378572211u, + 3174993278u, 3120533705u, 3032266256u, 2961025959u, 2923101090u, 2868635157u, 2813903052u, 2742672763u, + 2604032198u, 2683796849u, 2461293480u, 2524268063u, 2284983834u, 2364738477u, 2175806836u, 2238787779u, + 1569362073u, 1498123566u, 1409854455u, 1355396672u, 1317987909u, 1246755826u, 1192025387u, 1137557660u, + 2072149281u, 2135122070u, 1912620623u, 1992383480u, 1753615357u, 1816598090u, 1627664531u, 1707420964u, + 295390185u, 358241886u, 404320391u, 483945776u, 43990325u, 106832002u, 186451547u, 266083308u, + 932423249u, 861060070u, 1041341759u, 986742920u, 613929101u, 542559546u, 756411363u, 701822548u, + 3316196985u, 3244833742u, 3425377559u, 3370778784u, 3601682597u, 3530312978u, 3744426955u, 3689838204u, + 3819031489u, 3881883254u, 3928223919u, 4007849240u, 4037393693u, 4100235434u, 4180117107u, 4259748804u, + 2310601993u, 2373574846u, 2151335527u, 2231098320u, 2596047829u, 2659030626u, 2470359227u, 2550115596u, + 2947551409u, 2876312838u, 2788305887u, 2733848168u, 3165939309u, 3094707162u, 3040238851u, 2985771188u, }; -#define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024 - -#define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023 - // ---------------- Private Initializer Prototypes // ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__do_transform_io( - wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__do_transform_io( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_blocks( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__prepare_block( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_uncompressed( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__read_code_lengths( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__init_fixed_huffman( - wuffs_deflate__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__init_dynamic_huffman( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_src); +wuffs_bzip2__decoder__build_huffman_tree( + wuffs_bzip2__decoder* self, + uint32_t a_which); WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__init_huff( - wuffs_deflate__decoder* self, - uint32_t a_which, - uint32_t a_n_codes0, - uint32_t a_n_codes1, - uint32_t a_base_symbol); +static wuffs_base__empty_struct +wuffs_bzip2__decoder__build_huffman_table( + wuffs_bzip2__decoder* self, + uint32_t a_which); -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_bmi2( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) +static wuffs_base__empty_struct +wuffs_bzip2__decoder__invert_bwt( + wuffs_bzip2__decoder* self); WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast32( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src); +static wuffs_base__empty_struct +wuffs_bzip2__decoder__flush_fast( + wuffs_bzip2__decoder* self, + wuffs_base__io_buffer* a_dst); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast64( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src); +wuffs_bzip2__decoder__flush_slow( + wuffs_bzip2__decoder* self, + wuffs_base__io_buffer* a_dst); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__decode_huffman_fast( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_slow( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__decode_huffman_slow( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src); // ---------------- VTables const wuffs_base__io_transformer__func_ptrs -wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = { +wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_bzip2__decoder__dst_history_retain_length), (uint64_t(*)(const void*, - uint32_t))(&wuffs_deflate__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_deflate__decoder__history_retain_length), + uint32_t))(&wuffs_bzip2__decoder__get_quirk), (wuffs_base__status(*)(void*, uint32_t, - uint64_t))(&wuffs_deflate__decoder__set_quirk), + uint64_t))(&wuffs_bzip2__decoder__set_quirk), (wuffs_base__status(*)(void*, wuffs_base__io_buffer*, wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len), + wuffs_base__slice_u8))(&wuffs_bzip2__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bzip2__decoder__workbuf_len), }; // ---------------- Initializer Implementations wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_deflate__decoder__initialize( - wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__initialize( + wuffs_bzip2__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options){ @@ -34263,25 +34215,23 @@ wuffs_deflate__decoder__initialize( } } - self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default; - self->private_impl.magic = WUFFS_BASE__MAGIC; self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = wuffs_base__io_transformer__vtable_name; self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = - (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer); + (const void*)(&wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer); return wuffs_base__make_status(NULL); } -wuffs_deflate__decoder* -wuffs_deflate__decoder__alloc(void) { - wuffs_deflate__decoder* x = - (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1)); +wuffs_bzip2__decoder* +wuffs_bzip2__decoder__alloc(void) { + wuffs_bzip2__decoder* x = + (wuffs_bzip2__decoder*)(calloc(1, sizeof(wuffs_bzip2__decoder))); if (!x) { return NULL; } - if (wuffs_deflate__decoder__initialize( - x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + if (wuffs_bzip2__decoder__initialize( + x, sizeof(wuffs_bzip2__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { free(x); return NULL; } @@ -34289,59 +34239,18 @@ wuffs_deflate__decoder__alloc(void) { } size_t -sizeof__wuffs_deflate__decoder(void) { - return sizeof(wuffs_deflate__decoder); +sizeof__wuffs_bzip2__decoder(void) { + return sizeof(wuffs_bzip2__decoder); } // ---------------- Function Implementations -// -------- func deflate.decoder.add_history - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_deflate__decoder__add_history( - wuffs_deflate__decoder* self, - wuffs_base__slice_u8 a_hist) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); - } - - wuffs_base__slice_u8 v_s = {0}; - uint64_t v_n_copied = 0; - uint32_t v_already_full = 0; - - v_s = a_hist; - if (((uint64_t)(v_s.len)) >= 32768u) { - v_s = wuffs_base__slice_u8__suffix(v_s, 32768u); - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s); - self->private_impl.f_history_index = 32768u; - } else { - v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, (self->private_impl.f_history_index & 32767u), 32768), v_s); - if (v_n_copied < ((uint64_t)(v_s.len))) { - v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied); - v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s); - self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767u))) + 32768u); - } else { - v_already_full = 0u; - if (self->private_impl.f_history_index >= 32768u) { - v_already_full = 32768u; - } - self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767u) + ((uint32_t)((v_n_copied & 32767u))) + v_already_full); - } - } - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, 32768, 33025), wuffs_base__make_slice_u8(self->private_data.f_history, 33025)); - return wuffs_base__make_empty_struct(); -} - -// -------- func deflate.decoder.get_quirk +// -------- func bzip2.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_deflate__decoder__get_quirk( - const wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__get_quirk( + const wuffs_bzip2__decoder* self, uint32_t a_key) { if (!self) { return 0; @@ -34351,15 +34260,18 @@ wuffs_deflate__decoder__get_quirk( return 0; } + if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { + return 1u; + } return 0u; } -// -------- func deflate.decoder.set_quirk +// -------- func bzip2.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_deflate__decoder__set_quirk( - wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__set_quirk( + wuffs_bzip2__decoder* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -34372,32 +34284,36 @@ wuffs_deflate__decoder__set_quirk( : wuffs_base__error__initialize_not_called); } + if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + return wuffs_base__make_status(NULL); + } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func deflate.decoder.history_retain_length +// -------- func bzip2.decoder.dst_history_retain_length WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_deflate__decoder__history_retain_length( - const wuffs_deflate__decoder* self) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_bzip2__decoder__dst_history_retain_length( + const wuffs_bzip2__decoder* self) { if (!self) { - return 0; + return wuffs_base__utility__make_optional_u63(false, 0u); } if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + return wuffs_base__utility__make_optional_u63(false, 0u); } - return 0u; + return wuffs_base__utility__make_optional_u63(true, 0u); } -// -------- func deflate.decoder.workbuf_len +// -------- func bzip2.decoder.workbuf_len WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_deflate__decoder__workbuf_len( - const wuffs_deflate__decoder* self) { +wuffs_bzip2__decoder__workbuf_len( + const wuffs_bzip2__decoder* self) { if (!self) { return wuffs_base__utility__empty_range_ii_u64(); } @@ -34406,15 +34322,15 @@ wuffs_deflate__decoder__workbuf_len( return wuffs_base__utility__empty_range_ii_u64(); } - return wuffs_base__utility__make_range_ii_u64(1u, 1u); + return wuffs_base__utility__make_range_ii_u64(0u, 0u); } -// -------- func deflate.decoder.transform_io +// -------- func bzip2.decoder.transform_io WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_deflate__decoder__transform_io( - wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__transform_io( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf) { @@ -34441,17 +34357,17 @@ wuffs_deflate__decoder__transform_io( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_transform_io[0]; + uint32_t coro_susp_point = self->private_impl.p_transform_io; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_deflate__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + wuffs_base__status t_0 = wuffs_bzip2__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_deflate__error__truncated_input); + status = wuffs_base__make_status(wuffs_bzip2__error__truncated_input); goto exit; } status = v_status; @@ -34459,13 +34375,13 @@ wuffs_deflate__decoder__transform_io( } ok: - self->private_impl.p_transform_io[0] = 0; + self->private_impl.p_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; goto exit; @@ -34476,103 +34392,22 @@ wuffs_deflate__decoder__transform_io( return status; } -// -------- func deflate.decoder.do_transform_io +// -------- func bzip2.decoder.do_transform_io WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__do_transform_io( - wuffs_deflate__decoder* self, +wuffs_bzip2__decoder__do_transform_io( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint64_t v_mark = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } - - uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - self->private_impl.choosy_decode_huffman_fast64 = ( -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 : -#endif - self->private_impl.choosy_decode_huffman_fast64); - while (true) { - v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); - { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src); - v_status = t_0; - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - } - if ( ! wuffs_base__status__is_suspension(&v_status)) { - status = v_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; - } - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)))); - wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } - - ok: - self->private_impl.p_do_transform_io[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - - return status; -} - -// -------- func deflate.decoder.decode_blocks - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_blocks( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_final = 0; - uint32_t v_b0 = 0; - uint32_t v_type = 0; + uint8_t v_c8 = 0; + uint32_t v_i = 0; + uint64_t v_tag = 0; wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_final_checksum_want = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -34585,125 +34420,206 @@ wuffs_deflate__decoder__decode_blocks( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0]; + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; if (coro_susp_point) { - v_final = self->private_data.s_decode_blocks[0].v_final; + v_i = self->private_data.s_do_transform_io.v_i; + v_tag = self->private_data.s_do_transform_io.v_tag; + v_final_checksum_want = self->private_data.s_do_transform_io.v_final_checksum_want; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - label__outer__continue:; - while (v_final == 0u) { - while (self->private_impl.f_n_bits < 3u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 66u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (v_c8 != 90u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (v_c8 != 104u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if ((v_c8 < 49u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_header); + goto exit; + } + self->private_impl.f_max_incl_block_size = (((uint32_t)(((uint8_t)(v_c8 - 48u)))) * 100000u); + while (true) { + v_tag = 0u; + v_i = 0u; + while (v_i < 48u) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; } - uint32_t t_0 = *iop_a_src++; - v_b0 = t_0; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3u)); - self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3u) + 8u); + v_tag <<= 1u; + v_tag |= ((uint64_t)((self->private_impl.f_bits >> 31u))); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; } - v_final = (self->private_impl.f_bits & 1u); - v_type = ((self->private_impl.f_bits >> 1u) & 3u); - self->private_impl.f_bits >>= 3u; - self->private_impl.f_n_bits -= 3u; - if (v_type == 0u) { + if (v_tag == 25779555029136u) { + break; + } else if (v_tag != 54156738319193u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + status = wuffs_bzip2__decoder__prepare_block(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_block_size = 0u; + self->private_impl.f_decode_huffman_finished = false; + self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[0u] & 7u))]; + self->private_impl.f_decode_huffman_ticks = 50u; + self->private_impl.f_decode_huffman_section = 0u; + self->private_impl.f_decode_huffman_run_shift = 0u; + while ( ! self->private_impl.f_decode_huffman_finished) { if (a_src) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src); + v_status = wuffs_bzip2__decoder__decode_huffman_fast(self, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } - if (status.repr) { - goto suspend; - } - continue; - } else if (v_type == 1u) { - v_status = wuffs_deflate__decoder__init_fixed_huffman(self); - if ( ! wuffs_base__status__is_ok(&v_status)) { + if (wuffs_base__status__is_error(&v_status)) { status = v_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; + goto exit; + } else if (self->private_impl.f_decode_huffman_finished) { + break; } - } else if (v_type == 2u) { if (a_src) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + status = wuffs_bzip2__decoder__decode_huffman_slow(self, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } if (status.repr) { goto suspend; } - } else { - status = wuffs_base__make_status(wuffs_deflate__error__bad_block); + } + wuffs_bzip2__decoder__invert_bwt(self); + self->private_impl.f_block_checksum_have = 4294967295u; + if (self->private_impl.f_original_pointer >= self->private_impl.f_block_size) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); goto exit; } - self->private_impl.f_end_of_block = false; - while (true) { - if (sizeof(void*) == 4u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } else { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; - goto exit; - } - if (self->private_impl.f_end_of_block) { - goto label__outer__continue; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + self->private_impl.f_flush_pointer = (self->private_data.f_bwt[self->private_impl.f_original_pointer] >> 12u); + self->private_impl.f_flush_repeat_count = 0u; + self->private_impl.f_flush_prev = 0u; + while (self->private_impl.f_block_size > 0u) { + wuffs_bzip2__decoder__flush_fast(self, a_dst); + if (self->private_impl.f_block_size <= 0u) { + break; } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_bzip2__decoder__flush_slow(self, a_dst); if (status.repr) { goto suspend; } - if (self->private_impl.f_end_of_block) { - goto label__outer__continue; + } + self->private_impl.f_block_checksum_have ^= 4294967295u; + if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_block_checksum_have != self->private_impl.f_block_checksum_want)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum); + goto exit; + } + self->private_impl.f_final_checksum_have = (self->private_impl.f_block_checksum_have ^ ((self->private_impl.f_final_checksum_have >> 31u) | ((uint32_t)(self->private_impl.f_final_checksum_have << 1u)))); + } + v_final_checksum_want = 0u; + v_i = 0u; + while (v_i < 32u) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } + v_final_checksum_want <<= 1u; + v_final_checksum_want |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; + } + if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_final_checksum_have != v_final_checksum_want)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum); + goto exit; } + goto ok; ok: - self->private_impl.p_decode_blocks[0] = 0; + self->private_impl.p_do_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_blocks[0].v_final = v_final; + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_transform_io.v_i = v_i; + self->private_data.s_do_transform_io.v_tag = v_tag; + self->private_data.s_do_transform_io.v_final_checksum_want = v_final_checksum_want; goto exit; exit: @@ -34714,32 +34630,23 @@ wuffs_deflate__decoder__decode_blocks( return status; } -// -------- func deflate.decoder.decode_uncompressed +// -------- func bzip2.decoder.prepare_block WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_uncompressed( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__prepare_block( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_length = 0; - uint32_t v_n_copied = 0; + uint8_t v_c8 = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + uint32_t v_selector = 0; + uint32_t v_sel_ff = 0; + uint8_t v_movee = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -34751,387 +34658,287 @@ wuffs_deflate__decoder__decode_uncompressed( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0]; + uint32_t coro_susp_point = self->private_impl.p_prepare_block; if (coro_susp_point) { - v_length = self->private_data.s_decode_uncompressed[0].v_length; + v_i = self->private_data.s_prepare_block.v_i; + v_selector = self->private_data.s_prepare_block.v_selector; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } - self->private_impl.f_n_bits = 0u; - self->private_impl.f_bits = 0u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_uncompressed[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { + self->private_impl.f_block_checksum_want = 0u; + v_i = 0u; + while (v_i < 32u) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - v_length = t_0; - } - if ((((v_length) & 0xFFFFu) + ((v_length) >> (32u - 16u))) != 65535u) { - status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length); - goto exit; - } - v_length = ((v_length) & 0xFFFFu); - while (true) { - v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader( - &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src); - if (v_length <= v_n_copied) { - status = wuffs_base__make_status(NULL); - goto ok; - } - v_length -= v_n_copied; - if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - } else { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - } + self->private_impl.f_block_checksum_want <<= 1u; + self->private_impl.f_block_checksum_want |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; } - - ok: - self->private_impl.p_decode_uncompressed[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_uncompressed[0].v_length = v_length; - - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func deflate.decoder.init_fixed_huffman - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__init_fixed_huffman( - wuffs_deflate__decoder* self) { - uint32_t v_i = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - while (v_i < 144u) { - self->private_data.f_code_lengths[v_i] = 8u; - v_i += 1u; - } - while (v_i < 256u) { - self->private_data.f_code_lengths[v_i] = 9u; - v_i += 1u; - } - while (v_i < 280u) { - self->private_data.f_code_lengths[v_i] = 7u; - v_i += 1u; - } - while (v_i < 288u) { - self->private_data.f_code_lengths[v_i] = 8u; - v_i += 1u; - } - while (v_i < 320u) { - self->private_data.f_code_lengths[v_i] = 5u; - v_i += 1u; - } - v_status = wuffs_deflate__decoder__init_huff(self, - 0u, - 0u, - 288u, - 257u); - if (wuffs_base__status__is_error(&v_status)) { - return v_status; - } - v_status = wuffs_deflate__decoder__init_huff(self, - 1u, - 288u, - 320u, - 0u); - if (wuffs_base__status__is_error(&v_status)) { - return v_status; - } - return wuffs_base__make_status(NULL); -} - -// -------- func deflate.decoder.init_dynamic_huffman - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__init_dynamic_huffman( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_b0 = 0; - uint32_t v_n_lit = 0; - uint32_t v_n_dist = 0; - uint32_t v_n_clen = 0; - uint32_t v_i = 0; - uint32_t v_b1 = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t v_mask = 0; - uint32_t v_table_entry = 0; - uint32_t v_table_entry_n_bits = 0; - uint32_t v_b2 = 0; - uint32_t v_n_extra_bits = 0; - uint8_t v_rep_symbol = 0; - uint32_t v_rep_count = 0; - uint32_t v_b3 = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0]; - if (coro_susp_point) { - v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits; - v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits; - v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit; - v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist; - v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen; - v_i = self->private_data.s_init_dynamic_huffman[0].v_i; - v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask; - v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits; - v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol; - v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - v_bits = self->private_impl.f_bits; - v_n_bits = self->private_impl.f_n_bits; - while (v_n_bits < 14u) { + if (self->private_impl.f_n_bits <= 0u) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_0 = *iop_a_src++; - v_b0 = t_0; + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; } - v_bits |= (v_b0 << v_n_bits); - v_n_bits += 8u; - } - v_n_lit = (((v_bits) & 0x1Fu) + 257u); - if (v_n_lit > 286u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count); - goto exit; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - v_bits >>= 5u; - v_n_dist = (((v_bits) & 0x1Fu) + 1u); - if (v_n_dist > 30u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count); + if ((self->private_impl.f_bits >> 31u) != 0u) { + status = wuffs_base__make_status(wuffs_bzip2__error__unsupported_block_randomization); goto exit; } - v_bits >>= 5u; - v_n_clen = (((v_bits) & 0xFu) + 4u); - v_bits >>= 4u; - v_n_bits -= 14u; + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + self->private_impl.f_original_pointer = 0u; v_i = 0u; - while (v_i < v_n_clen) { - while (v_n_bits < 3u) { + while (v_i < 24u) { + if (self->private_impl.f_n_bits <= 0u) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_1 = *iop_a_src++; - v_b1 = t_1; + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; } - v_bits |= (v_b1 << v_n_bits); - v_n_bits += 8u; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7u))); - v_bits >>= 3u; - v_n_bits -= 3u; + self->private_impl.f_original_pointer <<= 1u; + self->private_impl.f_original_pointer |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; v_i += 1u; } - while (v_i < 19u) { - self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0u; + v_i = 0u; + while (v_i < 256u) { + self->private_data.f_presence[v_i] = 0u; v_i += 1u; } - v_status = wuffs_deflate__decoder__init_huff(self, - 0u, - 0u, - 19u, - 4095u); - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; - goto exit; - } - v_mask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); v_i = 0u; - while (v_i < (v_n_lit + v_n_dist)) { - while (true) { - v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_mask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - if (v_n_bits >= v_table_entry_n_bits) { - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - break; - } + while (v_i < 256u) { + if (self->private_impl.f_n_bits <= 0u) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_2 = *iop_a_src++; - v_b2 = t_2; + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; } - v_bits |= (v_b2 << v_n_bits); - v_n_bits += 8u; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - if ((v_table_entry >> 24u) != 128u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; + if ((self->private_impl.f_bits >> 31u) != 0u) { + self->private_data.f_presence[v_i] = 1u; } - v_table_entry = ((v_table_entry >> 8u) & 255u); - if (v_table_entry < 16u) { - self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry)); - v_i += 1u; + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 16u; + } + self->private_data.f_scratch = 0u; + v_i = 0u; + while (v_i < 256u) { + if (self->private_data.f_presence[v_i] == 0u) { + v_i += 16u; continue; } - v_n_extra_bits = 0u; - v_rep_symbol = 0u; - v_rep_count = 0u; - if (v_table_entry == 16u) { - v_n_extra_bits = 2u; - if (v_i <= 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition); - goto exit; + while (true) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; + } + self->private_data.f_scratch += (self->private_impl.f_bits >> 31u); + self->private_data.f_presence[(v_i & 255u)] = ((uint8_t)((self->private_impl.f_bits >> 31u))); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; + if ((v_i & 15u) == 0u) { + break; } - v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1u)] & 15u); - v_rep_count = 3u; - } else if (v_table_entry == 17u) { - v_n_extra_bits = 3u; - v_rep_symbol = 0u; - v_rep_count = 3u; - } else if (v_table_entry == 18u) { - v_n_extra_bits = 7u; - v_rep_symbol = 0u; - v_rep_count = 11u; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; } - while (v_n_bits < v_n_extra_bits) { + } + if ((self->private_data.f_scratch < 1u) || (256u < self->private_data.f_scratch)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); + goto exit; + } + self->private_impl.f_num_symbols = (self->private_data.f_scratch + 2u); + self->private_data.f_scratch = 0u; + v_i = 0u; + while (v_i < 3u) { + if (self->private_impl.f_n_bits <= 0u) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_3 = *iop_a_src++; - v_b3 = t_3; + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; } - v_bits |= (v_b3 << v_n_bits); - v_n_bits += 8u; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits)); - v_bits >>= v_n_extra_bits; - v_n_bits -= v_n_extra_bits; - while (v_rep_count > 0u) { - if (v_i >= (v_n_lit + v_n_dist)) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count); - goto exit; + self->private_data.f_scratch <<= 1u; + self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; + } + if ((self->private_data.f_scratch < 2u) || (6u < self->private_data.f_scratch)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); + goto exit; + } + self->private_impl.f_num_huffman_codes = self->private_data.f_scratch; + self->private_data.f_scratch = 0u; + v_i = 0u; + while (v_i < 15u) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; } - self->private_data.f_code_lengths[v_i] = v_rep_symbol; - v_i += 1u; - v_rep_count -= 1u; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } + self->private_data.f_scratch <<= 1u; + self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; } - if (v_i != (v_n_lit + v_n_dist)) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count); + if ((self->private_data.f_scratch < 1u) || (18001u < self->private_data.f_scratch)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); goto exit; } - if (self->private_data.f_code_lengths[256u] == 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code); - goto exit; + self->private_impl.f_num_sections = self->private_data.f_scratch; + v_i = 0u; + while (v_i < self->private_impl.f_num_huffman_codes) { + self->private_data.f_mtft[v_i] = ((uint8_t)(v_i)); + v_i += 1u; } - v_status = wuffs_deflate__decoder__init_huff(self, - 0u, - 0u, - v_n_lit, - 257u); - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; - goto exit; + v_i = 0u; + while (v_i < self->private_impl.f_num_sections) { + v_selector = 0u; + while (true) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_7 = *iop_a_src++; + v_c8 = t_7; + } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; + } + if ((self->private_impl.f_bits >> 31u) == 0u) { + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + break; + } + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_selector += 1u; + if (v_selector >= self->private_impl.f_num_huffman_codes) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); + goto exit; + } + } + if (v_selector == 0u) { + self->private_data.f_huffman_selectors[v_i] = self->private_data.f_mtft[0u]; + } else { + v_sel_ff = (v_selector & 255u); + v_movee = self->private_data.f_mtft[v_sel_ff]; + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_sel_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_sel_ff)); + self->private_data.f_mtft[0u] = v_movee; + self->private_data.f_huffman_selectors[v_i] = v_movee; + } + v_i += 1u; } - v_status = wuffs_deflate__decoder__init_huff(self, - 1u, - v_n_lit, - (v_n_lit + v_n_dist), - 0u); - if (wuffs_base__status__is_error(&v_status)) { - status = v_status; - goto exit; + v_i = 0u; + while (v_i < self->private_impl.f_num_huffman_codes) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_bzip2__decoder__read_code_lengths(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + v_status = wuffs_bzip2__decoder__build_huffman_tree(self, v_i); + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; + } + wuffs_bzip2__decoder__build_huffman_table(self, v_i); + v_i += 1u; + } + v_i = 0u; + v_j = 0u; + while (v_i < 256u) { + if (self->private_data.f_presence[v_i] != 0u) { + self->private_data.f_mtft[(v_j & 255u)] = ((uint8_t)(v_i)); + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 256u) { + self->private_data.f_letter_counts[v_i] = 0u; + v_i += 1u; } - self->private_impl.f_bits = v_bits; - self->private_impl.f_n_bits = v_n_bits; goto ok; ok: - self->private_impl.p_init_dynamic_huffman[0] = 0; + self->private_impl.p_prepare_block = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits; - self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits; - self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit; - self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist; - self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen; - self->private_data.s_init_dynamic_huffman[0].v_i = v_i; - self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask; - self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits; - self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol; - self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count; + self->private_impl.p_prepare_block = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_prepare_block.v_i = v_i; + self->private_data.s_prepare_block.v_selector = v_selector; goto exit; exit: @@ -35142,285 +34949,295 @@ wuffs_deflate__decoder__init_dynamic_huffman( return status; } -// -------- func deflate.decoder.init_huff +// -------- func bzip2.decoder.read_code_lengths WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__init_huff( - wuffs_deflate__decoder* self, - uint32_t a_which, - uint32_t a_n_codes0, - uint32_t a_n_codes1, - uint32_t a_base_symbol) { - uint16_t v_counts[16] = {0}; +wuffs_bzip2__decoder__read_code_lengths( + wuffs_bzip2__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; uint32_t v_i = 0; - uint32_t v_remaining = 0; - uint16_t v_offsets[16] = {0}; - uint32_t v_n_symbols = 0; - uint32_t v_count = 0; - uint16_t v_symbols[320] = {0}; - uint32_t v_min_cl = 0; - uint32_t v_max_cl = 0; - uint32_t v_initial_high_bits = 0; - uint32_t v_prev_cl = 0; - uint32_t v_prev_redirect_key = 0; - uint32_t v_top = 0; - uint32_t v_next_top = 0; - uint32_t v_code = 0; - uint32_t v_key = 0; - uint32_t v_value = 0; - uint32_t v_cl = 0; - uint32_t v_redirect_key = 0; - uint32_t v_j = 0; - uint32_t v_reversed_key = 0; - uint32_t v_symbol = 0; - uint32_t v_high_bits = 0; - uint32_t v_delta = 0; + uint32_t v_code_length = 0; - v_i = a_n_codes0; - while (v_i < a_n_codes1) { - if (v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - v_i += 1u; - } - if ((((uint32_t)(v_counts[0u])) + a_n_codes0) == a_n_codes1) { - return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - v_remaining = 1u; - v_i = 1u; - while (v_i <= 15u) { - if (v_remaining > 1073741824u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - v_remaining <<= 1u; - if (v_remaining < ((uint32_t)(v_counts[v_i]))) { - return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed); - } - v_remaining -= ((uint32_t)(v_counts[v_i])); - v_i += 1u; + + uint32_t coro_susp_point = self->private_impl.p_read_code_lengths; + if (coro_susp_point) { + v_i = self->private_data.s_read_code_lengths.v_i; + v_code_length = self->private_data.s_read_code_lengths.v_code_length; } - if (v_remaining != 0u) { - if ((a_which == 1u) && (v_counts[1u] == 1u) && ((((uint32_t)(v_counts[0u])) + a_n_codes0 + 1u) == a_n_codes1)) { - v_i = 0u; - while (v_i <= 29u) { - if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1u) { - self->private_impl.f_n_huffs_bits[1u] = 1u; - self->private_data.f_huffs[1u][0u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1u); - self->private_data.f_huffs[1u][1u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31u] | 1u); - return wuffs_base__make_status(NULL); + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_code_lengths_bitmask = 0u; + v_i = 0u; + while (v_i < 5u) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - v_i += 1u; + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } + v_code_length <<= 1u; + v_code_length |= (self->private_impl.f_bits >> 31u); + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + v_i += 1u; } - return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed); - } - v_i = 1u; - while (v_i <= 15u) { - v_offsets[v_i] = ((uint16_t)(v_n_symbols)); - v_count = ((uint32_t)(v_counts[v_i])); - if (v_n_symbols > (320u - v_count)) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - v_n_symbols = (v_n_symbols + v_count); - v_i += 1u; - } - if (v_n_symbols > 288u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - v_i = a_n_codes0; - while (v_i < a_n_codes1) { - if (v_i < a_n_codes0) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - if (self->private_data.f_code_lengths[v_i] != 0u) { - if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + v_i = 0u; + while (v_i < self->private_impl.f_num_symbols) { + while (true) { + if ((v_code_length < 1u) || (20u < v_code_length)) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header); + goto exit; + } + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; + } + if ((self->private_impl.f_bits >> 31u) == 0u) { + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + break; + } + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; + } + if ((self->private_impl.f_bits >> 31u) == 0u) { + v_code_length += 1u; + } else { + v_code_length -= 1u; + } + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; } - v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)]] = ((uint16_t)((v_i - a_n_codes0))); -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } - v_i += 1u; - } - v_min_cl = 1u; - while (true) { - if (v_counts[v_min_cl] != 0u) { - break; - } - if (v_min_cl >= 9u) { - return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length); - } - v_min_cl += 1u; - } - v_max_cl = 15u; - while (true) { - if (v_counts[v_max_cl] != 0u) { - break; - } - if (v_max_cl <= 1u) { - return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes); + self->private_impl.f_code_lengths_bitmask |= (((uint32_t)(1u)) << (v_code_length & 31u)); + self->private_data.f_bwt[v_i] = v_code_length; + v_i += 1u; } - v_max_cl -= 1u; - } - if (v_max_cl <= 9u) { - self->private_impl.f_n_huffs_bits[a_which] = v_max_cl; - } else { - self->private_impl.f_n_huffs_bits[a_which] = 9u; - } - v_i = 0u; - if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15u])))) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - if ((a_n_codes0 + ((uint32_t)(v_symbols[0u]))) >= 320u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + + goto ok; + ok: + self->private_impl.p_read_code_lengths = 0; + goto exit; } - v_initial_high_bits = 512u; - if (v_max_cl < 9u) { - v_initial_high_bits = (((uint32_t)(1u)) << v_max_cl); + + goto suspend; + suspend: + self->private_impl.p_read_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_read_code_lengths.v_i = v_i; + self->private_data.s_read_code_lengths.v_code_length = v_code_length; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0u])))] & 15u))); - v_prev_redirect_key = 4294967295u; - v_top = 0u; - v_next_top = 512u; - v_code = 0u; - v_key = 0u; - v_value = 0u; - while (true) { - if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + + return status; +} + +// -------- func bzip2.decoder.build_huffman_tree + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bzip2__decoder__build_huffman_tree( + wuffs_bzip2__decoder* self, + uint32_t a_which) { + uint32_t v_code_length = 0; + uint32_t v_symbol_index = 0; + uint32_t v_num_branch_nodes = 0; + uint32_t v_stack_height = 0; + uint32_t v_stack_values[21] = {0}; + uint32_t v_node_index = 0; + uint16_t v_leaf_value = 0; + + self->private_data.f_huffman_trees[a_which][0u][0u] = 0u; + self->private_data.f_huffman_trees[a_which][0u][1u] = 0u; + v_num_branch_nodes = 1u; + v_stack_height = 1u; + v_stack_values[0u] = 0u; + v_code_length = 1u; + while (v_code_length <= 20u) { + if ((self->private_impl.f_code_lengths_bitmask & (((uint32_t)(1u)) << v_code_length)) == 0u) { + v_code_length += 1u; + continue; } - v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15u))); - if (v_cl > v_prev_cl) { - v_code <<= (v_cl - v_prev_cl); - if (v_code >= 32768u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + v_symbol_index = 0u; + while (v_symbol_index < self->private_impl.f_num_symbols) { + if (self->private_data.f_bwt[v_symbol_index] != v_code_length) { + v_symbol_index += 1u; + continue; } - } - v_prev_cl = v_cl; - v_key = v_code; - if (v_cl > 9u) { - v_cl -= 9u; - v_redirect_key = ((v_key >> v_cl) & 511u); - v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl)); - if (v_prev_redirect_key != v_redirect_key) { - v_prev_redirect_key = v_redirect_key; - v_remaining = (((uint32_t)(1u)) << v_cl); - v_j = v_prev_cl; - while (v_j <= 15u) { - if (v_remaining <= ((uint32_t)(v_counts[v_j]))) { - break; - } - v_remaining -= ((uint32_t)(v_counts[v_j])); - if (v_remaining > 1073741824u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - v_remaining <<= 1u; - v_j += 1u; + while (true) { + if (v_stack_height <= 0u) { + return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_over_subscribed); + } else if (v_stack_height >= v_code_length) { + break; } - if ((v_j <= 9u) || (15u < v_j)) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + v_node_index = v_stack_values[(v_stack_height - 1u)]; + if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) { + self->private_data.f_huffman_trees[a_which][v_node_index][0u] = ((uint16_t)(v_num_branch_nodes)); + } else { + self->private_data.f_huffman_trees[a_which][v_node_index][1u] = ((uint16_t)(v_num_branch_nodes)); } - v_j -= 9u; - v_initial_high_bits = (((uint32_t)(1u)) << v_j); - v_top = v_next_top; - if ((v_top + (((uint32_t)(1u)) << v_j)) > 1024u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + if (v_num_branch_nodes >= 257u) { + return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed); } - v_next_top = (v_top + (((uint32_t)(1u)) << v_j)); - v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1u)])) | ((v_redirect_key & 1u) << 8u)); - self->private_data.f_huffs[a_which][v_redirect_key] = (268435465u | (v_top << 8u) | (v_j << 4u)); + v_stack_values[v_stack_height] = v_num_branch_nodes; + self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][0u] = 0u; + self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][1u] = 0u; + v_num_branch_nodes += 1u; + v_stack_height += 1u; } + v_node_index = v_stack_values[(v_stack_height - 1u)]; + if (v_symbol_index < 2u) { + v_leaf_value = ((uint16_t)((769u + v_symbol_index))); + } else if ((v_symbol_index + 1u) < self->private_impl.f_num_symbols) { + v_leaf_value = ((uint16_t)((511u + v_symbol_index))); + } else { + v_leaf_value = 768u; + } + if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) { + self->private_data.f_huffman_trees[a_which][v_node_index][0u] = v_leaf_value; + } else { + self->private_data.f_huffman_trees[a_which][v_node_index][1u] = v_leaf_value; + v_stack_height -= 1u; + while (v_stack_height > 0u) { + v_node_index = v_stack_values[(v_stack_height - 1u)]; + if (self->private_data.f_huffman_trees[a_which][v_node_index][1u] == 0u) { + break; + } + v_stack_height -= 1u; + } + } + v_symbol_index += 1u; } - if ((v_key >= 512u) || (v_counts[v_prev_cl] <= 0u)) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } + v_code_length += 1u; + } + if (v_stack_height != 0u) { + return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed); + } + return wuffs_base__make_status(NULL); +} + +// -------- func bzip2.decoder.build_huffman_table + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_bzip2__decoder__build_huffman_table( + wuffs_bzip2__decoder* self, + uint32_t a_which) { + uint32_t v_i = 0; + uint32_t v_bits = 0; + uint16_t v_n_bits = 0; + uint16_t v_child = 0; + + while (v_i < 256u) { + v_bits = (v_i << 24u); + v_n_bits = 0u; + v_child = 0u; + while ((v_child < 257u) && (v_n_bits < 8u)) { + v_child = self->private_data.f_huffman_trees[a_which][v_child][(v_bits >> 31u)]; + v_bits <<= 1u; #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif - v_counts[v_prev_cl] -= 1u; + v_n_bits += 1u; #if defined(__GNUC__) #pragma GCC diagnostic pop #endif - v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1u)])) | ((v_key & 1u) << 8u)); - v_reversed_key >>= (9u - v_cl); - v_symbol = ((uint32_t)(v_symbols[v_i])); - if (v_symbol == 256u) { - v_value = (536870912u | v_cl); - } else if ((v_symbol < 256u) && (a_which == 0u)) { - v_value = (2147483648u | (v_symbol << 8u) | v_cl); - } else if (v_symbol >= a_base_symbol) { - v_symbol -= a_base_symbol; - if (a_which == 0u) { - v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl); - } else { - v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl); - } - } else { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - v_high_bits = v_initial_high_bits; - v_delta = (((uint32_t)(1u)) << v_cl); - while (v_high_bits >= v_delta) { - v_high_bits -= v_delta; - if ((v_top + ((v_high_bits | v_reversed_key) & 511u)) >= 1024u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } - self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511u))] = v_value; } + self->private_data.f_huffman_tables[a_which][v_i] = ((uint16_t)(((uint16_t)(v_child | ((uint16_t)(v_n_bits << 12u)))))); v_i += 1u; - if (v_i >= v_n_symbols) { - break; - } - v_code += 1u; - if (v_code >= 32768u) { - return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - } } - return wuffs_base__make_status(NULL); + return wuffs_base__make_empty_struct(); } -// ‼ WUFFS MULTI-FILE SECTION +x86_bmi2 -// -------- func deflate.decoder.decode_huffman_bmi2 +// -------- func bzip2.decoder.invert_bwt -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_bmi2( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +static wuffs_base__empty_struct +wuffs_bzip2__decoder__invert_bwt( + wuffs_bzip2__decoder* self) { + uint32_t v_i = 0; + uint32_t v_letter = 0; + uint32_t v_sum = 0; + uint32_t v_old_sum = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_table_entry = 0; - uint32_t v_table_entry_n_bits = 0; - uint64_t v_lmask = 0; - uint64_t v_dmask = 0; - uint32_t v_redir_top = 0; - uint32_t v_redir_mask = 0; - uint32_t v_length = 0; - uint32_t v_dist_minus_1 = 0; - uint32_t v_hlen = 0; - uint32_t v_hdist = 0; - uint32_t v_hdist_adjustment = 0; + v_sum = 0u; + v_i = 0u; + while (v_i < 256u) { + v_old_sum = v_sum; + v_sum += self->private_data.f_letter_counts[v_i]; + self->private_data.f_letter_counts[v_i] = v_old_sum; + v_i += 1u; + } + v_i = 0u; + while (v_i < self->private_impl.f_block_size) { + v_letter = (self->private_data.f_bwt[v_i] & 255u); + self->private_data.f_bwt[(self->private_data.f_letter_counts[v_letter] & 1048575u)] |= (v_i << 12u); + self->private_data.f_letter_counts[v_letter] += 1u; + v_i += 1u; + } + return wuffs_base__make_empty_struct(); +} + +// -------- func bzip2.decoder.flush_fast + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_bzip2__decoder__flush_fast( + wuffs_bzip2__decoder* self, + wuffs_base__io_buffer* a_dst) { + uint32_t v_flush_pointer = 0; + uint32_t v_flush_repeat_count = 0; + uint8_t v_flush_prev = 0; + uint32_t v_block_checksum_have = 0; + uint32_t v_block_size = 0; + uint32_t v_entry = 0; + uint8_t v_curr = 0; uint8_t* iop_a_dst = NULL; uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -35435,217 +35252,204 @@ wuffs_deflate__decoder__decode_huffman_bmi2( io2_a_dst = iop_a_dst; } } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } - v_bits = ((uint64_t)(self->private_impl.f_bits)); - v_n_bits = self->private_impl.f_n_bits; - v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); - v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); - if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { - status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); - goto exit; + v_flush_pointer = self->private_impl.f_flush_pointer; + v_flush_repeat_count = self->private_impl.f_flush_repeat_count; + v_flush_prev = self->private_impl.f_flush_prev; + v_block_checksum_have = self->private_impl.f_block_checksum_have; + v_block_size = self->private_impl.f_block_size; + while ((v_block_size > 0u) && (((uint64_t)(io2_a_dst - iop_a_dst)) >= 255u)) { + if (v_flush_repeat_count < 4u) { + v_entry = self->private_data.f_bwt[v_flush_pointer]; + v_curr = ((uint8_t)(v_entry)); + v_flush_pointer = (v_entry >> 12u); + if (v_curr == v_flush_prev) { + v_flush_repeat_count += 1u; + } else { + v_flush_repeat_count = 1u; + } + v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr))] ^ ((uint32_t)(v_block_checksum_have << 8u))); + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_curr), iop_a_dst += 1); + v_flush_prev = v_curr; + v_block_size -= 1u; + } else { + v_entry = self->private_data.f_bwt[v_flush_pointer]; + v_curr = ((uint8_t)(v_entry)); + v_flush_pointer = (v_entry >> 12u); + v_flush_repeat_count = ((uint32_t)(v_curr)); + while (v_flush_repeat_count > 0u) { + v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev))] ^ ((uint32_t)(v_block_checksum_have << 8u))); + if (((uint64_t)(io2_a_dst - iop_a_dst)) > 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_flush_prev), iop_a_dst += 1); + } + v_flush_repeat_count -= 1u; + } + v_flush_repeat_count = 0u; + v_flush_prev = v_curr; + v_block_size -= 1u; + } } - v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); - label__loop__continue:; - while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) { - v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u))); - iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - v_length = (((v_table_entry >> 8u) & 255u) + 3u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_table_entry_n_bits > 0u) { - v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 28u) == 1u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - if ((v_table_entry >> 24u) != 64u) { - if ((v_table_entry >> 24u) == 8u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; + self->private_impl.f_flush_pointer = v_flush_pointer; + self->private_impl.f_flush_repeat_count = v_flush_repeat_count; + self->private_impl.f_flush_prev = v_flush_prev; + self->private_impl.f_block_checksum_have = v_block_checksum_have; + if (v_block_size <= 900000u) { + self->private_impl.f_block_size = v_block_size; + } + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + + return wuffs_base__make_empty_struct(); +} + +// -------- func bzip2.decoder.flush_slow + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_bzip2__decoder__flush_slow( + wuffs_bzip2__decoder* self, + wuffs_base__io_buffer* a_dst) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_flush_pointer = 0; + uint32_t v_flush_repeat_count = 0; + uint8_t v_flush_prev = 0; + uint32_t v_block_checksum_have = 0; + uint32_t v_block_size = 0; + uint32_t v_entry = 0; + uint8_t v_curr = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; } - v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - do { - if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { - v_hlen = 0u; - v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); - if (v_length > v_hdist) { - v_length -= v_hdist; - v_hlen = v_hdist; + } + + uint32_t coro_susp_point = self->private_impl.p_flush_slow; + if (coro_susp_point) { + v_flush_pointer = self->private_data.s_flush_slow.v_flush_pointer; + v_flush_repeat_count = self->private_data.s_flush_slow.v_flush_repeat_count; + v_flush_prev = self->private_data.s_flush_slow.v_flush_prev; + v_block_checksum_have = self->private_data.s_flush_slow.v_block_checksum_have; + v_block_size = self->private_data.s_flush_slow.v_block_size; + v_curr = self->private_data.s_flush_slow.v_curr; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + v_flush_pointer = self->private_impl.f_flush_pointer; + v_flush_repeat_count = self->private_impl.f_flush_repeat_count; + v_flush_prev = self->private_impl.f_flush_prev; + v_block_checksum_have = self->private_impl.f_block_checksum_have; + v_block_size = self->private_impl.f_block_size; + while ((v_block_size > 0u) && ! (self->private_impl.p_flush_slow != 0)) { + if (v_flush_repeat_count < 4u) { + v_entry = self->private_data.f_bwt[v_flush_pointer]; + v_curr = ((uint8_t)(v_entry)); + v_flush_pointer = (v_entry >> 12u); + if (v_curr == v_flush_prev) { + v_flush_repeat_count += 1u; } else { - v_hlen = v_length; - v_length = 0u; - } - v_hdist += v_hdist_adjustment; - if (self->private_impl.f_history_index < v_hdist) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); - goto exit; - } - wuffs_base__io_writer__limited_copy_u32_from_slice( - &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); - if (v_length == 0u) { - goto label__loop__continue; + v_flush_repeat_count = 1u; } - if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); - goto exit; + v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr))] ^ ((uint32_t)(v_block_checksum_have << 8u))); + self->private_data.s_flush_slow.scratch = v_curr; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (iop_a_dst == io2_a_dst) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + goto suspend; } - } - if ((v_dist_minus_1 + 1u) >= 8u) { - wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } else if ((v_dist_minus_1 + 1u) == 1u) { - wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow.scratch)); + v_flush_prev = v_curr; + v_block_size -= 1u; } else { - wuffs_base__io_writer__limited_copy_u32_from_history_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + v_entry = self->private_data.f_bwt[v_flush_pointer]; + v_curr = ((uint8_t)(v_entry)); + v_flush_pointer = (v_entry >> 12u); + v_flush_repeat_count = ((uint32_t)(v_curr)); + while (v_flush_repeat_count > 0u) { + v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[((uint8_t)(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev))] ^ ((uint32_t)(v_block_checksum_have << 8u))); + self->private_data.s_flush_slow.scratch = v_flush_prev; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (iop_a_dst == io2_a_dst) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + goto suspend; + } + *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow.scratch)); + v_flush_repeat_count -= 1u; + } + v_flush_repeat_count = 0u; + v_flush_prev = v_curr; + v_block_size -= 1u; } - } while (0); - } - if (v_n_bits > 63u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } - while (v_n_bits >= 8u) { - v_n_bits -= 8u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); - goto exit; } - } - self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u)))); - self->private_impl.f_n_bits = v_n_bits; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + self->private_impl.f_flush_pointer = v_flush_pointer; + self->private_impl.f_flush_repeat_count = v_flush_repeat_count; + self->private_impl.f_flush_prev = v_flush_prev; + self->private_impl.f_block_checksum_have = v_block_checksum_have; + if (v_block_size <= 900000u) { + self->private_impl.f_block_size = v_block_size; + } + + goto ok; + ok: + self->private_impl.p_flush_slow = 0; goto exit; } + + goto suspend; + suspend: + self->private_impl.p_flush_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_flush_slow.v_flush_pointer = v_flush_pointer; + self->private_data.s_flush_slow.v_flush_repeat_count = v_flush_repeat_count; + self->private_data.s_flush_slow.v_flush_prev = v_flush_prev; + self->private_data.s_flush_slow.v_block_checksum_have = v_block_checksum_have; + self->private_data.s_flush_slow.v_block_size = v_block_size; + self->private_data.s_flush_slow.v_curr = v_curr; + goto exit; exit: if (a_dst && a_dst->data.ptr) { a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } return status; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_bmi2 -// -------- func deflate.decoder.decode_huffman_fast32 +// -------- func bzip2.decoder.decode_huffman_fast WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast32( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__decode_huffman_fast( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); uint32_t v_bits = 0; uint32_t v_n_bits = 0; - uint32_t v_table_entry = 0; - uint32_t v_table_entry_n_bits = 0; - uint32_t v_lmask = 0; - uint32_t v_dmask = 0; - uint32_t v_redir_top = 0; - uint32_t v_redir_mask = 0; - uint32_t v_length = 0; - uint32_t v_dist_minus_1 = 0; - uint32_t v_hlen = 0; - uint32_t v_hdist = 0; - uint32_t v_hdist_adjustment = 0; + uint32_t v_block_size = 0; + uint8_t v_which = 0; + uint32_t v_ticks = 0; + uint32_t v_section = 0; + uint32_t v_run_shift = 0; + uint16_t v_table_entry = 0; + uint16_t v_child = 0; + uint32_t v_child_ff = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + uint32_t v_output = 0; + uint32_t v_run = 0; + uint32_t v_mtft0 = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -35657,205 +35461,92 @@ wuffs_deflate__decoder__decode_huffman_fast32( io2_a_src = io0_a_src + a_src->meta.wi; } - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } v_bits = self->private_impl.f_bits; v_n_bits = self->private_impl.f_n_bits; - v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); - v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); - if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { - status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); - goto exit; - } - v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); - label__loop__continue:; - while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12u)) { - if (v_n_bits < 15u) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; + v_block_size = self->private_impl.f_block_size; + v_which = self->private_impl.f_decode_huffman_which; + v_ticks = self->private_impl.f_decode_huffman_ticks; + v_section = self->private_impl.f_decode_huffman_section; + v_run_shift = self->private_impl.f_decode_huffman_run_shift; + while (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { + if (v_ticks > 0u) { + v_ticks -= 1u; } else { - } - v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - if (v_n_bits < 15u) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - } else { - } - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + v_ticks = 49u; + v_section += 1u; + if (v_section >= self->private_impl.f_num_sections) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections); goto exit; } - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - v_length = (((v_table_entry >> 8u) & 255u) + 3u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_table_entry_n_bits > 0u) { - if (v_n_bits < 15u) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - } else { - } - v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } else { - } - if (v_n_bits < 15u) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - } else { + v_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[(v_section & 32767u)] & 7u))]; } - v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 28u) == 1u) { - if (v_n_bits < 15u) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - } else { + v_bits |= (wuffs_base__peek_u32be__no_bounds_check(iop_a_src) >> v_n_bits); + iop_a_src += ((31u - v_n_bits) >> 3u); + v_n_bits |= 24u; + v_table_entry = self->private_data.f_huffman_tables[v_which][(v_bits >> 24u)]; + v_bits <<= ((uint16_t)(v_table_entry >> 12u)); + v_n_bits -= ((uint32_t)(((uint16_t)(v_table_entry >> 12u)))); + v_child = ((uint16_t)(v_table_entry & 1023u)); + while (v_child < 257u) { + v_child = self->private_data.f_huffman_trees[v_which][v_child][(v_bits >> 31u)]; + v_bits <<= 1u; + if (v_n_bits <= 0u) { + status = wuffs_base__make_status(wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } else { + v_n_bits -= 1u; } - if ((v_table_entry >> 24u) != 64u) { - if ((v_table_entry >> 24u) == 8u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + if (v_child < 768u) { + v_child_ff = ((uint32_t)(((uint16_t)(v_child & 255u)))); + v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff])); + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff)); + self->private_data.f_mtft[0u] = ((uint8_t)(v_output)); + self->private_data.f_letter_counts[v_output] += 1u; + self->private_data.f_bwt[v_block_size] = v_output; + if (v_block_size >= self->private_impl.f_max_incl_block_size) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); goto exit; } - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; + v_block_size += 1u; + v_run_shift = 0u; + continue; + } else if (v_child == 768u) { + self->private_impl.f_decode_huffman_finished = true; + break; } - v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_n_bits < v_table_entry_n_bits) { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; + if (v_run_shift >= 23u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); + goto exit; } - v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - do { - if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { - v_hlen = 0u; - v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); - if (v_length > v_hdist) { - v_length -= v_hdist; - v_hlen = v_hdist; - } else { - v_hlen = v_length; - v_length = 0u; - } - v_hdist += v_hdist_adjustment; - if (self->private_impl.f_history_index < v_hdist) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); - goto exit; - } - wuffs_base__io_writer__limited_copy_u32_from_slice( - &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); - if (v_length == 0u) { - goto label__loop__continue; - } - if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); - goto exit; - } - } - if ((v_dist_minus_1 + 1u) >= 8u) { - wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } else { - wuffs_base__io_writer__limited_copy_u32_from_history_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } - } while (0); - } - while (v_n_bits >= 8u) { - v_n_bits -= 8u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); + v_run = ((((uint32_t)(v_child)) & 3u) << v_run_shift); + v_run_shift += 1u; + v_i = v_block_size; + v_j = (v_run + v_block_size); + if (v_j > self->private_impl.f_max_incl_block_size) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); goto exit; } + v_block_size = v_j; + v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u])); + self->private_data.f_letter_counts[v_mtft0] += v_run; + while (v_i < v_j) { + self->private_data.f_bwt[v_i] = v_mtft0; + v_i += 1u; + } } - self->private_impl.f_bits = (v_bits & ((((uint32_t)(1u)) << v_n_bits) - 1u)); + self->private_impl.f_bits = v_bits; self->private_impl.f_n_bits = v_n_bits; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } + self->private_impl.f_block_size = v_block_size; + self->private_impl.f_decode_huffman_which = v_which; + self->private_impl.f_decode_huffman_ticks = v_ticks; + self->private_impl.f_decode_huffman_section = v_section; + self->private_impl.f_decode_huffman_run_shift = v_run_shift; + status = wuffs_base__make_status(NULL); + goto ok; + + ok: goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -35863,52 +35554,25 @@ wuffs_deflate__decoder__decode_huffman_fast32( return status; } -// -------- func deflate.decoder.decode_huffman_fast64 +// -------- func bzip2.decoder.decode_huffman_slow WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast64( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_bzip2__decoder__decode_huffman_slow( + wuffs_bzip2__decoder* self, wuffs_base__io_buffer* a_src) { - return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src); -} + wuffs_base__status status = wuffs_base__make_status(NULL); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_table_entry = 0; - uint32_t v_table_entry_n_bits = 0; - uint64_t v_lmask = 0; - uint64_t v_dmask = 0; - uint32_t v_redir_top = 0; - uint32_t v_redir_mask = 0; - uint32_t v_length = 0; - uint32_t v_dist_minus_1 = 0; - uint32_t v_hlen = 0; - uint32_t v_hdist = 0; - uint32_t v_hdist_adjustment = 0; + uint8_t v_c8 = 0; + uint32_t v_node_index = 0; + uint16_t v_child = 0; + uint32_t v_child_ff = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + uint32_t v_output = 0; + uint32_t v_run = 0; + uint32_t v_mtft0 = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -35920,160 +35584,101 @@ wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( io2_a_src = io0_a_src + a_src->meta.wi; } - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } - v_bits = ((uint64_t)(self->private_impl.f_bits)); - v_n_bits = self->private_impl.f_n_bits; - v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); - v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); - if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { - status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); - goto exit; + uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow; + if (coro_susp_point) { + v_node_index = self->private_data.s_decode_huffman_slow.v_node_index; } - v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); - label__loop__continue:; - while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) { - v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u))); - iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 31u) != 0u) { - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while ( ! (self->private_impl.p_decode_huffman_slow != 0)) { + if (self->private_impl.f_decode_huffman_ticks > 0u) { + self->private_impl.f_decode_huffman_ticks -= 1u; } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - v_length = (((v_table_entry >> 8u) & 255u) + 3u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_table_entry_n_bits > 0u) { - v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - if ((v_table_entry >> 28u) == 1u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - if ((v_table_entry >> 24u) != 64u) { - if ((v_table_entry >> 24u) == 8u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; + self->private_impl.f_decode_huffman_ticks = 49u; + self->private_impl.f_decode_huffman_section += 1u; + if (self->private_impl.f_decode_huffman_section >= self->private_impl.f_num_sections) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections); + goto exit; + } + self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[((uint8_t)(self->private_data.f_huffman_selectors[(self->private_impl.f_decode_huffman_section & 32767u)] & 7u))]; } - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - do { - if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { - v_hlen = 0u; - v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); - if (v_length > v_hdist) { - v_length -= v_hdist; - v_hlen = v_hdist; - } else { - v_hlen = v_length; - v_length = 0u; + v_node_index = 0u; + while (true) { + if (self->private_impl.f_n_bits <= 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + self->private_impl.f_bits = (((uint32_t)(v_c8)) << 24u); + self->private_impl.f_n_bits = 8u; } - v_hdist += v_hdist_adjustment; - if (self->private_impl.f_history_index < v_hdist) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); - goto exit; + v_child = self->private_data.f_huffman_trees[self->private_impl.f_decode_huffman_which][v_node_index][(self->private_impl.f_bits >> 31u)]; + self->private_impl.f_bits <<= 1u; + self->private_impl.f_n_bits -= 1u; + if (v_child < 257u) { + v_node_index = ((uint32_t)(v_child)); + continue; + } else if (v_child < 768u) { + v_child_ff = ((uint32_t)(((uint16_t)(v_child & 255u)))); + v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff])); + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff)); + self->private_data.f_mtft[0u] = ((uint8_t)(v_output)); + self->private_data.f_letter_counts[v_output] += 1u; + self->private_data.f_bwt[self->private_impl.f_block_size] = v_output; + if (self->private_impl.f_block_size >= self->private_impl.f_max_incl_block_size) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); + goto exit; + } + self->private_impl.f_block_size += 1u; + self->private_impl.f_decode_huffman_run_shift = 0u; + break; + } else if (v_child == 768u) { + self->private_impl.f_decode_huffman_finished = true; + goto label__outer__break; } - wuffs_base__io_writer__limited_copy_u32_from_slice( - &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); - if (v_length == 0u) { - goto label__loop__continue; + if (self->private_impl.f_decode_huffman_run_shift >= 23u) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); + goto exit; } - if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); + v_run = ((((uint32_t)(v_child)) & 3u) << self->private_impl.f_decode_huffman_run_shift); + self->private_impl.f_decode_huffman_run_shift += 1u; + v_i = self->private_impl.f_block_size; + v_j = (v_run + self->private_impl.f_block_size); + if (v_j > self->private_impl.f_max_incl_block_size) { + status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length); goto exit; } + self->private_impl.f_block_size = v_j; + v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u])); + self->private_data.f_letter_counts[v_mtft0] += v_run; + while (v_i < v_j) { + self->private_data.f_bwt[v_i] = v_mtft0; + v_i += 1u; + } + break; } - if ((v_dist_minus_1 + 1u) >= 8u) { - wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } else if ((v_dist_minus_1 + 1u) == 1u) { - wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } else { - wuffs_base__io_writer__limited_copy_u32_from_history_fast( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - } - } while (0); - } - if (v_n_bits > 63u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } - while (v_n_bits >= 8u) { - v_n_bits -= 8u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); - goto exit; } - } - self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u)))); - self->private_impl.f_n_bits = v_n_bits; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + label__outer__break:; + + goto ok; + ok: + self->private_impl.p_decode_huffman_slow = 0; goto exit; } + + goto suspend; + suspend: + self->private_impl.p_decode_huffman_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_huffman_slow.v_node_index = v_node_index; + goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -36081,40 +35686,229 @@ wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( return status; } -// -------- func deflate.decoder.decode_huffman_slow +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) + +// ---------------- Status Codes Implementations + +const char wuffs_cbor__error__bad_input[] = "#cbor: bad input"; +const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth"; +const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O"; +const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length"; + +// ---------------- Private Consts + +static const uint32_t +WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = { + 8388612u, 8388616u, 8388610u, 8388609u, +}; + +static const uint8_t +WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, + 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, + 2u, 3u, 5u, 9u, 0u, 0u, 0u, 1u, +}; + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +// ---------------- VTables + +const wuffs_base__token_decoder__func_ptrs +wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__token_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_cbor__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_cbor__decoder__set_quirk), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_cbor__decoder__initialize( + wuffs_cbor__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name = + wuffs_base__token_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers = + (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_cbor__decoder* +wuffs_cbor__decoder__alloc(void) { + wuffs_cbor__decoder* x = + (wuffs_cbor__decoder*)(calloc(1, sizeof(wuffs_cbor__decoder))); + if (!x) { + return NULL; + } + if (wuffs_cbor__decoder__initialize( + x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_cbor__decoder(void) { + return sizeof(wuffs_cbor__decoder); +} + +// ---------------- Function Implementations + +// -------- func cbor.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_deflate__decoder__decode_huffman_slow( - wuffs_deflate__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_cbor__decoder__get_quirk( + const wuffs_cbor__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func cbor.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_cbor__decoder__set_quirk( + wuffs_cbor__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func cbor.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_cbor__decoder__workbuf_len( + const wuffs_cbor__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__empty_range_ii_u64(); +} + +// -------- func cbor.decoder.decode_tokens + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_cbor__decoder__decode_tokens( + wuffs_cbor__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_table_entry = 0; - uint32_t v_table_entry_n_bits = 0; - uint32_t v_lmask = 0; - uint32_t v_dmask = 0; - uint32_t v_b0 = 0; - uint32_t v_redir_top = 0; - uint32_t v_redir_mask = 0; - uint32_t v_b1 = 0; - uint32_t v_length = 0; - uint32_t v_b2 = 0; - uint32_t v_b3 = 0; - uint32_t v_b4 = 0; - uint32_t v_dist_minus_1 = 0; - uint32_t v_b5 = 0; - uint32_t v_n_copied = 0; - uint32_t v_hlen = 0; - uint32_t v_hdist = 0; + uint64_t v_string_length = 0; + uint64_t v_n64 = 0; + uint32_t v_depth = 0; + uint32_t v_stack_byte = 0; + uint32_t v_stack_bit = 0; + uint32_t v_stack_val = 0; + uint32_t v_token_length = 0; + uint32_t v_vminor = 0; + uint32_t v_vminor_alt = 0; + uint32_t v_continued = 0; + uint8_t v_c8 = 0; + uint8_t v_c_major = 0; + uint8_t v_c_minor = 0; + bool v_tagged = false; + uint8_t v_indefinite_string_major_type = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; if (a_dst && a_dst->data.ptr) { io0_a_dst = a_dst->data.ptr; io1_a_dst = io0_a_dst + a_dst->meta.wi; @@ -36135,269 +35929,513 @@ wuffs_deflate__decoder__decode_huffman_slow( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_tokens; if (coro_susp_point) { - v_bits = self->private_data.s_decode_huffman_slow[0].v_bits; - v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits; - v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits; - v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask; - v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask; - v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top; - v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask; - v_length = self->private_data.s_decode_huffman_slow[0].v_length; - v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1; + v_string_length = self->private_data.s_decode_tokens.v_string_length; + v_depth = self->private_data.s_decode_tokens.v_depth; + v_tagged = self->private_data.s_decode_tokens.v_tagged; + v_indefinite_string_major_type = self->private_data.s_decode_tokens.v_indefinite_string_major_type; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; + if (self->private_impl.f_end_of_data) { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } - v_bits = self->private_impl.f_bits; - v_n_bits = self->private_impl.f_n_bits; - v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); - v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); - label__loop__continue:; - while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) { + label__outer__continue:; + while (true) { while (true) { - v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - if (v_n_bits >= v_table_entry_n_bits) { - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - break; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + do { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + goto label__outer__continue; } - uint32_t t_0 = *iop_a_src++; - v_b0 = t_0; - } - v_bits |= (v_b0 << v_n_bits); - v_n_bits += 8u; - } - if ((v_table_entry >> 31u) != 0u) { - self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u))); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (iop_a_dst == io2_a_dst) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - goto suspend; - } - *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch)); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - while (true) { - v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - if (v_n_bits >= v_table_entry_n_bits) { - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - break; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + goto label__outer__continue; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if ((v_indefinite_string_major_type != 0u) && (v_indefinite_string_major_type != ((uint8_t)(v_c8 >> 5u)))) { + if (v_c8 != 255u) { + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + goto exit; } - uint32_t t_1 = *iop_a_src++; - v_b1 = t_1; + v_vminor = 4194560u; + if (v_indefinite_string_major_type == 3u) { + v_vminor |= 19u; + } + v_indefinite_string_major_type = 0u; + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; } - v_bits |= (v_b1 << v_n_bits); - v_n_bits += 8u; - } - if ((v_table_entry >> 31u) != 0u) { - self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u))); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (iop_a_dst == io2_a_dst) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - goto suspend; + iop_a_src += 1u; + v_c_major = ((uint8_t)(((uint8_t)(v_c8 >> 5u)))); + v_c_minor = ((uint8_t)(v_c8 & 31u)); + if (v_c_minor < 24u) { + v_string_length = ((uint64_t)(v_c_minor)); + } else { + while (true) { + if (v_c_minor == 24u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 1u) { + v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); + iop_a_src += 1u; + break; + } + } else if (v_c_minor == 25u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 2u) { + v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2u; + break; + } + } else if (v_c_minor == 26u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { + v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4u; + break; + } + } else if (v_c_minor == 27u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 8u) { + v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8u; + break; + } + } else { + v_string_length = 0u; + break; + } + if (iop_a_src > io1_a_src) { + iop_a_src--; + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + goto label__outer__continue; + } + status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); + goto exit; + } } - *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch)); - continue; - } else if ((v_table_entry >> 30u) != 0u) { - } else if ((v_table_entry >> 29u) != 0u) { - self->private_impl.f_end_of_block = true; - break; - } else if ((v_table_entry >> 28u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + if (v_c_major == 0u) { + if (v_c_minor < 26u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((14680064u | ((uint32_t)((v_string_length & 65535u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor < 28u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((14680064u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + *iop_a_dst++ = wuffs_base__make_token( + (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + } else if (v_c_major == 1u) { + if (v_c_minor < 26u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length & 65535u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor < 28u) { + if (v_string_length < 9223372036854775808u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length >> 46u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + *iop_a_dst++ = wuffs_base__make_token( + (~((18446744073709551615u - v_string_length) & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } else { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | + (((uint64_t)(16777216u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + goto label__goto_parsed_a_leaf_value__break; + } + } else if (v_c_major == 2u) { + if (v_c_minor < 28u) { + if (v_string_length == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } else if (v_c_minor == 31u) { + if (v_indefinite_string_major_type != 0u) { + break; + } + v_indefinite_string_major_type = 2u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__outer__continue; + } else { + break; + } + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + continue; + } + v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src))); + v_token_length = ((uint32_t)((v_n64 & 65535u))); + if (v_n64 > 65535u) { + v_token_length = 65535u; + } else if (v_token_length <= 0u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + continue; + } + if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) { + status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length); + goto exit; + } + v_string_length -= ((uint64_t)(v_token_length)); + v_continued = 0u; + if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) { + v_continued = 1u; + } + iop_a_src += v_token_length; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194816u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (v_string_length > 0u) { + continue; + } else if (v_indefinite_string_major_type > 0u) { + goto label__outer__continue; + } + goto label__goto_parsed_a_leaf_value__break; + } + } else if (v_c_major == 3u) { + if (v_c_minor < 28u) { + if (v_string_length == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } else if (v_c_minor == 31u) { + if (v_indefinite_string_major_type != 0u) { + break; + } + v_indefinite_string_major_type = 3u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__outer__continue; + } else { + break; + } + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + continue; + } + v_n64 = wuffs_base__u64__min(v_string_length, 65535u); + v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src, + ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64)))))); + v_token_length = ((uint32_t)((v_n64 & 65535u))); + if (v_token_length <= 0u) { + if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) { + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); + continue; + } + if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) { + status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length); + goto exit; + } + v_string_length -= ((uint64_t)(v_token_length)); + v_continued = 0u; + if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) { + v_continued = 1u; + } + iop_a_src += v_token_length; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (v_string_length > 0u) { + continue; + } else if (v_indefinite_string_major_type > 0u) { + goto label__outer__continue; + } + goto label__goto_parsed_a_leaf_value__break; + } + } else if (v_c_major == 4u) { + if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) { + break; + } else if (v_depth >= 1024u) { + v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])); + while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) { + iop_a_src--; + v_token_length -= 1u; + } + status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth); + goto exit; + } + v_vminor = 2105361u; + v_vminor_alt = 2101282u; + if (v_depth > 0u) { + v_stack_byte = ((v_depth - 1u) / 16u); + v_stack_bit = (((v_depth - 1u) & 15u) * 2u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + v_vminor = 2105377u; + v_vminor_alt = 2105378u; + } else { + v_vminor = 2105409u; + v_vminor_alt = 2113570u; + } + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (v_c_minor == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + v_stack_byte = (v_depth / 16u); + v_stack_bit = ((v_depth & 15u) * 2u); + self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(3u)) << v_stack_bit)); + self->private_data.f_container_num_remaining[v_depth] = v_string_length; + v_depth += 1u; + v_tagged = false; + goto label__outer__continue; + } else if (v_c_major == 5u) { + if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) { + break; + } else if (v_depth >= 1024u) { + v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])); + while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) { + iop_a_src--; + v_token_length -= 1u; + } + status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth); + goto exit; + } + v_vminor = 2113553u; + v_vminor_alt = 2101314u; + if (v_depth > 0u) { + v_stack_byte = ((v_depth - 1u) / 16u); + v_stack_bit = (((v_depth - 1u) & 15u) * 2u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + v_vminor = 2113569u; + v_vminor_alt = 2105410u; + } else { + v_vminor = 2113601u; + v_vminor_alt = 2113602u; + } + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (v_c_minor == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + v_stack_byte = (v_depth / 16u); + v_stack_bit = ((v_depth & 15u) * 2u); + self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3u)) << v_stack_bit); + self->private_data.f_container_num_remaining[v_depth] = v_string_length; + v_depth += 1u; + v_tagged = false; + goto label__outer__continue; + } else if (v_c_major == 6u) { + if (v_c_minor >= 28u) { + break; + } + if (v_string_length < 262144u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | + (((uint64_t)((4194304u | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } else { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | + (((uint64_t)((4194304u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + *iop_a_dst++ = wuffs_base__make_token( + (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + v_tagged = true; + goto label__outer__continue; + } else if (v_c_major == 7u) { + if (v_c_minor < 20u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | + (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor < 24u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(WUFFS_CBOR__LITERALS[((uint8_t)(v_c_minor & 3u))])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor == 24u) { + if (v_string_length < 24u) { + if ( ! (iop_a_src > io1_a_src)) { + status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); + goto exit; + } + iop_a_src--; + break; + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) | + (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor < 28u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(10490113u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } else if (v_c_minor == 31u) { + if (v_tagged || (v_depth <= 0u)) { + break; + } + v_depth -= 1u; + if (self->private_data.f_container_num_remaining[v_depth] != 0u) { + break; + } + v_stack_byte = (v_depth / 16u); + v_stack_bit = ((v_depth & 15u) * 2u); + v_stack_val = (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit)); + if (v_stack_val == 1u) { + break; + } + if (v_stack_val != 3u) { + v_vminor_alt = 2097186u; + } else { + v_vminor_alt = 2097218u; + } + if (v_depth <= 0u) { + v_vminor_alt |= 4096u; + } else { + v_stack_byte = ((v_depth - 1u) / 16u); + v_stack_bit = (((v_depth - 1u) & 15u) * 2u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + v_vminor_alt |= 8192u; + } else { + v_vminor_alt |= 16384u; + } + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__goto_parsed_a_leaf_value__break; + } + } + } while (0); + if (iop_a_src > io1_a_src) { + iop_a_src--; + status = wuffs_base__make_status(wuffs_cbor__error__bad_input); goto exit; } - } else if ((v_table_entry >> 27u) != 0u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o); goto exit; } - v_length = (((v_table_entry >> 8u) & 255u) + 3u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_table_entry_n_bits > 0u) { - while (v_n_bits < v_table_entry_n_bits) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint32_t t_2 = *iop_a_src++; - v_b2 = t_2; - } - v_bits |= (v_b2 << v_n_bits); - v_n_bits += 8u; + label__goto_parsed_a_leaf_value__break:; + v_tagged = false; + while (v_depth > 0u) { + v_stack_byte = ((v_depth - 1u) / 16u); + v_stack_bit = (((v_depth - 1u) & 15u) * 2u); + self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1u)) << (v_stack_bit + 1u)); + if (1u == (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) { + goto label__outer__continue; } - v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - while (true) { - v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; - v_table_entry_n_bits = (v_table_entry & 15u); - if (v_n_bits >= v_table_entry_n_bits) { - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - break; + if (self->private_data.f_container_num_remaining[(v_depth - 1u)] <= 0u) { + goto label__outer__continue; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint32_t t_3 = *iop_a_src++; - v_b3 = t_3; - } - v_bits |= (v_b3 << v_n_bits); - v_n_bits += 8u; - } - if ((v_table_entry >> 28u) == 1u) { - v_redir_top = ((v_table_entry >> 8u) & 65535u); - v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); - while (true) { - v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; - v_table_entry_n_bits = (v_table_entry & 15u); - if (v_n_bits >= v_table_entry_n_bits) { - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - break; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint32_t t_4 = *iop_a_src++; - v_b4 = t_4; - } - v_bits |= (v_b4 << v_n_bits); - v_n_bits += 8u; + self->private_data.f_container_num_remaining[(v_depth - 1u)] -= 1u; + if (self->private_data.f_container_num_remaining[(v_depth - 1u)] > 0u) { + goto label__outer__continue; } - } - if ((v_table_entry >> 24u) != 64u) { - if ((v_table_entry >> 24u) == 8u) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); - goto exit; + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + continue; } - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); - goto exit; - } - v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); - v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); - if (v_table_entry_n_bits > 0u) { - while (v_n_bits < v_table_entry_n_bits) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint32_t t_5 = *iop_a_src++; - v_b5 = t_5; - } - v_bits |= (v_b5 << v_n_bits); - v_n_bits += 8u; + v_depth -= 1u; + v_stack_byte = (v_depth / 16u); + v_stack_bit = ((v_depth & 15u) * 2u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + v_vminor_alt = 2097186u; + } else { + v_vminor_alt = 2097218u; } - v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u); - v_bits >>= v_table_entry_n_bits; - v_n_bits -= v_table_entry_n_bits; - } - while (true) { - if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { - v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); - if (v_hdist < v_length) { - v_hlen = v_hdist; + if (v_depth <= 0u) { + v_vminor_alt |= 4096u; + } else { + v_stack_byte = ((v_depth - 1u) / 16u); + v_stack_bit = (((v_depth - 1u) & 15u) * 2u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + v_vminor_alt |= 8192u; } else { - v_hlen = v_length; - } - v_hdist += ((uint32_t)(((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))))); - if (self->private_impl.f_history_index < v_hdist) { - status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); - goto exit; - } - v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice( - &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); - if (v_n_copied < v_hlen) { - v_length -= v_n_copied; - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); - continue; - } - v_length -= v_hlen; - if (v_length == 0u) { - goto label__loop__continue; + v_vminor_alt |= 16384u; } } - v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history( - &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); - if (v_length <= v_n_copied) { - goto label__loop__continue; - } - v_length -= v_n_copied; - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); } + break; } - self->private_impl.f_bits = v_bits; - self->private_impl.f_n_bits = v_n_bits; - if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { - status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); - goto exit; - } + self->private_impl.f_end_of_data = true; ok: - self->private_impl.p_decode_huffman_slow[0] = 0; + self->private_impl.p_decode_tokens = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_huffman_slow[0].v_bits = v_bits; - self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits; - self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits; - self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask; - self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask; - self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top; - self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask; - self->private_data.s_decode_huffman_slow[0].v_length = v_length; - self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1; + self->private_impl.p_decode_tokens = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_data.s_decode_tokens.v_string_length = v_string_length; + self->private_data.s_decode_tokens.v_depth = v_depth; + self->private_data.s_decode_tokens.v_tagged = v_tagged; + self->private_data.s_decode_tokens.v_indefinite_string_major_type = v_indefinite_string_major_type; goto exit; exit: @@ -36408,243 +36446,607 @@ wuffs_deflate__decoder__decode_huffman_slow( a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) // ---------------- Status Codes Implementations -const char wuffs_gif__error__bad_lzw_code[] = "#gif: bad LZW code"; -const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label"; -const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size"; -const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control"; -const char wuffs_gif__error__bad_header[] = "#gif: bad header"; -const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width"; -const char wuffs_gif__error__bad_palette[] = "#gif: bad palette"; -const char wuffs_gif__error__truncated_input[] = "#gif: truncated input"; -const char wuffs_gif__error__internal_error_inconsistent_i_o[] = "#gif: internal error: inconsistent I/O"; - // ---------------- Private Consts static const uint32_t -WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = { - 4294967295, 1, 2, 4, 0, -}; - -static const uint8_t -WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1, 2, 4, 8, 8, -}; - -static const uint8_t -WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 1, 2, 4, 8, -}; - -static const uint8_t -WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = { - 65, 78, 73, 77, 69, 88, 84, 83, - 49, 46, 48, -}; - -static const uint8_t -WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = { - 78, 69, 84, 83, 67, 65, 80, 69, - 50, 46, 48, -}; - -static const uint8_t -WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = { - 73, 67, 67, 82, 71, 66, 71, 49, - 48, 49, 50, -}; - -static const uint8_t -WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = { - 88, 77, 80, 32, 68, 97, 116, 97, - 88, 77, 80, +WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = { + { + 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, + 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, + 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, + 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, + 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, + 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, + 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, + 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, + 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, + 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, + 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, + 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, + 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, + 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, + 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, + 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, + 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, + 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, + 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, + 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, + 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, + 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, + 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, + 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, + 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, + 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, + 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, + 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, + 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, + 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, + 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, + 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u, + }, { + 0u, 421212481u, 842424962u, 724390851u, 1684849924u, 2105013317u, 1448781702u, 1329698503u, + 3369699848u, 3519200073u, 4210026634u, 3824474571u, 2897563404u, 3048111693u, 2659397006u, 2274893007u, + 1254232657u, 1406739216u, 2029285587u, 1643069842u, 783210325u, 934667796u, 479770071u, 92505238u, + 2182846553u, 2600511768u, 2955803355u, 2838940570u, 3866582365u, 4285295644u, 3561045983u, 3445231262u, + 2508465314u, 2359236067u, 2813478432u, 3198777185u, 4058571174u, 3908292839u, 3286139684u, 3670389349u, + 1566420650u, 1145479147u, 1869335592u, 1987116393u, 959540142u, 539646703u, 185010476u, 303839341u, + 3745920755u, 3327985586u, 3983561841u, 4100678960u, 3140154359u, 2721170102u, 2300350837u, 2416418868u, + 396344571u, 243568058u, 631889529u, 1018359608u, 1945336319u, 1793607870u, 1103436669u, 1490954812u, + 4034481925u, 3915546180u, 3259968903u, 3679722694u, 2484439553u, 2366552896u, 2787371139u, 3208174018u, + 950060301u, 565965900u, 177645455u, 328046286u, 1556873225u, 1171730760u, 1861902987u, 2011255754u, + 3132841300u, 2745199637u, 2290958294u, 2442530455u, 3738671184u, 3352078609u, 3974232786u, 4126854035u, + 1919080284u, 1803150877u, 1079293406u, 1498383519u, 370020952u, 253043481u, 607678682u, 1025720731u, + 1711106983u, 2095471334u, 1472923941u, 1322268772u, 26324643u, 411738082u, 866634785u, 717028704u, + 2904875439u, 3024081134u, 2668790573u, 2248782444u, 3376948395u, 3495106026u, 4219356713u, 3798300520u, + 792689142u, 908347575u, 487136116u, 68299317u, 1263779058u, 1380486579u, 2036719216u, 1618931505u, + 3890672638u, 4278043327u, 3587215740u, 3435896893u, 2206873338u, 2593195963u, 2981909624u, 2829542713u, + 998479947u, 580430090u, 162921161u, 279890824u, 1609522511u, 1190423566u, 1842954189u, 1958874764u, + 4082766403u, 3930137346u, 3245109441u, 3631694208u, 2536953671u, 2385372678u, 2768287173u, 3155920004u, + 1900120602u, 1750776667u, 1131931800u, 1517083097u, 355290910u, 204897887u, 656092572u, 1040194781u, + 3113746450u, 2692952403u, 2343461520u, 2461357009u, 3723805974u, 3304059991u, 4022511508u, 4141455061u, + 2919742697u, 3072101800u, 2620513899u, 2234183466u, 3396041197u, 3547351212u, 4166851439u, 3779471918u, + 1725839073u, 2143618976u, 1424512099u, 1307796770u, 45282277u, 464110244u, 813994343u, 698327078u, + 3838160568u, 4259225593u, 3606301754u, 3488152955u, 2158586812u, 2578602749u, 2996767038u, 2877569151u, + 740041904u, 889656817u, 506086962u, 120682355u, 1215357364u, 1366020341u, 2051441462u, 1667084919u, + 3422213966u, 3538019855u, 4190942668u, 3772220557u, 2945847882u, 3062702859u, 2644537544u, 2226864521u, + 52649286u, 439905287u, 823476164u, 672009861u, 1733269570u, 2119477507u, 1434057408u, 1281543041u, + 2167981343u, 2552493150u, 3004082077u, 2853541596u, 3847487515u, 4233048410u, 3613549209u, 3464057816u, + 1239502615u, 1358593622u, 2077699477u, 1657543892u, 764250643u, 882293586u, 532408465u, 111204816u, + 1585378284u, 1197851309u, 1816695150u, 1968414767u, 974272232u, 587794345u, 136598634u, 289367339u, + 2527558116u, 2411481253u, 2760973158u, 3179948583u, 4073438432u, 3956313505u, 3237863010u, 3655790371u, + 347922877u, 229101820u, 646611775u, 1066513022u, 1892689081u, 1774917112u, 1122387515u, 1543337850u, + 3697634229u, 3313392372u, 3998419255u, 4148705398u, 3087642289u, 2702352368u, 2319436851u, 2468674930u, + }, { + 0u, 29518391u, 59036782u, 38190681u, 118073564u, 114017003u, 76381362u, 89069189u, + 236147128u, 265370511u, 228034006u, 206958561u, 152762724u, 148411219u, 178138378u, 190596925u, + 472294256u, 501532999u, 530741022u, 509615401u, 456068012u, 451764635u, 413917122u, 426358261u, + 305525448u, 334993663u, 296822438u, 275991697u, 356276756u, 352202787u, 381193850u, 393929805u, + 944588512u, 965684439u, 1003065998u, 973863097u, 1061482044u, 1049003019u, 1019230802u, 1023561829u, + 912136024u, 933002607u, 903529270u, 874031361u, 827834244u, 815125939u, 852716522u, 856752605u, + 611050896u, 631869351u, 669987326u, 640506825u, 593644876u, 580921211u, 551983394u, 556069653u, + 712553512u, 733666847u, 704405574u, 675154545u, 762387700u, 749958851u, 787859610u, 792175277u, + 1889177024u, 1901651959u, 1931368878u, 1927033753u, 2006131996u, 1985040171u, 1947726194u, 1976933189u, + 2122964088u, 2135668303u, 2098006038u, 2093965857u, 2038461604u, 2017599123u, 2047123658u, 2076625661u, + 1824272048u, 1836991623u, 1866005214u, 1861914857u, 1807058540u, 1786244187u, 1748062722u, 1777547317u, + 1655668488u, 1668093247u, 1630251878u, 1625932113u, 1705433044u, 1684323811u, 1713505210u, 1742760333u, + 1222101792u, 1226154263u, 1263738702u, 1251046777u, 1339974652u, 1310460363u, 1281013650u, 1301863845u, + 1187289752u, 1191637167u, 1161842422u, 1149379777u, 1103966788u, 1074747507u, 1112139306u, 1133218845u, + 1425107024u, 1429406311u, 1467333694u, 1454888457u, 1408811148u, 1379576507u, 1350309090u, 1371438805u, + 1524775400u, 1528845279u, 1499917702u, 1487177649u, 1575719220u, 1546255107u, 1584350554u, 1605185389u, + 3778354048u, 3774312887u, 3803303918u, 3816007129u, 3862737756u, 3892238699u, 3854067506u, 3833203973u, + 4012263992u, 4007927823u, 3970080342u, 3982554209u, 3895452388u, 3924658387u, 3953866378u, 3932773565u, + 4245928176u, 4241609415u, 4271336606u, 4283762345u, 4196012076u, 4225268251u, 4187931714u, 4166823541u, + 4076923208u, 4072833919u, 4035198246u, 4047918865u, 4094247316u, 4123732899u, 4153251322u, 4132437965u, + 3648544096u, 3636082519u, 3673983246u, 3678331705u, 3732010428u, 3753090955u, 3723829714u, 3694611429u, + 3614117080u, 3601426159u, 3572488374u, 3576541825u, 3496125444u, 3516976691u, 3555094634u, 3525581405u, + 3311336976u, 3298595879u, 3336186494u, 3340255305u, 3260503756u, 3281337595u, 3251864226u, 3222399125u, + 3410866088u, 3398419871u, 3368647622u, 3372945905u, 3427010420u, 3448139075u, 3485520666u, 3456284973u, + 2444203584u, 2423127159u, 2452308526u, 2481530905u, 2527477404u, 2539934891u, 2502093554u, 2497740997u, + 2679949304u, 2659102159u, 2620920726u, 2650438049u, 2562027300u, 2574714131u, 2603727690u, 2599670141u, + 2374579504u, 2353749767u, 2383274334u, 2412743529u, 2323684844u, 2336421851u, 2298759554u, 2294686645u, + 2207933576u, 2186809023u, 2149495014u, 2178734801u, 2224278612u, 2236720739u, 2266437690u, 2262135309u, + 2850214048u, 2820717207u, 2858812622u, 2879680249u, 2934667388u, 2938704459u, 2909776914u, 2897069605u, + 2817622296u, 2788420399u, 2759153014u, 2780249921u, 2700618180u, 2704950259u, 2742877610u, 2730399645u, + 3049550800u, 3020298727u, 3057690558u, 3078802825u, 2999835404u, 3004150075u, 2974355298u, 2961925461u, + 3151438440u, 3121956959u, 3092510214u, 3113327665u, 3168701108u, 3172786307u, 3210370778u, 3197646061u, + }, { + 0u, 3099354981u, 2852767883u, 313896942u, 2405603159u, 937357362u, 627793884u, 2648127673u, + 3316918511u, 2097696650u, 1874714724u, 3607201537u, 1255587768u, 4067088605u, 3772741427u, 1482887254u, + 1343838111u, 3903140090u, 4195393300u, 1118632049u, 3749429448u, 1741137837u, 1970407491u, 3452858150u, + 2511175536u, 756094997u, 1067759611u, 2266550430u, 449832999u, 2725482306u, 2965774508u, 142231497u, + 2687676222u, 412010587u, 171665333u, 2995192016u, 793786473u, 2548850444u, 2237264098u, 1038456711u, + 1703315409u, 3711623348u, 3482275674u, 1999841343u, 3940814982u, 1381529571u, 1089329165u, 4166106984u, + 4029413537u, 1217896388u, 1512189994u, 3802027855u, 2135519222u, 3354724499u, 3577784189u, 1845280792u, + 899665998u, 2367928107u, 2677414085u, 657096608u, 3137160985u, 37822588u, 284462994u, 2823350519u, + 2601801789u, 598228824u, 824021174u, 2309093331u, 343330666u, 2898962447u, 3195996129u, 113467524u, + 1587572946u, 3860600759u, 4104763481u, 1276501820u, 3519211397u, 1769898208u, 2076913422u, 3279374443u, + 3406630818u, 1941006535u, 1627703081u, 3652755532u, 1148164341u, 4241751952u, 3999682686u, 1457141531u, + 247015245u, 3053797416u, 2763059142u, 470583459u, 2178658330u, 963106687u, 735213713u, 2473467892u, + 992409347u, 2207944806u, 2435792776u, 697522413u, 3024379988u, 217581361u, 508405983u, 2800865210u, + 4271038444u, 1177467017u, 1419450215u, 3962007554u, 1911572667u, 3377213406u, 3690561584u, 1665525589u, + 1799331996u, 3548628985u, 3241568279u, 2039091058u, 3831314379u, 1558270126u, 1314193216u, 4142438437u, + 2928380019u, 372764438u, 75645176u, 3158189981u, 568925988u, 2572515393u, 2346768303u, 861712586u, + 3982079547u, 1441124702u, 1196457648u, 4293663189u, 1648042348u, 3666298377u, 3358779879u, 1888390786u, + 686661332u, 2421291441u, 2196002399u, 978858298u, 2811169155u, 523464422u, 226935048u, 3040519789u, + 3175145892u, 100435649u, 390670639u, 2952089162u, 841119475u, 2325614998u, 2553003640u, 546822429u, + 2029308235u, 3225988654u, 3539796416u, 1782671013u, 4153826844u, 1328167289u, 1570739863u, 3844338162u, + 1298864389u, 4124540512u, 3882013070u, 1608431339u, 3255406162u, 2058742071u, 1744848601u, 3501990332u, + 2296328682u, 811816591u, 584513889u, 2590678532u, 129869501u, 3204563416u, 2914283062u, 352848211u, + 494030490u, 2781751807u, 3078325777u, 264757620u, 2450577869u, 715964072u, 941166918u, 2158327331u, + 3636881013u, 1618608400u, 1926213374u, 3396585883u, 1470427426u, 4011365959u, 4255988137u, 1158766284u, + 1984818694u, 3471935843u, 3695453837u, 1693991400u, 4180638033u, 1100160564u, 1395044826u, 3952793279u, + 3019491049u, 189112716u, 435162722u, 2706139399u, 1016811966u, 2217162459u, 2526189877u, 774831696u, + 643086745u, 2666061564u, 2354934034u, 887166583u, 2838900430u, 294275499u, 54519365u, 3145957664u, + 3823145334u, 1532818963u, 1240029693u, 4048895640u, 1820460577u, 3560857924u, 3331051178u, 2117577167u, + 3598663992u, 1858283101u, 2088143283u, 3301633750u, 1495127663u, 3785470218u, 4078182116u, 1269332353u, + 332098007u, 2876706482u, 3116540252u, 25085497u, 2628386432u, 605395429u, 916469259u, 2384220526u, + 2254837415u, 1054503362u, 745528876u, 2496903497u, 151290352u, 2981684885u, 2735556987u, 464596510u, + 1137851976u, 4218313005u, 3923506883u, 1365741990u, 3434129695u, 1946996346u, 1723425172u, 3724871409u, + }, { + 0u, 1029712304u, 2059424608u, 1201699536u, 4118849216u, 3370159984u, 2403399072u, 2988497936u, + 812665793u, 219177585u, 1253054625u, 2010132753u, 3320900865u, 4170237105u, 3207642721u, 2186319825u, + 1625331586u, 1568718386u, 438355170u, 658566482u, 2506109250u, 2818578674u, 4020265506u, 3535817618u, + 1351670851u, 1844508147u, 709922595u, 389064339u, 2769320579u, 2557498163u, 3754961379u, 3803185235u, + 3250663172u, 4238411444u, 3137436772u, 2254525908u, 876710340u, 153198708u, 1317132964u, 1944187668u, + 4054934725u, 3436268917u, 2339452837u, 3054575125u, 70369797u, 961670069u, 2129760613u, 1133623509u, + 2703341702u, 2621542710u, 3689016294u, 3867263574u, 1419845190u, 1774270454u, 778128678u, 318858390u, + 2438067015u, 2888948471u, 3952189479u, 3606153623u, 1691440519u, 1504803895u, 504432359u, 594620247u, + 1492342857u, 1704161785u, 573770537u, 525542041u, 2910060169u, 2417219385u, 3618876905u, 3939730521u, + 1753420680u, 1440954936u, 306397416u, 790849880u, 2634265928u, 2690882808u, 3888375336u, 3668168600u, + 940822475u, 91481723u, 1121164459u, 2142483739u, 3448989963u, 4042473659u, 3075684971u, 2318603227u, + 140739594u, 889433530u, 1923340138u, 1338244826u, 4259521226u, 3229813626u, 2267247018u, 3124975642u, + 2570221389u, 2756861693u, 3824297005u, 3734113693u, 1823658381u, 1372780605u, 376603373u, 722643805u, + 2839690380u, 2485261628u, 3548540908u, 4007806556u, 1556257356u, 1638052860u, 637716780u, 459464860u, + 4191346895u, 3300051327u, 2199040943u, 3195181599u, 206718479u, 825388991u, 1989285231u, 1274166495u, + 3382881038u, 4106388158u, 3009607790u, 2382549470u, 1008864718u, 21111934u, 1189240494u, 2072147742u, + 2984685714u, 2357631266u, 3408323570u, 4131834434u, 1147541074u, 2030452706u, 1051084082u, 63335554u, + 2174155603u, 3170292451u, 4216760371u, 3325460867u, 1947622803u, 1232499747u, 248909555u, 867575619u, + 3506841360u, 3966111392u, 2881909872u, 2527485376u, 612794832u, 434546784u, 1581699760u, 1663499008u, + 3782634705u, 3692447073u, 2612412337u, 2799048193u, 351717905u, 697754529u, 1849071985u, 1398190273u, + 1881644950u, 1296545318u, 182963446u, 931652934u, 2242328918u, 3100053734u, 4284967478u, 3255255942u, + 1079497815u, 2100821479u, 983009079u, 133672583u, 3050795671u, 2293717799u, 3474399735u, 4067887175u, + 281479188u, 765927844u, 1778867060u, 1466397380u, 3846680276u, 3626469220u, 2676489652u, 2733102084u, + 548881365u, 500656741u, 1517752501u, 1729575173u, 3577210133u, 3898068133u, 2952246901u, 2459410373u, + 3910527195u, 3564487019u, 2480257979u, 2931134987u, 479546907u, 569730987u, 1716854139u, 1530213579u, + 3647316762u, 3825568426u, 2745561210u, 2663766474u, 753206746u, 293940330u, 1445287610u, 1799716618u, + 2314567513u, 3029685993u, 4080348217u, 3461678473u, 2088098201u, 1091956777u, 112560889u, 1003856713u, + 3112514712u, 2229607720u, 3276105720u, 4263857736u, 1275433560u, 1902492648u, 918929720u, 195422344u, + 685033439u, 364179055u, 1377080511u, 1869921551u, 3713294623u, 3761522863u, 2811507327u, 2599689167u, + 413436958u, 633644462u, 1650777982u, 1594160846u, 3978570462u, 3494118254u, 2548332990u, 2860797966u, + 1211387997u, 1968470509u, 854852413u, 261368461u, 3182753437u, 2161434413u, 3346310653u, 4195650637u, + 2017729436u, 1160000044u, 42223868u, 1071931724u, 2378480988u, 2963576044u, 4144295484u, 3395602316u, + }, { + 0u, 3411858341u, 1304994059u, 2257875630u, 2609988118u, 1355649459u, 3596215069u, 486879416u, + 3964895853u, 655315400u, 2711298918u, 1791488195u, 2009251963u, 3164476382u, 973758832u, 4048990933u, + 64357019u, 3364540734u, 1310630800u, 2235723829u, 2554806413u, 1394316072u, 3582976390u, 517157411u, + 4018503926u, 618222419u, 2722963965u, 1762783832u, 1947517664u, 3209171269u, 970744811u, 4068520014u, + 128714038u, 3438335635u, 1248109629u, 2167961496u, 2621261600u, 1466012805u, 3522553387u, 447296910u, + 3959392091u, 547575038u, 2788632144u, 1835791861u, 1886307661u, 3140622056u, 1034314822u, 4143626211u, + 75106221u, 3475428360u, 1236444838u, 2196665603u, 2682996155u, 1421317662u, 3525567664u, 427767573u, + 3895035328u, 594892389u, 2782995659u, 1857943406u, 1941489622u, 3101955187u, 1047553757u, 4113347960u, + 257428076u, 3288652233u, 1116777319u, 2311878850u, 2496219258u, 1603640287u, 3640781169u, 308099796u, + 3809183745u, 676813732u, 2932025610u, 1704983215u, 2023410199u, 3016104370u, 894593820u, 4262377657u, + 210634999u, 3352484690u, 1095150076u, 2316991065u, 2535410401u, 1547934020u, 3671583722u, 294336591u, + 3772615322u, 729897279u, 2903845777u, 1716123700u, 2068629644u, 2953845545u, 914647431u, 4258839074u, + 150212442u, 3282623743u, 1161604689u, 2388688372u, 2472889676u, 1480171241u, 3735940167u, 368132066u, + 3836185911u, 805002898u, 2842635324u, 1647574937u, 2134298401u, 3026852996u, 855535146u, 4188192143u, + 186781121u, 3229539940u, 1189784778u, 2377547631u, 2427670487u, 1542429810u, 3715886812u, 371670393u, + 3882979244u, 741170185u, 2864262823u, 1642462466u, 2095107514u, 3082559007u, 824732849u, 4201955092u, + 514856152u, 3589064573u, 1400419795u, 2552522358u, 2233554638u, 1316849003u, 3370776517u, 62202976u, + 4075001525u, 968836368u, 3207280574u, 1954014235u, 1769133219u, 2720925446u, 616199592u, 4024870413u, + 493229635u, 3594175974u, 1353627464u, 2616354029u, 2264355925u, 1303087088u, 3409966430u, 6498043u, + 4046820398u, 979978123u, 3170710821u, 2007099008u, 1789187640u, 2717386141u, 661419827u, 3962610838u, + 421269998u, 3527459403u, 1423225061u, 2676515648u, 2190300152u, 1238466653u, 3477467891u, 68755798u, + 4115633027u, 1041448998u, 3095868040u, 1943789869u, 1860096405u, 2776760880u, 588673182u, 3897205563u, + 449450869u, 3516317904u, 1459794558u, 2623431131u, 2170245475u, 1242006214u, 3432247400u, 131015629u, + 4137259288u, 1036337853u, 3142660115u, 1879958454u, 1829294862u, 2790523051u, 549483013u, 3952910752u, + 300424884u, 3669282065u, 1545650111u, 2541513754u, 2323209378u, 1092980487u, 3350330793u, 216870412u, + 4256931033u, 921128828u, 2960342482u, 2066738807u, 1714085583u, 2910195050u, 736264132u, 3770592353u, + 306060335u, 3647131530u, 1610005796u, 2494197377u, 2309971513u, 1123257756u, 3295149874u, 255536279u, + 4268596802u, 892423655u, 3013951305u, 2029645036u, 1711070292u, 2929725425u, 674528607u, 3815288570u, + 373562242u, 3709388839u, 1535949449u, 2429577516u, 2379569556u, 1183418929u, 3223189663u, 188820282u, + 4195850735u, 827017802u, 3084859620u, 2089020225u, 1636228089u, 2866415708u, 743340786u, 3876759895u, + 361896217u, 3738094268u, 1482340370u, 2466671543u, 2382584591u, 1163888810u, 3284924932u, 144124321u, + 4190215028u, 849168593u, 3020503679u, 2136336858u, 1649465698u, 2836138695u, 798521449u, 3838094284u, + }, { + 0u, 2792819636u, 2543784233u, 837294749u, 4098827283u, 1379413927u, 1674589498u, 3316072078u, + 871321191u, 2509784531u, 2758827854u, 34034938u, 3349178996u, 1641505216u, 1346337629u, 4131942633u, + 1742642382u, 3249117050u, 4030828007u, 1446413907u, 2475800797u, 904311657u, 68069876u, 2725880384u, + 1412551337u, 4064729373u, 3283010432u, 1708771380u, 2692675258u, 101317902u, 937551763u, 2442587175u, + 3485284764u, 1774858792u, 1478633653u, 4266992385u, 1005723023u, 2642744891u, 2892827814u, 169477906u, + 4233263099u, 1512406095u, 1808623314u, 3451546982u, 136139752u, 2926205020u, 2676114113u, 972376437u, + 2825102674u, 236236518u, 1073525883u, 2576072655u, 1546420545u, 4200303349u, 3417542760u, 1841601500u, + 2609703733u, 1039917185u, 202635804u, 2858742184u, 1875103526u, 3384067218u, 4166835727u, 1579931067u, + 1141601657u, 3799809741u, 3549717584u, 1977839588u, 2957267306u, 372464350u, 668680259u, 2175552503u, + 2011446046u, 3516084394u, 3766168119u, 1175200131u, 2209029901u, 635180217u, 338955812u, 2990736784u, + 601221559u, 2242044419u, 3024812190u, 306049834u, 3617246628u, 1911408144u, 1074125965u, 3866285881u, + 272279504u, 3058543716u, 2275784441u, 567459149u, 3832906691u, 1107462263u, 1944752874u, 3583875422u, + 2343980261u, 767641425u, 472473036u, 3126744696u, 2147051766u, 3649987394u, 3899029983u, 1309766251u, + 3092841090u, 506333494u, 801510315u, 2310084639u, 1276520081u, 3932237093u, 3683203000u, 2113813516u, + 3966292011u, 1243601823u, 2079834370u, 3716205238u, 405271608u, 3192979340u, 2411259153u, 701492901u, + 3750207052u, 2045810168u, 1209569125u, 4000285905u, 734575199u, 2378150379u, 3159862134u, 438345922u, + 2283203314u, 778166598u, 529136603u, 3120492655u, 2086260449u, 3660498261u, 3955679176u, 1303499900u, + 3153699989u, 495890209u, 744928700u, 2316418568u, 1337360518u, 3921775410u, 3626602927u, 2120129051u, + 4022892092u, 1237286280u, 2018993941u, 3726666913u, 461853231u, 3186645403u, 2350400262u, 711936178u, + 3693557851u, 2052076527u, 1270360434u, 3989775046u, 677911624u, 2384402428u, 3220639073u, 427820757u, + 1202443118u, 3789347034u, 3493118535u, 1984154099u, 3018127229u, 362020041u, 612099668u, 2181885408u, + 1950653705u, 3526596285u, 3822816288u, 1168934804u, 2148251930u, 645706414u, 395618355u, 2984485767u, + 544559008u, 2248295444u, 3085590153u, 295523645u, 3560598451u, 1917673479u, 1134918298u, 3855773998u, + 328860103u, 3052210803u, 2214924526u, 577903450u, 3889505748u, 1101147744u, 1883911421u, 3594338121u, + 3424493451u, 1785369663u, 1535282850u, 4260726038u, 944946072u, 2653270060u, 2949491377u, 163225861u, + 4294103532u, 1501944408u, 1752023237u, 3457862513u, 196998655u, 2915761739u, 2619532502u, 978710370u, + 2881684293u, 229902577u, 1012666988u, 2586515928u, 1603020630u, 4193987810u, 3356702335u, 1852063179u, + 2553040162u, 1046169238u, 263412747u, 2848217023u, 1818454321u, 3390333573u, 4227627032u, 1569420204u, + 60859927u, 2782375331u, 2487203646u, 843627658u, 4159668740u, 1368951216u, 1617990445u, 3322386585u, + 810543216u, 2520310724u, 2815490393u, 27783917u, 3288386659u, 1652017111u, 1402985802u, 4125677310u, + 1685994201u, 3255382381u, 4091620336u, 1435902020u, 2419138250u, 910562686u, 128847843u, 2715354199u, + 1469150398u, 4058414858u, 3222168983u, 1719234083u, 2749255853u, 94984985u, 876691844u, 2453031472u, + }, { + 0u, 3433693342u, 1109723005u, 2391738339u, 2219446010u, 1222643300u, 3329165703u, 180685081u, + 3555007413u, 525277995u, 2445286600u, 1567235158u, 1471092047u, 2600801745u, 361370162u, 3642757804u, + 2092642603u, 2953916853u, 1050555990u, 4063508168u, 4176560081u, 878395215u, 3134470316u, 1987983410u, + 2942184094u, 1676945920u, 3984272867u, 567356797u, 722740324u, 3887998202u, 1764827929u, 2778407815u, + 4185285206u, 903635656u, 3142804779u, 2012833205u, 2101111980u, 2979425330u, 1058630609u, 4088621903u, + 714308067u, 3862526333u, 1756790430u, 2753330688u, 2933487385u, 1651734407u, 3975966820u, 542535930u, + 2244825981u, 1231508451u, 3353891840u, 188896414u, 25648519u, 3442302233u, 1134713594u, 2399689316u, + 1445480648u, 2592229462u, 336416693u, 3634843435u, 3529655858u, 516441772u, 2420588879u, 1559052753u, + 698204909u, 3845636723u, 1807271312u, 2803025166u, 2916600855u, 1635634313u, 4025666410u, 593021940u, + 4202223960u, 919787974u, 3093159461u, 1962401467u, 2117261218u, 2996361020u, 1008193759u, 4038971457u, + 1428616134u, 2576151384u, 386135227u, 3685348389u, 3513580860u, 499580322u, 2471098945u, 1608776415u, + 2260985971u, 1248454893u, 3303468814u, 139259792u, 42591881u, 3458459159u, 1085071860u, 2349261162u, + 3505103035u, 474062885u, 2463016902u, 1583654744u, 1419882049u, 2550902495u, 377792828u, 3660491170u, + 51297038u, 3483679632u, 1093385331u, 2374089965u, 2269427188u, 1273935210u, 3311514249u, 164344343u, + 2890961296u, 1627033870u, 4000683757u, 585078387u, 672833386u, 3836780532u, 1782552599u, 2794821769u, + 2142603813u, 3005188795u, 1032883544u, 4047146438u, 4227826911u, 928351297u, 3118105506u, 1970307900u, + 1396409818u, 2677114180u, 287212199u, 3719594553u, 3614542624u, 467372990u, 2505346141u, 1509854403u, + 2162073199u, 1282711281u, 3271268626u, 240228748u, 76845205u, 3359543307u, 1186043880u, 2317064054u, + 796964081u, 3811226735u, 1839575948u, 2702160658u, 2882189835u, 1734392469u, 3924802934u, 625327592u, + 4234522436u, 818917338u, 3191908409u, 1927981223u, 2016387518u, 3028656416u, 973776579u, 4137723485u, + 2857232268u, 1726474002u, 3899187441u, 616751215u, 772270454u, 3803048424u, 1814228491u, 2693328533u, + 2041117753u, 3036871847u, 999160644u, 4146592730u, 4259508931u, 826864221u, 3217552830u, 1936586016u, + 3606501031u, 442291769u, 2496909786u, 1484378436u, 1388107869u, 2652297411u, 278519584u, 3694387134u, + 85183762u, 3384397196u, 1194773103u, 2342308593u, 2170143720u, 1307820918u, 3279733909u, 265733131u, + 2057717559u, 3054258089u, 948125770u, 4096344276u, 4276898253u, 843467091u, 3167309488u, 1885556270u, + 2839764098u, 1709792284u, 3949353983u, 667704161u, 755585656u, 3785577190u, 1865176325u, 2743489947u, + 102594076u, 3401021058u, 1144549729u, 2291298815u, 2186770662u, 1325234296u, 3228729243u, 215514885u, + 3589828009u, 424832311u, 2547870420u, 1534552650u, 1370645331u, 2635621325u, 328688686u, 3745342640u, + 2211456353u, 1333405183u, 3254067740u, 224338562u, 127544219u, 3408931589u, 1170156774u, 2299866232u, + 1345666772u, 2627681866u, 303053225u, 3736746295u, 3565105198u, 416624816u, 2522494803u, 1525692365u, + 4285207626u, 868291796u, 3176010551u, 1910772649u, 2065767088u, 3079346734u, 956571085u, 4121828691u, + 747507711u, 3760459617u, 1856702594u, 2717976604u, 2831417605u, 1684930971u, 3940615800u, 642451174u, + }, + { + 0u, 393942083u, 787884166u, 965557445u, 1575768332u, 1251427663u, 1931114890u, 1684106697u, + 3151536664u, 2896410203u, 2502855326u, 2186649309u, 3862229780u, 4048545623u, 3368213394u, 3753496529u, + 2898281073u, 3149616690u, 2184604407u, 2504883892u, 4046197629u, 3864463166u, 3755621371u, 3366006712u, + 387506281u, 6550570u, 971950319u, 781573292u, 1257550181u, 1569695014u, 1677892067u, 1937345952u, + 2196865699u, 2508887776u, 2886183461u, 3145514598u, 3743273903u, 3362179052u, 4058774313u, 3868258154u, + 958996667u, 777139448u, 400492605u, 10755198u, 1690661303u, 1941857780u, 1244879153u, 1565019506u, + 775012562u, 961205393u, 13101140u, 398261271u, 1943900638u, 1688634781u, 1563146584u, 1246801179u, + 2515100362u, 2190636681u, 3139390028u, 2892258831u, 3355784134u, 3749586821u, 3874691904u, 4052225795u, + 3734110983u, 3387496260u, 4033096577u, 3877584834u, 2206093835u, 2483373640u, 2911402637u, 3136515790u, + 1699389727u, 1915860316u, 1270647193u, 1556585946u, 950464531u, 803071056u, 374397077u, 19647702u, + 1917993334u, 1697207605u, 1554278896u, 1272937907u, 800985210u, 952435769u, 21510396u, 372452543u, + 3381322606u, 3740399405u, 3883715560u, 4027047851u, 2489758306u, 2199758369u, 3130039012u, 2917895847u, + 1550025124u, 1259902439u, 1922410786u, 1710144865u, 26202280u, 385139947u, 796522542u, 939715693u, + 3887801276u, 4039129087u, 3377269562u, 3728088953u, 3126293168u, 2905368307u, 2493602358u, 2212122229u, + 4037264341u, 3889747862u, 3730172755u, 3375300368u, 2907673305u, 3124004506u, 2209987167u, 2495786524u, + 1266377165u, 1543533966u, 1703758155u, 1928748296u, 379007169u, 32253058u, 945887303u, 790236164u, + 1716846671u, 1898845196u, 1218652361u, 1608006794u, 1002000707u, 750929152u, 357530053u, 36990342u, + 3717046871u, 3405166100u, 4084959953u, 3825245842u, 2153902939u, 2535122712u, 2929187805u, 3119304606u, + 3398779454u, 3723384445u, 3831720632u, 4078468859u, 2541294386u, 2147616625u, 3113171892u, 2935238647u, + 1900929062u, 1714877541u, 1606142112u, 1220599011u, 748794154u, 1004184937u, 39295404u, 355241455u, + 3835986668u, 4091516591u, 3394415210u, 3710500393u, 3108557792u, 2922629027u, 2545875814u, 2160455461u, + 1601970420u, 1208431799u, 1904871538u, 1727077425u, 43020792u, 367748539u, 744905086u, 991776061u, + 1214562461u, 1595921630u, 1720903707u, 1911159896u, 361271697u, 49513938u, 998160663u, 738569556u, + 4089209477u, 3838277318u, 3712633347u, 3392233024u, 2924491657u, 3106613194u, 2158369551u, 2547846988u, + 3100050248u, 2948339467u, 2519804878u, 2169126797u, 3844821572u, 4065347079u, 3420289730u, 3701894785u, + 52404560u, 342144275u, 770279894u, 982687125u, 1593045084u, 1233708063u, 1879431386u, 1736363161u, + 336019769u, 58479994u, 988899775u, 764050940u, 1240141877u, 1586496630u, 1729968307u, 1885744368u, + 2950685473u, 3097818978u, 2166999975u, 2522013668u, 4063474221u, 3846743662u, 3703937707u, 3418263272u, + 976650731u, 760059304u, 348170605u, 62635310u, 1742393575u, 1889649828u, 1227683937u, 1582820386u, + 2179867635u, 2526361520u, 2937588597u, 3093503798u, 3691148031u, 3413731004u, 4076100217u, 3851374138u, + 2532754330u, 2173556697u, 3087067932u, 2944139103u, 3407516310u, 3697379029u, 3857496592u, 4070026835u, + 758014338u, 978679233u, 64506116u, 346250567u, 1891774606u, 1740186829u, 1580472328u, 1229917259u, + }, { + 0u, 4022496062u, 83218493u, 3946298115u, 166436986u, 3861498692u, 220098631u, 3806075769u, + 332873972u, 4229245898u, 388141257u, 4175494135u, 440197262u, 4127099824u, 516501683u, 4044053389u, + 665747944u, 3362581206u, 593187285u, 3432594155u, 776282514u, 3246869164u, 716239279u, 3312622225u, + 880394524u, 3686509090u, 814485793u, 3746462239u, 1033003366u, 3528460888u, 963096923u, 3601193573u, + 1331495888u, 2694801646u, 1269355501u, 2758457555u, 1186374570u, 2843003028u, 1111716759u, 2910918825u, + 1552565028u, 3007850522u, 1484755737u, 3082680359u, 1432478558u, 3131279456u, 1368666979u, 3193329757u, + 1760789048u, 2268195078u, 1812353541u, 2210675003u, 1628971586u, 2396670332u, 1710092927u, 2318375233u, + 2066006732u, 2498144754u, 2144408305u, 2417195471u, 1926193846u, 2634877320u, 1983558283u, 2583222709u, + 2662991776u, 1903717534u, 2588923805u, 1972223139u, 2538711002u, 2022952164u, 2477029351u, 2087066841u, + 2372749140u, 1655647338u, 2308478825u, 1717238871u, 2223433518u, 1799654416u, 2155034387u, 1873894445u, + 3105130056u, 1456926070u, 3185661557u, 1378041163u, 2969511474u, 1597852940u, 3020617231u, 1539874097u, + 2864957116u, 1157737858u, 2922780289u, 1106542015u, 2737333958u, 1290407416u, 2816325371u, 1210047941u, + 3521578096u, 1042640718u, 3574781005u, 986759027u, 3624707082u, 936300340u, 3707335735u, 859512585u, + 3257943172u, 770846650u, 3334837433u, 688390023u, 3420185854u, 605654976u, 3475911875u, 552361981u, + 4132013464u, 428600998u, 4072428965u, 494812827u, 4288816610u, 274747100u, 4216845791u, 345349857u, + 3852387692u, 173846098u, 3781891409u, 245988975u, 3967116566u, 62328360u, 3900749099u, 121822741u, + 3859089665u, 164061759u, 3807435068u, 221426178u, 4025395579u, 2933317u, 3944446278u, 81334904u, + 4124199413u, 437265099u, 4045904328u, 518386422u, 4231653775u, 335250097u, 4174133682u, 386814604u, + 3249244393u, 778691543u, 3311294676u, 714879978u, 3359647891u, 662848429u, 3434477742u, 595039120u, + 3531393053u, 1035903779u, 3599308832u, 961245982u, 3684132967u, 877986649u, 3747788890u, 815846244u, + 2841119441u, 1184522735u, 2913852140u, 1114616274u, 2696129195u, 1332855189u, 2756082326u, 1266946472u, + 3129952805u, 1431118107u, 3195705880u, 1371074854u, 3009735263u, 1554415969u, 3079748194u, 1481855324u, + 2398522169u, 1630855175u, 2315475716u, 1707159610u, 2266835779u, 1759461501u, 2213084030u, 1814728768u, + 2636237773u, 1927520499u, 2580814832u, 1981182158u, 2496293815u, 2064121993u, 2420095882u, 2147340468u, + 2025787041u, 2541577631u, 2085281436u, 2475210146u, 1901375195u, 2660681189u, 1973518054u, 2590184920u, + 1801997909u, 2225743211u, 1872600680u, 2153772374u, 1652813359u, 2369881361u, 1719025170u, 2310296876u, + 1594986313u, 2966676599u, 1541693300u, 3022402634u, 1459236659u, 3107472397u, 1376780046u, 3184366640u, + 1288097725u, 2734990467u, 1211309952u, 2817619134u, 1160605639u, 2867791097u, 1104723962u, 2920993988u, + 937561457u, 3626001999u, 857201996u, 3704993394u, 1040821515u, 3519792693u, 989625654u, 3577615880u, + 607473029u, 3421972155u, 549494200u, 3473077894u, 769584639u, 3256649409u, 690699714u, 3337180924u, + 273452185u, 4287555495u, 347692196u, 4219156378u, 430386403u, 4133832669u, 491977950u, 4069562336u, + 60542061u, 3965298515u, 124656720u, 3903616878u, 175139863u, 3853649705u, 243645482u, 3779581716u, + }, { + 0u, 3247366080u, 1483520449u, 2581751297u, 2967040898u, 1901571138u, 3904227907u, 691737987u, + 3133399365u, 2068659845u, 3803142276u, 589399876u, 169513671u, 3415493895u, 1383475974u, 2482566342u, + 2935407819u, 1870142219u, 4137319690u, 924099274u, 506443593u, 3751897225u, 1178799752u, 2278412616u, + 339027342u, 3585866318u, 1280941135u, 2379694991u, 2766951948u, 1700956620u, 4236308429u, 1024339981u, + 2258407383u, 1192382487u, 3740284438u, 528411094u, 910556245u, 4157285269u, 1848198548u, 2946996820u, + 1012887186u, 4258378066u, 1681119059u, 2780629139u, 2357599504u, 1292419792u, 3572147409u, 358906641u, + 678054684u, 3924071644u, 1879503581u, 2978491677u, 2561882270u, 1497229150u, 3235873119u, 22109855u, + 2460592729u, 1395094937u, 3401913240u, 189516888u, 577821147u, 3825075739u, 2048679962u, 3146956762u, + 3595049455u, 398902831u, 2384764974u, 1336573934u, 1720805997u, 2803873197u, 1056822188u, 4285729900u, + 1821112490u, 2902796138u, 887570795u, 4117339819u, 3696397096u, 500978920u, 2218668777u, 1169222953u, + 2025774372u, 3106931428u, 550659301u, 3780950821u, 3362238118u, 166293862u, 2416645991u, 1367722151u, + 3262987361u, 66315169u, 2584839584u, 1537170016u, 1923370979u, 3005911075u, 717813282u, 3947244002u, + 1356109368u, 2438613496u, 146288633u, 3375820857u, 3759007162u, 562248314u, 3093388411u, 2045739963u, + 3927406461u, 731490493u, 2994458300u, 1945440636u, 1523451135u, 2604718911u, 44219710u, 3274466046u, + 4263662323u, 1068272947u, 2790189874u, 1740649714u, 1325080945u, 2406874801u, 379033776u, 3608758128u, + 1155642294u, 2238671990u, 479005303u, 3708016055u, 4097359924u, 901128180u, 2891217397u, 1843045941u, + 2011248031u, 3060787807u, 797805662u, 3993195422u, 3342353949u, 112630237u, 2673147868u, 1591353372u, + 3441611994u, 212601626u, 2504944923u, 1421914843u, 2113644376u, 3161815192u, 630660761u, 3826893145u, + 3642224980u, 412692116u, 2172340373u, 1089836885u, 1775141590u, 2822790422u, 832715543u, 4029474007u, + 1674842129u, 2723860433u, 1001957840u, 4197873168u, 3540870035u, 310623315u, 2338445906u, 1257178514u, + 4051548744u, 821257608u, 2836464521u, 1755307081u, 1101318602u, 2150241802u, 432566283u, 3628511179u, + 1270766349u, 2318435533u, 332587724u, 3529260300u, 4217841807u, 988411727u, 2735444302u, 1652903566u, + 1602977411u, 2651169091u, 132630338u, 3328776322u, 4015131905u, 786223809u, 3074340032u, 1991273216u, + 3846741958u, 616972294u, 3173262855u, 2091579847u, 1435626564u, 2485072772u, 234706309u, 3430124101u, + 2712218736u, 1613231024u, 4190475697u, 944458353u, 292577266u, 3506339890u, 1226630707u, 2291284467u, + 459984181u, 3672380149u, 1124496628u, 2189994804u, 2880683703u, 1782407543u, 4091479926u, 844224694u, + 257943739u, 3469817723u, 1462980986u, 2529005242u, 3213269817u, 2114471161u, 3890881272u, 644152632u, + 3046902270u, 1947391550u, 3991973951u, 746483711u, 88439420u, 3301680572u, 1563018173u, 2628197501u, + 657826727u, 3871046759u, 2136545894u, 3201811878u, 2548879397u, 1449267173u, 3481299428u, 235845156u, + 2650161890u, 1551408418u, 3315268387u, 68429027u, 758067552u, 3970035360u, 1967360161u, 3033356129u, + 2311284588u, 1213053100u, 3517963949u, 270598509u, 958010606u, 4170500910u, 1635167535u, 2700636911u, + 855672361u, 4069415401u, 1802256360u, 2866995240u, 2212099499u, 1113008747u, 3686091882u, 440112042u, + }, { + 0u, 2611301487u, 3963330207u, 2006897392u, 50740095u, 2560849680u, 4013794784u, 1956178319u, + 101480190u, 2645113489u, 3929532513u, 1905435662u, 84561281u, 2662269422u, 3912356638u, 1922342769u, + 202960380u, 2545787283u, 3760419683u, 2072395532u, 253679235u, 2495322860u, 3810871324u, 2021655667u, + 169122562u, 2444351341u, 3861841309u, 2106214898u, 152215677u, 2461527058u, 3844685538u, 2123133581u, + 405920760u, 2207553431u, 4094313831u, 1873742088u, 456646791u, 2157096168u, 4144791064u, 1823027831u, + 507358470u, 2241388905u, 4060492697u, 1772322806u, 490444409u, 2258557462u, 4043311334u, 1789215881u, + 338245124u, 2408348267u, 4161972379u, 1672996084u, 388959611u, 2357870868u, 4212429796u, 1622269835u, + 304431354u, 2306870421u, 4263435877u, 1706791434u, 287538053u, 2324051946u, 4246267162u, 1723705717u, + 811841520u, 2881944479u, 3696765295u, 1207788800u, 862293135u, 2831204576u, 3747484176u, 1157324415u, + 913293582u, 2915732833u, 3662962577u, 1106318334u, 896137841u, 2932651550u, 3646055662u, 1123494017u, + 1014716940u, 2816349795u, 3493905555u, 1273334012u, 1065181555u, 2765630748u, 3544645612u, 1222882179u, + 980888818u, 2714919069u, 3595350637u, 1307180546u, 963712909u, 2731826146u, 3578431762u, 1324336509u, + 676490248u, 3019317351u, 3295277719u, 1607253752u, 726947703u, 2968591128u, 3345992168u, 1556776327u, + 777919222u, 3053147801u, 3261432937u, 1505806342u, 760750473u, 3070062054u, 3244539670u, 1522987897u, + 608862708u, 3220163995u, 3362856811u, 1406423812u, 659339915u, 3169449700u, 3413582868u, 1355966587u, + 575076106u, 3118709605u, 3464325525u, 1440228858u, 557894773u, 3135602714u, 3447411434u, 1457397381u, + 1623683040u, 4217512847u, 2365387135u, 391757072u, 1673614495u, 4167309552u, 2415577600u, 341804655u, + 1724586270u, 4251866481u, 2331019137u, 290835438u, 1707942497u, 4268256782u, 2314648830u, 307490961u, + 1826587164u, 4152020595u, 2162433155u, 457265388u, 1876539747u, 4101829900u, 2212636668u, 407333779u, + 1792275682u, 4051089549u, 2263378557u, 491595282u, 1775619997u, 4067460082u, 2246988034u, 508239213u, + 2029433880u, 3813931127u, 2496473735u, 258500328u, 2079362919u, 3763716872u, 2546668024u, 208559511u, + 2130363110u, 3848244873u, 2462145657u, 157552662u, 2113730969u, 3864638966u, 2445764358u, 174205801u, + 1961777636u, 4014675339u, 2564147067u, 57707284u, 2011718299u, 3964481268u, 2614361092u, 7778411u, + 1927425818u, 3913769845u, 2665066885u, 92077546u, 1910772837u, 3930150922u, 2648673018u, 108709525u, + 1352980496u, 3405878399u, 3164554895u, 658115296u, 1403183983u, 3355946752u, 3214507504u, 607924639u, + 1453895406u, 3440239233u, 3130208369u, 557218846u, 1437504913u, 3456883198u, 3113552654u, 573589345u, + 1555838444u, 3340335491u, 2961681267u, 723707676u, 1606028947u, 3290383100u, 3011612684u, 673504355u, + 1521500946u, 3239382909u, 3062619533u, 758026722u, 1505130605u, 3256038402u, 3045975794u, 774417053u, + 1217725416u, 3543158663u, 2762906999u, 1057739032u, 1267939479u, 3493229816u, 2812847624u, 1007544935u, + 1318679830u, 3577493881u, 2728586121u, 956803046u, 1302285929u, 3594125830u, 2711933174u, 973184153u, + 1150152212u, 3743982203u, 2830528651u, 856898788u, 1200346475u, 3694041348u, 2880457716u, 806684571u, + 1115789546u, 3643069573u, 2931426933u, 891243034u, 1099408277u, 3659722746u, 2914794762u, 907637093u, + }, { + 0u, 3717650821u, 1616688459u, 3184159950u, 3233376918u, 489665299u, 2699419613u, 2104690264u, + 1510200173u, 2274691816u, 979330598u, 3888758691u, 2595928571u, 1194090622u, 4209380528u, 661706037u, + 3020400346u, 1771143007u, 3562738577u, 164481556u, 1958661196u, 2837976521u, 350386439u, 3379863682u, + 3993269687u, 865250354u, 2388181244u, 1406015865u, 784146209u, 4079732388u, 1323412074u, 2474079215u, + 3011398645u, 1860735600u, 3542286014u, 246687547u, 1942430051u, 2924607718u, 328963112u, 3456978349u, + 3917322392u, 887832861u, 2300653011u, 1421341782u, 700772878u, 4099025803u, 1234716485u, 2483986112u, + 125431087u, 3673109674u, 1730500708u, 3132326369u, 3351283641u, 441867836u, 2812031730u, 2047535991u, + 1568292418u, 2163009479u, 1025936137u, 3769651852u, 2646824148u, 1079348561u, 4255113631u, 537475098u, + 3180171691u, 1612400686u, 3721471200u, 4717925u, 2100624189u, 2694980280u, 493375094u, 3237910515u, + 3884860102u, 974691139u, 2278750093u, 1514417672u, 657926224u, 4204917205u, 1198234907u, 2600289438u, + 160053105u, 3558665972u, 1775665722u, 3024116671u, 3375586791u, 346391650u, 2842683564u, 1962488105u, + 1401545756u, 2384412057u, 869618007u, 3997403346u, 2469432970u, 1319524111u, 4083956673u, 788193860u, + 250862174u, 3546612699u, 1856990997u, 3006903952u, 3461001416u, 333211981u, 2920678787u, 1937824774u, + 1425017139u, 2305216694u, 883735672u, 3912918525u, 2487837605u, 1239398944u, 4095071982u, 696455019u, + 3136584836u, 1734518017u, 3668494799u, 121507914u, 2051872274u, 2816200599u, 437363545u, 3347544796u, + 3774328809u, 1029797484u, 2158697122u, 1564328743u, 542033279u, 4258798842u, 1074950196u, 2642717105u, + 2691310871u, 2113731730u, 3224801372u, 497043929u, 1624461185u, 3175454212u, 9435850u, 3709412175u, + 4201248378u, 671035391u, 2587181873u, 1201904308u, 986750188u, 3880142185u, 1519135143u, 2266689570u, + 342721485u, 3388693064u, 1949382278u, 2846355203u, 3570723163u, 155332830u, 3028835344u, 1763607957u, + 1315852448u, 2482538789u, 775087595u, 4087626862u, 2396469814u, 1396827059u, 4002123645u, 857560824u, + 320106210u, 3464673127u, 1934154665u, 2933785132u, 3551331444u, 238804465u, 3018961215u, 1852270778u, + 1226292623u, 2491507722u, 692783300u, 4108177729u, 2309936921u, 1412959900u, 3924976210u, 879016919u, + 2803091512u, 2055541181u, 3343875443u, 450471158u, 1739236014u, 3124525867u, 133568485u, 3663777376u, + 4245691221u, 545702608u, 2639048222u, 1088059291u, 1034514883u, 3762268230u, 1576387720u, 2153979149u, + 501724348u, 3228659001u, 2109407735u, 2687359090u, 3713981994u, 13109167u, 3171052385u, 1620357860u, + 1206151121u, 2591211092u, 666423962u, 4197321503u, 2271022407u, 1523307714u, 3875649548u, 982999433u, + 2850034278u, 1953942499u, 3384583981u, 338329256u, 1767471344u, 3033506165u, 151375291u, 3566408766u, + 4091789579u, 779425934u, 2478797888u, 1311354309u, 861580189u, 4006375960u, 1392910038u, 2391852883u, + 2929327945u, 1930372812u, 3469036034u, 324244359u, 1847629279u, 3015068762u, 243015828u, 3555391761u, + 4103744548u, 688715169u, 2496043375u, 1229996266u, 874727090u, 3920994103u, 1417671673u, 2313759356u, + 446585235u, 3339223062u, 2059594968u, 2807313757u, 3660002053u, 129100416u, 3128657486u, 1743609803u, + 1084066558u, 2634765179u, 549535669u, 4250396208u, 2149900392u, 1571961325u, 3765982499u, 1039043750u, + }, { + 0u, 2635063670u, 3782132909u, 2086741467u, 430739227u, 2225303149u, 4173482934u, 1707977408u, + 861478454u, 2924937024u, 3526875803u, 1329085421u, 720736557u, 3086643291u, 3415954816u, 1452586230u, + 1722956908u, 4223524122u, 2279405761u, 450042295u, 2132718455u, 3792785921u, 2658170842u, 58693292u, + 1441473114u, 3370435372u, 3028674295u, 696911745u, 1279765825u, 3511176247u, 2905172460u, 807831706u, + 3445913816u, 1349228974u, 738901109u, 2969918723u, 3569940419u, 1237784245u, 900084590u, 2829701656u, + 4265436910u, 1664255896u, 525574723u, 2187084597u, 3885099509u, 2057177219u, 117386584u, 2616249390u, + 2882946228u, 920233410u, 1253605401u, 3619119471u, 2994391983u, 796207833u, 1393823490u, 3457937012u, + 2559531650u, 92322804u, 2044829231u, 3840835417u, 2166609305u, 472659183u, 1615663412u, 4249022530u, + 1102706673u, 3702920839u, 2698457948u, 1037619754u, 1477802218u, 3306854812u, 3111894087u, 611605809u, + 1927342535u, 4025419953u, 2475568490u, 243387420u, 1800169180u, 4131620778u, 2317525617u, 388842247u, + 655084445u, 3120835307u, 3328511792u, 1533734470u, 1051149446u, 2745738736u, 3754524715u, 1120297309u, + 340972971u, 2304586973u, 4114354438u, 1748234352u, 234773168u, 2431761350u, 3968900637u, 1906278251u, + 2363330345u, 299003487u, 1840466820u, 4038896370u, 2507210802u, 142532932u, 1948239007u, 3910149609u, + 3213136159u, 579563625u, 1592415666u, 3286611140u, 2787646980u, 992477042u, 1195825833u, 3662232543u, + 3933188933u, 2002801203u, 184645608u, 2517538462u, 4089658462u, 1858919720u, 313391347u, 2409765253u, + 3644239219u, 1144605701u, 945318366u, 2773977256u, 3231326824u, 1570095902u, 569697989u, 3170568115u, + 2205413346u, 511446676u, 1646078799u, 4279421497u, 2598330617u, 131105167u, 2075239508u, 3871229218u, + 2955604436u, 757403810u, 1363424633u, 3427521551u, 2844163791u, 881434553u, 1223211618u, 3588709140u, + 3854685070u, 2026779384u, 78583587u, 2577462869u, 4235025557u, 1633861091u, 486774840u, 2148301134u, + 3600338360u, 1268198606u, 938871061u, 2868504675u, 3476308643u, 1379640277u, 777684494u, 3008718712u, + 1310168890u, 3541595724u, 2943964055u, 846639841u, 1471879201u, 3400857943u, 3067468940u, 735723002u, + 2102298892u, 3762382970u, 2619362721u, 19901655u, 1692534295u, 4193118049u, 2240594618u, 411247564u, + 681945942u, 3047836192u, 3385552891u, 1422167693u, 822682701u, 2886124859u, 3496468704u, 1298661782u, + 469546336u, 2264093718u, 4203901389u, 1738379451u, 38812283u, 2673859341u, 3812556502u, 2117148576u, + 3268024339u, 1606809957u, 598006974u, 3198893512u, 3680933640u, 1181316734u, 973624229u, 2802299603u, + 4052944421u, 1822222163u, 285065864u, 2381456382u, 3896478014u, 1966106696u, 156323219u, 2489232613u, + 2759337087u, 964150537u, 1159127250u, 3625517476u, 3184831332u, 551242258u, 1555722185u, 3249901247u, + 2535537225u, 170842943u, 1984954084u, 3946848146u, 2391651666u, 327308324u, 1877176831u, 4075589769u, + 263086283u, 2460058045u, 4005602406u, 1942963472u, 369291216u, 2332888742u, 4151061373u, 1784924683u, + 1022852861u, 2717425547u, 3717839440u, 1083595558u, 626782694u, 3092517008u, 3291821387u, 1497027645u, + 1763466407u, 4094934481u, 2289211402u, 360544636u, 1890636732u, 3988730570u, 2447251217u, 215086695u, + 1514488465u, 3343557607u, 3140191804u, 639919946u, 1139395978u, 3739626748u, 2726758695u, 1065936977u, + }, { + 0u, 3120290792u, 2827399569u, 293431929u, 2323408227u, 864534155u, 586863858u, 2600537882u, + 3481914503u, 1987188591u, 1729068310u, 3740575486u, 1173727716u, 4228805132u, 3983743093u, 1418249117u, + 1147313999u, 4254680231u, 3974377182u, 1428157750u, 3458136620u, 2011505092u, 1721256893u, 3747844181u, + 2347455432u, 839944224u, 594403929u, 2593536433u, 26687147u, 3094146371u, 2836498234u, 283794642u, + 2294627998u, 826205558u, 541298447u, 2578994407u, 45702141u, 3141697557u, 2856315500u, 331624836u, + 1196225049u, 4273416689u, 4023010184u, 1446090848u, 3442513786u, 1959480466u, 1706436331u, 3696098563u, + 3433538001u, 1968994873u, 1679888448u, 3722103720u, 1188807858u, 4280295258u, 3999102243u, 1470541515u, + 53374294u, 3134568126u, 2879970503u, 307431215u, 2303854645u, 816436189u, 567589284u, 2553242188u, + 3405478781u, 1929420949u, 1652411116u, 3682996484u, 1082596894u, 4185703926u, 3892424591u, 1375368295u, + 91404282u, 3163122706u, 2918450795u, 336584067u, 2400113305u, 922028401u, 663249672u, 2658384096u, + 2392450098u, 929185754u, 639587747u, 2682555979u, 82149713u, 3172883129u, 2892181696u, 362343208u, + 1091578037u, 4176212829u, 3918960932u, 1349337804u, 3412872662u, 1922537022u, 1676344391u, 3658557359u, + 1111377379u, 4224032267u, 3937989746u, 1396912026u, 3359776896u, 1908013928u, 1623494929u, 3644803833u, + 2377615716u, 877417100u, 623982837u, 2630542109u, 130804743u, 3190831087u, 2941083030u, 381060734u, + 106748588u, 3215393092u, 2933549885u, 388083925u, 2350956495u, 903570471u, 614862430u, 2640172470u, + 3386185259u, 1882115523u, 1632872378u, 3634920530u, 1135178568u, 4199721120u, 3945775833u, 1389631793u, + 1317531835u, 4152109907u, 3858841898u, 1610259138u, 3304822232u, 2097172016u, 1820140617u, 3582394273u, + 2165193788u, 955639764u, 696815021u, 2423477829u, 192043359u, 2995356343u, 2750736590u, 437203750u, + 182808564u, 3005133852u, 2724453989u, 462947725u, 2157513367u, 962777471u, 673168134u, 2447663342u, + 3312231283u, 2090301595u, 1844056802u, 3557935370u, 1326499344u, 4142603768u, 3885397889u, 1584245865u, + 3326266917u, 2142836173u, 1858371508u, 3611272284u, 1279175494u, 4123357358u, 3837270743u, 1564721471u, + 164299426u, 2955991370u, 2706223923u, 414607579u, 2209834945u, 978107433u, 724686416u, 2462715320u, + 2183156074u, 1004243586u, 715579643u, 2472360723u, 140260361u, 2980573153u, 2698675608u, 421617264u, + 1302961645u, 4099032581u, 3845074044u, 1557460884u, 3352688782u, 2116952934u, 1867729183u, 3601371895u, + 2222754758u, 1032278062u, 754596439u, 2499928511u, 234942117u, 3086693709u, 2793824052u, 528319708u, + 1274365761u, 4061043881u, 3816027856u, 1518873912u, 3246989858u, 2020800970u, 1762628531u, 3505670235u, + 3223196809u, 2045103969u, 1754834200u, 3512958704u, 1247965674u, 4086934018u, 3806642299u, 1528765331u, + 261609486u, 3060532198u, 2802936223u, 518697591u, 2246819181u, 1007707781u, 762121468u, 2492913428u, + 213497176u, 3041029808u, 2755593417u, 499441441u, 2261110843u, 1061030867u, 776167850u, 2545465922u, + 3274734047u, 2060165687u, 1807140942u, 3528266662u, 1229724860u, 4038575956u, 3788156205u, 1479636677u, + 1222322711u, 4045468159u, 3764231046u, 1504067694u, 3265744756u, 2069664924u, 1780612837u, 3554288909u, + 2270357136u, 1051278712u, 802445057u, 2519698665u, 221152243u, 3033880603u, 2779263586u, 475261322u, + }, { + 0u, 2926088593u, 2275419491u, 701019378u, 3560000647u, 2052709654u, 1402038756u, 4261017717u, + 1930665807u, 3715829470u, 4105419308u, 1524313021u, 2804077512u, 155861593u, 545453739u, 2397726522u, + 3861331614u, 1213181711u, 1636244477u, 3488582252u, 840331801u, 2625561480u, 3048626042u, 467584747u, + 2503254481u, 995897408u, 311723186u, 3170637091u, 1090907478u, 4016929991u, 3332753461u, 1758288292u, + 390036349u, 3109546732u, 2426363422u, 1056427919u, 3272488954u, 1835443819u, 1152258713u, 3938878216u, + 1680663602u, 3393484195u, 3817652561u, 1306808512u, 2954733749u, 510998820u, 935169494u, 2580880455u, + 4044899811u, 1601229938u, 1991794816u, 3637571857u, 623446372u, 2336332021u, 2726898695u, 216120726u, + 2181814956u, 744704829u, 95158223u, 2881711710u, 1446680107u, 4166125498u, 3516576584u, 2146575065u, + 780072698u, 2148951915u, 2849952665u, 129384968u, 4199529085u, 1411853292u, 2112855838u, 3548843663u, + 1567451573u, 4077254692u, 3670887638u, 1957027143u, 2304517426u, 657765539u, 251396177u, 2694091200u, + 3361327204u, 1714510325u, 1341779207u, 3784408214u, 476611811u, 2986349938u, 2613617024u, 899690513u, + 3142211371u, 354600634u, 1021997640u, 2458051545u, 1870338988u, 3239283261u, 3906682575u, 1186180958u, + 960597383u, 2536053782u, 3202459876u, 277428597u, 3983589632u, 1125666961u, 1792074851u, 3300423154u, + 1246892744u, 3829039961u, 3455203243u, 1671079482u, 2657312335u, 806080478u, 432241452u, 3081497277u, + 3748049689u, 1896751752u, 1489409658u, 4138600427u, 190316446u, 2772397583u, 2365053693u, 580864876u, + 2893360214u, 35503559u, 735381813u, 2243795108u, 2017747153u, 3593269568u, 4293150130u, 1368183843u, + 1560145396u, 4069882981u, 3680356503u, 1966430470u, 2295112051u, 648294626u, 258769936u, 2701399425u, + 804156091u, 2173100842u, 2823706584u, 103204425u, 4225711676u, 1438101421u, 2088704863u, 3524758222u, + 3134903146u, 347226875u, 1031468553u, 2467456920u, 1860935661u, 3229814396u, 3914054286u, 1193487135u, + 3385412645u, 1738661300u, 1315531078u, 3758225623u, 502792354u, 3012596019u, 2589468097u, 875607120u, + 1271043721u, 3853125400u, 3429020650u, 1644831355u, 2683558414u, 832261023u, 408158061u, 3057348348u, + 953223622u, 2528745559u, 3211865253u, 286899508u, 3974120769u, 1116263632u, 1799381026u, 3307794867u, + 2917509143u, 59586950u, 709201268u, 2217549029u, 2043995280u, 3619452161u, 4269064691u, 1344032866u, + 3740677976u, 1889445577u, 1498812987u, 4148069290u, 180845535u, 2762992206u, 2372361916u, 588238637u, + 1921194766u, 3706423967u, 4112727661u, 1531686908u, 2796705673u, 148555288u, 554857194u, 2407195515u, + 26248257u, 2952271312u, 2251333922u, 676868275u, 3584149702u, 2076793175u, 1375858085u, 4234771508u, + 2493785488u, 986493953u, 319029491u, 3178008930u, 1083533591u, 4009621638u, 3342158964u, 1767759333u, + 3887577823u, 1239362382u, 1612160956u, 3464433197u, 864482904u, 2649647049u, 3022443323u, 441336490u, + 1706844275u, 3419730402u, 3793503504u, 1282724993u, 2978819316u, 535149925u, 908921239u, 2554697734u, + 380632892u, 3100077741u, 2433735263u, 1063734222u, 3265180603u, 1828069930u, 1161729752u, 3948283721u, + 2207997677u, 770953084u, 71007118u, 2857626143u, 1470763626u, 4190274555u, 3490330377u, 2120394392u, + 4035494306u, 1591758899u, 1999168705u, 3644880208u, 616140069u, 2328960180u, 2736367686u, 225524183u, + }, }; -#define WUFFS_GIF__QUIRKS_BASE 1041635328 - -#define WUFFS_GIF__QUIRKS_COUNT 7 - // ---------------- Private Initializer Prototypes // ---------------- Private Function Prototypes -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_decode_image_config( - wuffs_gif__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_tell_me_more( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_decode_frame_config( - wuffs_gif__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__skip_frame( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_decode_frame( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); - WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_gif__decoder__reset_gc( - wuffs_gif__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_up_to_id_part1( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_header( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_lsd( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_extension( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__skip_blocks( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_ae( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_gc( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_id_part0( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_id_part1( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__decode_id_part2( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); +wuffs_crc32__ieee_hasher__up( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x); WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__copy_to_image_buffer( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_pb, - wuffs_base__slice_u8 a_src); +static wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__up__choosy_default( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x); +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_gif__decoder__lzw_init( - wuffs_gif__decoder* self); +wuffs_crc32__ieee_hasher__up_arm_crc32( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_gif__decoder__lzw_read_from( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src); +wuffs_crc32__ieee_hasher__up_x86_sse42( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) // ---------------- VTables -const wuffs_base__image_decoder__func_ptrs -wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect), +const wuffs_base__hasher_u32__func_ptrs +wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = { + (uint32_t(*)(const void*))(&wuffs_crc32__ieee_hasher__checksum_u32), (uint64_t(*)(const void*, - uint32_t))(&wuffs_gif__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_gif__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_gif__decoder__restart_frame), + uint32_t))(&wuffs_crc32__ieee_hasher__get_quirk), (wuffs_base__status(*)(void*, uint32_t, - uint64_t))(&wuffs_gif__decoder__set_quirk), + uint64_t))(&wuffs_crc32__ieee_hasher__set_quirk), (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_gif__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len), + wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update), + (uint32_t(*)(void*, + wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32), }; // ---------------- Initializer Implementations wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_gif__decoder__initialize( - wuffs_gif__decoder* self, +wuffs_crc32__ieee_hasher__initialize( + wuffs_crc32__ieee_hasher* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options){ @@ -36681,23 +37083,25 @@ wuffs_gif__decoder__initialize( } } + self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default; + self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder); + self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = + wuffs_base__hasher_u32__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = + (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32); return wuffs_base__make_status(NULL); } -wuffs_gif__decoder* -wuffs_gif__decoder__alloc(void) { - wuffs_gif__decoder* x = - (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1)); +wuffs_crc32__ieee_hasher* +wuffs_crc32__ieee_hasher__alloc(void) { + wuffs_crc32__ieee_hasher* x = + (wuffs_crc32__ieee_hasher*)(calloc(1, sizeof(wuffs_crc32__ieee_hasher))); if (!x) { return NULL; } - if (wuffs_gif__decoder__initialize( - x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + if (wuffs_crc32__ieee_hasher__initialize( + x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { free(x); return NULL; } @@ -36705,18 +37109,18 @@ wuffs_gif__decoder__alloc(void) { } size_t -sizeof__wuffs_gif__decoder(void) { - return sizeof(wuffs_gif__decoder); +sizeof__wuffs_crc32__ieee_hasher(void) { + return sizeof(wuffs_crc32__ieee_hasher); } // ---------------- Function Implementations -// -------- func gif.decoder.get_quirk +// -------- func crc32.ieee_hasher.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gif__decoder__get_quirk( - const wuffs_gif__decoder* self, +wuffs_crc32__ieee_hasher__get_quirk( + const wuffs_crc32__ieee_hasher* self, uint32_t a_key) { if (!self) { return 0; @@ -36726,25 +37130,15 @@ wuffs_gif__decoder__get_quirk( return 0; } - uint32_t v_key = 0; - - if (a_key >= 1041635328u) { - v_key = (a_key - 1041635328u); - if (v_key < 7u) { - if (self->private_impl.f_quirks[v_key]) { - return 1u; - } - } - } return 0u; } -// -------- func gif.decoder.set_quirk +// -------- func crc32.ieee_hasher.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__set_quirk( - wuffs_gif__decoder* self, +wuffs_crc32__ieee_hasher__set_quirk( + wuffs_crc32__ieee_hasher* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -36757,377 +37151,812 @@ wuffs_gif__decoder__set_quirk( : wuffs_base__error__initialize_not_called); } - if ((self->private_impl.f_call_sequence == 0u) && (a_key >= 1041635328u)) { - a_key -= 1041635328u; - if (a_key < 7u) { - self->private_impl.f_quirks[a_key] = (a_value > 0u); - return wuffs_base__make_status(NULL); - } - } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func gif.decoder.decode_image_config +// -------- func crc32.ieee_hasher.update WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__decode_image_config( - wuffs_gif__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__update( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return wuffs_base__make_empty_struct(); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + return wuffs_base__make_empty_struct(); } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_gif__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } - ok: - self->private_impl.p_decode_image_config[0] = 0; - goto exit; + if (self->private_impl.f_state == 0u) { + self->private_impl.choosy_up = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) + wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 : +#endif + self->private_impl.choosy_up); } + wuffs_crc32__ieee_hasher__up(self, a_x); + return wuffs_base__make_empty_struct(); +} - goto suspend; - suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; +// -------- func crc32.ieee_hasher.update_u32 - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_crc32__ieee_hasher__update_u32( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return 0; } - return status; + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return 0; + } + + wuffs_crc32__ieee_hasher__update(self, a_x); + return self->private_impl.f_state; } -// -------- func gif.decoder.do_decode_image_config +// -------- func crc32.ieee_hasher.up WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_decode_image_config( - wuffs_gif__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - bool v_ffio = false; +static wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__up( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { + return (*self->private_impl.choosy_up)(self, a_x); +} - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__up__choosy_default( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_s = 0; + wuffs_base__slice_u8 v_p = {0}; - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if ( ! self->private_impl.f_seen_header) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_gif__decoder__decode_header(self, a_src); - if (status.repr) { - goto suspend; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_gif__decoder__decode_lsd(self, a_src); - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_header = true; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src); - if (status.repr) { - goto suspend; - } - v_ffio = ! self->private_impl.f_gc_has_transparent_index; - if ( ! self->private_impl.f_quirks[2u]) { - v_ffio = (v_ffio && - (self->private_impl.f_frame_rect_x0 == 0u) && - (self->private_impl.f_frame_rect_y0 == 0u) && - (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) && - (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height)); - } else if (v_ffio) { - self->private_impl.f_black_color_u32_argb_premul = 4278190080u; - } - if (self->private_impl.f_background_color_u32_argb_premul == 77u) { - self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul; + v_s = (4294967295u ^ self->private_impl.f_state); + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 16; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32)); + while (v_p.ptr < i_end0_p) { + v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | + (((uint32_t)(v_p.ptr[1u])) << 8u) | + (((uint32_t)(v_p.ptr[2u])) << 16u) | + (((uint32_t)(v_p.ptr[3u])) << 24u)); + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ + WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ + WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ + WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ + WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ + WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ + WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ + WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ + WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ + WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ + WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ + WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ + WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ + WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ + WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ + WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); + v_p.ptr += 16; + v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | + (((uint32_t)(v_p.ptr[1u])) << 8u) | + (((uint32_t)(v_p.ptr[2u])) << 16u) | + (((uint32_t)(v_p.ptr[3u])) << 24u)); + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ + WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ + WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ + WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ + WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ + WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ + WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ + WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ + WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ + WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ + WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ + WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ + WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ + WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ + WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ + WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); + v_p.ptr += 16; } - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - 2198077448u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - v_ffio); + v_p.len = 16; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16)); + while (v_p.ptr < i_end1_p) { + v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) | + (((uint32_t)(v_p.ptr[1u])) << 8u) | + (((uint32_t)(v_p.ptr[2u])) << 16u) | + (((uint32_t)(v_p.ptr[3u])) << 24u)); + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^ + WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^ + WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^ + WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^ + WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^ + WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^ + WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^ + WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^ + WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^ + WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^ + WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^ + WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^ + WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^ + WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^ + WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^ + WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]); + v_p.ptr += 16; } - if (self->private_impl.f_call_sequence == 0u) { - self->private_impl.f_call_sequence = 32u; + v_p.len = 1; + const uint8_t* i_end2_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end2_p) { + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u)); + v_p.ptr += 1; } - - goto ok; - ok: - self->private_impl.p_do_decode_image_config[0] = 0; - goto exit; + v_p.len = 0; } - - goto suspend; - suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - return status; + self->private_impl.f_state = (4294967295u ^ v_s); + return wuffs_base__make_empty_struct(); } -// -------- func gif.decoder.set_report_metadata +// -------- func crc32.ieee_hasher.checksum_u32 WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_gif__decoder__set_report_metadata( - wuffs_gif__decoder* self, - uint32_t a_fourcc, - bool a_report) { +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_crc32__ieee_hasher__checksum_u32( + const wuffs_crc32__ieee_hasher* self) { if (!self) { - return wuffs_base__make_empty_struct(); + return 0; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - if (a_fourcc == 1229144912u) { - self->private_impl.f_report_metadata_iccp = a_report; - } else if (a_fourcc == 1481461792u) { - self->private_impl.f_report_metadata_xmp = a_report; + return self->private_impl.f_state; +} + +// ‼ WUFFS MULTI-FILE SECTION +arm_crc32 +// -------- func crc32.ieee_hasher.up_arm_crc32 + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__up_arm_crc32( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { + wuffs_base__slice_u8 v_p = {0}; + uint32_t v_s = 0; + + v_s = (4294967295u ^ self->private_impl.f_state); + while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { + v_s = __crc32b(v_s, a_x.ptr[0u]); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); + } + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 8; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128)); + while (v_p.ptr < i_end0_p) { + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + } + v_p.len = 8; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8)); + while (v_p.ptr < i_end1_p) { + v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr)); + v_p.ptr += 8; + } + v_p.len = 1; + const uint8_t* i_end2_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end2_p) { + v_s = __crc32b(v_s, v_p.ptr[0u]); + v_p.ptr += 1; + } + v_p.len = 0; } + self->private_impl.f_state = (4294967295u ^ v_s); return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_CRC32) +// ‼ WUFFS MULTI-FILE SECTION -arm_crc32 -// -------- func gif.decoder.tell_me_more +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func crc32.ieee_hasher.up_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__tell_me_more( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); +static wuffs_base__empty_struct +wuffs_crc32__ieee_hasher__up_x86_sse42( + wuffs_crc32__ieee_hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_s = 0; + __m128i v_kk = {0}; + __m128i v_x0 = {0}; + __m128i v_x1 = {0}; + __m128i v_x2 = {0}; + __m128i v_x3 = {0}; + __m128i v_x4 = {0}; + __m128i v_x5 = {0}; + __m128i v_x6 = {0}; + __m128i v_x7 = {0}; + __m128i v_y0 = {0}; + __m128i v_y1 = {0}; + __m128i v_y2 = {0}; + __m128i v_y3 = {0}; + __m128i v_y4 = {0}; + __m128i v_y5 = {0}; + __m128i v_y6 = {0}; + __m128i v_y7 = {0}; + + v_s = (4294967295u ^ self->private_impl.f_state); + while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); + if (((uint64_t)(a_x.len)) >= 128u) { + v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)); + v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); + v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)); + v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)); + v_x4 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u)); + v_x5 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u)); + v_x6 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u)); + v_x7 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u)); + v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(2433674945u), (int32_t)(0u), (int32_t)(872412467u)); + v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u); + while (((uint64_t)(a_x.len)) >= 128u) { + v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u)); + v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u)); + v_y1 = _mm_clmulepi64_si128(v_x1, v_kk, (int32_t)(0u)); + v_x1 = _mm_clmulepi64_si128(v_x1, v_kk, (int32_t)(17u)); + v_y2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(0u)); + v_x2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(17u)); + v_y3 = _mm_clmulepi64_si128(v_x3, v_kk, (int32_t)(0u)); + v_x3 = _mm_clmulepi64_si128(v_x3, v_kk, (int32_t)(17u)); + v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u)); + v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u)); + v_y5 = _mm_clmulepi64_si128(v_x5, v_kk, (int32_t)(0u)); + v_x5 = _mm_clmulepi64_si128(v_x5, v_kk, (int32_t)(17u)); + v_y6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(0u)); + v_x6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(17u)); + v_y7 = _mm_clmulepi64_si128(v_x7, v_kk, (int32_t)(0u)); + v_x7 = _mm_clmulepi64_si128(v_x7, v_kk, (int32_t)(17u)); + v_y0 = _mm_xor_si128(v_y0, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u))); + v_x0 = _mm_xor_si128(v_x0, v_y0); + v_y1 = _mm_xor_si128(v_y1, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u))); + v_x1 = _mm_xor_si128(v_x1, v_y1); + v_y2 = _mm_xor_si128(v_y2, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u))); + v_x2 = _mm_xor_si128(v_x2, v_y2); + v_y3 = _mm_xor_si128(v_y3, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u))); + v_x3 = _mm_xor_si128(v_x3, v_y3); + v_y4 = _mm_xor_si128(v_y4, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u))); + v_x4 = _mm_xor_si128(v_x4, v_y4); + v_y5 = _mm_xor_si128(v_y5, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u))); + v_x5 = _mm_xor_si128(v_x5, v_y5); + v_y6 = _mm_xor_si128(v_y6, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u))); + v_x6 = _mm_xor_si128(v_x6, v_y6); + v_y7 = _mm_xor_si128(v_y7, _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u))); + v_x7 = _mm_xor_si128(v_x7, v_y7); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u); + } + v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(3433693342u), (int32_t)(0u), (int32_t)(2926088593u)); + v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u)); + v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u)); + v_y2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(0u)); + v_x2 = _mm_clmulepi64_si128(v_x2, v_kk, (int32_t)(17u)); + v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u)); + v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u)); + v_y6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(0u)); + v_x6 = _mm_clmulepi64_si128(v_x6, v_kk, (int32_t)(17u)); + v_y0 = _mm_xor_si128(v_y0, v_x1); + v_x0 = _mm_xor_si128(v_x0, v_y0); + v_y2 = _mm_xor_si128(v_y2, v_x3); + v_x2 = _mm_xor_si128(v_x2, v_y2); + v_y4 = _mm_xor_si128(v_y4, v_x5); + v_x4 = _mm_xor_si128(v_x4, v_y4); + v_y6 = _mm_xor_si128(v_y6, v_x7); + v_x6 = _mm_xor_si128(v_x6, v_y6); + v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(2166711591u), (int32_t)(0u), (int32_t)(4057597354u)); + v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u)); + v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u)); + v_y4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(0u)); + v_x4 = _mm_clmulepi64_si128(v_x4, v_kk, (int32_t)(17u)); + v_y0 = _mm_xor_si128(v_y0, v_x2); + v_x0 = _mm_xor_si128(v_x0, v_y0); + v_y4 = _mm_xor_si128(v_y4, v_x6); + v_x4 = _mm_xor_si128(v_x4, v_y4); + v_kk = _mm_set_epi32((int32_t)(0u), (int32_t)(496309207u), (int32_t)(0u), (int32_t)(2402626965u)); + v_y0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(0u)); + v_x0 = _mm_clmulepi64_si128(v_x0, v_kk, (int32_t)(17u)); + v_y0 = _mm_xor_si128(v_y0, v_x4); + v_x0 = _mm_xor_si128(v_x0, v_y0); + v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u)); + v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)(((uint64_t)(_mm_extract_epi64(v_x0, (int32_t)(0u)))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u)))); + v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u)); + v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)((((uint64_t)(_mm_extract_epi64(v_x0, (int32_t)(1u)))) ^ ((uint64_t)(v_s))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u)))); + } + while (((uint64_t)(a_x.len)) >= 8u) { + v_kk = _mm_set_epi32((int32_t)(1u), (int32_t)(3681617473u), (int32_t)(3034951717u), (int32_t)(4144043585u)); + v_s = ((uint32_t)(_mm_extract_epi32(_mm_clmulepi64_si128(_mm_clmulepi64_si128(_mm_cvtsi64_si128((int64_t)((wuffs_base__peek_u64le__no_bounds_check(a_x.ptr) ^ ((uint64_t)(v_s))))), v_kk, (int32_t)(0u)), v_kk, (int32_t)(16u)), (int32_t)(2u)))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 8u); } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + while (((uint64_t)(a_x.len)) > 0u) { + v_s = (WUFFS_CRC32__IEEE_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); + self->private_impl.f_state = (4294967295u ^ v_s); + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 - wuffs_base__status v_status = wuffs_base__make_status(NULL); +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) - uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) - while (true) { - { - wuffs_base__status t_0 = wuffs_gif__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_gif__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +// ---------------- Status Codes Implementations - ok: - self->private_impl.p_tell_me_more[0] = 0; - goto exit; - } +// ---------------- Private Consts - goto suspend; - suspend: - self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; +static const uint64_t +WUFFS_CRC64__ECMA_TABLE[8][256] WUFFS_BASE__POTENTIALLY_UNUSED = { + { + 0u, 12911341560706588527u, 17619267392293085275u, 5164075066763771700u, 8921845837811637811u, 14483170935171449180u, 10328150133527543400u, 4357999468653093127u, + 17843691675623275622u, 4940391307328217865u, 226782375002905661u, 12685511915359257426u, 10119945210068853333u, 4566377562367245626u, 8715998937306186254u, 14689403211693301089u, + 9051005139383707209u, 14895072503764629798u, 9880782614656435730u, 4193374422961527165u, 453564750005811322u, 13070904082541799189u, 17496296445768931361u, 4747102235666401102u, + 9960315520700766767u, 4113029525020509504u, 9132755124734491252u, 14812441257301386523u, 17431997874612372508u, 4811156168024382323u, 391483189436228679u, 13132671735097031464u, + 18102010278767414418u, 5195199925788447741u, 1131375642422963401u, 13591081480414639014u, 9288535643022529185u, 3731739485546663374u, 8386748845923054330u, 14361410892855143829u, + 907129500011622644u, 13814943346342178715u, 17875617253995106479u, 5421418680781082560u, 8594564625313771207u, 14152643483341451688u, 9494204471332802204u, 3525329033817543155u, + 9704381199536204507u, 3855837706121835956u, 8226059050041019008u, 13908973417437222383u, 18265510249468982504u, 5643692520190618503u, 718348998302913715u, 13463047253836762076u, + 8146277531524994749u, 13989069943491807698u, 9622312336048764646u, 3938150108875254153u, 782966378872457358u, 13399312233903888353u, 18327840216347633877u, 5582173445676054458u, + 7257036000092981153u, 15535280666427316430u, 10390399851576895482u, 2529986302517213333u, 2262751284845926802u, 12414353723947190013u, 16997392145760156105u, 6398650419759490726u, + 10599130201908394951u, 2322133910755632296u, 7463478971093326748u, 15329644185724306675u, 16773497691846108660u, 6622864283287239323u, 2036569382881248687u, 12640783567252986560u, + 1814259000023245288u, 12250853444207230599u, 17125426475222188467u, 6811676960462675676u, 7132938157145702363u, 15119434731753103540u, 10842837361562165120u, 2690676064372932847u, + 17189129250627542414u, 6747026957542163169u, 1875814858707893717u, 12188560364711551674u, 10762704257491731389u, 2770420489343360210u, 7050658067635086310u, 15201536148867841161u, + 11493583972846619443u, 3219832958944941148u, 7711675412243671912u, 15576564987190227975u, 16452118100082038016u, 6305011443818121839u, 1213047649942025563u, 11816267669673208372u, + 7503259434831574869u, 15784731923736995898u, 11287385040381237006u, 3425713581329221729u, 1436697996605827430u, 11591809733187859977u, 16677985422973077821u, 6078267261889762898u, + 16292555063049989498u, 5851447209550246421u, 1630020308903038241u, 11939238787801010766u, 11081681957373440841u, 3090674103720225830u, 7876300217750508306u, 16023932746787097725u, + 1565932757744914716u, 12003503911822413427u, 16230825569204842823u, 5913566482019610152u, 7956607163135676207u, 15944361922680361024u, 11164346891352108916u, 3008957496780927003u, + 14514072000185962306u, 8809633696146542637u, 4460922918905818905u, 10287960411460399222u, 12879331835779764593u, 113391187501452830u, 5059972605034426666u, 17660565739912801861u, + 4525502569691853604u, 10224187249629523019u, 14576435430675780479u, 8748148222884465680u, 4980157760350383383u, 17740628527280140920u, 12797300839518981452u, 195741594718114339u, + 13040162471224305931u, 565687821211481700u, 4644267821511264592u, 17536326748496696895u, 14926957942186653496u, 8937808626997553239u, 4297282312656885603u, 9839608450464401420u, + 4852190599768102253u, 17327666750234135042u, 13245728566574478646u, 359174499151456857u, 4073138765762497374u, 10063573324157604913u, 14700457781105076997u, 9163920108173816938u, + 3628518000046490576u, 9328460452529085631u, 14330211790445699979u, 8498696072880078052u, 5299565100954197475u, 18061012165519327884u, 13623353920925351352u, 1018284691440624343u, + 14265876314291404726u, 8562713237611094233u, 3566469078572851181u, 9390260331795218562u, 13702854325316886917u, 937907429353946858u, 5381352128745865694u, 17978417549248290481u, + 5746791986423309721u, 18225777846762470134u, 13494053915084326338u, 606523824971012781u, 3751629717415787434u, 9745292510640121029u, 13876787882151992305u, 8338992711486538910u, + 13285957365033343487u, 815010154451519120u, 5540840978686720420u, 18431906428167644875u, 14101316135270172620u, 8115412784602421411u, 3978303581567838103u, 9519354766961195256u, + 12527462061959317731u, 2230461459452909452u, 6439665917889882296u, 16893009583564617687u, 15423350824487343824u, 7288217715337890239u, 2490078880175191691u, 10493603952060017124u, + 6520081235612152965u, 16813546994155744234u, 12610022887636243678u, 2148641156328442801u, 2426095299884051126u, 10557972909709735385u, 15361512820870335213u, 7350228890552538498u, + 15006518869663149738u, 7165105895222849989u, 2649782550477098737u, 10947027550912647582u, 12362696414880903321u, 1783234539286425590u, 6851427162658443458u, 17022309211647725485u, + 2873395993211654860u, 10722532847870938531u, 15232418832718623383u, 6938393941075996152u, 6642978682516671743u, 17230443782969840528u, 12156534523779525796u, 1989151790783919051u, + 6263731030979658865u, 16556202624882645790u, 11702894419100492842u, 1245039440087595845u, 3260040617806076482u, 11390642587947386157u, 15688795063501830681u, 7680756410435167606u, + 11622868312827688983u, 1324891275238549368u, 6181348207440451660u, 16638201170595874595u, 15752600435501016612u, 7616209416359311691u, 3321489341258335871u, 11328242235714328848u, + 3131865515489829432u, 10977756817953029463u, 16137146508898304611u, 7844397531750915340u, 5811434156413844491u, 16395372229761246052u, 11827132964039220304u, 1660744670629167935u, + 15913214326271352414u, 8068573254449152305u, 2905717078206922245u, 11204220263579804010u, 12035829987123708013u, 1452858539103461122u, 6017914993561854006u, 16189773752444600153u, + }, { + 0u, 6118555238288912653u, 12237110476577825306u, 18247330833359770391u, 13942380710360636081u, 10778293617712507836u, 7543452712389327019u, 4343374206906190246u, + 1162559746622204903u, 4957131115480832746u, 13398436261328603645u, 17084888254066768112u, 15086905424778654038u, 9634902877839851611u, 8686748413812380492u, 3198961161184305729u, + 2325119493244409806u, 8407378615347160771u, 9914262230961665492u, 15960741045388068057u, 16229058527915052415u, 13101053971319389298u, 5254506258681524069u, 2018377927885299304u, + 3487552142959377449u, 7246080283574668580u, 11075676491871100467u, 14798208821638459198u, 17373496827624760984u, 11957750539307177877u, 6397922322368611458u, 873845550624159119u, + 4650238986488819612u, 1468611264581623441u, 16814757230694321542u, 13669406796222545035u, 9364600845881799981u, 15356367945216001056u, 2893367039927949111u, 8993183146101597754u, + 5812680741028562043u, 307286854339917174u, 17976181078471403105u, 12506848973898782572u, 10509012517363048138u, 14213073068277772231u, 4036755855770598608u, 7848658706446142941u, + 6975104285918754898u, 3757679901787621727u, 14492160567149337160u, 11382574084698991429u, 11651310343450272483u, 17679087685142107118u, 604386294999662841u, 6668229816820511220u, + 8137636784695169973u, 2596263716583940792u, 15653459723670892975u, 10220140060479144098u, 12795844644737222916u, 16535671346696648713u, 1747691101248318238u, 5523790692630174227u, + 9300477972977639224u, 15418239225476001333u, 2937222529163246882u, 8947075512310451247u, 4642267913777087881u, 1478833794519692420u, 16842993350473770899u, 13643422681269376670u, + 10462937938231096543u, 14256895642581861842u, 4098594218943518405u, 7784568886045304776u, 5786734079855898222u, 335485660068962147u, 17986366292203195508u, 12498915352811683193u, + 11625361482057124086u, 17707288688936286715u, 614573708679834348u, 6660293997941431265u, 6929031904881267271u, 3801500275841901386u, 14553996732492558429u, 11318486464284246352u, + 12787875770090627857u, 16545891676414235164u, 1775925023235784971u, 5497808777625382918u, 8073511711541197216u, 2658137194938402989u, 15697317412892285882u, 10174030228858301111u, + 13950208571837509796u, 10768213751408296361u, 7515359803575243454u, 4369215658492879795u, 64266086328445461u, 6056541296517372696u, 12193111774187735055u, 18293581128395077890u, + 15112713823828466499u, 9606842886146402894u, 8676701462472931673u, 3206755967968430164u, 1208772589999325682u, 4913169729330573567u, 13336459633641022440u, 17149116886581154533u, + 16275273569390339946u, 13057090384914568807u, 5192527433167881584u, 2082608760381092989u, 2350925692077440475u, 8379320821714095318u, 9904217479574233025u, 15968533654375526092u, + 17437760713698643085u, 11895738795633802624u, 6353925819959930519u, 920093647833407386u, 3495382202496636476u, 7235998217053677361u, 11047581385260348454u, 14824052473177163051u, + 10447068876609200373u, 14128364157388739064u, 4118967294799201007u, 7908597456515216354u, 5874445058326493764u, 391603411424480073u, 17894151024620902494u, 12447300791057279315u, + 9284535827554175762u, 15289779793358354975u, 2957667589039384840u, 9071030930460645381u, 4729911307347480995u, 1535020299074674862u, 16750846767572792249u, 13591740465559749300u, + 12735909365018523451u, 16453465302197274166u, 1832394617641637153u, 5585730863000118316u, 8197188437887036810u, 2678299164963691655u, 15569137772090609552u, 10158372272797335197u, + 11573468159711796444u, 17614790262716542417u, 670971320137924294u, 6748289234561093579u, 7052776217202099821u, 3821593491595032416u, 14425748405936874615u, 11302896163253294458u, + 15020497008676966249u, 9555230900528283236u, 8764415362900159859u, 3262871967819308158u, 1229147417359668696u, 5037195377843840213u, 13320587995882862530u, 17020586948957226703u, + 13858063809762534542u, 10716528681989657987u, 7603000551683802772u, 4425403642365261721u, 84709666887204415u, 6180499360129388338u, 12177172482473303077u, 18165119875451415848u, + 17309582619392432295u, 11880078264510294442u, 6477599625422879421u, 940257368289594288u, 3551850046471569942u, 7323923223311315739u, 10995617555250765836u, 14731624552464748801u, + 16147023423082394432u, 13041502936518885965u, 5316274389876805978u, 2102700497890566231u, 2407324781779167729u, 8467313413945678076u, 9852321304593615851u, 15876037047908055782u, + 1291018766690942925u, 4973072573440528064u, 13274480430592564695u, 17064442507263798490u, 15030719607150486908u, 9547259896855319665u, 8738431316985759590u, 3291108156134209131u, + 128532172656890922u, 6134424711959717159u, 12113082593034745392u, 18226958170089932605u, 13886262546419256987u, 10690581952315096982u, 7595066862094806145u, 4435588787024731532u, + 3580050981226981379u, 7297974293382715662u, 10987681667836234265u, 14741811897106152212u, 17353402924945863346u, 11834005814401532863u, 6413511935936860328u, 1002093465131966885u, + 2417545179998651364u, 8459344608371405545u, 9826339458661147134u, 15904271038397419763u, 16208896970474576213u, 12977377931899316312u, 5270164626790366031u, 2146558256149678658u, + 5864365122984562769u, 399431204366950748u, 17919992407673188939u, 12419207813205476166u, 10385054866335763168u, 14192630174644861933u, 4165217520762185978u, 7864598685623228919u, + 4701851384154880950u, 1560828767195761339u, 16758641643428190636u, 13581693582721149089u, 9240574510442684679u, 15335992705270927370u, 3021896290089222941u, 9009054371811832336u, + 8153224920554538911u, 2724514274940876434u, 15633368673088300421u, 10096393516356015240u, 12707851639919861038u, 16479271570068024355u, 1840187295666814772u, 5575686180147088953u, + 6990764404993272952u, 3885857308630146421u, 14471996434107354722u, 11258899592309161839u, 11563386024119531209u, 17622620253752952772u, 696814903175779539u, 6720194058879067614u, + }, { + 0u, 4542972359516777931u, 9085944719033555862u, 4691664355513513565u, 18171889438067111724u, 14061474303606774503u, 9383328711027027130u, 13633424072306524529u, + 7676286055365832925u, 6164376987427609878u, 1481798532234586955u, 3142253189322229376u, 10855962452864321521u, 12223826156538735162u, 16771372852738792551u, 15543052108730888620u, + 15352572110731665850u, 16862791698018765937u, 12328753974855219756u, 10669987536837040103u, 2963597064469173910u, 1597421751597874013u, 6284506378644458752u, 7511137813735006411u, + 13801544397233820007u, 9260261528098962604u, 13951919735851666161u, 18344511890033026874u, 4874982405016790603u, 8983709158270585728u, 4445237816650825181u, 196831773885239318u, + 4091022007653359089u, 562346998784700474u, 5103132815620245095u, 8780357948041161644u, 14189083196432476893u, 18150173592266475286u, 13474345022262784331u, 9652793049543924864u, + 5927194128938347820u, 7875246409875505383u, 3194843503195748026u, 1395478681687169905u, 12569012757288917504u, 10477056948030502859u, 15022275627470012822u, 17253916197967211613u, + 17134349580696108107u, 15186860751721288064u, 10655150290339489757u, 12453952663903504918u, 1289987737384422247u, 3381381201708377772u, 8066289525279445233u, 5835212509754572090u, + 9749964810033581206u, 13278076374523191645u, 17967418316541171456u, 14290755639648123595u, 8890475633301650362u, 4929947589851190897u, 393663547770478636u, 4214651972966108647u, + 8182044015306718178u, 5658655167774316073u, 1124693997569400948u, 3499391957275839935u, 10206265631240490190u, 12873559114121502981u, 17560715896082323288u, 14753743294414502547u, + 1948880861322201919u, 2594127930539943668u, 7285718382500778153u, 6491924633276939618u, 16655531858934856723u, 15577868310755742168u, 11039333611388512133u, 11977453108914408014u, + 11854388257876695640u, 11207451878732806035u, 15750492819751010766u, 16545974958769302533u, 6389687006391496052u, 7469038772501250239u, 2790957363374339810u, 1851148384058628905u, + 14845159798643632773u, 17370237963685480270u, 12687582131971748115u, 10311195790054169816u, 3615017233668480425u, 946035540305899618u, 5493509258033841727u, 8302171348940565492u, + 5281120895271462419u, 8521283507583323096u, 3989500891288354181u, 600787064567550030u, 13071075951463747903u, 9974957613568212212u, 14659789384177486505u, 17616368207971182434u, + 2579975474768844494u, 2073357103652371205u, 6762762403416755544u, 7120694423275413651u, 16132579050558890466u, 16206641305794825257u, 11670425019509144180u, 11456679111066785727u, + 11260412520859862953u, 11767594448091671138u, 16308316081471249471u, 15949821717821010420u, 6947506857025941637u, 6872882154850049358u, 2196985003345963795u, 2411294364755134168u, + 17780951266603300724u, 14540225107906894527u, 9859895179702381794u, 13249171359945539881u, 787327095540957272u, 3884007889973030291u, 8429303945932217294u, 5472161678768272901u, + 16364088030613436356u, 15858029804260760079u, 11317310335548632146u, 11674676600264311193u, 2249387995138801896u, 2322888996435045667u, 6998783914551679870u, 6785602652076537525u, + 9916730820443375385u, 13156333278251739858u, 17836661041797717135u, 14448512960480194884u, 8480501340405739573u, 5384944246861192702u, 839650424281590691u, 3795664592519366248u, + 3897761722644403838u, 656471011406904245u, 5188255861079887336u, 8578093388688728099u, 14571436765001556306u, 17668683201823263897u, 12983849266553879236u, 10026146741872662287u, + 6669836397870376611u, 7177582867921406824u, 2488175334770097461u, 2129119614032302334u, 11583119667977343375u, 11507929313807383620u, 16044147764761037337u, 16259017374083049426u, + 15843330937415051829u, 16489139217633298430u, 11946100509993103779u, 11151742071862860904u, 2878174689517968665u, 1799951022334374098u, 6478030266801178255u, 7416715545229372228u, + 12779374012782992104u, 10255423946675697443u, 14938077545002500478u, 17313340186040954037u, 5581914726748679620u, 8249768321177223183u, 3702296768117257810u, 894758378090191769u, + 1067805515879173007u, 3592318064290702916u, 8126281399163064345u, 5750455340522077650u, 17509465798031703203u, 14841048614271029608u, 10153889598922762037u, 12961990299524614910u, + 7230034467336960850u, 6583663697231173273u, 1892071080611799236u, 2686992928761285903u, 10987018516067683454u, 12065805765134311861u, 16604342697881130984u, 15665095101429070371u, + 10562241790542924838u, 12510858718452294125u, 17042567015166646192u, 15242640940723501691u, 7979001782576708362u, 5886480219318720193u, 1201574129135100060u, 3433774845539634519u, + 17875696825445760251u, 14346457162030502192u, 9657117384671061869u, 13334903762452155046u, 305328503063841751u, 4266984645440464412u, 8803266454141587521u, 4981154328058445194u, + 5159950949537688988u, 8687502257518297175u, 4146714207304742410u, 470617173809470401u, 13525524806833511088u, 9565558111887030139u, 14241388846550827302u, 18061812720343526637u, + 3250597773715660097u, 1303669193657626762u, 5984074333724313303u, 7782311056298339100u, 15074661043719826029u, 17165493152098584486u, 12620272307991097851u, 10389759836427934768u, + 12273052416502600151u, 10761709128327461916u, 15295744618112993857u, 16955639155056813962u, 6232173811933554427u, 7599472825692375856u, 2912390363305901421u, 1684630829289181350u, + 13895013714051883274u, 18437420284065877185u, 13745764309700098716u, 9352044056584181591u, 4393970006691927590u, 284119552558480365u, 4822588729510268336u, 9072122871209877627u, + 9177754244107333741u, 4635909983525117350u, 92935459340889083u, 4486092121981797936u, 9471751652205676353u, 13581038687731985034u, 18259186513699183831u, 14010214853299335452u, + 1574654191081914544u, 3085435160094502267u, 7768015779946060582u, 6108684823746459373u, 16858607891864434588u, 15491872287116188247u, 10944323357536545802u, 12171520400656925121u, + }, { + 0u, 2156813408461955548u, 4313626816923911096u, 2752718492472304228u, 8627253633847822192u, 7661928252530632364u, 5505436984944608456u, 5875429064940414228u, + 17254507267695644384u, 17481523150583344956u, 15323856505061264728u, 14503785508944014468u, 11010873969889216912u, 9592933115173218380u, 11750858129880828456u, 13762408288327199732u, + 5489899806547772229u, 5899293950881604249u, 8641596751236382973u, 7639112309309301025u, 4290280838231655477u, 2766522915734824425u, 24548853041579917u, 2141951263632483921u, + 11764625126767791525u, 13739024951972572281u, 10995904098661322269u, 9617374173086412737u, 15347829100153899733u, 14488356108428585737u, 17231728733602892141u, 17495903608387299505u, + 10979799613095544458u, 9623805157521532758u, 11798587901763208498u, 13714458609834648814u, 17283193502472765946u, 17452775347443867686u, 15278224618618602050u, 14549338234851124126u, + 8580561676463310954u, 7708699370463537590u, 5533045831469648850u, 5847881786764880398u, 49097706083159834u, 2107935609010204358u, 4283902527264967842u, 2782645096555375998u, + 15298762408106657231u, 14537220494637179923u, 17261466032775972471u, 17465946411177207723u, 11811312492909331135u, 13692276008895521635u, 10968273481005252871u, 9644925621600215259u, + 4261616546501692207u, 2795266376586341107u, 70185227798988951u, 2096376465831291211u, 5520961050865536095u, 5868452604588535171u, 8593836137267777511u, 7687075229128879675u, + 11680230827506930577u, 13832259058284016205u, 11080421551794245673u, 9523735455073038837u, 15394057194608301281u, 14432953972299937085u, 17185658977434064729u, 17550865948466574981u, + 5579070418531851633u, 5801301123735731373u, 8552830750928559817u, 7736981982542757653u, 4239857041646656001u, 2826138345940532189u, 75412445699561913u, 2082177495183685733u, + 17161123352926621908u, 17565732457015587080u, 15417398740927075180u, 14419136389292487344u, 11066091662939297700u, 9546555762013386360u, 11695763573529760796u, 13808381012597372352u, + 98195412166319668u, 2067810197125185512u, 4215871218020408716u, 2841563382736944208u, 8567805054529935684u, 7712554084374493336u, 5565290193110751996u, 5824680096370817824u, + 4213277561403610395u, 2852497928146826439u, 118647349622822563u, 2038740285422565247u, 5603244184571253355u, 5777048188553278391u, 8511711324634206675u, 7778039831901335567u, + 15351860113773370363u, 14475212630091872807u, 17208772955998935107u, 17527831139023518111u, 11724816064851319947u, 13787876126790335831u, 11055209722282565427u, 9549167182608629487u, + 8523233093003384414u, 7756906139291137922u, 5590532753172682214u, 5799235221864313914u, 140370455597977902u, 2025555993157185778u, 4192752931662582422u, 2864620100732154698u, + 11041922101731072190u, 9570786891571902818u, 11736905209177070342u, 13767318537498720986u, 17187672274535555022u, 17539385849830522386u, 15374150458257759350u, 14462604578592423338u, + 15486092620961298855u, 14629711868178897019u, 17092483903335922207u, 17355247692313779139u, 11624791503456485079u, 13600030943165030155u, 11137009302703308143u, 9754815117126884531u, + 4151744643171039047u, 2626583331457439387u, 162377516962444543u, 2282879863086044451u, 5631712546292871223u, 6037452326221451755u, 8501327171535303567u, 7499692239708246611u, + 11158140837063703266u, 9743299917872012094u, 11602602247471462746u, 13612749016692676742u, 17105661501857119634u, 17333526894853233742u, 15473963965085515306u, 14650238604571402230u, + 8479714083293312002u, 7512977616177960414u, 5652276691881064378u, 6025361010828170854u, 150824891399123826u, 2303974039851176622u, 4164354990367371466u, 2604286280411140374u, + 5659250822143950637u, 6009834889821986545u, 8454565055791594645u, 7546392787102457161u, 4121809449076176989u, 2656298618920900993u, 211263906290727909u, 2233791159333640761u, + 11672732454520566221u, 13552292306546298897u, 11106145987650286197u, 9785898338790069161u, 15440531030182573757u, 14675335027319969633u, 17121240571213837573u, 17326570184971408601u, + 196390824332639336u, 2258328937796115892u, 4135620394250371024u, 2632959299571932684u, 8431742436040817432u, 7560729365405768388u, 5683126765473888416u, 5994308631384381820u, + 17135610109059871368u, 17303780593489122132u, 15425108168748986672u, 14699314298944934124u, 11130580386221503992u, 9770921945649714212u, 11649360192741635648u, 13566070240564762524u, + 8426555122807220790u, 7574959341548112874u, 5704995856293652878u, 5963537623700588626u, 237294699245645126u, 2208312048661695642u, 4077480570845130494u, 2700071425513574178u, + 11206488369142506710u, 9686112028953249034u, 11554096377106556782u, 13670376701660284594u, 17023422649268413350u, 17424940338905547386u, 15556079663802671134u, 14559229772221530562u, + 4089596066908350835u, 2679540256679954607u, 224121464376355531u, 2230046074588744471u, 5727171952466636291u, 5950815117732351967u, 8405427952099257787u, 7586487769270013031u, + 15543464952953907091u, 14581513594800801359u, 17034988434643772459u, 17403850594581005815u, 11533527867866456291u, 13682454788587061567u, 11228114617197060955u, 9672831084924650119u, + 17046466186006768828u, 17401835225210195296u, 15513812278582275844u, 14601417988320120536u, 11181065506345364428u, 9711332585899690512u, 11598470443728627828u, 13625782737014311336u, + 280740911195955804u, 2165085734748128128u, 4051111986314371556u, 2726642315882184760u, 8385505863325164844u, 7616087770173211888u, 5729240201464309396u, 5939354855465699144u, + 11574598932837183481u, 13641322155266051621u, 11203874897631210561u, 9696991643941850525u, 15500005765847099529u, 14624770467483748693u, 17061326039500450609u, 17377293083093715693u, + 5752625691707646233u, 5925581285101240517u, 8361067032314929825u, 7631051003498906493u, 4066548076212889193u, 2702667407911749557u, 266366940911429073u, 2187862166416278541u, + }, { + 0u, 6642096280510406750u, 13284192561020813500u, 16462795876764246242u, 16315823105410768893u, 13708963636559134627u, 6500836570635362113u, 439922346977066783u, + 6197597939812213119u, 733872460607717665u, 17174658310779658691u, 12859417258165748125u, 13001673141270724226u, 16736026809386770140u, 879844693954133566u, 5771540452186644064u, + 12395195879624426238u, 17305613297699152544u, 1467744921215435330u, 5220531075568771612u, 5650300446275329283u, 1316336633116425565u, 17740532779662220735u, 12258375912742239713u, + 18016332033719362433u, 11973850846087693279u, 4781749989466252093u, 2193612730179060579u, 1759689387908267132u, 4919860766213921826u, 11543080904373288128u, 18166453874549300382u, + 14614610554166352761u, 10879836598703668007u, 8253805222095936453u, 3361408799105547163u, 2935489842430870660u, 8399638907315561690u, 10441062151137543224u, 14757009366268798054u, + 11300600892550658566u, 13906759146888600152u, 2632673266232851130u, 8693166652788693732u, 9132946036408395259u, 2491556468171146661u, 14331668736193815879u, 11153489555886392601u, + 7409848711186274695u, 4249257595424012761u, 16037314857127418171u, 9413239572791867749u, 9563499978932504186u, 15606406401646028324u, 4387225460358121158u, 6976068332272625304u, + 3519378775816534264u, 7852640824571713702u, 9839721532427843652u, 15321459211647031322u, 15184496315767285509u, 10274783960564057947u, 7701371084599273401u, 3949009615571978215u, + 539203352115488887u, 6581683165424715817u, 13772373076031531211u, 16360516657443457173u, 16507610444191872906u, 13347445937900984276u, 6722817598211094326u, 99441604310980456u, + 5870979684861741320u, 960568039155968342u, 16799277814631123380u, 13046489736199563754u, 12904108438562707189u, 17238069777753355947u, 814716683761407561u, 6296880972452001303u, + 12357655745765665417u, 17821378201246059223u, 1379747099228580405u, 5694995023857257067u, 5265346532465702260u, 1530999186474390826u, 17386333305577387464u, 12494636173022434710u, + 18265892072816790518u, 11623803214076996520u, 4983112936342293322u, 1804507146630605588u, 2238305212630619147u, 4845162757404030037u, 12054694172541097143u, 18115614168568345833u, + 14819697422372549390u, 10486441695742104400u, 8498515190848025522u, 3016776137306395628u, 3442815973027425523u, 8352525304506551469u, 10925090729870978127u, 14677459070913039377u, + 11216336045685248625u, 14376925237369287215u, 2590274523633996493u, 9214355580338500243u, 8774450920716242316u, 2731551919773330898u, 13952136664545250608u, 11363291318662491502u, + 7038757551633068528u, 4432606169309893038u, 15705281649143427404u, 9644785238863483154u, 9494645848386137613u, 16136034042300943955u, 4294513027018469041u, 7472698529450626799u, + 4011857131457007759u, 7746628612951437521u, 10373500843358195763u, 15265904688119197805u, 15402742169198546802u, 9938598876682809132u, 7898019231143956430u, 3582070091934478224u, + 1078406704230977774u, 5970139571501035696u, 13163366330849431634u, 16897748309796073484u, 17049000381336047379u, 12733717820530814797u, 6107119981172920239u, 643361792051163121u, + 6410046491609887121u, 349161128571523535u, 16190407203032477997u, 13583585392940618099u, 13445635196422188652u, 16624205252526067250u, 198883208621960912u, 6840937431151644302u, + 11741959369723482640u, 18365299631022420558u, 1921136078311936684u, 5081265949533565682u, 4656338829252136429u, 2068229881835728307u, 17925537898651110737u, 11883093821164285199u, + 17650059563187254127u, 12167860639460954929u, 5524638460789093331u, 1190641388963713933u, 1629433367522815122u, 5382257181810330828u, 12593761944904002606u, 17504208224571739248u, + 14134199920450915223u, 10956049054195313609u, 8970094247992396587u, 2328741787718953845u, 2759494198457160810u, 8819954874021999668u, 11389990047714514134u, 13996106797082358920u, + 10530693064931404520u, 14846677937748691638u, 3061998372948781652u, 8526176301674629642u, 8091274350704555285u, 3198835872954668363u, 14416890915810522537u, 10682083699634542071u, + 7503655637611612521u, 3751252662574033207u, 15021960841764981205u, 10112215774463453579u, 9966225872684586644u, 15448000658827392714u, 3609014293261211176u, 7942304654960916086u, + 4476610425261238294u, 7065420035288041544u, 9690325514808060074u, 15733189881789008116u, 15874467260079749099u, 9250420838410950581u, 7212375292832610135u, 4051821833783301897u, + 688179623118076057u, 6170372224719608007u, 12814440204992854053u, 17148438651140642939u, 16997030381696051044u, 13244209591132604218u, 6033552274612791256u, 1123099122930255750u, + 6885631946054851046u, 262293608834169272u, 16705050609013102938u, 13544914965422553348u, 13683025758949262875u, 16271127284595091013u, 412415468322195111u, 6454862019777308409u, + 11927910341603441255u, 17988788832627006009u, 2148953154424896219u, 4755777988240824965u, 5180549047267992986u, 2001980365486523844u, 18428711160677000486u, 11786650616022549880u, + 17548901841432484632u, 12657171448130714438u, 5463103839546661796u, 1728714438829439994u, 1290082918514197733u, 5605359706950509755u, 12231113943998710873u, 17694874057198724103u, + 14077515103266137056u, 11488706867561743294u, 8865212338619786076u, 2822341649514070786u, 2391433177253116957u, 9015472726907116611u, 11054926469989481633u, 14215482952762858751u, + 10763369033251996319u, 14515766235920655041u, 3244216653174833699u, 8153963644554617469u, 8589026054036938082u, 3107253741862419772u, 14945397058901253598u, 10612099275430968704u, + 8023714262914015518u, 3707732413820797248u, 15493257225902875042u, 10029072425162228220u, 10174906129304731363u, 15067338284929851069u, 3850131242430201439u, 7584939832928591361u, + 4133108057121652833u, 7311251501606674495u, 9295800309597257949u, 15937155243838988419u, 15796038462287912860u, 9735579710801330114u, 7164140183868956448u, 4558017662132191102u, + }, { + 0u, 7026975924517234630u, 14053951849034469260u, 11713158812725061706u, 1498566550037692829u, 8453026741656872539u, 15547077823203331601u, 13134332388348864983u, + 2997133100075385658u, 5193532126013515004u, 16906053483313745078u, 10023477084983765872u, 4421425403924087463u, 6690338751863514465u, 18326734871926164779u, 11516110084014746349u, + 5994266200150771316u, 3651077923391955378u, 10387064252027030008u, 17411644826573123134u, 5180286430728521705u, 2765428220391841839u, 9578516152858789989u, 16530863678517358499u, + 8842850807848174926u, 1962664170658947720u, 13380677503727028930u, 15579466327313067268u, 7958959654645957843u, 1150444288916906773u, 12500388506175163231u, 14771411239789669529u, + 11988532400301542632u, 14401112944851970862u, 7302155846783910756u, 347530691846251682u, 12867955000885349749u, 15208934917731379891u, 8186843028093092601u, 1160054057126929727u, + 10360572861457043410u, 17171366937719040020u, 5530856440783683678u, 3262112454209283992u, 11170013709381963343u, 18052407625221859721u, 6344013830343901635u, 4147432248901248517u, + 17685701615696349852u, 10733466276663946586u, 3925328341317895440u, 6340298665266291414u, 16265807495604570881u, 9241127928571882695u, 2500178400086410381u, 4843267757373072203u, + 15917919309291915686u, 13646779991004769888u, 2300888577833813546u, 9109287431904666092u, 14423962049646856251u, 12225267820500938749u, 803223682168014775u, 7683504840782913649u, + 16025789128531904341u, 13827140552201887891u, 2120809441137969369u, 9001136188144267039u, 14604311693567821512u, 12333148557000565006u, 695061383692503364u, 7503436758785666690u, + 17866059964468495471u, 10841338299774886825u, 3817174930229677027u, 6160221704524114981u, 16373686056186185202u, 9421479739856314932u, 2320108114253859454u, 4735107671358188984u, + 10180636633891078433u, 17063072784830850791u, 5638869205660782253u, 3442330069771397483u, 11061712881567367356u, 17872478072565786490u, 6524224908418567984u, 4255451551249279222u, + 11880240423364919835u, 14221174549956093405u, 7482375666214882711u, 455541244296276561u, 12688027660687803270u, 15100631886079386688u, 8294864497802497034u, 1340262959281482700u, + 8662912472460168125u, 1854372134182743163u, 13488687978245964849u, 15759686224643400695u, 7850656682635790880u, 970516889046347238u, 12680597330532582828u, 14879432787265004138u, + 5885971969496909959u, 3471141773623390017u, 10567281927262422795u, 17519657531808653517u, 5000356800172820762u, 2657127470508076764u, 9686535514746144406u, 16711074697083887952u, + 3105005063510429129u, 5373890534425651727u, 16725976600334615109u, 9915323596096578947u, 4601777155667627092u, 6798217371950640018u, 18218574863809332184u, 11336039720248747038u, + 180360639130832627u, 7134845665859430709u, 13945800545768817023u, 11533079735570376377u, 1606447364336029550u, 8633376307814525096u, 15367009681565827298u, 13026170149548992292u, + 3321048140255203375u, 5733767250183223273u, 17086394267351834531u, 10131907641284540517u, 4241618882275938738u, 6582455852881933940u, 18002272376288534078u, 10975340495589554680u, + 540800415553098517u, 7351451582082282707u, 14161821513074465945u, 11892934580260027231u, 1390122767385006728u, 8272655212095272270u, 15006873517571333380u, 12810430501506267842u, + 9023334491325470299u, 2070960623556915613u, 13704726720259086807u, 16119558478964112913u, 7634349860459354054u, 609813203025260544u, 12320443409048229962u, 14663675712440713100u, + 6101997361665611105u, 3831000989484282535u, 10927717295939115757u, 17736259059608567083u, 4640216228507718908u, 2441383434118427450u, 9470215342716377968u, 16350357972595129526u, + 9820495924665654471u, 16847328885758262017u, 5422549171225416523u, 3081613207998608525u, 11277738411321564506u, 18232337151134792348u, 6884660139542794966u, 4472053216375158032u, + 11663933463862517757u, 13860471001487472699u, 7122221882022416497u, 239784031886489527u, 13048449816837135968u, 15317220237859158438u, 8510903102498558444u, 1700135351162517034u, + 15809464669166377651u, 13466419319190748533u, 1760673139591009599u, 8785396677427507961u, 14964751332429765422u, 12549754610540477672u, 911082488592553122u, 7863291466191287140u, + 17505901828360837513u, 10625576643111779919u, 3600872305391818245u, 5799522617425244611u, 16589728995604994068u, 9781356593166352338u, 2680525918562965400u, 4951691578960654430u, + 17325824944920336250u, 10517423154702741692u, 3708744268365486326u, 5979881026315534128u, 16481568986909349607u, 9601286230029496609u, 2860877669727689067u, 5059570199676927661u, + 15701313365271581760u, 13286340242614875014u, 1941033778092694476u, 8893266419348519946u, 14784683190314112477u, 12441592372201976347u, 1018963302412737105u, 8043641032810315159u, + 11771943938993819918u, 14040690898222216904u, 6942283547246780034u, 131491994814691652u, 13228658641689481363u, 15425241784889898837u, 8402600130983321375u, 1520207950847359193u, + 10000713600345641524u, 16955341590498866674u, 5314254941016153528u, 2901677057735113342u, 11385757773804508073u, 18412548169088955503u, 6704730509582687269u, 4363752465879022563u, + 6210010127020858258u, 4011218604585024596u, 10747781068851303454u, 17627964906259002328u, 4820427307211528719u, 2549402735887646153u, 9361914515530929539u, 16170428419360240197u, + 9203554311335254184u, 2178971175377796974u, 13596434743901280036u, 15939620083439087842u, 7742371330630129973u, 790022104701665011u, 12140516069312059065u, 14555372680310567295u, + 360721278261665254u, 7243300338934250016u, 14269691331718861418u, 12073295142069515692u, 1281960468464901243u, 8092587130592951229u, 15187223161047700471u, 12918311238500824113u, + 3212894728672059100u, 5553690289885640986u, 17266752615629050192u, 10239779664840078998u, 4061548595831021377u, 6474295767462639751u, 18110150936257777869u, 11155692307469580043u, + }, { + 0u, 2517245393515406572u, 5034490787030813144u, 7435750759411199284u, 10068981574061626288u, 12201157653998401372u, 14871501518822398568u, 17045318164640841348u, + 9628913577918544357u, 12056075433989135625u, 13870769438669140029u, 16326061061730899153u, 1016952077871524437u, 3239211695253081785u, 5459183210385793933u, 7578968205522831201u, + 11067918171351838031u, 13508029996328618403u, 15872723984458359959u, 18349972777811820667u, 1307470557354262271u, 3515654148887976467u, 6339673239971903271u, 8436375012170683339u, + 2033904155743048874u, 4528066323082129478u, 6478423390506163570u, 8865607338129291678u, 10918366420771587866u, 13072499669943034870u, 15157936411045662402u, 17344703028974807598u, + 11667391723826758683u, 9441211325989495031u, 16444045520167767491u, 14329311757255665967u, 3050858413050517419u, 628778578755597127u, 8036894684654706291u, 5577642697640442527u, + 2614941114708524542u, 478839856218937618u, 7031308297775952934u, 4862538486186004682u, 12679346479943806542u, 10167187506301176482u, 16872750024341366678u, 14467534086004917114u, + 4067808311486097748u, 1917635425212288440u, 9056132646164258956u, 6864284009665987680u, 12956846781012327140u, 10457633378212404744u, 17731214676258583356u, 15347951510183778256u, + 13678285260964991153u, 11474057634298917981u, 17873974704293108073u, 15772186515461651845u, 3922409453435093761u, 1477250791027468269u, 8336488571297909465u, 5863164957556321845u, + 15063804914172139187u, 17573731408537121375u, 10724047561790938987u, 13131499433903012743u, 6535100908406441219u, 8673469987586793967u, 2265113888856263899u, 4431612735036172343u, + 6101716826101034838u, 8521560882533092282u, 1257557157511194254u, 3719041779816530530u, 16073789369309412582u, 18302240886422657034u, 11155285395280885054u, 13267751491267498450u, + 5229882229417049084u, 7672809353916620560u, 957679712437875236u, 3433240205686757064u, 14062616595551905868u, 16269110787469675680u, 9725076972372009364u, 11824592944582215032u, + 14786588404820918809u, 17283564772171425525u, 9865866699426761665u, 12251361247433944877u, 5082513026899726761u, 7234957975966594373u, 240568853608110193u, 2430150771060047005u, + 8135616622972195496u, 5911125624750880324u, 3835270850424576880u, 1717722887501053852u, 18112265292328517912u, 15687370158510810612u, 13728568019331975360u, 11271004332422294572u, + 17674167644946721613u, 15539754686561718177u, 12725302718847165077u, 10553717607734429305u, 9150035367232403709u, 6635062193578351633u, 4261933579054297381u, 1858407040333796809u, + 16825062113507622887u, 14668696227990231819u, 12439147139764057663u, 10254616302904316627u, 7116415003206659159u, 4624520499557157051u, 2818284765131990415u, 428829699325493603u, + 7844818906870187522u, 5634399380472423150u, 2954501582054936538u, 860032292373900086u, 16672977142595818930u, 14235136279826723166u, 11726329915112643690u, 9246813302127474822u, + 3513487962258617315u, 1309817375275636495u, 8438743075148003899u, 6337546835477044951u, 13510341259434958931u, 11065716548023207103u, 18347741267953084811u, 15874986514718330215u, + 13070201816812882438u, 10920562880461237994u, 17346939975173587934u, 15155660198108440370u, 4530227777712527798u, 2031571415669472602u, 8863225470072344686u, 6480554254231811202u, + 12203433652202069676u, 10066744842596399680u, 17043121765066184564u, 14873799311837557656u, 2515114315022388508u, 2382082824317424u, 7438083559633061060u, 5032329272252129320u, + 3241337884980569929u, 1014584229661574053u, 7576621447749742225u, 5461349336866867837u, 12053812688995611897u, 9631145302510833685u, 16328262745174523169u, 13868458115447806413u, + 10459764458834098168u, 12954464700354433812u, 15345618707833241120u, 17733376188870843084u, 1915359424875750472u, 4070045040789094564u, 6866480411373514128u, 9053834855311329660u, + 1479513538183220765u, 3920177730975673073u, 5860963271950469061u, 8338799892386374441u, 11471931442405006765u, 13680653107046267201u, 15774533275401163893u, 17871808579940708505u, + 626467317811485367u, 3053060038512016987u, 5579874205336949615u, 8034632152261867395u, 9443377510452431111u, 11665044903776710123u, 14326943696444768479u, 16446171926791300147u, + 10165026053799453522u, 12681679222183806910u, 14469915951933188746u, 16870619158449294950u, 481137707216220386u, 2612744652856644622u, 4860301542120094010u, 7033584512875404758u, + 16271233245944390992u, 14060243759811248572u, 11822251249501760648u, 9727246909562751076u, 7670541700849153760u, 5232109988680716812u, 3435445775002107704u, 955373222128557012u, + 7237229143405862069u, 5080272407415421017u, 2427958334666397037u, 242871556844564865u, 17281429885116092165u, 14788965422804986857u, 12253699033039161053u, 9863708918048465457u, + 8671167069616523295u, 6537293559533907187u, 4433853414635209159u, 2262842661302265131u, 17575888975148309423u, 15061467343334031171u, 13129122476067492471u, 10726182388697724571u, + 18300070734464807418u, 16076131279156974870u, 13270124387156703266u, 11153162876657622222u, 8523867158108594762u, 6099511471519499942u, 3716814080667593618u, 1259824750463930238u, + 4622362935074513227u, 7118752576211060135u, 431206655032469651u, 2816149936058911871u, 14670999143827763963u, 16822869460218058263u, 10252375625438018339u, 12441418369480155087u, + 14232830006413318318u, 16675182499310091330u, 9249040999114314102u, 11724062320027170202u, 5636569530263980830u, 7842476994894082034u, 857659398650987206u, 2956624102806742570u, + 15689637813740375044u, 18110037535197587688u, 11268798760944846300u, 13730874507508556080u, 5909003164109873076u, 8137989456584309592u, 1720064584747800172u, 3833100915362378368u, + 6637197082762229217u, 9147658351414628621u, 1856069252600036409u, 4264091358266300629u, 15537483516989711953u, 17676408262268928701u, 10555910046260817801u, 12723000017772809061u, + }, { + 0u, 15762200328042667840u, 2856835172924432389u, 18238190752146915141u, 5713670345848864778u, 10805715811487326026u, 7561135427655163919u, 12848797446532677455u, + 11427340691697729556u, 4911321075843194708u, 13345174655120580625u, 7173389830452510545u, 15122270855310327838u, 820654137405644638u, 17760118084036943899u, 3226275954771115867u, + 12678913378224905901u, 8451595299172663789u, 9822642151686389416u, 5976168202979041768u, 16194808345499688615u, 4179641502022828519u, 14346779660905021090u, 2135996745225445858u, + 3558579666237890233u, 16995468946051088889u, 1641308274811289276u, 14733962144962732540u, 9090961916423626419u, 11859948271085519347u, 6452551909542231734u, 9453764156601606646u, + 14785799433083167711u, 1697614691135618207u, 16903190598345327578u, 3470771065211313306u, 9402037001392841685u, 6396285171454065813u, 11952336405958083536u, 9178809987380452496u, + 6027971268800324555u, 9878982515431963787u, 8359283004045657038u, 12591138999497481358u, 2084233168694272961u, 14290549069261356161u, 4271993490450891716u, 16282692837778922628u, + 7117159332475780466u, 13293411258189767218u, 4999205320339463543u, 11519692655715205687u, 3282616549622578552u, 17811921192019632696u, 732879648334208381u, 15029958398333780541u, + 18181923832847252838u, 2805107922438644262u, 15850048426093911395u, 92388385340408355u, 12905103819084463468u, 7612972483059622444u, 10717907374994120041u, 5621392111171994153u, + 629311348378851643u, 15133597752622646907u, 3395229382271236414u, 17699378041462564478u, 5183867188229904689u, 11335100742646646385u, 6941542130422626612u, 13469099241846138484u, + 10821536956051937583u, 5517832210058282607u, 12792570342908131626u, 7725577015716947562u, 15665448522205731109u, 277059068684322405u, 18357619974760904992u, 2629481737494357600u, + 12055942537600649110u, 9075274912216783062u, 9289461107078326163u, 6508930745710590163u, 16718566008091314076u, 3655465612432595164u, 14961454118931310489u, 1522030784741112025u, + 4168466337388545922u, 16386289672930760898u, 2196870928291817351u, 14177982363995224263u, 8543986980901783432u, 12406505804242475208u, 5852377756745475981u, 10054645982306597069u, + 14234318664951560932u, 2248669261341992356u, 16298510681658284769u, 4076149859246245281u, 9998410640678927086u, 5800610134637962670u, 12494386096293518059u, 8636334373997692331u, + 6565233099245157104u, 9341293662428177840u, 8987461698644630261u, 11963660006880118197u, 1465759296668416762u, 14909722918146729402u, 3743309483160705791u, 16810949547632248255u, + 7673845564465570889u, 12736298827739970313u, 5610215844877288524u, 10909381007990496012u, 2681314179816367171u, 18413922163761052419u, 184776770680816710u, 15577635352405072646u, + 17647610443766686813u, 3338994288425483037u, 15225944966119244888u, 717191546761911064u, 13520897736746902615u, 6997878541721926423u, 11242784222343988306u, 5096087965850491666u, + 1258622696757703286u, 14684288965200833846u, 3950222953022231155u, 17036158029906267443u, 6790458764542472828u, 9548224856613104956u, 8762045755503235705u, 11756540858562383161u, + 10367734376459809378u, 6151638724996853026u, 12124837022850257511u, 8285082520580115751u, 13883084260845253224u, 1879138195689975080u, 16649556998353834605u, 4445490780332133677u, + 13727827248377474267u, 7223104792207356827u, 11035664420116565214u, 4870673773980832670u, 17422178244240010449u, 3131857036752565137u, 15451154031433895124u, 924103331921597332u, + 2311784730144877775u, 18062687245331231631u, 554118137368644810u, 15928680121837474698u, 8024872609708797125u, 13105623011270275973u, 5258963474988715200u, 10539833548380279680u, + 15872427342139003305u, 502333042764009193u, 18150549824433566124u, 2404114375865757420u, 10596187595637903779u, 5310779519913856739u, 13017861491421180326u, 7932573568563556070u, + 4814384572959953341u, 10983915471956430589u, 7310931224865190328u, 13820193315420761848u, 980423156880069047u, 15503004023780282103u, 3044061569482224050u, 17329913425393921778u, + 8336932674777091844u, 12181156958151692356u, 6059373863990406913u, 10279938678082531393u, 4393741856583634702u, 16593268045114871886u, 1971504083133951755u, 13970910599835103307u, + 17087973961803566864u, 4006576835745435728u, 14591990156772618005u, 1170861220680101973u, 11704755513490951962u, 8705792948709298266u, 9640554597612056351u, 6878321524855255135u, + 1858937689852799821u, 14083548048513152013u, 4497338522683984712u, 16489741062169236488u, 6235036951360285511u, 10104345546597921799u, 8152299718492490562u, 12365860697102636034u, + 9753200483853429593u, 6765745319621112857u, 11601220269275925340u, 8809399250468705308u, 14416405870873226067u, 1346516287098352659u, 17272668747995384662u, 3821952007586370582u, + 13130466198490314208u, 7820039919040899744u, 10492627387899532773u, 5414409408661555877u, 17974923397289260522u, 2579810761044912810u, 16057098401758057967u, 317732763665910447u, + 2931518593336833524u, 17442526084696124084u, 1084062204544407025u, 15399436031514938033u, 7486618966321411582u, 13644576356632980158u, 4629793036166665723u, 11168576964637084347u, + 15347691128931141778u, 1027777753507534802u, 17534896747071563927u, 3019349226222860247u, 11220431689754577048u, 4686116923914377176u, 13552315720802183325u, 7398828111596124125u, + 5362628359632734342u, 10436379358185592774u, 7912374160093407363u, 13218332977821366211u, 369553541361633420u, 16113456511805446092u, 2487515902914439305u, 17887166489985742793u, + 8865757316743550527u, 11653040814255671679u, 6677988576850966074u, 9660905738751846778u, 3765703796660934197u, 17220887603689539957u, 1434383093523822128u, 14508740362393577840u, + 16546065181022836267u, 4549193289962883435u, 13995757083443852846u, 1766676892172462446u, 12309576339732698657u, 8100554995509053793u, 10192175931700983332u, 6327407589325138276u, + }, +}; - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} +static const uint8_t +WUFFS_CRC64__ECMA_X86_SSE42_FOLD1[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 228u, 58u, 57u, 202u, 151u, 212u, 93u, 224u, + 64u, 95u, 135u, 199u, 175u, 149u, 190u, 218u, +}; -// -------- func gif.decoder.do_tell_me_more +static const uint8_t +WUFFS_CRC64__ECMA_X86_SSE42_FOLD2[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 68u, 250u, 158u, 138u, 0u, 91u, 9u, 96u, + 81u, 175u, 225u, 15u, 163u, 83u, 230u, 59u, +}; + +static const uint8_t +WUFFS_CRC64__ECMA_X86_SSE42_FOLD4[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 243u, 65u, 212u, 157u, 187u, 239u, 227u, 106u, + 244u, 45u, 132u, 167u, 84u, 96u, 31u, 8u, +}; + +static const uint8_t +WUFFS_CRC64__ECMA_X86_SSE42_FOLD8[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 16u, 204u, 79u, 29u, 215u, 87u, 135u, + 64u, 231u, 61u, 247u, 42u, 107u, 216u, 215u, +}; + +static const uint8_t +WUFFS_CRC64__ECMA_X86_SSE42_MUPX[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 213u, 99u, 41u, 23u, 108u, 70u, 62u, 156u, + 133u, 30u, 14u, 175u, 43u, 175u, 216u, 146u, +}; + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_tell_me_more( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); - uint64_t v_chunk_length = 0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up__choosy_default( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up_x86_sse42( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) - uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// ---------------- VTables - if ((self->private_impl.f_call_sequence & 16u) == 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } - if (self->private_impl.f_metadata_fourcc == 0u) { - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; - } - while (true) { - while (true) { - if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) { - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - 2u, - 0u, - self->private_impl.f_metadata_io_position, - 0u, - 0u); - } - status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - 0u, - 0u, - 0u, - 0u, - 0u); - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - continue; - } - break; - } - v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); - if (v_chunk_length <= 0u) { - iop_a_src += 1u; - break; - } - if (self->private_impl.f_metadata_fourcc == 1481461792u) { - v_chunk_length += 1u; - } else { - iop_a_src += 1u; - } - self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length); - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - 3u, - self->private_impl.f_metadata_fourcc, - 0u, - wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), - self->private_impl.f_metadata_io_position); - } - status = wuffs_base__make_status(wuffs_base__suspension__even_more_information); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); +const wuffs_base__hasher_u64__func_ptrs +wuffs_crc64__ecma_hasher__func_ptrs_for__wuffs_base__hasher_u64 = { + (uint64_t(*)(const void*))(&wuffs_crc64__ecma_hasher__checksum_u64), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_crc64__ecma_hasher__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_crc64__ecma_hasher__set_quirk), + (wuffs_base__empty_struct(*)(void*, + wuffs_base__slice_u8))(&wuffs_crc64__ecma_hasher__update), + (uint64_t(*)(void*, + wuffs_base__slice_u8))(&wuffs_crc64__ecma_hasher__update_u64), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_crc64__ecma_hasher__initialize( + wuffs_crc64__ecma_hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); } - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - 3u, - self->private_impl.f_metadata_fourcc, - 0u, - self->private_impl.f_metadata_io_position, - self->private_impl.f_metadata_io_position); +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } - self->private_impl.f_call_sequence &= 239u; - self->private_impl.f_metadata_fourcc = 0u; - self->private_impl.f_metadata_io_position = 0u; - status = wuffs_base__make_status(NULL); - goto ok; - - ok: - self->private_impl.p_do_tell_me_more[0] = 0; - goto exit; } - goto suspend; - suspend: - self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.choosy_up = &wuffs_crc64__ecma_hasher__up__choosy_default; - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name = + wuffs_base__hasher_u64__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers = + (const void*)(&wuffs_crc64__ecma_hasher__func_ptrs_for__wuffs_base__hasher_u64); + return wuffs_base__make_status(NULL); +} + +wuffs_crc64__ecma_hasher* +wuffs_crc64__ecma_hasher__alloc(void) { + wuffs_crc64__ecma_hasher* x = + (wuffs_crc64__ecma_hasher*)(calloc(1, sizeof(wuffs_crc64__ecma_hasher))); + if (!x) { + return NULL; } + if (wuffs_crc64__ecma_hasher__initialize( + x, sizeof(wuffs_crc64__ecma_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} - return status; +size_t +sizeof__wuffs_crc64__ecma_hasher(void) { + return sizeof(wuffs_crc64__ecma_hasher); } -// -------- func gif.decoder.num_animation_loops +// ---------------- Function Implementations + +// -------- func crc64.ecma_hasher.get_quirk WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_gif__decoder__num_animation_loops( - const wuffs_gif__decoder* self) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_crc64__ecma_hasher__get_quirk( + const wuffs_crc64__ecma_hasher* self, + uint32_t a_key) { if (!self) { return 0; } @@ -37136,38 +37965,134 @@ wuffs_gif__decoder__num_animation_loops( return 0; } - if (self->private_impl.f_seen_num_animation_loops_value) { - return self->private_impl.f_num_animation_loops_value; - } - if (self->private_impl.f_num_decoded_frame_configs_value > 1u) { - return 1u; - } return 0u; } -// -------- func gif.decoder.num_decoded_frame_configs +// -------- func crc64.ecma_hasher.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_crc64__ecma_hasher__set_quirk( + wuffs_crc64__ecma_hasher* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func crc64.ecma_hasher.update + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__update( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } + + if (self->private_impl.f_state == 0u) { + self->private_impl.choosy_up = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc64__ecma_hasher__up_x86_sse42 : +#endif + self->private_impl.choosy_up); + } + wuffs_crc64__ecma_hasher__up(self, a_x); + return wuffs_base__make_empty_struct(); +} + +// -------- func crc64.ecma_hasher.update_u64 WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gif__decoder__num_decoded_frame_configs( - const wuffs_gif__decoder* self) { +wuffs_crc64__ecma_hasher__update_u64( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { return 0; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { return 0; } - return self->private_impl.f_num_decoded_frame_configs_value; + wuffs_crc64__ecma_hasher__update(self, a_x); + return wuffs_crc64__ecma_hasher__checksum_u64(self); } -// -------- func gif.decoder.num_decoded_frames +// -------- func crc64.ecma_hasher.up + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x) { + return (*self->private_impl.choosy_up)(self, a_x); +} + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up__choosy_default( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x) { + uint64_t v_s = 0; + wuffs_base__slice_u8 v_p = {0}; + + v_s = (18446744073709551615u ^ self->private_impl.f_state); + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 8; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8)); + while (v_p.ptr < i_end0_p) { + v_s ^= ((((uint64_t)(v_p.ptr[0u])) << 0u) | + (((uint64_t)(v_p.ptr[1u])) << 8u) | + (((uint64_t)(v_p.ptr[2u])) << 16u) | + (((uint64_t)(v_p.ptr[3u])) << 24u) | + (((uint64_t)(v_p.ptr[4u])) << 32u) | + (((uint64_t)(v_p.ptr[5u])) << 40u) | + (((uint64_t)(v_p.ptr[6u])) << 48u) | + (((uint64_t)(v_p.ptr[7u])) << 56u)); + v_s = (WUFFS_CRC64__ECMA_TABLE[0u][(255u & (v_s >> 56u))] ^ + WUFFS_CRC64__ECMA_TABLE[1u][(255u & (v_s >> 48u))] ^ + WUFFS_CRC64__ECMA_TABLE[2u][(255u & (v_s >> 40u))] ^ + WUFFS_CRC64__ECMA_TABLE[3u][(255u & (v_s >> 32u))] ^ + WUFFS_CRC64__ECMA_TABLE[4u][(255u & (v_s >> 24u))] ^ + WUFFS_CRC64__ECMA_TABLE[5u][(255u & (v_s >> 16u))] ^ + WUFFS_CRC64__ECMA_TABLE[6u][(255u & (v_s >> 8u))] ^ + WUFFS_CRC64__ECMA_TABLE[7u][(255u & (v_s >> 0u))]); + v_p.ptr += 8; + } + v_p.len = 1; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end1_p) { + v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u)); + v_p.ptr += 1; + } + v_p.len = 0; + } + self->private_impl.f_state = (18446744073709551615u ^ v_s); + return wuffs_base__make_empty_struct(); +} + +// -------- func crc64.ecma_hasher.checksum_u64 WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gif__decoder__num_decoded_frames( - const wuffs_gif__decoder* self) { +wuffs_crc64__ecma_hasher__checksum_u64( + const wuffs_crc64__ecma_hasher* self) { if (!self) { return 0; } @@ -37176,72 +38101,473 @@ wuffs_gif__decoder__num_decoded_frames( return 0; } - return self->private_impl.f_num_decoded_frames_value; + return self->private_impl.f_state; } -// -------- func gif.decoder.frame_dirty_rect +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func crc64.ecma_hasher.up_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_gif__decoder__frame_dirty_rect( - const wuffs_gif__decoder* self) { +static wuffs_base__empty_struct +wuffs_crc64__ecma_hasher__up_x86_sse42( + wuffs_crc64__ecma_hasher* self, + wuffs_base__slice_u8 a_x) { + uint64_t v_s = 0; + wuffs_base__slice_u8 v_p = {0}; + uint8_t v_buf[48] = {0}; + __m128i v_xa = {0}; + __m128i v_xb = {0}; + __m128i v_xc = {0}; + __m128i v_xd = {0}; + __m128i v_xe = {0}; + __m128i v_xf = {0}; + __m128i v_xg = {0}; + __m128i v_xh = {0}; + __m128i v_mu1 = {0}; + __m128i v_mu2 = {0}; + __m128i v_mu4 = {0}; + __m128i v_mu8 = {0}; + __m128i v_mupx = {0}; + + v_s = (18446744073709551615u ^ self->private_impl.f_state); + while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) { + v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ a_x.ptr[0u]))] ^ (v_s >> 8u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); + } + do { + do { + if (((uint64_t)(a_x.len)) >= 128u) { + } else if (((uint64_t)(a_x.len)) >= 64u) { + v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s))); + v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); + v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)); + v_xd = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 64u); + break; + } else if (((uint64_t)(a_x.len)) >= 32u) { + v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s))); + v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 32u); + goto label__chain2__break; + } else { + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 1; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end0_p) { + v_s = (WUFFS_CRC64__ECMA_TABLE[0u][((uint8_t)(((uint8_t)(v_s)) ^ v_p.ptr[0u]))] ^ (v_s >> 8u)); + v_p.ptr += 1; + } + v_p.len = 0; + } + self->private_impl.f_state = (18446744073709551615u ^ v_s); + return wuffs_base__make_empty_struct(); + } + v_xa = _mm_xor_si128(_mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u)), _mm_cvtsi64_si128((int64_t)(v_s))); + v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u)); + v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u)); + v_xd = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u)); + v_xe = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u)); + v_xf = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u)); + v_xg = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u)); + v_xh = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u)); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u); + v_mu8 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD8)); + while (((uint64_t)(a_x.len)) >= 128u) { + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u))); + v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u))); + v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u))); + v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u))); + v_xe = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xe, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xe, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 64u))); + v_xf = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xf, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xf, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 80u))); + v_xg = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xg, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xg, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 96u))); + v_xh = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xh, v_mu8, (int32_t)(0u)), _mm_clmulepi64_si128(v_xh, v_mu8, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 112u))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 128u); + } + v_mu4 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD4)); + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(17u))), v_xe); + v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(17u))), v_xf); + v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(17u))), v_xg); + v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(17u))), v_xh); + if (((uint64_t)(a_x.len)) > 64u) { + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u))); + v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u))); + v_xc = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xc, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u))); + v_xd = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(0u)), _mm_clmulepi64_si128(v_xd, v_mu4, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 64u); + } + } while (0); + v_mu2 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD2)); + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u))), v_xc); + v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(17u))), v_xd); + if (((uint64_t)(a_x.len)) > 32u) { + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u))); + v_xb = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu2, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 32u); + } + } while (0); + label__chain2__break:; + v_mu1 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD1)); + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(17u))), v_xb); + if (((uint64_t)(a_x.len)) > 24u) { + v_xa = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu1, (int32_t)(17u))), _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u))); + a_x = wuffs_base__slice_u8__subslice_i(a_x, 16u); + if (((uint64_t)(a_x.len)) > 24u) { + return wuffs_base__make_empty_struct(); + } + } + _mm_storeu_si128((__m128i*)(void*)(v_buf + (24u - ((uint64_t)(a_x.len)))), v_xa); + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(v_buf, ((24u - ((uint64_t)(a_x.len))) + 16u), 48), a_x); + v_mu2 = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_FOLD2)); + v_xa = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 0u)); + v_xb = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 16u)); + v_xc = _mm_lddqu_si128((const __m128i*)(const void*)(v_buf + 32u)); + v_xd = _mm_xor_si128(_mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(0u)), _mm_clmulepi64_si128(v_xa, v_mu2, (int32_t)(17u))); + v_xe = _mm_xor_si128(_mm_clmulepi64_si128(v_xb, v_mu1, (int32_t)(0u)), _mm_clmulepi64_si128(v_xb, v_mu1, (int32_t)(17u))); + v_xa = _mm_xor_si128(v_xd, _mm_xor_si128(v_xe, v_xc)); + v_mupx = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC64__ECMA_X86_SSE42_MUPX)); + v_xb = _mm_clmulepi64_si128(v_xa, v_mupx, (int32_t)(0u)); + v_xc = _mm_clmulepi64_si128(v_xb, v_mupx, (int32_t)(16u)); + v_s = ((uint64_t)(_mm_extract_epi64(_mm_xor_si128(_mm_xor_si128(v_xc, _mm_slli_si128(v_xb, (int32_t)(8u))), v_xa), (int32_t)(1u)))); + self->private_impl.f_state = (18446744073709551615u ^ v_s); + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC64) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) + +// ---------------- Status Codes Implementations + +const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)"; +const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)"; +const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count"; +const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition"; +const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code"; +const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length"; +const char wuffs_deflate__error__bad_block[] = "#deflate: bad block"; +const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance"; +const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count"; +const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count"; +const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length"; +const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code"; +const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes"; +const char wuffs_deflate__error__truncated_input[] = "#deflate: truncated input"; +const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state"; +const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O"; +const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance"; +const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits"; + +// ---------------- Private Consts + +static const uint8_t +WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = { + 16u, 17u, 18u, 0u, 8u, 7u, 9u, 6u, + 10u, 5u, 11u, 4u, 12u, 3u, 13u, 2u, + 14u, 1u, 15u, +}; + +static const uint8_t +WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 128u, 64u, 192u, 32u, 160u, 96u, 224u, + 16u, 144u, 80u, 208u, 48u, 176u, 112u, 240u, + 8u, 136u, 72u, 200u, 40u, 168u, 104u, 232u, + 24u, 152u, 88u, 216u, 56u, 184u, 120u, 248u, + 4u, 132u, 68u, 196u, 36u, 164u, 100u, 228u, + 20u, 148u, 84u, 212u, 52u, 180u, 116u, 244u, + 12u, 140u, 76u, 204u, 44u, 172u, 108u, 236u, + 28u, 156u, 92u, 220u, 60u, 188u, 124u, 252u, + 2u, 130u, 66u, 194u, 34u, 162u, 98u, 226u, + 18u, 146u, 82u, 210u, 50u, 178u, 114u, 242u, + 10u, 138u, 74u, 202u, 42u, 170u, 106u, 234u, + 26u, 154u, 90u, 218u, 58u, 186u, 122u, 250u, + 6u, 134u, 70u, 198u, 38u, 166u, 102u, 230u, + 22u, 150u, 86u, 214u, 54u, 182u, 118u, 246u, + 14u, 142u, 78u, 206u, 46u, 174u, 110u, 238u, + 30u, 158u, 94u, 222u, 62u, 190u, 126u, 254u, + 1u, 129u, 65u, 193u, 33u, 161u, 97u, 225u, + 17u, 145u, 81u, 209u, 49u, 177u, 113u, 241u, + 9u, 137u, 73u, 201u, 41u, 169u, 105u, 233u, + 25u, 153u, 89u, 217u, 57u, 185u, 121u, 249u, + 5u, 133u, 69u, 197u, 37u, 165u, 101u, 229u, + 21u, 149u, 85u, 213u, 53u, 181u, 117u, 245u, + 13u, 141u, 77u, 205u, 45u, 173u, 109u, 237u, + 29u, 157u, 93u, 221u, 61u, 189u, 125u, 253u, + 3u, 131u, 67u, 195u, 35u, 163u, 99u, 227u, + 19u, 147u, 83u, 211u, 51u, 179u, 115u, 243u, + 11u, 139u, 75u, 203u, 43u, 171u, 107u, 235u, + 27u, 155u, 91u, 219u, 59u, 187u, 123u, 251u, + 7u, 135u, 71u, 199u, 39u, 167u, 103u, 231u, + 23u, 151u, 87u, 215u, 55u, 183u, 119u, 247u, + 15u, 143u, 79u, 207u, 47u, 175u, 111u, 239u, + 31u, 159u, 95u, 223u, 63u, 191u, 127u, 255u, +}; + +static const uint32_t +WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1073741824u, 1073742080u, 1073742336u, 1073742592u, 1073742848u, 1073743104u, 1073743360u, 1073743616u, + 1073743888u, 1073744400u, 1073744912u, 1073745424u, 1073745952u, 1073746976u, 1073748000u, 1073749024u, + 1073750064u, 1073752112u, 1073754160u, 1073756208u, 1073758272u, 1073762368u, 1073766464u, 1073770560u, + 1073774672u, 1073782864u, 1073791056u, 1073799248u, 1073807104u, 134217728u, 134217728u, 134217728u, +}; + +static const uint32_t +WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1073741824u, 1073742080u, 1073742336u, 1073742592u, 1073742864u, 1073743376u, 1073743904u, 1073744928u, + 1073745968u, 1073748016u, 1073750080u, 1073754176u, 1073758288u, 1073766480u, 1073774688u, 1073791072u, + 1073807472u, 1073840240u, 1073873024u, 1073938560u, 1074004112u, 1074135184u, 1074266272u, 1074528416u, + 1074790576u, 1075314864u, 1075839168u, 1076887744u, 1077936336u, 1080033488u, 134217728u, 134217728u, +}; + +#define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024u + +#define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__do_transform_io( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_blocks( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_uncompressed( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__init_fixed_huffman( + wuffs_deflate__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__init_dynamic_huffman( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__init_huff( + wuffs_deflate__decoder* self, + uint32_t a_which, + uint32_t a_n_codes0, + uint32_t a_n_codes1, + uint32_t a_base_symbol); + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_bmi2( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_fast32( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_fast64( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_slow( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_deflate__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_deflate__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_deflate__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_deflate__decoder__initialize( + wuffs_deflate__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); } - return wuffs_base__utility__make_rect_ie_u32( - wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width), - wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height), - wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width), - wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height)); + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default; + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_deflate__decoder* +wuffs_deflate__decoder__alloc(void) { + wuffs_deflate__decoder* x = + (wuffs_deflate__decoder*)(calloc(1, sizeof(wuffs_deflate__decoder))); + if (!x) { + return NULL; + } + if (wuffs_deflate__decoder__initialize( + x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_deflate__decoder(void) { + return sizeof(wuffs_deflate__decoder); } -// -------- func gif.decoder.history_retain_length +// ---------------- Function Implementations + +// -------- func deflate.decoder.add_history WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gif__decoder__history_retain_length( - const wuffs_gif__decoder* self) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_deflate__decoder__add_history( + wuffs_deflate__decoder* self, + wuffs_base__slice_u8 a_hist) { if (!self) { - return 0; + return wuffs_base__make_empty_struct(); } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); } - return 0u; + wuffs_base__slice_u8 v_s = {0}; + uint64_t v_n_copied = 0; + uint32_t v_already_full = 0; + + v_s = a_hist; + if (((uint64_t)(v_s.len)) >= 32768u) { + v_s = wuffs_private_impl__slice_u8__suffix(v_s, 32768u); + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s); + self->private_impl.f_history_index = 32768u; + } else { + v_n_copied = wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, (self->private_impl.f_history_index & 32767u), 32768), v_s); + if (v_n_copied < ((uint64_t)(v_s.len))) { + v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied); + v_n_copied = wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s); + self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767u))) + 32768u); + } else { + v_already_full = 0u; + if (self->private_impl.f_history_index >= 32768u) { + v_already_full = 32768u; + } + self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767u) + ((uint32_t)((v_n_copied & 32767u))) + v_already_full); + } + } + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, 32768, 33025), wuffs_base__make_slice_u8(self->private_data.f_history, 33025)); + return wuffs_base__make_empty_struct(); } -// -------- func gif.decoder.workbuf_len +// -------- func deflate.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_gif__decoder__workbuf_len( - const wuffs_gif__decoder* self) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_deflate__decoder__get_quirk( + const wuffs_deflate__decoder* self, + uint32_t a_key) { if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); + return 0; } if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + return 0; } - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + return 0u; } -// -------- func gif.decoder.restart_frame +// -------- func deflate.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__restart_frame( - wuffs_gif__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { +wuffs_deflate__decoder__set_quirk( + wuffs_deflate__decoder* self, + uint32_t a_key, + uint64_t a_value) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -37252,28 +38578,52 @@ wuffs_gif__decoder__restart_frame( : wuffs_base__error__initialize_not_called); } - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } else if (a_io_position == 0u) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func deflate.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_deflate__decoder__dst_history_retain_length( + const wuffs_deflate__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); } - self->private_impl.f_delayed_num_decoded_frames = false; - self->private_impl.f_frame_config_io_position = a_io_position; - self->private_impl.f_num_decoded_frame_configs_value = a_index; - self->private_impl.f_num_decoded_frames_value = a_index; - wuffs_gif__decoder__reset_gc(self); - self->private_impl.f_call_sequence = 40u; - return wuffs_base__make_status(NULL); + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_base__utility__make_optional_u63(true, 0u); } -// -------- func gif.decoder.decode_frame_config +// -------- func deflate.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_deflate__decoder__workbuf_len( + const wuffs_deflate__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(1u, 1u); +} + +// -------- func deflate.decoder.transform_io WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__decode_frame_config( - wuffs_gif__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { +wuffs_deflate__decoder__transform_io( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -37283,12 +38633,12 @@ wuffs_gif__decoder__decode_frame_config( ? wuffs_base__error__disabled_by_previous_error : wuffs_base__error__initialize_not_called); } - if (!a_src) { + if (!a_dst || !a_src) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { + (self->private_impl.active_coroutine != 1)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -37297,17 +38647,17 @@ wuffs_gif__decoder__decode_frame_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_transform_io; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame_config(self, a_dst, a_src); + wuffs_base__status t_0 = wuffs_deflate__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_gif__error__truncated_input); + status = wuffs_base__make_status(wuffs_deflate__error__truncated_input); goto exit; } status = v_status; @@ -37315,14 +38665,14 @@ wuffs_gif__decoder__decode_frame_config( } ok: - self->private_impl.p_decode_frame_config[0] = 0; + self->private_impl.p_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; goto exit; exit: @@ -37332,403 +38682,103 @@ wuffs_gif__decoder__decode_frame_config( return status; } -// -------- func gif.decoder.do_decode_frame_config +// -------- func deflate.decoder.do_transform_io WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__do_decode_frame_config( - wuffs_gif__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { +wuffs_deflate__decoder__do_transform_io( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_background_color = 0; - uint8_t v_flags = 0; + uint64_t v_mark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; - if (coro_susp_point) { - v_background_color = self->private_data.s_do_decode_frame_config[0].v_background_color; - } + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - self->private_impl.f_dirty_max_excl_y = 0u; - if ((self->private_impl.f_call_sequence & 16u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + self->private_impl.choosy_decode_huffman_fast64 = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) + wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 : +#endif + self->private_impl.choosy_decode_huffman_fast64); + while (true) { + v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src); + v_status = t_0; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_gif__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; - } - } else if (self->private_impl.f_call_sequence == 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_gif__decoder__skip_frame(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_call_sequence >= 96u) { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - if ((self->private_impl.f_num_decoded_frame_configs_value > 0u) || (self->private_impl.f_call_sequence == 40u)) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_call_sequence >= 96u) { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - } - v_background_color = self->private_impl.f_black_color_u32_argb_premul; - if ( ! self->private_impl.f_gc_has_transparent_index) { - v_background_color = self->private_impl.f_background_color_u32_argb_premul; - if (self->private_impl.f_quirks[1u] && (self->private_impl.f_num_decoded_frame_configs_value == 0u)) { - while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - } - v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if ((v_flags & 128u) != 0u) { - v_background_color = self->private_impl.f_black_color_u32_argb_premul; + if ( ! wuffs_base__status__is_suspension(&v_status)) { + status = v_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; } - } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width), - wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height), - wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width), - wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)), - ((wuffs_base__flicks)(self->private_impl.f_gc_duration)), - self->private_impl.f_num_decoded_frame_configs_value, - self->private_impl.f_frame_config_io_position, - self->private_impl.f_gc_disposal, - ! self->private_impl.f_gc_has_transparent_index, - false, - v_background_color); - } - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u); - self->private_impl.f_call_sequence = 64u; - - ok: - self->private_impl.p_do_decode_frame_config[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_frame_config[0].v_background_color = v_background_color; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func gif.decoder.skip_frame - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__skip_frame( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_flags = 0; - uint8_t v_lw = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_skip_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_flags = t_0; - } - if ((v_flags & 128u) != 0u) { - self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3u)) << (1u + (v_flags & 7u))); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_skip_frame[0].scratch; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_lw = t_1; - } - if (v_lw > 8u) { - status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - status = wuffs_gif__decoder__skip_blocks(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_quirks[0u]) { - self->private_impl.f_delayed_num_decoded_frames = true; - } else { - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); - } - wuffs_gif__decoder__reset_gc(self); - self->private_impl.f_call_sequence = 32u; - - goto ok; - ok: - self->private_impl.p_skip_frame[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func gif.decoder.decode_frame - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gif__decoder__decode_frame( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_gif__error__truncated_input); - goto exit; - } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)))); + wuffs_deflate__decoder__add_history(self, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); status = v_status; WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } ok: - self->private_impl.p_decode_frame[0] = 0; + self->private_impl.p_do_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} - -// -------- func gif.decoder.do_decode_frame - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__do_decode_frame( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_gif__decoder__do_decode_frame_config(self, NULL, a_src); - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - if (self->private_impl.f_quirks[5u] && ((self->private_impl.f_frame_rect_x0 == self->private_impl.f_frame_rect_x1) || (self->private_impl.f_frame_rect_y0 == self->private_impl.f_frame_rect_y1))) { - status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size); - goto exit; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend); - if (status.repr) { - goto suspend; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf); - if (status.repr) { - goto suspend; - } - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); - wuffs_gif__decoder__reset_gc(self); - self->private_impl.f_call_sequence = 32u; - - ok: - self->private_impl.p_do_decode_frame[0] = 0; - goto exit; + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); } - goto suspend; - suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: return status; } -// -------- func gif.decoder.reset_gc - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_gif__decoder__reset_gc( - wuffs_gif__decoder* self) { - self->private_impl.f_gc_has_transparent_index = false; - self->private_impl.f_gc_transparent_index = 0u; - self->private_impl.f_gc_disposal = 0u; - self->private_impl.f_gc_duration = 0u; - return wuffs_base__make_empty_struct(); -} - -// -------- func gif.decoder.decode_up_to_id_part1 +// -------- func deflate.decoder.decode_blocks WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_up_to_id_part1( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__decode_blocks( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_block_type = 0; + uint32_t v_final = 0; + uint32_t v_b0 = 0; + uint32_t v_type = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -37741,71 +38791,125 @@ wuffs_gif__decoder__decode_up_to_id_part1( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_blocks; + if (coro_susp_point) { + v_final = self->private_data.s_decode_blocks.v_final; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_frame_config_io_position == 0u) || (self->private_impl.f_num_decoded_frame_configs_value > 0u)) { - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + label__outer__continue:; + while (v_final == 0u) { + while (self->private_impl.f_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_0 = *iop_a_src++; + v_b0 = t_0; } - uint8_t t_0 = *iop_a_src++; - v_block_type = t_0; + self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3u)); + self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3u) + 8u); } - if (v_block_type == 33u) { + v_final = (self->private_impl.f_bits & 1u); + v_type = ((self->private_impl.f_bits >> 1u) & 3u); + self->private_impl.f_bits >>= 3u; + self->private_impl.f_n_bits -= 3u; + if (v_type == 0u) { if (a_src) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_gif__decoder__decode_extension(self, a_src); + status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } if (status.repr) { goto suspend; } - } else if (v_block_type == 44u) { - if (self->private_impl.f_delayed_num_decoded_frames) { - self->private_impl.f_delayed_num_decoded_frames = false; - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + continue; + } else if (v_type == 1u) { + v_status = wuffs_deflate__decoder__init_fixed_huffman(self); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; } + } else if (v_type == 2u) { if (a_src) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_gif__decoder__decode_id_part0(self, a_src); + status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } if (status.repr) { goto suspend; } - break; } else { - if (self->private_impl.f_delayed_num_decoded_frames) { - self->private_impl.f_delayed_num_decoded_frames = false; - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + status = wuffs_base__make_status(wuffs_deflate__error__bad_block); + goto exit; + } + self->private_impl.f_end_of_block = false; + while (true) { + if (sizeof(void*) == 4u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } else { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; + } + if (self->private_impl.f_end_of_block) { + goto label__outer__continue; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_end_of_block) { + goto label__outer__continue; } - self->private_impl.f_call_sequence = 96u; - break; } } - goto ok; ok: - self->private_impl.p_decode_up_to_id_part1[0] = 0; + self->private_impl.p_decode_blocks = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_blocks = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_blocks.v_final = v_final; goto exit; exit: @@ -37816,18 +38920,32 @@ wuffs_gif__decoder__decode_up_to_id_part1( return status; } -// -------- func gif.decoder.decode_header +// -------- func deflate.decoder.decode_uncompressed WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_header( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__decode_uncompressed( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c[6] = {0}; - uint32_t v_i = 0; + uint32_t v_length = 0; + uint32_t v_n_copied = 0; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -37839,50 +38957,85 @@ wuffs_gif__decoder__decode_header( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_header[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed; if (coro_susp_point) { - memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c)); - v_i = self->private_data.s_decode_header[0].v_i; + v_length = self->private_data.s_decode_uncompressed.v_length; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - while (v_i < 6u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_n_bits = 0u; + self->private_impl.f_bits = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_uncompressed.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_uncompressed.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; } - uint8_t t_0 = *iop_a_src++; - v_c[v_i] = t_0; } - v_i += 1u; + v_length = t_0; } - if ((v_c[0u] != 71u) || - (v_c[1u] != 73u) || - (v_c[2u] != 70u) || - (v_c[3u] != 56u) || - ((v_c[4u] != 55u) && (v_c[4u] != 57u)) || - (v_c[5u] != 97u)) { - status = wuffs_base__make_status(wuffs_gif__error__bad_header); + if ((((v_length) & 0xFFFFu) + ((v_length) >> (32u - 16u))) != 65535u) { + status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length); goto exit; } + v_length = ((v_length) & 0xFFFFu); + while (true) { + v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_reader( + &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src); + if (v_length <= v_n_copied) { + status = wuffs_base__make_status(NULL); + goto ok; + } + v_length -= v_n_copied; + if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + } else { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + } + } - goto ok; ok: - self->private_impl.p_decode_header[0] = 0; + self->private_impl.p_decode_uncompressed = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c)); - self->private_data.s_decode_header[0].v_i = v_i; + self->private_impl.p_decode_uncompressed = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_uncompressed.v_length = v_length; goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -37890,21 +39043,80 @@ wuffs_gif__decoder__decode_header( return status; } -// -------- func gif.decoder.decode_lsd +// -------- func deflate.decoder.init_fixed_huffman WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_lsd( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__init_fixed_huffman( + wuffs_deflate__decoder* self) { + uint32_t v_i = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + while (v_i < 144u) { + self->private_data.f_code_lengths[v_i] = 8u; + v_i += 1u; + } + while (v_i < 256u) { + self->private_data.f_code_lengths[v_i] = 9u; + v_i += 1u; + } + while (v_i < 280u) { + self->private_data.f_code_lengths[v_i] = 7u; + v_i += 1u; + } + while (v_i < 288u) { + self->private_data.f_code_lengths[v_i] = 8u; + v_i += 1u; + } + while (v_i < 320u) { + self->private_data.f_code_lengths[v_i] = 5u; + v_i += 1u; + } + v_status = wuffs_deflate__decoder__init_huff(self, + 0u, + 0u, + 288u, + 257u); + if (wuffs_base__status__is_error(&v_status)) { + return v_status; + } + v_status = wuffs_deflate__decoder__init_huff(self, + 1u, + 288u, + 320u, + 0u); + if (wuffs_base__status__is_error(&v_status)) { + return v_status; + } + return wuffs_base__make_status(NULL); +} + +// -------- func deflate.decoder.init_dynamic_huffman + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__init_dynamic_huffman( + wuffs_deflate__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_flags = 0; - uint8_t v_background_color_index = 0; - uint32_t v_num_palette_entries = 0; + uint32_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_b0 = 0; + uint32_t v_n_lit = 0; + uint32_t v_n_dist = 0; + uint32_t v_n_clen = 0; uint32_t v_i = 0; - uint32_t v_j = 0; - uint32_t v_argb = 0; + uint32_t v_b1 = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_mask = 0; + uint32_t v_table_entry = 0; + uint32_t v_table_entry_n_bits = 0; + uint32_t v_b2 = 0; + uint32_t v_n_extra_bits = 0; + uint8_t v_rep_symbol = 0; + uint32_t v_rep_count = 0; + uint32_t v_b3 = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -37917,172 +39129,215 @@ wuffs_gif__decoder__decode_lsd( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0]; + uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman; if (coro_susp_point) { - v_flags = self->private_data.s_decode_lsd[0].v_flags; - v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index; - v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries; - v_i = self->private_data.s_decode_lsd[0].v_i; + v_bits = self->private_data.s_init_dynamic_huffman.v_bits; + v_n_bits = self->private_data.s_init_dynamic_huffman.v_n_bits; + v_n_lit = self->private_data.s_init_dynamic_huffman.v_n_lit; + v_n_dist = self->private_data.s_init_dynamic_huffman.v_n_dist; + v_n_clen = self->private_data.s_init_dynamic_huffman.v_n_clen; + v_i = self->private_data.s_init_dynamic_huffman.v_i; + v_mask = self->private_data.s_init_dynamic_huffman.v_mask; + v_n_extra_bits = self->private_data.s_init_dynamic_huffman.v_n_extra_bits; + v_rep_symbol = self->private_data.s_init_dynamic_huffman.v_rep_symbol; + v_rep_count = self->private_data.s_init_dynamic_huffman.v_rep_count; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_lsd[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { + v_bits = self->private_impl.f_bits; + v_n_bits = self->private_impl.f_n_bits; + while (v_n_bits < 14u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_0 = *iop_a_src++; + v_b0 = t_0; + } + v_bits |= (v_b0 << v_n_bits); + v_n_bits += 8u; + } + v_n_lit = (((v_bits) & 0x1Fu) + 257u); + if (v_n_lit > 286u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count); + goto exit; + } + v_bits >>= 5u; + v_n_dist = (((v_bits) & 0x1Fu) + 1u); + if (v_n_dist > 30u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count); + goto exit; + } + v_bits >>= 5u; + v_n_clen = (((v_bits) & 0xFu) + 4u); + v_bits >>= 4u; + v_n_bits -= 14u; + v_i = 0u; + while (v_i < v_n_clen) { + while (v_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 8) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; + uint32_t t_1 = *iop_a_src++; + v_b1 = t_1; } + v_bits |= (v_b1 << v_n_bits); + v_n_bits += 8u; } - self->private_impl.f_width = t_0; + self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7u))); + v_bits >>= 3u; + v_n_bits -= 3u; + v_i += 1u; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_lsd[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { + while (v_i < 19u) { + self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0u; + v_i += 1u; + } + v_status = wuffs_deflate__decoder__init_huff(self, + 0u, + 0u, + 19u, + 4095u); + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; + } + v_mask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); + v_i = 0u; + while (v_i < (v_n_lit + v_n_dist)) { + while (true) { + v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_mask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + if (v_n_bits >= v_table_entry_n_bits) { + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 8) { - t_1 = ((uint32_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; + uint32_t t_2 = *iop_a_src++; + v_b2 = t_2; } + v_bits |= (v_b2 << v_n_bits); + v_n_bits += 8u; } - self->private_impl.f_height = t_1; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if ((v_table_entry >> 24u) != 128u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - uint8_t t_2 = *iop_a_src++; - v_flags = t_2; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_table_entry = ((v_table_entry >> 8u) & 255u); + if (v_table_entry < 16u) { + self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry)); + v_i += 1u; + continue; } - uint8_t t_3 = *iop_a_src++; - v_background_color_index = t_3; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src++; - v_i = 0u; - self->private_impl.f_has_global_palette = ((v_flags & 128u) != 0u); - if (self->private_impl.f_has_global_palette) { - v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u))); - while (v_i < v_num_palette_entries) { + v_n_extra_bits = 0u; + v_rep_symbol = 0u; + v_rep_count = 0u; + if (v_table_entry == 16u) { + v_n_extra_bits = 2u; + if (v_i <= 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition); + goto exit; + } + v_rep_symbol = ((uint8_t)(self->private_data.f_code_lengths[(v_i - 1u)] & 15u)); + v_rep_count = 3u; + } else if (v_table_entry == 17u) { + v_n_extra_bits = 3u; + v_rep_symbol = 0u; + v_rep_count = 3u; + } else if (v_table_entry == 18u) { + v_n_extra_bits = 7u; + v_rep_symbol = 0u; + v_rep_count = 11u; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } + while (v_n_bits < v_n_extra_bits) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { - t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); - iop_a_src += 3; - } else { - self->private_data.s_decode_lsd[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); - if (num_bits_4 == 16) { - t_4 = ((uint32_t)(*scratch >> 40)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)); - } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_argb = t_4; + uint32_t t_3 = *iop_a_src++; + v_b3 = t_3; } - v_argb |= 4278190080u; - self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); - self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); - self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); - self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); - v_i += 1u; + v_bits |= (v_b3 << v_n_bits); + v_n_bits += 8u; } - if (self->private_impl.f_quirks[2u]) { - if ((v_background_color_index != 0u) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) { - v_j = (4u * ((uint32_t)(v_background_color_index))); - self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0u][(v_j + 0u)])) << 0u) | - (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 1u)])) << 8u) | - (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 2u)])) << 16u) | - (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 3u)])) << 24u)); - } else { - self->private_impl.f_background_color_u32_argb_premul = 77u; + v_rep_count += ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_n_extra_bits)); + v_bits >>= v_n_extra_bits; + v_n_bits -= v_n_extra_bits; + while (v_rep_count > 0u) { + if (v_i >= (v_n_lit + v_n_dist)) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count); + goto exit; } + self->private_data.f_code_lengths[v_i] = v_rep_symbol; + v_i += 1u; + v_rep_count -= 1u; } } - while (v_i < 256u) { - self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = 0u; - self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = 0u; - self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = 0u; - self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = 255u; - v_i += 1u; + if (v_i != (v_n_lit + v_n_dist)) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count); + goto exit; + } + if (self->private_data.f_code_lengths[256u] == 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code); + goto exit; + } + v_status = wuffs_deflate__decoder__init_huff(self, + 0u, + 0u, + v_n_lit, + 257u); + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; + } + v_status = wuffs_deflate__decoder__init_huff(self, + 1u, + v_n_lit, + (v_n_lit + v_n_dist), + 0u); + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; } + self->private_impl.f_bits = v_bits; + self->private_impl.f_n_bits = v_n_bits; goto ok; ok: - self->private_impl.p_decode_lsd[0] = 0; + self->private_impl.p_init_dynamic_huffman = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_lsd[0].v_flags = v_flags; - self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index; - self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries; - self->private_data.s_decode_lsd[0].v_i = v_i; + self->private_impl.p_init_dynamic_huffman = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_init_dynamic_huffman.v_bits = v_bits; + self->private_data.s_init_dynamic_huffman.v_n_bits = v_n_bits; + self->private_data.s_init_dynamic_huffman.v_n_lit = v_n_lit; + self->private_data.s_init_dynamic_huffman.v_n_dist = v_n_dist; + self->private_data.s_init_dynamic_huffman.v_n_clen = v_n_clen; + self->private_data.s_init_dynamic_huffman.v_i = v_i; + self->private_data.s_init_dynamic_huffman.v_mask = v_mask; + self->private_data.s_init_dynamic_huffman.v_n_extra_bits = v_n_extra_bits; + self->private_data.s_init_dynamic_huffman.v_rep_symbol = v_rep_symbol; + self->private_data.s_init_dynamic_huffman.v_rep_count = v_rep_count; goto exit; exit: @@ -38093,185 +39348,299 @@ wuffs_gif__decoder__decode_lsd( return status; } -// -------- func gif.decoder.decode_extension +// -------- func deflate.decoder.init_huff WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_extension( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_label = 0; +wuffs_deflate__decoder__init_huff( + wuffs_deflate__decoder* self, + uint32_t a_which, + uint32_t a_n_codes0, + uint32_t a_n_codes1, + uint32_t a_base_symbol) { + uint16_t v_counts[16] = {0}; + uint32_t v_i = 0; + uint32_t v_remaining = 0; + uint16_t v_offsets[16] = {0}; + uint32_t v_n_symbols = 0; + uint32_t v_count = 0; + uint16_t v_symbols[320] = {0}; + uint32_t v_min_cl = 0; + uint32_t v_max_cl = 0; + uint32_t v_initial_high_bits = 0; + uint32_t v_prev_cl = 0; + uint32_t v_prev_redirect_key = 0; + uint32_t v_top = 0; + uint32_t v_next_top = 0; + uint32_t v_code = 0; + uint32_t v_key = 0; + uint32_t v_value = 0; + uint32_t v_cl = 0; + uint32_t v_redirect_key = 0; + uint32_t v_j = 0; + uint32_t v_reversed_key = 0; + uint32_t v_symbol = 0; + uint32_t v_high_bits = 0; + uint32_t v_delta = 0; - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + v_i = a_n_codes0; + while (v_i < a_n_codes1) { + if (v_counts[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] >= 320u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_counts[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_i += 1u; } - - uint32_t coro_susp_point = self->private_impl.p_decode_extension[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_label = t_0; + if ((((uint32_t)(v_counts[0u])) + a_n_codes0) == a_n_codes1) { + return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes); + } + v_remaining = 1u; + v_i = 1u; + while (v_i <= 15u) { + if (v_remaining > 1073741824u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); } - if (v_label == 249u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_gif__decoder__decode_gc(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - status = wuffs_base__make_status(NULL); - goto ok; - } else if (v_label == 255u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_gif__decoder__decode_ae(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + v_remaining <<= 1u; + if (v_remaining < ((uint32_t)(v_counts[v_i]))) { + return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed); + } + v_remaining -= ((uint32_t)(v_counts[v_i])); + v_i += 1u; + } + if (v_remaining != 0u) { + if ((a_which == 1u) && (v_counts[1u] == 1u) && ((((uint32_t)(v_counts[0u])) + a_n_codes0 + 1u) == a_n_codes1)) { + v_i = 0u; + while (v_i <= 29u) { + if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1u) { + self->private_impl.f_n_huffs_bits[1u] = 1u; + self->private_data.f_huffs[1u][0u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1u); + self->private_data.f_huffs[1u][1u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31u] | 1u); + return wuffs_base__make_status(NULL); + } + v_i += 1u; } - status = wuffs_base__make_status(NULL); - goto ok; } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed); + } + v_i = 1u; + while (v_i <= 15u) { + v_offsets[v_i] = ((uint16_t)(v_n_symbols)); + v_count = ((uint32_t)(v_counts[v_i])); + if (v_n_symbols > (320u - v_count)) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - status = wuffs_gif__decoder__skip_blocks(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + v_n_symbols = (v_n_symbols + v_count); + v_i += 1u; + } + if (v_n_symbols > 288u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_i = a_n_codes0; + while (v_i < a_n_codes1) { + if (v_i < a_n_codes0) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); } - if (status.repr) { - goto suspend; + if (self->private_data.f_code_lengths[v_i] != 0u) { + if (v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] >= 320u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_symbols[v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))]] = ((uint16_t)((v_i - a_n_codes0))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_offsets[((uint8_t)(self->private_data.f_code_lengths[v_i] & 15u))] += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif } - - ok: - self->private_impl.p_decode_extension[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + v_i += 1u; } - - return status; -} - -// -------- func gif.decoder.skip_blocks - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_gif__decoder__skip_blocks( - wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_block_size = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + v_min_cl = 1u; + while (true) { + if (v_counts[v_min_cl] != 0u) { + break; + } + if (v_min_cl >= 9u) { + return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length); + } + v_min_cl += 1u; } - - uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_max_cl = 15u; + while (true) { + if (v_counts[v_max_cl] != 0u) { + break; + } + if (v_max_cl <= 1u) { + return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes); + } + v_max_cl -= 1u; + } + if (v_max_cl <= 9u) { + self->private_impl.f_n_huffs_bits[a_which] = v_max_cl; + } else { + self->private_impl.f_n_huffs_bits[a_which] = 9u; + } + v_i = 0u; + if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15u])))) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + if ((a_n_codes0 + ((uint32_t)(v_symbols[0u]))) >= 320u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_initial_high_bits = 512u; + if (v_max_cl < 9u) { + v_initial_high_bits = (((uint32_t)(1u)) << v_max_cl); + } + v_prev_cl = ((uint32_t)(((uint8_t)(self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0u])))] & 15u)))); + v_prev_redirect_key = 4294967295u; + v_top = 0u; + v_next_top = 512u; + v_code = 0u; + v_key = 0u; + v_value = 0u; + while (true) { + if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_cl = ((uint32_t)(((uint8_t)(self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15u)))); + if (v_cl > v_prev_cl) { + v_code <<= (v_cl - v_prev_cl); + if (v_code >= 32768u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + } + v_prev_cl = v_cl; + v_key = v_code; + if (v_cl > 9u) { + v_cl -= 9u; + v_redirect_key = ((v_key >> v_cl) & 511u); + v_key = ((v_key) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_cl)); + if (v_prev_redirect_key != v_redirect_key) { + v_prev_redirect_key = v_redirect_key; + v_remaining = (((uint32_t)(1u)) << v_cl); + v_j = v_prev_cl; + while (v_j <= 15u) { + if (v_remaining <= ((uint32_t)(v_counts[v_j]))) { + break; + } + v_remaining -= ((uint32_t)(v_counts[v_j])); + if (v_remaining > 1073741824u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_remaining <<= 1u; + v_j += 1u; } - uint8_t t_0 = *iop_a_src++; - v_block_size = t_0; + if ((v_j <= 9u) || (15u < v_j)) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_j -= 9u; + v_initial_high_bits = (((uint32_t)(1u)) << v_j); + v_top = v_next_top; + if ((v_top + (((uint32_t)(1u)) << v_j)) > 1024u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_next_top = (v_top + (((uint32_t)(1u)) << v_j)); + v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1u)])) | ((v_redirect_key & 1u) << 8u)); + self->private_data.f_huffs[a_which][v_redirect_key] = (268435465u | (v_top << 8u) | (v_j << 4u)); } - if (v_block_size == 0u) { - status = wuffs_base__make_status(NULL); - goto ok; + } + if ((v_key >= 512u) || (v_counts[v_prev_cl] <= 0u)) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_counts[v_prev_cl] -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1u)])) | ((v_key & 1u) << 8u)); + v_reversed_key >>= (9u - v_cl); + v_symbol = ((uint32_t)(v_symbols[v_i])); + if (v_symbol == 256u) { + v_value = (536870912u | v_cl); + } else if ((v_symbol < 256u) && (a_which == 0u)) { + v_value = (2147483648u | (v_symbol << 8u) | v_cl); + } else if (v_symbol >= a_base_symbol) { + v_symbol -= a_base_symbol; + if (a_which == 0u) { + v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl); + } else { + v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl); } - self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + } else { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + } + v_high_bits = v_initial_high_bits; + v_delta = (((uint32_t)(1u)) << v_cl); + while (v_high_bits >= v_delta) { + v_high_bits -= v_delta; + if ((v_top + ((v_high_bits | v_reversed_key) & 511u)) >= 1024u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); } - iop_a_src += self->private_data.s_skip_blocks[0].scratch; + self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511u))] = v_value; + } + v_i += 1u; + if (v_i >= v_n_symbols) { + break; + } + v_code += 1u; + if (v_code >= 32768u) { + return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); } - - ok: - self->private_impl.p_skip_blocks[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - - return status; + return wuffs_base__make_status(NULL); } -// -------- func gif.decoder.decode_ae +// ‼ WUFFS MULTI-FILE SECTION +x86_bmi2 +// -------- func deflate.decoder.decode_huffman_bmi2 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2") WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_ae( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__decode_huffman_bmi2( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_block_size = 0; - bool v_is_animexts = false; - bool v_is_netscape = false; - bool v_is_iccp = false; - bool v_is_xmp = false; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_table_entry = 0; + uint32_t v_table_entry_n_bits = 0; + uint64_t v_lmask = 0; + uint64_t v_dmask = 0; + uint32_t v_redir_top = 0; + uint32_t v_redir_mask = 0; + uint32_t v_length = 0; + uint32_t v_dist_minus_1 = 0; + uint32_t v_hlen = 0; + uint32_t v_hdist = 0; + uint32_t v_hdist_adjustment = 0; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -38283,214 +39652,206 @@ wuffs_gif__decoder__decode_ae( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_ae[0]; - if (coro_susp_point) { - v_block_size = self->private_data.s_decode_ae[0].v_block_size; - v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts; - v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape; - v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp; - v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - do { - if (self->private_impl.f_metadata_fourcc != 0u) { - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_block_size = t_0; - } - if (v_block_size == 0u) { - status = wuffs_base__make_status(NULL); - goto ok; - } - if (v_block_size != 11u) { - self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_ae[0].scratch; + v_bits = ((uint64_t)(self->private_impl.f_bits)); + v_n_bits = self->private_impl.f_n_bits; + v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); + v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); + if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { + status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); + goto exit; + } + v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); + label__loop__continue:; + while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) { + v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u))); + iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; break; + } else if ((v_table_entry >> 28u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - v_is_animexts = true; - v_is_netscape = true; - v_is_iccp = true; - v_is_xmp = true; - v_block_size = 0u; - while (v_block_size < 11u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size])); - v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size])); - v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size])); - v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size])); -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_block_size += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } + v_length = (((v_table_entry >> 8u) & 255u) + 3u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_table_entry_n_bits > 0u) { + v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } + v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 28u) == 1u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } + if ((v_table_entry >> 24u) != 64u) { + if ((v_table_entry >> 24u) == 8u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; } - if (v_is_animexts || v_is_netscape) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - v_block_size = t_2; - } - if (v_block_size != 3u) { - self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_ae[0].scratch; - break; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } + v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + do { + if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_hlen = 0u; + v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_length > v_hdist) { + v_length -= v_hdist; + v_hlen = v_hdist; + } else { + v_hlen = v_length; + v_length = 0u; } - if (v_c != 1u) { - self->private_data.s_decode_ae[0].scratch = 2u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_ae[0].scratch; - break; + v_hdist += v_hdist_adjustment; + if (self->private_impl.f_history_index < v_hdist) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); + goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_ae[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 8) { - t_4 = ((uint32_t)(*scratch)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; - } - } - self->private_impl.f_num_animation_loops_value = t_4; + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); + if (v_length == 0u) { + goto label__loop__continue; } - self->private_impl.f_seen_num_animation_loops_value = true; - if ((0u < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535u)) { - self->private_impl.f_num_animation_loops_value += 1u; + if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); + goto exit; } - } else if (self->private_impl.f_call_sequence >= 32u) { - } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) { - self->private_impl.f_metadata_fourcc = 1229144912u; - self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - self->private_impl.f_call_sequence = 16u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; - } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) { - self->private_impl.f_metadata_fourcc = 1481461792u; - self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - self->private_impl.f_call_sequence = 16u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; + } + if ((v_dist_minus_1 + 1u) >= 8u) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } else if ((v_dist_minus_1 + 1u) == 1u) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } else { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); } } while (0); - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - status = wuffs_gif__decoder__skip_blocks(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + } + if (v_n_bits > 63u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; + } + while (v_n_bits >= 8u) { + v_n_bits -= 8u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); + goto exit; } - - ok: - self->private_impl.p_decode_ae[0] = 0; + } + self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u)))); + self->private_impl.f_n_bits = v_n_bits; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); goto exit; } - - goto suspend; - suspend: - self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_ae[0].v_block_size = v_block_size; - self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts; - self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape; - self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp; - self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp; - goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } return status; } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +// ‼ WUFFS MULTI-FILE SECTION -x86_bmi2 -// -------- func gif.decoder.decode_gc +// -------- func deflate.decoder.decode_huffman_fast32 WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_gc( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__decode_huffman_fast32( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_flags = 0; - uint16_t v_gc_duration_centiseconds = 0; + uint32_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_table_entry = 0; + uint32_t v_table_entry_n_bits = 0; + uint32_t v_lmask = 0; + uint32_t v_dmask = 0; + uint32_t v_redir_top = 0; + uint32_t v_redir_mask = 0; + uint32_t v_length = 0; + uint32_t v_dist_minus_1 = 0; + uint32_t v_hlen = 0; + uint32_t v_hdist = 0; + uint32_t v_hdist_adjustment = 0; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -38502,106 +39863,205 @@ wuffs_gif__decoder__decode_gc( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_gc[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; + } + v_bits = self->private_impl.f_bits; + v_n_bits = self->private_impl.f_n_bits; + v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); + v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); + if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { + status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); + goto exit; + } + v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); + label__loop__continue:; + while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12u)) { + if (v_n_bits < 15u) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + } else { } - if (v_c != 4u) { - status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control); + v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + if (v_n_bits < 15u) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + } else { + } + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_length = (((v_table_entry >> 8u) & 255u) + 3u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_table_entry_n_bits > 0u) { + if (v_n_bits < 15u) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + } else { } - uint8_t t_1 = *iop_a_src++; - v_flags = t_1; + v_length = (((v_length + 253u + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } else { } - self->private_impl.f_gc_has_transparent_index = ((v_flags & 1u) != 0u); - v_flags = ((v_flags >> 2u) & 7u); - if (v_flags == 2u) { - self->private_impl.f_gc_disposal = 1u; - } else if ((v_flags == 3u) || (v_flags == 4u)) { - self->private_impl.f_gc_disposal = 2u; + if (v_n_bits < 15u) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; } else { - self->private_impl.f_gc_disposal = 0u; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint16_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - iop_a_src += 2; + v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 28u) == 1u) { + if (v_n_bits < 15u) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; } else { - self->private_data.s_decode_gc[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; - if (num_bits_2 == 8) { - t_2 = ((uint16_t)(*scratch)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; - } } - v_gc_duration_centiseconds = t_2; + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } else { } - self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if ((v_table_entry >> 24u) != 64u) { + if ((v_table_entry >> 24u) == 8u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; } - uint8_t t_3 = *iop_a_src++; - self->private_impl.f_gc_transparent_index = t_3; + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; + v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_n_bits < v_table_entry_n_bits) { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; } - if (v_c != 0u) { - status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control); + v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + do { + if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_hlen = 0u; + v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_length > v_hdist) { + v_length -= v_hdist; + v_hlen = v_hdist; + } else { + v_hlen = v_length; + v_length = 0u; + } + v_hdist += v_hdist_adjustment; + if (self->private_impl.f_history_index < v_hdist) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); + goto exit; + } + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); + if (v_length == 0u) { + goto label__loop__continue; + } + if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); + goto exit; + } + } + if ((v_dist_minus_1 + 1u) >= 8u) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } else { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } + } while (0); + } + while (v_n_bits >= 8u) { + v_n_bits -= 8u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); goto exit; } - - goto ok; - ok: - self->private_impl.p_decode_gc[0] = 0; + } + self->private_impl.f_bits = (v_bits & ((((uint32_t)(1u)) << v_n_bits) - 1u)); + self->private_impl.f_n_bits = v_n_bits; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); goto exit; } - - goto suspend; - suspend: - self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -38609,15 +40069,52 @@ wuffs_gif__decoder__decode_gc( return status; } -// -------- func gif.decoder.decode_id_part0 +// -------- func deflate.decoder.decode_huffman_fast64 WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_id_part0( - wuffs_gif__decoder* self, +wuffs_deflate__decoder__decode_huffman_fast64( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src); +} + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_deflate__decoder__decode_huffman_fast64__choosy_default( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_table_entry = 0; + uint32_t v_table_entry_n_bits = 0; + uint64_t v_lmask = 0; + uint64_t v_dmask = 0; + uint32_t v_redir_top = 0; + uint32_t v_redir_mask = 0; + uint32_t v_length = 0; + uint32_t v_dist_minus_1 = 0; + uint32_t v_hlen = 0; + uint32_t v_hdist = 0; + uint32_t v_hdist_adjustment = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -38629,147 +40126,160 @@ wuffs_gif__decoder__decode_id_part0( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; + } + v_bits = ((uint64_t)(self->private_impl.f_bits)); + v_n_bits = self->private_impl.f_n_bits; + v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); + v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); + if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) { + status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); + goto exit; + } + v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))); + label__loop__continue:; + while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) { + v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u))); + iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 31u) != 0u) { + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; } else { - self->private_data.s_decode_id_part0[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 8) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; - } + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - self->private_impl.f_frame_rect_x0 = t_0; + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_id_part0[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 8) { - t_1 = ((uint32_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; - } - } - self->private_impl.f_frame_rect_y0 = t_1; + v_length = (((v_table_entry >> 8u) & 255u) + 3u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_table_entry_n_bits > 0u) { + v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_id_part0[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; - if (num_bits_2 == 8) { - t_2 = ((uint32_t)(*scratch)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; - } + v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + if ((v_table_entry >> 28u) == 1u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } + if ((v_table_entry >> 24u) != 64u) { + if ((v_table_entry >> 24u) == 8u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; } - self->private_impl.f_frame_rect_x1 = t_2; + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_id_part0[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; - if (num_bits_3 == 8) { - t_3 = ((uint32_t)(*scratch)); - break; - } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)) << 56; + v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + do { + if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_hlen = 0u; + v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_length > v_hdist) { + v_length -= v_hdist; + v_hlen = v_hdist; + } else { + v_hlen = v_length; + v_length = 0u; + } + v_hdist += v_hdist_adjustment; + if (self->private_impl.f_history_index < v_hdist) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); + goto exit; + } + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); + if (v_length == 0u) { + goto label__loop__continue; + } + if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance); + goto exit; } } - self->private_impl.f_frame_rect_y1 = t_3; - } - self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0; - self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; - self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0; - if ((self->private_impl.f_num_decoded_frame_configs_value == 0u) && ! self->private_impl.f_quirks[4u]) { - self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1); - self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1); + if ((v_dist_minus_1 + 1u) >= 8u) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } else if ((v_dist_minus_1 + 1u) == 1u) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } else { + wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + } + } while (0); + } + if (v_n_bits > 63u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; + } + while (v_n_bits >= 8u) { + v_n_bits -= 8u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o); + goto exit; } - - goto ok; - ok: - self->private_impl.p_decode_id_part0[0] = 0; + } + self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u)))); + self->private_impl.f_n_bits = v_n_bits; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); goto exit; } - - goto suspend; - suspend: - self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -38777,25 +40287,49 @@ wuffs_gif__decoder__decode_id_part0( return status; } -// -------- func gif.decoder.decode_id_part1 +// -------- func deflate.decoder.decode_huffman_slow WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_id_part1( - wuffs_gif__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend) { +wuffs_deflate__decoder__decode_huffman_slow( + wuffs_deflate__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_flags = 0; - uint8_t v_which_palette = 0; - uint32_t v_num_palette_entries = 0; - uint32_t v_i = 0; - uint32_t v_argb = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint8_t v_lw = 0; + uint32_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_table_entry = 0; + uint32_t v_table_entry_n_bits = 0; + uint32_t v_lmask = 0; + uint32_t v_dmask = 0; + uint32_t v_b0 = 0; + uint32_t v_redir_top = 0; + uint32_t v_redir_mask = 0; + uint32_t v_b1 = 0; + uint32_t v_length = 0; + uint32_t v_b2 = 0; + uint32_t v_b3 = 0; + uint32_t v_b4 = 0; + uint32_t v_dist_minus_1 = 0; + uint32_t v_b5 = 0; + uint32_t v_n_copied = 0; + uint32_t v_hlen = 0; + uint32_t v_hdist = 0; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -38807,139 +40341,275 @@ wuffs_gif__decoder__decode_id_part1( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow; if (coro_susp_point) { - v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette; - v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries; - v_i = self->private_data.s_decode_id_part1[0].v_i; + v_bits = self->private_data.s_decode_huffman_slow.v_bits; + v_n_bits = self->private_data.s_decode_huffman_slow.v_n_bits; + v_table_entry_n_bits = self->private_data.s_decode_huffman_slow.v_table_entry_n_bits; + v_lmask = self->private_data.s_decode_huffman_slow.v_lmask; + v_dmask = self->private_data.s_decode_huffman_slow.v_dmask; + v_redir_top = self->private_data.s_decode_huffman_slow.v_redir_top; + v_redir_mask = self->private_data.s_decode_huffman_slow.v_redir_mask; + v_length = self->private_data.s_decode_huffman_slow.v_length; + v_dist_minus_1 = self->private_data.s_decode_huffman_slow.v_dist_minus_1; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_flags = t_0; - } - if ((v_flags & 64u) != 0u) { - self->private_impl.f_interlace = 4u; - } else { - self->private_impl.f_interlace = 0u; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); + goto exit; } - v_which_palette = 1u; - if ((v_flags & 128u) != 0u) { - v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u))); - v_i = 0u; - while (v_i < v_num_palette_entries) { + v_bits = self->private_impl.f_bits; + v_n_bits = self->private_impl.f_n_bits; + v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u); + v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u); + label__loop__continue:; + while ( ! (self->private_impl.p_decode_huffman_slow != 0)) { + while (true) { + v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + if (v_n_bits >= v_table_entry_n_bits) { + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + break; + } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { - t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); - iop_a_src += 3; - } else { - self->private_data.s_decode_id_part1[0].scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_0 = *iop_a_src++; + v_b0 = t_0; + } + v_bits |= (v_b0 << v_n_bits); + v_n_bits += 8u; + } + if ((v_table_entry >> 31u) != 0u) { + self->private_data.s_decode_huffman_slow.scratch = ((uint8_t)((v_table_entry >> 8u))); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (iop_a_dst == io2_a_dst) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + goto suspend; + } + *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow.scratch)); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + while (true) { + v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + if (v_n_bits >= v_table_entry_n_bits) { + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + break; + } + { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 16) { - t_1 = ((uint32_t)(*scratch >> 40)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint32_t t_1 = *iop_a_src++; + v_b1 = t_1; } - v_argb = t_1; + v_bits |= (v_b1 << v_n_bits); + v_n_bits += 8u; } - v_argb |= 4278190080u; - self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); - self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); - self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); - self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); - v_i += 1u; + if ((v_table_entry >> 31u) != 0u) { + self->private_data.s_decode_huffman_slow.scratch = ((uint8_t)((v_table_entry >> 8u))); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (iop_a_dst == io2_a_dst) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + goto suspend; + } + *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow.scratch)); + continue; + } else if ((v_table_entry >> 30u) != 0u) { + } else if ((v_table_entry >> 29u) != 0u) { + self->private_impl.f_end_of_block = true; + break; + } else if ((v_table_entry >> 28u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; + } + } else if ((v_table_entry >> 27u) != 0u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); + goto exit; } - while (v_i < 256u) { - self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = 0u; - self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = 0u; - self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = 0u; - self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = 255u; - v_i += 1u; + v_length = (((v_table_entry >> 8u) & 255u) + 3u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_table_entry_n_bits > 0u) { + while (v_n_bits < v_table_entry_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_2 = *iop_a_src++; + v_b2 = t_2; + } + v_bits |= (v_b2 << v_n_bits); + v_n_bits += 8u; + } + v_length = (((v_length + 253u + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; } - } else if (self->private_impl.f_quirks[6u] && ! self->private_impl.f_has_global_palette) { - status = wuffs_base__make_status(wuffs_gif__error__bad_palette); - goto exit; - } else if (self->private_impl.f_gc_has_transparent_index) { - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1u], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0u], 1024)); - } else { - v_which_palette = 0u; - } - if (self->private_impl.f_gc_has_transparent_index) { - self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0u)] = 0u; - self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1u)] = 0u; - self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2u)] = 0u; - self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3u)] = 0u; - } - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), - wuffs_base__utility__make_pixel_format(2198077448u), - wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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); + while (true) { + v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)]; + v_table_entry_n_bits = (v_table_entry & 15u); + if (v_n_bits >= v_table_entry_n_bits) { + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_3 = *iop_a_src++; + v_b3 = t_3; + } + v_bits |= (v_b3 << v_n_bits); + v_n_bits += 8u; + } + if ((v_table_entry >> 28u) == 1u) { + v_redir_top = ((v_table_entry >> 8u) & 65535u); + v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u); + while (true) { + v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)]; + v_table_entry_n_bits = (v_table_entry & 15u); + if (v_n_bits >= v_table_entry_n_bits) { + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_4 = *iop_a_src++; + v_b4 = t_4; + } + v_bits |= (v_b4 << v_n_bits); + v_n_bits += 8u; + } + } + if ((v_table_entry >> 24u) != 64u) { + if ((v_table_entry >> 24u) == 8u) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code); + goto exit; + } + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state); goto exit; } - goto ok; - } - if (self->private_impl.f_ignored_but_affects_benchmarks) { - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u); + v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u); + if (v_table_entry_n_bits > 0u) { + while (v_n_bits < v_table_entry_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_5 = *iop_a_src++; + v_b5 = t_5; + } + v_bits |= (v_b5 << v_n_bits); + v_n_bits += 8u; + } + v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u); + v_bits >>= v_table_entry_n_bits; + v_n_bits -= v_table_entry_n_bits; + } + while (true) { + if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_hdist < v_length) { + v_hlen = v_hdist; + } else { + v_hlen = v_length; + } + v_hdist += ((uint32_t)(((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))))); + if (self->private_impl.f_history_index < v_hdist) { + status = wuffs_base__make_status(wuffs_deflate__error__bad_distance); + goto exit; + } + v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025)); + if (v_n_copied < v_hlen) { + v_length -= v_n_copied; + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + continue; + } + v_length -= v_hlen; + if (v_length == 0u) { + goto label__loop__continue; + } + } + v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_history( + &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u)); + if (v_length <= v_n_copied) { + goto label__loop__continue; + } + v_length -= v_n_copied; + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); } - uint8_t t_2 = *iop_a_src++; - v_lw = t_2; } - if (v_lw > 8u) { - status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width); + self->private_impl.f_bits = v_bits; + self->private_impl.f_n_bits = v_n_bits; + if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) { + status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits); goto exit; } - self->private_impl.f_lzw_pending_literal_width_plus_one = ((uint32_t)((1u + v_lw))); - self->private_impl.f_ignored_but_affects_benchmarks = true; ok: - self->private_impl.p_decode_id_part1[0] = 0; + self->private_impl.p_decode_huffman_slow = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette; - self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries; - self->private_data.s_decode_id_part1[0].v_i = v_i; + self->private_impl.p_decode_huffman_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_huffman_slow.v_bits = v_bits; + self->private_data.s_decode_huffman_slow.v_n_bits = v_n_bits; + self->private_data.s_decode_huffman_slow.v_table_entry_n_bits = v_table_entry_n_bits; + self->private_data.s_decode_huffman_slow.v_lmask = v_lmask; + self->private_data.s_decode_huffman_slow.v_dmask = v_dmask; + self->private_data.s_decode_huffman_slow.v_redir_top = v_redir_top; + self->private_data.s_decode_huffman_slow.v_redir_mask = v_redir_mask; + self->private_data.s_decode_huffman_slow.v_length = v_length; + self->private_data.s_decode_huffman_slow.v_dist_minus_1 = v_dist_minus_1; goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -38947,782 +40617,538 @@ wuffs_gif__decoder__decode_id_part1( return status; } -// -------- func gif.decoder.decode_id_part2 +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) + +// ---------------- Status Codes Implementations + +const char wuffs_gif__error__bad_lzw_code[] = "#gif: bad LZW code"; +const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label"; +const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size"; +const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control"; +const char wuffs_gif__error__bad_header[] = "#gif: bad header"; +const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width"; +const char wuffs_gif__error__bad_palette[] = "#gif: bad palette"; +const char wuffs_gif__error__truncated_input[] = "#gif: truncated input"; +const char wuffs_gif__error__internal_error_inconsistent_i_o[] = "#gif: internal error: inconsistent I/O"; + +// ---------------- Private Consts + +static const uint32_t +WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = { + 4294967295u, 1u, 2u, 4u, 0u, +}; + +static const uint8_t +WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1u, 2u, 4u, 8u, 8u, +}; + +static const uint8_t +WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 1u, 2u, 4u, 8u, +}; + +static const uint8_t +WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = { + 65u, 78u, 73u, 77u, 69u, 88u, 84u, 83u, + 49u, 46u, 48u, +}; + +static const uint8_t +WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = { + 78u, 69u, 84u, 83u, 67u, 65u, 80u, 69u, + 50u, 46u, 48u, +}; + +static const uint8_t +WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = { + 73u, 67u, 67u, 82u, 71u, 66u, 71u, 49u, + 48u, 49u, 50u, +}; + +static const uint8_t +WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = { + 88u, 77u, 80u, 32u, 68u, 97u, 116u, 97u, + 88u, 77u, 80u, +}; + +#define WUFFS_GIF__QUIRKS_BASE 1041635328u + +#define WUFFS_GIF__QUIRKS_COUNT 7u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gif__decoder__decode_id_part2( +wuffs_gif__decoder__do_decode_image_config( + wuffs_gif__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__do_tell_me_more( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__do_decode_frame_config( + wuffs_gif__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__skip_frame( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__do_decode_frame( wuffs_gif__decoder* self, wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint64_t v_block_size = 0; - bool v_need_block_size = false; - uint32_t v_n_copied = 0; - uint64_t v_n_compressed = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint64_t v_mark = 0; - wuffs_base__status v_copy_status = wuffs_base__make_status(NULL); + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_gif__decoder__reset_gc( + wuffs_gif__decoder* self); - uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0]; - if (coro_susp_point) { - v_block_size = self->private_data.s_decode_id_part2[0].v_block_size; - v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_up_to_id_part1( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); - wuffs_gif__decoder__lzw_init(self); - v_need_block_size = true; - label__outer__continue:; - while (true) { - if (v_need_block_size) { - v_need_block_size = false; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t t_0 = *iop_a_src++; - v_block_size = t_0; - } - } - if (v_block_size == 0u) { - break; - } - while (((uint64_t)(io2_a_src - iop_a_src)) == 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - } - if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) { - self->private_impl.f_compressed_ri = 0u; - self->private_impl.f_compressed_wi = 0u; - } - while (self->private_impl.f_compressed_wi <= 3841u) { - v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src))); - if (v_n_compressed <= 0u) { - break; - } - v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice( - &iop_a_src, io2_a_src,((uint32_t)(v_n_compressed)), wuffs_base__make_slice_u8_ij(self->private_data.f_compressed, self->private_impl.f_compressed_wi, 4096)); - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied))); - wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied))); - if (v_block_size > 0u) { - break; - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - v_need_block_size = true; - break; - } - v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); - iop_a_src += 1u; - } - while (true) { - if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096u)) { - status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); - goto exit; - } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_compressed, - self->private_impl.f_compressed_ri, - self->private_impl.f_compressed_wi), - 0u); - v_mark = ((uint64_t)(iop_v_r - io0_v_r)); - u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr)); - wuffs_gif__decoder__lzw_read_from(self, v_r); - iop_v_r = u_r.data.ptr + u_r.meta.ri; - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r)))); - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; - } - if (self->private_impl.f_lzw_output_ri < self->private_impl.f_lzw_output_wi) { - v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_lzw_output, - self->private_impl.f_lzw_output_ri, - self->private_impl.f_lzw_output_wi)); - if (wuffs_base__status__is_error(&v_copy_status)) { - status = v_copy_status; - goto exit; - } - self->private_impl.f_lzw_output_ri = 0u; - self->private_impl.f_lzw_output_wi = 0u; - } - if (self->private_impl.f_lzw_read_from_return_value == 0u) { - self->private_impl.f_ignored_but_affects_benchmarks = false; - if (v_need_block_size || (v_block_size > 0u)) { - self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_id_part2[0].scratch; - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - status = wuffs_gif__decoder__skip_blocks(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } - goto label__outer__break; - } else if (self->private_impl.f_lzw_read_from_return_value == 1u) { - continue; - } else if (self->private_impl.f_lzw_read_from_return_value == 2u) { - goto label__outer__continue; - } else if (self->private_impl.f_quirks[3u] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0u)) { - if (v_need_block_size || (v_block_size > 0u)) { - self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_id_part2[0].scratch; - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - status = wuffs_gif__decoder__skip_blocks(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } - goto label__outer__break; - } else if (self->private_impl.f_lzw_read_from_return_value == 3u) { - status = wuffs_base__make_status(wuffs_gif__error__truncated_input); - goto exit; - } else if (self->private_impl.f_lzw_read_from_return_value == 4u) { - status = wuffs_base__make_status(wuffs_gif__error__bad_lzw_code); - goto exit; - } - status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); - goto exit; - } - } - label__outer__break:; - self->private_impl.f_compressed_ri = 0u; - self->private_impl.f_compressed_wi = 0u; - if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) && (self->private_impl.f_frame_rect_x0 != self->private_impl.f_frame_rect_x1) && (self->private_impl.f_frame_rect_y0 != self->private_impl.f_frame_rect_y1)) { - status = wuffs_base__make_status(wuffs_base__error__not_enough_data); - goto exit; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_header( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); - ok: - self->private_impl.p_decode_id_part2[0] = 0; - goto exit; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_lsd( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); - goto suspend; - suspend: - self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_id_part2[0].v_block_size = v_block_size; - self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_extension( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__skip_blocks( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); - return status; -} +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_ae( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); -// -------- func gif.decoder.copy_to_image_buffer +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_gc( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_id_part0( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_id_part1( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_id_part2( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_gif__decoder__copy_to_image_buffer( wuffs_gif__decoder* self, wuffs_base__pixel_buffer* a_pb, - wuffs_base__slice_u8 a_src) { - wuffs_base__slice_u8 v_dst = {0}; - wuffs_base__slice_u8 v_src = {0}; - uint64_t v_width_in_bytes = 0; - uint64_t v_n = 0; - uint64_t v_src_ri = 0; - wuffs_base__pixel_format v_pixfmt = {0}; - uint32_t v_bytes_per_pixel = 0; - uint32_t v_bits_per_pixel = 0; - wuffs_base__table_u8 v_tab = {0}; - uint64_t v_i = 0; - uint64_t v_j = 0; - uint32_t v_replicate_y0 = 0; - uint32_t v_replicate_y1 = 0; - wuffs_base__slice_u8 v_replicate_dst = {0}; - wuffs_base__slice_u8 v_replicate_src = {0}; + wuffs_base__slice_u8 a_src); - v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb); - v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt); - if ((v_bits_per_pixel & 7u) != 0u) { - return wuffs_base__make_status(wuffs_base__error__unsupported_option); +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_gif__decoder__lzw_init( + wuffs_gif__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_gif__decoder__lzw_read_from( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_gif__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_gif__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_gif__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_gif__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_gif__decoder__initialize( + wuffs_gif__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - v_bytes_per_pixel = (v_bits_per_pixel >> 3u); - v_width_in_bytes = ((uint64_t)((self->private_impl.f_width * v_bytes_per_pixel))); - v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0u); - while (v_src_ri < ((uint64_t)(a_src.len))) { - v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri); - if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) { - if (self->private_impl.f_quirks[3u]) { - return wuffs_base__make_status(NULL); - } - return wuffs_base__make_status(wuffs_base__error__too_much_data); - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0u); - } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes); - } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel))); - if (v_i < ((uint64_t)(v_dst.len))) { - v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel))); - if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) { - v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j); - } else { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i); - } - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), v_src); - wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u)); - } - if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) { - self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; - if (self->private_impl.f_interlace == 0u) { - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1u); - continue; - } - if ((self->private_impl.f_num_decoded_frames_value == 0u) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1u)) { - v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u); - v_replicate_y1 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_COUNT[self->private_impl.f_interlace]))); - v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1); - while (v_replicate_y0 < v_replicate_y1) { - v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0); - wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src); - v_replicate_y0 += 1u; - } - self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1); - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace]))); - while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) { -#if defined(__GNUC__) + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_interlace -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif - self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]); - } - continue; - } - if (((uint64_t)(a_src.len)) == v_src_ri) { - break; - } else if (((uint64_t)(a_src.len)) < v_src_ri) { - return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); } - v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x))); - v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri)); - wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n); - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) { - self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace]))); - while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_interlace -= 1u; -#if defined(__GNUC__) +#if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic pop #endif - self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]); - } - continue; - } - if (v_src_ri != ((uint64_t)(a_src.len))) { - return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } - break; } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder); return wuffs_base__make_status(NULL); } -// -------- func gif.decoder.lzw_init +wuffs_gif__decoder* +wuffs_gif__decoder__alloc(void) { + wuffs_gif__decoder* x = + (wuffs_gif__decoder*)(calloc(1, sizeof(wuffs_gif__decoder))); + if (!x) { + return NULL; + } + if (wuffs_gif__decoder__initialize( + x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_gif__decoder__lzw_init( - wuffs_gif__decoder* self) { - uint32_t v_i = 0; +size_t +sizeof__wuffs_gif__decoder(void) { + return sizeof(wuffs_gif__decoder); +} - self->private_impl.f_lzw_literal_width = 8u; - if (self->private_impl.f_lzw_pending_literal_width_plus_one > 0u) { - self->private_impl.f_lzw_literal_width = (self->private_impl.f_lzw_pending_literal_width_plus_one - 1u); +// ---------------- Function Implementations + +// -------- func gif.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_gif__decoder__get_quirk( + const wuffs_gif__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; } - self->private_impl.f_lzw_clear_code = (((uint32_t)(1u)) << self->private_impl.f_lzw_literal_width); - self->private_impl.f_lzw_end_code = (self->private_impl.f_lzw_clear_code + 1u); - self->private_impl.f_lzw_save_code = self->private_impl.f_lzw_end_code; - self->private_impl.f_lzw_prev_code = self->private_impl.f_lzw_end_code; - self->private_impl.f_lzw_width = (self->private_impl.f_lzw_literal_width + 1u); - self->private_impl.f_lzw_bits = 0u; - self->private_impl.f_lzw_n_bits = 0u; - self->private_impl.f_lzw_output_ri = 0u; - self->private_impl.f_lzw_output_wi = 0u; - v_i = 0u; - while (v_i < self->private_impl.f_lzw_clear_code) { - self->private_data.f_lzw_lm1s[v_i] = 0u; - self->private_data.f_lzw_suffixes[v_i][0u] = ((uint8_t)(v_i)); - v_i += 1u; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - return wuffs_base__make_empty_struct(); + + uint32_t v_key = 0; + + if (a_key >= 1041635328u) { + v_key = (a_key - 1041635328u); + if (v_key < 7u) { + if (self->private_impl.f_quirks[v_key]) { + return 1u; + } + } + } + return 0u; } -// -------- func gif.decoder.lzw_read_from +// -------- func gif.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_gif__decoder__lzw_read_from( +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gif__decoder__set_quirk( wuffs_gif__decoder* self, - wuffs_base__io_buffer* a_src) { - uint32_t v_clear_code = 0; - uint32_t v_end_code = 0; - uint32_t v_save_code = 0; - uint32_t v_prev_code = 0; - uint32_t v_width = 0; - uint32_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_output_wi = 0; - uint32_t v_code = 0; - uint32_t v_c = 0; - uint32_t v_o = 0; - uint32_t v_steps = 0; - uint8_t v_first_byte = 0; - uint16_t v_lm1_b = 0; - uint16_t v_lm1_a = 0; + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + if ((self->private_impl.f_call_sequence == 0u) && (a_key >= 1041635328u)) { + a_key -= 1041635328u; + if (a_key < 7u) { + self->private_impl.f_quirks[a_key] = (a_value > 0u); + return wuffs_base__make_status(NULL); + } } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} - v_clear_code = self->private_impl.f_lzw_clear_code; - v_end_code = self->private_impl.f_lzw_end_code; - v_save_code = self->private_impl.f_lzw_save_code; - v_prev_code = self->private_impl.f_lzw_prev_code; - v_width = self->private_impl.f_lzw_width; - v_bits = self->private_impl.f_lzw_bits; - v_n_bits = self->private_impl.f_lzw_n_bits; - v_output_wi = self->private_impl.f_lzw_output_wi; - while (true) { - if (v_n_bits < v_width) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { - v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits)); - iop_a_src += ((31u - v_n_bits) >> 3u); - v_n_bits |= 24u; - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - self->private_impl.f_lzw_read_from_return_value = 3u; - } else { - self->private_impl.f_lzw_read_from_return_value = 2u; - } - break; - } else { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - if (v_n_bits >= v_width) { - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - self->private_impl.f_lzw_read_from_return_value = 3u; - } else { - self->private_impl.f_lzw_read_from_return_value = 2u; - } - break; - } else { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - if (v_n_bits < v_width) { - self->private_impl.f_lzw_read_from_return_value = 5u; - break; - } - } - } - } - v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width)); - v_bits >>= v_width; - v_n_bits -= v_width; - if (v_code < v_clear_code) { - self->private_data.f_lzw_output[v_output_wi] = ((uint8_t)(v_code)); - v_output_wi = ((v_output_wi + 1u) & 8191u); - if (v_save_code <= 4095u) { - v_lm1_a = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u); - self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_a; - if ((v_lm1_a % 8u) != 0u) { - self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code]; - memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code])); - self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code)); - } else { - self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); - self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_code)); - } - v_save_code += 1u; - if (v_width < 12u) { - v_width += (1u & (v_save_code >> v_width)); - } - v_prev_code = v_code; - } - } else if (v_code <= v_end_code) { - if (v_code == v_end_code) { - self->private_impl.f_lzw_read_from_return_value = 0u; - break; - } - v_save_code = v_end_code; - v_prev_code = v_end_code; - v_width = (self->private_impl.f_lzw_literal_width + 1u); - } else if (v_code <= v_save_code) { - v_c = v_code; - if (v_code == v_save_code) { - v_c = v_prev_code; - } - v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) & 4294967288u)) & 8191u); - v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lzw_lm1s[v_c]))) & 8191u); - v_steps = (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) >> 3u); - while (true) { - memcpy((self->private_data.f_lzw_output)+(v_o), (self->private_data.f_lzw_suffixes[v_c]), 8u); - if (v_steps <= 0u) { - break; - } - v_steps -= 1u; - v_o = (((uint32_t)(v_o - 8u)) & 8191u); - v_c = ((uint32_t)(self->private_impl.f_lzw_prefixes[v_c])); - } - v_first_byte = self->private_data.f_lzw_suffixes[v_c][0u]; - if (v_code == v_save_code) { - self->private_data.f_lzw_output[v_output_wi] = v_first_byte; - v_output_wi = ((v_output_wi + 1u) & 8191u); - } - if (v_save_code <= 4095u) { - v_lm1_b = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u); - self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_b; - if ((v_lm1_b % 8u) != 0u) { - self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code]; - memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code])); - self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte; - } else { - self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); - self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte)); - } - v_save_code += 1u; - if (v_width < 12u) { - v_width += (1u & (v_save_code >> v_width)); - } - v_prev_code = v_code; - } - } else { - self->private_impl.f_lzw_read_from_return_value = 4u; - break; - } - if (v_output_wi > 4095u) { - self->private_impl.f_lzw_read_from_return_value = 1u; - break; - } +// -------- func gif.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gif__decoder__decode_image_config( + wuffs_gif__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if (self->private_impl.f_lzw_read_from_return_value != 2u) { - while (v_n_bits >= 8u) { - v_n_bits -= 8u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - self->private_impl.f_lzw_read_from_return_value = 5u; - break; - } - } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - self->private_impl.f_lzw_save_code = v_save_code; - self->private_impl.f_lzw_prev_code = v_prev_code; - self->private_impl.f_lzw_width = v_width; - self->private_impl.f_lzw_bits = v_bits; - self->private_impl.f_lzw_n_bits = v_n_bits; - self->private_impl.f_lzw_output_wi = v_output_wi; - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - return wuffs_base__make_empty_struct(); -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) + wuffs_base__status v_status = wuffs_base__make_status(NULL); -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -// ---------------- Status Codes Implementations + while (true) { + { + wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_gif__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } -const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum"; -const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method"; -const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags"; -const char wuffs_gzip__error__bad_header[] = "#gzip: bad header"; -const char wuffs_gzip__error__truncated_input[] = "#gzip: truncated input"; + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } -// ---------------- Private Consts + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; -// ---------------- Private Initializer Prototypes + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} -// ---------------- Private Function Prototypes +// -------- func gif.decoder.do_decode_image_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gzip__decoder__do_transform_io( - wuffs_gzip__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); - -// ---------------- VTables - -const wuffs_base__io_transformer__func_ptrs -wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = { - (uint64_t(*)(const void*, - uint32_t))(&wuffs_gzip__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_gzip__decoder__history_retain_length), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_gzip__decoder__set_quirk), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len), -}; +wuffs_gif__decoder__do_decode_image_config( + wuffs_gif__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// ---------------- Initializer Implementations + bool v_ffio = false; -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_gzip__decoder__initialize( - wuffs_gzip__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if ( ! self->private_impl.f_seen_header) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_gif__decoder__decode_header(self, a_src); + if (status.repr) { + goto suspend; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_gif__decoder__decode_lsd(self, a_src); + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_header = true; } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src); + if (status.repr) { + goto suspend; } - } - - { - wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( - &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options); - if (z.repr) { - return z; + v_ffio = ! self->private_impl.f_gc_has_transparent_index; + if ( ! self->private_impl.f_quirks[2u]) { + v_ffio = (v_ffio && + (self->private_impl.f_frame_rect_x0 == 0u) && + (self->private_impl.f_frame_rect_y0 == 0u) && + (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) && + (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height)); + } else if (v_ffio) { + self->private_impl.f_black_color_u32_argb_premul = 4278190080u; } - } - { - wuffs_base__status z = wuffs_deflate__decoder__initialize( - &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options); - if (z.repr) { - return z; + if (self->private_impl.f_background_color_u32_argb_premul == 77u) { + self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul; + } + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + 2198077448u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + v_ffio); + } + if (self->private_impl.f_call_sequence == 0u) { + self->private_impl.f_call_sequence = 32u; } - } - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = - wuffs_base__io_transformer__vtable_name; - self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = - (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer); - return wuffs_base__make_status(NULL); -} -wuffs_gzip__decoder* -wuffs_gzip__decoder__alloc(void) { - wuffs_gzip__decoder* x = - (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_gzip__decoder__initialize( - x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; } - return x; -} - -size_t -sizeof__wuffs_gzip__decoder(void) { - return sizeof(wuffs_gzip__decoder); -} -// ---------------- Function Implementations - -// -------- func gzip.decoder.get_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gzip__decoder__get_quirk( - const wuffs_gzip__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { - return 1u; - } - return 0u; + goto exit; + exit: + return status; } -// -------- func gzip.decoder.set_quirk +// -------- func gif.decoder.set_report_metadata WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gzip__decoder__set_quirk( - wuffs_gzip__decoder* self, - uint32_t a_key, - uint64_t a_value) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_gif__decoder__set_report_metadata( + wuffs_gif__decoder* self, + uint32_t a_fourcc, + bool a_report) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return wuffs_base__make_empty_struct(); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - if (a_key == 1u) { - self->private_impl.f_ignore_checksum = (a_value > 0u); - return wuffs_base__make_status(NULL); - } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); -} - -// -------- func gzip.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_gzip__decoder__history_retain_length( - const wuffs_gzip__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + return wuffs_base__make_empty_struct(); } - return 0u; -} - -// -------- func gzip.decoder.workbuf_len - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_gzip__decoder__workbuf_len( - const wuffs_gzip__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + if (a_fourcc == 1229144912u) { + self->private_impl.f_report_metadata_iccp = a_report; + } else if (a_fourcc == 1481461792u) { + self->private_impl.f_report_metadata_xmp = a_report; } - - return wuffs_base__utility__make_range_ii_u64(1u, 1u); + return wuffs_base__make_empty_struct(); } -// -------- func gzip.decoder.transform_io +// -------- func gif.decoder.tell_me_more WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_gzip__decoder__transform_io( - wuffs_gzip__decoder* self, +wuffs_gif__decoder__tell_me_more( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -39737,7 +41163,7 @@ wuffs_gzip__decoder__transform_io( return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { + (self->private_impl.active_coroutine != 2)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -39746,17 +41172,17 @@ wuffs_gzip__decoder__transform_io( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_transform_io[0]; + uint32_t coro_susp_point = self->private_impl.p_tell_me_more; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_gzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + wuffs_base__status t_0 = wuffs_gif__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_gzip__error__truncated_input); + status = wuffs_base__make_status(wuffs_gif__error__truncated_input); goto exit; } status = v_status; @@ -39764,14 +41190,14 @@ wuffs_gzip__decoder__transform_io( } ok: - self->private_impl.p_transform_io[0] = 0; + self->private_impl.p_tell_me_more = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; goto exit; exit: @@ -39781,40 +41207,19 @@ wuffs_gzip__decoder__transform_io( return status; } -// -------- func gzip.decoder.do_transform_io +// -------- func gif.decoder.do_tell_me_more WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_gzip__decoder__do_transform_io( - wuffs_gzip__decoder* self, +wuffs_gif__decoder__do_tell_me_more( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_flags = 0; - uint16_t v_xlen = 0; - uint64_t v_mark = 0; - uint32_t v_checksum_got = 0; - uint32_t v_decoded_length_got = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t v_checksum_want = 0; - uint32_t v_decoded_length_want = 0; + uint64_t v_chunk_length = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -39826,269 +41231,95 @@ wuffs_gzip__decoder__do_transform_io( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0]; - if (coro_susp_point) { - v_flags = self->private_data.s_do_transform_io[0].v_flags; - v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got; - v_decoded_length_got = self->private_data.s_do_transform_io[0].v_decoded_length_got; - v_checksum_want = self->private_data.s_do_transform_io[0].v_checksum_want; - } + uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c != 31u) { - status = wuffs_base__make_status(wuffs_gzip__error__bad_header); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - if (v_c != 139u) { - status = wuffs_base__make_status(wuffs_gzip__error__bad_header); + if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) == 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; - } - if (v_c != 8u) { - status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method); + if (self->private_impl.f_metadata_fourcc == 0u) { + status = wuffs_base__make_status(wuffs_base__error__no_more_information); goto exit; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_flags = t_3; - } - self->private_data.s_do_transform_io[0].scratch = 6u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_transform_io[0].scratch; - if ((v_flags & 4u) != 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint16_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - iop_a_src += 2; - } else { - self->private_data.s_do_transform_io[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 8) { - t_4 = ((uint16_t)(*scratch)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; - } - } - v_xlen = t_4; - } - self->private_data.s_do_transform_io[0].scratch = ((uint32_t)(v_xlen)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_transform_io[0].scratch; - } - if ((v_flags & 8u) != 0u) { + while (true) { while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) { + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + 2u, + 0u, + self->private_impl.f_metadata_io_position, + 0u, + 0u); } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; - } - if (v_c == 0u) { - break; + status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; } - } - } - if ((v_flags & 16u) != 0u) { - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + 0u, + 0u, + 0u, + 0u, + 0u); } - uint8_t t_6 = *iop_a_src++; - v_c = t_6; - } - if (v_c == 0u) { - break; - } - } - } - if ((v_flags & 2u) != 0u) { - self->private_data.s_do_transform_io[0].scratch = 2u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_transform_io[0].scratch; - } - if ((v_flags & 224u) != 0u) { - status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags); - goto exit; - } - while (true) { - v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); - { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf); - v_status = t_7; - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + continue; } + break; } - if ( ! self->private_impl.f_ignore_checksum) { - v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); - v_decoded_length_got += ((uint32_t)(wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))))); - } - if (wuffs_base__status__is_ok(&v_status)) { + v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); + if (v_chunk_length <= 0u) { + iop_a_src += 1u; break; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12); - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); - uint32_t t_8; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; + if (self->private_impl.f_metadata_fourcc == 1481461792u) { + v_chunk_length += 1u; } else { - self->private_data.s_do_transform_io[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; - uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8; - if (num_bits_8 == 24) { - t_8 = ((uint32_t)(*scratch)); - break; - } - num_bits_8 += 8u; - *scratch |= ((uint64_t)(num_bits_8)) << 56; - } + iop_a_src += 1u; } - v_checksum_want = t_8; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); - uint32_t t_9; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_transform_io[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; - uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9; - if (num_bits_9 == 24) { - t_9 = ((uint32_t)(*scratch)); - break; - } - num_bits_9 += 8u; - *scratch |= ((uint64_t)(num_bits_9)) << 56; - } + self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length); + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + 3u, + self->private_impl.f_metadata_fourcc, + 0u, + wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), + self->private_impl.f_metadata_io_position); } - v_decoded_length_want = t_9; + status = wuffs_base__make_status(wuffs_base__suspension__even_more_information); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); } - if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) { - status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum); - goto exit; + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + 3u, + self->private_impl.f_metadata_fourcc, + 0u, + self->private_impl.f_metadata_io_position, + self->private_impl.f_metadata_io_position); } + self->private_impl.f_call_sequence &= 239u; + self->private_impl.f_metadata_fourcc = 0u; + self->private_impl.f_metadata_io_position = 0u; + status = wuffs_base__make_status(NULL); + goto ok; ok: - self->private_impl.p_do_transform_io[0] = 0; + self->private_impl.p_do_tell_me_more = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_transform_io[0].v_flags = v_flags; - self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got; - self->private_data.s_do_transform_io[0].v_decoded_length_got = v_decoded_length_got; - self->private_data.s_do_transform_io[0].v_checksum_want = v_checksum_want; + self->private_impl.p_do_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -40096,2260 +41327,1143 @@ wuffs_gzip__decoder__do_transform_io( return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) +// -------- func gif.decoder.num_animation_loops -// ---------------- Status Codes Implementations +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_gif__decoder__num_animation_loops( + const wuffs_gif__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -const char wuffs_jpeg__error__bad_dht_marker[] = "#jpeg: bad DHT marker"; -const char wuffs_jpeg__error__bad_dqt_marker[] = "#jpeg: bad DQT marker"; -const char wuffs_jpeg__error__bad_dri_marker[] = "#jpeg: bad DRI marker"; -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__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"; -const char wuffs_jpeg__error__unsupported_arithmetic_coding[] = "#jpeg: unsupported arithmetic coding"; -const char wuffs_jpeg__error__unsupported_color_model[] = "#jpeg: unsupported color model"; -const char wuffs_jpeg__error__unsupported_fractional_sampling[] = "#jpeg: unsupported fractional sampling"; -const char wuffs_jpeg__error__unsupported_hierarchical_coding[] = "#jpeg: unsupported hierarchical coding"; -const char wuffs_jpeg__error__unsupported_implicit_height[] = "#jpeg: unsupported implicit height"; -const char wuffs_jpeg__error__unsupported_lossless_coding[] = "#jpeg: unsupported lossless coding"; -const char wuffs_jpeg__error__unsupported_marker[] = "#jpeg: unsupported marker"; -const char wuffs_jpeg__error__unsupported_precision_12_bits[] = "#jpeg: unsupported precision (12 bits)"; -const char wuffs_jpeg__error__unsupported_precision_16_bits[] = "#jpeg: unsupported precision (16 bits)"; -const char wuffs_jpeg__error__unsupported_precision[] = "#jpeg: unsupported precision"; -const char wuffs_jpeg__error__unsupported_scan_count[] = "#jpeg: unsupported scan count"; -const char wuffs_jpeg__error__internal_error_inconsistent_decoder_state[] = "#jpeg: internal error: inconsistent decoder state"; + if (self->private_impl.f_seen_num_animation_loops_value) { + return self->private_impl.f_num_animation_loops_value; + } + if (self->private_impl.f_num_decoded_frame_configs_value > 1u) { + return 1u; + } + return 0u; +} -// ---------------- Private Consts +// -------- func gif.decoder.num_decoded_frame_configs -static const uint8_t -WUFFS_JPEG__UNZIG[80] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 1, 8, 16, 9, 2, 3, - 10, 17, 24, 32, 25, 18, 11, 4, - 5, 12, 19, 26, 33, 40, 48, 41, - 34, 27, 20, 13, 6, 7, 14, 21, - 28, 35, 42, 49, 56, 57, 50, 43, - 36, 29, 22, 15, 23, 30, 37, 44, - 51, 58, 59, 52, 45, 38, 31, 39, - 46, 53, 60, 61, 54, 47, 55, 62, - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_gif__decoder__num_decoded_frame_configs( + const wuffs_gif__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -static const uint8_t -WUFFS_JPEG__BIAS_AND_CLAMP[1024] WUFFS_BASE__POTENTIALLY_UNUSED = { - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, -}; + return self->private_impl.f_num_decoded_frame_configs_value; +} -static const uint16_t -WUFFS_JPEG__EXTEND[16] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 65535, 65533, 65529, 65521, 65505, 65473, 65409, - 65281, 65025, 64513, 63489, 61441, 57345, 49153, 32769, -}; +// -------- func gif.decoder.num_decoded_frames -static const uint8_t -WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 1, 5, 1, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_gif__decoder__num_decoded_frames( + const wuffs_gif__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -static const uint8_t -WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1, 0, 3, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, -}; + return self->private_impl.f_num_decoded_frames_value; +} -static const uint8_t -WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = { - 16, 0, 2, 1, 3, 3, 2, 4, - 3, 5, 5, 4, 4, 0, 0, 1, - 125, 1, 2, 3, 0, 4, 17, 5, - 18, 33, 49, 65, 6, 19, 81, 97, - 7, 34, 113, 20, 50, 129, 145, 161, - 8, 35, 66, 177, 193, 21, 82, 209, - 240, 36, 51, 98, 114, 130, 9, 10, - 22, 23, 24, 25, 26, 37, 38, 39, - 40, 41, 42, 52, 53, 54, 55, 56, - 57, 58, 67, 68, 69, 70, 71, 72, - 73, 74, 83, 84, 85, 86, 87, 88, - 89, 90, 99, 100, 101, 102, 103, 104, - 105, 106, 115, 116, 117, 118, 119, 120, - 121, 122, 131, 132, 133, 134, 135, 136, - 137, 138, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 225, - 226, 227, 228, 229, 230, 231, 232, 233, - 234, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, -}; +// -------- func gif.decoder.frame_dirty_rect -static const uint8_t -WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = { - 17, 0, 2, 1, 2, 4, 4, 3, - 4, 7, 5, 4, 4, 0, 1, 2, - 119, 0, 1, 2, 3, 17, 4, 5, - 33, 49, 6, 18, 65, 81, 7, 97, - 113, 19, 34, 50, 129, 8, 20, 66, - 145, 161, 177, 193, 9, 35, 51, 82, - 240, 21, 98, 114, 209, 10, 22, 36, - 52, 225, 37, 241, 23, 24, 25, 26, - 38, 39, 40, 41, 42, 53, 54, 55, - 56, 57, 58, 67, 68, 69, 70, 71, - 72, 73, 74, 83, 84, 85, 86, 87, - 88, 89, 90, 99, 100, 101, 102, 103, - 104, 105, 106, 115, 116, 117, 118, 119, - 120, 121, 122, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 194, - 195, 196, 197, 198, 199, 200, 201, 202, - 210, 211, 212, 213, 214, 215, 216, 217, - 218, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 242, 243, 244, 245, 246, 247, - 248, 249, 250, -}; +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_gif__decoder__frame_dirty_rect( + const wuffs_gif__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } -// ---------------- Private Initializer Prototypes + return wuffs_base__utility__make_rect_ie_u32( + wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width), + wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height), + wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width), + wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height)); +} -// ---------------- Private Function Prototypes +// -------- func gif.decoder.workbuf_len WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q); +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_gif__decoder__workbuf_len( + const wuffs_gif__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct__choosy_default( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q); + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct_x86_avx2( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) +// -------- func gif.decoder.restart_frame WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__do_decode_image_config( - wuffs_jpeg__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gif__decoder__restart_frame( + wuffs_gif__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_dqt( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } else if (a_io_position == 0u) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_delayed_num_decoded_frames = false; + self->private_impl.f_frame_config_io_position = a_io_position; + self->private_impl.f_num_decoded_frame_configs_value = a_index; + self->private_impl.f_num_decoded_frames_value = a_index; + wuffs_gif__decoder__reset_gc(self); + self->private_impl.f_call_sequence = 40u; + return wuffs_base__make_status(NULL); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_dri( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); +// -------- func gif.decoder.decode_frame_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_appn( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src, - uint8_t a_marker); +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gif__decoder__decode_frame_config( + wuffs_gif__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_sof( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); + wuffs_base__status v_status = wuffs_base__make_status(NULL); -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__quantize_dimension( - const wuffs_jpeg__decoder* self, - uint32_t a_width, - uint8_t a_h, - uint8_t a_max_incl_h); + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__do_decode_frame_config( - wuffs_jpeg__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); + while (true) { + { + wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_gif__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__do_decode_frame( - wuffs_jpeg__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_dht( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; -WUFFS_BASE__GENERATED_C_CODE -static bool -wuffs_jpeg__decoder__calculate_huff_tables( - wuffs_jpeg__decoder* self, - uint8_t a_tc4_th, - uint32_t a_total_count); + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_sos( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); +// -------- func gif.decoder.do_decode_frame_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__prepare_scan( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); +wuffs_gif__decoder__do_decode_frame_config( + wuffs_gif__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__use_default_huffman_table( - wuffs_jpeg__decoder* self, - uint8_t a_tc4_th); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__calculate_single_component_scan_fields( - wuffs_jpeg__decoder* self); + uint32_t v_background_color = 0; + uint8_t v_flags = 0; -WUFFS_BASE__GENERATED_C_CODE -static bool -wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( - wuffs_jpeg__decoder* self); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__fill_bitstream( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + if (coro_susp_point) { + v_background_color = self->private_data.s_do_decode_frame_config.v_background_color; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__load_mcu_blocks_for_single_component( - wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel); + self->private_impl.f_dirty_max_excl_y = 0u; + if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_gif__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_gif__decoder__skip_frame(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_call_sequence >= 96u) { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if ((self->private_impl.f_num_decoded_frame_configs_value > 0u) || (self->private_impl.f_call_sequence == 40u)) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_call_sequence >= 96u) { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + } + v_background_color = self->private_impl.f_black_color_u32_argb_premul; + if ( ! self->private_impl.f_gc_has_transparent_index) { + v_background_color = self->private_impl.f_background_color_u32_argb_premul; + if (self->private_impl.f_quirks[1u] && (self->private_impl.f_num_decoded_frame_configs_value == 0u)) { + while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + } + v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (((uint8_t)(v_flags & 128u)) != 0u) { + v_background_color = self->private_impl.f_black_color_u32_argb_premul; + } + } + } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width), + wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height), + wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width), + wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)), + ((wuffs_base__flicks)(self->private_impl.f_gc_duration)), + self->private_impl.f_num_decoded_frame_configs_value, + self->private_impl.f_frame_config_io_position, + self->private_impl.f_gc_disposal, + ! self->private_impl.f_gc_has_transparent_index, + false, + v_background_color); + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u); + self->private_impl.f_call_sequence = 64u; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default( - wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel); + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__load_mcu_blocks( - wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf); + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_frame_config.v_background_color = v_background_color; -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__save_mcu_blocks( - wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__skip_past_the_next_restart_marker( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src); + return status; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__apply_progressive_idct( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf); +// -------- func gif.decoder.skip_frame WUFFS_BASE__GENERATED_C_CODE 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_gif__decoder__skip_frame( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -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); + uint8_t v_flags = 0; + uint8_t v_lw = 0; -WUFFS_BASE__GENERATED_C_CODE -static bool -wuffs_jpeg__decoder__top_left_quants_has_zero( - const wuffs_jpeg__decoder* self, - uint32_t a_q); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth( - wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel); + uint32_t coro_susp_point = self->private_impl.p_skip_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_flags = t_0; + } + if (((uint8_t)(v_flags & 128u)) != 0u) { + self->private_data.s_skip_frame.scratch = (((uint32_t)(3u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u))))); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_skip_frame.scratch; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_lw = t_1; + } + if (v_lw > 8u) { + status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_gif__decoder__skip_blocks(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_quirks[0u]) { + self->private_impl.f_delayed_num_decoded_frames = true; + } else { + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + } + wuffs_gif__decoder__reset_gc(self); + self->private_impl.f_call_sequence = 32u; -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu__choosy_default( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); + goto ok; + ok: + self->private_impl.p_skip_frame = 0; + goto exit; + } -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); + goto suspend; + suspend: + self->private_impl.p_skip_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); + return status; +} + +// -------- func gif.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit( - wuffs_jpeg__decoder* self, +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gif__decoder__decode_frame( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my); - -// ---------------- VTables - -const wuffs_base__image_decoder__func_ptrs -wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_jpeg__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_jpeg__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_jpeg__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_jpeg__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_jpeg__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_jpeg__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_jpeg__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_jpeg__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_jpeg__decoder__initialize( - wuffs_jpeg__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ + wuffs_base__decode_frame_options* a_opts) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); } - - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - self->private_impl.choosy_decode_idct = &wuffs_jpeg__decoder__decode_idct__choosy_default; - self->private_impl.choosy_load_mcu_blocks_for_single_component = &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default; - self->private_impl.choosy_decode_mcu = &wuffs_jpeg__decoder__decode_mcu__choosy_default; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); -} + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -wuffs_jpeg__decoder* -wuffs_jpeg__decoder__alloc(void) { - wuffs_jpeg__decoder* x = - (wuffs_jpeg__decoder*)(calloc(sizeof(wuffs_jpeg__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_jpeg__decoder__initialize( - x, sizeof(wuffs_jpeg__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + while (true) { + { + wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_gif__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; } - return x; -} -size_t -sizeof__wuffs_jpeg__decoder(void) { - return sizeof(wuffs_jpeg__decoder); -} + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; -// ---------------- Function Implementations + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} -// -------- func jpeg.decoder.decode_idct +// -------- func gif.decoder.do_decode_frame WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q) { - return (*self->private_impl.choosy_decode_idct)(self, a_dst_buffer, a_dst_stride, a_q); -} +static wuffs_base__status +wuffs_gif__decoder__do_decode_frame( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct__choosy_default( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q) { - uint32_t v_bq0 = 0; - uint32_t v_bq2 = 0; - uint32_t v_bq4 = 0; - uint32_t v_bq6 = 0; - uint32_t v_ca = 0; - uint32_t v_cb2 = 0; - uint32_t v_cb6 = 0; - uint32_t v_ccp = 0; - uint32_t v_ccm = 0; - uint32_t v_cd0 = 0; - uint32_t v_cd1 = 0; - uint32_t v_cd2 = 0; - uint32_t v_cd3 = 0; - uint32_t v_bq1 = 0; - uint32_t v_bq3 = 0; - uint32_t v_bq5 = 0; - uint32_t v_bq7 = 0; - uint32_t v_ci51 = 0; - uint32_t v_ci53 = 0; - uint32_t v_ci71 = 0; - uint32_t v_ci73 = 0; - uint32_t v_cj = 0; - uint32_t v_ck1 = 0; - uint32_t v_ck3 = 0; - uint32_t v_ck5 = 0; - uint32_t v_ck7 = 0; - uint32_t v_cl51 = 0; - uint32_t v_cl73 = 0; - uint32_t v_in0 = 0; - uint32_t v_in2 = 0; - uint32_t v_in4 = 0; - uint32_t v_in6 = 0; - uint32_t v_ra = 0; - uint32_t v_rb2 = 0; - uint32_t v_rb6 = 0; - uint32_t v_rcp = 0; - uint32_t v_rcm = 0; - uint32_t v_rd0 = 0; - uint32_t v_rd1 = 0; - uint32_t v_rd2 = 0; - uint32_t v_rd3 = 0; - uint32_t v_in1 = 0; - uint32_t v_in3 = 0; - uint32_t v_in5 = 0; - uint32_t v_in7 = 0; - uint32_t v_ri51 = 0; - uint32_t v_ri53 = 0; - uint32_t v_ri71 = 0; - uint32_t v_ri73 = 0; - uint32_t v_rj = 0; - uint32_t v_rk1 = 0; - uint32_t v_rk3 = 0; - uint32_t v_rk5 = 0; - uint32_t v_rk7 = 0; - uint32_t v_rl51 = 0; - uint32_t v_rl73 = 0; - uint32_t v_intermediate[64] = {0}; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (8u > a_dst_stride) { - return wuffs_base__make_empty_struct(); - } - if (0u == (self->private_data.f_mcu_blocks[0u][8u] | - self->private_data.f_mcu_blocks[0u][16u] | - self->private_data.f_mcu_blocks[0u][24u] | - self->private_data.f_mcu_blocks[0u][32u] | - self->private_data.f_mcu_blocks[0u][40u] | - self->private_data.f_mcu_blocks[0u][48u] | - self->private_data.f_mcu_blocks[0u][56u])) { - v_intermediate[0u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u])))) << 2u)); - v_intermediate[8u] = v_intermediate[0u]; - v_intermediate[16u] = v_intermediate[0u]; - v_intermediate[24u] = v_intermediate[0u]; - v_intermediate[32u] = v_intermediate[0u]; - v_intermediate[40u] = v_intermediate[0u]; - v_intermediate[48u] = v_intermediate[0u]; - v_intermediate[56u] = v_intermediate[0u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][16u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][16u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][48u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][48u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][32u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][32u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][8u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][8u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][24u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][24u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][40u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][40u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][56u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][56u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[0u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[56u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[8u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[48u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[16u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[40u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[24u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[32u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_gif__decoder__do_decode_frame_config(self, NULL, a_src); + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (self->private_impl.f_quirks[5u] && ((self->private_impl.f_frame_rect_x0 == self->private_impl.f_frame_rect_x1) || (self->private_impl.f_frame_rect_y0 == self->private_impl.f_frame_rect_y1))) { + status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size); + goto exit; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend); + if (status.repr) { + goto suspend; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf); + if (status.repr) { + goto suspend; + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + wuffs_gif__decoder__reset_gc(self); + self->private_impl.f_call_sequence = 32u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; } - if (0u == (self->private_data.f_mcu_blocks[0u][9u] | - self->private_data.f_mcu_blocks[0u][17u] | - self->private_data.f_mcu_blocks[0u][25u] | - self->private_data.f_mcu_blocks[0u][33u] | - self->private_data.f_mcu_blocks[0u][41u] | - self->private_data.f_mcu_blocks[0u][49u] | - self->private_data.f_mcu_blocks[0u][57u])) { - v_intermediate[1u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u])))) << 2u)); - v_intermediate[9u] = v_intermediate[1u]; - v_intermediate[17u] = v_intermediate[1u]; - v_intermediate[25u] = v_intermediate[1u]; - v_intermediate[33u] = v_intermediate[1u]; - v_intermediate[41u] = v_intermediate[1u]; - v_intermediate[49u] = v_intermediate[1u]; - v_intermediate[57u] = v_intermediate[1u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][17u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][17u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][49u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][49u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][33u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][33u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][9u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][9u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][25u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][25u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][41u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][41u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][57u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][57u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[1u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[57u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[9u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[49u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[17u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[41u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[25u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[33u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func gif.decoder.reset_gc + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_gif__decoder__reset_gc( + wuffs_gif__decoder* self) { + self->private_impl.f_gc_has_transparent_index = false; + self->private_impl.f_gc_transparent_index = 0u; + self->private_impl.f_gc_disposal = 0u; + self->private_impl.f_gc_duration = 0u; + return wuffs_base__make_empty_struct(); +} + +// -------- func gif.decoder.decode_up_to_id_part1 + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_up_to_id_part1( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_block_type = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (0u == (self->private_data.f_mcu_blocks[0u][10u] | - self->private_data.f_mcu_blocks[0u][18u] | - self->private_data.f_mcu_blocks[0u][26u] | - self->private_data.f_mcu_blocks[0u][34u] | - self->private_data.f_mcu_blocks[0u][42u] | - self->private_data.f_mcu_blocks[0u][50u] | - self->private_data.f_mcu_blocks[0u][58u])) { - v_intermediate[2u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u])))) << 2u)); - v_intermediate[10u] = v_intermediate[2u]; - v_intermediate[18u] = v_intermediate[2u]; - v_intermediate[26u] = v_intermediate[2u]; - v_intermediate[34u] = v_intermediate[2u]; - v_intermediate[42u] = v_intermediate[2u]; - v_intermediate[50u] = v_intermediate[2u]; - v_intermediate[58u] = v_intermediate[2u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][18u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][18u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][50u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][50u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][34u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][34u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][10u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][10u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][26u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][26u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][42u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][42u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][58u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][58u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[2u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[58u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[10u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[50u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[18u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[42u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[26u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[34u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if ((self->private_impl.f_frame_config_io_position == 0u) || (self->private_impl.f_num_decoded_frame_configs_value > 0u)) { + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_block_type = t_0; + } + if (v_block_type == 33u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_gif__decoder__decode_extension(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (v_block_type == 44u) { + if (self->private_impl.f_delayed_num_decoded_frames) { + self->private_impl.f_delayed_num_decoded_frames = false; + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_gif__decoder__decode_id_part0(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + break; + } else { + if (self->private_impl.f_delayed_num_decoded_frames) { + self->private_impl.f_delayed_num_decoded_frames = false; + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + } + self->private_impl.f_call_sequence = 96u; + break; + } + } + + goto ok; + ok: + self->private_impl.p_decode_up_to_id_part1 = 0; + goto exit; } - if (0u == (self->private_data.f_mcu_blocks[0u][11u] | - self->private_data.f_mcu_blocks[0u][19u] | - self->private_data.f_mcu_blocks[0u][27u] | - self->private_data.f_mcu_blocks[0u][35u] | - self->private_data.f_mcu_blocks[0u][43u] | - self->private_data.f_mcu_blocks[0u][51u] | - self->private_data.f_mcu_blocks[0u][59u])) { - v_intermediate[3u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u])))) << 2u)); - v_intermediate[11u] = v_intermediate[3u]; - v_intermediate[19u] = v_intermediate[3u]; - v_intermediate[27u] = v_intermediate[3u]; - v_intermediate[35u] = v_intermediate[3u]; - v_intermediate[43u] = v_intermediate[3u]; - v_intermediate[51u] = v_intermediate[3u]; - v_intermediate[59u] = v_intermediate[3u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][19u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][19u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][51u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][51u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][35u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][35u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][11u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][11u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][27u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][27u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][43u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][43u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][59u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][59u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[3u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[59u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[11u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[51u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[19u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[43u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[27u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[35u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + goto suspend; + suspend: + self->private_impl.p_decode_up_to_id_part1 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (0u == (self->private_data.f_mcu_blocks[0u][12u] | - self->private_data.f_mcu_blocks[0u][20u] | - self->private_data.f_mcu_blocks[0u][28u] | - self->private_data.f_mcu_blocks[0u][36u] | - self->private_data.f_mcu_blocks[0u][44u] | - self->private_data.f_mcu_blocks[0u][52u] | - self->private_data.f_mcu_blocks[0u][60u])) { - v_intermediate[4u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u])))) << 2u)); - v_intermediate[12u] = v_intermediate[4u]; - v_intermediate[20u] = v_intermediate[4u]; - v_intermediate[28u] = v_intermediate[4u]; - v_intermediate[36u] = v_intermediate[4u]; - v_intermediate[44u] = v_intermediate[4u]; - v_intermediate[52u] = v_intermediate[4u]; - v_intermediate[60u] = v_intermediate[4u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][20u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][20u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][52u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][52u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][36u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][36u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][12u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][12u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][28u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][28u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][44u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][44u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][60u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][60u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[4u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[60u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[12u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[52u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[20u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[44u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[28u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[36u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + return status; +} + +// -------- func gif.decoder.decode_header + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_header( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint64_t v_c48 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (0u == (self->private_data.f_mcu_blocks[0u][13u] | - self->private_data.f_mcu_blocks[0u][21u] | - self->private_data.f_mcu_blocks[0u][29u] | - self->private_data.f_mcu_blocks[0u][37u] | - self->private_data.f_mcu_blocks[0u][45u] | - self->private_data.f_mcu_blocks[0u][53u] | - self->private_data.f_mcu_blocks[0u][61u])) { - v_intermediate[5u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u])))) << 2u)); - v_intermediate[13u] = v_intermediate[5u]; - v_intermediate[21u] = v_intermediate[5u]; - v_intermediate[29u] = v_intermediate[5u]; - v_intermediate[37u] = v_intermediate[5u]; - v_intermediate[45u] = v_intermediate[5u]; - v_intermediate[53u] = v_intermediate[5u]; - v_intermediate[61u] = v_intermediate[5u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][21u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][21u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][53u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][53u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][37u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][37u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][13u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][13u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][29u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][29u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][45u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][45u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][61u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][61u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[5u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[61u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[13u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[53u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[21u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[45u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[29u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[37u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + uint32_t coro_susp_point = self->private_impl.p_decode_header; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) { + t_0 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))); + iop_a_src += 6; + } else { + self->private_data.s_decode_header.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_header.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 40) { + t_0 = ((uint64_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_c48 = t_0; + } + if ((v_c48 != 106889795225927u) && (v_c48 != 106898385160519u)) { + status = wuffs_base__make_status(wuffs_gif__error__bad_header); + goto exit; + } + + goto ok; + ok: + self->private_impl.p_decode_header = 0; + goto exit; } - if (0u == (self->private_data.f_mcu_blocks[0u][14u] | - self->private_data.f_mcu_blocks[0u][22u] | - self->private_data.f_mcu_blocks[0u][30u] | - self->private_data.f_mcu_blocks[0u][38u] | - self->private_data.f_mcu_blocks[0u][46u] | - self->private_data.f_mcu_blocks[0u][54u] | - self->private_data.f_mcu_blocks[0u][62u])) { - v_intermediate[6u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u])))) << 2u)); - v_intermediate[14u] = v_intermediate[6u]; - v_intermediate[22u] = v_intermediate[6u]; - v_intermediate[30u] = v_intermediate[6u]; - v_intermediate[38u] = v_intermediate[6u]; - v_intermediate[46u] = v_intermediate[6u]; - v_intermediate[54u] = v_intermediate[6u]; - v_intermediate[62u] = v_intermediate[6u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][22u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][22u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][54u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][54u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][38u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][38u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][14u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][14u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][30u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][30u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][46u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][46u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][62u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][62u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[6u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[62u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[14u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[54u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[22u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[46u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[30u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[38u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + goto suspend; + suspend: + self->private_impl.p_decode_header = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (0u == (self->private_data.f_mcu_blocks[0u][15u] | - self->private_data.f_mcu_blocks[0u][23u] | - self->private_data.f_mcu_blocks[0u][31u] | - self->private_data.f_mcu_blocks[0u][39u] | - self->private_data.f_mcu_blocks[0u][47u] | - self->private_data.f_mcu_blocks[0u][55u] | - self->private_data.f_mcu_blocks[0u][63u])) { - v_intermediate[7u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u])))) << 2u)); - v_intermediate[15u] = v_intermediate[7u]; - v_intermediate[23u] = v_intermediate[7u]; - v_intermediate[31u] = v_intermediate[7u]; - v_intermediate[39u] = v_intermediate[7u]; - v_intermediate[47u] = v_intermediate[7u]; - v_intermediate[55u] = v_intermediate[7u]; - v_intermediate[63u] = v_intermediate[7u]; - } else { - v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][23u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][23u])))); - v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][55u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][55u])))); - v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); - v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); - v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); - v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u])))); - v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][39u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][39u])))); - v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); - v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); - v_cd0 = ((uint32_t)(v_ccp + v_cb2)); - v_cd1 = ((uint32_t)(v_ccm + v_cb6)); - v_cd2 = ((uint32_t)(v_ccm - v_cb6)); - v_cd3 = ((uint32_t)(v_ccp - v_cb2)); - v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][15u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][15u])))); - v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][31u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][31u])))); - v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][47u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][47u])))); - v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][63u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][63u])))); - v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); - v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); - v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); - v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); - v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); - v_ck1 = ((uint32_t)(v_bq1 * 12299u)); - v_ck3 = ((uint32_t)(v_bq3 * 25172u)); - v_ck5 = ((uint32_t)(v_bq5 * 16819u)); - v_ck7 = ((uint32_t)(v_bq7 * 2446u)); - v_ci51 *= 4294964100u; - v_ci53 *= 4294946301u; - v_ci71 *= 4294959923u; - v_ci73 *= 4294951227u; - v_cl51 = ((uint32_t)(v_ci51 + v_cj)); - v_cl73 = ((uint32_t)(v_ci73 + v_cj)); - v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); - v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); - v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); - v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); - v_intermediate[7u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); - v_intermediate[63u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); - v_intermediate[15u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); - v_intermediate[55u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); - v_intermediate[23u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); - v_intermediate[47u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); - v_intermediate[31u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); - v_intermediate[39u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); + + return status; +} + +// -------- func gif.decoder.decode_lsd + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_lsd( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_flags = 0; + uint8_t v_background_color_index = 0; + uint32_t v_num_palette_entries = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + uint32_t v_argb = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (0u == (v_intermediate[1u] | - v_intermediate[2u] | - v_intermediate[3u] | - v_intermediate[4u] | - v_intermediate[5u] | - v_intermediate[6u] | - v_intermediate[7u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[0u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[2u]; - v_in6 = v_intermediate[6u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[0u]; - v_in4 = v_intermediate[4u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[1u]; - v_in3 = v_intermediate[3u]; - v_in5 = v_intermediate[5u]; - v_in7 = v_intermediate[7u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + + uint32_t coro_susp_point = self->private_impl.p_decode_lsd; + if (coro_susp_point) { + v_flags = self->private_data.s_decode_lsd.v_flags; + v_background_color_index = self->private_data.s_decode_lsd.v_background_color_index; + v_num_palette_entries = self->private_data.s_decode_lsd.v_num_palette_entries; + v_i = self->private_data.s_decode_lsd.v_i; } - if (0u == (v_intermediate[9u] | - v_intermediate[10u] | - v_intermediate[11u] | - v_intermediate[12u] | - v_intermediate[13u] | - v_intermediate[14u] | - v_intermediate[15u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_lsd.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_lsd.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 8) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + self->private_impl.f_width = t_0; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[8u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[10u]; - v_in6 = v_intermediate[14u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[8u]; - v_in4 = v_intermediate[12u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[9u]; - v_in3 = v_intermediate[11u]; - v_in5 = v_intermediate[13u]; - v_in7 = v_intermediate[15u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_lsd.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_lsd.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 8) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + self->private_impl.f_height = t_1; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } - if (0u == (v_intermediate[17u] | - v_intermediate[18u] | - v_intermediate[19u] | - v_intermediate[20u] | - v_intermediate[21u] | - v_intermediate[22u] | - v_intermediate[23u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_flags = t_2; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[16u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[18u]; - v_in6 = v_intermediate[22u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[16u]; - v_in4 = v_intermediate[20u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[17u]; - v_in3 = v_intermediate[19u]; - v_in5 = v_intermediate[21u]; - v_in7 = v_intermediate[23u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_background_color_index = t_3; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } - if (0u == (v_intermediate[25u] | - v_intermediate[26u] | - v_intermediate[27u] | - v_intermediate[28u] | - v_intermediate[29u] | - v_intermediate[30u] | - v_intermediate[31u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[24u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[26u]; - v_in6 = v_intermediate[30u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[24u]; - v_in4 = v_intermediate[28u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[25u]; - v_in3 = v_intermediate[27u]; - v_in5 = v_intermediate[29u]; - v_in7 = v_intermediate[31u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } - if (0u == (v_intermediate[33u] | - v_intermediate[34u] | - v_intermediate[35u] | - v_intermediate[36u] | - v_intermediate[37u] | - v_intermediate[38u] | - v_intermediate[39u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + iop_a_src++; + v_i = 0u; + self->private_impl.f_has_global_palette = (((uint8_t)(v_flags & 128u)) != 0u); + if (self->private_impl.f_has_global_palette) { + v_num_palette_entries = (((uint32_t)(1u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u))))); + while (v_i < v_num_palette_entries) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { + t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); + iop_a_src += 3; + } else { + self->private_data.s_decode_lsd.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_lsd.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + if (num_bits_4 == 16) { + t_4 = ((uint32_t)(*scratch >> 40)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)); + } + } + v_argb = t_4; + } + v_argb |= 4278190080u; + self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); + self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); + self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); + self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); + v_i += 1u; + } + if (self->private_impl.f_quirks[2u]) { + if ((v_background_color_index != 0u) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) { + v_j = (4u * ((uint32_t)(v_background_color_index))); + self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0u][(v_j + 0u)])) << 0u) | + (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 1u)])) << 8u) | + (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 2u)])) << 16u) | + (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 3u)])) << 24u)); + } else { + self->private_impl.f_background_color_u32_argb_premul = 77u; + } + } } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[32u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[34u]; - v_in6 = v_intermediate[38u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[32u]; - v_in4 = v_intermediate[36u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[33u]; - v_in3 = v_intermediate[35u]; - v_in5 = v_intermediate[37u]; - v_in7 = v_intermediate[39u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + while (v_i < 256u) { + self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = 0u; + self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = 0u; + self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = 0u; + self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = 255u; + v_i += 1u; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + + goto ok; + ok: + self->private_impl.p_decode_lsd = 0; + goto exit; } - if (0u == (v_intermediate[41u] | - v_intermediate[42u] | - v_intermediate[43u] | - v_intermediate[44u] | - v_intermediate[45u] | - v_intermediate[46u] | - v_intermediate[47u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[40u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[42u]; - v_in6 = v_intermediate[46u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[40u]; - v_in4 = v_intermediate[44u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[41u]; - v_in3 = v_intermediate[43u]; - v_in5 = v_intermediate[45u]; - v_in7 = v_intermediate[47u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + + goto suspend; + suspend: + self->private_impl.p_decode_lsd = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_lsd.v_flags = v_flags; + self->private_data.s_decode_lsd.v_background_color_index = v_background_color_index; + self->private_data.s_decode_lsd.v_num_palette_entries = v_num_palette_entries; + self->private_data.s_decode_lsd.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (0u == (v_intermediate[49u] | - v_intermediate[50u] | - v_intermediate[51u] | - v_intermediate[52u] | - v_intermediate[53u] | - v_intermediate[54u] | - v_intermediate[55u])) { - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + + return status; +} + +// -------- func gif.decoder.decode_extension + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_gif__decoder__decode_extension( + wuffs_gif__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_label = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_extension; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_label = t_0; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[48u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } else { - v_in2 = v_intermediate[50u]; - v_in6 = v_intermediate[54u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[48u]; - v_in4 = v_intermediate[52u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[49u]; - v_in3 = v_intermediate[51u]; - v_in5 = v_intermediate[53u]; - v_in7 = v_intermediate[55u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + if (v_label == 249u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_gif__decoder__decode_gc(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + status = wuffs_base__make_status(NULL); + goto ok; + } else if (v_label == 255u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_gif__decoder__decode_ae(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + status = wuffs_base__make_status(NULL); + goto ok; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - } - if (0u == (v_intermediate[57u] | - v_intermediate[58u] | - v_intermediate[59u] | - v_intermediate[60u] | - v_intermediate[61u] | - v_intermediate[62u] | - v_intermediate[63u])) { - if (8u > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[56u] + 16u)) >> 5u) & 1023u)]; - a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; - a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; - } else { - v_in2 = v_intermediate[58u]; - v_in6 = v_intermediate[62u]; - v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); - v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); - v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); - v_in0 = v_intermediate[56u]; - v_in4 = v_intermediate[60u]; - v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); - v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); - v_rd0 = ((uint32_t)(v_rcp + v_rb2)); - v_rd1 = ((uint32_t)(v_rcm + v_rb6)); - v_rd2 = ((uint32_t)(v_rcm - v_rb6)); - v_rd3 = ((uint32_t)(v_rcp - v_rb2)); - v_in1 = v_intermediate[57u]; - v_in3 = v_intermediate[59u]; - v_in5 = v_intermediate[61u]; - v_in7 = v_intermediate[63u]; - v_ri51 = ((uint32_t)(v_in5 + v_in1)); - v_ri53 = ((uint32_t)(v_in5 + v_in3)); - v_ri71 = ((uint32_t)(v_in7 + v_in1)); - v_ri73 = ((uint32_t)(v_in7 + v_in3)); - v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); - v_rk1 = ((uint32_t)(v_in1 * 12299u)); - v_rk3 = ((uint32_t)(v_in3 * 25172u)); - v_rk5 = ((uint32_t)(v_in5 * 16819u)); - v_rk7 = ((uint32_t)(v_in7 * 2446u)); - v_ri51 *= 4294964100u; - v_ri53 *= 4294946301u; - v_ri71 *= 4294959923u; - v_ri73 *= 4294951227u; - v_rl51 = ((uint32_t)(v_ri51 + v_rj)); - v_rl73 = ((uint32_t)(v_ri73 + v_rj)); - v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); - v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); - v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); - v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); - if (8u > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_gif__decoder__skip_blocks(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; - a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + if (status.repr) { + goto suspend; + } + + ok: + self->private_impl.p_decode_extension = 0; + goto exit; } - return wuffs_base__make_empty_struct(); + + goto suspend; + suspend: + self->private_impl.p_decode_extension = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; } -// ‼ WUFFS MULTI-FILE SECTION +x86_avx2 -// -------- func jpeg.decoder.decode_idct_x86_avx2 +// -------- func gif.decoder.skip_blocks -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_jpeg__decoder__decode_idct_x86_avx2( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_dst_buffer, - uint64_t a_dst_stride, - uint32_t a_q) { - __m256i v_k_0000 = {0}; - __m256i v_k_8080 = {0}; - __m256i v_k_0000_0002 = {0}; - __m256i v_k_0001_FFFF = {0}; - __m256i v_k_0400_0000 = {0}; - __m256i v_k_29CF_1151_D630_1151 = {0}; - __m256i v_k_E333_133E_ADFD_1051 = {0}; - __m256i v_k_E6DC_25A1_1925_25A1 = {0}; - __m256i v_k_ECC1_E333_EFB0_ADFD = {0}; - __m128i v_az_coeffs = {0}; - __m256i v_az_ah00 = {0}; - __m256i v_az_ad00 = {0}; - __m256i v_az_eh00 = {0}; - __m256i v_az_adeh = {0}; - __m256i v_rows01 = {0}; - __m256i v_rows23 = {0}; - __m256i v_rows45 = {0}; - __m256i v_rows67 = {0}; - __m256i v_quants01 = {0}; - __m256i v_quants23 = {0}; - __m256i v_quants45 = {0}; - __m256i v_quants67 = {0}; - __m256i v_rows04 = {0}; - __m256i v_rows31 = {0}; - __m256i v_rows26 = {0}; - __m256i v_rows75 = {0}; - __m256i v_fp_rows62 = {0}; - __m256i v_fp_bq2662ad = {0}; - __m256i v_fp_bq2662eh = {0}; - __m256i v_fp_cb26ad = {0}; - __m256i v_fp_cb26eh = {0}; - __m256i v_fp_rows40pos = {0}; - __m256i v_fp_rows04neg = {0}; - __m256i v_fp_rows0pm4 = {0}; - __m256i v_fp_ccpmad = {0}; - __m256i v_fp_ccpmeh = {0}; - __m256i v_fp_cd01ad = {0}; - __m256i v_fp_cd01eh = {0}; - __m256i v_fp_cd32ad = {0}; - __m256i v_fp_cd32eh = {0}; - __m256i v_fp_sums7351 = {0}; - __m256i v_fp_sums5173 = {0}; - __m256i v_fp_ci73515173ad = {0}; - __m256i v_fp_ci73515173eh = {0}; - __m256i v_fp_cl7351ad = {0}; - __m256i v_fp_cl7351eh = {0}; - __m256i v_fp_rows13 = {0}; - __m256i v_fp_bq7153ad = {0}; - __m256i v_fp_bq7153eh = {0}; - __m256i v_fp_ck75ad = {0}; - __m256i v_fp_ck75eh = {0}; - __m256i v_fp_cl5173ad = {0}; - __m256i v_fp_cl5173eh = {0}; - __m256i v_fp_ck13ad = {0}; - __m256i v_fp_ck13eh = {0}; - __m256i v_intermediate01ad = {0}; - __m256i v_intermediate01eh = {0}; - __m256i v_intermediate01 = {0}; - __m256i v_intermediate32ad = {0}; - __m256i v_intermediate32eh = {0}; - __m256i v_intermediate32 = {0}; - __m256i v_intermediate45ad = {0}; - __m256i v_intermediate45eh = {0}; - __m256i v_intermediate45 = {0}; - __m256i v_intermediate76ad = {0}; - __m256i v_intermediate76eh = {0}; - __m256i v_intermediate76 = {0}; - __m256i v_ita0a1e0e1 = {0}; - __m256i v_ita2a3e2e3 = {0}; - __m256i v_ita4a5e4e5 = {0}; - __m256i v_ita6a7e6e7 = {0}; - __m256i v_ita0c0e0g0 = {0}; - __m256i v_ita1c1e1g1 = {0}; - __m256i v_ita4c4e4g4 = {0}; - __m256i v_ita5c5e5g5 = {0}; - __m256i v_ita0b0e0f0 = {0}; - __m256i v_ita4b4e4f4 = {0}; - __m256i v_itc0d0g0h0 = {0}; - __m256i v_itc4d4g4h4 = {0}; - __m256i v_intermediateae = {0}; - __m256i v_intermediatebf = {0}; - __m256i v_intermediatecg = {0}; - __m256i v_intermediatedh = {0}; - __m256i v_intermediatedb = {0}; - __m256i v_intermediatehf = {0}; - __m256i v_sp_cols62 = {0}; - __m256i v_sp_bq2662ad = {0}; - __m256i v_sp_bq2662eh = {0}; - __m256i v_sp_rb26ad = {0}; - __m256i v_sp_rb26eh = {0}; - __m256i v_sp_cols40pos = {0}; - __m256i v_sp_cols04neg = {0}; - __m256i v_sp_cols0pm4 = {0}; - __m256i v_sp_rcpmad = {0}; - __m256i v_sp_rcpmeh = {0}; - __m256i v_sp_rd01ad = {0}; - __m256i v_sp_rd01eh = {0}; - __m256i v_sp_rd32ad = {0}; - __m256i v_sp_rd32eh = {0}; - __m256i v_sp_sums7351 = {0}; - __m256i v_sp_sums5173 = {0}; - __m256i v_sp_ri73515173ad = {0}; - __m256i v_sp_ri73515173eh = {0}; - __m256i v_sp_rl7351ad = {0}; - __m256i v_sp_rl7351eh = {0}; - __m256i v_sp_cols13 = {0}; - __m256i v_sp_bq7153ad = {0}; - __m256i v_sp_bq7153eh = {0}; - __m256i v_sp_rk75ad = {0}; - __m256i v_sp_rk75eh = {0}; - __m256i v_sp_rl5173ad = {0}; - __m256i v_sp_rl5173eh = {0}; - __m256i v_sp_rk13ad = {0}; - __m256i v_sp_rk13eh = {0}; - __m256i v_final01ad = {0}; - __m256i v_final01eh = {0}; - __m256i v_final01 = {0}; - __m256i v_final32ad = {0}; - __m256i v_final32eh = {0}; - __m256i v_final32 = {0}; - __m256i v_final45ad = {0}; - __m256i v_final45eh = {0}; - __m256i v_final45 = {0}; - __m256i v_final76ad = {0}; - __m256i v_final76eh = {0}; - __m256i v_final76 = {0}; - __m256i v_fta0a1e0e1 = {0}; - __m256i v_fta2a3e2e3 = {0}; - __m256i v_fta4a5e4e5 = {0}; - __m256i v_fta6a7e6e7 = {0}; - __m256i v_fta0c0e0g0 = {0}; - __m256i v_fta1c1e1g1 = {0}; - __m256i v_fta4c4e4g4 = {0}; - __m256i v_fta5c5e5g5 = {0}; - __m256i v_fta0b0e0f0 = {0}; - __m256i v_ftc0d0g0h0 = {0}; - __m256i v_fta4b4e4f4 = {0}; - __m256i v_ftc4d4g4h4 = {0}; - __m256i v_finalae = {0}; - __m256i v_finalbf = {0}; - __m256i v_finalcg = {0}; - __m256i v_finaldh = {0}; - __m256i v_final0145 = {0}; - __m256i v_final2367 = {0}; - uint64_t v_final0 = 0; - uint64_t v_final1 = 0; - uint64_t v_final2 = 0; - uint64_t v_final3 = 0; - uint64_t v_final4 = 0; - uint64_t v_final5 = 0; - uint64_t v_final6 = 0; - uint64_t v_final7 = 0; - wuffs_base__slice_u8 v_remaining = {0}; - - if (8u > a_dst_stride) { - return wuffs_base__make_empty_struct(); - } - v_k_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u)); - v_k_8080 = _mm256_set_epi16((int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u)); - v_k_0000_0002 = _mm256_set_epi16((int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u)); - v_k_0001_FFFF = _mm256_set_epi16((int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u)); - v_k_0400_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u)); - v_k_29CF_1151_D630_1151 = _mm256_set_epi16((int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u)); - v_k_E333_133E_ADFD_1051 = _mm256_set_epi16((int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u)); - v_k_E6DC_25A1_1925_25A1 = _mm256_set_epi16((int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u)); - v_k_ECC1_E333_EFB0_ADFD = _mm256_set_epi16((int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u)); - do { - if (0u == (wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)) | wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u)))) { - v_az_coeffs = _mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 24u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 40u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 56u))); - if (0u == ((uint64_t)(_mm_cvtsi128_si64(_mm_packs_epi16(v_az_coeffs, v_az_coeffs))))) { - v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u)); - v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u)); - v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01); - v_az_ah00 = _mm256_slli_epi16(v_rows01, (int32_t)(2u)); - v_az_ad00 = _mm256_unpacklo_epi16(v_az_ah00, v_az_ah00); - v_az_eh00 = _mm256_unpackhi_epi16(v_az_ah00, v_az_ah00); - v_az_adeh = _mm256_inserti128_si256(v_az_ad00, _mm256_castsi256_si128(v_az_eh00), (int32_t)(1u)); - v_intermediateae = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(0u)); - v_intermediatebf = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(85u)); - v_intermediatecg = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(170u)); - v_intermediatedh = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(255u)); - break; - } - } - v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u)); - v_rows23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u)); - v_rows45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u)); - v_rows67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u)); - v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u)); - v_quants23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 16u)); - v_quants45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 32u)); - v_quants67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 48u)); - v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01); - v_rows23 = _mm256_mullo_epi16(v_rows23, v_quants23); - v_rows45 = _mm256_mullo_epi16(v_rows45, v_quants45); - v_rows67 = _mm256_mullo_epi16(v_rows67, v_quants67); - v_rows04 = _mm256_permute2x128_si256(v_rows01, v_rows45, (int32_t)(32u)); - v_rows31 = _mm256_permute2x128_si256(v_rows23, v_rows01, (int32_t)(49u)); - v_rows26 = _mm256_permute2x128_si256(v_rows23, v_rows67, (int32_t)(32u)); - v_rows75 = _mm256_permute2x128_si256(v_rows67, v_rows45, (int32_t)(49u)); - v_fp_rows62 = _mm256_permute2x128_si256(v_rows26, v_rows26, (int32_t)(1u)); - v_fp_bq2662ad = _mm256_unpacklo_epi16(v_rows26, v_fp_rows62); - v_fp_bq2662eh = _mm256_unpackhi_epi16(v_rows26, v_fp_rows62); - v_fp_cb26ad = _mm256_madd_epi16(v_fp_bq2662ad, v_k_29CF_1151_D630_1151); - v_fp_cb26eh = _mm256_madd_epi16(v_fp_bq2662eh, v_k_29CF_1151_D630_1151); - v_fp_rows40pos = _mm256_permute2x128_si256(v_rows04, v_rows04, (int32_t)(1u)); - v_fp_rows04neg = _mm256_sign_epi16(v_rows04, v_k_0001_FFFF); - v_fp_rows0pm4 = _mm256_add_epi16(v_fp_rows40pos, v_fp_rows04neg); - v_fp_ccpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u)); - v_fp_ccpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u)); - v_fp_cd01ad = _mm256_add_epi32(v_fp_ccpmad, v_fp_cb26ad); - v_fp_cd01eh = _mm256_add_epi32(v_fp_ccpmeh, v_fp_cb26eh); - v_fp_cd32ad = _mm256_sub_epi32(v_fp_ccpmad, v_fp_cb26ad); - v_fp_cd32eh = _mm256_sub_epi32(v_fp_ccpmeh, v_fp_cb26eh); - v_fp_sums7351 = _mm256_add_epi16(v_rows75, v_rows31); - v_fp_sums5173 = _mm256_permute2x128_si256(v_fp_sums7351, v_fp_sums7351, (int32_t)(1u)); - v_fp_ci73515173ad = _mm256_unpacklo_epi16(v_fp_sums7351, v_fp_sums5173); - v_fp_ci73515173eh = _mm256_unpackhi_epi16(v_fp_sums7351, v_fp_sums5173); - v_fp_cl7351ad = _mm256_madd_epi16(v_fp_ci73515173ad, v_k_E6DC_25A1_1925_25A1); - v_fp_cl7351eh = _mm256_madd_epi16(v_fp_ci73515173eh, v_k_E6DC_25A1_1925_25A1); - v_fp_rows13 = _mm256_permute2x128_si256(v_rows31, v_rows31, (int32_t)(1u)); - v_fp_bq7153ad = _mm256_unpacklo_epi16(v_rows75, v_fp_rows13); - v_fp_bq7153eh = _mm256_unpackhi_epi16(v_rows75, v_fp_rows13); - v_fp_ck75ad = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351ad); - v_fp_ck75eh = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351eh); - v_fp_cl5173ad = _mm256_permute2x128_si256(v_fp_cl7351ad, v_fp_cl7351ad, (int32_t)(1u)); - v_fp_cl5173eh = _mm256_permute2x128_si256(v_fp_cl7351eh, v_fp_cl7351eh, (int32_t)(1u)); - v_fp_ck13ad = _mm256_add_epi32(v_fp_cl5173ad, _mm256_madd_epi16(v_fp_bq7153ad, v_k_E333_133E_ADFD_1051)); - v_fp_ck13eh = _mm256_add_epi32(v_fp_cl5173eh, _mm256_madd_epi16(v_fp_bq7153eh, v_k_E333_133E_ADFD_1051)); - v_intermediate01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u)); - v_intermediate01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u)); - v_intermediate01 = _mm256_packs_epi32(v_intermediate01ad, v_intermediate01eh); - v_intermediate32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u)); - v_intermediate32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u)); - v_intermediate32 = _mm256_packs_epi32(v_intermediate32ad, v_intermediate32eh); - v_intermediate45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u)); - v_intermediate45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u)); - v_intermediate45 = _mm256_packs_epi32(v_intermediate45ad, v_intermediate45eh); - v_intermediate76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u)); - v_intermediate76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u)); - v_intermediate76 = _mm256_packs_epi32(v_intermediate76ad, v_intermediate76eh); - v_ita0a1e0e1 = _mm256_permute4x64_epi64(v_intermediate01, (int32_t)(216u)); - v_ita2a3e2e3 = _mm256_permute4x64_epi64(v_intermediate32, (int32_t)(114u)); - v_ita4a5e4e5 = _mm256_permute4x64_epi64(v_intermediate45, (int32_t)(216u)); - v_ita6a7e6e7 = _mm256_permute4x64_epi64(v_intermediate76, (int32_t)(114u)); - v_ita0c0e0g0 = _mm256_unpacklo_epi16(v_ita0a1e0e1, v_ita2a3e2e3); - v_ita1c1e1g1 = _mm256_unpackhi_epi16(v_ita0a1e0e1, v_ita2a3e2e3); - v_ita4c4e4g4 = _mm256_unpacklo_epi16(v_ita4a5e4e5, v_ita6a7e6e7); - v_ita5c5e5g5 = _mm256_unpackhi_epi16(v_ita4a5e4e5, v_ita6a7e6e7); - v_ita0b0e0f0 = _mm256_unpacklo_epi16(v_ita0c0e0g0, v_ita1c1e1g1); - v_itc0d0g0h0 = _mm256_unpackhi_epi16(v_ita0c0e0g0, v_ita1c1e1g1); - v_ita4b4e4f4 = _mm256_unpacklo_epi16(v_ita4c4e4g4, v_ita5c5e5g5); - v_itc4d4g4h4 = _mm256_unpackhi_epi16(v_ita4c4e4g4, v_ita5c5e5g5); - v_intermediateae = _mm256_unpacklo_epi64(v_ita0b0e0f0, v_ita4b4e4f4); - v_intermediatebf = _mm256_unpackhi_epi64(v_ita0b0e0f0, v_ita4b4e4f4); - v_intermediatecg = _mm256_unpacklo_epi64(v_itc0d0g0h0, v_itc4d4g4h4); - v_intermediatedh = _mm256_unpackhi_epi64(v_itc0d0g0h0, v_itc4d4g4h4); - } while (0); - v_intermediatedb = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(32u)); - v_intermediatehf = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(49u)); - v_sp_cols62 = _mm256_permute2x128_si256(v_intermediatecg, v_intermediatecg, (int32_t)(1u)); - v_sp_bq2662ad = _mm256_unpacklo_epi16(v_intermediatecg, v_sp_cols62); - v_sp_bq2662eh = _mm256_unpackhi_epi16(v_intermediatecg, v_sp_cols62); - v_sp_rb26ad = _mm256_madd_epi16(v_sp_bq2662ad, v_k_29CF_1151_D630_1151); - v_sp_rb26eh = _mm256_madd_epi16(v_sp_bq2662eh, v_k_29CF_1151_D630_1151); - v_sp_cols40pos = _mm256_permute2x128_si256(v_intermediateae, v_intermediateae, (int32_t)(1u)); - v_sp_cols04neg = _mm256_sign_epi16(v_intermediateae, v_k_0001_FFFF); - v_sp_cols0pm4 = _mm256_add_epi16(v_sp_cols40pos, v_sp_cols04neg); - v_sp_rcpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u)); - v_sp_rcpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u)); - v_sp_rd01ad = _mm256_add_epi32(v_sp_rcpmad, v_sp_rb26ad); - v_sp_rd01eh = _mm256_add_epi32(v_sp_rcpmeh, v_sp_rb26eh); - v_sp_rd32ad = _mm256_sub_epi32(v_sp_rcpmad, v_sp_rb26ad); - v_sp_rd32eh = _mm256_sub_epi32(v_sp_rcpmeh, v_sp_rb26eh); - v_sp_sums7351 = _mm256_add_epi16(v_intermediatehf, v_intermediatedb); - v_sp_sums5173 = _mm256_permute2x128_si256(v_sp_sums7351, v_sp_sums7351, (int32_t)(1u)); - v_sp_ri73515173ad = _mm256_unpacklo_epi16(v_sp_sums7351, v_sp_sums5173); - v_sp_ri73515173eh = _mm256_unpackhi_epi16(v_sp_sums7351, v_sp_sums5173); - v_sp_rl7351ad = _mm256_madd_epi16(v_sp_ri73515173ad, v_k_E6DC_25A1_1925_25A1); - v_sp_rl7351eh = _mm256_madd_epi16(v_sp_ri73515173eh, v_k_E6DC_25A1_1925_25A1); - v_sp_cols13 = _mm256_permute2x128_si256(v_intermediatedb, v_intermediatedb, (int32_t)(1u)); - v_sp_bq7153ad = _mm256_unpacklo_epi16(v_intermediatehf, v_sp_cols13); - v_sp_bq7153eh = _mm256_unpackhi_epi16(v_intermediatehf, v_sp_cols13); - v_sp_rk75ad = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351ad); - v_sp_rk75eh = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351eh); - v_sp_rl5173ad = _mm256_permute2x128_si256(v_sp_rl7351ad, v_sp_rl7351ad, (int32_t)(1u)); - v_sp_rl5173eh = _mm256_permute2x128_si256(v_sp_rl7351eh, v_sp_rl7351eh, (int32_t)(1u)); - v_sp_rk13ad = _mm256_add_epi32(v_sp_rl5173ad, _mm256_madd_epi16(v_sp_bq7153ad, v_k_E333_133E_ADFD_1051)); - v_sp_rk13eh = _mm256_add_epi32(v_sp_rl5173eh, _mm256_madd_epi16(v_sp_bq7153eh, v_k_E333_133E_ADFD_1051)); - v_final01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u)); - v_final01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u)); - v_final01 = _mm256_packs_epi32(v_final01ad, v_final01eh); - v_final32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u)); - v_final32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u)); - v_final32 = _mm256_packs_epi32(v_final32ad, v_final32eh); - v_final45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u)); - v_final45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u)); - v_final45 = _mm256_packs_epi32(v_final45ad, v_final45eh); - v_final76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u)); - v_final76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u)); - v_final76 = _mm256_packs_epi32(v_final76ad, v_final76eh); - v_fta0a1e0e1 = _mm256_permute4x64_epi64(v_final01, (int32_t)(216u)); - v_fta2a3e2e3 = _mm256_permute4x64_epi64(v_final32, (int32_t)(114u)); - v_fta4a5e4e5 = _mm256_permute4x64_epi64(v_final45, (int32_t)(216u)); - v_fta6a7e6e7 = _mm256_permute4x64_epi64(v_final76, (int32_t)(114u)); - v_fta0c0e0g0 = _mm256_unpacklo_epi16(v_fta0a1e0e1, v_fta2a3e2e3); - v_fta1c1e1g1 = _mm256_unpackhi_epi16(v_fta0a1e0e1, v_fta2a3e2e3); - v_fta4c4e4g4 = _mm256_unpacklo_epi16(v_fta4a5e4e5, v_fta6a7e6e7); - v_fta5c5e5g5 = _mm256_unpackhi_epi16(v_fta4a5e4e5, v_fta6a7e6e7); - v_fta0b0e0f0 = _mm256_unpacklo_epi16(v_fta0c0e0g0, v_fta1c1e1g1); - v_ftc0d0g0h0 = _mm256_unpackhi_epi16(v_fta0c0e0g0, v_fta1c1e1g1); - v_fta4b4e4f4 = _mm256_unpacklo_epi16(v_fta4c4e4g4, v_fta5c5e5g5); - v_ftc4d4g4h4 = _mm256_unpackhi_epi16(v_fta4c4e4g4, v_fta5c5e5g5); - v_finalae = _mm256_unpacklo_epi64(v_fta0b0e0f0, v_fta4b4e4f4); - v_finalbf = _mm256_unpackhi_epi64(v_fta0b0e0f0, v_fta4b4e4f4); - v_finalcg = _mm256_unpacklo_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4); - v_finaldh = _mm256_unpackhi_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4); - v_final0145 = _mm256_add_epi8(_mm256_packs_epi16(v_finalae, v_finalbf), v_k_8080); - v_final2367 = _mm256_add_epi8(_mm256_packs_epi16(v_finalcg, v_finaldh), v_k_8080); - v_final0 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(0u)))); - v_final1 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(1u)))); - v_final2 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(0u)))); - v_final3 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(1u)))); - v_final4 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(2u)))); - v_final5 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(3u)))); - v_final6 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(2u)))); - v_final7 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(3u)))); - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final0); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final1); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final2); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final3); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final4); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final5); - a_dst_buffer = v_remaining; - if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final6); - a_dst_buffer = v_remaining; - if (8u > ((uint64_t)(a_dst_buffer.len))) { - return wuffs_base__make_empty_struct(); - } - wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final7); - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64) -// ‼ WUFFS MULTI-FILE SECTION -x86_avx2 - -// -------- func jpeg.decoder.get_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_jpeg__decoder__get_quirk( - const wuffs_jpeg__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func jpeg.decoder.set_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__set_quirk( - wuffs_jpeg__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - return wuffs_base__make_status(wuffs_base__error__unsupported_option); -} - -// -------- func jpeg.decoder.decode_image_config - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__decode_image_config( - wuffs_jpeg__decoder* self, - wuffs_base__image_config* a_dst, +static wuffs_base__status +wuffs_gif__decoder__skip_blocks( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint8_t v_block_size = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_skip_blocks; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_block_size = t_0; } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input); - goto exit; + if (v_block_size == 0u) { + status = wuffs_base__make_status(NULL); + goto ok; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + self->private_data.s_skip_blocks.scratch = ((uint32_t)(v_block_size)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (self->private_data.s_skip_blocks.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_skip_blocks.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_skip_blocks.scratch; } ok: - self->private_impl.p_decode_image_config[0] = 0; + self->private_impl.p_skip_blocks = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_impl.p_skip_blocks = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func jpeg.decoder.do_decode_image_config +// -------- func gif.decoder.decode_ae WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__do_decode_image_config( - wuffs_jpeg__decoder* self, - wuffs_base__image_config* a_dst, +wuffs_gif__decoder__decode_ae( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_marker = 0; - uint32_t v_pixfmt = 0; + uint8_t v_c8 = 0; + uint8_t v_block_size = 0; + bool v_is_animexts = false; + bool v_is_netscape = false; + bool v_is_iccp = false; + bool v_is_xmp = false; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -42362,253 +42476,191 @@ wuffs_jpeg__decoder__do_decode_image_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_ae; if (coro_susp_point) { - v_marker = self->private_data.s_do_decode_image_config[0].v_marker; + v_block_size = self->private_data.s_decode_ae.v_block_size; + v_is_animexts = self->private_data.s_decode_ae.v_is_animexts; + v_is_netscape = self->private_data.s_decode_ae.v_is_netscape; + v_is_iccp = self->private_data.s_decode_ae.v_is_iccp; + v_is_xmp = self->private_data.s_decode_ae.v_is_xmp; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + do { + if (self->private_impl.f_metadata_fourcc != 0u) { + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c != 255u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_header); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_block_size = t_0; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - if (v_c != 216u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_header); - goto exit; - } - while (true) { - while (true) { + if (v_block_size == 0u) { + status = wuffs_base__make_status(NULL); + goto ok; + } + if (v_block_size != 11u) { + self->private_data.s_decode_ae.scratch = ((uint32_t)(v_block_size)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_ae.scratch; + break; + } + v_is_animexts = true; + v_is_netscape = true; + v_is_iccp = true; + v_is_xmp = true; + v_block_size = 0u; + while (v_block_size < 11u) { { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + v_is_animexts = (v_is_animexts && (v_c8 == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size])); + v_is_netscape = (v_is_netscape && (v_c8 == WUFFS_GIF__NETSCAPE2DOT0[v_block_size])); + v_is_iccp = (v_is_iccp && (v_c8 == WUFFS_GIF__ICCRGBG1012[v_block_size])); + v_is_xmp = (v_is_xmp && (v_c8 == WUFFS_GIF__XMPDATAXMP[v_block_size])); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_block_size += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + if (v_is_animexts || v_is_netscape) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } uint8_t t_2 = *iop_a_src++; - v_c = t_2; + v_block_size = t_2; } - if (v_c == 255u) { + if (v_block_size != 3u) { + self->private_data.s_decode_ae.scratch = ((uint32_t)(v_block_size)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_ae.scratch; break; } - } - while (true) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } uint8_t t_3 = *iop_a_src++; - v_c = t_3; + v_c8 = t_3; } - if (v_c != 255u) { - v_marker = v_c; + if (v_c8 != 1u) { + self->private_data.s_decode_ae.scratch = 2u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (self->private_data.s_decode_ae.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_ae.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_ae.scratch; break; } - } - if (v_marker == 0u) { - continue; - } else if ((208u <= v_marker) && (v_marker <= 217u)) { - if (v_marker <= 215u) { - continue; - } - } else { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); uint32_t t_4; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); iop_a_src += 2; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + self->private_data.s_decode_ae.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_decode_ae.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; if (num_bits_4 == 8) { - t_4 = ((uint32_t)(*scratch >> 48)); + t_4 = ((uint32_t)(*scratch)); break; } num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)); + *scratch |= ((uint64_t)(num_bits_4)) << 56; } } - self->private_impl.f_payload_length = t_4; - } - if (self->private_impl.f_payload_length < 2u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); - goto exit; - } - self->private_impl.f_payload_length -= 2u; - } - if (v_marker < 192u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } else if (v_marker < 208u) { - if (v_marker <= 194u) { - if (self->private_impl.f_sof_marker != 0u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } - self->private_impl.f_sof_marker = v_marker; - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - status = wuffs_jpeg__decoder__decode_sof(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - break; - } else if (v_marker == 195u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_lossless_coding); - goto exit; - } else if (v_marker == 196u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } else if ((197u <= v_marker) && (v_marker <= 199u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_hierarchical_coding); - goto exit; - } else if (v_marker == 200u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_arithmetic_coding); - goto exit; - } - } else if (v_marker < 224u) { - if (v_marker < 218u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); - goto exit; - } else if (v_marker == 218u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } else if (v_marker == 219u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - status = wuffs_jpeg__decoder__decode_dqt(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - continue; - } else if (v_marker == 221u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_jpeg__decoder__decode_dri(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - continue; - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } - } else if (v_marker < 240u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - status = wuffs_jpeg__decoder__decode_appn(self, a_src, v_marker); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + self->private_impl.f_num_animation_loops_value = t_4; } - continue; - } else { - if (v_marker == 254u) { - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; + self->private_impl.f_seen_num_animation_loops_value = true; + if ((0u < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535u)) { + self->private_impl.f_num_animation_loops_value += 1u; } + } else if (self->private_impl.f_call_sequence >= 32u) { + } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) { + self->private_impl.f_metadata_fourcc = 1229144912u; + self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + self->private_impl.f_call_sequence = 16u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; + } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) { + self->private_impl.f_metadata_fourcc = 1481461792u; + self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + self->private_impl.f_call_sequence = 16u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; } - self->private_data.s_do_decode_image_config[0].scratch = self->private_impl.f_payload_length; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - self->private_impl.f_payload_length = 0u; + } while (0); + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - self->private_impl.choosy_decode_idct = ( -#if defined(WUFFS_BASE__CPU_ARCH__X86_64) - wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_jpeg__decoder__decode_idct_x86_avx2 : -#endif - self->private_impl.choosy_decode_idct); - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - if (a_dst != NULL) { - v_pixfmt = 536870920u; - if (self->private_impl.f_num_components > 1u) { - v_pixfmt = 2415954056u; - } - wuffs_base__image_config__set( - a_dst, - v_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - true); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + status = wuffs_gif__decoder__skip_blocks(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; } - self->private_impl.f_call_sequence = 32u; - goto ok; ok: - self->private_impl.p_do_decode_image_config[0] = 0; + self->private_impl.p_decode_ae = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_image_config[0].v_marker = v_marker; + self->private_impl.p_decode_ae = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_ae.v_block_size = v_block_size; + self->private_data.s_decode_ae.v_is_animexts = v_is_animexts; + self->private_data.s_decode_ae.v_is_netscape = v_is_netscape; + self->private_data.s_decode_ae.v_is_iccp = v_is_iccp; + self->private_data.s_decode_ae.v_is_xmp = v_is_xmp; goto exit; exit: @@ -42619,18 +42671,18 @@ wuffs_jpeg__decoder__do_decode_image_config( return status; } -// -------- func jpeg.decoder.decode_dqt +// -------- func gif.decoder.decode_gc WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__decode_dqt( - wuffs_jpeg__decoder* self, +wuffs_gif__decoder__decode_gc( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_q = 0; - uint32_t v_i = 0; + uint8_t v_c8 = 0; + uint8_t v_flags = 0; + uint16_t v_gc_duration_centiseconds = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -42643,73 +42695,103 @@ wuffs_jpeg__decoder__decode_dqt( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_dqt[0]; - if (coro_susp_point) { - v_q = self->private_data.s_decode_dqt[0].v_q; - v_i = self->private_data.s_decode_dqt[0].v_i; - } + uint32_t coro_susp_point = self->private_impl.p_decode_gc; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - while (self->private_impl.f_payload_length > 0u) { - self->private_impl.f_payload_length -= 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if ((v_c & 15u) > 3u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker); - goto exit; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_q = (v_c & 15u); - if ((v_c >> 4u) == 1u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision); - goto exit; - } else if (((v_c >> 4u) > 1u) || (self->private_impl.f_payload_length < 64u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker); - goto exit; + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 4u) { + status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - self->private_impl.f_payload_length -= 64u; - v_i = 0u; - while (v_i < 64u) { - v_i += 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint8_t t_1 = *iop_a_src++; + v_flags = t_1; + } + self->private_impl.f_gc_has_transparent_index = (((uint8_t)(v_flags & 1u)) != 0u); + v_flags = ((uint8_t)(((uint8_t)(v_flags >> 2u)) & 7u)); + if (v_flags == 2u) { + self->private_impl.f_gc_disposal = 1u; + } else if ((v_flags == 3u) || (v_flags == 4u)) { + self->private_impl.f_gc_disposal = 2u; + } else { + self->private_impl.f_gc_disposal = 0u; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint16_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + iop_a_src += 2; + } else { + self->private_data.s_decode_gc.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint16_t t_1 = *iop_a_src++; - self->private_impl.f_quant_tables[v_q][WUFFS_JPEG__UNZIG[v_i]] = t_1; + uint64_t* scratch = &self->private_data.s_decode_gc.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 8) { + t_2 = ((uint16_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; } } - self->private_impl.f_seen_dqt[v_q] = true; - if (self->private_impl.f_sof_marker == 0u) { - v_i = 0u; - while (v_i < 64u) { - self->private_impl.f_saved_quant_tables[v_q][v_i] = self->private_impl.f_quant_tables[v_q][v_i]; - v_i += 1u; - } - self->private_impl.f_saved_seen_dqt[v_q] = true; + v_gc_duration_centiseconds = t_2; + } + self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + self->private_impl.f_gc_transparent_index = t_3; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control); + goto exit; } goto ok; ok: - self->private_impl.p_decode_dqt[0] = 0; + self->private_impl.p_decode_gc = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_dqt[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_dqt[0].v_q = v_q; - self->private_data.s_decode_dqt[0].v_i = v_i; + self->private_impl.p_decode_gc = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -42720,12 +42802,12 @@ wuffs_jpeg__decoder__decode_dqt( return status; } -// -------- func jpeg.decoder.decode_dri +// -------- func gif.decoder.decode_id_part0 WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__decode_dri( - wuffs_jpeg__decoder* self, +wuffs_gif__decoder__decode_id_part0( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); @@ -42740,57 +42822,144 @@ wuffs_jpeg__decoder__decode_dri( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_dri[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_id_part0; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_payload_length != 2u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dri_marker); - goto exit; - } - self->private_impl.f_payload_length = 0u; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint16_t t_0; + uint32_t t_0; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src); + t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); iop_a_src += 2; } else { - self->private_data.s_decode_dri[0].scratch = 0; + self->private_data.s_decode_id_part0.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_dri[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; if (num_bits_0 == 8) { - t_0 = ((uint16_t)(*scratch >> 48)); + t_0 = ((uint32_t)(*scratch)); break; } num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); + *scratch |= ((uint64_t)(num_bits_0)) << 56; } } - self->private_impl.f_restart_interval = t_0; + self->private_impl.f_frame_rect_x0 = t_0; } - if (self->private_impl.f_sof_marker == 0u) { - self->private_impl.f_saved_restart_interval = self->private_impl.f_restart_interval; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_id_part0.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 8) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + self->private_impl.f_frame_rect_y0 = t_1; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_id_part0.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 8) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + self->private_impl.f_frame_rect_x1 = t_2; + } + self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_id_part0.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_id_part0.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 8) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; + } + } + self->private_impl.f_frame_rect_y1 = t_3; + } + self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0; + self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; + self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0; + if ((self->private_impl.f_num_decoded_frame_configs_value == 0u) && ! self->private_impl.f_quirks[4u]) { + self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1); + self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1); } goto ok; ok: - self->private_impl.p_decode_dri[0] = 0; + self->private_impl.p_decode_id_part0 = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_dri[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_id_part0 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -42801,18 +42970,24 @@ wuffs_jpeg__decoder__decode_dri( return status; } -// -------- func jpeg.decoder.decode_appn +// -------- func gif.decoder.decode_id_part1 WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__decode_appn( - wuffs_jpeg__decoder* self, +wuffs_gif__decoder__decode_id_part1( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, - uint8_t a_marker) { + wuffs_base__pixel_blend a_blend) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c8 = 0; - uint32_t v_c32 = 0; + uint8_t v_flags = 0; + uint8_t v_which_palette = 0; + uint32_t v_num_palette_entries = 0; + uint32_t v_i = 0; + uint32_t v_argb = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint8_t v_lw = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -42825,184 +43000,136 @@ wuffs_jpeg__decoder__decode_appn( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_appn[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_id_part1; + if (coro_susp_point) { + v_which_palette = self->private_data.s_decode_id_part1.v_which_palette; + v_num_palette_entries = self->private_data.s_decode_id_part1.v_num_palette_entries; + v_i = self->private_data.s_decode_id_part1.v_i; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - do { - if (a_marker == 224u) { - if (self->private_impl.f_payload_length >= 5u) { - self->private_impl.f_payload_length -= 5u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_appn[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; - } - } - v_c32 = t_0; - } - if (v_c32 != 1179207242u) { - self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 1u)); - break; - } - { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_flags = t_0; + } + if (((uint8_t)(v_flags & 64u)) != 0u) { + self->private_impl.f_interlace = 4u; + } else { + self->private_impl.f_interlace = 0u; + } + v_which_palette = 1u; + if (((uint8_t)(v_flags & 128u)) != 0u) { + v_num_palette_entries = (((uint32_t)(1u)) << ((uint8_t)(1u + ((uint8_t)(v_flags & 7u))))); + v_i = 0u; + while (v_i < v_num_palette_entries) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { + t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); + iop_a_src += 3; + } else { + self->private_data.s_decode_id_part1.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c8 = t_1; - } - self->private_impl.f_is_jfif = (v_c8 == 0u); - } - } else if (a_marker == 238u) { - if (self->private_impl.f_payload_length >= 12u) { - self->private_impl.f_payload_length -= 12u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_appn[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; - if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; - } - } - v_c32 = t_2; - } - if (v_c32 != 1651467329u) { - self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 8u)); - break; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_appn[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch)); - break; - } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)) << 56; + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - } - v_c32 = t_3; - } - if ((255u & v_c32) != 101u) { - self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 4u)); - break; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_appn[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 24) { - t_4 = ((uint32_t)(*scratch)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; + uint64_t* scratch = &self->private_data.s_decode_id_part1.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 16) { + t_1 = ((uint32_t)(*scratch >> 40)); + break; } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); } - v_c32 = t_4; - } - if ((v_c32 >> 24u) == 0u) { - self->private_impl.f_is_adobe = 1u; - } else { - self->private_impl.f_is_adobe = 2u; } + v_argb = t_1; } + v_argb |= 4278190080u; + self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); + self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); + self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); + self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); + v_i += 1u; } - } while (0); - self->private_data.s_decode_appn[0].scratch = self->private_impl.f_payload_length; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (self->private_data.s_decode_appn[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_appn[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + while (v_i < 256u) { + self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = 0u; + self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = 0u; + self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = 0u; + self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = 255u; + v_i += 1u; + } + } else if (self->private_impl.f_quirks[6u] && ! self->private_impl.f_has_global_palette) { + status = wuffs_base__make_status(wuffs_gif__error__bad_palette); + goto exit; + } else if (self->private_impl.f_gc_has_transparent_index) { + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1u], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0u], 1024)); + } else { + v_which_palette = 0u; } - iop_a_src += self->private_data.s_decode_appn[0].scratch; - self->private_impl.f_payload_length = 0u; + if (self->private_impl.f_gc_has_transparent_index) { + self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0u)] = 0u; + self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1u)] = 0u; + self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2u)] = 0u; + self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3u)] = 0u; + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), + wuffs_base__utility__make_pixel_format(2198077448u), + wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + if (self->private_impl.f_ignored_but_affects_benchmarks) { + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_lw = t_2; + } + if (v_lw > 8u) { + status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width); + goto exit; + } + self->private_impl.f_lzw_pending_literal_width_plus_one = ((uint32_t)(((uint8_t)(1u + v_lw)))); + self->private_impl.f_ignored_but_affects_benchmarks = true; - goto ok; ok: - self->private_impl.p_decode_appn[0] = 0; + self->private_impl.p_decode_id_part1 = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_appn[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_id_part1 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_id_part1.v_which_palette = v_which_palette; + self->private_data.s_decode_id_part1.v_num_palette_entries = v_num_palette_entries; + self->private_data.s_decode_id_part1.v_i = v_i; goto exit; exit: @@ -43013,30 +43140,29 @@ wuffs_jpeg__decoder__decode_appn( return status; } -// -------- func jpeg.decoder.decode_sof +// -------- func gif.decoder.decode_id_part2 WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__decode_sof( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src) { +wuffs_gif__decoder__decode_id_part2( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_comp_h = 0; - uint8_t v_comp_v = 0; - uint32_t v_i = 0; - uint32_t v_j = 0; - bool v_has_h24 = false; - bool v_has_h3 = false; - bool v_has_v24 = false; - bool v_has_v3 = false; - uint32_t v_upper_bound = 0; - uint64_t v_wh0 = 0; - uint64_t v_wh1 = 0; - uint64_t v_wh2 = 0; - uint64_t v_wh3 = 0; - uint64_t v_progressive = 0; + uint64_t v_block_size = 0; + bool v_need_block_size = false; + uint32_t v_n_copied = 0; + uint64_t v_n_compressed = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint64_t v_mark = 0; + wuffs_base__status v_copy_status = wuffs_base__make_status(NULL); const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -43049,269 +43175,185 @@ wuffs_jpeg__decoder__decode_sof( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_sof[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_id_part2; if (coro_susp_point) { - v_i = self->private_data.s_decode_sof[0].v_i; + v_block_size = self->private_data.s_decode_id_part2.v_block_size; + v_need_block_size = self->private_data.s_decode_id_part2.v_need_block_size; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_payload_length < 6u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } - self->private_impl.f_payload_length -= 6u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c == 8u) { - } else if (v_c == 12u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_12_bits); - goto exit; - } else if (v_c == 16u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_16_bits); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_1 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_sof[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - while (true) { + wuffs_gif__decoder__lzw_init(self); + v_need_block_size = true; + label__outer__continue:; + while (true) { + if (v_need_block_size) { + v_need_block_size = false; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 8) { - t_1 = ((uint32_t)(*scratch >> 48)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); + uint64_t t_0 = *iop_a_src++; + v_block_size = t_0; } } - self->private_impl.f_height = t_1; - } - if (self->private_impl.f_height == 0u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_implicit_height); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_sof[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); - if (num_bits_2 == 8) { - t_2 = ((uint32_t)(*scratch >> 48)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)); - } + if (v_block_size == 0u) { + break; } - self->private_impl.f_width = t_2; - } - if (self->private_impl.f_width == 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + while (((uint64_t)(io2_a_src - iop_a_src)) == 0u) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; - } - if ((v_c == 0u) || (v_c > 4u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } else if (v_c == 2u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_color_model); - goto exit; - } - self->private_impl.f_num_components = ((uint32_t)(v_c)); - if (self->private_impl.f_payload_length != (3u * self->private_impl.f_num_components)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } - self->private_impl.f_payload_length = 0u; - v_i = 0u; - while (v_i < self->private_impl.f_num_components) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - self->private_impl.f_components_c[v_i] = t_4; + if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) { + self->private_impl.f_compressed_ri = 0u; + self->private_impl.f_compressed_wi = 0u; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + while (self->private_impl.f_compressed_wi <= 3841u) { + v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src))); + if (v_n_compressed <= 0u) { + break; } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; - } - v_comp_h = (v_c >> 4u); - v_comp_v = (v_c & 15u); - if ((v_comp_h == 0u) || - (v_comp_h > 4u) || - (v_comp_v == 0u) || - (v_comp_v > 4u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } - self->private_impl.f_components_h[v_i] = v_comp_h; - if (self->private_impl.f_max_incl_components_h < self->private_impl.f_components_h[v_i]) { - self->private_impl.f_max_incl_components_h = self->private_impl.f_components_h[v_i]; - } - self->private_impl.f_components_v[v_i] = v_comp_v; - if (self->private_impl.f_max_incl_components_v < self->private_impl.f_components_v[v_i]) { - self->private_impl.f_max_incl_components_v = self->private_impl.f_components_v[v_i]; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_n_copied = wuffs_private_impl__io_reader__limited_copy_u32_to_slice( + &iop_a_src, io2_a_src,((uint32_t)(v_n_compressed)), wuffs_base__make_slice_u8_ij(self->private_data.f_compressed, self->private_impl.f_compressed_wi, 4096)); + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied))); + wuffs_private_impl__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied))); + if (v_block_size > 0u) { + break; } - uint8_t t_6 = *iop_a_src++; - v_c = t_6; - } - if (v_c >= 4u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + v_need_block_size = true; + break; + } + v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))); + iop_a_src += 1u; } - self->private_impl.f_components_tq[v_i] = v_c; - v_j = 0u; - while (v_j < v_i) { - if (self->private_impl.f_components_c[v_j] == self->private_impl.f_components_c[v_i]) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + while (true) { + if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096u)) { + status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); goto exit; } - v_j += 1u; - } - v_i += 1u; - } - if (self->private_impl.f_num_components == 1u) { - self->private_impl.f_max_incl_components_h = 1u; - self->private_impl.f_max_incl_components_v = 1u; - self->private_impl.f_components_h[0u] = 1u; - self->private_impl.f_components_v[0u] = 1u; - } else { - v_has_h24 = false; - v_has_h3 = false; - v_has_v24 = false; - v_has_v3 = false; - v_i = 0u; - while (v_i < self->private_impl.f_num_components) { - v_has_h24 = (v_has_h24 || (self->private_impl.f_components_h[v_i] == 2u) || (self->private_impl.f_components_h[v_i] == 4u)); - v_has_h3 = (v_has_h3 || (self->private_impl.f_components_h[v_i] == 3u)); - v_has_v24 = (v_has_v24 || (self->private_impl.f_components_v[v_i] == 2u) || (self->private_impl.f_components_v[v_i] == 4u)); - v_has_v3 = (v_has_v3 || (self->private_impl.f_components_v[v_i] == 3u)); - v_i += 1u; - } - if ((v_has_h24 && v_has_h3) || (v_has_v24 && v_has_v3)) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_fractional_sampling); - goto exit; - } - if (self->private_impl.f_num_components == 4u) { - self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe < 2u); - } else { - if (self->private_impl.f_is_jfif) { - self->private_impl.f_is_rgb_or_cmyk = false; - } else if (self->private_impl.f_is_adobe > 0u) { - self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe == 1u); - } else { - self->private_impl.f_is_rgb_or_cmyk = ((self->private_impl.f_components_c[0u] == 82u) && (self->private_impl.f_components_c[1u] == 71u) && (self->private_impl.f_components_c[2u] == 66u)); + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_compressed, + self->private_impl.f_compressed_ri, + self->private_impl.f_compressed_wi), + 0u); + v_mark = ((uint64_t)(iop_v_r - io0_v_r)); + u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr)); + wuffs_gif__decoder__lzw_read_from(self, v_r); + iop_v_r = u_r.data.ptr + u_r.meta.ri; + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r)))); + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; } - } - } - self->private_impl.f_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, 1u, self->private_impl.f_max_incl_components_h); - self->private_impl.f_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, 1u, self->private_impl.f_max_incl_components_v); - v_upper_bound = 65544u; - self->private_impl.f_components_workbuf_widths[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[0u])))); - self->private_impl.f_components_workbuf_widths[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[1u])))); - self->private_impl.f_components_workbuf_widths[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[2u])))); - self->private_impl.f_components_workbuf_widths[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[3u])))); - self->private_impl.f_components_workbuf_heights[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[0u])))); - self->private_impl.f_components_workbuf_heights[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[1u])))); - self->private_impl.f_components_workbuf_heights[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[2u])))); - self->private_impl.f_components_workbuf_heights[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[3u])))); - v_wh0 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0u]))); - v_wh1 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[1u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1u]))); - v_wh2 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[2u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2u]))); - v_wh3 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[3u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3u]))); - v_progressive = 0u; - if (self->private_impl.f_sof_marker >= 194u) { - v_progressive = 2u; - v_i = 0u; - while (v_i < 4u) { - v_j = 0u; - while (v_j < 10u) { - self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u; - v_j += 1u; + if (self->private_impl.f_lzw_output_ri < self->private_impl.f_lzw_output_wi) { + v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_lzw_output, + self->private_impl.f_lzw_output_ri, + self->private_impl.f_lzw_output_wi)); + if (wuffs_base__status__is_error(&v_copy_status)) { + status = v_copy_status; + goto exit; + } + self->private_impl.f_lzw_output_ri = 0u; + self->private_impl.f_lzw_output_wi = 0u; } - v_i += 1u; + if (self->private_impl.f_lzw_read_from_return_value == 0u) { + self->private_impl.f_ignored_but_affects_benchmarks = false; + if (v_need_block_size || (v_block_size > 0u)) { + self->private_data.s_decode_id_part2.scratch = ((uint32_t)(v_block_size)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (self->private_data.s_decode_id_part2.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_id_part2.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_id_part2.scratch; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_gif__decoder__skip_blocks(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + goto label__outer__break; + } else if (self->private_impl.f_lzw_read_from_return_value == 1u) { + continue; + } else if (self->private_impl.f_lzw_read_from_return_value == 2u) { + goto label__outer__continue; + } else if (self->private_impl.f_quirks[3u] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0u)) { + if (v_need_block_size || (v_block_size > 0u)) { + self->private_data.s_decode_id_part2.scratch = ((uint32_t)(v_block_size)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_data.s_decode_id_part2.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_id_part2.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_id_part2.scratch; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + status = wuffs_gif__decoder__skip_blocks(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + goto label__outer__break; + } else if (self->private_impl.f_lzw_read_from_return_value == 3u) { + status = wuffs_base__make_status(wuffs_gif__error__truncated_input); + goto exit; + } else if (self->private_impl.f_lzw_read_from_return_value == 4u) { + status = wuffs_base__make_status(wuffs_gif__error__bad_lzw_code); + goto exit; + } + status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); + goto exit; } } - self->private_impl.f_components_workbuf_offsets[0u] = 0u; - self->private_impl.f_components_workbuf_offsets[1u] = (self->private_impl.f_components_workbuf_offsets[0u] + v_wh0); - self->private_impl.f_components_workbuf_offsets[2u] = (self->private_impl.f_components_workbuf_offsets[1u] + v_wh1); - self->private_impl.f_components_workbuf_offsets[3u] = (self->private_impl.f_components_workbuf_offsets[2u] + v_wh2); - self->private_impl.f_components_workbuf_offsets[4u] = (self->private_impl.f_components_workbuf_offsets[3u] + v_wh3); - self->private_impl.f_components_workbuf_offsets[5u] = (self->private_impl.f_components_workbuf_offsets[4u] + (v_wh0 * v_progressive)); - self->private_impl.f_components_workbuf_offsets[6u] = (self->private_impl.f_components_workbuf_offsets[5u] + (v_wh1 * v_progressive)); - self->private_impl.f_components_workbuf_offsets[7u] = (self->private_impl.f_components_workbuf_offsets[6u] + (v_wh2 * v_progressive)); - self->private_impl.f_components_workbuf_offsets[8u] = (self->private_impl.f_components_workbuf_offsets[7u] + (v_wh3 * v_progressive)); + label__outer__break:; + self->private_impl.f_compressed_ri = 0u; + self->private_impl.f_compressed_wi = 0u; + if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) && (self->private_impl.f_frame_rect_x0 != self->private_impl.f_frame_rect_x1) && (self->private_impl.f_frame_rect_y0 != self->private_impl.f_frame_rect_y1)) { + status = wuffs_base__make_status(wuffs_base__error__not_enough_data); + goto exit; + } - goto ok; ok: - self->private_impl.p_decode_sof[0] = 0; + self->private_impl.p_decode_id_part2 = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_sof[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_sof[0].v_i = v_i; + self->private_impl.p_decode_id_part2 = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_id_part2.v_block_size = v_block_size; + self->private_data.s_decode_id_part2.v_need_block_size = v_need_block_size; goto exit; exit: @@ -43322,106 +43364,182 @@ wuffs_jpeg__decoder__decode_sof( return status; } -// -------- func jpeg.decoder.quantize_dimension +// -------- func gif.decoder.copy_to_image_buffer WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__quantize_dimension( - const wuffs_jpeg__decoder* self, - uint32_t a_width, - uint8_t a_h, - uint8_t a_max_incl_h) { - uint32_t v_ratio = 0; +static wuffs_base__status +wuffs_gif__decoder__copy_to_image_buffer( + wuffs_gif__decoder* self, + wuffs_base__pixel_buffer* a_pb, + wuffs_base__slice_u8 a_src) { + wuffs_base__slice_u8 v_dst = {0}; + wuffs_base__slice_u8 v_src = {0}; + uint64_t v_width_in_bytes = 0; + uint64_t v_n = 0; + uint64_t v_src_ri = 0; + wuffs_base__pixel_format v_pixfmt = {0}; + uint32_t v_bytes_per_pixel = 0; + uint32_t v_bits_per_pixel = 0; + wuffs_base__table_u8 v_tab = {0}; + uint64_t v_i = 0; + uint64_t v_j = 0; + uint32_t v_replicate_y0 = 0; + uint32_t v_replicate_y1 = 0; + wuffs_base__slice_u8 v_replicate_dst = {0}; + wuffs_base__slice_u8 v_replicate_src = {0}; - v_ratio = 0u; - if (a_h > 0u) { - v_ratio = ((uint32_t)((a_max_incl_h / a_h))); + v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb); + v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt); + if ((v_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } - if (v_ratio == 1u) { - return ((a_width + 7u) / 8u); - } else if (v_ratio == 2u) { - return ((a_width + 15u) / 16u); - } else if (v_ratio == 3u) { - return ((a_width + 23u) / 24u); + v_bytes_per_pixel = (v_bits_per_pixel >> 3u); + v_width_in_bytes = ((uint64_t)((self->private_impl.f_width * v_bytes_per_pixel))); + v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0u); + while (v_src_ri < ((uint64_t)(a_src.len))) { + v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri); + if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) { + if (self->private_impl.f_quirks[3u]) { + return wuffs_base__make_status(NULL); + } + return wuffs_base__make_status(wuffs_base__error__too_much_data); + } + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0u); + } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel))); + if (v_i < ((uint64_t)(v_dst.len))) { + v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel))); + if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) { + v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j); + } else { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i); + } + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), v_src); + wuffs_private_impl__u64__sat_add_indirect(&v_src_ri, v_n); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u)); + } + if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) { + self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; + if (self->private_impl.f_interlace == 0u) { + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1u); + continue; + } + if ((self->private_impl.f_num_decoded_frames_value == 0u) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1u)) { + v_replicate_src = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u); + v_replicate_y1 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_COUNT[self->private_impl.f_interlace]))); + v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1); + while (v_replicate_y0 < v_replicate_y1) { + v_replicate_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_replicate_y0); + wuffs_private_impl__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src); + v_replicate_y0 += 1u; + } + self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1); + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace]))); + while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_interlace -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]); + } + continue; + } + if (((uint64_t)(a_src.len)) == v_src_ri) { + break; + } else if (((uint64_t)(a_src.len)) < v_src_ri) { + return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); + } + v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x))); + v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri)); + wuffs_private_impl__u64__sat_add_indirect(&v_src_ri, v_n); + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) { + self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0; + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace]))); + while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_interlace -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]); + } + continue; + } + if (v_src_ri != ((uint64_t)(a_src.len))) { + return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o); + } + break; } - return ((a_width + 31u) / 32u); + return wuffs_base__make_status(NULL); } -// -------- func jpeg.decoder.decode_frame_config +// -------- func gif.decoder.lzw_init WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__decode_frame_config( - wuffs_jpeg__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +static wuffs_base__empty_struct +wuffs_gif__decoder__lzw_init( + wuffs_gif__decoder* self) { + uint32_t v_i = 0; - ok: - self->private_impl.p_decode_frame_config[0] = 0; - goto exit; + self->private_impl.f_lzw_literal_width = 8u; + if (self->private_impl.f_lzw_pending_literal_width_plus_one > 0u) { + self->private_impl.f_lzw_literal_width = (self->private_impl.f_lzw_pending_literal_width_plus_one - 1u); } - - goto suspend; - suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + self->private_impl.f_lzw_clear_code = (((uint32_t)(1u)) << self->private_impl.f_lzw_literal_width); + self->private_impl.f_lzw_end_code = (self->private_impl.f_lzw_clear_code + 1u); + self->private_impl.f_lzw_save_code = self->private_impl.f_lzw_end_code; + self->private_impl.f_lzw_prev_code = self->private_impl.f_lzw_end_code; + self->private_impl.f_lzw_width = (self->private_impl.f_lzw_literal_width + 1u); + self->private_impl.f_lzw_bits = 0u; + self->private_impl.f_lzw_n_bits = 0u; + self->private_impl.f_lzw_output_ri = 0u; + self->private_impl.f_lzw_output_wi = 0u; + v_i = 0u; + while (v_i < self->private_impl.f_lzw_clear_code) { + self->private_data.f_lzw_lm1s[v_i] = 0u; + self->private_data.f_lzw_suffixes[v_i][0u] = ((uint8_t)(v_i)); + v_i += 1u; } - return status; + return wuffs_base__make_empty_struct(); } -// -------- func jpeg.decoder.do_decode_frame_config +// -------- func gif.decoder.lzw_read_from WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__do_decode_frame_config( - wuffs_jpeg__decoder* self, - wuffs_base__frame_config* a_dst, +static wuffs_base__empty_struct +wuffs_gif__decoder__lzw_read_from( + wuffs_gif__decoder* self, wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); + uint32_t v_clear_code = 0; + uint32_t v_end_code = 0; + uint32_t v_save_code = 0; + uint32_t v_prev_code = 0; + uint32_t v_width = 0; + uint32_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_output_wi = 0; + uint32_t v_code = 0; + uint32_t v_c = 0; + uint32_t v_o = 0; + uint32_t v_steps = 0; + uint8_t v_first_byte = 0; + uint16_t v_lm1_b = 0; + uint16_t v_lm1_a = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -43434,83 +43552,370 @@ wuffs_jpeg__decoder__do_decode_frame_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + v_clear_code = self->private_impl.f_lzw_clear_code; + v_end_code = self->private_impl.f_lzw_end_code; + v_save_code = self->private_impl.f_lzw_save_code; + v_prev_code = self->private_impl.f_lzw_prev_code; + v_width = self->private_impl.f_lzw_width; + v_bits = self->private_impl.f_lzw_bits; + v_n_bits = self->private_impl.f_lzw_n_bits; + v_output_wi = self->private_impl.f_lzw_output_wi; + while (true) { + if (v_n_bits < v_width) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { + v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits)); + iop_a_src += ((31u - v_n_bits) >> 3u); + v_n_bits |= 24u; + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + self->private_impl.f_lzw_read_from_return_value = 3u; + } else { + self->private_impl.f_lzw_read_from_return_value = 2u; + } + break; + } else { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + if (v_n_bits >= v_width) { + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + self->private_impl.f_lzw_read_from_return_value = 3u; + } else { + self->private_impl.f_lzw_read_from_return_value = 2u; + } + break; + } else { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + if (v_n_bits < v_width) { + self->private_impl.f_lzw_read_from_return_value = 5u; + break; + } + } } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_jpeg__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + v_code = ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_width)); + v_bits >>= v_width; + v_n_bits -= v_width; + if (v_code < v_clear_code) { + self->private_data.f_lzw_output[v_output_wi] = ((uint8_t)(v_code)); + v_output_wi = ((v_output_wi + 1u) & 8191u); + if (v_save_code <= 4095u) { + v_lm1_a = ((uint16_t)(((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u)); + self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_a; + if (((uint16_t)(v_lm1_a % 8u)) != 0u) { + self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code]; + memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code])); + self->private_data.f_lzw_suffixes[v_save_code][((uint16_t)(v_lm1_a % 8u))] = ((uint8_t)(v_code)); + } else { + self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); + self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_code)); + } + v_save_code += 1u; + if (v_width < 12u) { + v_width += (1u & (v_save_code >> v_width)); + } + v_prev_code = v_code; } - if (status.repr) { - goto suspend; + } else if (v_code <= v_end_code) { + if (v_code == v_end_code) { + self->private_impl.f_lzw_read_from_return_value = 0u; + break; } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; + v_save_code = v_end_code; + v_prev_code = v_end_code; + v_width = (self->private_impl.f_lzw_literal_width + 1u); + } else if (v_code <= v_save_code) { + v_c = v_code; + if (v_code == v_save_code) { + v_c = v_prev_code; + } + v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) & 4294967288u)) & 8191u); + v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lzw_lm1s[v_c]))) & 8191u); + v_steps = (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) >> 3u); + while (true) { + memcpy((self->private_data.f_lzw_output)+(v_o), (self->private_data.f_lzw_suffixes[v_c]), 8u); + if (v_steps <= 0u) { + break; + } + v_steps -= 1u; + v_o = (((uint32_t)(v_o - 8u)) & 8191u); + v_c = ((uint32_t)(self->private_impl.f_lzw_prefixes[v_c])); + } + v_first_byte = self->private_data.f_lzw_suffixes[v_c][0u]; + if (v_code == v_save_code) { + self->private_data.f_lzw_output[v_output_wi] = v_first_byte; + v_output_wi = ((v_output_wi + 1u) & 8191u); + } + if (v_save_code <= 4095u) { + v_lm1_b = ((uint16_t)(((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u)); + self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_b; + if (((uint16_t)(v_lm1_b % 8u)) != 0u) { + self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code]; + memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code])); + self->private_data.f_lzw_suffixes[v_save_code][((uint16_t)(v_lm1_b % 8u))] = v_first_byte; + } else { + self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); + self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte)); + } + v_save_code += 1u; + if (v_width < 12u) { + v_width += (1u & (v_save_code >> v_width)); + } + v_prev_code = v_code; } - } else if (self->private_impl.f_call_sequence == 64u) { - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + self->private_impl.f_lzw_read_from_return_value = 4u; + break; } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height), - ((wuffs_base__flicks)(0u)), - 0u, - self->private_impl.f_frame_config_io_position, - 0u, - true, - false, - 4278190080u); + if (v_output_wi > 4095u) { + self->private_impl.f_lzw_read_from_return_value = 1u; + break; } - self->private_impl.f_call_sequence = 64u; - - ok: - self->private_impl.p_do_decode_frame_config[0] = 0; - goto exit; } - - goto suspend; - suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: + if (self->private_impl.f_lzw_read_from_return_value != 2u) { + while (v_n_bits >= 8u) { + v_n_bits -= 8u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + self->private_impl.f_lzw_read_from_return_value = 5u; + break; + } + } + } + self->private_impl.f_lzw_save_code = v_save_code; + self->private_impl.f_lzw_prev_code = v_prev_code; + self->private_impl.f_lzw_width = v_width; + self->private_impl.f_lzw_bits = v_bits; + self->private_impl.f_lzw_n_bits = v_n_bits; + self->private_impl.f_lzw_output_wi = v_output_wi; if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return status; + return wuffs_base__make_empty_struct(); } -// -------- func jpeg.decoder.decode_frame +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) + +// ---------------- Status Codes Implementations + +const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum"; +const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method"; +const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags"; +const char wuffs_gzip__error__bad_header[] = "#gzip: bad header"; +const char wuffs_gzip__error__truncated_input[] = "#gzip: truncated input"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__decode_frame( - wuffs_jpeg__decoder* self, - wuffs_base__pixel_buffer* a_dst, +static wuffs_base__status +wuffs_gzip__decoder__do_transform_io( + wuffs_gzip__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { + wuffs_base__slice_u8 a_workbuf); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_gzip__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_gzip__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_gzip__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_gzip__decoder__initialize( + wuffs_gzip__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + { + wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( + &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_deflate__decoder__initialize( + &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_gzip__decoder* +wuffs_gzip__decoder__alloc(void) { + wuffs_gzip__decoder* x = + (wuffs_gzip__decoder*)(calloc(1, sizeof(wuffs_gzip__decoder))); + if (!x) { + return NULL; + } + if (wuffs_gzip__decoder__initialize( + x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_gzip__decoder(void) { + return sizeof(wuffs_gzip__decoder); +} + +// ---------------- Function Implementations + +// -------- func gzip.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_gzip__decoder__get_quirk( + const wuffs_gzip__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { + return 1u; + } + return 0u; +} + +// -------- func gzip.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gzip__decoder__set_quirk( + wuffs_gzip__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + return wuffs_base__make_status(NULL); + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func gzip.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_gzip__decoder__dst_history_retain_length( + const wuffs_gzip__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_base__utility__make_optional_u63(true, 0u); +} + +// -------- func gzip.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_gzip__decoder__workbuf_len( + const wuffs_gzip__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(1u, 1u); +} + +// -------- func gzip.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_gzip__decoder__transform_io( + wuffs_gzip__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -43525,65 +43930,41 @@ wuffs_jpeg__decoder__decode_frame( return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { + (self->private_impl.active_coroutine != 1)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_ddf_status = wuffs_base__make_status(NULL); - wuffs_base__status v_swizzle_status = wuffs_base__make_status(NULL); - uint32_t v_scan_count = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_transform_io; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { - v_scan_count = self->private_impl.f_scan_count; { - wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_ddf_status = t_0; - } - 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); + wuffs_base__status t_0 = wuffs_gzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + v_status = t_0; } - if (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); - } else { - v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self, a_dst, a_workbuf); - } - if (wuffs_base__status__is_error(&v_ddf_status)) { - status = v_ddf_status; - goto exit; - } else if (wuffs_base__status__is_error(&v_swizzle_status)) { - status = v_swizzle_status; - goto exit; - } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_gzip__error__truncated_input); + goto exit; } - status = v_ddf_status; + status = v_status; WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } ok: - self->private_impl.p_decode_frame[0] = 0; + self->private_impl.p_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; goto exit; exit: @@ -43593,24 +43974,40 @@ wuffs_jpeg__decoder__decode_frame( return status; } -// -------- func jpeg.decoder.do_decode_frame +// -------- func gzip.decoder.do_transform_io WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__do_decode_frame( - wuffs_jpeg__decoder* self, - wuffs_base__pixel_buffer* a_dst, +wuffs_gzip__decoder__do_transform_io( + wuffs_gzip__decoder* self, + wuffs_base__io_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { + wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_pixfmt = 0; + uint8_t v_c8 = 0; + uint8_t v_flags = 0; + uint16_t v_xlen = 0; + uint64_t v_mark = 0; + uint32_t v_checksum_have = 0; + uint32_t v_decoded_length_have = 0; wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint8_t v_marker = 0; + uint32_t v_checksum_want = 0; + uint32_t v_decoded_length_want = 0; + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -43622,236 +44019,269 @@ wuffs_jpeg__decoder__do_decode_frame( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; if (coro_susp_point) { - v_marker = self->private_data.s_do_decode_frame[0].v_marker; + v_flags = self->private_data.s_do_transform_io.v_flags; + v_checksum_have = self->private_data.s_do_transform_io.v_checksum_have; + v_decoded_length_have = self->private_data.s_do_transform_io.v_decoded_length_have; + v_checksum_want = self->private_data.s_do_transform_io.v_checksum_want; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } + { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_jpeg__decoder__do_decode_frame_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - if (status.repr) { + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 31u) { + status = wuffs_base__make_status(wuffs_gzip__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; } - v_pixfmt = 536870920u; - if (self->private_impl.f_num_components > 1u) { - v_pixfmt = 2415954056u; + if (v_c8 != 139u) { + status = wuffs_base__make_status(wuffs_gzip__error__bad_header); + goto exit; } - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), - wuffs_base__utility__make_pixel_format(v_pixfmt), - wuffs_base__utility__empty_slice_u8(), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - goto ok; + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; } - 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); + if (v_c8 != 8u) { + status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method); goto exit; - } else if (self->private_impl.f_components_workbuf_offsets[4u] < self->private_impl.f_components_workbuf_offsets[8u]) { - wuffs_base__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); } - if (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_memset(a_workbuf.ptr, self->private_impl.f_components_workbuf_offsets[4u], 128u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_flags = t_3; } - while (true) { + self->private_data.s_do_transform_io.scratch = 6u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_transform_io.scratch; + if (((uint8_t)(v_flags & 4u)) != 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint16_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 8) { + t_4 = ((uint16_t)(*scratch)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)) << 56; + } + } + v_xlen = t_4; + } + self->private_data.s_do_transform_io.scratch = ((uint32_t)(v_xlen)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_transform_io.scratch; + } + if (((uint8_t)(v_flags & 8u)) != 0u) { while (true) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; } - if (v_c == 255u) { + if (v_c8 == 0u) { break; } } + } + if (((uint8_t)(v_flags & 16u)) != 0u) { while (true) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; } - if (v_c != 255u) { - v_marker = v_c; + if (v_c8 == 0u) { break; } } - if (v_marker == 0u) { - continue; - } else if ((208u <= v_marker) && (v_marker <= 217u)) { - if (v_marker <= 215u) { - continue; + } + if (((uint8_t)(v_flags & 2u)) != 0u) { + self->private_data.s_do_transform_io.scratch = 2u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_transform_io.scratch; + } + if (((uint8_t)(v_flags & 224u)) != 0u) { + status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags); + goto exit; + } + while (true) { + v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); } - } else { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_frame[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); - if (num_bits_2 == 8) { - t_2 = ((uint32_t)(*scratch >> 48)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)); - } - } - self->private_impl.f_payload_length = t_2; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (self->private_impl.f_payload_length < 2u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); - goto exit; + wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf); + v_status = t_7; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - self->private_impl.f_payload_length -= 2u; } - if (v_marker < 192u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } else if (v_marker < 208u) { - if (v_marker == 196u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - status = wuffs_jpeg__decoder__decode_dht(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { + if ( ! self->private_impl.f_ignore_checksum) { + v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + v_decoded_length_have += ((uint32_t)(wuffs_private_impl__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))))); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + uint32_t t_8; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - continue; - } else if (v_marker == 200u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); - goto exit; - } else if (v_marker < 224u) { - if (v_marker < 217u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); - goto exit; - } else if (v_marker == 217u) { - break; - } else if (v_marker == 218u) { - if (a_src) { - 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); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8; + if (num_bits_8 == 24) { + t_8 = ((uint32_t)(*scratch)); + break; } - if (status.repr) { + num_bits_8 += 8u; + *scratch |= ((uint64_t)(num_bits_8)) << 56; + } + } + v_checksum_want = t_8; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + uint32_t t_9; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - continue; - } else if (v_marker == 219u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - status = wuffs_jpeg__decoder__decode_dqt(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - continue; - } else if (v_marker == 221u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_jpeg__decoder__decode_dri(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9; + if (num_bits_9 == 24) { + t_9 = ((uint32_t)(*scratch)); + break; } - continue; - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; - } - } else if (v_marker < 240u) { - } else { - if (v_marker == 254u) { - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); - goto exit; + num_bits_9 += 8u; + *scratch |= ((uint64_t)(num_bits_9)) << 56; } } - self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_payload_length; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame[0].scratch; - self->private_impl.f_payload_length = 0u; + v_decoded_length_want = t_9; + } + if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_have != v_checksum_want) || (v_decoded_length_have != v_decoded_length_want))) { + status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum); + goto exit; } - self->private_impl.f_call_sequence = 96u; ok: - self->private_impl.p_do_decode_frame[0] = 0; + self->private_impl.p_do_transform_io = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_frame[0].v_marker = v_marker; + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_transform_io.v_flags = v_flags; + self->private_data.s_do_transform_io.v_checksum_have = v_checksum_have; + self->private_data.s_do_transform_io.v_decoded_length_have = v_decoded_length_have; + self->private_data.s_do_transform_io.v_checksum_want = v_checksum_want; goto exit; exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -43859,891 +44289,398 @@ wuffs_jpeg__decoder__do_decode_frame( return status; } -// -------- func jpeg.decoder.decode_dht +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_jpeg__decoder__decode_dht( - wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) - uint8_t v_c = 0; - uint8_t v_tc = 0; - uint8_t v_th = 0; - uint8_t v_tc4_th = 0; - uint32_t v_working_total_count = 0; - uint32_t v_total_count = 0; - uint32_t v_i = 0; - bool v_failed = false; +// ---------------- Status Codes Implementations - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +const char wuffs_jpeg__error__bad_dht_marker[] = "#jpeg: bad DHT marker"; +const char wuffs_jpeg__error__bad_dqt_marker[] = "#jpeg: bad DQT marker"; +const char wuffs_jpeg__error__bad_dri_marker[] = "#jpeg: bad DRI marker"; +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__rejected_progressive_jpeg[] = "#jpeg: rejected progressive JPEG"; +const char wuffs_jpeg__error__truncated_input[] = "#jpeg: truncated input"; +const char wuffs_jpeg__error__unsupported_arithmetic_coding[] = "#jpeg: unsupported arithmetic coding"; +const char wuffs_jpeg__error__unsupported_color_model[] = "#jpeg: unsupported color model"; +const char wuffs_jpeg__error__unsupported_fractional_sampling[] = "#jpeg: unsupported fractional sampling"; +const char wuffs_jpeg__error__unsupported_hierarchical_coding[] = "#jpeg: unsupported hierarchical coding"; +const char wuffs_jpeg__error__unsupported_implicit_height[] = "#jpeg: unsupported implicit height"; +const char wuffs_jpeg__error__unsupported_lossless_coding[] = "#jpeg: unsupported lossless coding"; +const char wuffs_jpeg__error__unsupported_marker[] = "#jpeg: unsupported marker"; +const char wuffs_jpeg__error__unsupported_precision_12_bits[] = "#jpeg: unsupported precision (12 bits)"; +const char wuffs_jpeg__error__unsupported_precision_16_bits[] = "#jpeg: unsupported precision (16 bits)"; +const char wuffs_jpeg__error__unsupported_precision[] = "#jpeg: unsupported precision"; +const char wuffs_jpeg__error__unsupported_scan_count[] = "#jpeg: unsupported scan count"; +const char wuffs_jpeg__error__internal_error_inconsistent_decoder_state[] = "#jpeg: internal error: inconsistent decoder state"; - uint32_t coro_susp_point = self->private_impl.p_decode_dht[0]; - if (coro_susp_point) { - v_tc4_th = self->private_data.s_decode_dht[0].v_tc4_th; - v_total_count = self->private_data.s_decode_dht[0].v_total_count; - v_i = self->private_data.s_decode_dht[0].v_i; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// ---------------- Private Consts - if (self->private_impl.f_sof_marker == 0u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - while (self->private_impl.f_payload_length > 0u) { - if (self->private_impl.f_payload_length < 17u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - self->private_impl.f_payload_length -= 17u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (((v_c >> 4u) > 1u) || ((v_c & 15u) > 3u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - v_tc = (v_c >> 4u); - v_th = (v_c & 15u); - v_tc4_th = ((uint8_t)(((v_tc * 4u) | v_th))); - if ((self->private_impl.f_sof_marker == 192u) && ((v_tc4_th & 3u) > 1u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - v_i = 0u; - while (v_i < 16u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - self->private_data.f_dht_temp_counts[v_i] = t_1; - } - v_i += 1u; - } - v_working_total_count = 0u; - v_i = 0u; - while (v_i < 16u) { - v_working_total_count = ((v_working_total_count + ((uint32_t)(self->private_data.f_dht_temp_counts[v_i]))) & 65535u); - v_i += 1u; - } - if ((v_working_total_count <= 0u) || (256u < v_working_total_count)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - v_total_count = v_working_total_count; - if (self->private_impl.f_payload_length < v_total_count) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - self->private_impl.f_payload_length -= v_total_count; - v_i = 0u; - while (v_i < v_total_count) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = t_2; - } - v_i += 1u; - } - while (v_i < 256u) { - self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = 0u; - v_i += 1u; - } - if ((v_tc4_th & 4u) == 0u) { - v_i = 0u; - while (v_i < v_total_count) { - if (self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] > 15u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - v_i += 1u; - } - } - v_failed = wuffs_jpeg__decoder__calculate_huff_tables(self, v_tc4_th, v_total_count); - if (v_failed) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); - goto exit; - } - self->private_impl.f_seen_dht[v_tc4_th] = true; - } +static const uint8_t +WUFFS_JPEG__UNZIG[80] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 1u, 8u, 16u, 9u, 2u, 3u, + 10u, 17u, 24u, 32u, 25u, 18u, 11u, 4u, + 5u, 12u, 19u, 26u, 33u, 40u, 48u, 41u, + 34u, 27u, 20u, 13u, 6u, 7u, 14u, 21u, + 28u, 35u, 42u, 49u, 56u, 57u, 50u, 43u, + 36u, 29u, 22u, 15u, 23u, 30u, 37u, 44u, + 51u, 58u, 59u, 52u, 45u, 38u, 31u, 39u, + 46u, 53u, 60u, 61u, 54u, 47u, 55u, 62u, + 63u, 63u, 63u, 63u, 63u, 63u, 63u, 63u, + 63u, 63u, 63u, 63u, 63u, 63u, 63u, 63u, +}; - goto ok; - ok: - self->private_impl.p_decode_dht[0] = 0; - goto exit; - } +static const uint8_t +WUFFS_JPEG__BIAS_AND_CLAMP[1024] WUFFS_BASE__POTENTIALLY_UNUSED = { + 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u, + 136u, 137u, 138u, 139u, 140u, 141u, 142u, 143u, + 144u, 145u, 146u, 147u, 148u, 149u, 150u, 151u, + 152u, 153u, 154u, 155u, 156u, 157u, 158u, 159u, + 160u, 161u, 162u, 163u, 164u, 165u, 166u, 167u, + 168u, 169u, 170u, 171u, 172u, 173u, 174u, 175u, + 176u, 177u, 178u, 179u, 180u, 181u, 182u, 183u, + 184u, 185u, 186u, 187u, 188u, 189u, 190u, 191u, + 192u, 193u, 194u, 195u, 196u, 197u, 198u, 199u, + 200u, 201u, 202u, 203u, 204u, 205u, 206u, 207u, + 208u, 209u, 210u, 211u, 212u, 213u, 214u, 215u, + 216u, 217u, 218u, 219u, 220u, 221u, 222u, 223u, + 224u, 225u, 226u, 227u, 228u, 229u, 230u, 231u, + 232u, 233u, 234u, 235u, 236u, 237u, 238u, 239u, + 240u, 241u, 242u, 243u, 244u, 245u, 246u, 247u, + 248u, 249u, 250u, 251u, 252u, 253u, 254u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 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, +}; - goto suspend; - suspend: - self->private_impl.p_decode_dht[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_dht[0].v_tc4_th = v_tc4_th; - self->private_data.s_decode_dht[0].v_total_count = v_total_count; - self->private_data.s_decode_dht[0].v_i = v_i; +static const uint16_t +WUFFS_JPEG__EXTEND[16] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 65535u, 65533u, 65529u, 65521u, 65505u, 65473u, 65409u, + 65281u, 65025u, 64513u, 63489u, 61441u, 57345u, 49153u, 32769u, +}; - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +static const uint8_t +WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 1u, 5u, 1u, 1u, 1u, 1u, + 1u, 1u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, + 7u, 8u, 9u, 10u, 11u, +}; - return status; -} +static const uint8_t +WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1u, 0u, 3u, 1u, 1u, 1u, 1u, 1u, + 1u, 1u, 1u, 1u, 0u, 0u, 0u, 0u, + 0u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, + 7u, 8u, 9u, 10u, 11u, +}; -// -------- func jpeg.decoder.calculate_huff_tables +static const uint8_t +WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = { + 16u, 0u, 2u, 1u, 3u, 3u, 2u, 4u, + 3u, 5u, 5u, 4u, 4u, 0u, 0u, 1u, + 125u, 1u, 2u, 3u, 0u, 4u, 17u, 5u, + 18u, 33u, 49u, 65u, 6u, 19u, 81u, 97u, + 7u, 34u, 113u, 20u, 50u, 129u, 145u, 161u, + 8u, 35u, 66u, 177u, 193u, 21u, 82u, 209u, + 240u, 36u, 51u, 98u, 114u, 130u, 9u, 10u, + 22u, 23u, 24u, 25u, 26u, 37u, 38u, 39u, + 40u, 41u, 42u, 52u, 53u, 54u, 55u, 56u, + 57u, 58u, 67u, 68u, 69u, 70u, 71u, 72u, + 73u, 74u, 83u, 84u, 85u, 86u, 87u, 88u, + 89u, 90u, 99u, 100u, 101u, 102u, 103u, 104u, + 105u, 106u, 115u, 116u, 117u, 118u, 119u, 120u, + 121u, 122u, 131u, 132u, 133u, 134u, 135u, 136u, + 137u, 138u, 146u, 147u, 148u, 149u, 150u, 151u, + 152u, 153u, 154u, 162u, 163u, 164u, 165u, 166u, + 167u, 168u, 169u, 170u, 178u, 179u, 180u, 181u, + 182u, 183u, 184u, 185u, 186u, 194u, 195u, 196u, + 197u, 198u, 199u, 200u, 201u, 202u, 210u, 211u, + 212u, 213u, 214u, 215u, 216u, 217u, 218u, 225u, + 226u, 227u, 228u, 229u, 230u, 231u, 232u, 233u, + 234u, 241u, 242u, 243u, 244u, 245u, 246u, 247u, + 248u, 249u, 250u, +}; + +static const uint8_t +WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = { + 17u, 0u, 2u, 1u, 2u, 4u, 4u, 3u, + 4u, 7u, 5u, 4u, 4u, 0u, 1u, 2u, + 119u, 0u, 1u, 2u, 3u, 17u, 4u, 5u, + 33u, 49u, 6u, 18u, 65u, 81u, 7u, 97u, + 113u, 19u, 34u, 50u, 129u, 8u, 20u, 66u, + 145u, 161u, 177u, 193u, 9u, 35u, 51u, 82u, + 240u, 21u, 98u, 114u, 209u, 10u, 22u, 36u, + 52u, 225u, 37u, 241u, 23u, 24u, 25u, 26u, + 38u, 39u, 40u, 41u, 42u, 53u, 54u, 55u, + 56u, 57u, 58u, 67u, 68u, 69u, 70u, 71u, + 72u, 73u, 74u, 83u, 84u, 85u, 86u, 87u, + 88u, 89u, 90u, 99u, 100u, 101u, 102u, 103u, + 104u, 105u, 106u, 115u, 116u, 117u, 118u, 119u, + 120u, 121u, 122u, 130u, 131u, 132u, 133u, 134u, + 135u, 136u, 137u, 138u, 146u, 147u, 148u, 149u, + 150u, 151u, 152u, 153u, 154u, 162u, 163u, 164u, + 165u, 166u, 167u, 168u, 169u, 170u, 178u, 179u, + 180u, 181u, 182u, 183u, 184u, 185u, 186u, 194u, + 195u, 196u, 197u, 198u, 199u, 200u, 201u, 202u, + 210u, 211u, 212u, 213u, 214u, 215u, 216u, 217u, + 218u, 226u, 227u, 228u, 229u, 230u, 231u, 232u, + 233u, 234u, 242u, 243u, 244u, 245u, 246u, 247u, + 248u, 249u, 250u, +}; + +#define WUFFS_JPEG__QUIRKS_BASE 1220532224u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -static bool -wuffs_jpeg__decoder__calculate_huff_tables( +static wuffs_base__empty_struct +wuffs_jpeg__decoder__decode_idct( wuffs_jpeg__decoder* self, - uint8_t a_tc4_th, - uint32_t a_total_count) { - uint32_t v_i = 0; - uint8_t v_j = 0; - uint8_t v_k = 0; - uint32_t v_bit_length_minus_one = 0; - uint8_t v_bit_length = 0; - uint32_t v_bit_string = 0; - uint32_t v_slow = 0; - uint8_t v_prefix = 0; - uint16_t v_fast = 0; - uint32_t v_reps = 0; + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, + uint32_t a_q); - v_i = 0u; - v_k = 0u; - v_bit_length_minus_one = 0u; - while (v_i < a_total_count) { - while (v_k >= self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) { - v_k = 0u; - v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u); - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_k += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - self->private_data.f_dht_temp_bit_lengths[v_i] = ((uint8_t)((v_bit_length_minus_one + 1u))); - v_i += 1u; - } - v_bit_length = 0u; - v_bit_string = 0u; - v_i = 0u; - while (v_i < a_total_count) { - while (v_bit_length < self->private_data.f_dht_temp_bit_lengths[v_i]) { - if (v_bit_length >= 16u) { - return true; - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_bit_length += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - v_bit_string <<= 1u; - } - self->private_data.f_dht_temp_bit_strings[v_i] = ((uint16_t)(v_bit_string)); - v_bit_string += 1u; - if ((v_bit_string >> v_bit_length) > 0u) { - return true; - } - v_i += 1u; - } - v_k = 0u; - v_bit_length_minus_one = 0u; - while (true) { - if (self->private_data.f_dht_temp_counts[v_bit_length_minus_one] == 0u) { - self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = 0u; - } else { - v_slow = (255u & ((uint32_t)(((uint32_t)(v_k)) - ((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_k]))))); - v_k += self->private_data.f_dht_temp_counts[v_bit_length_minus_one]; - self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = (v_slow | ((((uint32_t)(self->private_data.f_dht_temp_bit_strings[((uint8_t)(v_k - 1u))])) + 1u) << 8u)); - } - v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u); - if (v_bit_length_minus_one == 0u) { - break; - } - } - v_i = 0u; - while (v_i < 256u) { - self->private_impl.f_huff_tables_fast[a_tc4_th][v_i] = 65535u; - v_i += 1u; - } - v_j = 0u; - v_bit_length_minus_one = 0u; - while (v_bit_length_minus_one < 8u) { - v_k = 0u; - while (v_k < self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) { - v_prefix = ((uint8_t)((((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_j])) << (7u - v_bit_length_minus_one)))); - v_fast = ((uint16_t)(((((uint32_t)((v_bit_length_minus_one + 1u))) << 8u) | ((uint32_t)(self->private_impl.f_huff_tables_symbols[a_tc4_th][v_j]))))); - v_reps = (((uint32_t)(1u)) << (7u - v_bit_length_minus_one)); - while (v_reps > 0u) { - self->private_impl.f_huff_tables_fast[a_tc4_th][v_prefix] = v_fast; - v_prefix += 1u; - v_reps -= 1u; - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - v_k += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - v_j += 1u; - } - v_bit_length_minus_one += 1u; - } - return false; -} +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__decode_idct__choosy_default( + wuffs_jpeg__decoder* self, + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, + uint32_t a_q); -// -------- func jpeg.decoder.decode_sos +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__decode_idct_x86_avx2( + wuffs_jpeg__decoder* self, + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, + uint32_t a_q); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__decode_sos( +wuffs_jpeg__decoder__do_decode_image_config( wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_my = 0; - uint32_t v_mx = 0; - uint32_t v_decode_mcu_result = 0; - uint32_t v_bitstream_length = 0; - - uint32_t coro_susp_point = self->private_impl.p_decode_sos[0]; - if (coro_susp_point) { - v_my = self->private_data.s_decode_sos[0].v_my; - v_mx = self->private_data.s_decode_sos[0].v_mx; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); - if (self->private_impl.f_scan_count >= 64u) { - status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_scan_count); - goto exit; - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_jpeg__decoder__prepare_scan(self, a_src); - if (status.repr) { - goto suspend; - } - self->private_impl.f_next_restart_marker = 0u; - self->private_impl.f_mcu_previous_dc_values[0u] = 0u; - self->private_impl.f_mcu_previous_dc_values[1u] = 0u; - self->private_impl.f_mcu_previous_dc_values[2u] = 0u; - self->private_impl.f_mcu_previous_dc_values[3u] = 0u; - self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval; - self->private_impl.f_eob_run = 0u; - self->private_impl.f_bitstream_bits = 0u; - self->private_impl.f_bitstream_n_bits = 0u; - self->private_impl.f_bitstream_ri = 0u; - self->private_impl.f_bitstream_wi = 0u; - self->private_impl.f_bitstream_padding = 12345u; - wuffs_jpeg__decoder__fill_bitstream(self, a_src); - v_my = 0u; - while (v_my < self->private_impl.f_scan_height_in_mcus) { - v_mx = 0u; - while (v_mx < self->private_impl.f_scan_width_in_mcus) { - self->private_impl.f_mcu_current_block = 0u; - self->private_impl.f_mcu_zig_index = ((uint32_t)(self->private_impl.f_scan_ss)); - if (self->private_impl.f_sof_marker >= 194u) { - 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); - if (v_decode_mcu_result == 0u) { - break; - } else if (v_decode_mcu_result != 1u) { - status = wuffs_base__make_status(wuffs_jpeg__error__internal_error_inconsistent_decoder_state); - goto exit; - } - while (true) { - v_bitstream_length = ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri)); - wuffs_jpeg__decoder__fill_bitstream(self, a_src); - if (v_bitstream_length < ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri))) { - break; - } else if (self->private_impl.f_bitstream_padding == 0u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } else if ((a_src && a_src->meta.closed) && ! self->private_impl.f_bitstream_is_closed) { - if (self->private_impl.f_bitstream_wi < 1024u) { - wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[self->private_impl.f_bitstream_wi], 264u, 0u); - self->private_impl.f_bitstream_wi += 264u; - self->private_impl.f_bitstream_is_closed = true; - } - break; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - } - } - if (self->private_impl.f_sof_marker >= 194u) { - wuffs_jpeg__decoder__save_mcu_blocks(self, v_mx, v_my, a_workbuf); - } - if (self->private_impl.f_restarts_remaining > 0u) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_restarts_remaining -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - if (self->private_impl.f_restarts_remaining == 0u) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_jpeg__decoder__skip_past_the_next_restart_marker(self, a_src); - if (status.repr) { - goto suspend; - } - self->private_impl.f_mcu_previous_dc_values[0u] = 0u; - self->private_impl.f_mcu_previous_dc_values[1u] = 0u; - self->private_impl.f_mcu_previous_dc_values[2u] = 0u; - self->private_impl.f_mcu_previous_dc_values[3u] = 0u; - self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval; - self->private_impl.f_eob_run = 0u; - self->private_impl.f_bitstream_bits = 0u; - self->private_impl.f_bitstream_n_bits = 0u; - self->private_impl.f_bitstream_ri = 0u; - self->private_impl.f_bitstream_wi = 0u; - self->private_impl.f_bitstream_padding = 12345u; - } - } - v_mx += 1u; - } - v_my += 1u; - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_scan_count, 1u); +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dqt( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src); - ok: - self->private_impl.p_decode_sos[0] = 0; - goto exit; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dri( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src); - goto suspend; - suspend: - self->private_impl.p_decode_sos[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_sos[0].v_my = v_my; - self->private_data.s_decode_sos[0].v_mx = v_mx; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_appn( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src, + uint8_t a_marker); - goto exit; - exit: - return status; -} +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_sof( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src); -// -------- func jpeg.decoder.prepare_scan +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_jpeg__decoder__quantize_dimension( + const wuffs_jpeg__decoder* self, + uint32_t a_width, + uint8_t a_h, + uint8_t a_max_incl_h); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_jpeg__decoder__prepare_scan( +wuffs_jpeg__decoder__do_decode_frame_config( wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - uint32_t v_i = 0; - uint32_t v_j = 0; - uint32_t v_j_max_incl = 0; - bool v_failed = false; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_prepare_scan[0]; - if (coro_susp_point) { - v_i = self->private_data.s_prepare_scan[0].v_i; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if ((self->private_impl.f_payload_length < 6u) || (self->private_impl.f_payload_length > 12u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if ((v_c < 1u) || (v_c > 4u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_scan_num_components = ((uint32_t)(v_c)); - if ((self->private_impl.f_scan_num_components > self->private_impl.f_num_components) || (self->private_impl.f_payload_length != (4u + (2u * self->private_impl.f_scan_num_components)))) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_payload_length = 0u; - v_i = 0u; - while (v_i < self->private_impl.f_scan_num_components) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - v_j = 0u; - while (true) { - if (v_j >= self->private_impl.f_num_components) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - if (v_c == self->private_impl.f_components_c[v_j]) { - if ( ! self->private_impl.f_seen_dqt[self->private_impl.f_components_tq[v_j]]) { - status = wuffs_base__make_status(wuffs_jpeg__error__missing_quantization_table); - goto exit; - } - self->private_impl.f_scan_comps_cselector[v_i] = ((uint8_t)(v_j)); - break; - } - v_j += 1u; - } - v_j = 0u; - while (v_j < v_i) { - if (self->private_impl.f_scan_comps_cselector[v_i] == self->private_impl.f_scan_comps_cselector[v_j]) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - v_j += 1u; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; - } - if (((v_c >> 4u) > 3u) || ((v_c & 15u) > 3u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_scan_comps_td[v_i] = (v_c >> 4u); - self->private_impl.f_scan_comps_ta[v_i] = (v_c & 15u); - if (self->private_impl.f_sof_marker == 192u) { - if ((self->private_impl.f_scan_comps_td[v_i] > 1u) || (self->private_impl.f_scan_comps_ta[v_i] > 1u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - } - v_i += 1u; - } - if (self->private_impl.f_sof_marker < 194u) { - self->private_data.s_prepare_scan[0].scratch = 3u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (self->private_data.s_prepare_scan[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_prepare_scan[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_prepare_scan[0].scratch; - self->private_impl.f_scan_ss = 0u; - self->private_impl.f_scan_se = 63u; - self->private_impl.f_scan_ah = 0u; - self->private_impl.f_scan_al = 0u; - } else { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; - } - if (v_c > 63u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_scan_ss = v_c; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; - } - if ((v_c > 63u) || (v_c < self->private_impl.f_scan_ss)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_scan_se = v_c; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; - } - if (((v_c >> 4u) > 14u) || ((v_c & 15u) > 13u)) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - self->private_impl.f_scan_ah = (v_c >> 4u); - self->private_impl.f_scan_al = (v_c & 15u); - if (self->private_impl.f_scan_ah > 0u) { - if ((self->private_impl.f_scan_ah - 1u) != self->private_impl.f_scan_al) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - } - if (self->private_impl.f_scan_ss == 0u) { - if (self->private_impl.f_scan_se != 0u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } else if (self->private_impl.f_scan_ah == 0u) { - self->private_impl.choosy_decode_mcu = ( - &wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits); - } else { - self->private_impl.choosy_decode_mcu = ( - &wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit); - } - } else { - if (self->private_impl.f_scan_num_components != 1u) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } else if (self->private_impl.f_scan_ah == 0u) { - self->private_impl.choosy_decode_mcu = ( - &wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits); - } else { - self->private_impl.choosy_decode_mcu = ( - &wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit); - } - } - } - v_i = 0u; - while (v_i < self->private_impl.f_scan_num_components) { - if ((self->private_impl.f_scan_ss == 0u) && ! self->private_impl.f_seen_dht[(0u | self->private_impl.f_scan_comps_td[v_i])]) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - status = wuffs_jpeg__decoder__use_default_huffman_table(self, (0u | self->private_impl.f_scan_comps_td[v_i])); - if (status.repr) { - goto suspend; - } - } - if ((self->private_impl.f_scan_se != 0u) && ! self->private_impl.f_seen_dht[(4u | self->private_impl.f_scan_comps_ta[v_i])]) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_jpeg__decoder__use_default_huffman_table(self, (4u | self->private_impl.f_scan_comps_ta[v_i])); - if (status.repr) { - goto suspend; - } - } - v_j = ((uint32_t)(self->private_impl.f_scan_ss)); - v_j_max_incl = ((uint32_t)(wuffs_base__u8__min(self->private_impl.f_scan_se, 9u))); - while (v_j <= v_j_max_incl) { - self->private_impl.f_block_smoothing_lowest_scan_al[self->private_impl.f_scan_comps_cselector[v_i]][v_j] = self->private_impl.f_scan_al; - v_j += 1u; - } - v_i += 1u; - } - if (self->private_impl.f_scan_num_components == 1u) { - wuffs_jpeg__decoder__calculate_single_component_scan_fields(self); - } else { - v_failed = wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(self); - if (v_failed) { - status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); - goto exit; - } - } + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); - goto ok; - ok: - self->private_impl.p_prepare_scan[0] = 0; - goto exit; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__do_decode_frame( + wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); - goto suspend; - suspend: - self->private_impl.p_prepare_scan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_prepare_scan[0].v_i = v_i; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dht( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src); - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +WUFFS_BASE__GENERATED_C_CODE +static bool +wuffs_jpeg__decoder__calculate_huff_tables( + wuffs_jpeg__decoder* self, + uint8_t a_tc4_th, + uint32_t a_total_count); - return status; -} +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); -// -------- func jpeg.decoder.use_default_huffman_table +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__prepare_scan( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_jpeg__decoder__use_default_huffman_table( wuffs_jpeg__decoder* self, - uint8_t a_tc4_th) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__slice_u8 v_data = {0}; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - if (a_tc4_th == 0u) { - v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA), 29); - } else if (a_tc4_th == 1u) { - v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA), 29); - } else if (a_tc4_th == 4u) { - v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA), 179); - } else if (a_tc4_th == 5u) { - v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA), 179); - } else { - status = wuffs_base__make_status(wuffs_jpeg__error__missing_huffman_table); - goto exit; - } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - v_data, - 0u); - self->private_impl.f_payload_length = ((uint32_t)((((uint64_t)(v_data.len)) & 65535u))); - { - wuffs_base__status t_0 = wuffs_jpeg__decoder__decode_dht(self, v_r); - v_status = t_0; - } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; - } - status = v_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; - - ok: - goto exit; - exit: - return status; -} - -// -------- func jpeg.decoder.calculate_single_component_scan_fields + uint8_t a_tc4_th); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct wuffs_jpeg__decoder__calculate_single_component_scan_fields( - wuffs_jpeg__decoder* self) { - uint8_t v_csel = 0; - - self->private_impl.f_scan_comps_bx_offset[0u] = 0u; - self->private_impl.f_scan_comps_by_offset[0u] = 0u; - self->private_impl.f_mcu_num_blocks = 1u; - self->private_impl.f_mcu_blocks_sselector[0u] = 0u; - v_csel = self->private_impl.f_scan_comps_cselector[0u]; - self->private_impl.f_mcu_blocks_offset[0u] = self->private_impl.f_components_workbuf_offsets[v_csel]; - self->private_impl.f_mcu_blocks_mx_mul[0u] = 8u; - self->private_impl.f_mcu_blocks_my_mul[0u] = (8u * self->private_impl.f_components_workbuf_widths[v_csel]); - self->private_impl.f_mcu_blocks_dc_hselector[0u] = (0u | self->private_impl.f_scan_comps_td[0u]); - self->private_impl.f_mcu_blocks_ac_hselector[0u] = (4u | self->private_impl.f_scan_comps_ta[0u]); - self->private_impl.f_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h); - self->private_impl.f_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v); - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.calculate_multiple_component_scan_fields + wuffs_jpeg__decoder* self); WUFFS_BASE__GENERATED_C_CODE static bool wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( - wuffs_jpeg__decoder* self) { - uint32_t v_i = 0; - uint32_t v_h = 0; - uint32_t v_v = 0; - uint32_t v_hv = 0; - uint32_t v_total_hv = 0; - uint32_t v_b = 0; - uint32_t v_bx_offset = 0; - uint32_t v_by_offset = 0; - uint8_t v_ssel = 0; - uint8_t v_csel = 0; - - v_total_hv = 0u; - v_i = 0u; - v_b = 0u; - v_bx_offset = 0u; - v_by_offset = 0u; - while (v_i < self->private_impl.f_scan_num_components) { - 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]]))); - 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))); - self->private_impl.f_scan_comps_by_offset[(v_b & 15u)] = ((uint8_t)((v_by_offset & 3u))); - self->private_impl.f_mcu_blocks_sselector[(v_b & 15u)] = ((uint8_t)(v_i)); - v_b += 1u; - v_bx_offset += 1u; - if (v_bx_offset == v_h) { - v_bx_offset = 0u; - v_by_offset += 1u; - if (v_by_offset == v_v) { - v_by_offset = 0u; - } - } - v_hv -= 1u; - } - v_i += 1u; - } - if (v_total_hv > 10u) { - return true; - } - self->private_impl.f_mcu_num_blocks = 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]; - v_csel = self->private_impl.f_scan_comps_cselector[v_ssel]; - self->private_impl.f_mcu_blocks_offset[v_b] = (self->private_impl.f_components_workbuf_offsets[v_csel] + (8u * ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (8u * ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b])) * ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])))); - self->private_impl.f_mcu_blocks_mx_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_h[v_csel]))); - 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] = (0u | self->private_impl.f_scan_comps_td[v_ssel]); - self->private_impl.f_mcu_blocks_ac_hselector[v_b] = (4u | self->private_impl.f_scan_comps_ta[v_ssel]); - v_b += 1u; - } - self->private_impl.f_scan_width_in_mcus = self->private_impl.f_width_in_mcus; - self->private_impl.f_scan_height_in_mcus = self->private_impl.f_height_in_mcus; - return false; -} - -// -------- func jpeg.decoder.fill_bitstream + wuffs_jpeg__decoder* self); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct wuffs_jpeg__decoder__fill_bitstream( wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src) { - uint32_t v_wi = 0; - uint8_t v_c = 0; - uint32_t v_new_wi = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - if (self->private_impl.f_bitstream_ri <= 0u) { - } else if (self->private_impl.f_bitstream_ri >= self->private_impl.f_bitstream_wi) { - self->private_impl.f_bitstream_ri = 0u; - self->private_impl.f_bitstream_wi = 0u; - } else { - v_wi = (self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri); - wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_bitstream_buffer, 2048), wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi)); - self->private_impl.f_bitstream_ri = 0u; - self->private_impl.f_bitstream_wi = v_wi; - } - v_wi = self->private_impl.f_bitstream_wi; - while ((v_wi < 2048u) && (((uint64_t)(io2_a_src - iop_a_src)) > 0u)) { - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (v_c < 255u) { - self->private_data.f_bitstream_buffer[v_wi] = v_c; - v_wi += 1u; - iop_a_src += 1u; - continue; - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) { - break; - } else if ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u) { - break; - } else { - self->private_data.f_bitstream_buffer[v_wi] = 255u; - v_wi += 1u; - iop_a_src += 2u; - } - } - if (((uint64_t)(io2_a_src - iop_a_src)) > 1u) { - if ((wuffs_base__peek_u8be__no_bounds_check(iop_a_src) >= 255u) && ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u)) { - v_new_wi = (wuffs_base__u32__min(v_wi, 1784u) + 264u); - v_new_wi = wuffs_base__u32__min(v_new_wi, (v_wi + self->private_impl.f_bitstream_padding)); - if (v_wi < v_new_wi) { - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_bitstream_padding, (v_new_wi - v_wi)); - wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[v_wi], (v_new_wi - v_wi), 0u); - v_wi = v_new_wi; - } - } - } - self->private_impl.f_bitstream_wi = v_wi; - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.load_mcu_blocks_for_single_component + wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct @@ -44752,9 +44689,7 @@ wuffs_jpeg__decoder__load_mcu_blocks_for_single_component( uint32_t a_mx, uint32_t a_my, wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel) { - return (*self->private_impl.choosy_load_mcu_blocks_for_single_component)(self, a_mx, a_my, a_workbuf, a_csel); -} + uint32_t a_csel); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct @@ -44763,19 +44698,7 @@ wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default( uint32_t a_mx, uint32_t a_my, wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel) { - uint64_t v_stride16 = 0; - uint64_t v_offset = 0; - - v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u))); - v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16)); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); - } - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.load_mcu_blocks + uint32_t a_csel); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct @@ -44783,34 +44706,7 @@ wuffs_jpeg__decoder__load_mcu_blocks( wuffs_jpeg__decoder* self, uint32_t a_mx, uint32_t a_my, - wuffs_base__slice_u8 a_workbuf) { - uint32_t v_b = 0; - uint8_t v_csel = 0; - uint64_t v_h = 0; - uint64_t v_v = 0; - uint64_t v_stride16 = 0; - uint64_t v_offset = 0; - - v_h = 1u; - v_v = 1u; - v_b = 0u; - while (v_b < self->private_impl.f_mcu_num_blocks) { - v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]]; - if (self->private_impl.f_scan_num_components > 1u) { - v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel])); - v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel])); - } - v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u))); - v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16)); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); - } - v_b += 1u; - } - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.save_mcu_blocks + wuffs_base__slice_u8 a_workbuf); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct @@ -44818,4983 +44714,17911 @@ wuffs_jpeg__decoder__save_mcu_blocks( wuffs_jpeg__decoder* self, uint32_t a_mx, uint32_t a_my, - wuffs_base__slice_u8 a_workbuf) { - uint32_t v_b = 0; - uint8_t v_csel = 0; - uint64_t v_h = 0; - uint64_t v_v = 0; - uint64_t v_stride16 = 0; - uint64_t v_offset = 0; - - v_h = 1u; - v_v = 1u; - v_b = 0u; - while (v_b < self->private_impl.f_mcu_num_blocks) { - v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]]; - if (self->private_impl.f_scan_num_components > 1u) { - v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel])); - v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel])); - } - v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u))); - v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16)); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); - } - v_b += 1u; - } - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.skip_past_the_next_restart_marker + wuffs_base__slice_u8 a_workbuf); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status wuffs_jpeg__decoder__skip_past_the_next_restart_marker( wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_skip_past_the_next_restart_marker[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; - } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) < 255u) { - iop_a_src += 1u; - continue; - } - v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u))); - if (v_c < 192u) { - iop_a_src += 2u; - continue; - } else if ((v_c < 208u) || (215u < v_c)) { - break; - } - v_c &= 7u; - if ((self->private_impl.f_next_restart_marker == ((v_c + 1u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 2u) & 7u))) { - break; - } else if ((self->private_impl.f_next_restart_marker == ((v_c + 7u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 6u) & 7u))) { - iop_a_src += 2u; - continue; - } else { - iop_a_src += 2u; - break; - } - } - self->private_impl.f_next_restart_marker = (((uint8_t)(self->private_impl.f_next_restart_marker + 1u)) & 7u); - - ok: - self->private_impl.p_skip_past_the_next_restart_marker[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_skip_past_the_next_restart_marker[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func jpeg.decoder.apply_progressive_idct + wuffs_base__io_buffer* a_src); WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct wuffs_jpeg__decoder__apply_progressive_idct( wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf) { - uint32_t v_csel = 0; - bool v_block_smoothing_applicable = false; - uint32_t v_scan_width_in_mcus = 0; - uint32_t v_scan_height_in_mcus = 0; - uint32_t v_mcu_blocks_mx_mul_0 = 0; - uint32_t v_mcu_blocks_my_mul_0 = 0; - uint32_t v_my = 0; - uint32_t v_mx = 0; - uint64_t v_stride = 0; - uint64_t v_offset = 0; - uint8_t v_stashed_mcu_blocks_0[128] = {0}; - - wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128)); - v_block_smoothing_applicable = true; - v_csel = 0u; - while (v_csel < self->private_impl.f_num_components) { - if ((self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][0u] >= 16u) || wuffs_jpeg__decoder__top_left_quants_has_zero(self, ((uint32_t)(self->private_impl.f_components_tq[v_csel])))) { - v_block_smoothing_applicable = false; - } - v_csel += 1u; - } - v_csel = 0u; - while (v_csel < self->private_impl.f_num_components) { - v_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h); - v_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v); - v_mcu_blocks_mx_mul_0 = 8u; - v_mcu_blocks_my_mul_0 = (8u * self->private_impl.f_components_workbuf_widths[v_csel]); - if (v_block_smoothing_applicable && (0u != (self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][1u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][2u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][3u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][4u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][5u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][6u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] | - self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][9u]))) { - self->private_impl.choosy_load_mcu_blocks_for_single_component = ( - &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth); - self->private_impl.f_block_smoothing_mx_max_incl = wuffs_base__u32__sat_sub(v_scan_width_in_mcus, 1u); - self->private_impl.f_block_smoothing_my_max_incl = wuffs_base__u32__sat_sub(v_scan_height_in_mcus, 1u); - } else { - self->private_impl.choosy_load_mcu_blocks_for_single_component = ( - &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default); - } - v_my = 0u; - while (v_my < v_scan_height_in_mcus) { - v_mx = 0u; - while (v_mx < v_scan_width_in_mcus) { - wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(self, - v_mx, - v_my, - a_workbuf, - v_csel); - v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])); - v_offset = (self->private_impl.f_components_workbuf_offsets[v_csel] + (((uint64_t)(v_mcu_blocks_mx_mul_0)) * ((uint64_t)(v_mx))) + (((uint64_t)(v_mcu_blocks_my_mul_0)) * ((uint64_t)(v_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]))); - } - v_mx += 1u; - } - v_my += 1u; - } - v_csel += 1u; - } - wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128)); - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.swizzle_gray + wuffs_base__slice_u8 a_workbuf); WUFFS_BASE__GENERATED_C_CODE 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__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; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint32_t v_y = 0; - uint64_t v_stride = 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - 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_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_y = 0u; - while (v_y < self->private_impl.f_height) { - v_dst = wuffs_base__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); - } - 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); - } else { - a_workbuf = wuffs_base__utility__empty_slice_u8(); - } - v_y += 1u; - } - return wuffs_base__make_status(NULL); -} - -// -------- func jpeg.decoder.swizzle_colorful + 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 v_src0 = {0}; - wuffs_base__slice_u8 v_src1 = {0}; - wuffs_base__slice_u8 v_src2 = {0}; - wuffs_base__slice_u8 v_src3 = {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]); - } - 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, - 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], - self->private_impl.f_components_h[0u], - self->private_impl.f_components_h[1u], - self->private_impl.f_components_h[2u], - self->private_impl.f_components_h[3u], - self->private_impl.f_components_v[0u], - self->private_impl.f_components_v[1u], - self->private_impl.f_components_v[2u], - self->private_impl.f_components_v[3u], - self->private_impl.f_is_rgb_or_cmyk, - true, - wuffs_base__make_slice_u8(self->private_data.f_swizzle_ycck_scratch_buffer_2k, 2048)); - return wuffs_base__status__ensure_not_a_suspension(v_status); -} - -// -------- func jpeg.decoder.frame_dirty_rect + 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 -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_jpeg__decoder__frame_dirty_rect( - const wuffs_jpeg__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - - return wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height); -} - -// -------- func jpeg.decoder.num_animation_loops +static bool +wuffs_jpeg__decoder__top_left_quants_has_zero( + const wuffs_jpeg__decoder* self, + uint32_t a_q); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_jpeg__decoder__num_animation_loops( - const wuffs_jpeg__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func jpeg.decoder.num_decoded_frame_configs +static wuffs_base__empty_struct +wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_csel); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_jpeg__decoder__num_decoded_frame_configs( - const wuffs_jpeg__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - if (self->private_impl.f_call_sequence > 32u) { - return 1u; - } - return 0u; -} - -// -------- func jpeg.decoder.num_decoded_frames +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); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_jpeg__decoder__num_decoded_frames( - const wuffs_jpeg__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - if (self->private_impl.f_call_sequence > 64u) { - return 1u; - } - return 0u; -} - -// -------- func jpeg.decoder.restart_frame +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); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__restart_frame( +static uint32_t +wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits( wuffs_jpeg__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - uint32_t v_i = 0; - uint32_t v_j = 0; + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_mx, + uint32_t a_my); - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } - if (a_index != 0u) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - self->private_impl.f_call_sequence = 40u; - self->private_impl.f_bitstream_is_closed = 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; - v_i = 0u; - while (v_i < 4u) { - self->private_impl.f_seen_dqt[v_i] = self->private_impl.f_saved_seen_dqt[v_i]; - v_j = 0u; - while (v_j < 64u) { - self->private_impl.f_quant_tables[v_i][v_j] = self->private_impl.f_saved_quant_tables[v_i][v_j]; - v_j += 1u; - } - v_i += 1u; - } - v_i = 0u; - while (v_i < 4u) { - v_j = 0u; - while (v_j < 10u) { - self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u; - v_j += 1u; - } - v_i += 1u; - } - v_i = 0u; - while (v_i < 8u) { - self->private_impl.f_seen_dht[v_i] = false; - v_i += 1u; - } - return wuffs_base__make_status(NULL); -} +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); -// -------- func jpeg.decoder.set_report_metadata +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); WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_jpeg__decoder__set_report_metadata( +static uint32_t +wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit( wuffs_jpeg__decoder* self, - uint32_t a_fourcc, - bool a_report) { - return wuffs_base__make_empty_struct(); -} + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_mx, + uint32_t a_my); -// -------- func jpeg.decoder.tell_me_more +// ---------------- VTables -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_jpeg__decoder__tell_me_more( +const wuffs_base__image_decoder__func_ptrs +wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_jpeg__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_jpeg__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_jpeg__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_jpeg__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_jpeg__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_jpeg__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_jpeg__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_jpeg__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_jpeg__decoder__initialize( wuffs_jpeg__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; + self->private_impl.choosy_decode_idct = &wuffs_jpeg__decoder__decode_idct__choosy_default; + self->private_impl.choosy_load_mcu_blocks_for_single_component = &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default; + self->private_impl.choosy_decode_mcu = &wuffs_jpeg__decoder__decode_mcu__choosy_default; - goto ok; - ok: - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); } -// -------- func jpeg.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_jpeg__decoder__history_retain_length( - const wuffs_jpeg__decoder* self) { - if (!self) { - return 0; +wuffs_jpeg__decoder* +wuffs_jpeg__decoder__alloc(void) { + wuffs_jpeg__decoder* x = + (wuffs_jpeg__decoder*)(calloc(1, sizeof(wuffs_jpeg__decoder))); + if (!x) { + return NULL; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (wuffs_jpeg__decoder__initialize( + x, sizeof(wuffs_jpeg__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; } + return x; +} - return 0u; +size_t +sizeof__wuffs_jpeg__decoder(void) { + return sizeof(wuffs_jpeg__decoder); } -// -------- func jpeg.decoder.workbuf_len +// ---------------- Function Implementations + +// -------- func jpeg.decoder.decode_idct WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_jpeg__decoder__workbuf_len( - const wuffs_jpeg__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } - - return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_components_workbuf_offsets[8u], self->private_impl.f_components_workbuf_offsets[8u]); -} - -// -------- func jpeg.decoder.top_left_quants_has_zero - -WUFFS_BASE__GENERATED_C_CODE -static bool -wuffs_jpeg__decoder__top_left_quants_has_zero( - const wuffs_jpeg__decoder* self, +static wuffs_base__empty_struct +wuffs_jpeg__decoder__decode_idct( + wuffs_jpeg__decoder* self, + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, uint32_t a_q) { - return ((self->private_impl.f_quant_tables[a_q][0u] == 0u) || - (self->private_impl.f_quant_tables[a_q][1u] == 0u) || - (self->private_impl.f_quant_tables[a_q][2u] == 0u) || - (self->private_impl.f_quant_tables[a_q][3u] == 0u) || - (self->private_impl.f_quant_tables[a_q][8u] == 0u) || - (self->private_impl.f_quant_tables[a_q][9u] == 0u) || - (self->private_impl.f_quant_tables[a_q][10u] == 0u) || - (self->private_impl.f_quant_tables[a_q][16u] == 0u) || - (self->private_impl.f_quant_tables[a_q][17u] == 0u) || - (self->private_impl.f_quant_tables[a_q][24u] == 0u)); + return (*self->private_impl.choosy_decode_idct)(self, a_dst_buffer, a_dst_stride, a_q); } -// -------- func jpeg.decoder.load_mcu_blocks_for_single_component_smooth - WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth( +wuffs_jpeg__decoder__decode_idct__choosy_default( wuffs_jpeg__decoder* self, - uint32_t a_mx, - uint32_t a_my, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_csel) { - uint64_t v_stride16 = 0; - uint64_t v_offset = 0; - uint32_t v_dx = 0; - uint32_t v_dy = 0; - uint32_t v_mx = 0; - uint32_t v_my = 0; - uint8_t v_q = 0; - uint32_t v_q_00 = 0; - uint32_t v_q_xy = 0; - uint8_t v_al = 0; - uint32_t v_scratch = 0; - uint32_t v_limit = 0; + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, + uint32_t a_q) { + uint32_t v_bq0 = 0; + uint32_t v_bq2 = 0; + uint32_t v_bq4 = 0; + uint32_t v_bq6 = 0; + uint32_t v_ca = 0; + uint32_t v_cb2 = 0; + uint32_t v_cb6 = 0; + uint32_t v_ccp = 0; + uint32_t v_ccm = 0; + uint32_t v_cd0 = 0; + uint32_t v_cd1 = 0; + uint32_t v_cd2 = 0; + uint32_t v_cd3 = 0; + uint32_t v_bq1 = 0; + uint32_t v_bq3 = 0; + uint32_t v_bq5 = 0; + uint32_t v_bq7 = 0; + uint32_t v_ci51 = 0; + uint32_t v_ci53 = 0; + uint32_t v_ci71 = 0; + uint32_t v_ci73 = 0; + uint32_t v_cj = 0; + uint32_t v_ck1 = 0; + uint32_t v_ck3 = 0; + uint32_t v_ck5 = 0; + uint32_t v_ck7 = 0; + uint32_t v_cl51 = 0; + uint32_t v_cl73 = 0; + uint32_t v_in0 = 0; + uint32_t v_in2 = 0; + uint32_t v_in4 = 0; + uint32_t v_in6 = 0; + uint32_t v_ra = 0; + uint32_t v_rb2 = 0; + uint32_t v_rb6 = 0; + uint32_t v_rcp = 0; + uint32_t v_rcm = 0; + uint32_t v_rd0 = 0; + uint32_t v_rd1 = 0; + uint32_t v_rd2 = 0; + uint32_t v_rd3 = 0; + uint32_t v_in1 = 0; + uint32_t v_in3 = 0; + uint32_t v_in5 = 0; + uint32_t v_in7 = 0; + uint32_t v_ri51 = 0; + uint32_t v_ri53 = 0; + uint32_t v_ri71 = 0; + uint32_t v_ri73 = 0; + uint32_t v_rj = 0; + uint32_t v_rk1 = 0; + uint32_t v_rk3 = 0; + uint32_t v_rk5 = 0; + uint32_t v_rk7 = 0; + uint32_t v_rl51 = 0; + uint32_t v_rl73 = 0; + uint32_t v_intermediate[64] = {0}; - v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u))); - v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16)); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + if (8u > a_dst_stride) { + return wuffs_base__make_empty_struct(); } - v_dy = 0u; - while (v_dy < 5u) { - v_my = wuffs_base__u32__min(self->private_impl.f_block_smoothing_my_max_incl, wuffs_base__u32__sat_sub((a_my + v_dy), 2u)); - v_dx = 0u; - while (v_dx < 5u) { - v_mx = wuffs_base__u32__min(self->private_impl.f_block_smoothing_mx_max_incl, wuffs_base__u32__sat_sub((a_mx + v_dx), 2u)); - v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(v_mx)) * 128u) + (((uint64_t)(v_my)) * v_stride16)); - if (v_offset <= ((uint64_t)(a_workbuf.len))) { - wuffs_base__bulk_load_host_endian(&self->private_impl.f_block_smoothing_dc_values[v_dy][v_dx], 1u * (size_t)2u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); - } - v_dx += 1u; - } - v_dy += 1u; + if (0u == (self->private_data.f_mcu_blocks[0u][8u] | + self->private_data.f_mcu_blocks[0u][16u] | + self->private_data.f_mcu_blocks[0u][24u] | + self->private_data.f_mcu_blocks[0u][32u] | + self->private_data.f_mcu_blocks[0u][40u] | + self->private_data.f_mcu_blocks[0u][48u] | + self->private_data.f_mcu_blocks[0u][56u])) { + v_intermediate[0u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u])))) << 2u)); + v_intermediate[8u] = v_intermediate[0u]; + v_intermediate[16u] = v_intermediate[0u]; + v_intermediate[24u] = v_intermediate[0u]; + v_intermediate[32u] = v_intermediate[0u]; + v_intermediate[40u] = v_intermediate[0u]; + v_intermediate[48u] = v_intermediate[0u]; + v_intermediate[56u] = v_intermediate[0u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][16u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][16u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][48u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][48u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][32u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][32u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][8u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][8u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][24u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][24u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][40u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][40u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][56u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][56u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[0u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[56u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[8u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[48u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[16u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[40u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[24u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[32u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - v_q = self->private_impl.f_components_tq[a_csel]; - v_q_00 = ((uint32_t)(self->private_impl.f_quant_tables[v_q][0u])); - if (v_q_00 <= 0u) { - return wuffs_base__make_empty_struct(); + if (0u == (self->private_data.f_mcu_blocks[0u][9u] | + self->private_data.f_mcu_blocks[0u][17u] | + self->private_data.f_mcu_blocks[0u][25u] | + self->private_data.f_mcu_blocks[0u][33u] | + self->private_data.f_mcu_blocks[0u][41u] | + self->private_data.f_mcu_blocks[0u][49u] | + self->private_data.f_mcu_blocks[0u][57u])) { + v_intermediate[1u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u])))) << 2u)); + v_intermediate[9u] = v_intermediate[1u]; + v_intermediate[17u] = v_intermediate[1u]; + v_intermediate[25u] = v_intermediate[1u]; + v_intermediate[33u] = v_intermediate[1u]; + v_intermediate[41u] = v_intermediate[1u]; + v_intermediate[49u] = v_intermediate[1u]; + v_intermediate[57u] = v_intermediate[1u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][17u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][17u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][49u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][49u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][33u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][33u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][9u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][9u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][25u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][25u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][41u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][41u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][57u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][57u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[1u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[57u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[9u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[49u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[17u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[41u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[25u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[33u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - if (0u != (16u & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][6u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][7u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][8u] & - self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][9u])) { - v_scratch = 0u; - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(152u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + 128u)) / 256u))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + 128u)) / 256u))); - } - self->private_data.f_mcu_blocks[0u][0u] = ((uint16_t)(v_scratch)); - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][3u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][3u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][3u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][10u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][10u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][10u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][17u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][17u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][17u] = ((uint16_t)(v_scratch)); - } - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][24u])); - if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][24u] == 0u)) { - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } else { - v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); - } - self->private_data.f_mcu_blocks[0u][24u] = ((uint16_t)(v_scratch)); - } + if (0u == (self->private_data.f_mcu_blocks[0u][10u] | + self->private_data.f_mcu_blocks[0u][18u] | + self->private_data.f_mcu_blocks[0u][26u] | + self->private_data.f_mcu_blocks[0u][34u] | + self->private_data.f_mcu_blocks[0u][42u] | + self->private_data.f_mcu_blocks[0u][50u] | + self->private_data.f_mcu_blocks[0u][58u])) { + v_intermediate[2u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u])))) << 2u)); + v_intermediate[10u] = v_intermediate[2u]; + v_intermediate[18u] = v_intermediate[2u]; + v_intermediate[26u] = v_intermediate[2u]; + v_intermediate[34u] = v_intermediate[2u]; + v_intermediate[42u] = v_intermediate[2u]; + v_intermediate[50u] = v_intermediate[2u]; + v_intermediate[58u] = v_intermediate[2u]; } else { - v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u]; - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u])); - if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) { - v_limit = ((((uint32_t)(1u)) << v_al) - 1u); - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } else { - v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } - self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch)); - } - v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u]; - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u])); - if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) { - v_limit = ((((uint32_t)(1u)) << v_al) - 1u); - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } else { - v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } - self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch)); - } - v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u]; - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u])); - if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) { - v_limit = ((((uint32_t)(1u)) << v_al) - 1u); - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } else { - v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } - self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch)); - } - v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u]; - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u])); - if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) { - v_limit = ((((uint32_t)(1u)) << v_al) - 1u); - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } else { - v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } - self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch)); - } - v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u]; - v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u])); - if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) { - v_limit = ((((uint32_t)(1u)) << v_al) - 1u); - v_scratch = 0u; - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); - v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); - v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); - v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); - v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); - v_scratch *= v_q_00; - if (v_scratch < 2147483648u) { - v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } else { - v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); - } - self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch)); - } + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][18u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][18u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][50u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][50u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][34u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][34u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][10u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][10u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][26u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][26u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][42u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][42u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][58u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][58u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[2u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[58u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[10u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[50u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[18u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[42u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[26u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[34u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - return wuffs_base__make_empty_struct(); -} - -// -------- func jpeg.decoder.decode_mcu - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu( - wuffs_jpeg__decoder* self, - 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); -} - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu__choosy_default( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my) { - uint32_t v_ret = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint8_t v_csel = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint32_t v_pos = 0; - uint8_t v_dc_h = 0; - uint32_t v_dc_symbol = 0; - uint32_t v_dc_ht_fast = 0; - uint32_t v_dc_bl = 0; - uint32_t v_dc_code = 0; - uint32_t v_dc_blm1 = 0; - uint32_t v_dc_ht_slow = 0; - uint16_t v_dc_value = 0; - uint16_t v_dc_extend = 0; - const uint16_t* v_ac_huff_table_fast = NULL; - uint8_t v_ac_h = 0; - uint32_t v_ac_symbol = 0; - uint32_t v_ac_ht_fast = 0; - uint32_t v_ac_bl = 0; - uint32_t v_ac_code = 0; - uint32_t v_ac_blm1 = 0; - uint32_t v_ac_ht_slow = 0; - uint16_t v_ac_value = 0; - uint16_t v_ac_extend = 0; - uint32_t v_ac_rrrr = 0; - uint32_t v_ac_ssss = 0; - uint32_t v_z = 0; - uint32_t v_mcb = 0; - uint64_t v_stride = 0; - uint64_t v_offset = 0; - - v_bits = self->private_impl.f_bitstream_bits; - v_n_bits = self->private_impl.f_bitstream_n_bits; - if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { - return 2u; + if (0u == (self->private_data.f_mcu_blocks[0u][11u] | + self->private_data.f_mcu_blocks[0u][19u] | + self->private_data.f_mcu_blocks[0u][27u] | + self->private_data.f_mcu_blocks[0u][35u] | + self->private_data.f_mcu_blocks[0u][43u] | + self->private_data.f_mcu_blocks[0u][51u] | + self->private_data.f_mcu_blocks[0u][59u])) { + v_intermediate[3u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u])))) << 2u)); + v_intermediate[11u] = v_intermediate[3u]; + v_intermediate[19u] = v_intermediate[3u]; + v_intermediate[27u] = v_intermediate[3u]; + v_intermediate[35u] = v_intermediate[3u]; + v_intermediate[43u] = v_intermediate[3u]; + v_intermediate[51u] = v_intermediate[3u]; + v_intermediate[59u] = v_intermediate[3u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][19u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][19u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][51u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][51u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][35u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][35u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][11u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][11u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][27u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][27u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][43u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][43u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][59u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][59u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[3u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[59u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[11u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[51u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[19u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[43u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[27u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[35u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi), - ((uint64_t)(self->private_impl.f_bitstream_ri))); - do { - while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { - while (self->private_impl.f_mcu_zig_index <= 0u) { - wuffs_base__bulk_memset(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, 0u); - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block]; - v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)])); - v_dc_bl = (v_dc_ht_fast >> 8u); - if (v_n_bits >= v_dc_bl) { - v_dc_symbol = (15u & v_dc_ht_fast); - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - v_bits <<= (v_dc_bl & 63u); - v_n_bits -= v_dc_bl; - } else { - v_dc_code = ((uint32_t)((v_bits >> 55u))); - v_dc_blm1 = 8u; - v_bits <<= 9u; - v_n_bits -= 9u; - while (true) { - v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1]; - if (v_dc_code < (v_dc_ht_slow >> 8u)) { - v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))]))); - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - break; - } - v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); - v_bits <<= 1u; - v_n_bits -= 1u; - v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u); - if (v_dc_blm1 == 0u) { - v_dc_symbol = 0u; - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - break; - } - } - } - v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol)))); - v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)); - v_bits <<= v_dc_symbol; - v_n_bits -= v_dc_symbol; - v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]]; - self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value; - self->private_data.f_mcu_blocks[0u][0u] = self->private_impl.f_mcu_previous_dc_values[v_csel]; - self->private_impl.f_mcu_zig_index = 1u; - break; - } - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - if (v_n_bits < 16u) { - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - } - v_z = 1u; - self->private_impl.f_mcu_zig_index = 0u; - v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[self->private_impl.f_mcu_current_block]; - v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; - while (v_z < 64u) { - v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_ac_bl = (v_ac_ht_fast >> 8u); - if (v_n_bits >= v_ac_bl) { - v_ac_symbol = (255u & v_ac_ht_fast); - v_bits <<= (v_ac_bl & 63u); - v_n_bits -= v_ac_bl; - } else { - v_ac_code = ((uint32_t)((v_bits >> 55u))); - v_ac_blm1 = 8u; - v_bits <<= 9u; - v_n_bits -= 9u; - while (true) { - v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; - if (v_ac_code < (v_ac_ht_slow >> 8u)) { - v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); - break; - } - v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); - v_bits <<= 1u; - v_n_bits -= 1u; - v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); - if (v_ac_blm1 == 0u) { - v_ac_symbol = 0u; - break; - } - } - } - v_ac_rrrr = (v_ac_symbol >> 4u); - v_z += (v_ac_rrrr + 1u); - v_ac_ssss = (v_ac_symbol & 15u); - v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss]; - if (v_ac_ssss > 0u) { - v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss)))); - v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)); - v_bits <<= v_ac_ssss; - v_n_bits -= v_ac_ssss; - self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = v_ac_value; - } else if (v_ac_rrrr < 15u) { - break; - } - } - v_mcb = self->private_impl.f_mcu_current_block; - self->private_impl.f_mcu_current_block += 1u; - 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]))); - } - } - self->private_impl.f_mcu_current_block = 0u; - } while (0); - label__goto_done__break:; - v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); - if (v_pos > self->private_impl.f_bitstream_wi) { - v_ret = 2u; - } else { - self->private_impl.f_bitstream_ri = v_pos; - } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; + if (0u == (self->private_data.f_mcu_blocks[0u][12u] | + self->private_data.f_mcu_blocks[0u][20u] | + self->private_data.f_mcu_blocks[0u][28u] | + self->private_data.f_mcu_blocks[0u][36u] | + self->private_data.f_mcu_blocks[0u][44u] | + self->private_data.f_mcu_blocks[0u][52u] | + self->private_data.f_mcu_blocks[0u][60u])) { + v_intermediate[4u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u])))) << 2u)); + v_intermediate[12u] = v_intermediate[4u]; + v_intermediate[20u] = v_intermediate[4u]; + v_intermediate[28u] = v_intermediate[4u]; + v_intermediate[36u] = v_intermediate[4u]; + v_intermediate[44u] = v_intermediate[4u]; + v_intermediate[52u] = v_intermediate[4u]; + v_intermediate[60u] = v_intermediate[4u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][20u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][20u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][52u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][52u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][36u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][36u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][12u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][12u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][28u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][28u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][44u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][44u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][60u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][60u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[4u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[60u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[12u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[52u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[20u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[44u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[28u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[36u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - self->private_impl.f_bitstream_bits = v_bits; - self->private_impl.f_bitstream_n_bits = v_n_bits; - return v_ret; -} - -// -------- func jpeg.decoder.decode_mcu_progressive_ac_high_bits - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my) { - uint32_t v_ret = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint32_t v_pos = 0; - const uint16_t* v_ac_huff_table_fast = NULL; - uint8_t v_ac_h = 0; - uint32_t v_ac_symbol = 0; - uint32_t v_ac_ht_fast = 0; - uint32_t v_ac_bl = 0; - uint32_t v_ac_code = 0; - uint32_t v_ac_blm1 = 0; - uint32_t v_ac_ht_slow = 0; - uint16_t v_ac_value = 0; - uint16_t v_ac_extend = 0; - uint32_t v_ac_rrrr = 0; - uint32_t v_ac_ssss = 0; - uint32_t v_z = 0; - - if (self->private_impl.f_eob_run > 0u) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_eob_run -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - return 0u; + if (0u == (self->private_data.f_mcu_blocks[0u][13u] | + self->private_data.f_mcu_blocks[0u][21u] | + self->private_data.f_mcu_blocks[0u][29u] | + self->private_data.f_mcu_blocks[0u][37u] | + self->private_data.f_mcu_blocks[0u][45u] | + self->private_data.f_mcu_blocks[0u][53u] | + self->private_data.f_mcu_blocks[0u][61u])) { + v_intermediate[5u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u])))) << 2u)); + v_intermediate[13u] = v_intermediate[5u]; + v_intermediate[21u] = v_intermediate[5u]; + v_intermediate[29u] = v_intermediate[5u]; + v_intermediate[37u] = v_intermediate[5u]; + v_intermediate[45u] = v_intermediate[5u]; + v_intermediate[53u] = v_intermediate[5u]; + v_intermediate[61u] = v_intermediate[5u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][21u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][21u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][53u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][53u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][37u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][37u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][13u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][13u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][29u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][29u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][45u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][45u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][61u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][61u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[5u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[61u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[13u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[53u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[21u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[45u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[29u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[37u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - v_bits = self->private_impl.f_bitstream_bits; - v_n_bits = self->private_impl.f_bitstream_n_bits; - if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { - return 2u; + if (0u == (self->private_data.f_mcu_blocks[0u][14u] | + self->private_data.f_mcu_blocks[0u][22u] | + self->private_data.f_mcu_blocks[0u][30u] | + self->private_data.f_mcu_blocks[0u][38u] | + self->private_data.f_mcu_blocks[0u][46u] | + self->private_data.f_mcu_blocks[0u][54u] | + self->private_data.f_mcu_blocks[0u][62u])) { + v_intermediate[6u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u])))) << 2u)); + v_intermediate[14u] = v_intermediate[6u]; + v_intermediate[22u] = v_intermediate[6u]; + v_intermediate[30u] = v_intermediate[6u]; + v_intermediate[38u] = v_intermediate[6u]; + v_intermediate[46u] = v_intermediate[6u]; + v_intermediate[54u] = v_intermediate[6u]; + v_intermediate[62u] = v_intermediate[6u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][22u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][22u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][54u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][54u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][38u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][38u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][14u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][14u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][30u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][30u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][46u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][46u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][62u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][62u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[6u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[62u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[14u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[54u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[22u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[46u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[30u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[38u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi), - ((uint64_t)(self->private_impl.f_bitstream_ri))); - do { - do { - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - if (v_n_bits < 16u) { - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - } - v_z = self->private_impl.f_mcu_zig_index; - self->private_impl.f_mcu_zig_index = 0u; - v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u]; - v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; - while (v_z <= ((uint32_t)(self->private_impl.f_scan_se))) { - v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_ac_bl = (v_ac_ht_fast >> 8u); - if (v_n_bits >= v_ac_bl) { - v_ac_symbol = (255u & v_ac_ht_fast); - v_bits <<= (v_ac_bl & 63u); - v_n_bits -= v_ac_bl; - } else { - v_ac_code = ((uint32_t)((v_bits >> 55u))); - v_ac_blm1 = 8u; - v_bits <<= 9u; - v_n_bits -= 9u; - while (true) { - v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; - if (v_ac_code < (v_ac_ht_slow >> 8u)) { - v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); - break; - } - v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); - v_bits <<= 1u; - v_n_bits -= 1u; - v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); - if (v_ac_blm1 == 0u) { - v_ac_symbol = 0u; - break; - } - } - } - v_ac_rrrr = (v_ac_symbol >> 4u); - v_z += (v_ac_rrrr + 1u); - v_ac_ssss = (v_ac_symbol & 15u); - v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss]; - if (v_ac_ssss > 0u) { - v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss)))); - v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)); - v_bits <<= v_ac_ssss; - v_n_bits -= v_ac_ssss; - self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = ((uint16_t)(((uint16_t)(v_ac_value << self->private_impl.f_scan_al)))); - } else if (v_ac_rrrr < 15u) { - self->private_impl.f_eob_run = ((uint16_t)(((((uint16_t)(1u)) << v_ac_rrrr) - 1u))); - if (v_ac_rrrr > 0u) { - self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr)))); - v_bits <<= v_ac_rrrr; - v_n_bits -= v_ac_rrrr; - } - break; - } - } - } while (0); - } while (0); - label__goto_done__break:; - v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); - if (v_pos > self->private_impl.f_bitstream_wi) { - v_ret = 2u; - } else { - self->private_impl.f_bitstream_ri = v_pos; - } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; + if (0u == (self->private_data.f_mcu_blocks[0u][15u] | + self->private_data.f_mcu_blocks[0u][23u] | + self->private_data.f_mcu_blocks[0u][31u] | + self->private_data.f_mcu_blocks[0u][39u] | + self->private_data.f_mcu_blocks[0u][47u] | + self->private_data.f_mcu_blocks[0u][55u] | + self->private_data.f_mcu_blocks[0u][63u])) { + v_intermediate[7u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u])))) << 2u)); + v_intermediate[15u] = v_intermediate[7u]; + v_intermediate[23u] = v_intermediate[7u]; + v_intermediate[31u] = v_intermediate[7u]; + v_intermediate[39u] = v_intermediate[7u]; + v_intermediate[47u] = v_intermediate[7u]; + v_intermediate[55u] = v_intermediate[7u]; + v_intermediate[63u] = v_intermediate[7u]; + } else { + v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][23u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][23u])))); + v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][55u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][55u])))); + v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u)); + v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u)))); + v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u)))); + v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u])))); + v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][39u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][39u])))); + v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u)); + v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u)); + v_cd0 = ((uint32_t)(v_ccp + v_cb2)); + v_cd1 = ((uint32_t)(v_ccm + v_cb6)); + v_cd2 = ((uint32_t)(v_ccm - v_cb6)); + v_cd3 = ((uint32_t)(v_ccp - v_cb2)); + v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][15u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][15u])))); + v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][31u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][31u])))); + v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][47u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][47u])))); + v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][63u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][63u])))); + v_ci51 = ((uint32_t)(v_bq5 + v_bq1)); + v_ci53 = ((uint32_t)(v_bq5 + v_bq3)); + v_ci71 = ((uint32_t)(v_bq7 + v_bq1)); + v_ci73 = ((uint32_t)(v_bq7 + v_bq3)); + v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u)); + v_ck1 = ((uint32_t)(v_bq1 * 12299u)); + v_ck3 = ((uint32_t)(v_bq3 * 25172u)); + v_ck5 = ((uint32_t)(v_bq5 * 16819u)); + v_ck7 = ((uint32_t)(v_bq7 * 2446u)); + v_ci51 *= 4294964100u; + v_ci53 *= 4294946301u; + v_ci71 *= 4294959923u; + v_ci73 *= 4294951227u; + v_cl51 = ((uint32_t)(v_ci51 + v_cj)); + v_cl73 = ((uint32_t)(v_ci73 + v_cj)); + v_ck1 += ((uint32_t)(v_ci71 + v_cl51)); + v_ck3 += ((uint32_t)(v_ci53 + v_cl73)); + v_ck5 += ((uint32_t)(v_ci53 + v_cl51)); + v_ck7 += ((uint32_t)(v_ci71 + v_cl73)); + v_intermediate[7u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u); + v_intermediate[63u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u); + v_intermediate[15u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u); + v_intermediate[55u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u); + v_intermediate[23u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u); + v_intermediate[47u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u); + v_intermediate[31u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u); + v_intermediate[39u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u); } - self->private_impl.f_bitstream_bits = v_bits; - self->private_impl.f_bitstream_n_bits = v_n_bits; - return v_ret; -} - -// -------- func jpeg.decoder.decode_mcu_progressive_ac_low_bit - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my) { - uint32_t v_ret = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint16_t v_one_lshift_scan_al = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint32_t v_pos = 0; - const uint16_t* v_ac_huff_table_fast = NULL; - uint8_t v_ac_h = 0; - uint32_t v_ac_symbol = 0; - uint32_t v_ac_ht_fast = 0; - uint32_t v_ac_bl = 0; - uint32_t v_ac_code = 0; - uint32_t v_ac_blm1 = 0; - uint32_t v_ac_ht_slow = 0; - uint16_t v_ac_value = 0; - uint32_t v_ac_rrrr = 0; - uint32_t v_ac_ssss = 0; - uint8_t v_unzig = 0; - bool v_bit = false; - - v_bits = self->private_impl.f_bitstream_bits; - v_n_bits = self->private_impl.f_bitstream_n_bits; - v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al); - if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { - return 2u; - } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi), - ((uint64_t)(self->private_impl.f_bitstream_ri))); - do { - do { - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - while (true) { - if (self->private_impl.f_eob_run > 0u) { - break; - } - v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u]; - v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; - while (true) { - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); - v_ac_bl = (v_ac_ht_fast >> 8u); - if (v_n_bits >= v_ac_bl) { - v_ac_symbol = (255u & v_ac_ht_fast); - v_bits <<= (v_ac_bl & 63u); - v_n_bits -= v_ac_bl; - } else { - v_ac_code = ((uint32_t)((v_bits >> 55u))); - v_ac_blm1 = 8u; - v_bits <<= 9u; - v_n_bits -= 9u; - while (true) { - v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; - if (v_ac_code < (v_ac_ht_slow >> 8u)) { - v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); - break; - } - v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); - v_bits <<= 1u; - v_n_bits -= 1u; - v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); - if (v_ac_blm1 == 0u) { - v_ac_symbol = 0u; - break; - } - } - } - v_ac_rrrr = (v_ac_symbol >> 4u); - v_ac_ssss = (v_ac_symbol & 15u); - v_ac_value = 0u; - if (v_ac_ssss > 0u) { - v_ac_value = (((uint16_t)(1u)) << self->private_impl.f_scan_al); - if ((v_bits >> 63u) == 0u) { - v_ac_value = ((uint16_t)(((uint16_t)(65535u)) << self->private_impl.f_scan_al)); - } - v_bits <<= 1u; - v_n_bits -= 1u; - } else if (v_ac_rrrr < 15u) { - self->private_impl.f_eob_run = (((uint16_t)(1u)) << v_ac_rrrr); - if (v_ac_rrrr > 0u) { - self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr)))); - v_bits <<= v_ac_rrrr; - v_n_bits -= v_ac_rrrr; - } - goto label__goto_do_eob__break; - } - while (true) { - v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]; - if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) { - if (v_n_bits == 0u) { - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - } - v_bit = ((v_bits >> 63u) > 0u); - v_bits <<= 1u; - v_n_bits -= 1u; - if (v_bit) { - if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } - } - } else if (v_ac_rrrr <= 0u) { - break; - } else { - v_ac_rrrr -= 1u; - } - if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { - break; - } - self->private_impl.f_mcu_zig_index += 1u; - } - if (v_ac_value != 0u) { - self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]] = v_ac_value; - } - if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { - break; - } - self->private_impl.f_mcu_zig_index += 1u; - } - goto label__block__break; - } - label__goto_do_eob__break:; - if (self->private_impl.f_eob_run <= 0u) { - v_ret = 2u; - goto label__goto_done__break; - } - while (true) { - v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]; - if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) { - if (v_n_bits == 0u) { - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - } - v_bit = ((v_bits >> 63u) > 0u); - v_bits <<= 1u; - v_n_bits -= 1u; - if (v_bit) { - if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } - } - } - if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { - break; - } - self->private_impl.f_mcu_zig_index += 1u; - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_eob_run -= 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } while (0); - label__block__break:; - } while (0); - label__goto_done__break:; - v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); - if (v_pos > self->private_impl.f_bitstream_wi) { - v_ret = 2u; - } else { - self->private_impl.f_bitstream_ri = v_pos; + if (0u == (v_intermediate[1u] | + v_intermediate[2u] | + v_intermediate[3u] | + v_intermediate[4u] | + v_intermediate[5u] | + v_intermediate[6u] | + v_intermediate[7u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; - } - self->private_impl.f_bitstream_bits = v_bits; - self->private_impl.f_bitstream_n_bits = v_n_bits; - return v_ret; -} - -// -------- func jpeg.decoder.decode_mcu_progressive_dc_high_bits - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my) { - uint32_t v_ret = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint8_t v_csel = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint32_t v_pos = 0; - uint8_t v_dc_h = 0; - uint32_t v_dc_symbol = 0; - uint32_t v_dc_ht_fast = 0; - uint32_t v_dc_bl = 0; - uint32_t v_dc_code = 0; - uint32_t v_dc_blm1 = 0; - uint32_t v_dc_ht_slow = 0; - uint16_t v_dc_value = 0; - uint16_t v_dc_extend = 0; - - v_bits = self->private_impl.f_bitstream_bits; - v_n_bits = self->private_impl.f_bitstream_n_bits; - if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { - return 2u; - } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi), - ((uint64_t)(self->private_impl.f_bitstream_ri))); - do { - while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - do { - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block]; - v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)])); - v_dc_bl = (v_dc_ht_fast >> 8u); - if (v_n_bits >= v_dc_bl) { - v_dc_symbol = (15u & v_dc_ht_fast); - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - v_bits <<= (v_dc_bl & 63u); - v_n_bits -= v_dc_bl; - } else { - v_dc_code = ((uint32_t)((v_bits >> 55u))); - v_dc_blm1 = 8u; - v_bits <<= 9u; - v_n_bits -= 9u; - while (true) { - v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1]; - if (v_dc_code < (v_dc_ht_slow >> 8u)) { - v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))]))); - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - break; - } - v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); - v_bits <<= 1u; - v_n_bits -= 1u; - v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u); - if (v_dc_blm1 == 0u) { - v_dc_symbol = 0u; - v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; - break; - } - } - } - v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol)))); - v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)); - v_bits <<= v_dc_symbol; - v_n_bits -= v_dc_symbol; - v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]]; - self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value; - self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] = ((uint16_t)(self->private_impl.f_mcu_previous_dc_values[v_csel] << self->private_impl.f_scan_al)); - } while (0); - self->private_impl.f_mcu_current_block += 1u; - } - self->private_impl.f_mcu_current_block = 0u; - } while (0); - label__goto_done__break:; - v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); - if (v_pos > self->private_impl.f_bitstream_wi) { - v_ret = 2u; - } else { - self->private_impl.f_bitstream_ri = v_pos; + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[0u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[2u]; + v_in6 = v_intermediate[6u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[0u]; + v_in4 = v_intermediate[4u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[1u]; + v_in3 = v_intermediate[3u]; + v_in5 = v_intermediate[5u]; + v_in7 = v_intermediate[7u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; - } - self->private_impl.f_bitstream_bits = v_bits; - self->private_impl.f_bitstream_n_bits = v_n_bits; - return v_ret; -} - -// -------- func jpeg.decoder.decode_mcu_progressive_dc_low_bit - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit( - wuffs_jpeg__decoder* self, - wuffs_base__slice_u8 a_workbuf, - uint32_t a_mx, - uint32_t a_my) { - uint32_t v_ret = 0; - uint64_t v_bits = 0; - uint32_t v_n_bits = 0; - uint16_t v_one_lshift_scan_al = 0; - wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_r = &u_r; - const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint32_t v_pos = 0; - - v_bits = self->private_impl.f_bitstream_bits; - v_n_bits = self->private_impl.f_bitstream_n_bits; - v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al); - if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { - return 2u; + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - { - wuffs_base__io_buffer* o_0_v_r = v_r; - const uint8_t *o_0_iop_v_r = iop_v_r; - const uint8_t *o_0_io0_v_r = io0_v_r; - const uint8_t *o_0_io1_v_r = io1_v_r; - const uint8_t *o_0_io2_v_r = io2_v_r; - v_r = wuffs_base__io_reader__set( - &u_r, - &iop_v_r, - &io0_v_r, - &io1_v_r, - &io2_v_r, - wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, - self->private_impl.f_bitstream_ri, - self->private_impl.f_bitstream_wi), - ((uint64_t)(self->private_impl.f_bitstream_ri))); - do { - while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { - if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { - v_ret = 1u; - goto label__goto_done__break; - } - do { - if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { - v_ret = 2u; - goto label__goto_done__break; - } - v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); - iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); - v_n_bits |= 56u; - if ((v_bits >> 63u) != 0u) { - self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] |= v_one_lshift_scan_al; - } - v_bits <<= 1u; - v_n_bits -= 1u; - } while (0); - self->private_impl.f_mcu_current_block += 1u; - } - self->private_impl.f_mcu_current_block = 0u; - } while (0); - label__goto_done__break:; - v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); - if (v_pos > self->private_impl.f_bitstream_wi) { - v_ret = 2u; - } else { - self->private_impl.f_bitstream_ri = v_pos; + if (0u == (v_intermediate[9u] | + v_intermediate[10u] | + v_intermediate[11u] | + v_intermediate[12u] | + v_intermediate[13u] | + v_intermediate[14u] | + v_intermediate[15u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } - v_r = o_0_v_r; - iop_v_r = o_0_iop_v_r; - io0_v_r = o_0_io0_v_r; - io1_v_r = o_0_io1_v_r; - io2_v_r = o_0_io2_v_r; - } - self->private_impl.f_bitstream_bits = v_bits; - self->private_impl.f_bitstream_n_bits = v_n_bits; - return v_ret; -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) - -// ---------------- Status Codes Implementations - -const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code"; -const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8"; -const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape"; -const char wuffs_json__error__bad_input[] = "#json: bad input"; -const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string"; -const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination"; -const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length"; -const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth"; -const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O"; - -// ---------------- Private Consts - -#define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99 - -static const uint8_t -WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 162, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 0, 175, - 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 220, 0, 0, 0, - 0, 1, 136, 0, 0, 2, 140, 0, - 0, 0, 0, 0, 0, 0, 138, 0, - 0, 0, 141, 0, 137, 0, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t -WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 1, 3, 4, 5, 6, 7, 10, -}; - -static const uint8_t -WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 7, 27, 10, 63, 39, 11, 0, -}; - -static const uint8_t -WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 32, 32, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -}; - -#define WUFFS_JSON__CLASS_WHITESPACE 0 - -#define WUFFS_JSON__CLASS_STRING 1 - -#define WUFFS_JSON__CLASS_COMMA 2 - -#define WUFFS_JSON__CLASS_COLON 3 - -#define WUFFS_JSON__CLASS_NUMBER 4 - -#define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5 - -#define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6 - -#define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7 - -#define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8 - -#define WUFFS_JSON__CLASS_FALSE 9 - -#define WUFFS_JSON__CLASS_TRUE 10 - -#define WUFFS_JSON__CLASS_NULL_NAN_INF 11 - -#define WUFFS_JSON__CLASS_COMMENT 12 - -#define WUFFS_JSON__EXPECT_VALUE 7858 - -#define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856 - -#define WUFFS_JSON__EXPECT_STRING 4098 - -#define WUFFS_JSON__EXPECT_COMMA 4100 - -#define WUFFS_JSON__EXPECT_COLON 4104 - -#define WUFFS_JSON__EXPECT_NUMBER 4112 - -#define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160 - -#define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352 - -static const uint8_t -WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 0, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 0, 15, 1, 15, 15, 15, 15, 15, - 15, 15, 15, 11, 2, 4, 15, 12, - 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 3, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 11, 15, 15, 15, 15, 11, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 7, 15, 8, 15, 15, - 15, 15, 15, 15, 15, 15, 9, 15, - 15, 11, 15, 15, 15, 15, 11, 15, - 15, 15, 15, 15, 10, 15, 15, 15, - 15, 15, 15, 5, 15, 6, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, -}; - -static const uint8_t -WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t -WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 0, 0, 0, 0, 0, 0, - 0, 138, 139, 140, 141, 142, 143, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 139, 140, 141, 142, 143, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -#define WUFFS_JSON__QUIRKS_BASE 1225364480 - -#define WUFFS_JSON__QUIRKS_COUNT 21 - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_json__decoder__decode_number( - wuffs_json__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_json__decoder__decode_digits( - wuffs_json__decoder* self, - wuffs_base__io_buffer* a_src, - uint32_t a_n); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_leading( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_comment( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_inf_nan( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_trailer( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -// ---------------- VTables - -const wuffs_base__token_decoder__func_ptrs -wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__token_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_json__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_json__decoder__history_retain_length), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_json__decoder__set_quirk), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_json__decoder__initialize( - wuffs_json__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[8u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[10u]; + v_in6 = v_intermediate[14u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[8u]; + v_in4 = v_intermediate[12u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[9u]; + v_in3 = v_intermediate[11u]; + v_in5 = v_intermediate[13u]; + v_in7 = v_intermediate[15u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + if (0u == (v_intermediate[17u] | + v_intermediate[18u] | + v_intermediate[19u] | + v_intermediate[20u] | + v_intermediate[21u] | + v_intermediate[22u] | + v_intermediate[23u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[16u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + v_in2 = v_intermediate[18u]; + v_in6 = v_intermediate[22u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[16u]; + v_in4 = v_intermediate[20u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[17u]; + v_in3 = v_intermediate[19u]; + v_in5 = v_intermediate[21u]; + v_in7 = v_intermediate[23u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name = - wuffs_base__token_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers = - (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder); - return wuffs_base__make_status(NULL); -} - -wuffs_json__decoder* -wuffs_json__decoder__alloc(void) { - wuffs_json__decoder* x = - (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_json__decoder__initialize( - x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} - -size_t -sizeof__wuffs_json__decoder(void) { - return sizeof(wuffs_json__decoder); -} - -// ---------------- Function Implementations - -// -------- func json.decoder.get_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_json__decoder__get_quirk( - const wuffs_json__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - uint32_t v_key = 0; - - if (a_key >= 1225364480u) { - v_key = (a_key - 1225364480u); - if (v_key < 21u) { - if (self->private_impl.f_quirks[v_key]) { - return 1u; - } + if (0u == (v_intermediate[25u] | + v_intermediate[26u] | + v_intermediate[27u] | + v_intermediate[28u] | + v_intermediate[29u] | + v_intermediate[30u] | + v_intermediate[31u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } - } - return 0u; -} - -// -------- func json.decoder.set_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_json__decoder__set_quirk( - wuffs_json__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - if (a_key >= 1225364480u) { - a_key -= 1225364480u; - if (a_key < 21u) { - self->private_impl.f_quirks[a_key] = (a_value > 0u); - return wuffs_base__make_status(NULL); + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[24u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[26u]; + v_in6 = v_intermediate[30u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[24u]; + v_in4 = v_intermediate[28u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[25u]; + v_in3 = v_intermediate[27u]; + v_in5 = v_intermediate[29u]; + v_in7 = v_intermediate[31u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); -} - -// -------- func json.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_json__decoder__history_retain_length( - const wuffs_json__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (0u == (v_intermediate[33u] | + v_intermediate[34u] | + v_intermediate[35u] | + v_intermediate[36u] | + v_intermediate[37u] | + v_intermediate[38u] | + v_intermediate[39u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[32u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[34u]; + v_in6 = v_intermediate[38u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[32u]; + v_in4 = v_intermediate[36u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[33u]; + v_in3 = v_intermediate[35u]; + v_in5 = v_intermediate[37u]; + v_in7 = v_intermediate[39u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - - return 0u; -} - -// -------- func json.decoder.workbuf_len - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_json__decoder__workbuf_len( - const wuffs_json__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); + if (0u == (v_intermediate[41u] | + v_intermediate[42u] | + v_intermediate[43u] | + v_intermediate[44u] | + v_intermediate[45u] | + v_intermediate[46u] | + v_intermediate[47u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[40u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[42u]; + v_in6 = v_intermediate[46u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[40u]; + v_in4 = v_intermediate[44u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[41u]; + v_in3 = v_intermediate[43u]; + v_in5 = v_intermediate[45u]; + v_in7 = v_intermediate[47u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + if (0u == (v_intermediate[49u] | + v_intermediate[50u] | + v_intermediate[51u] | + v_intermediate[52u] | + v_intermediate[53u] | + v_intermediate[54u] | + v_intermediate[55u])) { + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[48u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + } else { + v_in2 = v_intermediate[50u]; + v_in6 = v_intermediate[54u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[48u]; + v_in4 = v_intermediate[52u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[49u]; + v_in3 = v_intermediate[51u]; + v_in5 = v_intermediate[53u]; + v_in7 = v_intermediate[55u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); } - - return wuffs_base__utility__empty_range_ii_u64(); + if (0u == (v_intermediate[57u] | + v_intermediate[58u] | + v_intermediate[59u] | + v_intermediate[60u] | + v_intermediate[61u] | + v_intermediate[62u] | + v_intermediate[63u])) { + if (8u > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[56u] + 16u)) >> 5u) & 1023u)]; + a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u]; + a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u]; + } else { + v_in2 = v_intermediate[58u]; + v_in6 = v_intermediate[62u]; + v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u)); + v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u)))); + v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u)))); + v_in0 = v_intermediate[56u]; + v_in4 = v_intermediate[60u]; + v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u)); + v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u)); + v_rd0 = ((uint32_t)(v_rcp + v_rb2)); + v_rd1 = ((uint32_t)(v_rcm + v_rb6)); + v_rd2 = ((uint32_t)(v_rcm - v_rb6)); + v_rd3 = ((uint32_t)(v_rcp - v_rb2)); + v_in1 = v_intermediate[57u]; + v_in3 = v_intermediate[59u]; + v_in5 = v_intermediate[61u]; + v_in7 = v_intermediate[63u]; + v_ri51 = ((uint32_t)(v_in5 + v_in1)); + v_ri53 = ((uint32_t)(v_in5 + v_in3)); + v_ri71 = ((uint32_t)(v_in7 + v_in1)); + v_ri73 = ((uint32_t)(v_in7 + v_in3)); + v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u)); + v_rk1 = ((uint32_t)(v_in1 * 12299u)); + v_rk3 = ((uint32_t)(v_in3 * 25172u)); + v_rk5 = ((uint32_t)(v_in5 * 16819u)); + v_rk7 = ((uint32_t)(v_in7 * 2446u)); + v_ri51 *= 4294964100u; + v_ri53 *= 4294946301u; + v_ri71 *= 4294959923u; + v_ri73 *= 4294951227u; + v_rl51 = ((uint32_t)(v_ri51 + v_rj)); + v_rl73 = ((uint32_t)(v_ri73 + v_rj)); + v_rk1 += ((uint32_t)(v_ri71 + v_rl51)); + v_rk3 += ((uint32_t)(v_ri53 + v_rl73)); + v_rk5 += ((uint32_t)(v_ri53 + v_rl51)); + v_rk7 += ((uint32_t)(v_ri71 + v_rl73)); + if (8u > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)]; + a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)]; + } + return wuffs_base__make_empty_struct(); } -// -------- func json.decoder.decode_tokens +// ‼ WUFFS MULTI-FILE SECTION +x86_avx2 +// -------- func jpeg.decoder.decode_idct_x86_avx2 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2") WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_json__decoder__decode_tokens( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_vminor = 0; - uint32_t v_number_length = 0; - uint32_t v_number_status = 0; - uint32_t v_string_length = 0; - uint32_t v_whitespace_length = 0; - uint32_t v_depth = 0; - uint32_t v_stack_byte = 0; - uint32_t v_stack_bit = 0; - uint32_t v_match = 0; - uint32_t v_c4 = 0; - uint8_t v_c = 0; - uint8_t v_backslash = 0; - uint8_t v_char = 0; - uint8_t v_class = 0; - uint32_t v_multi_byte_utf8 = 0; - uint8_t v_backslash_x_ok = 0; - uint8_t v_backslash_x_value = 0; - uint32_t v_backslash_x_string = 0; - uint8_t v_uni4_ok = 0; - uint64_t v_uni4_string = 0; - uint32_t v_uni4_value = 0; - uint32_t v_uni4_high_surrogate = 0; - uint8_t v_uni8_ok = 0; - uint64_t v_uni8_string = 0; - uint32_t v_uni8_value = 0; - uint32_t v_expect = 0; - uint32_t v_expect_after_value = 0; - - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +static wuffs_base__empty_struct +wuffs_jpeg__decoder__decode_idct_x86_avx2( + wuffs_jpeg__decoder* self, + wuffs_base__slice_u8 a_dst_buffer, + uint64_t a_dst_stride, + uint32_t a_q) { + __m256i v_k_0000 = {0}; + __m256i v_k_8080 = {0}; + __m256i v_k_0000_0002 = {0}; + __m256i v_k_0001_FFFF = {0}; + __m256i v_k_0400_0000 = {0}; + __m256i v_k_29CF_1151_D630_1151 = {0}; + __m256i v_k_E333_133E_ADFD_1051 = {0}; + __m256i v_k_E6DC_25A1_1925_25A1 = {0}; + __m256i v_k_ECC1_E333_EFB0_ADFD = {0}; + __m128i v_az_coeffs = {0}; + __m256i v_az_ah00 = {0}; + __m256i v_az_ad00 = {0}; + __m256i v_az_eh00 = {0}; + __m256i v_az_adeh = {0}; + __m256i v_rows01 = {0}; + __m256i v_rows23 = {0}; + __m256i v_rows45 = {0}; + __m256i v_rows67 = {0}; + __m256i v_quants01 = {0}; + __m256i v_quants23 = {0}; + __m256i v_quants45 = {0}; + __m256i v_quants67 = {0}; + __m256i v_rows04 = {0}; + __m256i v_rows31 = {0}; + __m256i v_rows26 = {0}; + __m256i v_rows75 = {0}; + __m256i v_fp_rows62 = {0}; + __m256i v_fp_bq2662ad = {0}; + __m256i v_fp_bq2662eh = {0}; + __m256i v_fp_cb26ad = {0}; + __m256i v_fp_cb26eh = {0}; + __m256i v_fp_rows40pos = {0}; + __m256i v_fp_rows04neg = {0}; + __m256i v_fp_rows0pm4 = {0}; + __m256i v_fp_ccpmad = {0}; + __m256i v_fp_ccpmeh = {0}; + __m256i v_fp_cd01ad = {0}; + __m256i v_fp_cd01eh = {0}; + __m256i v_fp_cd32ad = {0}; + __m256i v_fp_cd32eh = {0}; + __m256i v_fp_sums7351 = {0}; + __m256i v_fp_sums5173 = {0}; + __m256i v_fp_ci73515173ad = {0}; + __m256i v_fp_ci73515173eh = {0}; + __m256i v_fp_cl7351ad = {0}; + __m256i v_fp_cl7351eh = {0}; + __m256i v_fp_rows13 = {0}; + __m256i v_fp_bq7153ad = {0}; + __m256i v_fp_bq7153eh = {0}; + __m256i v_fp_ck75ad = {0}; + __m256i v_fp_ck75eh = {0}; + __m256i v_fp_cl5173ad = {0}; + __m256i v_fp_cl5173eh = {0}; + __m256i v_fp_ck13ad = {0}; + __m256i v_fp_ck13eh = {0}; + __m256i v_intermediate01ad = {0}; + __m256i v_intermediate01eh = {0}; + __m256i v_intermediate01 = {0}; + __m256i v_intermediate32ad = {0}; + __m256i v_intermediate32eh = {0}; + __m256i v_intermediate32 = {0}; + __m256i v_intermediate45ad = {0}; + __m256i v_intermediate45eh = {0}; + __m256i v_intermediate45 = {0}; + __m256i v_intermediate76ad = {0}; + __m256i v_intermediate76eh = {0}; + __m256i v_intermediate76 = {0}; + __m256i v_ita0a1e0e1 = {0}; + __m256i v_ita2a3e2e3 = {0}; + __m256i v_ita4a5e4e5 = {0}; + __m256i v_ita6a7e6e7 = {0}; + __m256i v_ita0c0e0g0 = {0}; + __m256i v_ita1c1e1g1 = {0}; + __m256i v_ita4c4e4g4 = {0}; + __m256i v_ita5c5e5g5 = {0}; + __m256i v_ita0b0e0f0 = {0}; + __m256i v_ita4b4e4f4 = {0}; + __m256i v_itc0d0g0h0 = {0}; + __m256i v_itc4d4g4h4 = {0}; + __m256i v_intermediateae = {0}; + __m256i v_intermediatebf = {0}; + __m256i v_intermediatecg = {0}; + __m256i v_intermediatedh = {0}; + __m256i v_intermediatedb = {0}; + __m256i v_intermediatehf = {0}; + __m256i v_sp_cols62 = {0}; + __m256i v_sp_bq2662ad = {0}; + __m256i v_sp_bq2662eh = {0}; + __m256i v_sp_rb26ad = {0}; + __m256i v_sp_rb26eh = {0}; + __m256i v_sp_cols40pos = {0}; + __m256i v_sp_cols04neg = {0}; + __m256i v_sp_cols0pm4 = {0}; + __m256i v_sp_rcpmad = {0}; + __m256i v_sp_rcpmeh = {0}; + __m256i v_sp_rd01ad = {0}; + __m256i v_sp_rd01eh = {0}; + __m256i v_sp_rd32ad = {0}; + __m256i v_sp_rd32eh = {0}; + __m256i v_sp_sums7351 = {0}; + __m256i v_sp_sums5173 = {0}; + __m256i v_sp_ri73515173ad = {0}; + __m256i v_sp_ri73515173eh = {0}; + __m256i v_sp_rl7351ad = {0}; + __m256i v_sp_rl7351eh = {0}; + __m256i v_sp_cols13 = {0}; + __m256i v_sp_bq7153ad = {0}; + __m256i v_sp_bq7153eh = {0}; + __m256i v_sp_rk75ad = {0}; + __m256i v_sp_rk75eh = {0}; + __m256i v_sp_rl5173ad = {0}; + __m256i v_sp_rl5173eh = {0}; + __m256i v_sp_rk13ad = {0}; + __m256i v_sp_rk13eh = {0}; + __m256i v_final01ad = {0}; + __m256i v_final01eh = {0}; + __m256i v_final01 = {0}; + __m256i v_final32ad = {0}; + __m256i v_final32eh = {0}; + __m256i v_final32 = {0}; + __m256i v_final45ad = {0}; + __m256i v_final45eh = {0}; + __m256i v_final45 = {0}; + __m256i v_final76ad = {0}; + __m256i v_final76eh = {0}; + __m256i v_final76 = {0}; + __m256i v_fta0a1e0e1 = {0}; + __m256i v_fta2a3e2e3 = {0}; + __m256i v_fta4a5e4e5 = {0}; + __m256i v_fta6a7e6e7 = {0}; + __m256i v_fta0c0e0g0 = {0}; + __m256i v_fta1c1e1g1 = {0}; + __m256i v_fta4c4e4g4 = {0}; + __m256i v_fta5c5e5g5 = {0}; + __m256i v_fta0b0e0f0 = {0}; + __m256i v_ftc0d0g0h0 = {0}; + __m256i v_fta4b4e4f4 = {0}; + __m256i v_ftc4d4g4h4 = {0}; + __m256i v_finalae = {0}; + __m256i v_finalbf = {0}; + __m256i v_finalcg = {0}; + __m256i v_finaldh = {0}; + __m256i v_final0145 = {0}; + __m256i v_final2367 = {0}; + uint64_t v_final0 = 0; + uint64_t v_final1 = 0; + uint64_t v_final2 = 0; + uint64_t v_final3 = 0; + uint64_t v_final4 = 0; + uint64_t v_final5 = 0; + uint64_t v_final6 = 0; + uint64_t v_final7 = 0; + wuffs_base__slice_u8 v_remaining = {0}; - uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0]; - if (coro_susp_point) { - v_depth = self->private_data.s_decode_tokens[0].v_depth; - v_expect = self->private_data.s_decode_tokens[0].v_expect; - v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value; + if (8u > a_dst_stride) { + return wuffs_base__make_empty_struct(); } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if (self->private_impl.f_end_of_data) { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - if (self->private_impl.f_quirks[18u]) { - if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u] || self->private_impl.f_quirks[17u]) { - status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination); - goto exit; + v_k_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u)); + v_k_8080 = _mm256_set_epi16((int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u)); + v_k_0000_0002 = _mm256_set_epi16((int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u)); + v_k_0001_FFFF = _mm256_set_epi16((int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u)); + v_k_0400_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u)); + v_k_29CF_1151_D630_1151 = _mm256_set_epi16((int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u)); + v_k_E333_133E_ADFD_1051 = _mm256_set_epi16((int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u)); + v_k_E6DC_25A1_1925_25A1 = _mm256_set_epi16((int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u)); + v_k_ECC1_E333_EFB0_ADFD = _mm256_set_epi16((int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u)); + do { + if (0u == (wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)) | wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u)))) { + v_az_coeffs = _mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 24u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 40u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 56u))); + if (0u == ((uint64_t)(_mm_cvtsi128_si64(_mm_packs_epi16(v_az_coeffs, v_az_coeffs))))) { + v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u)); + v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u)); + v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01); + v_az_ah00 = _mm256_slli_epi16(v_rows01, (int32_t)(2u)); + v_az_ad00 = _mm256_unpacklo_epi16(v_az_ah00, v_az_ah00); + v_az_eh00 = _mm256_unpackhi_epi16(v_az_ah00, v_az_ah00); + v_az_adeh = _mm256_inserti128_si256(v_az_ad00, _mm256_castsi256_si128(v_az_eh00), (int32_t)(1u)); + v_intermediateae = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(0u)); + v_intermediatebf = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(85u)); + v_intermediatecg = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(170u)); + v_intermediatedh = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(255u)); + break; } } - if (self->private_impl.f_quirks[15u] || self->private_impl.f_quirks[16u]) { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_json__decoder__decode_leading(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } + v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u)); + v_rows23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u)); + v_rows45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u)); + v_rows67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u)); + v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u)); + v_quants23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 16u)); + v_quants45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 32u)); + v_quants67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 48u)); + v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01); + v_rows23 = _mm256_mullo_epi16(v_rows23, v_quants23); + v_rows45 = _mm256_mullo_epi16(v_rows45, v_quants45); + v_rows67 = _mm256_mullo_epi16(v_rows67, v_quants67); + v_rows04 = _mm256_permute2x128_si256(v_rows01, v_rows45, (int32_t)(32u)); + v_rows31 = _mm256_permute2x128_si256(v_rows23, v_rows01, (int32_t)(49u)); + v_rows26 = _mm256_permute2x128_si256(v_rows23, v_rows67, (int32_t)(32u)); + v_rows75 = _mm256_permute2x128_si256(v_rows67, v_rows45, (int32_t)(49u)); + v_fp_rows62 = _mm256_permute2x128_si256(v_rows26, v_rows26, (int32_t)(1u)); + v_fp_bq2662ad = _mm256_unpacklo_epi16(v_rows26, v_fp_rows62); + v_fp_bq2662eh = _mm256_unpackhi_epi16(v_rows26, v_fp_rows62); + v_fp_cb26ad = _mm256_madd_epi16(v_fp_bq2662ad, v_k_29CF_1151_D630_1151); + v_fp_cb26eh = _mm256_madd_epi16(v_fp_bq2662eh, v_k_29CF_1151_D630_1151); + v_fp_rows40pos = _mm256_permute2x128_si256(v_rows04, v_rows04, (int32_t)(1u)); + v_fp_rows04neg = _mm256_sign_epi16(v_rows04, v_k_0001_FFFF); + v_fp_rows0pm4 = _mm256_add_epi16(v_fp_rows40pos, v_fp_rows04neg); + v_fp_ccpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u)); + v_fp_ccpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u)); + v_fp_cd01ad = _mm256_add_epi32(v_fp_ccpmad, v_fp_cb26ad); + v_fp_cd01eh = _mm256_add_epi32(v_fp_ccpmeh, v_fp_cb26eh); + v_fp_cd32ad = _mm256_sub_epi32(v_fp_ccpmad, v_fp_cb26ad); + v_fp_cd32eh = _mm256_sub_epi32(v_fp_ccpmeh, v_fp_cb26eh); + v_fp_sums7351 = _mm256_add_epi16(v_rows75, v_rows31); + v_fp_sums5173 = _mm256_permute2x128_si256(v_fp_sums7351, v_fp_sums7351, (int32_t)(1u)); + v_fp_ci73515173ad = _mm256_unpacklo_epi16(v_fp_sums7351, v_fp_sums5173); + v_fp_ci73515173eh = _mm256_unpackhi_epi16(v_fp_sums7351, v_fp_sums5173); + v_fp_cl7351ad = _mm256_madd_epi16(v_fp_ci73515173ad, v_k_E6DC_25A1_1925_25A1); + v_fp_cl7351eh = _mm256_madd_epi16(v_fp_ci73515173eh, v_k_E6DC_25A1_1925_25A1); + v_fp_rows13 = _mm256_permute2x128_si256(v_rows31, v_rows31, (int32_t)(1u)); + v_fp_bq7153ad = _mm256_unpacklo_epi16(v_rows75, v_fp_rows13); + v_fp_bq7153eh = _mm256_unpackhi_epi16(v_rows75, v_fp_rows13); + v_fp_ck75ad = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351ad); + v_fp_ck75eh = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351eh); + v_fp_cl5173ad = _mm256_permute2x128_si256(v_fp_cl7351ad, v_fp_cl7351ad, (int32_t)(1u)); + v_fp_cl5173eh = _mm256_permute2x128_si256(v_fp_cl7351eh, v_fp_cl7351eh, (int32_t)(1u)); + v_fp_ck13ad = _mm256_add_epi32(v_fp_cl5173ad, _mm256_madd_epi16(v_fp_bq7153ad, v_k_E333_133E_ADFD_1051)); + v_fp_ck13eh = _mm256_add_epi32(v_fp_cl5173eh, _mm256_madd_epi16(v_fp_bq7153eh, v_k_E333_133E_ADFD_1051)); + v_intermediate01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u)); + v_intermediate01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u)); + v_intermediate01 = _mm256_packs_epi32(v_intermediate01ad, v_intermediate01eh); + v_intermediate32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u)); + v_intermediate32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u)); + v_intermediate32 = _mm256_packs_epi32(v_intermediate32ad, v_intermediate32eh); + v_intermediate45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u)); + v_intermediate45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u)); + v_intermediate45 = _mm256_packs_epi32(v_intermediate45ad, v_intermediate45eh); + v_intermediate76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u)); + v_intermediate76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u)); + v_intermediate76 = _mm256_packs_epi32(v_intermediate76ad, v_intermediate76eh); + v_ita0a1e0e1 = _mm256_permute4x64_epi64(v_intermediate01, (int32_t)(216u)); + v_ita2a3e2e3 = _mm256_permute4x64_epi64(v_intermediate32, (int32_t)(114u)); + v_ita4a5e4e5 = _mm256_permute4x64_epi64(v_intermediate45, (int32_t)(216u)); + v_ita6a7e6e7 = _mm256_permute4x64_epi64(v_intermediate76, (int32_t)(114u)); + v_ita0c0e0g0 = _mm256_unpacklo_epi16(v_ita0a1e0e1, v_ita2a3e2e3); + v_ita1c1e1g1 = _mm256_unpackhi_epi16(v_ita0a1e0e1, v_ita2a3e2e3); + v_ita4c4e4g4 = _mm256_unpacklo_epi16(v_ita4a5e4e5, v_ita6a7e6e7); + v_ita5c5e5g5 = _mm256_unpackhi_epi16(v_ita4a5e4e5, v_ita6a7e6e7); + v_ita0b0e0f0 = _mm256_unpacklo_epi16(v_ita0c0e0g0, v_ita1c1e1g1); + v_itc0d0g0h0 = _mm256_unpackhi_epi16(v_ita0c0e0g0, v_ita1c1e1g1); + v_ita4b4e4f4 = _mm256_unpacklo_epi16(v_ita4c4e4g4, v_ita5c5e5g5); + v_itc4d4g4h4 = _mm256_unpackhi_epi16(v_ita4c4e4g4, v_ita5c5e5g5); + v_intermediateae = _mm256_unpacklo_epi64(v_ita0b0e0f0, v_ita4b4e4f4); + v_intermediatebf = _mm256_unpackhi_epi64(v_ita0b0e0f0, v_ita4b4e4f4); + v_intermediatecg = _mm256_unpacklo_epi64(v_itc0d0g0h0, v_itc4d4g4h4); + v_intermediatedh = _mm256_unpackhi_epi64(v_itc0d0g0h0, v_itc4d4g4h4); + } while (0); + v_intermediatedb = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(32u)); + v_intermediatehf = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(49u)); + v_sp_cols62 = _mm256_permute2x128_si256(v_intermediatecg, v_intermediatecg, (int32_t)(1u)); + v_sp_bq2662ad = _mm256_unpacklo_epi16(v_intermediatecg, v_sp_cols62); + v_sp_bq2662eh = _mm256_unpackhi_epi16(v_intermediatecg, v_sp_cols62); + v_sp_rb26ad = _mm256_madd_epi16(v_sp_bq2662ad, v_k_29CF_1151_D630_1151); + v_sp_rb26eh = _mm256_madd_epi16(v_sp_bq2662eh, v_k_29CF_1151_D630_1151); + v_sp_cols40pos = _mm256_permute2x128_si256(v_intermediateae, v_intermediateae, (int32_t)(1u)); + v_sp_cols04neg = _mm256_sign_epi16(v_intermediateae, v_k_0001_FFFF); + v_sp_cols0pm4 = _mm256_add_epi16(v_sp_cols40pos, v_sp_cols04neg); + v_sp_rcpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u)); + v_sp_rcpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u)); + v_sp_rd01ad = _mm256_add_epi32(v_sp_rcpmad, v_sp_rb26ad); + v_sp_rd01eh = _mm256_add_epi32(v_sp_rcpmeh, v_sp_rb26eh); + v_sp_rd32ad = _mm256_sub_epi32(v_sp_rcpmad, v_sp_rb26ad); + v_sp_rd32eh = _mm256_sub_epi32(v_sp_rcpmeh, v_sp_rb26eh); + v_sp_sums7351 = _mm256_add_epi16(v_intermediatehf, v_intermediatedb); + v_sp_sums5173 = _mm256_permute2x128_si256(v_sp_sums7351, v_sp_sums7351, (int32_t)(1u)); + v_sp_ri73515173ad = _mm256_unpacklo_epi16(v_sp_sums7351, v_sp_sums5173); + v_sp_ri73515173eh = _mm256_unpackhi_epi16(v_sp_sums7351, v_sp_sums5173); + v_sp_rl7351ad = _mm256_madd_epi16(v_sp_ri73515173ad, v_k_E6DC_25A1_1925_25A1); + v_sp_rl7351eh = _mm256_madd_epi16(v_sp_ri73515173eh, v_k_E6DC_25A1_1925_25A1); + v_sp_cols13 = _mm256_permute2x128_si256(v_intermediatedb, v_intermediatedb, (int32_t)(1u)); + v_sp_bq7153ad = _mm256_unpacklo_epi16(v_intermediatehf, v_sp_cols13); + v_sp_bq7153eh = _mm256_unpackhi_epi16(v_intermediatehf, v_sp_cols13); + v_sp_rk75ad = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351ad); + v_sp_rk75eh = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351eh); + v_sp_rl5173ad = _mm256_permute2x128_si256(v_sp_rl7351ad, v_sp_rl7351ad, (int32_t)(1u)); + v_sp_rl5173eh = _mm256_permute2x128_si256(v_sp_rl7351eh, v_sp_rl7351eh, (int32_t)(1u)); + v_sp_rk13ad = _mm256_add_epi32(v_sp_rl5173ad, _mm256_madd_epi16(v_sp_bq7153ad, v_k_E333_133E_ADFD_1051)); + v_sp_rk13eh = _mm256_add_epi32(v_sp_rl5173eh, _mm256_madd_epi16(v_sp_bq7153eh, v_k_E333_133E_ADFD_1051)); + v_final01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u)); + v_final01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u)); + v_final01 = _mm256_packs_epi32(v_final01ad, v_final01eh); + v_final32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u)); + v_final32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u)); + v_final32 = _mm256_packs_epi32(v_final32ad, v_final32eh); + v_final45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u)); + v_final45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u)); + v_final45 = _mm256_packs_epi32(v_final45ad, v_final45eh); + v_final76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u)); + v_final76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u)); + v_final76 = _mm256_packs_epi32(v_final76ad, v_final76eh); + v_fta0a1e0e1 = _mm256_permute4x64_epi64(v_final01, (int32_t)(216u)); + v_fta2a3e2e3 = _mm256_permute4x64_epi64(v_final32, (int32_t)(114u)); + v_fta4a5e4e5 = _mm256_permute4x64_epi64(v_final45, (int32_t)(216u)); + v_fta6a7e6e7 = _mm256_permute4x64_epi64(v_final76, (int32_t)(114u)); + v_fta0c0e0g0 = _mm256_unpacklo_epi16(v_fta0a1e0e1, v_fta2a3e2e3); + v_fta1c1e1g1 = _mm256_unpackhi_epi16(v_fta0a1e0e1, v_fta2a3e2e3); + v_fta4c4e4g4 = _mm256_unpacklo_epi16(v_fta4a5e4e5, v_fta6a7e6e7); + v_fta5c5e5g5 = _mm256_unpackhi_epi16(v_fta4a5e4e5, v_fta6a7e6e7); + v_fta0b0e0f0 = _mm256_unpacklo_epi16(v_fta0c0e0g0, v_fta1c1e1g1); + v_ftc0d0g0h0 = _mm256_unpackhi_epi16(v_fta0c0e0g0, v_fta1c1e1g1); + v_fta4b4e4f4 = _mm256_unpacklo_epi16(v_fta4c4e4g4, v_fta5c5e5g5); + v_ftc4d4g4h4 = _mm256_unpackhi_epi16(v_fta4c4e4g4, v_fta5c5e5g5); + v_finalae = _mm256_unpacklo_epi64(v_fta0b0e0f0, v_fta4b4e4f4); + v_finalbf = _mm256_unpackhi_epi64(v_fta0b0e0f0, v_fta4b4e4f4); + v_finalcg = _mm256_unpacklo_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4); + v_finaldh = _mm256_unpackhi_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4); + v_final0145 = _mm256_add_epi8(_mm256_packs_epi16(v_finalae, v_finalbf), v_k_8080); + v_final2367 = _mm256_add_epi8(_mm256_packs_epi16(v_finalcg, v_finaldh), v_k_8080); + v_final0 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(0u)))); + v_final1 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(1u)))); + v_final2 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(0u)))); + v_final3 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(1u)))); + v_final4 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(2u)))); + v_final5 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(3u)))); + v_final6 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(2u)))); + v_final7 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(3u)))); + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final0); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final1); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final2); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final3); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final4); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final5); + a_dst_buffer = v_remaining; + if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride); + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final6); + a_dst_buffer = v_remaining; + if (8u > ((uint64_t)(a_dst_buffer.len))) { + return wuffs_base__make_empty_struct(); + } + wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final7); + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) +// ‼ WUFFS MULTI-FILE SECTION -x86_avx2 + +// -------- func jpeg.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_jpeg__decoder__get_quirk( + const wuffs_jpeg__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (a_key == 2u) { + if (self->private_impl.f_use_lower_quality) { + return 18446744073709551615u; + } + } else if (a_key == 1220532224u) { + if (self->private_impl.f_reject_progressive_jpegs) { + return 1u; + } + } + return 0u; +} + +// -------- func jpeg.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__set_quirk( + wuffs_jpeg__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : 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); + } else if (a_key == 1220532224u) { + self->private_impl.f_reject_progressive_jpegs = (a_value != 0u); + return wuffs_base__make_status(NULL); + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func jpeg.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__decode_image_config( + wuffs_jpeg__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func jpeg.decoder.do_decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__do_decode_image_config( + wuffs_jpeg__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint8_t v_marker = 0; + uint32_t v_pixfmt = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + if (coro_susp_point) { + v_marker = self->private_data.s_do_decode_image_config.v_marker; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 255u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (v_c8 != 216u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_header); + goto exit; } - v_expect = 7858u; - label__outer__continue:; while (true) { while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - goto label__outer__continue; - } - v_whitespace_length = 0u; - v_c = 0u; - v_class = 0u; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (v_whitespace_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_whitespace_length = 0u; - } - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - goto label__outer__continue; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - v_class = WUFFS_JSON__LUT_CLASSES[v_c]; - if (v_class != 0u) { - break; - } - iop_a_src += 1u; - if (v_whitespace_length >= 65534u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(65535u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_whitespace_length = 0u; - goto label__outer__continue; + goto suspend; } - v_whitespace_length += 1u; + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; } - if (v_whitespace_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_whitespace_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__outer__continue; + if (v_c8 == 255u) { + break; + } + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; } - if (0u == (v_expect & (((uint32_t)(1u)) << v_class))) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; + if (v_c8 != 255u) { + v_marker = v_c8; + break; } - if (v_class == 1u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - label__string_loop_outer__continue:; - while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - continue; - } - v_string_length = 0u; + } + if (v_marker == 0u) { + continue; + } else if ((208u <= v_marker) && (v_marker <= 217u)) { + if (v_marker <= 215u) { + continue; + } + } else { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - } - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - goto label__string_loop_outer__continue; + goto suspend; } - while (((uint64_t)(io2_a_src - iop_a_src)) > 4u) { - v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - if (0u != (WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 0u))] | - WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 8u))] | - WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 16u))] | - WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 24u))])) { - break; - } - iop_a_src += 4u; - if (v_string_length > 65527u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - goto label__string_loop_outer__continue; - } - v_string_length += 4u; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + if (num_bits_4 == 8) { + t_4 = ((uint32_t)(*scratch >> 48)); + break; } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - v_char = WUFFS_JSON__LUT_CHARS[v_c]; - if (v_char == 0u) { - iop_a_src += 1u; - if (v_string_length >= 65531u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(65532u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - goto label__string_loop_outer__continue; - } - v_string_length += 1u; - continue; - } else if (v_char == 1u) { - if (v_string_length != 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - } - goto label__string_loop_outer__break; - } else if (v_char == 2u) { - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__string_loop_outer__continue; - } - } - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - goto label__string_loop_outer__continue; - } - v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u))); - v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c]; - if ((v_backslash & 128u) != 0u) { - iop_a_src += 2u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | ((uint32_t)((v_backslash & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } else if (v_backslash != 0u) { - if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7u)]]) { - iop_a_src += 2u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7u)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - } else if (v_c == 117u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); - goto label__string_loop_outer__continue; - } - v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16u); - v_uni4_value = 0u; - v_uni4_ok = 128u; - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u); - if (v_uni4_ok == 0u) { - } else if ((v_uni4_value < 55296u) || (57343u < v_uni4_value)) { - iop_a_src += 6u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } else if (v_uni4_value >= 56320u) { - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) < 12u) { - if (a_src && a_src->meta.closed) { - if (self->private_impl.f_quirks[20u]) { - iop_a_src += 6u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - goto label__string_loop_outer__continue; - } - v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4u) >> 16u); - if (((255u & (v_uni4_string >> 0u)) != 92u) || ((255u & (v_uni4_string >> 8u)) != 117u)) { - v_uni4_high_surrogate = 0u; - v_uni4_value = 0u; - v_uni4_ok = 0u; - } else { - v_uni4_high_surrogate = (65536u + ((v_uni4_value - 55296u) << 10u)); - v_uni4_value = 0u; - v_uni4_ok = 128u; - v_uni4_string >>= 16u; - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))]; - v_uni4_ok &= v_c; - v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u); - } - if ((v_uni4_ok != 0u) && (56320u <= v_uni4_value) && (v_uni4_value <= 57343u)) { - v_uni4_value -= 56320u; - iop_a_src += 12u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(12u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - } - if (self->private_impl.f_quirks[20u]) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) { - status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); - goto exit; - } - iop_a_src += 6u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - } else if ((v_c == 85u) && self->private_impl.f_quirks[2u]) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 10u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); - goto label__string_loop_outer__continue; - } - v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2u); - v_uni8_value = 0u; - v_uni8_ok = 128u; - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 0u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 28u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 8u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 24u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 16u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 20u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 24u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 16u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 32u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 12u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 40u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 8u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 48u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 4u); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 56u))]; - v_uni8_ok &= v_c; - v_uni8_value |= (((uint32_t)((v_c & 15u))) << 0u); - if (v_uni8_ok == 0u) { - } else if ((v_uni8_value < 55296u) || ((57343u < v_uni8_value) && (v_uni8_value <= 1114111u))) { - iop_a_src += 10u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | (v_uni8_value & 2097151u)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } else if (self->private_impl.f_quirks[20u]) { - iop_a_src += 10u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - } else if ((v_c == 120u) && self->private_impl.f_quirks[9u]) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); - goto label__string_loop_outer__continue; - } - v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - v_backslash_x_ok = 128u; - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 16u))]; - v_backslash_x_ok &= v_c; - v_backslash_x_value = ((uint8_t)(((v_c & 15u) << 4u))); - v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 24u))]; - v_backslash_x_ok &= v_c; - v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15u)))); - if ((v_backslash_x_ok == 0u) || ((v_backslash_x_string & 65535u) != 30812u)) { - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } - iop_a_src += 4u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); - goto exit; - } else if (v_char == 3u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__string_loop_outer__continue; - } - } - if (a_src && a_src->meta.closed) { - if (self->private_impl.f_quirks[20u]) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); - goto label__string_loop_outer__continue; - } - v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - if ((v_multi_byte_utf8 & 49152u) == 32768u) { - v_multi_byte_utf8 = ((1984u & ((uint32_t)(v_multi_byte_utf8 << 6u))) | (63u & (v_multi_byte_utf8 >> 8u))); - iop_a_src += 2u; - if (v_string_length >= 65528u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_string_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - goto label__string_loop_outer__continue; - } - v_string_length += 2u; - continue; - } - } else if (v_char == 4u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__string_loop_outer__continue; - } - } - if (a_src && a_src->meta.closed) { - if (self->private_impl.f_quirks[20u]) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12); - goto label__string_loop_outer__continue; - } - v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); - if ((v_multi_byte_utf8 & 12632064u) == 8421376u) { - v_multi_byte_utf8 = ((61440u & ((uint32_t)(v_multi_byte_utf8 << 12u))) | (4032u & (v_multi_byte_utf8 >> 2u)) | (63u & (v_multi_byte_utf8 >> 16u))); - if ((2047u < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296u) || (57343u < v_multi_byte_utf8))) { - iop_a_src += 3u; - if (v_string_length >= 65528u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_string_length + 3u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - goto label__string_loop_outer__continue; - } - v_string_length += 3u; - continue; - } - } - } else if (v_char == 5u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__string_loop_outer__continue; - } - } - if (a_src && a_src->meta.closed) { - if (self->private_impl.f_quirks[20u]) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13); - goto label__string_loop_outer__continue; - } - v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - if ((v_multi_byte_utf8 & 3233857536u) == 2155905024u) { - v_multi_byte_utf8 = ((1835008u & ((uint32_t)(v_multi_byte_utf8 << 18u))) | - (258048u & ((uint32_t)(v_multi_byte_utf8 << 4u))) | - (4032u & (v_multi_byte_utf8 >> 10u)) | - (63u & (v_multi_byte_utf8 >> 24u))); - if ((65535u < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111u)) { - iop_a_src += 4u; - if (v_string_length >= 65528u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - goto label__string_loop_outer__continue; - } - v_string_length += 4u; - continue; - } - } - } - if (v_string_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_string_length = 0u; - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - goto label__string_loop_outer__continue; - } - } - if ((v_char & 128u) != 0u) { - if (self->private_impl.f_quirks[0u]) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((6291456u | ((uint32_t)((v_char & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - goto label__string_loop_outer__continue; - } - if (v_char == 138u) { - status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string); - goto exit; - } - status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code); - goto exit; - } - if (self->private_impl.f_quirks[20u]) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 1u; - goto label__string_loop_outer__continue; - } - status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); - goto exit; + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)); } } - label__string_loop_outer__break:; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14); - continue; - } - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15); - continue; - } - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - break; + self->private_impl.f_payload_length = t_4; + } + if (self->private_impl.f_payload_length < 2u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); + goto exit; + } + self->private_impl.f_payload_length -= 2u; + } + if (v_marker < 192u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } else if (v_marker < 208u) { + if (v_marker <= 194u) { + if ((v_marker == 194u) && self->private_impl.f_reject_progressive_jpegs) { + status = wuffs_base__make_status(wuffs_jpeg__error__rejected_progressive_jpeg); + goto exit; + } else if (self->private_impl.f_sof_marker != 0u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; } - if (0u == (v_expect & (((uint32_t)(1u)) << 4u))) { - v_expect = 4104u; - goto label__outer__continue; + self->private_impl.f_sof_marker = v_marker; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + status = wuffs_jpeg__decoder__decode_sof(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; } break; - } else if (v_class == 2u) { - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (0u == (v_expect & (((uint32_t)(1u)) << 8u))) { - if (self->private_impl.f_quirks[13u]) { - v_expect = 4162u; - } else { - v_expect = 4098u; - } - } else { - if (self->private_impl.f_quirks[13u]) { - v_expect = 8114u; - } else { - v_expect = 7858u; - } + } else if (v_marker == 195u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_lossless_coding); + goto exit; + } else if (v_marker == 196u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } else if ((197u <= v_marker) && (v_marker <= 199u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_hierarchical_coding); + goto exit; + } else if (v_marker == 200u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_arithmetic_coding); + goto exit; + } + } else if (v_marker < 224u) { + if (v_marker < 218u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); + goto exit; + } else if (v_marker == 218u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } else if (v_marker == 219u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - goto label__outer__continue; - } else if (v_class == 3u) { - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 7858u; - goto label__outer__continue; - } else if (v_class == 4u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_jpeg__decoder__decode_dqt(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else if (v_marker == 221u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_jpeg__decoder__decode_dri(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } + } else if (v_marker < 240u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + status = wuffs_jpeg__decoder__decode_appn(self, a_src, v_marker); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else { + if (v_marker == 254u) { + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } + } + self->private_data.s_do_decode_image_config.scratch = self->private_impl.f_payload_length; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + self->private_impl.f_payload_length = 0u; + } + self->private_impl.choosy_decode_idct = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V3) + wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_jpeg__decoder__decode_idct_x86_avx2 : +#endif + self->private_impl.choosy_decode_idct); + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + v_pixfmt = 536870920u; + if (self->private_impl.f_num_components > 1u) { + v_pixfmt = 2415954056u; + } + wuffs_base__image_config__set( + a_dst, + v_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + true); + } + self->private_impl.f_call_sequence = 32u; + + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_image_config.v_marker = v_marker; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_dqt + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dqt( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint8_t v_q = 0; + uint32_t v_i = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_dqt; + if (coro_susp_point) { + v_q = self->private_data.s_decode_dqt.v_q; + v_i = self->private_data.s_decode_dqt.v_i; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (self->private_impl.f_payload_length > 0u) { + self->private_impl.f_payload_length -= 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (((uint8_t)(v_c8 & 15u)) > 3u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker); + goto exit; + } + v_q = ((uint8_t)(v_c8 & 15u)); + if (((uint8_t)(v_c8 >> 4u)) == 1u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision); + goto exit; + } else if ((((uint8_t)(v_c8 >> 4u)) > 1u) || (self->private_impl.f_payload_length < 64u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker); + goto exit; + } + self->private_impl.f_payload_length -= 64u; + v_i = 0u; + while (v_i < 64u) { + v_i += 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint16_t t_1 = *iop_a_src++; + self->private_impl.f_quant_tables[v_q][WUFFS_JPEG__UNZIG[v_i]] = t_1; + } + } + self->private_impl.f_seen_dqt[v_q] = true; + if (self->private_impl.f_sof_marker == 0u) { + v_i = 0u; + while (v_i < 64u) { + self->private_impl.f_saved_quant_tables[v_q][v_i] = self->private_impl.f_quant_tables[v_q][v_i]; + v_i += 1u; + } + self->private_impl.f_saved_seen_dqt[v_q] = true; + } + } + + goto ok; + ok: + self->private_impl.p_decode_dqt = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_dqt = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_dqt.v_q = v_q; + self->private_data.s_decode_dqt.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_dri + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dri( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_dri; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_payload_length != 2u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dri_marker); + goto exit; + } + self->private_impl.f_payload_length = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint16_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src); + iop_a_src += 2; + } else { + self->private_data.s_decode_dri.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_dri.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 8) { + t_0 = ((uint16_t)(*scratch >> 48)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + self->private_impl.f_restart_interval = t_0; + } + if (self->private_impl.f_sof_marker == 0u) { + self->private_impl.f_saved_restart_interval = self->private_impl.f_restart_interval; + } + + goto ok; + ok: + self->private_impl.p_decode_dri = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_dri = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_appn + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_appn( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src, + uint8_t a_marker) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_c32 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_appn; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + do { + if (a_marker == 224u) { + if (self->private_impl.f_payload_length >= 5u) { + self->private_impl.f_payload_length -= 5u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_appn.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_appn.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_c32 = t_0; + } + if (v_c32 != 1179207242u) { + self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 1u)); + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + self->private_impl.f_is_jfif = (v_c8 == 0u); + } + } else if (a_marker == 238u) { + if (self->private_impl.f_payload_length >= 12u) { + self->private_impl.f_payload_length -= 12u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_appn.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_appn.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + v_c32 = t_2; + } + if (v_c32 != 1651467329u) { + self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 8u)); + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_appn.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_appn.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; + } + } + v_c32 = t_3; + } + if ((255u & v_c32) != 101u) { + self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 4u)); + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_appn.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_appn.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 24) { + t_4 = ((uint32_t)(*scratch)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)) << 56; + } + } + v_c32 = t_4; + } + if ((v_c32 >> 24u) == 0u) { + self->private_impl.f_is_adobe = 1u; + } else { + self->private_impl.f_is_adobe = 2u; + } + } + } + } while (0); + self->private_data.s_decode_appn.scratch = self->private_impl.f_payload_length; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (self->private_data.s_decode_appn.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_appn.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_appn.scratch; + self->private_impl.f_payload_length = 0u; + + goto ok; + ok: + self->private_impl.p_decode_appn = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_appn = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_sof + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_sof( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint8_t v_comp_h = 0; + uint8_t v_comp_v = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + bool v_has_h24 = false; + bool v_has_h3 = false; + bool v_has_v24 = false; + bool v_has_v3 = false; + uint32_t v_upper_bound = 0; + uint64_t v_wh0 = 0; + uint64_t v_wh1 = 0; + uint64_t v_wh2 = 0; + uint64_t v_wh3 = 0; + uint64_t v_progressive = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_sof; + if (coro_susp_point) { + v_i = self->private_data.s_decode_sof.v_i; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_payload_length < 6u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } + self->private_impl.f_payload_length -= 6u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 == 8u) { + } else if (v_c8 == 12u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_12_bits); + goto exit; + } else if (v_c8 == 16u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_16_bits); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_1 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_sof.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_sof.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 8) { + t_1 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); + } + } + self->private_impl.f_height = t_1; + } + if (self->private_impl.f_height == 0u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_implicit_height); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_sof.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_sof.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); + if (num_bits_2 == 8) { + t_2 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)); + } + } + self->private_impl.f_width = t_2; + } + if (self->private_impl.f_width == 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if ((v_c8 == 0u) || (v_c8 > 4u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } else if (v_c8 == 2u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_color_model); + goto exit; + } + self->private_impl.f_num_components = ((uint32_t)(v_c8)); + if (self->private_impl.f_payload_length != (3u * self->private_impl.f_num_components)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } + self->private_impl.f_payload_length = 0u; + v_i = 0u; + while (v_i < self->private_impl.f_num_components) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + self->private_impl.f_components_c[v_i] = t_4; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + v_comp_h = ((uint8_t)(v_c8 >> 4u)); + v_comp_v = ((uint8_t)(v_c8 & 15u)); + if ((v_comp_h == 0u) || + (v_comp_h > 4u) || + (v_comp_v == 0u) || + (v_comp_v > 4u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } + self->private_impl.f_components_h[v_i] = v_comp_h; + if (self->private_impl.f_max_incl_components_h < self->private_impl.f_components_h[v_i]) { + self->private_impl.f_max_incl_components_h = self->private_impl.f_components_h[v_i]; + } + self->private_impl.f_components_v[v_i] = v_comp_v; + if (self->private_impl.f_max_incl_components_v < self->private_impl.f_components_v[v_i]) { + self->private_impl.f_max_incl_components_v = self->private_impl.f_components_v[v_i]; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + if (v_c8 >= 4u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } + self->private_impl.f_components_tq[v_i] = v_c8; + v_j = 0u; + while (v_j < v_i) { + if (self->private_impl.f_components_c[v_j] == self->private_impl.f_components_c[v_i]) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } + v_j += 1u; + } + v_i += 1u; + } + if (self->private_impl.f_num_components == 1u) { + self->private_impl.f_max_incl_components_h = 1u; + self->private_impl.f_max_incl_components_v = 1u; + self->private_impl.f_components_h[0u] = 1u; + self->private_impl.f_components_v[0u] = 1u; + } else { + v_has_h24 = false; + v_has_h3 = false; + v_has_v24 = false; + v_has_v3 = false; + v_i = 0u; + while (v_i < self->private_impl.f_num_components) { + v_has_h24 = (v_has_h24 || (self->private_impl.f_components_h[v_i] == 2u) || (self->private_impl.f_components_h[v_i] == 4u)); + v_has_h3 = (v_has_h3 || (self->private_impl.f_components_h[v_i] == 3u)); + v_has_v24 = (v_has_v24 || (self->private_impl.f_components_v[v_i] == 2u) || (self->private_impl.f_components_v[v_i] == 4u)); + v_has_v3 = (v_has_v3 || (self->private_impl.f_components_v[v_i] == 3u)); + v_i += 1u; + } + if ((v_has_h24 && v_has_h3) || (v_has_v24 && v_has_v3)) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_fractional_sampling); + goto exit; + } + if (self->private_impl.f_num_components == 4u) { + self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe < 2u); + } else { + if (self->private_impl.f_is_jfif) { + self->private_impl.f_is_rgb_or_cmyk = false; + } else if (self->private_impl.f_is_adobe > 0u) { + self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe == 1u); + } else { + self->private_impl.f_is_rgb_or_cmyk = ((self->private_impl.f_components_c[0u] == 82u) && (self->private_impl.f_components_c[1u] == 71u) && (self->private_impl.f_components_c[2u] == 66u)); + } + } + } + self->private_impl.f_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, 1u, self->private_impl.f_max_incl_components_h); + self->private_impl.f_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, 1u, self->private_impl.f_max_incl_components_v); + v_upper_bound = 65544u; + self->private_impl.f_components_workbuf_widths[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[0u])))); + self->private_impl.f_components_workbuf_widths[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[1u])))); + self->private_impl.f_components_workbuf_widths[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[2u])))); + self->private_impl.f_components_workbuf_widths[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[3u])))); + self->private_impl.f_components_workbuf_heights[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[0u])))); + self->private_impl.f_components_workbuf_heights[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[1u])))); + self->private_impl.f_components_workbuf_heights[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[2u])))); + self->private_impl.f_components_workbuf_heights[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[3u])))); + v_wh0 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0u]))); + v_wh1 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[1u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1u]))); + v_wh2 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[2u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2u]))); + v_wh3 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[3u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3u]))); + v_progressive = 0u; + if (self->private_impl.f_sof_marker >= 194u) { + v_progressive = 2u; + v_i = 0u; + while (v_i < 4u) { + v_j = 0u; + while (v_j < 10u) { + self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u; + v_j += 1u; + } + v_i += 1u; + } + } + self->private_impl.f_components_workbuf_offsets[0u] = 0u; + self->private_impl.f_components_workbuf_offsets[1u] = (self->private_impl.f_components_workbuf_offsets[0u] + v_wh0); + self->private_impl.f_components_workbuf_offsets[2u] = (self->private_impl.f_components_workbuf_offsets[1u] + v_wh1); + self->private_impl.f_components_workbuf_offsets[3u] = (self->private_impl.f_components_workbuf_offsets[2u] + v_wh2); + self->private_impl.f_components_workbuf_offsets[4u] = (self->private_impl.f_components_workbuf_offsets[3u] + v_wh3); + self->private_impl.f_components_workbuf_offsets[5u] = (self->private_impl.f_components_workbuf_offsets[4u] + (v_wh0 * v_progressive)); + self->private_impl.f_components_workbuf_offsets[6u] = (self->private_impl.f_components_workbuf_offsets[5u] + (v_wh1 * v_progressive)); + self->private_impl.f_components_workbuf_offsets[7u] = (self->private_impl.f_components_workbuf_offsets[6u] + (v_wh2 * v_progressive)); + self->private_impl.f_components_workbuf_offsets[8u] = (self->private_impl.f_components_workbuf_offsets[7u] + (v_wh3 * v_progressive)); + + goto ok; + ok: + self->private_impl.p_decode_sof = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_sof = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_sof.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.quantize_dimension + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_jpeg__decoder__quantize_dimension( + const wuffs_jpeg__decoder* self, + uint32_t a_width, + uint8_t a_h, + uint8_t a_max_incl_h) { + uint32_t v_ratio = 0; + + v_ratio = 0u; + if (a_h > 0u) { + v_ratio = ((uint32_t)(((uint8_t)(a_max_incl_h / a_h)))); + } + if (v_ratio == 1u) { + return ((a_width + 7u) / 8u); + } else if (v_ratio == 2u) { + return ((a_width + 15u) / 16u); + } else if (v_ratio == 3u) { + return ((a_width + 23u) / 24u); + } + return ((a_width + 31u) / 32u); +} + +// -------- func jpeg.decoder.decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__decode_frame_config( + wuffs_jpeg__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func jpeg.decoder.do_decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__do_decode_frame_config( + wuffs_jpeg__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_jpeg__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + self->private_impl.f_frame_config_io_position, + 0u, + true, + false, + 4278190080u); + } + self->private_impl.f_call_sequence = 64u; + + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__decode_frame( + wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_ddf_status = wuffs_base__make_status(NULL); + wuffs_base__status v_swizzle_status = wuffs_base__make_status(NULL); + uint32_t v_scan_count = 0; + + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + v_scan_count = self->private_impl.f_scan_count; + { + wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_ddf_status = t_0; + } + 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 ( ! 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, + 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, + 0u, + 4294967295u, + 0u, + 4294967295u); + } + if (wuffs_base__status__is_error(&v_ddf_status)) { + status = v_ddf_status; + goto exit; + } else if (wuffs_base__status__is_error(&v_swizzle_status)) { + status = v_swizzle_status; + goto exit; + } + } + status = v_ddf_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func jpeg.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__do_decode_frame( + wuffs_jpeg__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_pixfmt = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint8_t v_c8 = 0; + uint8_t v_marker = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + if (coro_susp_point) { + v_marker = self->private_data.s_do_decode_frame.v_marker; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_jpeg__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + v_pixfmt = 536870920u; + if (self->private_impl.f_num_components > 1u) { + v_pixfmt = 2415954056u; + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), + wuffs_base__utility__make_pixel_format(v_pixfmt), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + self->private_impl.f_swizzle_immediately = false; + if (self->private_impl.f_components_workbuf_offsets[8u] > ((uint64_t)(a_workbuf.len))) { + 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); + } + if (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_memset(a_workbuf.ptr, self->private_impl.f_components_workbuf_offsets[4u], 128u); + } + while (true) { + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 == 255u) { + break; + } + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (v_c8 != 255u) { + v_marker = v_c8; + break; + } + } + if (v_marker == 0u) { + continue; + } else if ((208u <= v_marker) && (v_marker <= 217u)) { + if (v_marker <= 215u) { + continue; + } + } else { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_frame.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); + if (num_bits_2 == 8) { + t_2 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)); + } + } + self->private_impl.f_payload_length = t_2; + } + if (self->private_impl.f_payload_length < 2u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); + goto exit; + } + self->private_impl.f_payload_length -= 2u; + } + if (v_marker < 192u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } else if (v_marker < 208u) { + if (v_marker == 196u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + status = wuffs_jpeg__decoder__decode_dht(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else if (v_marker == 200u) { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker); + goto exit; + } else if (v_marker < 224u) { + if (v_marker < 217u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker); + goto exit; + } else if (v_marker == 217u) { + break; + } else if (v_marker == 218u) { + if (a_src) { + 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_dst, a_src, a_workbuf); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else if (v_marker == 219u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_jpeg__decoder__decode_dqt(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else if (v_marker == 221u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_jpeg__decoder__decode_dri(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + continue; + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } + } else if (v_marker < 240u) { + } else { + if (v_marker == 254u) { + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker); + goto exit; + } + } + self->private_data.s_do_decode_frame.scratch = self->private_impl.f_payload_length; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame.scratch; + self->private_impl.f_payload_length = 0u; + } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_frame.v_marker = v_marker; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.decode_dht + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__decode_dht( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint8_t v_tc = 0; + uint8_t v_th = 0; + uint8_t v_tc4_th = 0; + uint32_t v_working_total_count = 0; + uint32_t v_total_count = 0; + uint32_t v_i = 0; + bool v_failed = false; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_dht; + if (coro_susp_point) { + v_tc4_th = self->private_data.s_decode_dht.v_tc4_th; + v_total_count = self->private_data.s_decode_dht.v_total_count; + v_i = self->private_data.s_decode_dht.v_i; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_sof_marker == 0u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + while (self->private_impl.f_payload_length > 0u) { + if (self->private_impl.f_payload_length < 17u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + self->private_impl.f_payload_length -= 17u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if ((((uint8_t)(v_c8 >> 4u)) > 1u) || (((uint8_t)(v_c8 & 15u)) > 3u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + v_tc = ((uint8_t)(v_c8 >> 4u)); + v_th = ((uint8_t)(v_c8 & 15u)); + v_tc4_th = ((uint8_t)(((uint8_t)(((uint8_t)(v_tc * 4u)) | v_th)))); + if ((self->private_impl.f_sof_marker == 192u) && (((uint8_t)(v_tc4_th & 3u)) > 1u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + v_i = 0u; + while (v_i < 16u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + self->private_data.f_dht_temp_counts[v_i] = t_1; + } + v_i += 1u; + } + v_working_total_count = 0u; + v_i = 0u; + while (v_i < 16u) { + v_working_total_count = ((v_working_total_count + ((uint32_t)(self->private_data.f_dht_temp_counts[v_i]))) & 65535u); + v_i += 1u; + } + if ((v_working_total_count <= 0u) || (256u < v_working_total_count)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + v_total_count = v_working_total_count; + if (self->private_impl.f_payload_length < v_total_count) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + self->private_impl.f_payload_length -= v_total_count; + v_i = 0u; + while (v_i < v_total_count) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = t_2; + } + v_i += 1u; + } + while (v_i < 256u) { + self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = 0u; + v_i += 1u; + } + if (((uint8_t)(v_tc4_th & 4u)) == 0u) { + v_i = 0u; + while (v_i < v_total_count) { + if (self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] > 15u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + v_i += 1u; + } + } + v_failed = wuffs_jpeg__decoder__calculate_huff_tables(self, v_tc4_th, v_total_count); + if (v_failed) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker); + goto exit; + } + self->private_impl.f_seen_dht[v_tc4_th] = true; + } + + goto ok; + ok: + self->private_impl.p_decode_dht = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_dht = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_dht.v_tc4_th = v_tc4_th; + self->private_data.s_decode_dht.v_total_count = v_total_count; + self->private_data.s_decode_dht.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.calculate_huff_tables + +WUFFS_BASE__GENERATED_C_CODE +static bool +wuffs_jpeg__decoder__calculate_huff_tables( + wuffs_jpeg__decoder* self, + uint8_t a_tc4_th, + uint32_t a_total_count) { + uint32_t v_i = 0; + uint8_t v_j = 0; + uint8_t v_k = 0; + uint32_t v_bit_length_minus_one = 0; + uint8_t v_bit_length = 0; + uint32_t v_bit_string = 0; + uint32_t v_slow = 0; + uint8_t v_prefix = 0; + uint16_t v_fast = 0; + uint32_t v_reps = 0; + + v_i = 0u; + v_k = 0u; + v_bit_length_minus_one = 0u; + while (v_i < a_total_count) { + while (v_k >= self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) { + v_k = 0u; + v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u); + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_k += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_data.f_dht_temp_bit_lengths[v_i] = ((uint8_t)((v_bit_length_minus_one + 1u))); + v_i += 1u; + } + v_bit_length = 0u; + v_bit_string = 0u; + v_i = 0u; + while (v_i < a_total_count) { + while (v_bit_length < self->private_data.f_dht_temp_bit_lengths[v_i]) { + if (v_bit_length >= 16u) { + return true; + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_bit_length += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bit_string <<= 1u; + } + self->private_data.f_dht_temp_bit_strings[v_i] = ((uint16_t)(v_bit_string)); + v_bit_string += 1u; + if ((v_bit_string >> v_bit_length) > 0u) { + return true; + } + v_i += 1u; + } + v_k = 0u; + v_bit_length_minus_one = 0u; + while (true) { + if (self->private_data.f_dht_temp_counts[v_bit_length_minus_one] == 0u) { + self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = 0u; + } else { + v_slow = (255u & ((uint32_t)(((uint32_t)(v_k)) - ((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_k]))))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_k += self->private_data.f_dht_temp_counts[v_bit_length_minus_one]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = (v_slow | ((((uint32_t)(self->private_data.f_dht_temp_bit_strings[((uint8_t)(v_k - 1u))])) + 1u) << 8u)); + } + v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u); + if (v_bit_length_minus_one == 0u) { + break; + } + } + v_i = 0u; + while (v_i < 256u) { + self->private_impl.f_huff_tables_fast[a_tc4_th][v_i] = 65535u; + v_i += 1u; + } + v_j = 0u; + v_bit_length_minus_one = 0u; + while (v_bit_length_minus_one < 8u) { + v_k = 0u; + while (v_k < self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) { + v_prefix = ((uint8_t)((((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_j])) << (7u - v_bit_length_minus_one)))); + v_fast = ((uint16_t)(((((uint32_t)((v_bit_length_minus_one + 1u))) << 8u) | ((uint32_t)(self->private_impl.f_huff_tables_symbols[a_tc4_th][v_j]))))); + v_reps = (((uint32_t)(1u)) << (7u - v_bit_length_minus_one)); + while (v_reps > 0u) { + self->private_impl.f_huff_tables_fast[a_tc4_th][v_prefix] = v_fast; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_prefix += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_reps -= 1u; + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_k += 1u; + v_j += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + v_bit_length_minus_one += 1u; + } + return false; +} + +// -------- func jpeg.decoder.decode_sos + +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); + + uint32_t v_my = 0; + uint32_t v_mx = 0; + uint32_t v_decode_mcu_result = 0; + uint32_t v_bitstream_length = 0; + + uint32_t coro_susp_point = self->private_impl.p_decode_sos; + if (coro_susp_point) { + v_my = self->private_data.s_decode_sos.v_my; + v_mx = self->private_data.s_decode_sos.v_mx; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + 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); + if (status.repr) { + goto suspend; + } + self->private_impl.f_next_restart_marker = 0u; + self->private_impl.f_mcu_previous_dc_values[0u] = 0u; + self->private_impl.f_mcu_previous_dc_values[1u] = 0u; + self->private_impl.f_mcu_previous_dc_values[2u] = 0u; + self->private_impl.f_mcu_previous_dc_values[3u] = 0u; + self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval; + self->private_impl.f_eob_run = 0u; + self->private_impl.f_bitstream_bits = 0u; + self->private_impl.f_bitstream_n_bits = 0u; + self->private_impl.f_bitstream_ri = 0u; + self->private_impl.f_bitstream_wi = 0u; + self->private_impl.f_bitstream_padding = 12345u; + wuffs_jpeg__decoder__fill_bitstream(self, a_src); + v_my = 0u; + while (v_my < self->private_impl.f_scan_height_in_mcus) { + v_mx = 0u; + while (v_mx < self->private_impl.f_scan_width_in_mcus) { + self->private_impl.f_mcu_current_block = 0u; + self->private_impl.f_mcu_zig_index = ((uint32_t)(self->private_impl.f_scan_ss)); + if (self->private_impl.f_sof_marker >= 194u) { + 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_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 == 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)); + wuffs_jpeg__decoder__fill_bitstream(self, a_src); + if (v_bitstream_length < ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri))) { + break; + } else if (self->private_impl.f_bitstream_padding == 0u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } else if ((a_src && a_src->meta.closed) && ! self->private_impl.f_bitstream_is_closed) { + if (self->private_impl.f_bitstream_wi < 1024u) { + wuffs_private_impl__bulk_memset(&self->private_data.f_bitstream_buffer[self->private_impl.f_bitstream_wi], 264u, 0u); + self->private_impl.f_bitstream_wi += 264u; + self->private_impl.f_bitstream_is_closed = true; + } + break; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } + } + if (self->private_impl.f_sof_marker >= 194u) { + wuffs_jpeg__decoder__save_mcu_blocks(self, v_mx, v_my, a_workbuf); + } + if (self->private_impl.f_restarts_remaining > 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_restarts_remaining -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + if (self->private_impl.f_restarts_remaining == 0u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_jpeg__decoder__skip_past_the_next_restart_marker(self, a_src); + if (status.repr) { + goto suspend; + } + self->private_impl.f_mcu_previous_dc_values[0u] = 0u; + self->private_impl.f_mcu_previous_dc_values[1u] = 0u; + self->private_impl.f_mcu_previous_dc_values[2u] = 0u; + self->private_impl.f_mcu_previous_dc_values[3u] = 0u; + self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval; + self->private_impl.f_eob_run = 0u; + self->private_impl.f_bitstream_bits = 0u; + self->private_impl.f_bitstream_n_bits = 0u; + self->private_impl.f_bitstream_ri = 0u; + self->private_impl.f_bitstream_wi = 0u; + self->private_impl.f_bitstream_padding = 12345u; + } + } + v_mx += 1u; + } + v_my += 1u; + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_scan_count, 1u); + + ok: + self->private_impl.p_decode_sos = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_sos = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_sos.v_my = v_my; + self->private_data.s_decode_sos.v_mx = v_mx; + + goto exit; + exit: + return status; +} + +// -------- func jpeg.decoder.prepare_scan + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__prepare_scan( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_i = 0; + uint32_t v_j = 0; + uint32_t v_j_max_incl = 0; + bool v_failed = false; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_prepare_scan; + if (coro_susp_point) { + v_i = self->private_data.s_prepare_scan.v_i; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if ((self->private_impl.f_payload_length < 6u) || (self->private_impl.f_payload_length > 12u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if ((v_c8 < 1u) || (v_c8 > 4u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_scan_num_components = ((uint32_t)(v_c8)); + if ((self->private_impl.f_scan_num_components > self->private_impl.f_num_components) || (self->private_impl.f_payload_length != (4u + (2u * self->private_impl.f_scan_num_components)))) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_payload_length = 0u; + v_i = 0u; + while (v_i < self->private_impl.f_scan_num_components) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + v_j = 0u; + while (true) { + if (v_j >= self->private_impl.f_num_components) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + if (v_c8 == self->private_impl.f_components_c[v_j]) { + if ( ! self->private_impl.f_seen_dqt[self->private_impl.f_components_tq[v_j]]) { + status = wuffs_base__make_status(wuffs_jpeg__error__missing_quantization_table); + goto exit; + } + self->private_impl.f_scan_comps_cselector[v_i] = ((uint8_t)(v_j)); + break; + } + v_j += 1u; + } + v_j = 0u; + while (v_j < v_i) { + if (self->private_impl.f_scan_comps_cselector[v_i] == self->private_impl.f_scan_comps_cselector[v_j]) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + v_j += 1u; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if ((((uint8_t)(v_c8 >> 4u)) > 3u) || (((uint8_t)(v_c8 & 15u)) > 3u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_scan_comps_td[v_i] = ((uint8_t)(v_c8 >> 4u)); + self->private_impl.f_scan_comps_ta[v_i] = ((uint8_t)(v_c8 & 15u)); + if (self->private_impl.f_sof_marker == 192u) { + if ((self->private_impl.f_scan_comps_td[v_i] > 1u) || (self->private_impl.f_scan_comps_ta[v_i] > 1u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + } + 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); + if (self->private_data.s_prepare_scan.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_prepare_scan.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_prepare_scan.scratch; + self->private_impl.f_scan_ss = 0u; + self->private_impl.f_scan_se = 63u; + self->private_impl.f_scan_ah = 0u; + self->private_impl.f_scan_al = 0u; + } else { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if (v_c8 > 63u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_scan_ss = v_c8; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if ((v_c8 > 63u) || (v_c8 < self->private_impl.f_scan_ss)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_scan_se = v_c8; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + if ((((uint8_t)(v_c8 >> 4u)) > 14u) || (((uint8_t)(v_c8 & 15u)) > 13u)) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + self->private_impl.f_scan_ah = ((uint8_t)(v_c8 >> 4u)); + self->private_impl.f_scan_al = ((uint8_t)(v_c8 & 15u)); + if (self->private_impl.f_scan_ah > 0u) { + if (((uint8_t)(self->private_impl.f_scan_ah - 1u)) != self->private_impl.f_scan_al) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + } + if (self->private_impl.f_scan_ss == 0u) { + if (self->private_impl.f_scan_se != 0u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } else if (self->private_impl.f_scan_ah == 0u) { + self->private_impl.choosy_decode_mcu = ( + &wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits); + } else { + self->private_impl.choosy_decode_mcu = ( + &wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit); + } + } else { + if (self->private_impl.f_scan_num_components != 1u) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } else if (self->private_impl.f_scan_ah == 0u) { + self->private_impl.choosy_decode_mcu = ( + &wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits); + } else { + self->private_impl.choosy_decode_mcu = ( + &wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit); + } + } + } + v_i = 0u; + while (v_i < self->private_impl.f_scan_num_components) { + if ((self->private_impl.f_scan_ss == 0u) && ! self->private_impl.f_seen_dht[((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_i]))]) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_jpeg__decoder__use_default_huffman_table(self, ((uint8_t)(0u | self->private_impl.f_scan_comps_td[v_i]))); + if (status.repr) { + goto suspend; + } + } + if ((self->private_impl.f_scan_se != 0u) && ! self->private_impl.f_seen_dht[((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_i]))]) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_jpeg__decoder__use_default_huffman_table(self, ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[v_i]))); + if (status.repr) { + goto suspend; + } + } + v_j = ((uint32_t)(self->private_impl.f_scan_ss)); + v_j_max_incl = ((uint32_t)(wuffs_base__u8__min(self->private_impl.f_scan_se, 9u))); + while (v_j <= v_j_max_incl) { + self->private_impl.f_block_smoothing_lowest_scan_al[self->private_impl.f_scan_comps_cselector[v_i]][v_j] = self->private_impl.f_scan_al; + v_j += 1u; + } + v_i += 1u; + } + if (self->private_impl.f_scan_num_components == 1u) { + wuffs_jpeg__decoder__calculate_single_component_scan_fields(self); + } else { + v_failed = wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(self); + if (v_failed) { + status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker); + goto exit; + } + } + + goto ok; + ok: + self->private_impl.p_prepare_scan = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_prepare_scan = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_prepare_scan.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.use_default_huffman_table + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__use_default_huffman_table( + wuffs_jpeg__decoder* self, + uint8_t a_tc4_th) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__slice_u8 v_data = {0}; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + if (a_tc4_th == 0u) { + v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA), 29); + } else if (a_tc4_th == 1u) { + v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA), 29); + } else if (a_tc4_th == 4u) { + v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA), 179); + } else if (a_tc4_th == 5u) { + v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA), 179); + } else { + status = wuffs_base__make_status(wuffs_jpeg__error__missing_huffman_table); + goto exit; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + v_data, + 0u); + self->private_impl.f_payload_length = ((uint32_t)((((uint64_t)(v_data.len)) & 65535u))); + { + wuffs_base__status t_0 = wuffs_jpeg__decoder__decode_dht(self, v_r); + v_status = t_0; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + status = v_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; + + ok: + goto exit; + exit: + return status; +} + +// -------- func jpeg.decoder.calculate_single_component_scan_fields + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__calculate_single_component_scan_fields( + wuffs_jpeg__decoder* self) { + uint8_t v_csel = 0; + + self->private_impl.f_scan_comps_bx_offset[0u] = 0u; + self->private_impl.f_scan_comps_by_offset[0u] = 0u; + self->private_impl.f_mcu_num_blocks = 1u; + self->private_impl.f_mcu_blocks_sselector[0u] = 0u; + v_csel = self->private_impl.f_scan_comps_cselector[0u]; + self->private_impl.f_mcu_blocks_offset[0u] = self->private_impl.f_components_workbuf_offsets[v_csel]; + self->private_impl.f_mcu_blocks_mx_mul[0u] = 8u; + self->private_impl.f_mcu_blocks_my_mul[0u] = (8u * self->private_impl.f_components_workbuf_widths[v_csel]); + self->private_impl.f_mcu_blocks_dc_hselector[0u] = ((uint8_t)(0u | self->private_impl.f_scan_comps_td[0u])); + self->private_impl.f_mcu_blocks_ac_hselector[0u] = ((uint8_t)(4u | self->private_impl.f_scan_comps_ta[0u])); + self->private_impl.f_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h); + self->private_impl.f_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v); + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.calculate_multiple_component_scan_fields + +WUFFS_BASE__GENERATED_C_CODE +static bool +wuffs_jpeg__decoder__calculate_multiple_component_scan_fields( + wuffs_jpeg__decoder* self) { + uint32_t v_i = 0; + uint32_t v_h = 0; + uint32_t v_v = 0; + uint32_t v_hv = 0; + uint32_t v_total_hv = 0; + 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; + + v_total_hv = 0u; + v_i = 0u; + v_b = 0u; + v_bx_offset = 0u; + v_by_offset = 0u; + while (v_i < self->private_impl.f_scan_num_components) { + 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))); + self->private_impl.f_scan_comps_by_offset[(v_b & 15u)] = ((uint8_t)((v_by_offset & 3u))); + self->private_impl.f_mcu_blocks_sselector[(v_b & 15u)] = ((uint8_t)(v_i)); + v_b += 1u; + v_bx_offset += 1u; + if (v_bx_offset == v_h) { + v_bx_offset = 0u; + v_by_offset += 1u; + if (v_by_offset == v_v) { + v_by_offset = 0u; + } + } + v_hv -= 1u; + } + v_i += 1u; + } + if (v_total_hv > 10u) { + 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]; + v_csel = self->private_impl.f_scan_comps_cselector[v_ssel]; + self->private_impl.f_mcu_blocks_offset[v_b] = (self->private_impl.f_components_workbuf_offsets[v_csel] + (8u * ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (8u * ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b])) * ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])))); + self->private_impl.f_mcu_blocks_mx_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_h[v_csel]))); + 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; + self->private_impl.f_scan_height_in_mcus = self->private_impl.f_height_in_mcus; + return false; +} + +// -------- func jpeg.decoder.fill_bitstream + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__fill_bitstream( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + uint32_t v_wi = 0; + uint8_t v_c8 = 0; + uint32_t v_new_wi = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + if (self->private_impl.f_bitstream_ri <= 0u) { + } else if (self->private_impl.f_bitstream_ri >= self->private_impl.f_bitstream_wi) { + self->private_impl.f_bitstream_ri = 0u; + self->private_impl.f_bitstream_wi = 0u; + } else { + v_wi = (self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri); + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_bitstream_buffer, 2048), wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi)); + self->private_impl.f_bitstream_ri = 0u; + self->private_impl.f_bitstream_wi = v_wi; + } + v_wi = self->private_impl.f_bitstream_wi; + while ((v_wi < 2048u) && (((uint64_t)(io2_a_src - iop_a_src)) > 0u)) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (v_c8 < 255u) { + self->private_data.f_bitstream_buffer[v_wi] = v_c8; + v_wi += 1u; + iop_a_src += 1u; + continue; + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) { + break; + } else if (((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)) > 0u) { + break; + } else { + self->private_data.f_bitstream_buffer[v_wi] = 255u; + v_wi += 1u; + iop_a_src += 2u; + } + } + if (((uint64_t)(io2_a_src - iop_a_src)) > 1u) { + if ((wuffs_base__peek_u8be__no_bounds_check(iop_a_src) >= 255u) && (((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)) > 0u)) { + v_new_wi = (wuffs_base__u32__min(v_wi, 1784u) + 264u); + v_new_wi = wuffs_base__u32__min(v_new_wi, (v_wi + self->private_impl.f_bitstream_padding)); + if (v_wi < v_new_wi) { + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_bitstream_padding, (v_new_wi - v_wi)); + wuffs_private_impl__bulk_memset(&self->private_data.f_bitstream_buffer[v_wi], (v_new_wi - v_wi), 0u); + v_wi = v_new_wi; + } + } + } + self->private_impl.f_bitstream_wi = v_wi; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.load_mcu_blocks_for_single_component + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__load_mcu_blocks_for_single_component( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_csel) { + return (*self->private_impl.choosy_load_mcu_blocks_for_single_component)(self, a_mx, a_my, a_workbuf, a_csel); +} + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_csel) { + uint64_t v_stride16 = 0; + uint64_t v_offset = 0; + + v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u))); + v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16)); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + } + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.load_mcu_blocks + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__load_mcu_blocks( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf) { + uint32_t v_b = 0; + uint8_t v_csel = 0; + uint64_t v_h = 0; + uint64_t v_v = 0; + uint64_t v_stride16 = 0; + uint64_t v_offset = 0; + + v_h = 1u; + v_v = 1u; + v_b = 0u; + while (v_b < self->private_impl.f_mcu_num_blocks) { + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]]; + if (self->private_impl.f_scan_num_components > 1u) { + v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel])); + v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel])); + } + v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u))); + v_offset = (self->private_impl.f_components_workbuf_offsets[((uint8_t)(v_csel | 4u))] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16)); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_load_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + } + v_b += 1u; + } + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.save_mcu_blocks + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__save_mcu_blocks( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf) { + uint32_t v_b = 0; + uint8_t v_csel = 0; + uint64_t v_h = 0; + uint64_t v_v = 0; + uint64_t v_stride16 = 0; + uint64_t v_offset = 0; + + v_h = 1u; + v_v = 1u; + v_b = 0u; + while (v_b < self->private_impl.f_mcu_num_blocks) { + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]]; + if (self->private_impl.f_scan_num_components > 1u) { + v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel])); + v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel])); + } + v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u))); + v_offset = (self->private_impl.f_components_workbuf_offsets[((uint8_t)(v_csel | 4u))] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16)); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_save_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + } + v_b += 1u; + } + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.skip_past_the_next_restart_marker + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_jpeg__decoder__skip_past_the_next_restart_marker( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_skip_past_the_next_restart_marker; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) < 255u) { + iop_a_src += 1u; + continue; + } + v_c8 = ((uint8_t)(((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)))); + if (v_c8 < 192u) { + iop_a_src += 2u; + continue; + } else if ((v_c8 < 208u) || (215u < v_c8)) { + break; + } + v_c8 &= 7u; + if ((self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 1u)) & 7u))) || (self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 2u)) & 7u)))) { + break; + } else if ((self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 7u)) & 7u))) || (self->private_impl.f_next_restart_marker == ((uint8_t)(((uint8_t)(v_c8 + 6u)) & 7u)))) { + iop_a_src += 2u; + continue; + } else { + iop_a_src += 2u; + break; + } + } + self->private_impl.f_next_restart_marker = ((uint8_t)(((uint8_t)(self->private_impl.f_next_restart_marker + 1u)) & 7u)); + + ok: + self->private_impl.p_skip_past_the_next_restart_marker = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_skip_past_the_next_restart_marker = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func jpeg.decoder.apply_progressive_idct + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__apply_progressive_idct( + wuffs_jpeg__decoder* self, + wuffs_base__slice_u8 a_workbuf) { + uint32_t v_csel = 0; + bool v_block_smoothing_applicable = false; + uint32_t v_scan_width_in_mcus = 0; + uint32_t v_scan_height_in_mcus = 0; + uint32_t v_mcu_blocks_mx_mul_0 = 0; + uint32_t v_mcu_blocks_my_mul_0 = 0; + uint32_t v_my = 0; + uint32_t v_mx = 0; + uint64_t v_stride = 0; + uint64_t v_offset = 0; + uint8_t v_stashed_mcu_blocks_0[128] = {0}; + + wuffs_private_impl__bulk_save_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128)); + v_block_smoothing_applicable = true; + v_csel = 0u; + while (v_csel < self->private_impl.f_num_components) { + if ((self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][0u] >= 16u) || wuffs_jpeg__decoder__top_left_quants_has_zero(self, ((uint32_t)(self->private_impl.f_components_tq[v_csel])))) { + v_block_smoothing_applicable = false; + } + v_csel += 1u; + } + v_csel = 0u; + while (v_csel < self->private_impl.f_num_components) { + v_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h); + v_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v); + v_mcu_blocks_mx_mul_0 = 8u; + v_mcu_blocks_my_mul_0 = (8u * self->private_impl.f_components_workbuf_widths[v_csel]); + if (v_block_smoothing_applicable && (0u != (self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][1u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][2u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][3u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][4u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][5u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][6u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] | + self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][9u]))) { + self->private_impl.choosy_load_mcu_blocks_for_single_component = ( + &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth); + self->private_impl.f_block_smoothing_mx_max_incl = wuffs_base__u32__sat_sub(v_scan_width_in_mcus, 1u); + self->private_impl.f_block_smoothing_my_max_incl = wuffs_base__u32__sat_sub(v_scan_height_in_mcus, 1u); + } else { + self->private_impl.choosy_load_mcu_blocks_for_single_component = ( + &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default); + } + v_my = 0u; + while (v_my < v_scan_height_in_mcus) { + v_mx = 0u; + while (v_mx < v_scan_width_in_mcus) { + wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(self, + v_mx, + v_my, + a_workbuf, + v_csel); + v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel])); + v_offset = (self->private_impl.f_components_workbuf_offsets[v_csel] + (((uint64_t)(v_mcu_blocks_mx_mul_0)) * ((uint64_t)(v_mx))) + (((uint64_t)(v_mcu_blocks_my_mul_0)) * ((uint64_t)(v_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]))); + } + v_mx += 1u; + } + v_my += 1u; + } + v_csel += 1u; + } + wuffs_private_impl__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128)); + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.swizzle_gray + +WUFFS_BASE__GENERATED_C_CODE +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, + 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_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; + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + 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 = 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_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); + 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(); + } + v_y += 1u; + } + return wuffs_base__make_status(NULL); +} + +// -------- func jpeg.decoder.swizzle_colorful + +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, + 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_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)), + (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, + 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], + self->private_impl.f_components_h[3u], + self->private_impl.f_components_v[0u], + self->private_impl.f_components_v[1u], + self->private_impl.f_components_v[2u], + self->private_impl.f_components_v[3u], + self->private_impl.f_is_rgb_or_cmyk, + ! 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); +} + +// -------- func jpeg.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_jpeg__decoder__frame_dirty_rect( + const wuffs_jpeg__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); +} + +// -------- func jpeg.decoder.num_animation_loops + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_jpeg__decoder__num_animation_loops( + const wuffs_jpeg__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func jpeg.decoder.num_decoded_frame_configs + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_jpeg__decoder__num_decoded_frame_configs( + const wuffs_jpeg__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; +} + +// -------- func jpeg.decoder.num_decoded_frames + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_jpeg__decoder__num_decoded_frames( + const wuffs_jpeg__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; +} + +// -------- func jpeg.decoder.restart_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__restart_frame( + wuffs_jpeg__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + uint32_t v_i = 0; + uint32_t v_j = 0; + + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if (a_index != 0u) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + 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; + v_i = 0u; + while (v_i < 4u) { + self->private_impl.f_seen_dqt[v_i] = self->private_impl.f_saved_seen_dqt[v_i]; + v_j = 0u; + while (v_j < 64u) { + self->private_impl.f_quant_tables[v_i][v_j] = self->private_impl.f_saved_quant_tables[v_i][v_j]; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 4u) { + v_j = 0u; + while (v_j < 10u) { + self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 8u) { + self->private_impl.f_seen_dht[v_i] = false; + v_i += 1u; + } + return wuffs_base__make_status(NULL); +} + +// -------- func jpeg.decoder.set_report_metadata + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_jpeg__decoder__set_report_metadata( + wuffs_jpeg__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_jpeg__decoder__tell_me_more( + wuffs_jpeg__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + + goto ok; + ok: + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func jpeg.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_jpeg__decoder__workbuf_len( + const wuffs_jpeg__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + 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]); +} + +// -------- func jpeg.decoder.top_left_quants_has_zero + +WUFFS_BASE__GENERATED_C_CODE +static bool +wuffs_jpeg__decoder__top_left_quants_has_zero( + const wuffs_jpeg__decoder* self, + uint32_t a_q) { + return ((self->private_impl.f_quant_tables[a_q][0u] == 0u) || + (self->private_impl.f_quant_tables[a_q][1u] == 0u) || + (self->private_impl.f_quant_tables[a_q][2u] == 0u) || + (self->private_impl.f_quant_tables[a_q][3u] == 0u) || + (self->private_impl.f_quant_tables[a_q][8u] == 0u) || + (self->private_impl.f_quant_tables[a_q][9u] == 0u) || + (self->private_impl.f_quant_tables[a_q][10u] == 0u) || + (self->private_impl.f_quant_tables[a_q][16u] == 0u) || + (self->private_impl.f_quant_tables[a_q][17u] == 0u) || + (self->private_impl.f_quant_tables[a_q][24u] == 0u)); +} + +// -------- func jpeg.decoder.load_mcu_blocks_for_single_component_smooth + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth( + wuffs_jpeg__decoder* self, + uint32_t a_mx, + uint32_t a_my, + wuffs_base__slice_u8 a_workbuf, + uint32_t a_csel) { + uint64_t v_stride16 = 0; + uint64_t v_offset = 0; + uint32_t v_dx = 0; + uint32_t v_dy = 0; + uint32_t v_mx = 0; + uint32_t v_my = 0; + uint8_t v_q = 0; + uint32_t v_q_00 = 0; + uint32_t v_q_xy = 0; + uint8_t v_al = 0; + uint32_t v_scratch = 0; + uint32_t v_limit = 0; + + v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u))); + v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16)); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + } + v_dy = 0u; + while (v_dy < 5u) { + v_my = wuffs_base__u32__min(self->private_impl.f_block_smoothing_my_max_incl, wuffs_base__u32__sat_sub((a_my + v_dy), 2u)); + v_dx = 0u; + while (v_dx < 5u) { + v_mx = wuffs_base__u32__min(self->private_impl.f_block_smoothing_mx_max_incl, wuffs_base__u32__sat_sub((a_mx + v_dx), 2u)); + v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(v_mx)) * 128u) + (((uint64_t)(v_my)) * v_stride16)); + if (v_offset <= ((uint64_t)(a_workbuf.len))) { + wuffs_private_impl__bulk_load_host_endian(&self->private_impl.f_block_smoothing_dc_values[v_dy][v_dx], 1u * (size_t)2u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset)); + } + v_dx += 1u; + } + v_dy += 1u; + } + v_q = self->private_impl.f_components_tq[a_csel]; + v_q_00 = ((uint32_t)(self->private_impl.f_quant_tables[v_q][0u])); + if (v_q_00 <= 0u) { + return wuffs_base__make_empty_struct(); + } + if (0u != (16u & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][6u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][7u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][8u] & + self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][9u])) { + v_scratch = 0u; + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(152u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + 128u)) / 256u))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + 128u)) / 256u))); + } + self->private_data.f_mcu_blocks[0u][0u] = ((uint16_t)(v_scratch)); + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][3u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][3u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][3u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][10u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][10u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][10u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][17u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][17u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][17u] = ((uint16_t)(v_scratch)); + } + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][24u])); + if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][24u] == 0u)) { + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } else { + v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))); + } + self->private_data.f_mcu_blocks[0u][24u] = ((uint16_t)(v_scratch)); + } + } else { + v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u]; + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u])); + if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) { + v_limit = ((((uint32_t)(1u)) << v_al) - 1u); + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } else { + v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } + self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch)); + } + v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u]; + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u])); + if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) { + v_limit = ((((uint32_t)(1u)) << v_al) - 1u); + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } else { + v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } + self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch)); + } + v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u]; + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u])); + if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) { + v_limit = ((((uint32_t)(1u)) << v_al) - 1u); + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } else { + v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } + self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch)); + } + v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u]; + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u])); + if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) { + v_limit = ((((uint32_t)(1u)) << v_al) - 1u); + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } else { + v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } + self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch)); + } + v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u]; + v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u])); + if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) { + v_limit = ((((uint32_t)(1u)) << v_al) - 1u); + v_scratch = 0u; + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u]))); + v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u]))); + v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u]))); + v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u]))); + v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u]))); + v_scratch *= v_q_00; + if (v_scratch < 2147483648u) { + v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } else { + v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))))); + } + self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch)); + } + } + return wuffs_base__make_empty_struct(); +} + +// -------- func jpeg.decoder.decode_mcu + +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_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) { + uint32_t v_ret = 0; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint8_t v_csel = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint32_t v_pos = 0; + uint8_t v_dc_h = 0; + uint32_t v_dc_symbol = 0; + uint32_t v_dc_ht_fast = 0; + uint32_t v_dc_bl = 0; + uint32_t v_dc_code = 0; + uint32_t v_dc_blm1 = 0; + uint32_t v_dc_ht_slow = 0; + uint16_t v_dc_value = 0; + uint16_t v_dc_extend = 0; + const uint16_t* v_ac_huff_table_fast = NULL; + uint8_t v_ac_h = 0; + uint32_t v_ac_symbol = 0; + uint32_t v_ac_ht_fast = 0; + uint32_t v_ac_bl = 0; + uint32_t v_ac_code = 0; + uint32_t v_ac_blm1 = 0; + uint32_t v_ac_ht_slow = 0; + uint16_t v_ac_value = 0; + uint16_t v_ac_extend = 0; + uint32_t v_ac_rrrr = 0; + uint32_t v_ac_ssss = 0; + uint32_t v_z = 0; + uint32_t v_mcb = 0; + uint64_t v_stride = 0; + uint64_t v_offset = 0; + + v_bits = self->private_impl.f_bitstream_bits; + v_n_bits = self->private_impl.f_bitstream_n_bits; + if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { + return 2u; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi), + ((uint64_t)(self->private_impl.f_bitstream_ri))); + do { + while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { + while (self->private_impl.f_mcu_zig_index <= 0u) { + wuffs_private_impl__bulk_memset(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, 0u); + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block]; + v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)])); + v_dc_bl = (v_dc_ht_fast >> 8u); + if (v_n_bits >= v_dc_bl) { + v_dc_symbol = (15u & v_dc_ht_fast); + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + v_bits <<= (v_dc_bl & 63u); + v_n_bits -= v_dc_bl; + } else { + v_dc_code = ((uint32_t)((v_bits >> 55u))); + v_dc_blm1 = 8u; + v_bits <<= 9u; + v_n_bits -= 9u; + while (true) { + v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1]; + if (v_dc_code < (v_dc_ht_slow >> 8u)) { + v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))]))); + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + break; + } + v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); + v_bits <<= 1u; + v_n_bits -= 1u; + v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u); + if (v_dc_blm1 == 0u) { + v_dc_symbol = 0u; + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + break; + } + } + } + v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_dc_value += ((uint16_t)(v_dc_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_dc_symbol; + v_n_bits -= v_dc_symbol; + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_data.f_mcu_blocks[0u][0u] = self->private_impl.f_mcu_previous_dc_values[v_csel]; + self->private_impl.f_mcu_zig_index = 1u; + break; + } + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + if (v_n_bits < 16u) { + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + } + v_z = 1u; + self->private_impl.f_mcu_zig_index = 0u; + v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[self->private_impl.f_mcu_current_block]; + v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; + while (v_z < 64u) { + v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_ac_bl = (v_ac_ht_fast >> 8u); + if (v_n_bits >= v_ac_bl) { + v_ac_symbol = (255u & v_ac_ht_fast); + v_bits <<= (v_ac_bl & 63u); + v_n_bits -= v_ac_bl; + } else { + v_ac_code = ((uint32_t)((v_bits >> 55u))); + v_ac_blm1 = 8u; + v_bits <<= 9u; + v_n_bits -= 9u; + while (true) { + v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; + if (v_ac_code < (v_ac_ht_slow >> 8u)) { + v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); + break; + } + v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); + v_bits <<= 1u; + v_n_bits -= 1u; + v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); + if (v_ac_blm1 == 0u) { + v_ac_symbol = 0u; + break; + } + } + } + v_ac_rrrr = (v_ac_symbol >> 4u); + v_z += (v_ac_rrrr + 1u); + v_ac_ssss = (v_ac_symbol & 15u); + v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss]; + if (v_ac_ssss > 0u) { + v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_ac_value += ((uint16_t)(v_ac_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_ac_ssss; + v_n_bits -= v_ac_ssss; + self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = v_ac_value; + } else if (v_ac_rrrr < 15u) { + break; + } + } + v_mcb = self->private_impl.f_mcu_current_block; + self->private_impl.f_mcu_current_block += 1u; + if (self->private_impl.f_test_only_interrupt_decode_mcu) { + goto label__goto_done__break; + } + 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; + } while (0); + label__goto_done__break:; + v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); + if (v_pos > self->private_impl.f_bitstream_wi) { + v_ret = 2u; + } else { + self->private_impl.f_bitstream_ri = v_pos; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + self->private_impl.f_bitstream_bits = v_bits; + self->private_impl.f_bitstream_n_bits = v_n_bits; + return v_ret; +} + +// -------- func jpeg.decoder.decode_mcu_progressive_ac_high_bits + +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) { + uint32_t v_ret = 0; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint32_t v_pos = 0; + const uint16_t* v_ac_huff_table_fast = NULL; + uint8_t v_ac_h = 0; + uint32_t v_ac_symbol = 0; + uint32_t v_ac_ht_fast = 0; + uint32_t v_ac_bl = 0; + uint32_t v_ac_code = 0; + uint32_t v_ac_blm1 = 0; + uint32_t v_ac_ht_slow = 0; + uint16_t v_ac_value = 0; + uint16_t v_ac_extend = 0; + uint32_t v_ac_rrrr = 0; + uint32_t v_ac_ssss = 0; + uint32_t v_z = 0; + + if (self->private_impl.f_eob_run > 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_eob_run -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + return 0u; + } + v_bits = self->private_impl.f_bitstream_bits; + v_n_bits = self->private_impl.f_bitstream_n_bits; + if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { + return 2u; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi), + ((uint64_t)(self->private_impl.f_bitstream_ri))); + do { + do { + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + if (v_n_bits < 16u) { + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + } + v_z = self->private_impl.f_mcu_zig_index; + self->private_impl.f_mcu_zig_index = 0u; + v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u]; + v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; + while (v_z <= ((uint32_t)(self->private_impl.f_scan_se))) { + v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_ac_bl = (v_ac_ht_fast >> 8u); + if (v_n_bits >= v_ac_bl) { + v_ac_symbol = (255u & v_ac_ht_fast); + v_bits <<= (v_ac_bl & 63u); + v_n_bits -= v_ac_bl; + } else { + v_ac_code = ((uint32_t)((v_bits >> 55u))); + v_ac_blm1 = 8u; + v_bits <<= 9u; + v_n_bits -= 9u; + while (true) { + v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; + if (v_ac_code < (v_ac_ht_slow >> 8u)) { + v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); + break; + } + v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); + v_bits <<= 1u; + v_n_bits -= 1u; + v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); + if (v_ac_blm1 == 0u) { + v_ac_symbol = 0u; + break; + } + } + } + v_ac_rrrr = (v_ac_symbol >> 4u); + v_z += (v_ac_rrrr + 1u); + v_ac_ssss = (v_ac_symbol & 15u); + v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss]; + if (v_ac_ssss > 0u) { + v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_ac_value += ((uint16_t)(v_ac_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_ac_ssss; + v_n_bits -= v_ac_ssss; + self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = ((uint16_t)(((uint16_t)(v_ac_value << self->private_impl.f_scan_al)))); + } else if (v_ac_rrrr < 15u) { + self->private_impl.f_eob_run = ((uint16_t)(((uint16_t)(((uint16_t)(((uint16_t)(1u)) << v_ac_rrrr)) - 1u)))); + if (v_ac_rrrr > 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_ac_rrrr; + v_n_bits -= v_ac_rrrr; + } + break; + } + } + } while (0); + } while (0); + label__goto_done__break:; + v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); + if (v_pos > self->private_impl.f_bitstream_wi) { + v_ret = 2u; + } else { + self->private_impl.f_bitstream_ri = v_pos; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + self->private_impl.f_bitstream_bits = v_bits; + self->private_impl.f_bitstream_n_bits = v_n_bits; + return v_ret; +} + +// -------- func jpeg.decoder.decode_mcu_progressive_ac_low_bit + +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) { + uint32_t v_ret = 0; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint16_t v_one_lshift_scan_al = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint32_t v_pos = 0; + const uint16_t* v_ac_huff_table_fast = NULL; + uint8_t v_ac_h = 0; + uint32_t v_ac_symbol = 0; + uint32_t v_ac_ht_fast = 0; + uint32_t v_ac_bl = 0; + uint32_t v_ac_code = 0; + uint32_t v_ac_blm1 = 0; + uint32_t v_ac_ht_slow = 0; + uint16_t v_ac_value = 0; + uint32_t v_ac_rrrr = 0; + uint32_t v_ac_ssss = 0; + uint8_t v_unzig = 0; + bool v_bit = false; + + v_bits = self->private_impl.f_bitstream_bits; + v_n_bits = self->private_impl.f_bitstream_n_bits; + v_one_lshift_scan_al = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al)); + if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { + return 2u; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi), + ((uint64_t)(self->private_impl.f_bitstream_ri))); + do { + do { + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + while (true) { + if (self->private_impl.f_eob_run > 0u) { + break; + } + v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u]; + v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u]; + while (true) { + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)])); + v_ac_bl = (v_ac_ht_fast >> 8u); + if (v_n_bits >= v_ac_bl) { + v_ac_symbol = (255u & v_ac_ht_fast); + v_bits <<= (v_ac_bl & 63u); + v_n_bits -= v_ac_bl; + } else { + v_ac_code = ((uint32_t)((v_bits >> 55u))); + v_ac_blm1 = 8u; + v_bits <<= 9u; + v_n_bits -= 9u; + while (true) { + v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1]; + if (v_ac_code < (v_ac_ht_slow >> 8u)) { + v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))])); + break; + } + v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); + v_bits <<= 1u; + v_n_bits -= 1u; + v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u); + if (v_ac_blm1 == 0u) { + v_ac_symbol = 0u; + break; + } + } + } + v_ac_rrrr = (v_ac_symbol >> 4u); + v_ac_ssss = (v_ac_symbol & 15u); + v_ac_value = 0u; + if (v_ac_ssss > 0u) { + v_ac_value = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al)); + if ((v_bits >> 63u) == 0u) { + v_ac_value = ((uint16_t)(((uint16_t)(65535u)) << self->private_impl.f_scan_al)); + } + v_bits <<= 1u; + v_n_bits -= 1u; + } else if (v_ac_rrrr < 15u) { + self->private_impl.f_eob_run = ((uint16_t)(((uint16_t)(1u)) << v_ac_rrrr)); + if (v_ac_rrrr > 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_ac_rrrr; + v_n_bits -= v_ac_rrrr; + } + goto label__goto_do_eob__break; + } + while (true) { + v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]; + if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) { + if (v_n_bits == 0u) { + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + } + v_bit = ((v_bits >> 63u) > 0u); + v_bits <<= 1u; + v_n_bits -= 1u; + if (v_bit) { + if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + } + } else if (v_ac_rrrr <= 0u) { + break; + } else { + v_ac_rrrr -= 1u; + } + if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { + break; + } + self->private_impl.f_mcu_zig_index += 1u; + } + if (v_ac_value != 0u) { + self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]] = v_ac_value; + } + if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { + break; + } + self->private_impl.f_mcu_zig_index += 1u; + } + goto label__block__break; + } + label__goto_do_eob__break:; + if (self->private_impl.f_eob_run <= 0u) { + v_ret = 2u; + goto label__goto_done__break; + } + while (true) { + v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]; + if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) { + if (v_n_bits == 0u) { + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + } + v_bit = ((v_bits >> 63u) > 0u); + v_bits <<= 1u; + v_n_bits -= 1u; + if (v_bit) { + if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + } + } + if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) { + break; + } + self->private_impl.f_mcu_zig_index += 1u; + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_eob_run -= 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } while (0); + label__block__break:; + } while (0); + label__goto_done__break:; + v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); + if (v_pos > self->private_impl.f_bitstream_wi) { + v_ret = 2u; + } else { + self->private_impl.f_bitstream_ri = v_pos; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + self->private_impl.f_bitstream_bits = v_bits; + self->private_impl.f_bitstream_n_bits = v_n_bits; + return v_ret; +} + +// -------- func jpeg.decoder.decode_mcu_progressive_dc_high_bits + +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) { + uint32_t v_ret = 0; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint8_t v_csel = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint32_t v_pos = 0; + uint8_t v_dc_h = 0; + uint32_t v_dc_symbol = 0; + uint32_t v_dc_ht_fast = 0; + uint32_t v_dc_bl = 0; + uint32_t v_dc_code = 0; + uint32_t v_dc_blm1 = 0; + uint32_t v_dc_ht_slow = 0; + uint16_t v_dc_value = 0; + uint16_t v_dc_extend = 0; + + v_bits = self->private_impl.f_bitstream_bits; + v_n_bits = self->private_impl.f_bitstream_n_bits; + if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { + return 2u; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi), + ((uint64_t)(self->private_impl.f_bitstream_ri))); + do { + while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + do { + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block]; + v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)])); + v_dc_bl = (v_dc_ht_fast >> 8u); + if (v_n_bits >= v_dc_bl) { + v_dc_symbol = (15u & v_dc_ht_fast); + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + v_bits <<= (v_dc_bl & 63u); + v_n_bits -= v_dc_bl; + } else { + v_dc_code = ((uint32_t)((v_bits >> 55u))); + v_dc_blm1 = 8u; + v_bits <<= 9u; + v_n_bits -= 9u; + while (true) { + v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1]; + if (v_dc_code < (v_dc_ht_slow >> 8u)) { + v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))]))); + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + break; + } + v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u)))); + v_bits <<= 1u; + v_n_bits -= 1u; + v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u); + if (v_dc_blm1 == 0u) { + v_dc_symbol = 0u; + v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol]; + break; + } + } + } + v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_dc_value += ((uint16_t)(v_dc_extend & ((uint16_t)(((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_bits <<= v_dc_symbol; + v_n_bits -= v_dc_symbol; + v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] = ((uint16_t)(self->private_impl.f_mcu_previous_dc_values[v_csel] << self->private_impl.f_scan_al)); + } while (0); + self->private_impl.f_mcu_current_block += 1u; + } + self->private_impl.f_mcu_current_block = 0u; + } while (0); + label__goto_done__break:; + v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); + if (v_pos > self->private_impl.f_bitstream_wi) { + v_ret = 2u; + } else { + self->private_impl.f_bitstream_ri = v_pos; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + self->private_impl.f_bitstream_bits = v_bits; + self->private_impl.f_bitstream_n_bits = v_n_bits; + return v_ret; +} + +// -------- func jpeg.decoder.decode_mcu_progressive_dc_low_bit + +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) { + uint32_t v_ret = 0; + uint64_t v_bits = 0; + uint32_t v_n_bits = 0; + uint16_t v_one_lshift_scan_al = 0; + wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_r = &u_r; + const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint32_t v_pos = 0; + + v_bits = self->private_impl.f_bitstream_bits; + v_n_bits = self->private_impl.f_bitstream_n_bits; + v_one_lshift_scan_al = ((uint16_t)(((uint16_t)(1u)) << self->private_impl.f_scan_al)); + if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) { + return 2u; + } + { + wuffs_base__io_buffer* o_0_v_r = v_r; + const uint8_t* o_0_iop_v_r = iop_v_r; + const uint8_t* o_0_io0_v_r = io0_v_r; + const uint8_t* o_0_io1_v_r = io1_v_r; + const uint8_t* o_0_io2_v_r = io2_v_r; + v_r = wuffs_private_impl__io_reader__set( + &u_r, + &iop_v_r, + &io0_v_r, + &io1_v_r, + &io2_v_r, + wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer, + self->private_impl.f_bitstream_ri, + self->private_impl.f_bitstream_wi), + ((uint64_t)(self->private_impl.f_bitstream_ri))); + do { + while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) { + if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) { + v_ret = 1u; + goto label__goto_done__break; + } + do { + if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) { + v_ret = 2u; + goto label__goto_done__break; + } + v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u)); + iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u); + v_n_bits |= 56u; + if ((v_bits >> 63u) != 0u) { + self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] |= v_one_lshift_scan_al; + } + v_bits <<= 1u; + v_n_bits -= 1u; + } while (0); + self->private_impl.f_mcu_current_block += 1u; + } + self->private_impl.f_mcu_current_block = 0u; + } while (0); + label__goto_done__break:; + v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r))))); + if (v_pos > self->private_impl.f_bitstream_wi) { + v_ret = 2u; + } else { + self->private_impl.f_bitstream_ri = v_pos; + } + v_r = o_0_v_r; + iop_v_r = o_0_iop_v_r; + io0_v_r = o_0_io0_v_r; + io1_v_r = o_0_io1_v_r; + io2_v_r = o_0_io2_v_r; + } + self->private_impl.f_bitstream_bits = v_bits; + self->private_impl.f_bitstream_n_bits = v_n_bits; + return v_ret; +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) + +// ---------------- Status Codes Implementations + +const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code"; +const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8"; +const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape"; +const char wuffs_json__error__bad_input[] = "#json: bad input"; +const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string"; +const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination"; +const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length"; +const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth"; +const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O"; + +// ---------------- Private Consts + +#define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99u + +static const uint8_t +WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 3u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 162u, 0u, 0u, 0u, 0u, 5u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 175u, + 7u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 4u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 220u, 0u, 0u, 0u, + 0u, 1u, 136u, 0u, 0u, 2u, 140u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 138u, 0u, + 0u, 0u, 141u, 0u, 137u, 0u, 6u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, +}; + +static const uint8_t +WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 1u, 3u, 4u, 5u, 6u, 7u, 10u, +}; + +static const uint8_t +WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 7u, 27u, 10u, 63u, 39u, 11u, 0u, +}; + +static const uint8_t +WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u, + 136u, 137u, 138u, 139u, 140u, 141u, 142u, 143u, + 144u, 145u, 146u, 147u, 148u, 149u, 150u, 151u, + 152u, 153u, 154u, 155u, 156u, 157u, 158u, 159u, + 0u, 0u, 1u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 2u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 16u, 16u, 16u, 16u, 16u, 16u, 16u, 16u, + 32u, 32u, 3u, 3u, 3u, 3u, 3u, 3u, + 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, + 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, + 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, + 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, + 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, + 5u, 5u, 5u, 5u, 5u, 32u, 32u, 32u, + 32u, 32u, 32u, 32u, 32u, 32u, 32u, 32u, +}; + +#define WUFFS_JSON__CLASS_WHITESPACE 0u + +#define WUFFS_JSON__CLASS_STRING 1u + +#define WUFFS_JSON__CLASS_COMMA 2u + +#define WUFFS_JSON__CLASS_COLON 3u + +#define WUFFS_JSON__CLASS_NUMBER 4u + +#define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5u + +#define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6u + +#define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7u + +#define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8u + +#define WUFFS_JSON__CLASS_FALSE 9u + +#define WUFFS_JSON__CLASS_TRUE 10u + +#define WUFFS_JSON__CLASS_NULL_NAN_INF 11u + +#define WUFFS_JSON__CLASS_COMMENT 12u + +#define WUFFS_JSON__EXPECT_VALUE 7858u + +#define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856u + +#define WUFFS_JSON__EXPECT_STRING 4098u + +#define WUFFS_JSON__EXPECT_COMMA 4100u + +#define WUFFS_JSON__EXPECT_COLON 4104u + +#define WUFFS_JSON__EXPECT_NUMBER 4112u + +#define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160u + +#define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352u + +static const uint8_t +WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 0u, 0u, 15u, 15u, 0u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 0u, 15u, 1u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 11u, 2u, 4u, 15u, 12u, + 4u, 4u, 4u, 4u, 4u, 4u, 4u, 4u, + 4u, 4u, 3u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 11u, 15u, 15u, 15u, 15u, 11u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 7u, 15u, 8u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 9u, 15u, + 15u, 11u, 15u, 15u, 15u, 15u, 11u, 15u, + 15u, 15u, 15u, 15u, 10u, 15u, 15u, 15u, + 15u, 15u, 15u, 5u, 15u, 6u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, + 15u, 15u, 15u, 15u, 15u, 15u, 15u, 15u, +}; + +static const uint8_t +WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u, + 136u, 137u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, +}; + +static const uint8_t +WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 128u, 129u, 130u, 131u, 132u, 133u, 134u, 135u, + 136u, 137u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 138u, 139u, 140u, 141u, 142u, 143u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 138u, 139u, 140u, 141u, 142u, 143u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, +}; + +#define WUFFS_JSON__QUIRKS_BASE 1225364480u + +#define WUFFS_JSON__QUIRKS_COUNT 21u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_json__decoder__decode_number( + wuffs_json__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_json__decoder__decode_digits( + wuffs_json__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_n); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_leading( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_comment( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_inf_nan( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_trailer( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +// ---------------- VTables + +const wuffs_base__token_decoder__func_ptrs +wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__token_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_json__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_json__decoder__set_quirk), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_json__decoder__initialize( + wuffs_json__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name = + wuffs_base__token_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers = + (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_json__decoder* +wuffs_json__decoder__alloc(void) { + wuffs_json__decoder* x = + (wuffs_json__decoder*)(calloc(1, sizeof(wuffs_json__decoder))); + if (!x) { + return NULL; + } + if (wuffs_json__decoder__initialize( + x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_json__decoder(void) { + return sizeof(wuffs_json__decoder); +} + +// ---------------- Function Implementations + +// -------- func json.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_json__decoder__get_quirk( + const wuffs_json__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + uint32_t v_key = 0; + + if (a_key >= 1225364480u) { + v_key = (a_key - 1225364480u); + if (v_key < 21u) { + if (self->private_impl.f_quirks[v_key]) { + return 1u; + } + } + } + return 0u; +} + +// -------- func json.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_json__decoder__set_quirk( + wuffs_json__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (a_key >= 1225364480u) { + a_key -= 1225364480u; + if (a_key < 21u) { + self->private_impl.f_quirks[a_key] = (a_value > 0u); + return wuffs_base__make_status(NULL); + } + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func json.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_json__decoder__workbuf_len( + const wuffs_json__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__empty_range_ii_u64(); +} + +// -------- func json.decoder.decode_tokens + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_json__decoder__decode_tokens( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_vminor = 0; + uint32_t v_number_length = 0; + uint32_t v_number_status = 0; + uint32_t v_string_length = 0; + uint32_t v_whitespace_length = 0; + uint32_t v_depth = 0; + uint32_t v_stack_byte = 0; + uint32_t v_stack_bit = 0; + uint32_t v_match = 0; + uint32_t v_c32 = 0; + uint8_t v_c8 = 0; + uint8_t v_backslash = 0; + uint8_t v_char = 0; + uint8_t v_class = 0; + uint32_t v_multi_byte_utf8 = 0; + uint8_t v_backslash_x_ok = 0; + uint8_t v_backslash_x_value = 0; + uint32_t v_backslash_x_string = 0; + uint8_t v_uni4_ok = 0; + uint64_t v_uni4_string = 0; + uint32_t v_uni4_value = 0; + uint32_t v_uni4_high_surrogate = 0; + uint8_t v_uni8_ok = 0; + uint64_t v_uni8_string = 0; + uint32_t v_uni8_value = 0; + uint32_t v_expect = 0; + uint32_t v_expect_after_value = 0; + + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_tokens; + if (coro_susp_point) { + v_depth = self->private_data.s_decode_tokens.v_depth; + v_expect = self->private_data.s_decode_tokens.v_expect; + v_expect_after_value = self->private_data.s_decode_tokens.v_expect_after_value; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_end_of_data) { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (self->private_impl.f_quirks[18u]) { + if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u] || self->private_impl.f_quirks[17u]) { + status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination); + goto exit; + } + } + if (self->private_impl.f_quirks[15u] || self->private_impl.f_quirks[16u]) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_json__decoder__decode_leading(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + v_expect = 7858u; + label__outer__continue:; + while (true) { + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + goto label__outer__continue; + } + v_whitespace_length = 0u; + v_c8 = 0u; + v_class = 0u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (v_whitespace_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_whitespace_length = 0u; + } + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + goto label__outer__continue; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + v_class = WUFFS_JSON__LUT_CLASSES[v_c8]; + if (v_class != 0u) { + break; + } + iop_a_src += 1u; + if (v_whitespace_length >= 65534u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(65535u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_whitespace_length = 0u; + goto label__outer__continue; + } + v_whitespace_length += 1u; + } + if (v_whitespace_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_whitespace_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__outer__continue; + } + } + if (0u == (v_expect & (((uint32_t)(1u)) << v_class))) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + if (v_class == 1u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + label__string_loop_outer__continue:; + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + continue; + } + v_string_length = 0u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + } + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + goto label__string_loop_outer__continue; + } + while (((uint64_t)(io2_a_src - iop_a_src)) > 4u) { + v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + if (0u != (WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 0u))] | + WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 8u))] | + WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 16u))] | + WUFFS_JSON__LUT_CHARS[(255u & (v_c32 >> 24u))])) { + break; + } + iop_a_src += 4u; + if (v_string_length > 65527u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + goto label__string_loop_outer__continue; + } + v_string_length += 4u; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + v_char = WUFFS_JSON__LUT_CHARS[v_c8]; + if (v_char == 0u) { + iop_a_src += 1u; + if (v_string_length >= 65531u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(65532u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + goto label__string_loop_outer__continue; + } + v_string_length += 1u; + continue; + } else if (v_char == 1u) { + if (v_string_length != 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + } + goto label__string_loop_outer__break; + } else if (v_char == 2u) { + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__string_loop_outer__continue; + } + } + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + goto label__string_loop_outer__continue; + } + v_c8 = ((uint8_t)(((uint16_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)))); + v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c8]; + if (((uint8_t)(v_backslash & 128u)) != 0u) { + iop_a_src += 2u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | ((uint32_t)(((uint8_t)(v_backslash & 127u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } else if (v_backslash != 0u) { + if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[((uint8_t)(v_backslash & 7u))]]) { + iop_a_src += 2u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[((uint8_t)(v_backslash & 7u))]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + } else if (v_c8 == 117u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); + goto label__string_loop_outer__continue; + } + v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16u); + v_uni4_value = 0u; + v_uni4_ok = 128u; + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u); + if (v_uni4_ok == 0u) { + } else if ((v_uni4_value < 55296u) || (57343u < v_uni4_value)) { + iop_a_src += 6u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } else if (v_uni4_value >= 56320u) { + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) < 12u) { + if (a_src && a_src->meta.closed) { + if (self->private_impl.f_quirks[20u]) { + iop_a_src += 6u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + goto label__string_loop_outer__continue; + } + v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4u) >> 16u); + if (((255u & (v_uni4_string >> 0u)) != 92u) || ((255u & (v_uni4_string >> 8u)) != 117u)) { + v_uni4_high_surrogate = 0u; + v_uni4_value = 0u; + v_uni4_ok = 0u; + } else { + v_uni4_high_surrogate = (65536u + ((v_uni4_value - 55296u) << 10u)); + v_uni4_value = 0u; + v_uni4_ok = 128u; + v_uni4_string >>= 16u; + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))]; + v_uni4_ok &= v_c8; + v_uni4_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u); + } + if ((v_uni4_ok != 0u) && (56320u <= v_uni4_value) && (v_uni4_value <= 57343u)) { + v_uni4_value -= 56320u; + iop_a_src += 12u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(12u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + } + if (self->private_impl.f_quirks[20u]) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) { + status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); + goto exit; + } + iop_a_src += 6u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + } else if ((v_c8 == 85u) && self->private_impl.f_quirks[2u]) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 10u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + goto label__string_loop_outer__continue; + } + v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2u); + v_uni8_value = 0u; + v_uni8_ok = 128u; + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 0u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 28u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 8u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 24u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 16u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 20u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 24u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 16u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 32u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 12u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 40u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 8u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 48u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 4u); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 56u))]; + v_uni8_ok &= v_c8; + v_uni8_value |= (((uint32_t)(((uint8_t)(v_c8 & 15u)))) << 0u); + if (v_uni8_ok == 0u) { + } else if ((v_uni8_value < 55296u) || ((57343u < v_uni8_value) && (v_uni8_value <= 1114111u))) { + iop_a_src += 10u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | (v_uni8_value & 2097151u)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } else if (self->private_impl.f_quirks[20u]) { + iop_a_src += 10u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + } else if ((v_c8 == 120u) && self->private_impl.f_quirks[9u]) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + goto label__string_loop_outer__continue; + } + v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + v_backslash_x_ok = 128u; + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 16u))]; + v_backslash_x_ok &= v_c8; + v_backslash_x_value = ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 & 15u)) << 4u)))); + v_c8 = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 24u))]; + v_backslash_x_ok &= v_c8; + v_backslash_x_value = ((uint8_t)(((uint8_t)(v_backslash_x_value | ((uint8_t)(v_c8 & 15u)))))); + if ((v_backslash_x_ok == 0u) || ((v_backslash_x_string & 65535u) != 30812u)) { + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } + iop_a_src += 4u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape); + goto exit; + } else if (v_char == 3u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__string_loop_outer__continue; + } + } + if (a_src && a_src->meta.closed) { + if (self->private_impl.f_quirks[20u]) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); + goto label__string_loop_outer__continue; + } + v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + if ((v_multi_byte_utf8 & 49152u) == 32768u) { + v_multi_byte_utf8 = ((1984u & ((uint32_t)(v_multi_byte_utf8 << 6u))) | (63u & (v_multi_byte_utf8 >> 8u))); + iop_a_src += 2u; + if (v_string_length >= 65528u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_string_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + goto label__string_loop_outer__continue; + } + v_string_length += 2u; + continue; + } + } else if (v_char == 4u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__string_loop_outer__continue; + } + } + if (a_src && a_src->meta.closed) { + if (self->private_impl.f_quirks[20u]) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12); + goto label__string_loop_outer__continue; + } + v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); + if ((v_multi_byte_utf8 & 12632064u) == 8421376u) { + v_multi_byte_utf8 = ((61440u & ((uint32_t)(v_multi_byte_utf8 << 12u))) | (4032u & (v_multi_byte_utf8 >> 2u)) | (63u & (v_multi_byte_utf8 >> 16u))); + if ((2047u < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296u) || (57343u < v_multi_byte_utf8))) { + iop_a_src += 3u; + if (v_string_length >= 65528u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_string_length + 3u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + goto label__string_loop_outer__continue; + } + v_string_length += 3u; + continue; + } + } + } else if (v_char == 5u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__string_loop_outer__continue; + } + } + if (a_src && a_src->meta.closed) { + if (self->private_impl.f_quirks[20u]) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13); + goto label__string_loop_outer__continue; + } + v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + if ((v_multi_byte_utf8 & 3233857536u) == 2155905024u) { + v_multi_byte_utf8 = ((1835008u & ((uint32_t)(v_multi_byte_utf8 << 18u))) | + (258048u & ((uint32_t)(v_multi_byte_utf8 << 4u))) | + (4032u & (v_multi_byte_utf8 >> 10u)) | + (63u & (v_multi_byte_utf8 >> 24u))); + if ((65535u < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111u)) { + iop_a_src += 4u; + if (v_string_length >= 65528u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + goto label__string_loop_outer__continue; + } + v_string_length += 4u; + continue; + } + } + } + if (v_string_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_string_length = 0u; + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + goto label__string_loop_outer__continue; + } + } + if (((uint8_t)(v_char & 128u)) != 0u) { + if (self->private_impl.f_quirks[0u]) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((6291456u | ((uint32_t)(((uint8_t)(v_char & 127u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + goto label__string_loop_outer__continue; + } + if (v_char == 138u) { + status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string); + goto exit; + } + status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code); + goto exit; + } + if (self->private_impl.f_quirks[20u]) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 1u; + goto label__string_loop_outer__continue; + } + status = wuffs_base__make_status(wuffs_json__error__bad_utf_8); + goto exit; + } + } + label__string_loop_outer__break:; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14); + continue; + } + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15); + continue; + } + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + break; + } + if (0u == (v_expect & (((uint32_t)(1u)) << 4u))) { + v_expect = 4104u; + goto label__outer__continue; + } + break; + } else if (v_class == 2u) { + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (0u == (v_expect & (((uint32_t)(1u)) << 8u))) { + if (self->private_impl.f_quirks[13u]) { + v_expect = 4162u; + } else { + v_expect = 4098u; + } + } else { + if (self->private_impl.f_quirks[13u]) { + v_expect = 8114u; + } else { + v_expect = 7858u; + } + } + goto label__outer__continue; + } else if (v_class == 3u) { + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 7858u; + goto label__outer__continue; + } else if (v_class == 4u) { + while (true) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_number_length = wuffs_json__decoder__decode_number(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + v_number_status = (v_number_length >> 8u); + v_vminor = 10486787u; + if ((v_number_length & 128u) != 0u) { + v_vminor = 10486785u; + } + v_number_length = (v_number_length & 127u); + if (v_number_status == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + break; + } + while (v_number_length > 0u) { + v_number_length -= 1u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); + goto exit; + } + } + if (v_number_status == 1u) { + if (self->private_impl.f_quirks[14u]) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + break; + } + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } else if (v_number_status == 2u) { + status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17); + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18); + } + } + } + break; + } else if (v_class == 5u) { + v_vminor = 2113553u; + if (v_depth == 0u) { + } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) { + v_vminor = 2113601u; + } else { + v_vminor = 2113569u; + } + if (v_depth >= 1024u) { + status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth); + goto exit; + } + v_stack_byte = (v_depth / 32u); + v_stack_bit = (v_depth & 31u); + self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1u)) << v_stack_bit); + v_depth += 1u; + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 4162u; + v_expect_after_value = 4164u; + goto label__outer__continue; + } else if (v_class == 6u) { + iop_a_src += 1u; + if (v_depth <= 1u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2101314u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__outer__break; + } + v_depth -= 1u; + v_stack_byte = ((v_depth - 1u) / 32u); + v_stack_bit = ((v_depth - 1u) & 31u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2105410u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 4356u; + v_expect_after_value = 4356u; + } else { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2113602u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 4164u; + v_expect_after_value = 4164u; + } + goto label__outer__continue; + } else if (v_class == 7u) { + v_vminor = 2105361u; + if (v_depth == 0u) { + } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) { + v_vminor = 2105409u; + } else { + v_vminor = 2105377u; + } + if (v_depth >= 1024u) { + status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth); + goto exit; + } + v_stack_byte = (v_depth / 32u); + v_stack_bit = (v_depth & 31u); + self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(1u)) << v_stack_bit)); + v_depth += 1u; + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 8114u; + v_expect_after_value = 4356u; + goto label__outer__continue; + } else if (v_class == 8u) { + iop_a_src += 1u; + if (v_depth <= 1u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2101282u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + goto label__outer__break; + } + v_depth -= 1u; + v_stack_byte = ((v_depth - 1u) / 32u); + v_stack_bit = ((v_depth - 1u) & 31u); + if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2105378u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 4356u; + v_expect_after_value = 4356u; + } else { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2113570u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + v_expect = 4164u; + v_expect_after_value = 4164u; + } + goto label__outer__continue; + } else if (v_class == 9u) { + v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 111546413966853u); + if (v_match == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(8388612u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(5u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) { + status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); + goto exit; + } + iop_a_src += 5u; + break; + } else if (v_match == 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19); + goto label__outer__continue; + } + } else if (v_class == 10u) { + v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 435762131972u); + if (v_match == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(8388616u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); + goto exit; + } + iop_a_src += 4u; + break; + } else if (v_match == 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20); + goto label__outer__continue; + } + } else if (v_class == 11u) { + v_match = wuffs_private_impl__io_reader__match7(iop_a_src, io2_a_src, a_src, 465676103172u); + if (v_match == 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(8388610u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); + goto exit; + } + iop_a_src += 4u; + break; + } else if (v_match == 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21); + goto label__outer__continue; + } + if (self->private_impl.f_quirks[14u]) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); + status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + break; + } + } else if (v_class == 12u) { + if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u]) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); + status = wuffs_json__decoder__decode_comment(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_comment_type > 0u) { + goto label__outer__continue; + } + } + } + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + if (v_depth == 0u) { + break; + } + v_expect = v_expect_after_value; + } + label__outer__break:; + if (self->private_impl.f_quirks[17u] || self->private_impl.f_quirks[18u]) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); + status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + self->private_impl.f_end_of_data = true; + + ok: + self->private_impl.p_decode_tokens = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_tokens = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_data.s_decode_tokens.v_depth = v_depth; + self->private_data.s_decode_tokens.v_expect = v_expect; + self->private_data.s_decode_tokens.v_expect_after_value = v_expect_after_value; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func json.decoder.decode_number + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_json__decoder__decode_number( + wuffs_json__decoder* self, + wuffs_base__io_buffer* a_src) { + uint8_t v_c8 = 0; + uint32_t v_n = 0; + uint32_t v_floating_point = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + do { + v_n = 0u; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (v_c8 != 45u) { + } else { + v_n += 1u; + iop_a_src += 1u; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + v_n |= 256u; + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + } + if (v_c8 == 48u) { + v_n += 1u; + iop_a_src += 1u; + } else { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (v_n > 99u) { + break; + } + } + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (v_c8 != 46u) { + } else { + if (v_n >= 99u) { + v_n |= 512u; + break; + } + v_n += 1u; + iop_a_src += 1u; + v_floating_point = 128u; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (v_n > 99u) { + break; + } + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + } + if ((v_c8 != 69u) && (v_c8 != 101u)) { + break; + } + if (v_n >= 99u) { + v_n |= 512u; + break; + } + v_n += 1u; + iop_a_src += 1u; + v_floating_point = 128u; + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + v_n |= 256u; + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if ((v_c8 != 43u) && (v_c8 != 45u)) { + } else { + if (v_n >= 99u) { + v_n |= 512u; + break; + } + v_n += 1u; + iop_a_src += 1u; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } while (0); + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + return (v_n | v_floating_point); +} + +// -------- func json.decoder.decode_digits + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_json__decoder__decode_digits( + wuffs_json__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_n) { + uint8_t v_c8 = 0; + uint32_t v_n = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + v_n = a_n; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if ( ! (a_src && a_src->meta.closed)) { + v_n |= 768u; + } + break; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (0u == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c8]) { + break; + } + if (v_n >= 99u) { + v_n |= 512u; + break; + } + v_n += 1u; + iop_a_src += 1u; + } + if (v_n == a_n) { + v_n |= 256u; + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + return v_n; +} + +// -------- func json.decoder.decode_leading + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_leading( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_u = 0; + + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_leading; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15u]; + self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16u]; + while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + break; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + continue; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if ((v_c8 == 30u) && self->private_impl.f_allow_leading_ars) { + self->private_impl.f_allow_leading_ars = false; + iop_a_src += 1u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + continue; + } else if ((v_c8 == 239u) && self->private_impl.f_allow_leading_ubom) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { + if (a_src && a_src->meta.closed) { + break; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + continue; + } + v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); + if (v_u == 12565487u) { + self->private_impl.f_allow_leading_ubom = false; + iop_a_src += 3u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + continue; + } + } + break; + } + + ok: + self->private_impl.p_decode_leading = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_leading = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func json.decoder.decode_comment + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_comment( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint16_t v_c16 = 0; + uint32_t v_length = 0; + + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_comment; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_comment_type = 0u; + while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1u)) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(NULL); + goto ok; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } + v_c16 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + if ((v_c16 == 10799u) && self->private_impl.f_quirks[11u]) { + iop_a_src += 2u; + v_length = 2u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) { + if (v_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + } + v_length = 0u; + continue; + } + v_c16 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + if (v_c16 == 12074u) { + iop_a_src += 2u; + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)((v_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + self->private_impl.f_comment_type = 1u; + status = wuffs_base__make_status(NULL); + goto ok; + } + iop_a_src += 1u; + if (v_length >= 65533u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + } + v_length = 0u; + continue; + } + v_length += 1u; + } + } else if ((v_c16 == 12079u) && self->private_impl.f_quirks[12u]) { + iop_a_src += 2u; + v_length = 2u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + self->private_impl.f_comment_type = 2u; + status = wuffs_base__make_status(NULL); + goto ok; + } else if (v_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); + } + v_length = 0u; + continue; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (v_c8 == 10u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + self->private_impl.f_comment_type = 2u; + status = wuffs_base__make_status(NULL); + goto ok; + } + iop_a_src += 1u; + if (v_length >= 65533u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | + (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + } + v_length = 0u; + continue; + } + v_length += 1u; + } + } + + ok: + self->private_impl.p_decode_comment = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_comment = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func json.decoder.decode_inf_nan + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_inf_nan( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_c32 = 0; + uint32_t v_neg = 0; + + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } + if (((uint64_t)(io2_a_src - iop_a_src)) <= 2u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + continue; + } + v_c32 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); + if ((v_c32 | 2105376u) == 6712937u) { + if (((uint64_t)(io2_a_src - iop_a_src)) > 7u) { + if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536u) == 8751735898823356009u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(8u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 8u; + status = wuffs_base__make_status(NULL); + goto ok; + } + } else if ( ! (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + continue; + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 3u; + status = wuffs_base__make_status(NULL); + goto ok; + } else if ((v_c32 | 2105376u) == 7233902u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(10485888u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 3u; + status = wuffs_base__make_status(NULL); + goto ok; + } else if ((v_c32 & 255u) == 43u) { + v_neg = 0u; + } else if ((v_c32 & 255u) == 45u) { + v_neg = 1u; + } else { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + if (((uint64_t)(io2_a_src - iop_a_src)) <= 3u) { + if (a_src && a_src->meta.closed) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + continue; + } + v_c32 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8u); + if ((v_c32 | 2105376u) == 6712937u) { + if (((uint64_t)(io2_a_src - iop_a_src)) > 8u) { + if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1u) | 2314885530818453536u) == 8751735898823356009u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 9u; + status = wuffs_base__make_status(NULL); + goto ok; + } + } else if ( ! (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + continue; + } + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 4u; + status = wuffs_base__make_status(NULL); + goto ok; + } else if ((v_c32 | 2105376u) == 7233902u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)((10485760u | (((uint32_t)(128u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + iop_a_src += 4u; + status = wuffs_base__make_status(NULL); + goto ok; + } + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + + ok: + self->private_impl.p_decode_inf_nan = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_inf_nan = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func json.decoder.decode_trailer + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_json__decoder__decode_trailer( + wuffs_json__decoder* self, + wuffs_base__token_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_whitespace_length = 0; + + wuffs_base__token* iop_a_dst = NULL; + wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_trailer; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_quirks[18u]) { + self->private_impl.f_trailer_stop = 10u; + } else { + self->private_impl.f_trailer_stop = 0u; + } + label__outer__continue:; + while (true) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } + v_whitespace_length = 0u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (v_whitespace_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + if (a_src && a_src->meta.closed) { + goto label__outer__break; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + goto label__outer__continue; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (WUFFS_JSON__LUT_CLASSES[v_c8] != 0u) { + if (v_whitespace_length > 0u) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + } + if (self->private_impl.f_trailer_stop > 0u) { + status = wuffs_base__make_status(wuffs_json__error__bad_input); + goto exit; + } + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_json__decoder__decode_comment(self, a_dst, a_src); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_comment_type > 0u) { + goto label__outer__continue; + } + status = wuffs_base__make_status(NULL); + goto ok; + } + iop_a_src += 1u; + if ((v_whitespace_length >= 65534u) || (v_c8 == self->private_impl.f_trailer_stop)) { + *iop_a_dst++ = wuffs_base__make_token( + (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | + (((uint64_t)((v_whitespace_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + if (v_c8 == self->private_impl.f_trailer_stop) { + status = wuffs_base__make_status(NULL); + goto ok; + } + goto label__outer__continue; + } + v_whitespace_length += 1u; + } + } + label__outer__break:; + + ok: + self->private_impl.p_decode_trailer = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_trailer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) + +// ---------------- Status Codes Implementations + +const char wuffs_lzma__error__bad_lzma2_header[] = "#lzma: bad LZMA2 header"; +const char wuffs_lzma__error__bad_bitstream_trailer[] = "#lzma: bad bitstream trailer"; +const char wuffs_lzma__error__bad_code[] = "#lzma: bad code"; +const char wuffs_lzma__error__bad_decoded_length[] = "#lzma: bad decoded length"; +const char wuffs_lzma__error__bad_distance[] = "#lzma: bad distance"; +const char wuffs_lzma__error__bad_header[] = "#lzma: bad header"; +const char wuffs_lzma__error__truncated_input[] = "#lzma: truncated input"; +const char wuffs_lzma__error__unsupported_decoded_length[] = "#lzma: unsupported decoded length"; +const char wuffs_lzma__error__unsupported_properties[] = "#lzma: unsupported properties"; +const char wuffs_lzma__error__internal_error_inconsistent_i_o[] = "#lzma: internal error: inconsistent I/O"; +const char wuffs_lzma__error__internal_error_inconsistent_dictionary_state[] = "#lzma: internal error: inconsistent dictionary state"; + +// ---------------- Private Consts + +static const uint8_t +WUFFS_LZMA__STATE_TRANSITION_LITERAL[12] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 1u, 2u, 3u, 4u, + 5u, 6u, 4u, 5u, +}; + +static const uint8_t +WUFFS_LZMA__STATE_TRANSITION_MATCH[12] WUFFS_BASE__POTENTIALLY_UNUSED = { + 7u, 7u, 7u, 7u, 7u, 7u, 7u, 10u, + 10u, 10u, 10u, 10u, +}; + +static const uint8_t +WUFFS_LZMA__STATE_TRANSITION_LONGREP[12] WUFFS_BASE__POTENTIALLY_UNUSED = { + 8u, 8u, 8u, 8u, 8u, 8u, 8u, 11u, + 11u, 11u, 11u, 11u, +}; + +static const uint8_t +WUFFS_LZMA__STATE_TRANSITION_SHORTREP[12] WUFFS_BASE__POTENTIALLY_UNUSED = { + 9u, 9u, 9u, 9u, 9u, 9u, 9u, 11u, + 11u, 11u, 11u, 11u, +}; + +static const uint8_t +WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 1u, 2u, 3u, 3u, 3u, 3u, 3u, +}; + +#define WUFFS_LZMA__QUIRKS_BASE 1348001792u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream_fast( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream_slow( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__add_history( + wuffs_lzma__decoder* self, + wuffs_base__slice_u8 a_hist, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__do_transform_io( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__update_stashed_bytes( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_optional_end_of_stream( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzma__decoder__initialize_dict( + wuffs_lzma__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzma__decoder__initialize_probs( + wuffs_lzma__decoder* self); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_lzma__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzma__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_lzma__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_lzma__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_lzma__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzma__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_lzma__decoder__initialize( + wuffs_lzma__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_lzma__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_lzma__decoder* +wuffs_lzma__decoder__alloc(void) { + wuffs_lzma__decoder* x = + (wuffs_lzma__decoder*)(calloc(1, sizeof(wuffs_lzma__decoder))); + if (!x) { + return NULL; + } + if (wuffs_lzma__decoder__initialize( + x, sizeof(wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_lzma__decoder(void) { + return sizeof(wuffs_lzma__decoder); +} + +// ---------------- Function Implementations + +// -------- func lzma.decoder.decode_bitstream_fast + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream_fast( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_bits = 0; + uint32_t v_range = 0; + uint32_t v_state = 0; + uint32_t v_rep0 = 0; + uint32_t v_rep1 = 0; + uint32_t v_rep2 = 0; + uint32_t v_rep3 = 0; + uint32_t v_reptmp = 0; + uint32_t v_rep = 0; + uint64_t v_pos = 0; + uint64_t v_pos_end = 0; + uint32_t v_lc = 0; + uint64_t v_lp_mask = 0; + uint64_t v_pb_mask = 0; + uint32_t v_prob = 0; + uint32_t v_threshold = 0; + uint32_t v_tree_node = 0; + uint8_t v_prev_byte = 0; + uint32_t v_match_byte = 0; + uint32_t v_match_cusp = 0; + uint32_t v_len_state = 0; + uint32_t v_slot = 0; + uint32_t v_len = 0; + uint32_t v_lanl_offset = 0; + uint32_t v_lanl_old_offset = 0; + uint32_t v_lanl_index = 0; + uint32_t v_num_extra_bits = 0; + uint32_t v_dist_extra_bits = 0; + uint32_t v_high_bit_was_on = 0; + uint32_t v_i = 0; + uint32_t v_index_ao00 = 0; + uint32_t v_index_ao41 = 0; + uint32_t v_index_lit = 0; + uint32_t v_index_len = 0; + uint32_t v_index_small_dist_base = 0; + uint32_t v_index_small_dist_extra = 0; + uint32_t v_index_small_dist = 0; + uint32_t v_index_large_dist = 0; + uint32_t v_dist = 0; + uint32_t v_adj_dist = 0; + uint64_t v_wb_index = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + v_prev_byte = self->private_impl.f_stashed_bytes[0u]; + v_match_byte = ((uint32_t)(self->private_impl.f_stashed_bytes[1u])); + v_bits = self->private_impl.f_stashed_bits; + v_range = self->private_impl.f_stashed_range; + v_state = self->private_impl.f_stashed_state; + v_rep0 = self->private_impl.f_stashed_rep0; + v_rep1 = self->private_impl.f_stashed_rep1; + v_rep2 = self->private_impl.f_stashed_rep2; + v_rep3 = self->private_impl.f_stashed_rep3; + v_pos = self->private_impl.f_stashed_pos; + v_pos_end = self->private_impl.f_stashed_pos_end; + v_lc = self->private_impl.f_lc; + v_lp_mask = ((((uint64_t)(1u)) << self->private_impl.f_lp) - 1u); + v_pb_mask = ((((uint64_t)(1u)) << self->private_impl.f_pb) - 1u); + while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 282u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 48u)) { + if (v_pos >= v_pos_end) { + self->private_impl.f_end_of_chunk = true; + break; + } + v_index_ao00 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask)))); + v_prob = ((uint32_t)(self->private_data.f_probs_ao00[v_index_ao00])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_lit = (15u & ((((uint32_t)((v_pos & v_lp_mask))) << v_lc) | (((uint32_t)(v_prev_byte)) >> (8u - v_lc)))); + v_lanl_offset = 0u; + if (v_state >= 7u) { + v_lanl_offset = 256u; + } + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_match_byte <<= 1u; + v_lanl_old_offset = v_lanl_offset; + v_lanl_offset &= v_match_byte; + v_lanl_index = (v_lanl_offset + v_lanl_old_offset + v_tree_node); + v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_lanl_index])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_lanl_offset = ((v_lanl_offset ^ v_lanl_old_offset) & 256u); + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_prev_byte = ((uint8_t)(v_tree_node)); + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_prev_byte), iop_a_dst += 1); + v_pos += 1u; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LITERAL[v_state])); + continue; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_ao20[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len_state = ((uint32_t)(WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[(v_tree_node & 7u)])); + v_len = ((v_tree_node & 7u) + 2u); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 10u); + v_len_state = 3u; + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_high[0u][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 255u) + 18u); + v_len_state = 3u; + } while (0); + v_slot = 1u; + while (v_slot < 64u) { + v_prob = ((uint32_t)(self->private_data.f_probs_slot[v_len_state][v_slot])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob)); + v_slot = (v_slot << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob)); + v_slot = ((v_slot << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_slot &= 63u; + v_rep = v_slot; + if (v_slot < 4u) { + } else if (v_slot < 14u) { + v_num_extra_bits = ((v_slot >> 1u) - 1u); + v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits); + v_index_small_dist_base = ((uint32_t)(v_rep - v_slot)); + v_index_small_dist_extra = 1u; + v_dist_extra_bits = 0u; + v_i = 0u; + while (v_i < v_num_extra_bits) { + v_index_small_dist = (((uint32_t)(v_index_small_dist_base + v_index_small_dist_extra)) & 127u); + v_prob = ((uint32_t)(self->private_data.f_probs_small_dist[v_index_small_dist])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob)); + v_index_small_dist_extra = ((uint32_t)(v_index_small_dist_extra << 1u)); + v_i += 1u; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob)); + v_index_small_dist_extra = (((uint32_t)(v_index_small_dist_extra << 1u)) | 1u); + v_dist_extra_bits |= (((uint32_t)(1u)) << v_i); + v_i += 1u; + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_rep += v_dist_extra_bits; + } else { + v_num_extra_bits = ((v_slot >> 1u) - 1u); + v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits); + v_dist_extra_bits = 0u; + while (true) { + v_range >>= 1u; + v_bits -= v_range; + v_high_bit_was_on = ((uint32_t)(0u - (v_bits >> 31u))); + v_bits += (v_range & v_high_bit_was_on); + v_dist_extra_bits = (((uint32_t)(v_dist_extra_bits << 1u)) | (((uint32_t)(v_high_bit_was_on + 1u)) & 1u)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_num_extra_bits -= 1u; + if (v_num_extra_bits <= 4u) { + break; + } + } + v_dist_extra_bits <<= 4u; + v_index_large_dist = 1u; + while (true) { + v_prob = ((uint32_t)(self->private_data.f_probs_large_dist[v_index_large_dist])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob)); + v_index_large_dist = (15u & ((uint32_t)(v_index_large_dist << 1u))); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob)); + v_index_large_dist = (15u & (((uint32_t)(v_index_large_dist << 1u)) | 1u)); + v_dist_extra_bits |= (((uint32_t)(1u)) << (4u - v_num_extra_bits)); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_num_extra_bits -= 1u; + if (v_num_extra_bits <= 0u) { + break; + } + } + v_rep += v_dist_extra_bits; + } + if (v_rep >= 4294967295u) { + self->private_impl.f_end_of_chunk = true; + goto label__outer__break; + } + v_rep3 = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_rep; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_MATCH[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao40[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + v_index_ao41 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask)))); + v_prob = ((uint32_t)(self->private_data.f_probs_ao41[v_index_ao41])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_len = 1u; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_SHORTREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao60[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } else { + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao63[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep3; + v_rep3 = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } + } + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 2u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 10u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_high[0u][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_i_o); + goto exit; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 255u) + 18u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + } while (0); + } while (0); + v_dist = (v_rep0 + 1u); + if ((((uint64_t)(v_dist)) > v_pos) || (((uint64_t)(v_dist)) > ((uint64_t)(self->private_impl.f_dict_size)))) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_distance); + goto exit; + } + v_pos += ((uint64_t)(v_len)); + if (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_adj_dist > self->private_impl.f_dict_seen) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_distance); + goto exit; + } + v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist)))); + while (v_wb_index >= 9223372036854775808u) { + v_wb_index += ((uint64_t)(self->private_impl.f_dict_size)); + } + if (v_wb_index >= ((uint64_t)(a_workbuf.len))) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + if (v_len < v_adj_dist) { + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,(v_len + 1u), wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_match_byte = ((uint32_t)(iop_a_dst[-1])); + iop_a_dst--; + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_prev_byte = iop_a_dst[-1]; + continue; + } else if (v_len == v_adj_dist) { + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_len, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + wuffs_private_impl__io_writer__limited_copy_u32_from_history( + &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist); + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_match_byte = ((uint32_t)(iop_a_dst[-1])); + iop_a_dst--; + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_prev_byte = iop_a_dst[-1]; + continue; + } + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_adj_dist, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + v_len -= v_adj_dist; + if ((((uint64_t)(v_len)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_len + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst)))) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + } + if (v_dist >= 8u) { + v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast_return_cusp( + &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist); + v_match_byte = (v_match_cusp >> 8u); + v_prev_byte = ((uint8_t)(v_match_cusp)); + } else { + v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp( + &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist); + v_match_byte = (v_match_cusp >> 8u); + v_prev_byte = ((uint8_t)(v_match_cusp)); + } + } + label__outer__break:; + self->private_impl.f_stashed_bytes[0u] = v_prev_byte; + self->private_impl.f_stashed_bytes[1u] = ((uint8_t)(v_match_byte)); + self->private_impl.f_stashed_bits = v_bits; + self->private_impl.f_stashed_range = v_range; + self->private_impl.f_stashed_state = v_state; + self->private_impl.f_stashed_rep0 = v_rep0; + self->private_impl.f_stashed_rep1 = v_rep1; + self->private_impl.f_stashed_rep2 = v_rep2; + self->private_impl.f_stashed_rep3 = v_rep3; + self->private_impl.f_stashed_pos = v_pos; + self->private_impl.f_stashed_pos_end = v_pos_end; + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func lzma.decoder.decode_bitstream_slow + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream_slow( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_bits = 0; + uint32_t v_range = 0; + uint32_t v_state = 0; + uint32_t v_rep0 = 0; + uint32_t v_rep1 = 0; + uint32_t v_rep2 = 0; + uint32_t v_rep3 = 0; + uint32_t v_reptmp = 0; + uint32_t v_rep = 0; + uint64_t v_pos = 0; + uint64_t v_pos_end = 0; + uint32_t v_lc = 0; + uint64_t v_lp_mask = 0; + uint64_t v_pb_mask = 0; + uint32_t v_prob = 0; + uint32_t v_threshold = 0; + uint32_t v_tree_node = 0; + uint8_t v_prev_byte = 0; + uint32_t v_match_byte = 0; + uint32_t v_match_cusp = 0; + uint32_t v_len_state = 0; + uint32_t v_slot = 0; + uint32_t v_len = 0; + uint32_t v_lanl_offset = 0; + uint32_t v_lanl_old_offset = 0; + uint32_t v_lanl_index = 0; + uint32_t v_num_extra_bits = 0; + uint32_t v_dist_extra_bits = 0; + uint32_t v_high_bit_was_on = 0; + uint32_t v_i = 0; + uint32_t v_index_ao00 = 0; + uint32_t v_index_ao41 = 0; + uint32_t v_index_lit = 0; + uint32_t v_index_len = 0; + uint32_t v_index_small_dist_base = 0; + uint32_t v_index_small_dist_extra = 0; + uint32_t v_index_small_dist = 0; + uint32_t v_index_large_dist = 0; + uint32_t v_dist = 0; + uint32_t v_adj_dist = 0; + uint64_t v_wb_index = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_bitstream_slow; + if (coro_susp_point) { + v_bits = self->private_data.s_decode_bitstream_slow.v_bits; + v_range = self->private_data.s_decode_bitstream_slow.v_range; + v_state = self->private_data.s_decode_bitstream_slow.v_state; + v_rep0 = self->private_data.s_decode_bitstream_slow.v_rep0; + v_rep1 = self->private_data.s_decode_bitstream_slow.v_rep1; + v_rep2 = self->private_data.s_decode_bitstream_slow.v_rep2; + v_rep3 = self->private_data.s_decode_bitstream_slow.v_rep3; + v_rep = self->private_data.s_decode_bitstream_slow.v_rep; + v_pos = self->private_data.s_decode_bitstream_slow.v_pos; + v_pos_end = self->private_data.s_decode_bitstream_slow.v_pos_end; + v_lc = self->private_data.s_decode_bitstream_slow.v_lc; + v_lp_mask = self->private_data.s_decode_bitstream_slow.v_lp_mask; + v_pb_mask = self->private_data.s_decode_bitstream_slow.v_pb_mask; + v_tree_node = self->private_data.s_decode_bitstream_slow.v_tree_node; + v_prev_byte = self->private_data.s_decode_bitstream_slow.v_prev_byte; + v_match_byte = self->private_data.s_decode_bitstream_slow.v_match_byte; + v_len_state = self->private_data.s_decode_bitstream_slow.v_len_state; + v_slot = self->private_data.s_decode_bitstream_slow.v_slot; + v_len = self->private_data.s_decode_bitstream_slow.v_len; + v_lanl_offset = self->private_data.s_decode_bitstream_slow.v_lanl_offset; + v_num_extra_bits = self->private_data.s_decode_bitstream_slow.v_num_extra_bits; + v_dist_extra_bits = self->private_data.s_decode_bitstream_slow.v_dist_extra_bits; + v_i = self->private_data.s_decode_bitstream_slow.v_i; + v_index_lit = self->private_data.s_decode_bitstream_slow.v_index_lit; + v_index_len = self->private_data.s_decode_bitstream_slow.v_index_len; + v_index_small_dist_base = self->private_data.s_decode_bitstream_slow.v_index_small_dist_base; + v_index_small_dist_extra = self->private_data.s_decode_bitstream_slow.v_index_small_dist_extra; + v_index_large_dist = self->private_data.s_decode_bitstream_slow.v_index_large_dist; + v_dist = self->private_data.s_decode_bitstream_slow.v_dist; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + v_prev_byte = self->private_impl.f_stashed_bytes[0u]; + v_match_byte = ((uint32_t)(self->private_impl.f_stashed_bytes[1u])); + v_bits = self->private_impl.f_stashed_bits; + v_range = self->private_impl.f_stashed_range; + v_state = self->private_impl.f_stashed_state; + v_rep0 = self->private_impl.f_stashed_rep0; + v_rep1 = self->private_impl.f_stashed_rep1; + v_rep2 = self->private_impl.f_stashed_rep2; + v_rep3 = self->private_impl.f_stashed_rep3; + v_pos = self->private_impl.f_stashed_pos; + v_pos_end = self->private_impl.f_stashed_pos_end; + v_lc = self->private_impl.f_lc; + v_lp_mask = ((((uint64_t)(1u)) << self->private_impl.f_lp) - 1u); + v_pb_mask = ((((uint64_t)(1u)) << self->private_impl.f_pb) - 1u); + while ( ! (self->private_impl.p_decode_bitstream_slow != 0)) { + if (v_pos >= v_pos_end) { + self->private_impl.f_end_of_chunk = true; + break; + } + v_index_ao00 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask)))); + v_prob = ((uint32_t)(self->private_data.f_probs_ao00[v_index_ao00])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_lit = (15u & ((((uint32_t)((v_pos & v_lp_mask))) << v_lc) | (((uint32_t)(v_prev_byte)) >> (8u - v_lc)))); + if (v_state >= 7u) { + v_lanl_offset = 256u; + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_match_byte <<= 1u; + v_lanl_old_offset = v_lanl_offset; + v_lanl_offset &= v_match_byte; + v_lanl_index = (v_lanl_offset + v_lanl_old_offset + v_tree_node); + v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_lanl_index])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_lanl_offset = ((v_lanl_offset ^ v_lanl_old_offset) & 256u); + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_lanl_index] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + } else { + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_prob = ((uint32_t)(self->private_data.f_probs_lit[v_index_lit][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_lit[v_index_lit][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + } + v_prev_byte = ((uint8_t)(v_tree_node)); + self->private_data.s_decode_bitstream_slow.scratch = v_prev_byte; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (iop_a_dst == io2_a_dst) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + goto suspend; + } + *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_bitstream_slow.scratch)); + v_pos += 1u; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LITERAL[v_state])); + continue; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao00[v_index_ao00] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_ao20[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_low[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len_state = ((uint32_t)(WUFFS_LZMA__CLAMP_NO_MORE_THAN_3[(v_tree_node & 7u)])); + v_len = ((v_tree_node & 7u) + 2u); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_7 = *iop_a_src++; + v_c8 = t_7; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_8 = *iop_a_src++; + v_c8 = t_8; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_9 = *iop_a_src++; + v_c8 = t_9; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 10u); + v_len_state = 3u; + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_10 = *iop_a_src++; + v_c8 = t_10; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_prob = ((uint32_t)(self->private_data.f_probs_match_len_high[0u][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_match_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_11 = *iop_a_src++; + v_c8 = t_11; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 255u) + 18u); + v_len_state = 3u; + } while (0); + v_slot = 1u; + while (v_slot < 64u) { + v_prob = ((uint32_t)(self->private_data.f_probs_slot[v_len_state][v_slot])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob)); + v_slot = (v_slot << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_slot[v_len_state][v_slot] = ((uint16_t)(v_prob)); + v_slot = ((v_slot << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_12 = *iop_a_src++; + v_c8 = t_12; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_slot &= 63u; + v_rep = v_slot; + if (v_slot < 4u) { + } else if (v_slot < 14u) { + v_num_extra_bits = ((v_slot >> 1u) - 1u); + v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits); + v_index_small_dist_base = ((uint32_t)(v_rep - v_slot)); + v_index_small_dist_extra = 1u; + v_dist_extra_bits = 0u; + v_i = 0u; + while (v_i < v_num_extra_bits) { + v_index_small_dist = (((uint32_t)(v_index_small_dist_base + v_index_small_dist_extra)) & 127u); + v_prob = ((uint32_t)(self->private_data.f_probs_small_dist[v_index_small_dist])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob)); + v_index_small_dist_extra = ((uint32_t)(v_index_small_dist_extra << 1u)); + v_i += 1u; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_small_dist[v_index_small_dist] = ((uint16_t)(v_prob)); + v_index_small_dist_extra = (((uint32_t)(v_index_small_dist_extra << 1u)) | 1u); + v_dist_extra_bits |= (((uint32_t)(1u)) << v_i); + v_i += 1u; + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_13 = *iop_a_src++; + v_c8 = t_13; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_rep += v_dist_extra_bits; + } else { + v_num_extra_bits = ((v_slot >> 1u) - 1u); + v_rep = ((2u | (v_slot & 1u)) << v_num_extra_bits); + v_dist_extra_bits = 0u; + while (true) { + v_range >>= 1u; + v_bits -= v_range; + v_high_bit_was_on = ((uint32_t)(0u - (v_bits >> 31u))); + v_bits += (v_range & v_high_bit_was_on); + v_dist_extra_bits = (((uint32_t)(v_dist_extra_bits << 1u)) | (((uint32_t)(v_high_bit_was_on + 1u)) & 1u)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_14 = *iop_a_src++; + v_c8 = t_14; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_num_extra_bits -= 1u; + if (v_num_extra_bits <= 4u) { + break; + } + } + v_dist_extra_bits <<= 4u; + v_index_large_dist = 1u; + while (true) { + v_prob = ((uint32_t)(self->private_data.f_probs_large_dist[v_index_large_dist])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob)); + v_index_large_dist = (15u & ((uint32_t)(v_index_large_dist << 1u))); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_large_dist[v_index_large_dist] = ((uint16_t)(v_prob)); + v_index_large_dist = (15u & (((uint32_t)(v_index_large_dist << 1u)) | 1u)); + v_dist_extra_bits |= (((uint32_t)(1u)) << (4u - v_num_extra_bits)); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_15 = *iop_a_src++; + v_c8 = t_15; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_num_extra_bits -= 1u; + if (v_num_extra_bits <= 0u) { + break; + } + } + v_rep += v_dist_extra_bits; + } + if (v_rep >= 4294967295u) { + self->private_impl.f_end_of_chunk = true; + goto label__outer__break; + } + v_rep3 = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_rep; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_MATCH[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao20[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_16 = *iop_a_src++; + v_c8 = t_16; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao40[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_17 = *iop_a_src++; + v_c8 = t_17; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_ao41 = ((v_state << 4u) | ((uint32_t)((v_pos & v_pb_mask)))); + v_prob = ((uint32_t)(self->private_data.f_probs_ao41[v_index_ao41])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_18 = *iop_a_src++; + v_c8 = t_18; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_len = 1u; + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_SHORTREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao41[v_index_ao41] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_19 = *iop_a_src++; + v_c8 = t_19; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao40[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_20 = *iop_a_src++; + v_c8 = t_20; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao60[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_21 = *iop_a_src++; + v_c8 = t_21; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao60[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_22 = *iop_a_src++; + v_c8 = t_22; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_ao63[v_state])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_23 = *iop_a_src++; + v_c8 = t_23; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_ao63[v_state] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_24 = *iop_a_src++; + v_c8 = t_24; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_reptmp = v_rep3; + v_rep3 = v_rep2; + v_rep2 = v_rep1; + v_rep1 = v_rep0; + v_rep0 = v_reptmp; + } + } + } + do { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_25 = *iop_a_src++; + v_c8 = t_25; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_low[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_26 = *iop_a_src++; + v_c8 = t_26; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 2u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_low[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_27 = *iop_a_src++; + v_c8 = t_27; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[0u][0u])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_28 = *iop_a_src++; + v_c8 = t_28; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_index_len = ((uint32_t)((v_pos & v_pb_mask))); + v_tree_node = 1u; + while (v_tree_node < 8u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_mid[v_index_len][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_29 = *iop_a_src++; + v_c8 = t_29; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 7u) + 10u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + break; + } + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_mid[0u][0u] = ((uint16_t)(v_prob)); + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_30 = *iop_a_src++; + v_c8 = t_30; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + v_tree_node = 1u; + while (v_tree_node < 256u) { + v_prob = ((uint32_t)(self->private_data.f_probs_longrep_len_high[0u][v_tree_node])); + v_threshold = ((uint32_t)((v_range >> 11u) * v_prob)); + if (v_bits < v_threshold) { + v_range = v_threshold; + v_prob += (((uint32_t)(2048u - v_prob)) >> 5u); + self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = (v_tree_node << 1u); + } else { + v_bits -= v_threshold; + v_range -= v_threshold; + v_prob -= (v_prob >> 5u); + self->private_data.f_probs_longrep_len_high[0u][v_tree_node] = ((uint16_t)(v_prob)); + v_tree_node = ((v_tree_node << 1u) | 1u); + } + if ((v_range >> 24u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_31 = *iop_a_src++; + v_c8 = t_31; + } + v_bits = (((uint32_t)(v_bits << 8u)) | ((uint32_t)(v_c8))); + v_range <<= 8u; + } + } + v_len = ((v_tree_node & 255u) + 18u); + v_state = ((uint32_t)(WUFFS_LZMA__STATE_TRANSITION_LONGREP[v_state])); + } while (0); + } while (0); + v_dist = (v_rep0 + 1u); + if ((((uint64_t)(v_dist)) > v_pos) || (((uint64_t)(v_dist)) > ((uint64_t)(self->private_impl.f_dict_size)))) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_distance); + goto exit; + } + v_pos += ((uint64_t)(v_len)); + while (274u > ((uint64_t)(io2_a_dst - iop_a_dst))) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(34); + } + if (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst))) { + v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + if (v_adj_dist > self->private_impl.f_dict_seen) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_distance); + goto exit; + } + v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist)))); + while (v_wb_index >= 9223372036854775808u) { + v_wb_index += ((uint64_t)(self->private_impl.f_dict_size)); + } + if (v_wb_index >= ((uint64_t)(a_workbuf.len))) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + if (v_len < v_adj_dist) { + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,(v_len + 1u), wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_match_byte = ((uint32_t)(iop_a_dst[-1])); + iop_a_dst--; + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_prev_byte = iop_a_dst[-1]; + continue; + } else if (v_len == v_adj_dist) { + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_len, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + wuffs_private_impl__io_writer__limited_copy_u32_from_history( + &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist); + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_match_byte = ((uint32_t)(iop_a_dst[-1])); + iop_a_dst--; + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + v_prev_byte = iop_a_dst[-1]; + continue; + } + wuffs_private_impl__io_writer__limited_copy_u32_from_slice( + &iop_a_dst, io2_a_dst,v_adj_dist, wuffs_base__slice_u8__subslice_i(a_workbuf, v_wb_index)); + v_len -= v_adj_dist; + if ((((uint64_t)(v_len)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)(v_dist)) > ((uint64_t)(iop_a_dst - io0_a_dst)))) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + } + v_match_cusp = wuffs_private_impl__io_writer__limited_copy_u32_from_history_fast_return_cusp( + &iop_a_dst, io0_a_dst, io2_a_dst, v_len, v_dist); + v_match_byte = (v_match_cusp >> 8u); + v_prev_byte = ((uint8_t)(v_match_cusp)); + } + label__outer__break:; + self->private_impl.f_stashed_bytes[0u] = v_prev_byte; + self->private_impl.f_stashed_bytes[1u] = ((uint8_t)(v_match_byte)); + self->private_impl.f_stashed_bits = v_bits; + self->private_impl.f_stashed_range = v_range; + self->private_impl.f_stashed_state = v_state; + self->private_impl.f_stashed_rep0 = v_rep0; + self->private_impl.f_stashed_rep1 = v_rep1; + self->private_impl.f_stashed_rep2 = v_rep2; + self->private_impl.f_stashed_rep3 = v_rep3; + self->private_impl.f_stashed_pos = v_pos; + self->private_impl.f_stashed_pos_end = v_pos_end; + + ok: + self->private_impl.p_decode_bitstream_slow = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_bitstream_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_bitstream_slow.v_bits = v_bits; + self->private_data.s_decode_bitstream_slow.v_range = v_range; + self->private_data.s_decode_bitstream_slow.v_state = v_state; + self->private_data.s_decode_bitstream_slow.v_rep0 = v_rep0; + self->private_data.s_decode_bitstream_slow.v_rep1 = v_rep1; + self->private_data.s_decode_bitstream_slow.v_rep2 = v_rep2; + self->private_data.s_decode_bitstream_slow.v_rep3 = v_rep3; + self->private_data.s_decode_bitstream_slow.v_rep = v_rep; + self->private_data.s_decode_bitstream_slow.v_pos = v_pos; + self->private_data.s_decode_bitstream_slow.v_pos_end = v_pos_end; + self->private_data.s_decode_bitstream_slow.v_lc = v_lc; + self->private_data.s_decode_bitstream_slow.v_lp_mask = v_lp_mask; + self->private_data.s_decode_bitstream_slow.v_pb_mask = v_pb_mask; + self->private_data.s_decode_bitstream_slow.v_tree_node = v_tree_node; + self->private_data.s_decode_bitstream_slow.v_prev_byte = v_prev_byte; + self->private_data.s_decode_bitstream_slow.v_match_byte = v_match_byte; + self->private_data.s_decode_bitstream_slow.v_len_state = v_len_state; + self->private_data.s_decode_bitstream_slow.v_slot = v_slot; + self->private_data.s_decode_bitstream_slow.v_len = v_len; + self->private_data.s_decode_bitstream_slow.v_lanl_offset = v_lanl_offset; + self->private_data.s_decode_bitstream_slow.v_num_extra_bits = v_num_extra_bits; + self->private_data.s_decode_bitstream_slow.v_dist_extra_bits = v_dist_extra_bits; + self->private_data.s_decode_bitstream_slow.v_i = v_i; + self->private_data.s_decode_bitstream_slow.v_index_lit = v_index_lit; + self->private_data.s_decode_bitstream_slow.v_index_len = v_index_len; + self->private_data.s_decode_bitstream_slow.v_index_small_dist_base = v_index_small_dist_base; + self->private_data.s_decode_bitstream_slow.v_index_small_dist_extra = v_index_small_dist_extra; + self->private_data.s_decode_bitstream_slow.v_index_large_dist = v_index_large_dist; + self->private_data.s_decode_bitstream_slow.v_dist = v_dist; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func lzma.decoder.add_history + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__add_history( + wuffs_lzma__decoder* self, + wuffs_base__slice_u8 a_hist, + wuffs_base__slice_u8 a_workbuf) { + uint64_t v_dict_workbuf_index = 0; + uint64_t v_dict_size = 0; + uint64_t v_hist_length = 0; + wuffs_base__slice_u8 v_s = {0}; + uint64_t v_n_copied = 0; + uint64_t v_n = 0; + + v_dict_workbuf_index = ((uint64_t)(self->private_impl.f_dict_workbuf_index)); + v_dict_size = ((uint64_t)(self->private_impl.f_dict_size)); + if (((uint64_t)(a_hist.len)) == 0u) { + return wuffs_base__make_status(NULL); + } + if (((uint64_t)(a_workbuf.len)) < (v_dict_size + 273u)) { + return wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + } + v_hist_length = ((uint64_t)(a_hist.len)); + if (v_hist_length > 4294967295u) { + self->private_impl.f_dict_seen = 4294967295u; + } else { + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dict_seen, ((uint32_t)(v_hist_length))); + } + v_s = a_hist; + if (((uint64_t)(v_s.len)) >= v_dict_size) { + v_s = wuffs_private_impl__slice_u8__suffix(v_s, v_dict_size); + wuffs_private_impl__slice_u8__copy_from_slice(a_workbuf, v_s); + self->private_impl.f_dict_workbuf_index = 0u; + } else if (v_dict_workbuf_index > v_dict_size) { + return wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + } else { + v_n_copied = wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_ij(a_workbuf, v_dict_workbuf_index, v_dict_size), v_s); + if (v_n_copied < ((uint64_t)(v_s.len))) { + v_n = wuffs_private_impl__slice_u8__copy_from_slice(a_workbuf, wuffs_base__slice_u8__subslice_i(v_s, v_n_copied)); + self->private_impl.f_dict_workbuf_index = ((uint32_t)(v_n)); + } else { + v_n = ((uint64_t)(v_dict_workbuf_index + v_n_copied)); + if (v_n < v_dict_size) { + self->private_impl.f_dict_workbuf_index = ((uint32_t)(v_n)); + } else { + self->private_impl.f_dict_workbuf_index = 0u; + } + } + } + if ((273u > v_dict_size) || (v_dict_size > ((uint64_t)(a_workbuf.len)))) { + return wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + } + wuffs_private_impl__slice_u8__copy_from_slice(wuffs_base__slice_u8__subslice_i(a_workbuf, v_dict_size), wuffs_base__slice_u8__subslice_j(a_workbuf, 273u)); + return wuffs_base__make_status(NULL); +} + +// -------- func lzma.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_lzma__decoder__get_quirk( + const wuffs_lzma__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (a_key == 1348001792u) { + if (self->private_impl.f_allow_non_zero_initial_byte) { + return 1u; + } + } else if (a_key == 1348001793u) { + return ((uint64_t)(self->private_impl.f_format_extension)); + } + return 0u; +} + +// -------- func lzma.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzma__decoder__set_quirk( + wuffs_lzma__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + uint32_t v_v = 0; + uint32_t v_n = 0; + + if (a_key == 1348001792u) { + self->private_impl.f_allow_non_zero_initial_byte = (a_value > 0u); + } else if (a_key == 1348001793u) { + if (a_value == 0u) { + self->private_impl.f_format_extension = 0u; + return wuffs_base__make_status(NULL); + } else if ((a_value & 255u) == 1u) { + if ((a_value >> 8u) <= 255u) { + self->private_impl.f_format_extension = ((uint32_t)(a_value)); + v_v = (self->private_impl.f_format_extension >> 8u); + v_n = (((uint32_t)(1u)) << (v_v & 31u)); + wuffs_private_impl__u32__sat_sub_indirect(&v_n, ((v_n >> 4u) * ((v_v >> 5u) & 7u))); + if ((v_n < 4096u) || (536870912u < v_n)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_dict_size = v_n; + return wuffs_base__make_status(NULL); + } + } else if ((a_value & 255u) == 2u) { + if ((a_value >> 8u) <= 40u) { + self->private_impl.f_format_extension = ((uint32_t)(a_value)); + v_v = (self->private_impl.f_format_extension >> 8u); + if (v_v < 40u) { + self->private_impl.f_dict_size = ((2u | (v_v & 1u)) << ((v_v >> 1u) + 11u)); + } else { + self->private_impl.f_dict_size = 4294967295u; + } + return wuffs_base__make_status(NULL); + } + } + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func lzma.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzma__decoder__dst_history_retain_length( + const wuffs_lzma__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_base__utility__make_optional_u63(true, 0u); +} + +// -------- func lzma.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_lzma__decoder__workbuf_len( + const wuffs_lzma__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + uint64_t v_m = 0; + + if (self->private_impl.f_dict_size == 0u) { + return wuffs_base__utility__make_range_ii_u64(0u, 0u); + } + v_m = (((uint64_t)(self->private_impl.f_dict_size)) + 273u); + return wuffs_base__utility__make_range_ii_u64(v_m, v_m); +} + +// -------- func lzma.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzma__decoder__transform_io( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint64_t v_mark = 0; + wuffs_base__status v_dti_status = wuffs_base__make_status(NULL); + wuffs_base__status v_ah_status = wuffs_base__make_status(NULL); + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + + uint32_t coro_susp_point = self->private_impl.p_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + wuffs_base__status t_0 = wuffs_lzma__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + v_dti_status = t_0; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + } + if ( ! wuffs_base__status__is_suspension(&v_dti_status)) { + status = v_dti_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; + } else if ((v_dti_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_lzma__error__truncated_input); + goto exit; + } + v_ah_status = wuffs_lzma__decoder__add_history(self, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst), a_workbuf); + if (wuffs_base__status__is_error(&v_ah_status)) { + status = v_ah_status; + goto exit; + } + status = v_dti_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func lzma.decoder.do_transform_io + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__do_transform_io( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_header_byte = 0; + uint8_t v_c8 = 0; + uint32_t v_c32 = 0; + uint8_t v_prop_byte = 0; + uint32_t v_lc = 0; + uint32_t v_lp = 0; + uint32_t v_pb = 0; + uint32_t v_length = 0; + uint32_t v_n_copied = 0; + uint64_t v_smark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; + if (coro_susp_point) { + v_header_byte = self->private_data.s_do_transform_io.v_header_byte; + v_length = self->private_data.s_do_transform_io.v_length; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_lzma2_need_prob_reset = true; + self->private_impl.f_lzma2_need_properties = true; + self->private_impl.f_lzma2_need_dict_reset = true; + while (true) { + if ((self->private_impl.f_format_extension & 255u) == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_prop_byte = t_0; + } + if (v_prop_byte >= 225u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_header); + goto exit; + } + v_lc = ((uint32_t)(((uint8_t)(v_prop_byte % 9u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_prop_byte /= 9u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_lp = ((uint32_t)(((uint8_t)(v_prop_byte % 5u)))); + v_pb = ((uint32_t)(((uint8_t)(v_prop_byte / 5u)))); + if ((v_lc + v_lp) > 4u) { + status = wuffs_base__make_status(wuffs_lzma__error__unsupported_properties); + goto exit; + } + self->private_impl.f_lc = wuffs_base__u32__min(v_lc, 4u); + self->private_impl.f_lp = v_lp; + self->private_impl.f_pb = v_pb; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_c32 = t_1; + } + self->private_impl.f_dict_size = wuffs_base__u32__max(v_c32, 4096u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint64_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_2 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 56) { + t_2 = ((uint64_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + self->private_impl.f_decoded_length = t_2; + } + if ((self->private_impl.f_decoded_length >= 9223372036854775808u) && (self->private_impl.f_decoded_length != 18446744073709551615u)) { + status = wuffs_base__make_status(wuffs_lzma__error__unsupported_decoded_length); + goto exit; + } + wuffs_lzma__decoder__initialize_probs(self); + } else if ((self->private_impl.f_format_extension & 255u) == 1u) { + self->private_impl.f_lc = 3u; + self->private_impl.f_lp = 0u; + self->private_impl.f_pb = 2u; + self->private_impl.f_decoded_length = 18446744073709551615u; + wuffs_lzma__decoder__initialize_probs(self); + } else { + while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + } + if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) == 0u) { + iop_a_src += 1u; + break; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_header_byte = t_3; + } + if (v_header_byte < 128u) { + if (v_header_byte < 2u) { + self->private_impl.f_lzma2_need_prob_reset = true; + self->private_impl.f_lzma2_need_properties = true; + self->private_impl.f_lzma2_need_dict_reset = false; + wuffs_lzma__decoder__initialize_dict(self); + } else if ((v_header_byte > 2u) || self->private_impl.f_lzma2_need_dict_reset) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header); + goto exit; + } + self->private_impl.f_prev_lzma2_chunk_was_uncompressed = true; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + if (num_bits_4 == 8) { + t_4 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)); + } + } + v_c32 = t_4; + } + v_length = (1u + v_c32); + while (true) { + v_n_copied = wuffs_private_impl__io_writer__limited_copy_u32_from_reader( + &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src); + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_stashed_pos, ((uint64_t)(v_n_copied))); + if (v_length <= v_n_copied) { + break; + } + v_length -= v_n_copied; + if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + } else { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); + } + } + continue; + } + self->private_impl.f_decoded_length = ((uint64_t)(v_header_byte)); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + uint32_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); + if (num_bits_5 == 8) { + t_5 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)); + } + } + v_c32 = t_5; + } + self->private_impl.f_decoded_length = (((self->private_impl.f_decoded_length & 31u) << 16u) + ((uint64_t)((1u + v_c32)))); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + uint32_t t_6; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6); + if (num_bits_6 == 8) { + t_6 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_6 += 8u; + *scratch |= ((uint64_t)(num_bits_6)); + } + } + v_c32 = t_6; + } + self->private_impl.f_lzma2_encoded_length_want = ((uint64_t)((1u + v_c32))); + if (v_header_byte >= 160u) { + wuffs_lzma__decoder__initialize_probs(self); + self->private_impl.f_lzma2_need_prob_reset = false; + } + if (v_header_byte >= 192u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_7 = *iop_a_src++; + v_prop_byte = t_7; + } + if (v_prop_byte >= 225u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header); + goto exit; + } + v_lc = ((uint32_t)(((uint8_t)(v_prop_byte % 9u)))); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_prop_byte /= 9u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_lp = ((uint32_t)(((uint8_t)(v_prop_byte % 5u)))); + v_pb = ((uint32_t)(((uint8_t)(v_prop_byte / 5u)))); + if ((v_lc + v_lp) > 4u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header); + goto exit; + } + self->private_impl.f_lc = wuffs_base__u32__min(v_lc, 4u); + self->private_impl.f_lp = v_lp; + self->private_impl.f_pb = v_pb; + self->private_impl.f_lzma2_need_properties = false; + } + if (v_header_byte >= 224u) { + self->private_impl.f_lzma2_need_dict_reset = false; + wuffs_lzma__decoder__initialize_dict(self); + } else if (self->private_impl.f_prev_lzma2_chunk_was_uncompressed) { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); + status = wuffs_lzma__decoder__update_stashed_bytes(self, a_dst, a_workbuf); + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (status.repr) { + goto suspend; + } + } + self->private_impl.f_prev_lzma2_chunk_was_uncompressed = false; + if (self->private_impl.f_lzma2_need_prob_reset || self->private_impl.f_lzma2_need_properties || self->private_impl.f_lzma2_need_dict_reset) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header); + goto exit; + } + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_8 = *iop_a_src++; + v_c8 = t_8; + } + if ((v_c8 != 0u) && ! self->private_impl.f_allow_non_zero_initial_byte) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_code); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); + uint32_t t_9; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_9 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_9 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_9); + if (num_bits_9 == 24) { + t_9 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_9 += 8u; + *scratch |= ((uint64_t)(num_bits_9)); + } + } + self->private_impl.f_stashed_bits = t_9; + } + if (self->private_impl.f_stashed_bits == 4294967295u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_code); + goto exit; + } + self->private_impl.f_stashed_range = 4294967295u; + self->private_impl.f_stashed_pos_end = wuffs_base__u64__sat_add(self->private_impl.f_stashed_pos, self->private_impl.f_decoded_length); + if ((self->private_impl.f_stashed_pos_end == 18446744073709551615u) && (self->private_impl.f_decoded_length != 18446744073709551615u)) { + status = wuffs_base__make_status(wuffs_lzma__error__unsupported_decoded_length); + goto exit; + } + self->private_impl.f_lzma2_encoded_length_have = 5u; + while (((uint64_t)(a_workbuf.len)) < (((uint64_t)(self->private_impl.f_dict_size)) + 273u)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_workbuf); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21); + } + while (true) { + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_10 = wuffs_lzma__decoder__decode_bitstream(self, a_dst, a_src, a_workbuf); + v_status = t_10; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_lzma2_encoded_length_have, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)))); + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(22); + } + if (self->private_impl.f_decoded_length == 18446744073709551615u) { + if (self->private_impl.f_stashed_bits != 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer); + goto exit; + } + } else if (self->private_impl.f_stashed_pos != self->private_impl.f_stashed_pos_end) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_decoded_length); + goto exit; + } else if (self->private_impl.f_stashed_bits != 0u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); + status = wuffs_lzma__decoder__decode_optional_end_of_stream(self, a_src, a_workbuf); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_stashed_bits != 0u) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer); + goto exit; + } + } + if ((self->private_impl.f_format_extension & 255u) < 2u) { + break; + } else if (self->private_impl.f_lzma2_encoded_length_have != self->private_impl.f_lzma2_encoded_length_want) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_lzma2_header); + goto exit; + } + } + + ok: + self->private_impl.p_do_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_transform_io.v_header_byte = v_header_byte; + self->private_data.s_do_transform_io.v_length = v_length; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func lzma.decoder.decode_bitstream + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_bitstream( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + 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); + + uint32_t coro_susp_point = self->private_impl.p_decode_bitstream; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_end_of_chunk = false; + while (true) { + v_status = wuffs_lzma__decoder__decode_bitstream_fast(self, a_dst, a_src, a_workbuf); + if (wuffs_base__status__is_error(&v_status)) { + status = v_status; + goto exit; + } + if (self->private_impl.f_end_of_chunk) { + break; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_lzma__decoder__decode_bitstream_slow(self, a_dst, a_src, a_workbuf); + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_end_of_chunk) { + break; + } + } + + goto ok; + ok: + self->private_impl.p_decode_bitstream = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_bitstream = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func lzma.decoder.update_stashed_bytes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__update_stashed_bytes( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_dist = 0; + uint32_t v_which = 0; + uint32_t v_adj_dist = 0; + uint64_t v_wb_index = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + + uint32_t coro_susp_point = self->private_impl.p_update_stashed_bytes; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + v_dist = 1u; + v_which = 0u; + while (v_which < 2u) { + if (((uint64_t)(v_dist)) <= ((uint64_t)(iop_a_dst - io0_a_dst))) { + wuffs_private_impl__io_writer__limited_copy_u32_from_history( + &iop_a_dst, io0_a_dst, io2_a_dst, 1u, v_dist); + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + self->private_impl.f_stashed_bytes[v_which] = iop_a_dst[-1]; + iop_a_dst--; + } else { + v_adj_dist = ((uint32_t)((((uint64_t)(v_dist)) - ((uint64_t)(iop_a_dst - io0_a_dst))))); + v_wb_index = ((uint64_t)(((uint64_t)(self->private_impl.f_dict_workbuf_index)) - ((uint64_t)(v_adj_dist)))); + while (v_wb_index >= 9223372036854775808u) { + v_wb_index += ((uint64_t)(self->private_impl.f_dict_size)); + } + if (v_wb_index >= ((uint64_t)(a_workbuf.len))) { + status = wuffs_base__make_status(wuffs_lzma__error__internal_error_inconsistent_dictionary_state); + goto exit; + } + self->private_impl.f_stashed_bytes[v_which] = a_workbuf.ptr[v_wb_index]; + } + v_dist = (1u + self->private_impl.f_stashed_rep0); + v_which += 1u; + } + + ok: + self->private_impl.p_update_stashed_bytes = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_update_stashed_bytes = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + + return status; +} + +// -------- func lzma.decoder.decode_optional_end_of_stream + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzma__decoder__decode_optional_end_of_stream( + wuffs_lzma__decoder* self, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_w = &u_w; + uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_optional_end_of_stream; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_stashed_pos_end = 18446744073709551615u; + while (true) { + { + wuffs_base__io_buffer* o_0_v_w = v_w; + uint8_t* o_0_iop_v_w = iop_v_w; + uint8_t* o_0_io0_v_w = io0_v_w; + uint8_t* o_0_io1_v_w = io1_v_w; + uint8_t* o_0_io2_v_w = io2_v_w; + v_w = wuffs_private_impl__io_writer__set( + &u_w, + &iop_v_w, + &io0_v_w, + &io1_v_w, + &io2_v_w, + wuffs_base__utility__empty_slice_u8(), + 0u); + { + wuffs_base__status t_0 = wuffs_lzma__decoder__decode_bitstream_slow(self, v_w, a_src, a_workbuf); + v_status = t_0; + } + v_w = o_0_v_w; + iop_v_w = o_0_iop_v_w; + io0_v_w = o_0_io0_v_w; + io1_v_w = o_0_io1_v_w; + io2_v_w = o_0_io2_v_w; + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if (v_status.repr == wuffs_base__suspension__short_write) { + status = wuffs_base__make_status(wuffs_lzma__error__bad_bitstream_trailer); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + self->private_impl.f_stashed_pos_end = self->private_impl.f_stashed_pos; + + ok: + self->private_impl.p_decode_optional_end_of_stream = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_optional_end_of_stream = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func lzma.decoder.initialize_dict + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzma__decoder__initialize_dict( + wuffs_lzma__decoder* self) { + self->private_impl.f_dict_workbuf_index = 0u; + self->private_impl.f_dict_seen = 0u; + self->private_impl.f_stashed_bytes[0u] = 0u; + self->private_impl.f_stashed_bytes[1u] = 0u; + self->private_impl.f_stashed_pos = 0u; + return wuffs_base__make_empty_struct(); +} + +// -------- func lzma.decoder.initialize_probs + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzma__decoder__initialize_probs( + wuffs_lzma__decoder* self) { + uint32_t v_i = 0; + uint32_t v_j = 0; + + v_i = 0u; + while (v_i < 192u) { + self->private_data.f_probs_ao00[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 12u) { + self->private_data.f_probs_ao20[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 12u) { + self->private_data.f_probs_ao40[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 192u) { + self->private_data.f_probs_ao41[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 12u) { + self->private_data.f_probs_ao60[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 12u) { + self->private_data.f_probs_ao63[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + v_j = 0u; + while (v_j < 8u) { + self->private_data.f_probs_match_len_low[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + v_j = 0u; + while (v_j < 8u) { + self->private_data.f_probs_match_len_mid[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 256u) { + self->private_data.f_probs_match_len_high[0u][v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + v_j = 0u; + while (v_j < 8u) { + self->private_data.f_probs_longrep_len_low[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + v_j = 0u; + while (v_j < 8u) { + self->private_data.f_probs_longrep_len_mid[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 256u) { + self->private_data.f_probs_longrep_len_high[0u][v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 4u) { + v_j = 0u; + while (v_j < 64u) { + self->private_data.f_probs_slot[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + v_i = 0u; + while (v_i < 128u) { + self->private_data.f_probs_small_dist[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + self->private_data.f_probs_large_dist[v_i] = 1024u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 16u) { + v_j = 0u; + while (v_j < 768u) { + self->private_data.f_probs_lit[v_i][v_j] = 1024u; + v_j += 1u; + } + v_i += 1u; + } + self->private_impl.f_stashed_state = 0u; + self->private_impl.f_stashed_rep0 = 0u; + self->private_impl.f_stashed_rep1 = 0u; + self->private_impl.f_stashed_rep2 = 0u; + self->private_impl.f_stashed_rep3 = 0u; + return wuffs_base__make_empty_struct(); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZMA) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) + +// ---------------- Status Codes Implementations + +const char wuffs_lzip__error__bad_checksum[] = "#lzip: bad checksum"; +const char wuffs_lzip__error__bad_footer[] = "#lzip: bad footer"; +const char wuffs_lzip__error__bad_header[] = "#lzip: bad header"; +const char wuffs_lzip__error__truncated_input[] = "#lzip: truncated input"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzip__decoder__do_transform_io( + wuffs_lzip__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_lzip__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzip__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_lzip__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_lzip__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_lzip__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzip__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_lzip__decoder__initialize( + wuffs_lzip__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + { + wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( + &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_lzma__decoder__initialize( + &self->private_data.f_lzma, sizeof(self->private_data.f_lzma), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_lzip__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_lzip__decoder* +wuffs_lzip__decoder__alloc(void) { + wuffs_lzip__decoder* x = + (wuffs_lzip__decoder*)(calloc(1, sizeof(wuffs_lzip__decoder))); + if (!x) { + return NULL; + } + if (wuffs_lzip__decoder__initialize( + x, sizeof(wuffs_lzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_lzip__decoder(void) { + return sizeof(wuffs_lzip__decoder); +} + +// ---------------- Function Implementations + +// -------- func lzip.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_lzip__decoder__get_quirk( + const wuffs_lzip__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { + return 1u; + } + return 0u; +} + +// -------- func lzip.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzip__decoder__set_quirk( + wuffs_lzip__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + return wuffs_base__make_status(NULL); + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func lzip.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzip__decoder__dst_history_retain_length( + const wuffs_lzip__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_lzma__decoder__dst_history_retain_length(&self->private_data.f_lzma); +} + +// -------- func lzip.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_lzip__decoder__workbuf_len( + const wuffs_lzip__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_lzma__decoder__workbuf_len(&self->private_data.f_lzma); +} + +// -------- func lzip.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzip__decoder__transform_io( + wuffs_lzip__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_lzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_lzip__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func lzip.decoder.do_transform_io + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzip__decoder__do_transform_io( + wuffs_lzip__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_c32 = 0; + uint64_t v_c64 = 0; + uint64_t v_dmark = 0; + uint64_t v_smark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_checksum_want = 0; + uint32_t v_checksum_have = 0; + uint64_t v_size_want = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 5)) { + t_0 = ((uint64_t)(wuffs_base__peek_u40le__no_bounds_check(iop_a_src))); + iop_a_src += 5; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 32) { + t_0 = ((uint64_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_c64 = t_0; + } + if (v_c64 != 5641951820u) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + v_status = wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001793u, (1u | (((uint64_t)(v_c8)) << 8u))); + if ( ! wuffs_base__status__is_ok(&v_status)) { + if (v_status.repr == wuffs_base__error__bad_argument) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_header); + goto exit; + } + status = v_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; + } + self->private_impl.f_ssize_have = 0u; + self->private_impl.f_dsize_have = 0u; + wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001792u, 1u); + while (true) { + v_dmark = ((uint64_t)(iop_a_dst - io0_a_dst)); + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf); + v_status = t_2; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + self->private_impl.f_ssize_have += wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))); + self->private_impl.f_dsize_have += wuffs_private_impl__io__count_since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst))); + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; + } + } + v_checksum_want = t_3; + } + if ( ! self->private_impl.f_ignore_checksum) { + v_checksum_have = wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32); + if (v_checksum_have != v_checksum_want) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_checksum); + goto exit; + } + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint64_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_4 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 56) { + t_4 = ((uint64_t)(*scratch)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)) << 56; + } + } + v_size_want = t_4; + } + if (self->private_impl.f_dsize_have != v_size_want) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_footer); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + uint64_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_5 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5; + if (num_bits_5 == 56) { + t_5 = ((uint64_t)(*scratch)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)) << 56; + } + } + v_size_want = t_5; + } + if ((v_size_want < 26u) || (2251799813685248u < v_size_want)) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_footer); + goto exit; + } else if (self->private_impl.f_ssize_have != (v_size_want - 26u)) { + status = wuffs_base__make_status(wuffs_lzip__error__bad_footer); + goto exit; + } + while (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + if (a_src && a_src->meta.closed) { + goto label__outer__break; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); + } + v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + if (v_c32 != 1346984524u) { + break; + } + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_private_impl__ignore_status(wuffs_lzma__decoder__initialize(&self->private_data.f_lzma, + sizeof (wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + label__outer__break:; + + ok: + self->private_impl.p_do_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZIP) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) + +// ---------------- Status Codes Implementations + +const char wuffs_lzw__error__bad_code[] = "#lzw: bad code"; +const char wuffs_lzw__error__truncated_input[] = "#lzw: truncated input"; +const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O"; + +// ---------------- Private Consts + +#define WUFFS_LZW__QUIRKS_BASE 1348378624u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzw__decoder__read_from( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzw__decoder__write_to( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_dst); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_lzw__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_lzw__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_lzw__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_lzw__decoder__initialize( + wuffs_lzw__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_lzw__decoder* +wuffs_lzw__decoder__alloc(void) { + wuffs_lzw__decoder* x = + (wuffs_lzw__decoder*)(calloc(1, sizeof(wuffs_lzw__decoder))); + if (!x) { + return NULL; + } + if (wuffs_lzw__decoder__initialize( + x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_lzw__decoder(void) { + return sizeof(wuffs_lzw__decoder); +} + +// ---------------- Function Implementations + +// -------- func lzw.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_lzw__decoder__get_quirk( + const wuffs_lzw__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (a_key == 1348378624u) { + return ((uint64_t)(self->private_impl.f_pending_literal_width_plus_one)); + } + return 0u; +} + +// -------- func lzw.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzw__decoder__set_quirk( + wuffs_lzw__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (a_key == 1348378624u) { + if (a_value > 9u) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value)); + return wuffs_base__make_status(NULL); + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func lzw.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_lzw__decoder__dst_history_retain_length( + const wuffs_lzw__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_base__utility__make_optional_u63(true, 0u); +} + +// -------- func lzw.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_lzw__decoder__workbuf_len( + const wuffs_lzw__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} + +// -------- func lzw.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_lzw__decoder__transform_io( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_i = 0; + + uint32_t coro_susp_point = self->private_impl.p_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + self->private_impl.f_literal_width = 8u; + if (self->private_impl.f_pending_literal_width_plus_one > 0u) { + self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1u); + } + self->private_impl.f_clear_code = (((uint32_t)(1u)) << self->private_impl.f_literal_width); + self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1u); + self->private_impl.f_save_code = self->private_impl.f_end_code; + self->private_impl.f_prev_code = self->private_impl.f_end_code; + self->private_impl.f_width = (self->private_impl.f_literal_width + 1u); + self->private_impl.f_bits = 0u; + self->private_impl.f_n_bits = 0u; + self->private_impl.f_output_ri = 0u; + self->private_impl.f_output_wi = 0u; + v_i = 0u; + while (v_i < self->private_impl.f_clear_code) { + self->private_data.f_lm1s[v_i] = 0u; + self->private_data.f_suffixes[v_i][0u] = ((uint8_t)(v_i)); + v_i += 1u; + } + while (true) { + wuffs_lzw__decoder__read_from(self, a_src); + if (self->private_impl.f_output_wi > 0u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_lzw__decoder__write_to(self, a_dst); + if (status.repr) { + goto suspend; + } + } + if (self->private_impl.f_read_from_return_value == 0u) { + break; + } else if (self->private_impl.f_read_from_return_value == 1u) { + continue; + } else if (self->private_impl.f_read_from_return_value == 2u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } else if (self->private_impl.f_read_from_return_value == 3u) { + status = wuffs_base__make_status(wuffs_lzw__error__truncated_input); + goto exit; + } else if (self->private_impl.f_read_from_return_value == 4u) { + status = wuffs_base__make_status(wuffs_lzw__error__bad_code); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o); + goto exit; + } + } + + ok: + self->private_impl.p_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func lzw.decoder.read_from + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_lzw__decoder__read_from( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_src) { + uint32_t v_clear_code = 0; + uint32_t v_end_code = 0; + uint32_t v_save_code = 0; + uint32_t v_prev_code = 0; + uint32_t v_width = 0; + uint32_t v_bits = 0; + uint32_t v_n_bits = 0; + uint32_t v_output_wi = 0; + uint32_t v_code = 0; + uint32_t v_c = 0; + uint32_t v_o = 0; + uint32_t v_steps = 0; + uint8_t v_first_byte = 0; + uint16_t v_lm1_b = 0; + uint16_t v_lm1_a = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + v_clear_code = self->private_impl.f_clear_code; + v_end_code = self->private_impl.f_end_code; + v_save_code = self->private_impl.f_save_code; + v_prev_code = self->private_impl.f_prev_code; + v_width = self->private_impl.f_width; + v_bits = self->private_impl.f_bits; + v_n_bits = self->private_impl.f_n_bits; + v_output_wi = self->private_impl.f_output_wi; + while (true) { + if (v_n_bits < v_width) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { + v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits)); + iop_a_src += ((31u - v_n_bits) >> 3u); + v_n_bits |= 24u; + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + self->private_impl.f_read_from_return_value = 3u; + } else { + self->private_impl.f_read_from_return_value = 2u; + } + break; + } else { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + if (v_n_bits >= v_width) { + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + if (a_src && a_src->meta.closed) { + self->private_impl.f_read_from_return_value = 3u; + } else { + self->private_impl.f_read_from_return_value = 2u; + } + break; + } else { + v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); + iop_a_src += 1u; + v_n_bits += 8u; + if (v_n_bits < v_width) { + self->private_impl.f_read_from_return_value = 5u; + break; + } + } + } + } + v_code = ((v_bits) & WUFFS_PRIVATE_IMPL__LOW_BITS_MASK__U32(v_width)); + v_bits >>= v_width; + v_n_bits -= v_width; + if (v_code < v_clear_code) { + self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code)); + v_output_wi = ((v_output_wi + 1u) & 8191u); + if (v_save_code <= 4095u) { + v_lm1_a = ((uint16_t)(((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u)); + self->private_data.f_lm1s[v_save_code] = v_lm1_a; + if (((uint16_t)(v_lm1_a % 8u)) != 0u) { + self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code]; + memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code])); + self->private_data.f_suffixes[v_save_code][((uint16_t)(v_lm1_a % 8u))] = ((uint8_t)(v_code)); + } else { + self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); + self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_code)); + } + v_save_code += 1u; + if (v_width < 12u) { + v_width += (1u & (v_save_code >> v_width)); + } + v_prev_code = v_code; + } + } else if (v_code <= v_end_code) { + if (v_code == v_end_code) { + self->private_impl.f_read_from_return_value = 0u; + break; + } + v_save_code = v_end_code; + v_prev_code = v_end_code; + v_width = (self->private_impl.f_literal_width + 1u); + } else if (v_code <= v_save_code) { + v_c = v_code; + if (v_code == v_save_code) { + v_c = v_prev_code; + } + v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288u)) & 8191u); + v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191u); + v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3u); + while (true) { + memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8u); + if (v_steps <= 0u) { + break; + } + v_steps -= 1u; + v_o = (((uint32_t)(v_o - 8u)) & 8191u); + v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c])); + } + v_first_byte = self->private_data.f_suffixes[v_c][0u]; + if (v_code == v_save_code) { + self->private_data.f_output[v_output_wi] = v_first_byte; + v_output_wi = ((v_output_wi + 1u) & 8191u); + } + if (v_save_code <= 4095u) { + v_lm1_b = ((uint16_t)(((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u)); + self->private_data.f_lm1s[v_save_code] = v_lm1_b; + if (((uint16_t)(v_lm1_b % 8u)) != 0u) { + self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code]; + memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code])); + self->private_data.f_suffixes[v_save_code][((uint16_t)(v_lm1_b % 8u))] = v_first_byte; + } else { + self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); + self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte)); + } + v_save_code += 1u; + if (v_width < 12u) { + v_width += (1u & (v_save_code >> v_width)); + } + v_prev_code = v_code; + } + } else { + self->private_impl.f_read_from_return_value = 4u; + break; + } + if (v_output_wi > 4095u) { + self->private_impl.f_read_from_return_value = 1u; + break; + } + } + if (self->private_impl.f_read_from_return_value != 2u) { + while (v_n_bits >= 8u) { + v_n_bits -= 8u; + if (iop_a_src > io1_a_src) { + iop_a_src--; + } else { + self->private_impl.f_read_from_return_value = 5u; + break; + } + } + } + self->private_impl.f_save_code = v_save_code; + self->private_impl.f_prev_code = v_prev_code; + self->private_impl.f_width = v_width; + self->private_impl.f_bits = v_bits; + self->private_impl.f_n_bits = v_n_bits; + self->private_impl.f_output_wi = v_output_wi; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return wuffs_base__make_empty_struct(); +} + +// -------- func lzw.decoder.write_to + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_lzw__decoder__write_to( + wuffs_lzw__decoder* self, + wuffs_base__io_buffer* a_dst) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__slice_u8 v_s = {0}; + uint64_t v_n = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + + uint32_t coro_susp_point = self->private_impl.p_write_to; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (self->private_impl.f_output_wi > 0u) { + if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) { + status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o); + goto exit; + } + v_s = wuffs_base__make_slice_u8_ij(self->private_data.f_output, + self->private_impl.f_output_ri, + self->private_impl.f_output_wi); + v_n = wuffs_private_impl__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s); + if (v_n == ((uint64_t)(v_s.len))) { + self->private_impl.f_output_ri = 0u; + self->private_impl.f_output_wi = 0u; + status = wuffs_base__make_status(NULL); + goto ok; + } + self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)(v_n)))) & 8191u); + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_write_to = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_write_to = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + + return status; +} + +// -------- func lzw.decoder.flush + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8 +wuffs_lzw__decoder__flush( + wuffs_lzw__decoder* self) { + if (!self) { + return wuffs_base__empty_slice_u8(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__empty_slice_u8(); + } + + uint32_t v_ri = 0; + uint32_t v_wi = 0; + + v_ri = self->private_impl.f_output_ri; + v_wi = self->private_impl.f_output_wi; + self->private_impl.f_output_ri = 0u; + self->private_impl.f_output_wi = 0u; + if (v_ri <= v_wi) { + return wuffs_base__make_slice_u8_ij(self->private_data.f_output, v_ri, v_wi); + } + return wuffs_base__make_slice_u8(self->private_data.f_output, 0); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) + +// ---------------- Status Codes Implementations + +const char wuffs_netpbm__error__bad_header[] = "#netpbm: bad header"; +const char wuffs_netpbm__error__truncated_input[] = "#netpbm: truncated input"; +const char wuffs_netpbm__error__unsupported_netpbm_file[] = "#netpbm: unsupported Netpbm file"; +const char wuffs_netpbm__note__internal_note_short_read[] = "@netpbm: internal note: short read"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_image_config( + wuffs_netpbm__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_frame_config( + wuffs_netpbm__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_frame( + wuffs_netpbm__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__swizzle( + wuffs_netpbm__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_netpbm__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_netpbm__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_netpbm__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_netpbm__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_netpbm__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_netpbm__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_netpbm__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_netpbm__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_netpbm__decoder__initialize( + wuffs_netpbm__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_netpbm__decoder* +wuffs_netpbm__decoder__alloc(void) { + wuffs_netpbm__decoder* x = + (wuffs_netpbm__decoder*)(calloc(1, sizeof(wuffs_netpbm__decoder))); + if (!x) { + return NULL; + } + if (wuffs_netpbm__decoder__initialize( + x, sizeof(wuffs_netpbm__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_netpbm__decoder(void) { + return sizeof(wuffs_netpbm__decoder); +} + +// ---------------- Function Implementations + +// -------- func netpbm.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_netpbm__decoder__get_quirk( + const wuffs_netpbm__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func netpbm.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__set_quirk( + wuffs_netpbm__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func netpbm.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__decode_image_config( + wuffs_netpbm__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func netpbm.decoder.do_decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_image_config( + wuffs_netpbm__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_n = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 80u) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if ((v_c8 < 49u) || (55u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } else if (v_c8 == 53u) { + self->private_impl.f_pixfmt = 536870920u; + } else if (v_c8 == 54u) { + self->private_impl.f_pixfmt = 2684356744u; + } else { + status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (v_c8 != 10u) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if ((v_c8 == 32u) || (v_c8 == 9u)) { + continue; + } else if (v_c8 == 35u) { + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if (v_c8 == 10u) { + break; + } + } + continue; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + self->private_impl.f_width = ((uint32_t)(((uint8_t)(v_c8 - 48u)))); + break; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + if ((v_c8 == 32u) || (v_c8 == 9u)) { + break; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + v_n = ((10u * self->private_impl.f_width) + ((uint32_t)(((uint8_t)(v_c8 - 48u))))); + if (v_n > 16777215u) { + status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + goto exit; + } + self->private_impl.f_width = v_n; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + if ((v_c8 == 32u) || (v_c8 == 9u)) { + continue; + } else if (v_c8 == 35u) { + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_7 = *iop_a_src++; + v_c8 = t_7; + } + if (v_c8 == 10u) { + break; + } + } + continue; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + self->private_impl.f_height = ((uint32_t)(((uint8_t)(v_c8 - 48u)))); + break; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_8 = *iop_a_src++; + v_c8 = t_8; + } + if ((v_c8 == 32u) || (v_c8 == 9u) || (v_c8 == 13u)) { + continue; + } else if (v_c8 == 10u) { + break; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + v_n = ((10u * self->private_impl.f_height) + ((uint32_t)(((uint8_t)(v_c8 - 48u))))); + if (v_n > 16777215u) { + status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + goto exit; + } + self->private_impl.f_height = v_n; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_9 = *iop_a_src++; + v_c8 = t_9; + } + if ((v_c8 == 32u) || (v_c8 == 9u)) { + continue; + } else if (v_c8 == 35u) { + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_10 = *iop_a_src++; + v_c8 = t_10; + } + if (v_c8 == 10u) { + break; + } + } + continue; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + self->private_impl.f_max_value = ((uint32_t)(((uint8_t)(v_c8 - 48u)))); + break; + } + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_11 = *iop_a_src++; + v_c8 = t_11; + } + if ((v_c8 == 32u) || (v_c8 == 9u) || (v_c8 == 13u)) { + continue; + } else if (v_c8 == 10u) { + break; + } else if ((v_c8 < 48u) || (57u < v_c8)) { + status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + goto exit; + } + v_n = ((10u * self->private_impl.f_max_value) + ((uint32_t)(((uint8_t)(v_c8 - 48u))))); + if (v_n > 16777215u) { + status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + goto exit; + } + self->private_impl.f_max_value = v_n; + } + if (self->private_impl.f_max_value != 255u) { + status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + goto exit; + } + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + false); + } + self->private_impl.f_call_sequence = 32u; + + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func netpbm.decoder.decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__decode_frame_config( + wuffs_netpbm__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func netpbm.decoder.do_decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_frame_config( + wuffs_netpbm__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_netpbm__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + self->private_impl.f_frame_config_io_position, + 0u, + false, + false, + 0u); + } + self->private_impl.f_call_sequence = 64u; + + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func netpbm.decoder.decode_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__decode_frame( + wuffs_netpbm__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func netpbm.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__do_decode_frame( + wuffs_netpbm__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_netpbm__decoder__do_decode_frame_config(self, NULL, a_src); + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y = 0u; + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette(a_dst), + wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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_status = wuffs_netpbm__decoder__swizzle(self, a_dst, a_src); + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if (v_status.repr != wuffs_netpbm__note__internal_note_short_read) { + status = v_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; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func netpbm.decoder.swizzle + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_netpbm__decoder__swizzle( + wuffs_netpbm__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + 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_bytes_per_row = 0; + uint32_t v_src_bytes_per_pixel = 0; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_j = 0; + uint64_t v_n = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + while (true) { + if (self->private_impl.f_dst_x == self->private_impl.f_width) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += 1u; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + break; + } + } + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i >= ((uint64_t)(v_dst.len))) { + v_src_bytes_per_pixel = 1u; + if (self->private_impl.f_pixfmt == 2684356744u) { + v_src_bytes_per_pixel = 3u; + } + v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); + v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); + v_j = v_n; + while (v_j >= 8u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { + iop_a_src += (v_src_bytes_per_pixel * 8u); + } + v_j -= 8u; + } + while (v_j > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { + iop_a_src += (v_src_bytes_per_pixel * 1u); + } + v_j -= 1u; + } + } else { + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( + &self->private_impl.f_swizzler, + wuffs_base__slice_u8__subslice_i(v_dst, v_i), + wuffs_base__pixel_buffer__palette(a_dst), + &iop_a_src, + io2_a_src); + } + if (v_n == 0u) { + status = wuffs_base__make_status(wuffs_netpbm__note__internal_note_short_read); + goto ok; + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + } + status = wuffs_base__make_status(NULL); + goto ok; + + ok: + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func netpbm.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_netpbm__decoder__frame_dirty_rect( + const wuffs_netpbm__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); +} + +// -------- func netpbm.decoder.num_animation_loops + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_netpbm__decoder__num_animation_loops( + const wuffs_netpbm__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func netpbm.decoder.num_decoded_frame_configs + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_netpbm__decoder__num_decoded_frame_configs( + const wuffs_netpbm__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; +} + +// -------- func netpbm.decoder.num_decoded_frames + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_netpbm__decoder__num_decoded_frames( + const wuffs_netpbm__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; +} + +// -------- func netpbm.decoder.restart_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__restart_frame( + wuffs_netpbm__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + return wuffs_base__make_status(NULL); +} + +// -------- func netpbm.decoder.set_report_metadata + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_netpbm__decoder__set_report_metadata( + wuffs_netpbm__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func netpbm.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_netpbm__decoder__tell_me_more( + wuffs_netpbm__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + + goto ok; + ok: + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func netpbm.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_netpbm__decoder__workbuf_len( + const wuffs_netpbm__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) + +// ---------------- Status Codes Implementations + +const char wuffs_nie__error__bad_header[] = "#nie: bad header"; +const char wuffs_nie__error__truncated_input[] = "#nie: truncated input"; +const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file"; +const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_image_config( + wuffs_nie__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_frame_config( + wuffs_nie__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_frame( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__swizzle( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_nie__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_nie__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_nie__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_nie__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_nie__decoder__initialize( + wuffs_nie__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_nie__decoder* +wuffs_nie__decoder__alloc(void) { + wuffs_nie__decoder* x = + (wuffs_nie__decoder*)(calloc(1, sizeof(wuffs_nie__decoder))); + if (!x) { + return NULL; + } + if (wuffs_nie__decoder__initialize( + x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_nie__decoder(void) { + return sizeof(wuffs_nie__decoder); +} + +// ---------------- Function Implementations + +// -------- func nie.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_nie__decoder__get_quirk( + const wuffs_nie__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func nie.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__set_quirk( + wuffs_nie__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func nie.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_image_config( + wuffs_nie__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_nie__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func nie.decoder.do_decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_image_config( + wuffs_nie__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_a = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_a = t_0; + } + if (v_a != 1169146734u) { + status = wuffs_base__make_status(wuffs_nie__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_a = t_1; + } + if (v_a == 879649535u) { + self->private_impl.f_pixfmt = 2164295816u; + } else if (v_a == 946758399u) { + self->private_impl.f_pixfmt = 2164308923u; + } else if (v_a == 879780607u) { + status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file); + goto exit; + } else if (v_a == 946889471u) { + status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_nie__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + v_a = t_2; + } + if (v_a > 2147483647u) { + status = wuffs_base__make_status(wuffs_nie__error__bad_header); + goto exit; + } else if (v_a > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_width = v_a; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; + } + } + v_a = t_3; + } + if (v_a > 2147483647u) { + status = wuffs_base__make_status(wuffs_nie__error__bad_header); + goto exit; + } else if (v_a > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_height = v_a; + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + 16u, + false); + } + self->private_impl.f_call_sequence = 32u; + + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func nie.decoder.decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_frame_config( + wuffs_nie__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_nie__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func nie.decoder.do_decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_frame_config( + wuffs_nie__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_nie__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + 16u, + 0u, + false, + false, + 0u); + } + self->private_impl.f_call_sequence = 64u; + + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func nie.decoder.decode_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__decode_frame( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_nie__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func nie.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__do_decode_frame( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_nie__decoder__do_decode_frame_config(self, NULL, a_src); + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y = 0u; + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette(a_dst), + wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src); + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) { + status = v_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; + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func nie.decoder.swizzle + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_nie__decoder__swizzle( + wuffs_nie__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + 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_bytes_per_row = 0; + uint32_t v_src_bytes_per_pixel = 0; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_i = 0; + uint64_t v_j = 0; + uint64_t v_n = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + while (true) { + if (self->private_impl.f_dst_x == self->private_impl.f_width) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += 1u; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + break; + } + } + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + if (v_i >= ((uint64_t)(v_dst.len))) { + v_src_bytes_per_pixel = 4u; + if (self->private_impl.f_pixfmt == 2164308923u) { + v_src_bytes_per_pixel = 8u; + } + v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); + v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); + v_j = v_n; + while (v_j >= 8u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { + iop_a_src += (v_src_bytes_per_pixel * 8u); + } + v_j -= 8u; + } + while (v_j > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { + iop_a_src += (v_src_bytes_per_pixel * 1u); + } + v_j -= 1u; + } + } else { + v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( + &self->private_impl.f_swizzler, + wuffs_base__slice_u8__subslice_i(v_dst, v_i), + wuffs_base__pixel_buffer__palette(a_dst), + &iop_a_src, + io2_a_src); + } + if (v_n == 0u) { + status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read); + goto ok; + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + } + status = wuffs_base__make_status(NULL); + goto ok; + + ok: + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func nie.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_nie__decoder__frame_dirty_rect( + const wuffs_nie__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); +} + +// -------- func nie.decoder.num_animation_loops + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_nie__decoder__num_animation_loops( + const wuffs_nie__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func nie.decoder.num_decoded_frame_configs + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_nie__decoder__num_decoded_frame_configs( + const wuffs_nie__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; +} + +// -------- func nie.decoder.num_decoded_frames + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_nie__decoder__num_decoded_frames( + const wuffs_nie__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; +} + +// -------- func nie.decoder.restart_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__restart_frame( + wuffs_nie__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if ((a_index != 0u) || (a_io_position != 16u)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + return wuffs_base__make_status(NULL); +} + +// -------- func nie.decoder.set_report_metadata + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_nie__decoder__set_report_metadata( + wuffs_nie__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func nie.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_nie__decoder__tell_me_more( + wuffs_nie__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + + goto ok; + ok: + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func nie.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_nie__decoder__workbuf_len( + const wuffs_nie__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) + +// ---------------- Status Codes Implementations + +const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required"; +const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum"; +const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method"; +const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size"; +const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check"; +const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary"; +const char wuffs_zlib__error__truncated_input[] = "#zlib: truncated input"; + +// ---------------- Private Consts + +#define WUFFS_ZLIB__QUIRKS_BASE 2113790976u + +#define WUFFS_ZLIB__QUIRKS_COUNT 1u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_zlib__decoder__do_transform_io( + wuffs_zlib__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +// ---------------- VTables + +const wuffs_base__io_transformer__func_ptrs +wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_zlib__decoder__dst_history_retain_length), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_zlib__decoder__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_zlib__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_zlib__decoder__initialize( + wuffs_zlib__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + { + wuffs_base__status z = wuffs_adler32__hasher__initialize( + &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_adler32__hasher__initialize( + &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_deflate__decoder__initialize( + &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer); + return wuffs_base__make_status(NULL); +} + +wuffs_zlib__decoder* +wuffs_zlib__decoder__alloc(void) { + wuffs_zlib__decoder* x = + (wuffs_zlib__decoder*)(calloc(1, sizeof(wuffs_zlib__decoder))); + if (!x) { + return NULL; + } + if (wuffs_zlib__decoder__initialize( + x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_zlib__decoder(void) { + return sizeof(wuffs_zlib__decoder); +} + +// ---------------- Function Implementations + +// -------- func zlib.decoder.dictionary_id + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_zlib__decoder__dictionary_id( + const wuffs_zlib__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return self->private_impl.f_dict_id_want; +} + +// -------- func zlib.decoder.add_dictionary + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_zlib__decoder__add_dictionary( + wuffs_zlib__decoder* self, + wuffs_base__slice_u8 a_dict) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } + + if (self->private_impl.f_header_complete) { + self->private_impl.f_bad_call_sequence = true; + } else { + self->private_impl.f_dict_id_have = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict); + wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict); + } + self->private_impl.f_got_dictionary = true; + return wuffs_base__make_empty_struct(); +} + +// -------- func zlib.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_zlib__decoder__get_quirk( + const wuffs_zlib__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + uint32_t v_key = 0; + + if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { + return 1u; + } else if (a_key >= 2113790976u) { + v_key = (a_key - 2113790976u); + if (v_key < 1u) { + if (self->private_impl.f_quirks[v_key]) { + return 1u; + } + } + } + return 0u; +} + +// -------- func zlib.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_zlib__decoder__set_quirk( + wuffs_zlib__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (self->private_impl.f_header_complete) { + self->private_impl.f_bad_call_sequence = true; + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } else if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + return wuffs_base__make_status(NULL); + } else if (a_key >= 2113790976u) { + a_key -= 2113790976u; + if (a_key < 1u) { + self->private_impl.f_quirks[a_key] = (a_value > 0u); + return wuffs_base__make_status(NULL); + } + } + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func zlib.decoder.dst_history_retain_length + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_zlib__decoder__dst_history_retain_length( + const wuffs_zlib__decoder* self) { + if (!self) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_base__utility__make_optional_u63(true, 0u); +} + +// -------- func zlib.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_zlib__decoder__workbuf_len( + const wuffs_zlib__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(1u, 1u); +} + +// -------- func zlib.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_zlib__decoder__transform_io( + wuffs_zlib__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_zlib__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_zlib__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func zlib.decoder.do_transform_io + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_zlib__decoder__do_transform_io( + wuffs_zlib__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint16_t v_x = 0; + uint32_t v_checksum_have = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_checksum_want = 0; + uint64_t v_mark = 0; + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; + if (coro_susp_point) { + v_checksum_have = self->private_data.s_do_transform_io.v_checksum_have; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_bad_call_sequence) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if (self->private_impl.f_quirks[0u]) { + } else if ( ! self->private_impl.f_want_dictionary) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint16_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_number_length = wuffs_json__decoder__decode_number(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - v_number_status = (v_number_length >> 8u); - v_vminor = 10486787u; - if ((v_number_length & 128u) != 0u) { - v_vminor = 10486785u; + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_number_length = (v_number_length & 127u); - if (v_number_status == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 8) { + t_0 = ((uint16_t)(*scratch >> 48)); break; } - while (v_number_length > 0u) { - v_number_length -= 1u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); - goto exit; + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + v_x = t_0; + } + if (((uint16_t)(((uint16_t)(v_x >> 8u)) & 15u)) != 8u) { + status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method); + goto exit; + } + if (((uint16_t)(v_x >> 12u)) > 7u) { + status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size); + goto exit; + } + if (((uint16_t)(v_x % 31u)) != 0u) { + status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check); + goto exit; + } + self->private_impl.f_want_dictionary = (((uint16_t)(v_x & 32u)) != 0u); + if (self->private_impl.f_want_dictionary) { + self->private_impl.f_dict_id_have = 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - } - if (v_number_status == 1u) { - if (self->private_impl.f_quirks[14u]) { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch >> 32)); break; } - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } else if (v_number_status == 2u) { - status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17); - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18); - } - } - } - break; - } else if (v_class == 5u) { - v_vminor = 2113553u; - if (v_depth == 0u) { - } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) { - v_vminor = 2113601u; - } else { - v_vminor = 2113569u; - } - if (v_depth >= 1024u) { - status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth); - goto exit; - } - v_stack_byte = (v_depth / 32u); - v_stack_bit = (v_depth & 31u); - self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1u)) << v_stack_bit); - v_depth += 1u; - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 4162u; - v_expect_after_value = 4164u; - goto label__outer__continue; - } else if (v_class == 6u) { - iop_a_src += 1u; - if (v_depth <= 1u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2101314u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__outer__break; - } - v_depth -= 1u; - v_stack_byte = ((v_depth - 1u) / 32u); - v_stack_bit = ((v_depth - 1u) & 31u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2105410u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 4356u; - v_expect_after_value = 4356u; - } else { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2113602u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 4164u; - v_expect_after_value = 4164u; - } - goto label__outer__continue; - } else if (v_class == 7u) { - v_vminor = 2105361u; - if (v_depth == 0u) { - } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) { - v_vminor = 2105409u; - } else { - v_vminor = 2105377u; - } - if (v_depth >= 1024u) { - status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth); - goto exit; - } - v_stack_byte = (v_depth / 32u); - v_stack_bit = (v_depth & 31u); - self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(1u)) << v_stack_bit)); - v_depth += 1u; - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 8114u; - v_expect_after_value = 4356u; - goto label__outer__continue; - } else if (v_class == 8u) { - iop_a_src += 1u; - if (v_depth <= 1u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2101282u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - goto label__outer__break; - } - v_depth -= 1u; - v_stack_byte = ((v_depth - 1u) / 32u); - v_stack_bit = ((v_depth - 1u) & 31u); - if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2105378u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 4356u; - v_expect_after_value = 4356u; - } else { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2113570u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - v_expect = 4164u; - v_expect_after_value = 4164u; - } - goto label__outer__continue; - } else if (v_class == 9u) { - v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 111546413966853u); - if (v_match == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(8388612u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(5u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) { - status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); - goto exit; - } - iop_a_src += 5u; - break; - } else if (v_match == 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19); - goto label__outer__continue; - } - } else if (v_class == 10u) { - v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 435762131972u); - if (v_match == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(8388616u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); - goto exit; - } - iop_a_src += 4u; - break; - } else if (v_match == 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20); - goto label__outer__continue; - } - } else if (v_class == 11u) { - v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 465676103172u); - if (v_match == 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(8388610u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o); - goto exit; - } - iop_a_src += 4u; - break; - } else if (v_match == 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21); - goto label__outer__continue; - } - if (self->private_impl.f_quirks[14u]) { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); - status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - break; - } - } else if (v_class == 12u) { - if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u]) { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); - status = wuffs_json__decoder__decode_comment(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_comment_type > 0u) { - goto label__outer__continue; + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); } } + self->private_impl.f_dict_id_want = t_1; } - status = wuffs_base__make_status(wuffs_json__error__bad_input); + status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required); + goto ok; + } else if (self->private_impl.f_got_dictionary) { + status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary); goto exit; } - if (v_depth == 0u) { - break; + } else if (self->private_impl.f_dict_id_have != self->private_impl.f_dict_id_want) { + if (self->private_impl.f_got_dictionary) { + status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary); + goto exit; } - v_expect = v_expect_after_value; + status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required); + goto ok; } - label__outer__break:; - if (self->private_impl.f_quirks[17u] || self->private_impl.f_quirks[18u]) { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + self->private_impl.f_header_complete = true; + while (true) { + v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf); + v_status = t_2; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if ( ! self->private_impl.f_ignore_checksum && ! self->private_impl.f_quirks[0u]) { + v_checksum_have = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); - status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + if (wuffs_base__status__is_ok(&v_status)) { + break; } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + } + if ( ! self->private_impl.f_quirks[0u]) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)); + } + } + v_checksum_want = t_3; } - if (status.repr) { - goto suspend; + if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) { + status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum); + goto exit; } } - self->private_impl.f_end_of_data = true; - ok: - self->private_impl.p_decode_tokens[0] = 0; - goto exit; - } + ok: + self->private_impl.p_do_transform_io = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_transform_io.v_checksum_have = v_checksum_have; + + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) + +// ---------------- Status Codes Implementations + +const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number"; +const char wuffs_png__error__bad_checksum[] = "#png: bad checksum"; +const char wuffs_png__error__bad_chunk[] = "#png: bad chunk"; +const char wuffs_png__error__bad_filter[] = "#png: bad filter"; +const char wuffs_png__error__bad_header[] = "#png: bad header"; +const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)"; +const char wuffs_png__error__missing_palette[] = "#png: missing palette"; +const char wuffs_png__error__truncated_input[] = "#png: truncated input"; +const char wuffs_png__error__unsupported_cgbi_extension[] = "#png: unsupported CgBI extension"; +const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method"; +const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file"; +const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O"; +const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type"; +const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length"; +const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input"; + +// ---------------- Private Consts + +#define WUFFS_PNG__ANCILLARY_BIT 32u + +static const uint8_t +WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = { + { + 0u, 0u, 0u, 0u, 0u, 0u, + }, { + 3u, 7u, 0u, 3u, 7u, 0u, + }, { + 3u, 3u, 4u, 3u, 7u, 0u, + }, { + 2u, 3u, 0u, 3u, 3u, 4u, + }, { + 2u, 1u, 2u, 2u, 3u, 0u, + }, { + 1u, 1u, 0u, 2u, 1u, 2u, + }, { + 1u, 0u, 1u, 1u, 1u, 0u, + }, { + 0u, 0u, 0u, 1u, 0u, 1u, + }, +}; + +static const uint8_t +WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 255u, 85u, 0u, 17u, 0u, 0u, 0u, +}; + +static const uint8_t +WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 8u, 4u, 0u, 2u, 0u, 0u, 0u, +}; + +static const uint8_t +WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1u, 0u, 3u, 1u, 2u, 0u, 4u, 0u, +}; + +static const uint16_t +WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 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, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 41410u, 41666u, 41922u, 42178u, 42434u, 42690u, 42946u, + 43202u, 43458u, 43714u, 43970u, 44226u, 44482u, 44738u, 44994u, + 45250u, 45506u, 45762u, 46018u, 46274u, 46530u, 46786u, 47042u, + 47298u, 47554u, 47810u, 48066u, 48322u, 48578u, 48834u, 49090u, + 32963u, 33219u, 33475u, 33731u, 33987u, 34243u, 34499u, 34755u, + 35011u, 35267u, 35523u, 35779u, 36035u, 36291u, 36547u, 36803u, + 37059u, 37315u, 37571u, 37827u, 38083u, 38339u, 38595u, 38851u, + 39107u, 39363u, 39619u, 39875u, 40131u, 40387u, 40643u, 40899u, + 41155u, 41411u, 41667u, 41923u, 42179u, 42435u, 42691u, 42947u, + 43203u, 43459u, 43715u, 43971u, 44227u, 44483u, 44739u, 44995u, + 45251u, 45507u, 45763u, 46019u, 46275u, 46531u, 46787u, 47043u, + 47299u, 47555u, 47811u, 48067u, 48323u, 48579u, 48835u, 49091u, +}; + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_2( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); - goto suspend; - suspend: - self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - self->private_data.s_decode_tokens[0].v_depth = v_depth; - self->private_data.s_decode_tokens[0].v_expect = v_expect; - self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); -// -------- func json.decoder.decode_number +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_json__decoder__decode_number( - wuffs_json__decoder* self, - wuffs_base__io_buffer* a_src) { - uint8_t v_c = 0; - uint32_t v_n = 0; - uint32_t v_floating_point = 0; +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); - do { - v_n = 0u; - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - break; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (v_c != 45u) { - } else { - v_n += 1u; - iop_a_src += 1u; - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - v_n |= 256u; - break; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - } - if (v_c == 48u) { - v_n += 1u; - iop_a_src += 1u; - } else { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (v_n > 99u) { - break; - } - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - break; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (v_c != 46u) { - } else { - if (v_n >= 99u) { - v_n |= 512u; - break; - } - v_n += 1u; - iop_a_src += 1u; - v_floating_point = 128u; - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (v_n > 99u) { - break; - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - break; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - } - if ((v_c != 69u) && (v_c != 101u)) { - break; - } - if (v_n >= 99u) { - v_n |= 512u; - break; - } - v_n += 1u; - iop_a_src += 1u; - v_floating_point = 128u; - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - v_n |= 256u; - break; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if ((v_c != 43u) && (v_c != 45u)) { - } else { - if (v_n >= 99u) { - v_n |= 512u; - break; - } - v_n += 1u; - iop_a_src += 1u; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } while (0); - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - return (v_n | v_floating_point); -} +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); -// -------- func json.decoder.decode_digits +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) WUFFS_BASE__GENERATED_C_CODE -static uint32_t -wuffs_json__decoder__decode_digits( - wuffs_json__decoder* self, +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev); +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_decode_image_config( + wuffs_png__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_ihdr( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__assign_filter_distance( + wuffs_png__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static uint64_t +wuffs_png__decoder__calculate_bytes_per_row( + const wuffs_png__decoder* self, + uint32_t a_width); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__choose_filter_implementations( + wuffs_png__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_other_chunk( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src, - uint32_t a_n) { - uint8_t v_c = 0; - uint32_t v_n = 0; + bool a_framy); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_actl( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_chrm( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_exif( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_fctl( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_gama( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_iccp( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_plte( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_srgb( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_trns( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_decode_frame_config( + wuffs_png__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__skip_frame( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_decode_frame( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__decode_pass( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_tell_me_more( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle__choosy_default( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle_tricky( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_png__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_png__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_png__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_png__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_png__decoder__initialize( + wuffs_png__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); } - v_n = a_n; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if ( ! (a_src && a_src->meta.closed)) { - v_n |= 768u; - } - break; + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (0u == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) { - break; +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } - if (v_n >= 99u) { - v_n |= 512u; - break; + } + + self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default; + self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default; + self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default; + self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default; + + { + wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( + &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options); + if (z.repr) { + return z; } - v_n += 1u; - iop_a_src += 1u; } - if (v_n == a_n) { - v_n |= 256u; + { + wuffs_base__status z = wuffs_zlib__decoder__initialize( + &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options); + if (z.repr) { + return z; + } } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_png__decoder* +wuffs_png__decoder__alloc(void) { + wuffs_png__decoder* x = + (wuffs_png__decoder*)(calloc(1, sizeof(wuffs_png__decoder))); + if (!x) { + return NULL; } - return v_n; + if (wuffs_png__decoder__initialize( + x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_png__decoder(void) { + return sizeof(wuffs_png__decoder); } -// -------- func json.decoder.decode_leading +// ---------------- Function Implementations -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_leading( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +// ‼ WUFFS MULTI-FILE SECTION +arm_neon +// -------- func png.decoder.filter_1_distance_4_arm_neon - uint8_t v_c = 0; - uint32_t v_u = 0; +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + wuffs_base__slice_u8 v_curr = {0}; + uint8x8_t v_fa = {0}; + uint8x8_t v_fx = {0}; - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, v_fa); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, v_fa); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; } + v_curr.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, v_fa); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + } + v_curr.len = 0; } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +// ‼ WUFFS MULTI-FILE SECTION -arm_neon - uint32_t coro_susp_point = self->private_impl.p_decode_leading[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// ‼ WUFFS MULTI-FILE SECTION +arm_neon +// -------- func png.decoder.filter_3_distance_4_arm_neon - self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15u]; - self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16u]; - while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint8x8_t v_fa = {0}; + uint8x8_t v_fb = {0}; + uint8x8_t v_fx = {0}; + + if (((uint64_t)(a_prev.len)) == 0u) { + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - break; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - continue; + v_curr.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if ((v_c == 30u) && self->private_impl.f_allow_leading_ars) { - self->private_impl.f_allow_leading_ars = false; - iop_a_src += 1u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - continue; - } else if ((v_c == 239u) && self->private_impl.f_allow_leading_ubom) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { - if (a_src && a_src->meta.closed) { - break; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - continue; - } - v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); - if (v_u == 12565487u) { - self->private_impl.f_allow_leading_ubom = false; - iop_a_src += 3u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - continue; - } + v_curr.len = 0; + } + } else { + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; } - break; + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; + } + v_curr.len = 0; + v_prev.len = 0; } - - ok: - self->private_impl.p_decode_leading[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - - return status; + return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +// ‼ WUFFS MULTI-FILE SECTION -arm_neon -// -------- func json.decoder.decode_comment +// ‼ WUFFS MULTI-FILE SECTION +arm_neon +// -------- func png.decoder.filter_4_distance_3_arm_neon +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_comment( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - uint16_t v_c2 = 0; - uint32_t v_length = 0; +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint8x8_t v_fa = {0}; + uint8x8_t v_fb = {0}; + uint8x8_t v_fc = {0}; + uint8x8_t v_fx = {0}; + uint16x8_t v_fafb = {0}; + uint16x8_t v_fcfc = {0}; + uint16x8_t v_pa = {0}; + uint16x8_t v_pb = {0}; + uint16x8_t v_pc = {0}; + uint16x8_t v_cmpab = {0}; + uint16x8_t v_cmpac = {0}; + uint8x8_t v_picka = {0}; + uint8x8_t v_pickb = {0}; - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6)); + while (v_curr.ptr < i_end0_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 3; + v_prev.ptr += 3; + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 3; + v_prev.ptr += 3; } + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3)); + while (v_curr.ptr < i_end1_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 3; + v_prev.ptr += 3; + } + v_curr.len = 3; + v_prev.len = 3; + const uint8_t* i_end2_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end2_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_curr.ptr += 3; + v_prev.ptr += 3; + } + v_curr.len = 0; + v_prev.len = 0; } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +// ‼ WUFFS MULTI-FILE SECTION -arm_neon - uint32_t coro_susp_point = self->private_impl.p_decode_comment[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// ‼ WUFFS MULTI-FILE SECTION +arm_neon +// -------- func png.decoder.filter_4_distance_4_arm_neon - self->private_impl.f_comment_type = 0u; - while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1u)) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; - } - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(NULL); - goto ok; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - } - v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - if ((v_c2 == 10799u) && self->private_impl.f_quirks[11u]) { - iop_a_src += 2u; - v_length = 2u; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) { - if (v_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - } - v_length = 0u; - continue; - } - v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - if (v_c2 == 12074u) { - iop_a_src += 2u; - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)((v_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - self->private_impl.f_comment_type = 1u; - status = wuffs_base__make_status(NULL); - goto ok; - } - iop_a_src += 1u; - if (v_length >= 65533u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - } - v_length = 0u; - continue; - } - v_length += 1u; - } - } else if ((v_c2 == 12079u) && self->private_impl.f_quirks[12u]) { - iop_a_src += 2u; - v_length = 2u; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - self->private_impl.f_comment_type = 2u; - status = wuffs_base__make_status(NULL); - goto ok; - } else if (v_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); - } - v_length = 0u; - continue; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (v_c == 10u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - self->private_impl.f_comment_type = 2u; - status = wuffs_base__make_status(NULL); - goto ok; - } - iop_a_src += 1u; - if (v_length >= 65533u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) | - (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - } - v_length = 0u; - continue; - } - v_length += 1u; - } +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_arm_neon( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint8x8_t v_fa = {0}; + uint8x8_t v_fb = {0}; + uint8x8_t v_fc = {0}; + uint8x8_t v_fx = {0}; + uint16x8_t v_fafb = {0}; + uint16x8_t v_fcfc = {0}; + uint16x8_t v_pa = {0}; + uint16x8_t v_pb = {0}; + uint16x8_t v_pc = {0}; + uint16x8_t v_cmpab = {0}; + uint16x8_t v_cmpac = {0}; + uint8x8_t v_picka = {0}; + uint8x8_t v_pickb = {0}; + + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; } - - ok: - self->private_impl.p_decode_comment[0] = 0; - goto exit; + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_fafb = vaddl_u8(v_fa, v_fb); + v_fcfc = vaddl_u8(v_fc, v_fc); + v_pa = vabdl_u8(v_fb, v_fc); + v_pb = vabdl_u8(v_fa, v_fc); + v_pc = vabdq_u16(v_fafb, v_fcfc); + v_cmpab = vcleq_u16(v_pa, v_pb); + v_cmpac = vcleq_u16(v_pa, v_pc); + v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); + v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); + v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); + v_fc = v_fb; + v_fa = v_fx; + v_curr.ptr += 4; + v_prev.ptr += 4; + } + v_curr.len = 0; + v_prev.len = 0; } + return wuffs_base__make_empty_struct(); +} +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) +// ‼ WUFFS MULTI-FILE SECTION -arm_neon - goto suspend; - suspend: - self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; +// -------- func png.decoder.filter_1 - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + return (*self->private_impl.choosy_filter_1)(self, a_curr); +} - return status; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + uint64_t v_filter_distance = 0; + uint8_t v_fa = 0; + uint64_t v_i_start = 0; + uint64_t v_i = 0; + + v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); + v_i_start = 0u; + while (v_i_start < v_filter_distance) { + v_fa = 0u; + v_i = v_i_start; + while (v_i < ((uint64_t)(a_curr.len))) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa)); + v_fa = a_curr.ptr[v_i]; + v_i += v_filter_distance; + } + v_i_start += 1u; + } + return wuffs_base__make_empty_struct(); } -// -------- func json.decoder.decode_inf_nan +// -------- func png.decoder.filter_1_distance_3_fallback WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_inf_nan( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_c4 = 0; - uint32_t v_neg = 0; +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + wuffs_base__slice_u8 v_curr = {0}; + uint8_t v_fa0 = 0; + uint8_t v_fa1 = 0; + uint8_t v_fa2 = 0; - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 3; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; } + v_curr.len = 3; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end1_curr) { + v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + } + v_curr.len = 0; } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + return wuffs_base__make_empty_struct(); +} - uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// -------- func png.decoder.filter_1_distance_4_fallback - while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 2u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - continue; - } - v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); - if ((v_c4 | 2105376u) == 6712937u) { - if (((uint64_t)(io2_a_src - iop_a_src)) > 7u) { - if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536u) == 8751735898823356009u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(8u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 8u; - status = wuffs_base__make_status(NULL); - goto ok; - } - } else if ( ! (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - continue; - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 3u; - status = wuffs_base__make_status(NULL); - goto ok; - } else if ((v_c4 | 2105376u) == 7233902u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(10485888u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 3u; - status = wuffs_base__make_status(NULL); - goto ok; - } else if ((v_c4 & 255u) == 43u) { - v_neg = 0u; - } else if ((v_c4 & 255u) == 45u) { - v_neg = 1u; - } else { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - if (((uint64_t)(io2_a_src - iop_a_src)) <= 3u) { - if (a_src && a_src->meta.closed) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - continue; - } - v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8u); - if ((v_c4 | 2105376u) == 6712937u) { - if (((uint64_t)(io2_a_src - iop_a_src)) > 8u) { - if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1u) | 2314885530818453536u) == 8751735898823356009u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 9u; - status = wuffs_base__make_status(NULL); - goto ok; - } - } else if ( ! (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - continue; - } - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 4u; - status = wuffs_base__make_status(NULL); - goto ok; - } else if ((v_c4 | 2105376u) == 7233902u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)((10485760u | (((uint32_t)(128u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - iop_a_src += 4u; - status = wuffs_base__make_status(NULL); - goto ok; - } - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + wuffs_base__slice_u8 v_curr = {0}; + uint8_t v_fa0 = 0; + uint8_t v_fa1 = 0; + uint8_t v_fa2 = 0; + uint8_t v_fa3 = 0; - ok: - self->private_impl.p_decode_inf_nan[0] = 0; - goto exit; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3u])); + v_curr.ptr[3u] = v_fa3; + v_curr.ptr += 4; + } + v_curr.len = 0; } + return wuffs_base__make_empty_struct(); +} - goto suspend; - suspend: - self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; +// -------- func png.decoder.filter_2 - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_2( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + uint64_t v_n = 0; + uint64_t v_i = 0; - return status; + v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); + v_i = 0u; + while (v_i < v_n) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i])); + v_i += 1u; + } + return wuffs_base__make_empty_struct(); } -// -------- func json.decoder.decode_trailer +// -------- func png.decoder.filter_3 WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_json__decoder__decode_trailer( - wuffs_json__decoder* self, - wuffs_base__token_buffer* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev); +} - uint8_t v_c = 0; - uint32_t v_whitespace_length = 0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + uint64_t v_filter_distance = 0; + uint64_t v_n = 0; + uint64_t v_i = 0; - wuffs_base__token* iop_a_dst = NULL; - wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; + v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); + if (((uint64_t)(a_prev.len)) == 0u) { + v_i = v_filter_distance; + while (v_i < ((uint64_t)(a_curr.len))) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(a_curr.ptr[(v_i - v_filter_distance)] / 2u)))); + v_i += 1u; + } + } else { + v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); + v_i = 0u; + while ((v_i < v_n) && (v_i < v_filter_distance)) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(a_prev.ptr[v_i] / 2u)))); + v_i += 1u; + } + v_i = v_filter_distance; + while (v_i < v_n) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2u))))); + v_i += 1u; } } - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + return wuffs_base__make_empty_struct(); +} - uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// -------- func png.decoder.filter_3_distance_3_fallback - if (self->private_impl.f_quirks[18u]) { - self->private_impl.f_trailer_stop = 10u; - } else { - self->private_impl.f_trailer_stop = 0u; - } - label__outer__continue:; - while (true) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_3_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint8_t v_fa0 = 0; + uint8_t v_fa1 = 0; + uint8_t v_fa2 = 0; + + if (((uint64_t)(a_prev.len)) == 0u) { + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 3; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; } - v_whitespace_length = 0u; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (v_whitespace_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - if (a_src && a_src->meta.closed) { - goto label__outer__break; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - goto label__outer__continue; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (WUFFS_JSON__LUT_CLASSES[v_c] != 0u) { - if (v_whitespace_length > 0u) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - } - if (self->private_impl.f_trailer_stop > 0u) { - status = wuffs_base__make_status(wuffs_json__error__bad_input); - goto exit; - } - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_json__decoder__decode_comment(self, a_dst, a_src); - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_comment_type > 0u) { - goto label__outer__continue; - } - status = wuffs_base__make_status(NULL); - goto ok; - } - iop_a_src += 1u; - if ((v_whitespace_length >= 65534u) || (v_c == self->private_impl.f_trailer_stop)) { - *iop_a_dst++ = wuffs_base__make_token( - (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) | - (((uint64_t)((v_whitespace_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT)); - if (v_c == self->private_impl.f_trailer_stop) { - status = wuffs_base__make_status(NULL); - goto ok; - } - goto label__outer__continue; - } - v_whitespace_length += 1u; + v_curr.len = 3; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end1_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; } + v_curr.len = 0; + } + } else { + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 3; + v_prev.len = 3; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + v_prev.ptr += 3; + v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + v_prev.ptr += 3; + } + v_curr.len = 3; + v_prev.len = 3; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end1_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_curr.ptr += 3; + v_prev.ptr += 3; + } + v_curr.len = 0; + v_prev.len = 0; } - label__outer__break:; - - ok: - self->private_impl.p_decode_trailer[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - - return status; + return wuffs_base__make_empty_struct(); } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) - -// ---------------- Status Codes Implementations - -const char wuffs_lzw__error__bad_code[] = "#lzw: bad code"; -const char wuffs_lzw__error__truncated_input[] = "#lzw: truncated input"; -const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O"; - -// ---------------- Private Consts - -#define WUFFS_LZW__QUIRKS_BASE 1348378624 - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes +// -------- func png.decoder.filter_3_distance_4_fallback WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_lzw__decoder__read_from( - wuffs_lzw__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_lzw__decoder__write_to( - wuffs_lzw__decoder* self, - wuffs_base__io_buffer* a_dst); - -// ---------------- VTables - -const wuffs_base__io_transformer__func_ptrs -wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = { - (uint64_t(*)(const void*, - uint32_t))(&wuffs_lzw__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_lzw__decoder__history_retain_length), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_lzw__decoder__set_quirk), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_lzw__decoder__initialize( - wuffs_lzw__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } +wuffs_png__decoder__filter_3_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint8_t v_fa0 = 0; + uint8_t v_fa1 = 0; + uint8_t v_fa2 = 0; + uint8_t v_fa3 = 0; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + if (((uint64_t)(a_prev.len)) == 0u) { + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(v_fa0 / 2u)) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(v_fa1 / 2u)) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(v_fa2 / 2u)) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_fa3 = ((uint8_t)(((uint8_t)(v_fa3 / 2u)) + v_curr.ptr[3u])); + v_curr.ptr[3u] = v_fa3; + v_curr.ptr += 4; + } + v_curr.len = 0; } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end0_curr) { + v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); + v_curr.ptr[0u] = v_fa0; + v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); + v_curr.ptr[1u] = v_fa1; + v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); + v_curr.ptr[2u] = v_fa2; + v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3u]))) / 2u))) + v_curr.ptr[3u])); + v_curr.ptr[3u] = v_fa3; + v_curr.ptr += 4; + v_prev.ptr += 4; + } + v_curr.len = 0; + v_prev.len = 0; } } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = - wuffs_base__io_transformer__vtable_name; - self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = - (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer); - return wuffs_base__make_status(NULL); + return wuffs_base__make_empty_struct(); } -wuffs_lzw__decoder* -wuffs_lzw__decoder__alloc(void) { - wuffs_lzw__decoder* x = - (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_lzw__decoder__initialize( - x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} +// -------- func png.decoder.filter_4 -size_t -sizeof__wuffs_lzw__decoder(void) { - return sizeof(wuffs_lzw__decoder); +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev); } -// ---------------- Function Implementations - -// -------- func lzw.decoder.get_quirk - WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_lzw__decoder__get_quirk( - const wuffs_lzw__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4__choosy_default( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + uint64_t v_filter_distance = 0; + uint64_t v_n = 0; + uint64_t v_i = 0; + uint32_t v_fa = 0; + uint32_t v_fb = 0; + uint32_t v_fc = 0; + uint32_t v_pp = 0; + uint32_t v_pa = 0; + uint32_t v_pb = 0; + uint32_t v_pc = 0; - if (a_key == 1348378624u) { - return ((uint64_t)(self->private_impl.f_pending_literal_width_plus_one)); + v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); + v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); + v_i = 0u; + while ((v_i < v_n) && (v_i < v_filter_distance)) { + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i])); + v_i += 1u; } - return 0u; + v_i = v_filter_distance; + while (v_i < v_n) { + v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])); + v_fb = ((uint32_t)(a_prev.ptr[v_i])); + v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)])); + v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc)); + v_pa = ((uint32_t)(v_pp - v_fa)); + if (v_pa >= 2147483648u) { + v_pa = ((uint32_t)(0u - v_pa)); + } + v_pb = ((uint32_t)(v_pp - v_fb)); + if (v_pb >= 2147483648u) { + v_pb = ((uint32_t)(0u - v_pb)); + } + v_pc = ((uint32_t)(v_pp - v_fc)); + if (v_pc >= 2147483648u) { + v_pc = ((uint32_t)(0u - v_pc)); + } + if ((v_pa <= v_pb) && (v_pa <= v_pc)) { + } else if (v_pb <= v_pc) { + v_fa = v_fb; + } else { + v_fa = v_fc; + } + a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(v_fa)))); + v_i += 1u; + } + return wuffs_base__make_empty_struct(); } -// -------- func lzw.decoder.set_quirk +// -------- func png.decoder.filter_4_distance_3_fallback WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_lzw__decoder__set_quirk( - wuffs_lzw__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint32_t v_fa0 = 0; + uint32_t v_fa1 = 0; + uint32_t v_fa2 = 0; + uint32_t v_fb0 = 0; + uint32_t v_fb1 = 0; + uint32_t v_fb2 = 0; + uint32_t v_fc0 = 0; + uint32_t v_fc1 = 0; + uint32_t v_fc2 = 0; + uint32_t v_pp0 = 0; + uint32_t v_pp1 = 0; + uint32_t v_pp2 = 0; + uint32_t v_pa0 = 0; + uint32_t v_pa1 = 0; + uint32_t v_pa2 = 0; + uint32_t v_pb0 = 0; + uint32_t v_pb1 = 0; + uint32_t v_pb2 = 0; + uint32_t v_pc0 = 0; + uint32_t v_pc1 = 0; + uint32_t v_pc2 = 0; - if (a_key == 1348378624u) { - if (a_value > 9u) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 3; + v_prev.len = 3; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end0_curr) { + v_fb0 = ((uint32_t)(v_prev.ptr[0u])); + v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0)); + v_pa0 = ((uint32_t)(v_pp0 - v_fa0)); + if (v_pa0 >= 2147483648u) { + v_pa0 = ((uint32_t)(0u - v_pa0)); + } + v_pb0 = ((uint32_t)(v_pp0 - v_fb0)); + if (v_pb0 >= 2147483648u) { + v_pb0 = ((uint32_t)(0u - v_pb0)); + } + v_pc0 = ((uint32_t)(v_pp0 - v_fc0)); + if (v_pc0 >= 2147483648u) { + v_pc0 = ((uint32_t)(0u - v_pc0)); + } + if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) { + } else if (v_pb0 <= v_pc0) { + v_fa0 = v_fb0; + } else { + v_fa0 = v_fc0; + } + v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0)))); + v_fa0 = ((uint32_t)(v_curr.ptr[0u])); + v_fc0 = v_fb0; + v_fb1 = ((uint32_t)(v_prev.ptr[1u])); + v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1)); + v_pa1 = ((uint32_t)(v_pp1 - v_fa1)); + if (v_pa1 >= 2147483648u) { + v_pa1 = ((uint32_t)(0u - v_pa1)); + } + v_pb1 = ((uint32_t)(v_pp1 - v_fb1)); + if (v_pb1 >= 2147483648u) { + v_pb1 = ((uint32_t)(0u - v_pb1)); + } + v_pc1 = ((uint32_t)(v_pp1 - v_fc1)); + if (v_pc1 >= 2147483648u) { + v_pc1 = ((uint32_t)(0u - v_pc1)); + } + if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) { + } else if (v_pb1 <= v_pc1) { + v_fa1 = v_fb1; + } else { + v_fa1 = v_fc1; + } + v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1)))); + v_fa1 = ((uint32_t)(v_curr.ptr[1u])); + v_fc1 = v_fb1; + v_fb2 = ((uint32_t)(v_prev.ptr[2u])); + v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2)); + v_pa2 = ((uint32_t)(v_pp2 - v_fa2)); + if (v_pa2 >= 2147483648u) { + v_pa2 = ((uint32_t)(0u - v_pa2)); + } + v_pb2 = ((uint32_t)(v_pp2 - v_fb2)); + if (v_pb2 >= 2147483648u) { + v_pb2 = ((uint32_t)(0u - v_pb2)); + } + v_pc2 = ((uint32_t)(v_pp2 - v_fc2)); + if (v_pc2 >= 2147483648u) { + v_pc2 = ((uint32_t)(0u - v_pc2)); + } + if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) { + } else if (v_pb2 <= v_pc2) { + v_fa2 = v_fb2; + } else { + v_fa2 = v_fc2; + } + v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2)))); + v_fa2 = ((uint32_t)(v_curr.ptr[2u])); + v_fc2 = v_fb2; + v_curr.ptr += 3; + v_prev.ptr += 3; } - self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value)); - return wuffs_base__make_status(NULL); + v_curr.len = 0; + v_prev.len = 0; } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + return wuffs_base__make_empty_struct(); } -// -------- func lzw.decoder.history_retain_length +// -------- func png.decoder.filter_4_distance_4_fallback WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_lzw__decoder__history_retain_length( - const wuffs_lzw__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func lzw.decoder.workbuf_len +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_fallback( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + uint32_t v_fa0 = 0; + uint32_t v_fa1 = 0; + uint32_t v_fa2 = 0; + uint32_t v_fa3 = 0; + uint32_t v_fb0 = 0; + uint32_t v_fb1 = 0; + uint32_t v_fb2 = 0; + uint32_t v_fb3 = 0; + uint32_t v_fc0 = 0; + uint32_t v_fc1 = 0; + uint32_t v_fc2 = 0; + uint32_t v_fc3 = 0; + uint32_t v_pp0 = 0; + uint32_t v_pp1 = 0; + uint32_t v_pp2 = 0; + uint32_t v_pp3 = 0; + uint32_t v_pa0 = 0; + uint32_t v_pa1 = 0; + uint32_t v_pa2 = 0; + uint32_t v_pa3 = 0; + uint32_t v_pb0 = 0; + uint32_t v_pb1 = 0; + uint32_t v_pb2 = 0; + uint32_t v_pb3 = 0; + uint32_t v_pc0 = 0; + uint32_t v_pc1 = 0; + uint32_t v_pc2 = 0; + uint32_t v_pc3 = 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_lzw__decoder__workbuf_len( - const wuffs_lzw__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end0_curr) { + v_fb0 = ((uint32_t)(v_prev.ptr[0u])); + v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0)); + v_pa0 = ((uint32_t)(v_pp0 - v_fa0)); + if (v_pa0 >= 2147483648u) { + v_pa0 = ((uint32_t)(0u - v_pa0)); + } + v_pb0 = ((uint32_t)(v_pp0 - v_fb0)); + if (v_pb0 >= 2147483648u) { + v_pb0 = ((uint32_t)(0u - v_pb0)); + } + v_pc0 = ((uint32_t)(v_pp0 - v_fc0)); + if (v_pc0 >= 2147483648u) { + v_pc0 = ((uint32_t)(0u - v_pc0)); + } + if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) { + } else if (v_pb0 <= v_pc0) { + v_fa0 = v_fb0; + } else { + v_fa0 = v_fc0; + } + v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0)))); + v_fa0 = ((uint32_t)(v_curr.ptr[0u])); + v_fc0 = v_fb0; + v_fb1 = ((uint32_t)(v_prev.ptr[1u])); + v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1)); + v_pa1 = ((uint32_t)(v_pp1 - v_fa1)); + if (v_pa1 >= 2147483648u) { + v_pa1 = ((uint32_t)(0u - v_pa1)); + } + v_pb1 = ((uint32_t)(v_pp1 - v_fb1)); + if (v_pb1 >= 2147483648u) { + v_pb1 = ((uint32_t)(0u - v_pb1)); + } + v_pc1 = ((uint32_t)(v_pp1 - v_fc1)); + if (v_pc1 >= 2147483648u) { + v_pc1 = ((uint32_t)(0u - v_pc1)); + } + if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) { + } else if (v_pb1 <= v_pc1) { + v_fa1 = v_fb1; + } else { + v_fa1 = v_fc1; + } + v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1)))); + v_fa1 = ((uint32_t)(v_curr.ptr[1u])); + v_fc1 = v_fb1; + v_fb2 = ((uint32_t)(v_prev.ptr[2u])); + v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2)); + v_pa2 = ((uint32_t)(v_pp2 - v_fa2)); + if (v_pa2 >= 2147483648u) { + v_pa2 = ((uint32_t)(0u - v_pa2)); + } + v_pb2 = ((uint32_t)(v_pp2 - v_fb2)); + if (v_pb2 >= 2147483648u) { + v_pb2 = ((uint32_t)(0u - v_pb2)); + } + v_pc2 = ((uint32_t)(v_pp2 - v_fc2)); + if (v_pc2 >= 2147483648u) { + v_pc2 = ((uint32_t)(0u - v_pc2)); + } + if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) { + } else if (v_pb2 <= v_pc2) { + v_fa2 = v_fb2; + } else { + v_fa2 = v_fc2; + } + v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2)))); + v_fa2 = ((uint32_t)(v_curr.ptr[2u])); + v_fc2 = v_fb2; + v_fb3 = ((uint32_t)(v_prev.ptr[3u])); + v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3)); + v_pa3 = ((uint32_t)(v_pp3 - v_fa3)); + if (v_pa3 >= 2147483648u) { + v_pa3 = ((uint32_t)(0u - v_pa3)); + } + v_pb3 = ((uint32_t)(v_pp3 - v_fb3)); + if (v_pb3 >= 2147483648u) { + v_pb3 = ((uint32_t)(0u - v_pb3)); + } + v_pc3 = ((uint32_t)(v_pp3 - v_fc3)); + if (v_pc3 >= 2147483648u) { + v_pc3 = ((uint32_t)(0u - v_pc3)); + } + if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) { + } else if (v_pb3 <= v_pc3) { + v_fa3 = v_fb3; + } else { + v_fa3 = v_fc3; + } + v_curr.ptr[3u] = ((uint8_t)(v_curr.ptr[3u] + ((uint8_t)(v_fa3)))); + v_fa3 = ((uint32_t)(v_curr.ptr[3u])); + v_fc3 = v_fb3; + v_curr.ptr += 4; + v_prev.ptr += 4; + } + v_curr.len = 0; + v_prev.len = 0; } - - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + return wuffs_base__make_empty_struct(); } -// -------- func lzw.decoder.transform_io +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func png.decoder.filter_1_distance_4_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_lzw__decoder__transform_io( - wuffs_lzw__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_i = 0; - - uint32_t coro_susp_point = self->private_impl.p_transform_io[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +static wuffs_base__empty_struct +wuffs_png__decoder__filter_1_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr) { + wuffs_base__slice_u8 v_curr = {0}; + __m128i v_x128 = {0}; + __m128i v_a128 = {0}; - self->private_impl.f_literal_width = 8u; - if (self->private_impl.f_pending_literal_width_plus_one > 0u) { - self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1u); - } - self->private_impl.f_clear_code = (((uint32_t)(1u)) << self->private_impl.f_literal_width); - self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1u); - self->private_impl.f_save_code = self->private_impl.f_end_code; - self->private_impl.f_prev_code = self->private_impl.f_end_code; - self->private_impl.f_width = (self->private_impl.f_literal_width + 1u); - self->private_impl.f_bits = 0u; - self->private_impl.f_n_bits = 0u; - self->private_impl.f_output_ri = 0u; - self->private_impl.f_output_wi = 0u; - v_i = 0u; - while (v_i < self->private_impl.f_clear_code) { - self->private_data.f_lm1s[v_i] = 0u; - self->private_data.f_suffixes[v_i][0u] = ((uint8_t)(v_i)); - v_i += 1u; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_a128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_a128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; } - while (true) { - wuffs_lzw__decoder__read_from(self, a_src); - if (self->private_impl.f_output_wi > 0u) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_lzw__decoder__write_to(self, a_dst); - if (status.repr) { - goto suspend; - } - } - if (self->private_impl.f_read_from_return_value == 0u) { - break; - } else if (self->private_impl.f_read_from_return_value == 1u) { - continue; - } else if (self->private_impl.f_read_from_return_value == 2u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - } else if (self->private_impl.f_read_from_return_value == 3u) { - status = wuffs_base__make_status(wuffs_lzw__error__truncated_input); - goto exit; - } else if (self->private_impl.f_read_from_return_value == 4u) { - status = wuffs_base__make_status(wuffs_lzw__error__bad_code); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o); - goto exit; - } + v_curr.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_a128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; } - - ok: - self->private_impl.p_transform_io[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + v_curr.len = 0; } - return status; + return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// -------- func lzw.decoder.read_from +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func png.decoder.filter_3_distance_4_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_lzw__decoder__read_from( - wuffs_lzw__decoder* self, - wuffs_base__io_buffer* a_src) { - uint32_t v_clear_code = 0; - uint32_t v_end_code = 0; - uint32_t v_save_code = 0; - uint32_t v_prev_code = 0; - uint32_t v_width = 0; - uint32_t v_bits = 0; - uint32_t v_n_bits = 0; - uint32_t v_output_wi = 0; - uint32_t v_code = 0; - uint32_t v_c = 0; - uint32_t v_o = 0; - uint32_t v_steps = 0; - uint8_t v_first_byte = 0; - uint16_t v_lm1_b = 0; - uint16_t v_lm1_a = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +wuffs_png__decoder__filter_3_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + __m128i v_x128 = {0}; + __m128i v_a128 = {0}; + __m128i v_b128 = {0}; + __m128i v_p128 = {0}; + __m128i v_k128 = {0}; - v_clear_code = self->private_impl.f_clear_code; - v_end_code = self->private_impl.f_end_code; - v_save_code = self->private_impl.f_save_code; - v_prev_code = self->private_impl.f_prev_code; - v_width = self->private_impl.f_width; - v_bits = self->private_impl.f_bits; - v_n_bits = self->private_impl.f_n_bits; - v_output_wi = self->private_impl.f_output_wi; - while (true) { - if (v_n_bits < v_width) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) { - v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits)); - iop_a_src += ((31u - v_n_bits) >> 3u); - v_n_bits |= 24u; - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - self->private_impl.f_read_from_return_value = 3u; - } else { - self->private_impl.f_read_from_return_value = 2u; - } - break; - } else { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - if (v_n_bits >= v_width) { - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - if (a_src && a_src->meta.closed) { - self->private_impl.f_read_from_return_value = 3u; - } else { - self->private_impl.f_read_from_return_value = 2u; - } - break; - } else { - v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits); - iop_a_src += 1u; - v_n_bits += 8u; - if (v_n_bits < v_width) { - self->private_impl.f_read_from_return_value = 5u; - break; - } - } - } - } - v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width)); - v_bits >>= v_width; - v_n_bits -= v_width; - if (v_code < v_clear_code) { - self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code)); - v_output_wi = ((v_output_wi + 1u) & 8191u); - if (v_save_code <= 4095u) { - v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u); - self->private_data.f_lm1s[v_save_code] = v_lm1_a; - if ((v_lm1_a % 8u) != 0u) { - self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code]; - memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code])); - self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code)); - } else { - self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); - self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_code)); - } - v_save_code += 1u; - if (v_width < 12u) { - v_width += (1u & (v_save_code >> v_width)); - } - v_prev_code = v_code; - } - } else if (v_code <= v_end_code) { - if (v_code == v_end_code) { - self->private_impl.f_read_from_return_value = 0u; - break; - } - v_save_code = v_end_code; - v_prev_code = v_end_code; - v_width = (self->private_impl.f_literal_width + 1u); - } else if (v_code <= v_save_code) { - v_c = v_code; - if (v_code == v_save_code) { - v_c = v_prev_code; - } - v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288u)) & 8191u); - v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191u); - v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3u); - while (true) { - memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8u); - if (v_steps <= 0u) { - break; - } - v_steps -= 1u; - v_o = (((uint32_t)(v_o - 8u)) & 8191u); - v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c])); - } - v_first_byte = self->private_data.f_suffixes[v_c][0u]; - if (v_code == v_save_code) { - self->private_data.f_output[v_output_wi] = v_first_byte; - v_output_wi = ((v_output_wi + 1u) & 8191u); + if (((uint64_t)(a_prev.len)) == 0u) { + v_k128 = _mm_set1_epi8((int8_t)(254u)); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + v_curr.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; } - if (v_save_code <= 4095u) { - v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u); - self->private_data.f_lm1s[v_save_code] = v_lm1_b; - if ((v_lm1_b % 8u) != 0u) { - self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code]; - memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code])); - self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte; - } else { - self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code)); - self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte)); - } - v_save_code += 1u; - if (v_width < 12u) { - v_width += (1u & (v_save_code >> v_width)); - } - v_prev_code = v_code; + v_curr.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; } - } else { - self->private_impl.f_read_from_return_value = 4u; - break; - } - if (v_output_wi > 4095u) { - self->private_impl.f_read_from_return_value = 1u; - break; + v_curr.len = 0; } - } - if (self->private_impl.f_read_from_return_value != 2u) { - while (v_n_bits >= 8u) { - v_n_bits -= 8u; - if (iop_a_src > io1_a_src) { - iop_a_src--; - } else { - self->private_impl.f_read_from_return_value = 5u; - break; + } else { + v_k128 = _mm_set1_epi8((int8_t)(1u)); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_p128 = _mm_avg_epu8(v_a128, v_b128); + v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_p128 = _mm_avg_epu8(v_a128, v_b128); + v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; + } + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_p128 = _mm_avg_epu8(v_a128, v_b128); + v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; } + v_curr.len = 0; + v_prev.len = 0; } } - self->private_impl.f_save_code = v_save_code; - self->private_impl.f_prev_code = v_prev_code; - self->private_impl.f_width = v_width; - self->private_impl.f_bits = v_bits; - self->private_impl.f_n_bits = v_n_bits; - self->private_impl.f_output_wi = v_output_wi; - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// -------- func lzw.decoder.write_to +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func png.decoder.filter_4_distance_3_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_lzw__decoder__write_to( - wuffs_lzw__decoder* self, - wuffs_base__io_buffer* a_dst) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__slice_u8 v_s = {0}; - uint64_t v_n = 0; +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_3_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + __m128i v_x128 = {0}; + __m128i v_a128 = {0}; + __m128i v_b128 = {0}; + __m128i v_c128 = {0}; + __m128i v_p128 = {0}; + __m128i v_pa128 = {0}; + __m128i v_pb128 = {0}; + __m128i v_pc128 = {0}; + __m128i v_smallest128 = {0}; + __m128i v_z128 = {0}; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6)); + while (v_curr.ptr < i_end0_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 3; + v_prev.ptr += 3; + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 3; + v_prev.ptr += 3; } - } - - uint32_t coro_susp_point = self->private_impl.p_write_to[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (self->private_impl.f_output_wi > 0u) { - if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) { - status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o); - goto exit; - } - v_s = wuffs_base__make_slice_u8_ij(self->private_data.f_output, - self->private_impl.f_output_ri, - self->private_impl.f_output_wi); - v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s); - if (v_n == ((uint64_t)(v_s.len))) { - self->private_impl.f_output_ri = 0u; - self->private_impl.f_output_wi = 0u; - status = wuffs_base__make_status(NULL); - goto ok; - } - self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)(v_n)))) & 8191u); - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, wuffs_private_impl__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3)); + while (v_curr.ptr < i_end1_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 3; + v_prev.ptr += 3; } - - ok: - self->private_impl.p_write_to[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - - return status; -} - -// -------- func lzw.decoder.flush - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8 -wuffs_lzw__decoder__flush( - wuffs_lzw__decoder* self) { - if (!self) { - return wuffs_base__make_slice_u8(NULL, 0); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_slice_u8(NULL, 0); - } - - uint32_t v_ri = 0; - uint32_t v_wi = 0; - - v_ri = self->private_impl.f_output_ri; - v_wi = self->private_impl.f_output_wi; - self->private_impl.f_output_ri = 0u; - self->private_impl.f_output_wi = 0u; - if (v_ri <= v_wi) { - return wuffs_base__make_slice_u8_ij(self->private_data.f_output, v_ri, v_wi); + v_curr.len = 3; + v_prev.len = 3; + const uint8_t* i_end2_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3)); + while (v_curr.ptr < i_end2_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 3; + v_prev.ptr += 3; + } + v_curr.len = 0; + v_prev.len = 0; } - return wuffs_base__make_slice_u8(self->private_data.f_output, 0); + return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) - -// ---------------- Status Codes Implementations - -const char wuffs_netpbm__error__bad_header[] = "#netpbm: bad header"; -const char wuffs_netpbm__error__truncated_input[] = "#netpbm: truncated input"; -const char wuffs_netpbm__error__unsupported_netpbm_file[] = "#netpbm: unsupported Netpbm file"; -const char wuffs_netpbm__note__internal_note_short_read[] = "@netpbm: internal note: short read"; - -// ---------------- Private Consts - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_netpbm__decoder__do_decode_image_config( - wuffs_netpbm__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_netpbm__decoder__do_decode_frame_config( - wuffs_netpbm__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_netpbm__decoder__do_decode_frame( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); +// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 +// -------- func png.decoder.filter_4_distance_4_x86_sse42 +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_netpbm__decoder__swizzle( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -// ---------------- VTables - -const wuffs_base__image_decoder__func_ptrs -wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_netpbm__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_netpbm__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_netpbm__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_netpbm__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_netpbm__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_netpbm__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_netpbm__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_netpbm__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_netpbm__decoder__initialize( - wuffs_netpbm__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } +static wuffs_base__empty_struct +wuffs_png__decoder__filter_4_distance_4_x86_sse42( + wuffs_png__decoder* self, + wuffs_base__slice_u8 a_curr, + wuffs_base__slice_u8 a_prev) { + wuffs_base__slice_u8 v_curr = {0}; + wuffs_base__slice_u8 v_prev = {0}; + __m128i v_x128 = {0}; + __m128i v_a128 = {0}; + __m128i v_b128 = {0}; + __m128i v_c128 = {0}; + __m128i v_p128 = {0}; + __m128i v_pa128 = {0}; + __m128i v_pb128 = {0}; + __m128i v_pc128 = {0}; + __m128i v_smallest128 = {0}; + __m128i v_z128 = {0}; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + { + wuffs_base__slice_u8 i_slice_curr = a_curr; + v_curr.ptr = i_slice_curr.ptr; + wuffs_base__slice_u8 i_slice_prev = a_prev; + v_prev.ptr = i_slice_prev.ptr; + i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end0_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8)); + while (v_curr.ptr < i_end0_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + v_curr.len = 4; + v_prev.len = 4; + const uint8_t* i_end1_curr = wuffs_private_impl__ptr_u8_plus_len(v_curr.ptr, (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4)); + while (v_curr.ptr < i_end1_curr) { + v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); + v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); + v_pa128 = _mm_sub_epi16(v_b128, v_c128); + v_pb128 = _mm_sub_epi16(v_a128, v_c128); + v_pc128 = _mm_add_epi16(v_pa128, v_pb128); + v_pa128 = _mm_abs_epi16(v_pa128); + v_pb128 = _mm_abs_epi16(v_pb128); + v_pc128 = _mm_abs_epi16(v_pc128); + v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); + v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); + v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); + v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); + v_x128 = _mm_add_epi8(v_x128, v_p128); + v_a128 = v_x128; + v_c128 = v_b128; + v_x128 = _mm_packus_epi16(v_x128, v_x128); + wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); + v_curr.ptr += 4; + v_prev.ptr += 4; } + v_curr.len = 0; + v_prev.len = 0; } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); -} - -wuffs_netpbm__decoder* -wuffs_netpbm__decoder__alloc(void) { - wuffs_netpbm__decoder* x = - (wuffs_netpbm__decoder*)(calloc(sizeof(wuffs_netpbm__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_netpbm__decoder__initialize( - x, sizeof(wuffs_netpbm__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} - -size_t -sizeof__wuffs_netpbm__decoder(void) { - return sizeof(wuffs_netpbm__decoder); + return wuffs_base__make_empty_struct(); } +#endif // defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) +// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// ---------------- Function Implementations - -// -------- func netpbm.decoder.get_quirk +// -------- func png.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__get_quirk( - const wuffs_netpbm__decoder* self, +wuffs_png__decoder__get_quirk( + const wuffs_png__decoder* self, uint32_t a_key) { if (!self) { return 0; @@ -49804,15 +62628,18 @@ wuffs_netpbm__decoder__get_quirk( return 0; } + if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { + return 1u; + } return 0u; } -// -------- func netpbm.decoder.set_quirk +// -------- func png.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__set_quirk( - wuffs_netpbm__decoder* self, +wuffs_png__decoder__set_quirk( + wuffs_png__decoder* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -49825,15 +62652,20 @@ wuffs_netpbm__decoder__set_quirk( : wuffs_base__error__initialize_not_called); } + if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, a_key, a_value); + return wuffs_base__make_status(NULL); + } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func netpbm.decoder.decode_image_config +// -------- func png.decoder.decode_image_config WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_image_config( - wuffs_netpbm__decoder* self, +wuffs_png__decoder__decode_image_config( + wuffs_png__decoder* self, wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { if (!self) { @@ -49859,53 +62691,364 @@ wuffs_netpbm__decoder__decode_image_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_png__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_png__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func png.decoder.do_decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_decode_image_config( + wuffs_png__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint64_t v_magic = 0; + uint64_t v_mark = 0; + uint32_t v_checksum_have = 0; + uint32_t v_checksum_want = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + if (coro_susp_point) { + v_checksum_have = self->private_data.s_do_decode_image_config.v_checksum_have; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if ( ! self->private_impl.f_seen_ihdr) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 56) { + t_0 = ((uint64_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_magic = t_0; + } + if (v_magic != 727905341920923785u) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint64_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 56) { + t_1 = ((uint64_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_magic = t_1; + } + if (v_magic != 5927942488114331648u) { + if (v_magic == 5278895250759221248u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_cgbi_extension); + goto exit; + } + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; + } + self->private_impl.f_chunk_type_array[0u] = 73u; + self->private_impl.f_chunk_type_array[1u] = 72u; + self->private_impl.f_chunk_type_array[2u] = 68u; + self->private_impl.f_chunk_type_array[3u] = 82u; + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); + while (true) { + v_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src); + v_status = t_2; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if ( ! self->private_impl.f_ignore_checksum) { + v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)); + } + } + v_checksum_want = t_3; + } + if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) { + status = wuffs_base__make_status(wuffs_png__error__bad_checksum); + goto exit; + } + self->private_impl.f_seen_ihdr = true; + } else if (self->private_impl.f_metadata_fourcc != 0u) { + self->private_impl.f_call_sequence = 16u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; + } while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + continue; + } + self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); + if (self->private_impl.f_chunk_type == 1413563465u) { + if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) { + break; + } + self->private_impl.f_seen_idat = true; + } else if (self->private_impl.f_chunk_type == 1413571686u) { + if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) { + break; + } + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + iop_a_src += 8u; + if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) { + self->private_impl.f_chunk_type_array[0u] = ((uint8_t)((self->private_impl.f_chunk_type >> 0u))); + self->private_impl.f_chunk_type_array[1u] = ((uint8_t)((self->private_impl.f_chunk_type >> 8u))); + self->private_impl.f_chunk_type_array[2u] = ((uint8_t)((self->private_impl.f_chunk_type >> 16u))); + self->private_impl.f_chunk_type_array[3u] = ((uint8_t)((self->private_impl.f_chunk_type >> 24u))); + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); + } + while (true) { + v_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src, false); + v_status = t_4; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) { + v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + } + if (self->private_impl.f_metadata_fourcc != 0u) { + self->private_impl.f_call_sequence = 16u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; + } { - wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + uint32_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); + if (num_bits_5 == 24) { + t_5 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)); + } + } + v_checksum_want = t_5; } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); + if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u) && (v_checksum_have != v_checksum_want)) { + status = wuffs_base__make_status(wuffs_png__error__bad_checksum); goto exit; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } + if ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte) { + status = wuffs_base__make_status(wuffs_png__error__missing_palette); + goto exit; + } + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position; + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_dst_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_first_config_io_position, + ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns)); + } + if ( ! self->private_impl.f_seen_actl) { + self->private_impl.f_num_animation_frames_value = 1u; + self->private_impl.f_first_rect_x0 = 0u; + self->private_impl.f_first_rect_y0 = 0u; + self->private_impl.f_first_rect_x1 = self->private_impl.f_width; + self->private_impl.f_first_rect_y1 = self->private_impl.f_height; + self->private_impl.f_first_duration = 0u; + self->private_impl.f_first_disposal = 0u; + self->private_impl.f_first_overwrite_instead_of_blend = false; + } + self->private_impl.f_call_sequence = 32u; ok: - self->private_impl.p_decode_image_config[0] = 0; + self->private_impl.p_do_decode_image_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_image_config.v_checksum_have = v_checksum_have; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func netpbm.decoder.do_decode_image_config +// -------- func png.decoder.decode_ihdr WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_netpbm__decoder__do_decode_image_config( - wuffs_netpbm__decoder* self, - wuffs_base__image_config* a_dst, +wuffs_png__decoder__decode_ihdr( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint32_t v_n = 0; + uint32_t v_a32 = 0; + uint8_t v_a8 = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -49918,348 +63061,343 @@ wuffs_netpbm__decoder__do_decode_image_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_ihdr; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_ihdr.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_ihdr.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + v_a32 = t_0; + } + if ((v_a32 == 0u) || (v_a32 > 2147483647u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; + } else if (v_a32 > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); goto exit; } + self->private_impl.f_width = v_a32; { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_ihdr.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_ihdr.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); + } + } + v_a32 = t_1; + } + if ((v_a32 == 0u) || (v_a32 > 2147483647u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; + } else if (v_a32 > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_height = v_a32; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; + uint8_t t_2 = *iop_a_src++; + v_a8 = t_2; } - if (v_c != 80u) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + if (v_a8 > 16u) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); goto exit; } + self->private_impl.f_depth = v_a8; { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; + uint8_t t_3 = *iop_a_src++; + v_a8 = t_3; } - if ((v_c < 49u) || (55u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; - } else if (v_c == 53u) { - self->private_impl.f_pixfmt = 536870920u; - } else if (v_c == 54u) { - self->private_impl.f_pixfmt = 2684356744u; - } else { - status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); + if ((v_a8 == 1u) || (v_a8 == 5u) || (v_a8 > 6u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); goto exit; } + self->private_impl.f_color_type = v_a8; { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint8_t t_2 = *iop_a_src++; - v_c = t_2; + uint8_t t_4 = *iop_a_src++; + v_a8 = t_4; } - if (v_c != 10u) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); + if (v_a8 != 0u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); goto exit; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; - } - if ((v_c == 32u) || (v_c == 9u)) { - continue; - } else if (v_c == 35u) { - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; - } - if (v_c == 10u) { - break; - } - } - continue; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - self->private_impl.f_width = ((uint32_t)((v_c - 48u))); - break; + uint8_t t_5 = *iop_a_src++; + v_a8 = t_5; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; - } - if ((v_c == 32u) || (v_c == 9u)) { - break; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; - } - v_n = ((10u * self->private_impl.f_width) + ((uint32_t)((v_c - 48u)))); - if (v_n > 16777215u) { - status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); - goto exit; - } - self->private_impl.f_width = v_n; + if (v_a8 != 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_6 = *iop_a_src++; - v_c = t_6; - } - if ((v_c == 32u) || (v_c == 9u)) { - continue; - } else if (v_c == 35u) { - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_7 = *iop_a_src++; - v_c = t_7; - } - if (v_c == 10u) { - break; - } - } - continue; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - self->private_impl.f_height = ((uint32_t)((v_c - 48u))); - break; + uint8_t t_6 = *iop_a_src++; + v_a8 = t_6; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_8 = *iop_a_src++; - v_c = t_8; - } - if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) { - continue; - } else if (v_c == 10u) { - break; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; - } - v_n = ((10u * self->private_impl.f_height) + ((uint32_t)((v_c - 48u)))); - if (v_n > 16777215u) { - status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); - goto exit; - } - self->private_impl.f_height = v_n; + if (v_a8 == 0u) { + self->private_impl.f_interlace_pass = 0u; + } else if (v_a8 == 1u) { + self->private_impl.f_interlace_pass = 1u; + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_9 = *iop_a_src++; - v_c = t_9; - } - if ((v_c == 32u) || (v_c == 9u)) { - continue; - } else if (v_c == 35u) { - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_10 = *iop_a_src++; - v_c = t_10; - } - if (v_c == 10u) { - break; - } - } - continue; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; - } - self->private_impl.f_max_value = ((uint32_t)((v_c - 48u))); - break; + self->private_impl.f_filter_distance = 0u; + wuffs_png__decoder__assign_filter_distance(self); + if (self->private_impl.f_filter_distance == 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_header); + goto exit; } - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_11 = *iop_a_src++; - v_c = t_11; - } - if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) { - continue; - } else if (v_c == 10u) { - break; - } else if ((v_c < 48u) || (57u < v_c)) { - status = wuffs_base__make_status(wuffs_netpbm__error__bad_header); - goto exit; - } - v_n = ((10u * self->private_impl.f_max_value) + ((uint32_t)((v_c - 48u)))); - if (v_n > 16777215u) { - status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); - goto exit; + self->private_impl.f_overall_workbuf_length = (((uint64_t)(self->private_impl.f_height)) * (1u + wuffs_png__decoder__calculate_bytes_per_row(self, self->private_impl.f_width))); + wuffs_png__decoder__choose_filter_implementations(self); + + goto ok; + ok: + self->private_impl.p_decode_ihdr = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_ihdr = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func png.decoder.assign_filter_distance + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__assign_filter_distance( + wuffs_png__decoder* self) { + if (self->private_impl.f_depth < 8u) { + if ((self->private_impl.f_depth != 1u) && (self->private_impl.f_depth != 2u) && (self->private_impl.f_depth != 4u)) { + return wuffs_base__make_empty_struct(); + } else if (self->private_impl.f_color_type == 0u) { + self->private_impl.f_dst_pixfmt = 536870920u; + self->private_impl.f_src_pixfmt = 536870920u; + } else if (self->private_impl.f_color_type == 3u) { + self->private_impl.f_dst_pixfmt = 2198077448u; + self->private_impl.f_src_pixfmt = 2198077448u; + } else { + return wuffs_base__make_empty_struct(); + } + self->private_impl.f_filter_distance = 1u; + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); + } else if (self->private_impl.f_color_type == 0u) { + if (self->private_impl.f_depth == 8u) { + self->private_impl.f_dst_pixfmt = 536870920u; + self->private_impl.f_src_pixfmt = 536870920u; + self->private_impl.f_filter_distance = 1u; + } else if (self->private_impl.f_depth == 16u) { + if (self->private_impl.f_interlace_pass == 0u) { + self->private_impl.f_dst_pixfmt = 536870923u; + self->private_impl.f_src_pixfmt = 537919499u; + } else { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; } - self->private_impl.f_max_value = v_n; + self->private_impl.f_filter_distance = 2u; } - if (self->private_impl.f_max_value != 255u) { - status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file); - goto exit; + } else if (self->private_impl.f_color_type == 2u) { + if (self->private_impl.f_depth == 8u) { + self->private_impl.f_dst_pixfmt = 2147485832u; + self->private_impl.f_src_pixfmt = 2684356744u; + self->private_impl.f_filter_distance = 3u; + } else if (self->private_impl.f_depth == 16u) { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; + self->private_impl.f_filter_distance = 6u; + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); } - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - self->private_impl.f_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - false); + } else if (self->private_impl.f_color_type == 3u) { + if (self->private_impl.f_depth == 8u) { + self->private_impl.f_dst_pixfmt = 2198077448u; + self->private_impl.f_src_pixfmt = 2198077448u; + self->private_impl.f_filter_distance = 1u; + } + } else if (self->private_impl.f_color_type == 4u) { + if (self->private_impl.f_depth == 8u) { + self->private_impl.f_dst_pixfmt = 553648264u; + self->private_impl.f_src_pixfmt = 553648264u; + self->private_impl.f_filter_distance = 2u; + } else if (self->private_impl.f_depth == 16u) { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; + self->private_impl.f_filter_distance = 4u; + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); + } + } else if (self->private_impl.f_color_type == 6u) { + if (self->private_impl.f_depth == 8u) { + self->private_impl.f_dst_pixfmt = 2164295816u; + self->private_impl.f_src_pixfmt = 2701166728u; + self->private_impl.f_filter_distance = 4u; + } else if (self->private_impl.f_depth == 16u) { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; + self->private_impl.f_filter_distance = 8u; + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); } - self->private_impl.f_call_sequence = 32u; - - goto ok; - ok: - self->private_impl.p_do_decode_image_config[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - - return status; + return wuffs_base__make_empty_struct(); } -// -------- func netpbm.decoder.decode_frame_config +// -------- func png.decoder.calculate_bytes_per_row WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_frame_config( - wuffs_netpbm__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +static uint64_t +wuffs_png__decoder__calculate_bytes_per_row( + const wuffs_png__decoder* self, + uint32_t a_width) { + uint64_t v_bytes_per_channel = 0; - ok: - self->private_impl.p_decode_frame_config[0] = 0; - goto exit; + if (self->private_impl.f_depth == 1u) { + return ((uint64_t)(((a_width + 7u) / 8u))); + } else if (self->private_impl.f_depth == 2u) { + return ((uint64_t)(((a_width + 3u) / 4u))); + } else if (self->private_impl.f_depth == 4u) { + return ((uint64_t)(((a_width + 1u) / 2u))); } + v_bytes_per_channel = ((uint64_t)(((uint8_t)(self->private_impl.f_depth >> 3u)))); + return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type]))); +} - goto suspend; - suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; +// -------- func png.decoder.choose_filter_implementations - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_png__decoder__choose_filter_implementations( + wuffs_png__decoder* self) { + if (self->private_impl.f_filter_distance == 3u) { + self->private_impl.choosy_filter_1 = ( + &wuffs_png__decoder__filter_1_distance_3_fallback); + self->private_impl.choosy_filter_3 = ( + &wuffs_png__decoder__filter_3_distance_3_fallback); + self->private_impl.choosy_filter_4 = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 : +#endif + &wuffs_png__decoder__filter_4_distance_3_fallback); + } else if (self->private_impl.f_filter_distance == 4u) { + self->private_impl.choosy_filter_1 = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 : +#endif + &wuffs_png__decoder__filter_1_distance_4_fallback); + self->private_impl.choosy_filter_3 = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 : +#endif + &wuffs_png__decoder__filter_3_distance_4_fallback); + self->private_impl.choosy_filter_4 = ( +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__ARM_NEON) + wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon : +#endif +#if defined(WUFFS_PRIVATE_IMPL__CPU_ARCH__X86_64_V2) + wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 : +#endif + &wuffs_png__decoder__filter_4_distance_4_fallback); } - return status; + return wuffs_base__make_empty_struct(); } -// -------- func netpbm.decoder.do_decode_frame_config +// -------- func png.decoder.decode_other_chunk WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_netpbm__decoder__do_decode_frame_config( - wuffs_netpbm__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { +wuffs_png__decoder__decode_other_chunk( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src, + bool a_framy) { wuffs_base__status status = wuffs_base__make_status(NULL); const uint8_t* iop_a_src = NULL; @@ -50273,62 +63411,218 @@ wuffs_netpbm__decoder__do_decode_frame_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if ((self->private_impl.f_chunk_type == 1163152464u) && ! a_framy) { + if (self->private_impl.f_seen_plte) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } else if (self->private_impl.f_color_type == 3u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_png__decoder__decode_plte(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if ((self->private_impl.f_color_type == 2u) || (self->private_impl.f_color_type == 6u)) { + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_netpbm__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + self->private_impl.f_seen_plte = true; + } else if ((self->private_impl.f_chunk_type & 32u) == 0u) { + if (self->private_impl.f_chunk_type != 1413563465u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - if (status.repr) { - goto suspend; + } + if (self->private_impl.f_chunk_type == 1716082789u) { + if (self->private_impl.f_report_metadata_exif) { + if (self->private_impl.f_seen_exif) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_png__decoder__decode_exif(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_exif = true; } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; + } else if ((self->private_impl.f_chunk_type == 1951945833u) || (self->private_impl.f_chunk_type == 1951942004u) || (self->private_impl.f_chunk_type == 1951945850u)) { + if (self->private_impl.f_report_metadata_kvp) { + self->private_impl.f_metadata_flavor = 4u; + self->private_impl.f_metadata_fourcc = 1263947851u; + self->private_impl.f_metadata_x = 0u; + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + } + } else if ( ! a_framy) { + if (self->private_impl.f_chunk_type == 1280598881u) { + if (self->private_impl.f_seen_actl) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_png__decoder__decode_actl(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_actl = true; + } else if (self->private_impl.f_chunk_type == 1297238115u) { + if (self->private_impl.f_report_metadata_chrm) { + if (self->private_impl.f_seen_chrm) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_png__decoder__decode_chrm(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_chrm = true; + } + } else if (self->private_impl.f_chunk_type == 1280598886u) { + if (self->private_impl.f_seen_fctl) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + 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_png__decoder__decode_fctl(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_fctl = true; + } else if (self->private_impl.f_chunk_type == 1095582055u) { + if (self->private_impl.f_report_metadata_gama) { + if (self->private_impl.f_seen_gama) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + status = wuffs_png__decoder__decode_gama(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_gama = true; + } + } else if (self->private_impl.f_chunk_type == 1346585449u) { + if (self->private_impl.f_report_metadata_iccp) { + if (self->private_impl.f_seen_iccp) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + status = wuffs_png__decoder__decode_iccp(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_iccp = true; + } + } else if (self->private_impl.f_chunk_type == 1111970419u) { + if (self->private_impl.f_report_metadata_srgb) { + if (self->private_impl.f_seen_srgb) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_png__decoder__decode_srgb(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_seen_srgb = true; + } + } else if (self->private_impl.f_chunk_type == 1397641844u) { + if (self->private_impl.f_seen_trns || ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte)) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } else if (self->private_impl.f_color_type > 3u) { + } else { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_png__decoder__decode_trns(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + self->private_impl.f_seen_trns = true; } - } else if (self->private_impl.f_call_sequence == 64u) { - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height), - ((wuffs_base__flicks)(0u)), - 0u, - self->private_impl.f_frame_config_io_position, - 0u, - false, - false, - 0u); + if (self->private_impl.f_metadata_fourcc == 0u) { + self->private_data.s_decode_other_chunk.scratch = self->private_impl.f_chunk_length; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (self->private_data.s_decode_other_chunk.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_decode_other_chunk.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_decode_other_chunk.scratch; } - self->private_impl.f_call_sequence = 64u; + goto ok; ok: - self->private_impl.p_do_decode_frame_config[0] = 0; + self->private_impl.p_decode_other_chunk = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_other_chunk = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -50339,181 +63633,130 @@ wuffs_netpbm__decoder__do_decode_frame_config( return status; } -// -------- func netpbm.decoder.decode_frame - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__decode_frame( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } - - ok: - self->private_impl.p_decode_frame[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} - -// -------- func netpbm.decoder.do_decode_frame +// -------- func png.decoder.decode_actl WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_netpbm__decoder__do_decode_frame( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { +wuffs_png__decoder__decode_actl( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_actl; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_netpbm__decoder__do_decode_frame_config(self, NULL, a_src); - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + if (self->private_impl.f_chunk_length != 8u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } else if (self->private_impl.f_interlace_pass > 0u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + goto exit; } - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y = 0u; - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette(a_dst), - wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), - wuffs_base__utility__empty_slice_u8(), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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; + self->private_impl.f_chunk_length = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_actl.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_actl.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } } - goto ok; + self->private_impl.f_num_animation_frames_value = t_0; } - while (true) { - v_status = wuffs_netpbm__decoder__swizzle(self, a_dst, a_src); - if (wuffs_base__status__is_ok(&v_status)) { - break; - } else if (v_status.repr != wuffs_netpbm__note__internal_note_short_read) { - status = v_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; + if (self->private_impl.f_num_animation_frames_value == 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_actl.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_actl.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); } - goto ok; } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + self->private_impl.f_num_animation_loops_value = t_1; } - self->private_impl.f_call_sequence = 96u; + goto ok; ok: - self->private_impl.p_do_decode_frame[0] = 0; + self->private_impl.p_decode_actl = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_actl = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + return status; } -// -------- func netpbm.decoder.swizzle +// -------- func png.decoder.decode_chrm WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_netpbm__decoder__swizzle( - wuffs_netpbm__decoder* self, - wuffs_base__pixel_buffer* a_dst, +wuffs_png__decoder__decode_chrm( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - 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_bytes_per_row = 0; - uint32_t v_src_bytes_per_pixel = 0; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_j = 0; - uint64_t v_n = 0; + uint64_t v_u = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -50526,543 +63769,337 @@ wuffs_netpbm__decoder__swizzle( io2_a_src = io0_a_src + a_src->meta.wi; } - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - while (true) { - if (self->private_impl.f_dst_x == self->private_impl.f_width) { - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += 1u; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - break; - } - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + uint32_t coro_susp_point = self->private_impl.p_decode_chrm; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_chunk_length != 32u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i >= ((uint64_t)(v_dst.len))) { - v_src_bytes_per_pixel = 1u; - if (self->private_impl.f_pixfmt == 2684356744u) { - v_src_bytes_per_pixel = 3u; - } - v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); - v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); - v_j = v_n; - while (v_j >= 8u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { - iop_a_src += (v_src_bytes_per_pixel * 8u); + self->private_impl.f_chunk_length = 0u; + self->private_impl.f_metadata_flavor = 5u; + self->private_impl.f_metadata_fourcc = 1128813133u; + self->private_impl.f_metadata_x = 0u; + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); } - v_j -= 8u; } - while (v_j > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { - iop_a_src += (v_src_bytes_per_pixel * 1u); + v_u = t_0; + } + self->private_impl.f_metadata_x |= ((16777215u & v_u) << 0u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint64_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 24) { + t_1 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); } - v_j -= 1u; } - } else { - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( - &self->private_impl.f_swizzler, - wuffs_base__slice_u8__subslice_i(v_dst, v_i), - wuffs_base__pixel_buffer__palette(a_dst), - &iop_a_src, - io2_a_src); - } - if (v_n == 0u) { - status = wuffs_base__make_status(wuffs_netpbm__note__internal_note_short_read); - goto ok; + v_u = t_1; } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); - } - status = wuffs_base__make_status(NULL); - goto ok; - - ok: - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func netpbm.decoder.frame_dirty_rect - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_netpbm__decoder__frame_dirty_rect( - const wuffs_netpbm__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - - return wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height); -} - -// -------- func netpbm.decoder.num_animation_loops - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_netpbm__decoder__num_animation_loops( - const wuffs_netpbm__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func netpbm.decoder.num_decoded_frame_configs - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__num_decoded_frame_configs( - const wuffs_netpbm__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - if (self->private_impl.f_call_sequence > 32u) { - return 1u; - } - return 0u; -} - -// -------- func netpbm.decoder.num_decoded_frames - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__num_decoded_frames( - const wuffs_netpbm__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - if (self->private_impl.f_call_sequence > 64u) { - return 1u; - } - return 0u; -} - -// -------- func netpbm.decoder.restart_frame - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__restart_frame( - wuffs_netpbm__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } - if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - self->private_impl.f_call_sequence = 40u; - return wuffs_base__make_status(NULL); -} - -// -------- func netpbm.decoder.set_report_metadata - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_netpbm__decoder__set_report_metadata( - wuffs_netpbm__decoder* self, - uint32_t a_fourcc, - bool a_report) { - return wuffs_base__make_empty_struct(); -} - -// -------- func netpbm.decoder.tell_me_more - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_netpbm__decoder__tell_me_more( - wuffs_netpbm__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; - - goto ok; - ok: - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} - -// -------- func netpbm.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_netpbm__decoder__history_retain_length( - const wuffs_netpbm__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func netpbm.decoder.workbuf_len - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_netpbm__decoder__workbuf_len( - const wuffs_netpbm__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } - - return wuffs_base__utility__make_range_ii_u64(0u, 0u); -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) - -// ---------------- Status Codes Implementations - -const char wuffs_nie__error__bad_header[] = "#nie: bad header"; -const char wuffs_nie__error__truncated_input[] = "#nie: truncated input"; -const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file"; -const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read"; - -// ---------------- Private Consts - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_nie__decoder__do_decode_image_config( - wuffs_nie__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_nie__decoder__do_decode_frame_config( - wuffs_nie__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_nie__decoder__do_decode_frame( - wuffs_nie__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_nie__decoder__swizzle( - wuffs_nie__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src); - -// ---------------- VTables - -const wuffs_base__image_decoder__func_ptrs -wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_nie__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_nie__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_nie__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_nie__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_nie__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_nie__decoder__initialize( - wuffs_nie__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } - - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + self->private_impl.f_metadata_x |= ((16777215u & v_u) << 24u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint64_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); + if (num_bits_2 == 24) { + t_2 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)); + } + } + v_u = t_2; } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + self->private_impl.f_metadata_x |= ((uint64_t)((16777215u & v_u) << 48u)); + self->private_impl.f_metadata_y |= ((16777215u & v_u) >> 16u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint64_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); + if (num_bits_3 == 24) { + t_3 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)); + } + } + v_u = t_3; } - } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); -} - -wuffs_nie__decoder* -wuffs_nie__decoder__alloc(void) { - wuffs_nie__decoder* x = - (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_nie__decoder__initialize( - x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} - -size_t -sizeof__wuffs_nie__decoder(void) { - return sizeof(wuffs_nie__decoder); -} - -// ---------------- Function Implementations - -// -------- func nie.decoder.get_quirk + self->private_impl.f_metadata_y |= ((16777215u & v_u) << 8u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + uint64_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + if (num_bits_4 == 24) { + t_4 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)); + } + } + v_u = t_4; + } + self->private_impl.f_metadata_y |= ((16777215u & v_u) << 32u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + uint64_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); + if (num_bits_5 == 24) { + t_5 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)); + } + } + v_u = t_5; + } + self->private_impl.f_metadata_y |= ((uint64_t)((16777215u & v_u) << 56u)); + self->private_impl.f_metadata_z |= ((16777215u & v_u) >> 8u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + uint64_t t_6; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6); + if (num_bits_6 == 24) { + t_6 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_6 += 8u; + *scratch |= ((uint64_t)(num_bits_6)); + } + } + v_u = t_6; + } + self->private_impl.f_metadata_z |= ((16777215u & v_u) << 16u); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + uint64_t t_7; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_chrm.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_chrm.scratch; + uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7); + if (num_bits_7 == 24) { + t_7 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_7 += 8u; + *scratch |= ((uint64_t)(num_bits_7)); + } + } + v_u = t_7; + } + self->private_impl.f_metadata_z |= ((16777215u & v_u) << 40u); -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__get_quirk( - const wuffs_nie__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + goto ok; + ok: + self->private_impl.p_decode_chrm = 0; + goto exit; } - return 0u; -} - -// -------- func nie.decoder.set_quirk + goto suspend; + suspend: + self->private_impl.p_decode_chrm = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__set_quirk( - wuffs_nie__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + return status; } -// -------- func nie.decoder.decode_image_config +// -------- func png.decoder.decode_exif WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_image_config( - wuffs_nie__decoder* self, - wuffs_base__image_config* a_dst, +static wuffs_base__status +wuffs_png__decoder__decode_exif( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_nie__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } - ok: - self->private_impl.p_decode_image_config[0] = 0; + if (self->private_impl.f_chunk_length < 4u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); goto exit; } + self->private_impl.f_metadata_flavor = 3u; + self->private_impl.f_metadata_fourcc = 1163413830u; + self->private_impl.f_metadata_x = 0u; + self->private_impl.f_metadata_y = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + self->private_impl.f_metadata_z = wuffs_base__u64__sat_add(self->private_impl.f_metadata_y, ((uint64_t)(self->private_impl.f_chunk_length))); + self->private_impl.f_chunk_length = 0u; - goto suspend; - suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - + goto ok; + ok: goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func nie.decoder.do_decode_image_config +// -------- func png.decoder.decode_fctl WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_nie__decoder__do_decode_image_config( - wuffs_nie__decoder* self, - wuffs_base__image_config* a_dst, +wuffs_png__decoder__decode_fctl( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_a = 0; + uint32_t v_x0 = 0; + uint32_t v_y0 = 0; + uint32_t v_x1 = 0; + uint32_t v_y1 = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -51075,185 +64112,309 @@ wuffs_nie__decoder__do_decode_image_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_fctl; + if (coro_susp_point) { + v_x0 = self->private_data.s_decode_fctl.v_x0; + v_x1 = self->private_data.s_decode_fctl.v_x1; + v_y1 = self->private_data.s_decode_fctl.v_y1; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + if (self->private_impl.f_chunk_length != 26u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); goto exit; } + self->private_impl.f_chunk_length = 0u; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); uint32_t t_0; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; + self->private_data.s_decode_fctl.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch)); + t_0 = ((uint32_t)(*scratch >> 32)); break; } num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; + *scratch |= ((uint64_t)(num_bits_0)); } } - v_a = t_0; + v_x0 = t_0; } - if (v_a != 1169146734u) { - status = wuffs_base__make_status(wuffs_nie__error__bad_header); + if (v_x0 != self->private_impl.f_next_animation_seq_num) { + status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); + goto exit; + } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); goto exit; } + self->private_impl.f_next_animation_seq_num += 1u; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); uint32_t t_1; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; + self->private_data.s_decode_fctl.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch)); + t_1 = ((uint32_t)(*scratch >> 32)); break; } num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; + *scratch |= ((uint64_t)(num_bits_1)); } } - v_a = t_1; - } - if (v_a == 879649535u) { - self->private_impl.f_pixfmt = 2164295816u; - } else if (v_a == 946758399u) { - self->private_impl.f_pixfmt = 2164308923u; - } else if (v_a == 879780607u) { - status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file); - goto exit; - } else if (v_a == 946889471u) { - status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file); - goto exit; - } else { - status = wuffs_base__make_status(wuffs_nie__error__bad_header); - goto exit; + v_x1 = t_1; } { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); uint32_t t_2; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; + self->private_data.s_decode_fctl.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch)); + t_2 = ((uint32_t)(*scratch >> 32)); break; } num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; + *scratch |= ((uint64_t)(num_bits_2)); } } - v_a = t_2; - } - if (v_a > 2147483647u) { - status = wuffs_base__make_status(wuffs_nie__error__bad_header); - goto exit; - } else if (v_a > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; + v_y1 = t_2; } - self->private_impl.f_width = v_a; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); uint32_t t_3; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; + self->private_data.s_decode_fctl.scratch = 0; WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)); + } + } + v_x0 = t_3; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_fctl.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); + if (num_bits_4 == 24) { + t_4 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)); + } + } + v_y0 = t_4; + } + v_x1 += v_x0; + v_y1 += v_y0; + if ((v_x0 >= v_x1) || + (v_x0 > self->private_impl.f_width) || + (v_x1 > self->private_impl.f_width) || + (v_y0 >= v_y1) || + (v_y0 > self->private_impl.f_height) || + (v_y1 > self->private_impl.f_height)) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_frame_rect_x0 = v_x0; + self->private_impl.f_frame_rect_y0 = v_y0; + self->private_impl.f_frame_rect_x1 = v_x1; + self->private_impl.f_frame_rect_y1 = v_y1; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + uint32_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_fctl.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); + if (num_bits_5 == 8) { + t_5 = ((uint32_t)(*scratch >> 48)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)); + } + } + v_x0 = t_5; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + uint32_t t_6; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_fctl.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_fctl.scratch; + uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu)); *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch)); + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6); + if (num_bits_6 == 8) { + t_6 = ((uint32_t)(*scratch >> 48)); break; } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)) << 56; + num_bits_6 += 8u; + *scratch |= ((uint64_t)(num_bits_6)); } } - v_a = t_3; + v_x1 = t_6; } - if (v_a > 2147483647u) { - status = wuffs_base__make_status(wuffs_nie__error__bad_header); + if (v_x1 <= 0u) { + self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000u); + } else { + self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000u) / ((uint64_t)(v_x1))); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_7 = *iop_a_src++; + v_x0 = t_7; + } + if (v_x0 == 0u) { + self->private_impl.f_frame_disposal = 0u; + } else if (v_x0 == 1u) { + self->private_impl.f_frame_disposal = 1u; + } else if (v_x0 == 2u) { + self->private_impl.f_frame_disposal = 2u; + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); goto exit; - } else if (v_a > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_8 = *iop_a_src++; + v_x0 = t_8; + } + if (v_x0 == 0u) { + self->private_impl.f_frame_overwrite_instead_of_blend = true; + } else if (v_x0 == 1u) { + self->private_impl.f_frame_overwrite_instead_of_blend = false; + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); goto exit; } - self->private_impl.f_height = v_a; - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - self->private_impl.f_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - 16u, - false); + if (self->private_impl.f_num_decoded_frame_configs_value == 0u) { + self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0; + self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0; + self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1; + self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1; + self->private_impl.f_first_duration = self->private_impl.f_frame_duration; + self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal; + self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend; } - self->private_impl.f_call_sequence = 32u; goto ok; ok: - self->private_impl.p_do_decode_image_config[0] = 0; + self->private_impl.p_decode_fctl = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_fctl = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_fctl.v_x0 = v_x0; + self->private_data.s_decode_fctl.v_x1 = v_x1; + self->private_data.s_decode_fctl.v_y1 = v_y1; goto exit; exit: @@ -51264,82 +64425,99 @@ wuffs_nie__decoder__do_decode_image_config( return status; } -// -------- func nie.decoder.decode_frame_config +// -------- func png.decoder.decode_gama WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_frame_config( - wuffs_nie__decoder* self, - wuffs_base__frame_config* a_dst, +static wuffs_base__status +wuffs_png__decoder__decode_gama( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_gama; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - while (true) { - { - wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_nie__error__truncated_input); - goto exit; + if (self->private_impl.f_chunk_length != 4u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length = 0u; + self->private_impl.f_metadata_flavor = 5u; + self->private_impl.f_metadata_fourcc = 1195461953u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); + iop_a_src += 4; + } else { + self->private_data.s_decode_gama.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_gama.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint64_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + self->private_impl.f_metadata_x = t_0; } + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + goto ok; ok: - self->private_impl.p_decode_frame_config[0] = 0; + self->private_impl.p_decode_gama = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + self->private_impl.p_decode_gama = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func nie.decoder.do_decode_frame_config +// -------- func png.decoder.decode_iccp WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_nie__decoder__do_decode_frame_config( - wuffs_nie__decoder* self, - wuffs_base__frame_config* a_dst, +wuffs_png__decoder__decode_iccp( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); + uint8_t v_c8 = 0; + const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -51351,62 +64529,63 @@ wuffs_nie__decoder__do_decode_frame_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_iccp; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + while (true) { + if (self->private_impl.f_chunk_length <= 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_nie__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + self->private_impl.f_chunk_length -= 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - if (status.repr) { - goto suspend; + if (v_c8 == 0u) { + break; } - } else if (self->private_impl.f_call_sequence == 40u) { - if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; + } + if (self->private_impl.f_chunk_length <= 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - } else if (self->private_impl.f_call_sequence == 64u) { - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height), - ((wuffs_base__flicks)(0u)), - 0u, - 16u, - 0u, - false, - false, - 0u); + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); + goto exit; } - self->private_impl.f_call_sequence = 64u; + self->private_impl.f_metadata_is_zlib_compressed = true; + self->private_impl.f_metadata_flavor = 4u; + self->private_impl.f_metadata_fourcc = 1229144912u; + self->private_impl.f_metadata_x = 0u; + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + goto ok; ok: - self->private_impl.p_do_decode_frame_config[0] = 0; + self->private_impl.p_decode_iccp = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_iccp = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -51417,182 +64596,119 @@ wuffs_nie__decoder__do_decode_frame_config( return status; } -// -------- func nie.decoder.decode_frame +// -------- func png.decoder.decode_plte WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__decode_frame( - wuffs_nie__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; +static wuffs_base__status +wuffs_png__decoder__decode_plte( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_nie__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } + uint32_t v_num_entries = 0; + uint32_t v_i = 0; + uint32_t v_argb = 0; - ok: - self->private_impl.p_decode_frame[0] = 0; - goto exit; + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - goto suspend; - suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + uint32_t coro_susp_point = self->private_impl.p_decode_plte; + if (coro_susp_point) { + v_num_entries = self->private_data.s_decode_plte.v_num_entries; + v_i = self->private_data.s_decode_plte.v_i; } - return status; -} - -// -------- func nie.decoder.do_decode_frame - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_nie__decoder__do_decode_frame( - wuffs_nie__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_nie__decoder__do_decode_frame_config(self, NULL, a_src); - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y = 0u; - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette(a_dst), - wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), - wuffs_base__utility__empty_slice_u8(), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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; + if ((self->private_impl.f_chunk_length > 768u) || ((self->private_impl.f_chunk_length % 3u) != 0u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - while (true) { - v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src); - if (wuffs_base__status__is_ok(&v_status)) { - break; - } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) { - status = v_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; + v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3u); + self->private_impl.f_chunk_length = 0u; + while (v_i < v_num_entries) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { + t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); + iop_a_src += 3; + } else { + self->private_data.s_decode_plte.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_plte.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 16) { + t_0 = ((uint32_t)(*scratch >> 40)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } } - goto ok; + v_argb = t_0; } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + v_argb |= 4278190080u; + self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); + self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); + self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); + self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); + v_i += 1u; + } + while (v_i < 256u) { + self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u; + self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u; + v_i += 1u; } - self->private_impl.f_call_sequence = 96u; + goto ok; ok: - self->private_impl.p_do_decode_frame[0] = 0; + self->private_impl.p_decode_plte = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_plte = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_plte.v_num_entries = v_num_entries; + self->private_data.s_decode_plte.v_i = v_i; goto exit; exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + return status; } -// -------- func nie.decoder.swizzle +// -------- func png.decoder.decode_srgb WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_nie__decoder__swizzle( - wuffs_nie__decoder* self, - wuffs_base__pixel_buffer* a_dst, +wuffs_png__decoder__decode_srgb( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - 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_bytes_per_row = 0; - uint32_t v_src_bytes_per_pixel = 0; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_i = 0; - uint64_t v_j = 0; - uint64_t v_n = 0; - const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -51604,66 +64720,39 @@ wuffs_nie__decoder__swizzle( io2_a_src = io0_a_src + a_src->meta.wi; } - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); - v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - while (true) { - if (self->private_impl.f_dst_x == self->private_impl.f_width) { - self->private_impl.f_dst_x = 0u; - self->private_impl.f_dst_y += 1u; - if (self->private_impl.f_dst_y >= self->private_impl.f_height) { - break; - } - } - v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); - if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); - } - v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); - if (v_i >= ((uint64_t)(v_dst.len))) { - v_src_bytes_per_pixel = 4u; - if (self->private_impl.f_pixfmt == 2164308923u) { - v_src_bytes_per_pixel = 8u; - } - v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel))); - v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x))))); - v_j = v_n; - while (v_j >= 8u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) { - iop_a_src += (v_src_bytes_per_pixel * 8u); - } - v_j -= 8u; - } - while (v_j > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) { - iop_a_src += (v_src_bytes_per_pixel * 1u); - } - v_j -= 1u; - } - } else { - v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader( - &self->private_impl.f_swizzler, - wuffs_base__slice_u8__subslice_i(v_dst, v_i), - wuffs_base__pixel_buffer__palette(a_dst), - &iop_a_src, - io2_a_src); + uint32_t coro_susp_point = self->private_impl.p_decode_srgb; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_chunk_length != 1u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - if (v_n == 0u) { - status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read); - goto ok; + self->private_impl.f_chunk_length = 0u; + self->private_impl.f_metadata_flavor = 5u; + self->private_impl.f_metadata_fourcc = 1397901122u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t t_0 = *iop_a_src++; + self->private_impl.f_metadata_x = t_0; } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n))); + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + + goto ok; + ok: + self->private_impl.p_decode_srgb = 0; + goto exit; } - status = wuffs_base__make_status(NULL); - goto ok; - ok: + goto suspend; + suspend: + self->private_impl.p_decode_srgb = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + goto exit; exit: if (a_src && a_src->data.ptr) { @@ -51673,131 +64762,199 @@ wuffs_nie__decoder__swizzle( return status; } -// -------- func nie.decoder.frame_dirty_rect - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_nie__decoder__frame_dirty_rect( - const wuffs_nie__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - - return wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height); -} - -// -------- func nie.decoder.num_animation_loops +// -------- func png.decoder.decode_trns WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_nie__decoder__num_animation_loops( - const wuffs_nie__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} +static wuffs_base__status +wuffs_png__decoder__decode_trns( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// -------- func nie.decoder.num_decoded_frame_configs + uint32_t v_i = 0; + uint32_t v_n = 0; + uint64_t v_u = 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__num_decoded_frame_configs( - const wuffs_nie__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (self->private_impl.f_call_sequence > 32u) { - return 1u; + uint32_t coro_susp_point = self->private_impl.p_decode_trns; + if (coro_susp_point) { + v_i = self->private_data.s_decode_trns.v_i; + v_n = self->private_data.s_decode_trns.v_n; } - return 0u; -} - -// -------- func nie.decoder.num_decoded_frames + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__num_decoded_frames( - const wuffs_nie__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + if (self->private_impl.f_color_type == 0u) { + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); + if (self->private_impl.f_depth <= 8u) { + self->private_impl.f_dst_pixfmt = 2164295816u; + self->private_impl.f_src_pixfmt = 2164295816u; + } else { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; + } + if (self->private_impl.f_chunk_length != 2u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_decode_trns.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_trns.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 8) { + t_0 = ((uint64_t)(*scratch >> 48)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + v_u = t_0; + } + if (self->private_impl.f_depth <= 1u) { + self->private_impl.f_remap_transparency = (((v_u & 1u) * 16777215u) | 4278190080u); + } else if (self->private_impl.f_depth <= 2u) { + self->private_impl.f_remap_transparency = (((v_u & 3u) * 5592405u) | 4278190080u); + } else if (self->private_impl.f_depth <= 4u) { + self->private_impl.f_remap_transparency = (((v_u & 15u) * 1118481u) | 4278190080u); + } else if (self->private_impl.f_depth <= 8u) { + self->private_impl.f_remap_transparency = (((v_u & 255u) * 65793u) | 4278190080u); + } else { + self->private_impl.f_remap_transparency = ((v_u * 4295032833u) | 18446462598732840960u); + } + } else if (self->private_impl.f_color_type == 2u) { + self->private_impl.choosy_filter_and_swizzle = ( + &wuffs_png__decoder__filter_and_swizzle_tricky); + if (self->private_impl.f_depth <= 8u) { + self->private_impl.f_dst_pixfmt = 2164295816u; + self->private_impl.f_src_pixfmt = 2164295816u; + } else { + self->private_impl.f_dst_pixfmt = 2164308923u; + self->private_impl.f_src_pixfmt = 2164308923u; + } + if (self->private_impl.f_chunk_length != 6u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length = 0u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint64_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) { + t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src))); + iop_a_src += 6; + } else { + self->private_data.s_decode_trns.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_trns.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 40) { + t_1 = ((uint64_t)(*scratch >> 16)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); + } + } + v_u = t_1; + } + if (self->private_impl.f_depth <= 8u) { + self->private_impl.f_remap_transparency = ((255u & (v_u >> 0u)) | + (65280u & (v_u >> 8u)) | + (16711680u & (v_u >> 16u)) | + 4278190080u); + } else { + self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u); + } + } else if (self->private_impl.f_color_type == 3u) { + self->private_impl.f_dst_pixfmt = 2164523016u; + self->private_impl.f_src_pixfmt = 2164523016u; + if (self->private_impl.f_chunk_length > 256u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + v_n = ((uint32_t)(self->private_impl.f_chunk_length)); + self->private_impl.f_chunk_length = 0u; + while (v_i < v_n) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + self->private_data.f_src_palette[((4u * v_i) + 3u)] = t_2; + } + v_i += 1u; + } + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } - if (self->private_impl.f_call_sequence > 64u) { - return 1u; + goto ok; + ok: + self->private_impl.p_decode_trns = 0; + goto exit; } - return 0u; -} - -// -------- func nie.decoder.restart_frame -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__restart_frame( - wuffs_nie__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } + goto suspend; + suspend: + self->private_impl.p_decode_trns = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_trns.v_i = v_i; + self->private_data.s_decode_trns.v_n = v_n; - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } - if ((a_index != 0u) || (a_io_position != 16u)) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - self->private_impl.f_call_sequence = 40u; - return wuffs_base__make_status(NULL); -} -// -------- func nie.decoder.set_report_metadata - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_nie__decoder__set_report_metadata( - wuffs_nie__decoder* self, - uint32_t a_fourcc, - bool a_report) { - return wuffs_base__make_empty_struct(); + return status; } -// -------- func nie.decoder.tell_me_more +// -------- func png.decoder.decode_frame_config WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_nie__decoder__tell_me_more( - wuffs_nie__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, +wuffs_png__decoder__decode_frame_config( + wuffs_png__decoder* self, + wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); @@ -51808,354 +64965,485 @@ wuffs_nie__decoder__tell_me_more( ? wuffs_base__error__disabled_by_previous_error : wuffs_base__error__initialize_not_called); } - if (!a_dst || !a_src) { + if (!a_src) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { + (self->private_impl.active_coroutine != 2)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; - - goto ok; - ok: - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} - -// -------- func nie.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_nie__decoder__history_retain_length( - const wuffs_nie__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func nie.decoder.workbuf_len - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_nie__decoder__workbuf_len( - const wuffs_nie__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); - } - - return wuffs_base__utility__make_range_ii_u64(0u, 0u); -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) - -// ---------------- Status Codes Implementations - -const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required"; -const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum"; -const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method"; -const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size"; -const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check"; -const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary"; -const char wuffs_zlib__error__truncated_input[] = "#zlib: truncated input"; - -// ---------------- Private Consts - -#define WUFFS_ZLIB__QUIRKS_BASE 2113790976 - -#define WUFFS_ZLIB__QUIRKS_COUNT 1 - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_zlib__decoder__do_transform_io( - wuffs_zlib__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); - -// ---------------- VTables - -const wuffs_base__io_transformer__func_ptrs -wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = { - (uint64_t(*)(const void*, - uint32_t))(&wuffs_zlib__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_zlib__decoder__history_retain_length), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_zlib__decoder__set_quirk), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__io_buffer*, - wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len), -}; - -// ---------------- Initializer Implementations - -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_zlib__decoder__initialize( - wuffs_zlib__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); - } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); - } + wuffs_base__status v_status = wuffs_base__make_status(NULL); - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } - } + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - { - wuffs_base__status z = wuffs_adler32__hasher__initialize( - &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options); - if (z.repr) { - return z; - } - } - { - wuffs_base__status z = wuffs_adler32__hasher__initialize( - &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options); - if (z.repr) { - return z; - } - } - { - wuffs_base__status z = wuffs_deflate__decoder__initialize( - &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options); - if (z.repr) { - return z; + while (true) { + { + wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_png__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - } - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = - wuffs_base__io_transformer__vtable_name; - self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = - (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer); - return wuffs_base__make_status(NULL); -} - -wuffs_zlib__decoder* -wuffs_zlib__decoder__alloc(void) { - wuffs_zlib__decoder* x = - (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_zlib__decoder__initialize( - x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; - } - return x; -} - -size_t -sizeof__wuffs_zlib__decoder(void) { - return sizeof(wuffs_zlib__decoder); -} - -// ---------------- Function Implementations - -// -------- func zlib.decoder.dictionary_id - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_zlib__decoder__dictionary_id( - const wuffs_zlib__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return self->private_impl.f_dict_id_want; -} -// -------- func zlib.decoder.add_dictionary - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_zlib__decoder__add_dictionary( - wuffs_zlib__decoder* self, - wuffs_base__slice_u8 a_dict) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; } - if (self->private_impl.f_header_complete) { - self->private_impl.f_bad_call_sequence = true; - } else { - self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict); - wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict); + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - self->private_impl.f_got_dictionary = true; - return wuffs_base__make_empty_struct(); + return status; } -// -------- func zlib.decoder.get_quirk +// -------- func png.decoder.do_decode_frame_config WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_zlib__decoder__get_quirk( - const wuffs_zlib__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; +static wuffs_base__status +wuffs_png__decoder__do_decode_frame_config( + wuffs_png__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_checksum_have = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t v_key = 0; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { - return 1u; - } else if (a_key >= 2113790976u) { - v_key = (a_key - 2113790976u); - if (v_key < 1u) { - if (self->private_impl.f_quirks[v_key]) { - return 1u; + if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_png__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_png__decoder__skip_frame(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (self->private_impl.f_metadata_fourcc != 0u) { + self->private_impl.f_call_sequence = 48u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; + } + if (self->private_impl.f_num_decoded_frame_configs_value == 0u) { + self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0; + self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0; + self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1; + self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1; + self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position; + self->private_impl.f_frame_duration = self->private_impl.f_first_duration; + self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal; + self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend; + } else { + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_frame_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + self->private_impl.f_chunk_length = t_0; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_frame_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + self->private_impl.f_chunk_type = t_1; + } + if (self->private_impl.f_chunk_type == 1145980233u) { + if (self->private_impl.f_chunk_length != 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_frame_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_frame_config.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + v_checksum_have = t_2; + } + if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != 2187346606u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_checksum); + goto exit; + } + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else if (self->private_impl.f_chunk_type == 1413571686u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } else if (self->private_impl.f_chunk_type == 1280598886u) { + self->private_impl.f_frame_config_io_position = ((uint64_t)(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) - 8u)); + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_png__decoder__decode_fctl(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_data.s_do_decode_frame_config.scratch = 4u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (self->private_data.s_do_decode_frame_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame_config.scratch; + break; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + status = wuffs_png__decoder__decode_other_chunk(self, a_src, true); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_metadata_fourcc != 0u) { + self->private_impl.f_call_sequence = 48u; + status = wuffs_base__make_status(wuffs_base__note__metadata_reported); + goto ok; + } + self->private_data.s_do_decode_frame_config.scratch = 4u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (self->private_data.s_do_decode_frame_config.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame_config.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame_config.scratch; + self->private_impl.f_chunk_length = 0u; } } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + self->private_impl.f_frame_rect_x0, + self->private_impl.f_frame_rect_y0, + self->private_impl.f_frame_rect_x1, + self->private_impl.f_frame_rect_y1), + ((wuffs_base__flicks)(self->private_impl.f_frame_duration)), + ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)), + self->private_impl.f_frame_config_io_position, + self->private_impl.f_frame_disposal, + ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns), + self->private_impl.f_frame_overwrite_instead_of_blend, + 0u); + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u); + self->private_impl.f_call_sequence = 64u; + + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; } - return 0u; -} -// -------- func zlib.decoder.set_quirk + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_zlib__decoder__set_quirk( - wuffs_zlib__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (self->private_impl.f_header_complete) { - self->private_impl.f_bad_call_sequence = true; - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } else if (a_key == 1u) { - self->private_impl.f_ignore_checksum = (a_value > 0u); - return wuffs_base__make_status(NULL); - } else if (a_key >= 2113790976u) { - a_key -= 2113790976u; - if (a_key < 1u) { - self->private_impl.f_quirks[a_key] = (a_value > 0u); - return wuffs_base__make_status(NULL); - } - } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + return status; } -// -------- func zlib.decoder.history_retain_length +// -------- func png.decoder.skip_frame WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_zlib__decoder__history_retain_length( - const wuffs_zlib__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; +static wuffs_base__status +wuffs_png__decoder__skip_frame( + wuffs_png__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_seq_num = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - return 0u; -} + uint32_t coro_susp_point = self->private_impl.p_skip_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -// -------- func zlib.decoder.workbuf_len + self->private_impl.f_chunk_type_array[0u] = 0u; + self->private_impl.f_chunk_type_array[1u] = 0u; + self->private_impl.f_chunk_type_array[2u] = 0u; + self->private_impl.f_chunk_type_array[3u] = 0u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + continue; + } + self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); + if (self->private_impl.f_chunk_type == 1413563465u) { + if (self->private_impl.f_chunk_type_array[0u] == 102u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_type_array[0u] = 73u; + self->private_impl.f_chunk_type_array[1u] = 68u; + self->private_impl.f_chunk_type_array[2u] = 65u; + self->private_impl.f_chunk_type_array[3u] = 84u; + } else if (self->private_impl.f_chunk_type == 1413571686u) { + if (self->private_impl.f_chunk_type_array[0u] == 73u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_type_array[0u] = 102u; + self->private_impl.f_chunk_type_array[1u] = 100u; + self->private_impl.f_chunk_type_array[2u] = 65u; + self->private_impl.f_chunk_type_array[3u] = 84u; + if (self->private_impl.f_chunk_length < 4u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 4u; + iop_a_src += 8u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_skip_frame.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_skip_frame.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + v_seq_num = t_0; + } + if (v_seq_num != self->private_impl.f_next_animation_seq_num) { + status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); + goto exit; + } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + goto exit; + } + self->private_impl.f_next_animation_seq_num += 1u; + self->private_data.s_skip_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4u); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_skip_frame.scratch; + self->private_impl.f_chunk_length = 0u; + continue; + } else if (self->private_impl.f_chunk_type_array[0u] != 0u) { + break; + } else if (self->private_impl.f_chunk_type == 1280598886u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_data.s_skip_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_data.s_skip_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_skip_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_skip_frame.scratch; + self->private_impl.f_chunk_length = 0u; + } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + self->private_impl.f_call_sequence = 32u; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_zlib__decoder__workbuf_len( - const wuffs_zlib__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); + ok: + self->private_impl.p_skip_frame = 0; + goto exit; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + + goto suspend; + suspend: + self->private_impl.p_skip_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__utility__make_range_ii_u64(1u, 1u); + return status; } -// -------- func zlib.decoder.transform_io +// -------- func png.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_zlib__decoder__transform_io( - wuffs_zlib__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_png__decoder__decode_frame( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -52170,7 +65458,7 @@ wuffs_zlib__decoder__transform_io( return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { + (self->private_impl.active_coroutine != 3)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -52179,71 +65467,312 @@ wuffs_zlib__decoder__transform_io( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_transform_io[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_png__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func png.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_png__decoder__do_decode_frame( + wuffs_png__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_seq_num = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_pass_width = 0; + uint32_t v_pass_height = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } else if (self->private_impl.f_call_sequence >= 96u) { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else if (self->private_impl.f_call_sequence != 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_png__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } while (true) { - { - wuffs_base__status t_0 = wuffs_zlib__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); - v_status = t_0; + if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + continue; } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_zlib__error__truncated_input); + self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); + if (self->private_impl.f_chunk_type == 1413563465u) { + self->private_impl.f_chunk_type_array[0u] = 73u; + self->private_impl.f_chunk_type_array[1u] = 68u; + self->private_impl.f_chunk_type_array[2u] = 65u; + self->private_impl.f_chunk_type_array[3u] = 84u; + iop_a_src += 8u; + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); + } + break; + } else if (self->private_impl.f_chunk_type == 1413571686u) { + self->private_impl.f_chunk_type_array[0u] = 102u; + self->private_impl.f_chunk_type_array[1u] = 100u; + self->private_impl.f_chunk_type_array[2u] = 65u; + self->private_impl.f_chunk_type_array[3u] = 84u; + if (self->private_impl.f_chunk_length < 4u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 4u; + iop_a_src += 8u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_frame.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); + } + } + v_seq_num = t_0; + } + if (v_seq_num != self->private_impl.f_next_animation_seq_num) { + status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); + goto exit; + } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + goto exit; + } + self->private_impl.f_next_animation_seq_num += 1u; + break; + } else if (self->private_impl.f_chunk_type == 1280598886u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); goto exit; } + self->private_data.s_do_decode_frame.scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame.scratch; + self->private_impl.f_chunk_length = 0u; + } + if (self->private_impl.f_zlib_is_dirty) { + wuffs_private_impl__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib, + sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + if (self->private_impl.f_ignore_checksum) { + wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u); + } + } + self->private_impl.f_zlib_is_dirty = true; + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), + wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), + wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + 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; + } + self->private_impl.f_workbuf_hist_pos_base = 0u; + while (true) { + if (self->private_impl.f_chunk_type_array[0u] == 73u) { + v_pass_width = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][1u])) + self->private_impl.f_width) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u])); + v_pass_height = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][4u])) + self->private_impl.f_height) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u])); + } else { + v_pass_width = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0))); + v_pass_height = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0))); + } + if ((v_pass_width > 0u) && (v_pass_height > 0u)) { + self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width); + self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1u + self->private_impl.f_pass_bytes_per_row)); + while (true) { + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_1 = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf); + v_status = t_1; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) { + if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) { + wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi)); + } + if (v_status.repr == wuffs_base__suspension__short_read) { + status = wuffs_base__make_status(wuffs_png__error__truncated_input); + goto exit; + } + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + } + v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length; + } + if ((self->private_impl.f_interlace_pass == 0u) || (self->private_impl.f_interlace_pass >= 7u)) { + break; + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_interlace_pass += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif } + wuffs_private_impl__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); + self->private_impl.f_call_sequence = 32u; ok: - self->private_impl.p_transform_io[0] = 0; + self->private_impl.p_do_decode_frame = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func zlib.decoder.do_transform_io +// -------- func png.decoder.decode_pass WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_zlib__decoder__do_transform_io( - wuffs_zlib__decoder* self, - wuffs_base__io_buffer* a_dst, +wuffs_png__decoder__decode_pass( + wuffs_png__decoder* self, wuffs_base__io_buffer* a_src, wuffs_base__slice_u8 a_workbuf) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint16_t v_x = 0; - uint32_t v_checksum_got = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); + wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_w = &u_w; + uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint64_t v_w_mark = 0; + uint64_t v_r_mark = 0; + wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL); + uint32_t v_checksum_have = 0; uint32_t v_checksum_want = 0; - uint64_t v_mark = 0; + uint32_t v_seq_num = 0; - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -52255,77 +65784,93 @@ wuffs_zlib__decoder__do_transform_io( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0]; - if (coro_susp_point) { - v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got; - } + uint32_t coro_susp_point = self->private_impl.p_decode_pass; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_bad_call_sequence) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if (self->private_impl.f_quirks[0u]) { - } else if ( ! self->private_impl.f_want_dictionary) { + self->private_impl.f_workbuf_wi = 0u; + while (true) { + if ((self->private_impl.f_workbuf_wi > self->private_impl.f_pass_workbuf_length) || (self->private_impl.f_pass_workbuf_length > ((uint64_t)(a_workbuf.len)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint16_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src); - iop_a_src += 2; - } else { - self->private_data.s_do_transform_io[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + wuffs_base__io_buffer* o_0_v_w = v_w; + uint8_t* o_0_iop_v_w = iop_v_w; + uint8_t* o_0_io0_v_w = io0_v_w; + uint8_t* o_0_io1_v_w = io1_v_w; + uint8_t* o_0_io2_v_w = io2_v_w; + v_w = wuffs_private_impl__io_writer__set( + &u_w, + &iop_v_w, + &io0_v_w, + &io1_v_w, + &io2_v_w, + wuffs_base__slice_u8__subslice_ij(a_workbuf, + self->private_impl.f_workbuf_wi, + self->private_impl.f_pass_workbuf_length), + ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi))); + { + const bool o_1_closed_a_src = a_src->meta.closed; + const uint8_t* o_1_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; + } + v_w_mark = ((uint64_t)(iop_v_w - io0_v_w)); + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr)); + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 8) { - t_0 = ((uint16_t)(*scratch >> 48)); - break; + wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8()); + v_zlib_status = t_0; + iop_v_w = u_w.data.ptr + u_w.meta.wi; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); + } + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_private_impl__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)))); + io2_a_src = o_1_io2_a_src; + if (a_src) { + a_src->meta.closed = o_1_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); } } - v_x = t_0; - } - if (((v_x >> 8u) & 15u) != 8u) { - status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method); - goto exit; - } - if ((v_x >> 12u) > 7u) { - status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size); - goto exit; - } - if ((v_x % 31u) != 0u) { - status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check); - goto exit; + v_w = o_0_v_w; + iop_v_w = o_0_iop_v_w; + io0_v_w = o_0_io0_v_w; + io1_v_w = o_0_io1_v_w; + io2_v_w = o_0_io2_v_w; } - self->private_impl.f_want_dictionary = ((v_x & 32u) != 0u); - if (self->private_impl.f_want_dictionary) { - self->private_impl.f_dict_id_got = 1u; + if (wuffs_base__status__is_ok(&v_zlib_status)) { + if (self->private_impl.f_chunk_length > 0u) { + status = wuffs_base__make_status(wuffs_base__error__too_much_data); + goto exit; + } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); uint32_t t_1; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); iop_a_src += 4; } else { - self->private_data.s_do_transform_io[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + self->private_data.s_decode_pass.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; + uint64_t* scratch = &self->private_data.s_decode_pass.scratch; uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); *scratch >>= 8; *scratch <<= 8; @@ -52338,101 +65883,208 @@ wuffs_zlib__decoder__do_transform_io( *scratch |= ((uint64_t)(num_bits_1)); } } - self->private_impl.f_dict_id_want = t_1; + v_checksum_want = t_1; } - status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required); - goto ok; - } else if (self->private_impl.f_got_dictionary) { - status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary); - goto exit; - } - } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) { - if (self->private_impl.f_got_dictionary) { - status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary); + if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) { + v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8()); + if (v_checksum_have != v_checksum_want) { + status = wuffs_base__make_status(wuffs_png__error__bad_checksum); + goto exit; + } + } + break; + } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) { + if ((1u <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6u)) { + break; + } + status = wuffs_base__make_status(wuffs_base__error__too_much_data); goto exit; - } - status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required); - goto ok; - } - self->private_impl.f_header_complete = true; - while (true) { - v_mark = ((uint64_t)(iop_a_dst - io0_a_dst)); - { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) { + status = v_zlib_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; } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + goto ok; + } else if (self->private_impl.f_chunk_length == 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_pass.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_pass.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)); + } + } + v_checksum_want = t_2; } - wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf); - v_status = t_2; - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) { + v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8()); + if (v_checksum_have != v_checksum_want) { + status = wuffs_base__make_status(wuffs_png__error__bad_checksum); + goto exit; + } } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_pass.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_pass.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)); + } + } + self->private_impl.f_chunk_length = t_3; } - } - if ( ! self->private_impl.f_ignore_checksum && ! self->private_impl.f_quirks[0u]) { - v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); - } - if (wuffs_base__status__is_ok(&v_status)) { - break; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - } - if ( ! self->private_impl.f_quirks[0u]) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_transform_io[0].scratch = 0; + { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + uint32_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_pass.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_pass.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 24) { + t_4 = ((uint32_t)(*scratch)); + break; + } + num_bits_4 += 8u; + *scratch |= ((uint64_t)(num_bits_4)) << 56; } - uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch >> 32)); - break; + } + self->private_impl.f_chunk_type = t_4; + } + if (self->private_impl.f_chunk_type_array[0u] == 73u) { + if (self->private_impl.f_chunk_type != 1413563465u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); + } + } else { + if ((self->private_impl.f_chunk_type != 1413571686u) || (self->private_impl.f_chunk_length < 4u)) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 4u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + uint32_t t_5; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_pass.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_pass.scratch; + uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); + if (num_bits_5 == 24) { + t_5 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_5 += 8u; + *scratch |= ((uint64_t)(num_bits_5)); + } } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)); + v_seq_num = t_5; + } + if (v_seq_num != self->private_impl.f_next_animation_seq_num) { + status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); + goto exit; + } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + goto exit; } + self->private_impl.f_next_animation_seq_num += 1u; } - v_checksum_want = t_3; - } - if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) { - status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum); + continue; + } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0u) { + status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input); goto exit; } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); + } + if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) { + status = wuffs_base__make_status(wuffs_base__error__not_enough_data); + goto exit; + } else if (0u < ((uint64_t)(a_workbuf.len))) { + if (a_workbuf.ptr[0u] == 4u) { + a_workbuf.ptr[0u] = 1u; + } } ok: - self->private_impl.p_do_transform_io[0] = 0; + self->private_impl.p_decode_pass = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got; + self->private_impl.p_decode_pass = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -52440,2021 +66092,1710 @@ wuffs_zlib__decoder__do_transform_io( return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) - -// ---------------- Status Codes Implementations - -const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number"; -const char wuffs_png__error__bad_checksum[] = "#png: bad checksum"; -const char wuffs_png__error__bad_chunk[] = "#png: bad chunk"; -const char wuffs_png__error__bad_filter[] = "#png: bad filter"; -const char wuffs_png__error__bad_header[] = "#png: bad header"; -const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)"; -const char wuffs_png__error__missing_palette[] = "#png: missing palette"; -const char wuffs_png__error__truncated_input[] = "#png: truncated input"; -const char wuffs_png__error__unsupported_cgbi_extension[] = "#png: unsupported CgBI extension"; -const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method"; -const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file"; -const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O"; -const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type"; -const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds"; -const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length"; -const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input"; - -// ---------------- Private Consts - -#define WUFFS_PNG__ANCILLARY_BIT 32 - -static const uint8_t -WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = { - { - 0, 0, 0, 0, 0, 0, - }, { - 3, 7, 0, 3, 7, 0, - }, { - 3, 3, 4, 3, 7, 0, - }, { - 2, 3, 0, 3, 3, 4, - }, { - 2, 1, 2, 2, 3, 0, - }, { - 1, 1, 0, 2, 1, 2, - }, { - 1, 0, 1, 1, 1, 0, - }, { - 0, 0, 0, 1, 0, 1, - }, -}; - -static const uint8_t -WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 255, 85, 0, 17, 0, 0, 0, -}; - -static const uint8_t -WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 8, 4, 0, 2, 0, 0, 0, -}; - -static const uint8_t -WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { - 1, 0, 3, 1, 2, 0, 4, 0, -}; - -static const uint16_t -WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 41410, 41666, 41922, 42178, 42434, 42690, 42946, - 43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994, - 45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042, - 47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090, - 32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755, - 35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803, - 37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851, - 39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899, - 41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947, - 43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995, - 45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043, - 47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091, -}; - -// ---------------- Private Initializer Prototypes - -// ---------------- Private Function Prototypes - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1__choosy_default( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_3_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_2( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3__choosy_default( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_3_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4__choosy_default( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); - -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev); -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__do_decode_image_config( - wuffs_png__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_ihdr( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__assign_filter_distance( - wuffs_png__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -static uint64_t -wuffs_png__decoder__calculate_bytes_per_row( - const wuffs_png__decoder* self, - uint32_t a_width); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__choose_filter_implementations( - wuffs_png__decoder* self); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_other_chunk( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src, - bool a_framy); - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_actl( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +// -------- func png.decoder.frame_dirty_rect WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_chrm( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_png__decoder__frame_dirty_rect( + const wuffs_png__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_exif( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); + return wuffs_base__utility__make_rect_ie_u32( + self->private_impl.f_frame_rect_x0, + self->private_impl.f_frame_rect_y0, + self->private_impl.f_frame_rect_x1, + self->private_impl.f_frame_rect_y1); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_fctl( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +// -------- func png.decoder.num_animation_loops WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_gama( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_png__decoder__num_animation_loops( + const wuffs_png__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_iccp( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); + return self->private_impl.f_num_animation_loops_value; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_plte( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +// -------- func png.decoder.num_decoded_frame_configs WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_srgb( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_png__decoder__num_decoded_frame_configs( + const wuffs_png__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_trns( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); + return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__do_decode_frame_config( - wuffs_png__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); +// -------- func png.decoder.num_decoded_frames WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__skip_frame( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src); +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_png__decoder__num_decoded_frames( + const wuffs_png__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__do_decode_frame( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); + return ((uint64_t)(self->private_impl.f_num_decoded_frames_value)); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_pass( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf); +// -------- func png.decoder.restart_frame WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__do_tell_me_more( +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_png__decoder__restart_frame( wuffs_png__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src); + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf); + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } else if ((a_index >= ((uint64_t)(self->private_impl.f_num_animation_frames_value))) || ((a_index == 0u) && (a_io_position != self->private_impl.f_first_config_io_position))) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + if (self->private_impl.f_interlace_pass >= 1u) { + self->private_impl.f_interlace_pass = 1u; + } + self->private_impl.f_frame_config_io_position = a_io_position; + self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)(a_index)); + self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value; + return wuffs_base__make_status(NULL); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle__choosy_default( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf); +// -------- func png.decoder.set_report_metadata WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle_tricky( +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_png__decoder__set_report_metadata( wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf); - -// ---------------- VTables + uint32_t a_fourcc, + bool a_report) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } -const wuffs_base__image_decoder__func_ptrs -wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_png__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_png__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_png__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_png__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_png__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len), -}; + if (a_fourcc == 1128813133u) { + self->private_impl.f_report_metadata_chrm = a_report; + } else if (a_fourcc == 1163413830u) { + self->private_impl.f_report_metadata_exif = a_report; + } else if (a_fourcc == 1195461953u) { + self->private_impl.f_report_metadata_gama = a_report; + } else if (a_fourcc == 1229144912u) { + self->private_impl.f_report_metadata_iccp = a_report; + } else if (a_fourcc == 1263947808u) { + self->private_impl.f_report_metadata_kvp = a_report; + } else if (a_fourcc == 1397901122u) { + self->private_impl.f_report_metadata_srgb = a_report; + } + return wuffs_base__make_empty_struct(); +} -// ---------------- Initializer Implementations +// -------- func png.decoder.tell_me_more -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_png__decoder__initialize( +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_png__decoder__tell_me_more( wuffs_png__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); } - - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); - } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default; - self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default; - self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default; - self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - { - wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( - &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options); - if (z.repr) { - return z; - } - } - { - wuffs_base__status z = wuffs_zlib__decoder__initialize( - &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options); - if (z.repr) { - return z; + uint32_t coro_susp_point = self->private_impl.p_tell_me_more; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_png__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_png__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - } - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); -} -wuffs_png__decoder* -wuffs_png__decoder__alloc(void) { - wuffs_png__decoder* x = - (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1)); - if (!x) { - return NULL; - } - if (wuffs_png__decoder__initialize( - x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + ok: + self->private_impl.p_tell_me_more = 0; + goto exit; } - return x; -} -size_t -sizeof__wuffs_png__decoder(void) { - return sizeof(wuffs_png__decoder); -} + goto suspend; + suspend: + self->private_impl.p_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; -// ---------------- Function Implementations + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} -// ‼ WUFFS MULTI-FILE SECTION +arm_neon -// -------- func png.decoder.filter_1_distance_4_arm_neon +// -------- func png.decoder.do_tell_me_more -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_arm_neon( +static wuffs_base__status +wuffs_png__decoder__do_tell_me_more( wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - wuffs_base__slice_u8 v_curr = {0}; - uint8x8_t v_fa = {0}; - uint8x8_t v_fx = {0}; + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, v_fa); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, v_fa); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - } - v_curr.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, v_fa); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; + uint8_t v_c8 = 0; + uint16_t v_c16 = 0; + wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer(); + wuffs_base__io_buffer* v_w = &u_w; + uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint64_t v_num_written = 0; + uint64_t v_w_mark = 0; + uint64_t v_r_mark = 0; + wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL); + + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; } - v_curr.len = 0; } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -// ‼ WUFFS MULTI-FILE SECTION -arm_neon - -// ‼ WUFFS MULTI-FILE SECTION +arm_neon -// -------- func png.decoder.filter_3_distance_4_arm_neon + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint8x8_t v_fa = {0}; - uint8x8_t v_fb = {0}; - uint8x8_t v_fx = {0}; + uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more; + if (coro_susp_point) { + v_zlib_status = self->private_data.s_do_tell_me_more.v_zlib_status; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (((uint64_t)(a_prev.len)) == 0u) { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; + if (((uint8_t)(self->private_impl.f_call_sequence & 16u)) == 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } + if (self->private_impl.f_metadata_fourcc == 0u) { + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + } + do { + if (self->private_impl.f_metadata_flavor == 3u) { + while (true) { + if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_y) { + status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); + goto exit; + } else if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + self->private_impl.f_metadata_flavor, + self->private_impl.f_metadata_fourcc, + self->private_impl.f_metadata_x, + self->private_impl.f_metadata_y, + self->private_impl.f_metadata_z); + } + if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) { + goto label__goto_done__break; + } + self->private_impl.f_metadata_y = self->private_impl.f_metadata_z; + status = wuffs_base__make_status(wuffs_base__suspension__even_more_information); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + } + if (self->private_impl.f_metadata_is_zlib_compressed) { + if (self->private_impl.f_zlib_is_dirty) { + wuffs_private_impl__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib, + sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + if (self->private_impl.f_ignore_checksum) { + wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u); + } + } + self->private_impl.f_zlib_is_dirty = true; + self->private_impl.f_ztxt_hist_pos = 0u; + } + label__loop__continue:; + while (true) { + if (a_minfo != NULL) { + wuffs_base__more_information__set(a_minfo, + self->private_impl.f_metadata_flavor, + self->private_impl.f_metadata_fourcc, + self->private_impl.f_metadata_x, + self->private_impl.f_metadata_y, + self->private_impl.f_metadata_z); + } + if (self->private_impl.f_metadata_flavor != 4u) { + break; + } + if (self->private_impl.f_metadata_is_zlib_compressed) { + if (self->private_impl.f_chunk_type == 1346585449u) { + { + const bool o_0_closed_a_src = a_src->meta.closed; + const uint8_t* o_0_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; + } + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8()); + v_zlib_status = t_0; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + io2_a_src = o_0_io2_a_src; + if (a_src) { + a_src->meta.closed = o_0_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); + } + } + if (wuffs_base__status__is_ok(&v_zlib_status)) { + self->private_impl.f_metadata_is_zlib_compressed = false; + break; + } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { + status = v_zlib_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; + } + status = v_zlib_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } else if (self->private_impl.f_chunk_type == 1951945833u) { + { + const bool o_1_closed_a_src = a_src->meta.closed; + const uint8_t* o_1_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; + } + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_1 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8()); + v_zlib_status = t_1; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + io2_a_src = o_1_io2_a_src; + if (a_src) { + a_src->meta.closed = o_1_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); + } + } + if (wuffs_base__status__is_ok(&v_zlib_status)) { + self->private_impl.f_metadata_is_zlib_compressed = false; + break; + } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { + status = v_zlib_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; + } + status = v_zlib_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + } else if (self->private_impl.f_chunk_type == 1951945850u) { + if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) { + { + wuffs_base__io_buffer* o_2_v_w = v_w; + uint8_t* o_2_iop_v_w = iop_v_w; + uint8_t* o_2_io0_v_w = io0_v_w; + uint8_t* o_2_io1_v_w = io1_v_w; + uint8_t* o_2_io2_v_w = io2_v_w; + v_w = wuffs_private_impl__io_writer__set( + &u_w, + &iop_v_w, + &io0_v_w, + &io1_v_w, + &io2_v_w, + wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), + self->private_impl.f_ztxt_hist_pos); + { + const bool o_3_closed_a_src = a_src->meta.closed; + const uint8_t* o_3_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; + } + v_w_mark = ((uint64_t)(iop_v_w - io0_v_w)); + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr)); + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8()); + v_zlib_status = t_2; + iop_v_w = u_w.data.ptr + u_w.meta.wi; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + v_num_written = wuffs_private_impl__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))); + io2_a_src = o_3_io2_a_src; + if (a_src) { + a_src->meta.closed = o_3_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); + } + } + v_w = o_2_v_w; + iop_v_w = o_2_iop_v_w; + io0_v_w = o_2_io0_v_w; + io1_v_w = o_2_io1_v_w; + io2_v_w = o_2_io2_v_w; + } + if (v_num_written > 1024u) { + status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o); + goto exit; + } + self->private_impl.f_ztxt_ri = 0u; + self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written)); + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written); + } + while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) { + v_c16 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]]; + if (v_c16 == 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1); + goto exit; + } else if (v_c16 <= 127u) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + goto label__loop__continue; + } + self->private_impl.f_ztxt_ri += 1u; + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c16))), iop_a_dst += 1); + } else { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + goto label__loop__continue; + } + self->private_impl.f_ztxt_ri += 1u; + (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c16), iop_a_dst += 2); + } + } + if (wuffs_base__status__is_ok(&v_zlib_status)) { + self->private_impl.f_metadata_is_zlib_compressed = false; + break; + } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { + status = v_zlib_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; + } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) { + status = v_zlib_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + } + } else { + status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type); + goto exit; + } + } else if ((self->private_impl.f_chunk_type == 1951945833u) && (self->private_impl.f_metadata_fourcc == 1263947862u)) { + while (true) { + if (self->private_impl.f_chunk_length <= 0u) { + goto label__loop__break; + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); + goto label__loop__continue; + } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + goto label__loop__continue; + } + self->private_impl.f_chunk_length -= 1u; + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c8), iop_a_dst += 1); + } + } else { + while (true) { + if (self->private_impl.f_chunk_length <= 0u) { + if (self->private_impl.f_metadata_fourcc == 1263947851u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + goto label__loop__break; + } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + goto label__loop__continue; + } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + if (v_c8 == 0u) { + self->private_impl.f_chunk_length -= 1u; + iop_a_src += 1u; + goto label__loop__break; + } + v_c16 = WUFFS_PNG__LATIN_1[v_c8]; + if (v_c16 == 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1); + goto exit; + } else if (v_c16 <= 127u) { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + goto label__loop__continue; + } + self->private_impl.f_chunk_length -= 1u; + iop_a_src += 1u; + (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c16))), iop_a_dst += 1); + } else { + if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); + goto label__loop__continue; + } + self->private_impl.f_chunk_length -= 1u; + iop_a_src += 1u; + (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c16), iop_a_dst += 2); + } + } + } } - v_curr.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; + label__loop__break:; + if (self->private_impl.f_metadata_fourcc == 1263947851u) { + self->private_impl.f_metadata_fourcc = 1263947862u; + if (self->private_impl.f_chunk_type == 1951945833u) { + if (self->private_impl.f_chunk_length <= 1u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 2u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if (v_c8 == 0u) { + self->private_impl.f_metadata_is_zlib_compressed = false; + } else if (v_c8 == 1u) { + self->private_impl.f_metadata_is_zlib_compressed = true; + } else { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if ((v_c8 != 0u) && self->private_impl.f_metadata_is_zlib_compressed) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); + goto exit; + } + self->private_impl.f_metadata_fourcc -= 2u; + while (self->private_impl.f_metadata_fourcc != 1263947862u) { + self->private_impl.f_metadata_fourcc += 1u; + while (true) { + if (self->private_impl.f_chunk_length <= 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + if (v_c8 == 0u) { + break; + } + } + } + } else if (self->private_impl.f_chunk_type == 1951945850u) { + if (self->private_impl.f_chunk_length <= 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; + } + self->private_impl.f_chunk_length -= 1u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); + goto exit; + } + self->private_impl.f_metadata_is_zlib_compressed = true; + } + self->private_impl.f_call_sequence &= 239u; + status = wuffs_base__make_status(NULL); + goto ok; } - v_curr.len = 0; + } while (0); + label__goto_done__break:; + if (self->private_impl.f_chunk_length != 0u) { + status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + goto exit; } - } else { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb)); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 0; - v_prev.len = 0; + self->private_data.s_do_tell_me_more.scratch = 4u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + if (self->private_data.s_do_tell_me_more.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_tell_me_more.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -// ‼ WUFFS MULTI-FILE SECTION -arm_neon - -// ‼ WUFFS MULTI-FILE SECTION +arm_neon -// -------- func png.decoder.filter_4_distance_3_arm_neon - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint8x8_t v_fa = {0}; - uint8x8_t v_fb = {0}; - uint8x8_t v_fc = {0}; - uint8x8_t v_fx = {0}; - uint16x8_t v_fafb = {0}; - uint16x8_t v_fcfc = {0}; - uint16x8_t v_pa = {0}; - uint16x8_t v_pb = {0}; - uint16x8_t v_pc = {0}; - uint16x8_t v_cmpab = {0}; - uint16x8_t v_cmpac = {0}; - uint8x8_t v_picka = {0}; - uint8x8_t v_pickb = {0}; + iop_a_src += self->private_data.s_do_tell_me_more.scratch; + self->private_impl.f_metadata_flavor = 0u; + self->private_impl.f_metadata_fourcc = 0u; + self->private_impl.f_metadata_x = 0u; + self->private_impl.f_metadata_y = 0u; + self->private_impl.f_metadata_z = 0u; + self->private_impl.f_call_sequence &= 239u; + status = wuffs_base__make_status(NULL); + goto ok; - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6); - while (v_curr.ptr < i_end0_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 3; - v_prev.ptr += 3; - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3); - while (v_curr.ptr < i_end1_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 3; - v_prev.len = 3; - uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end2_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 0; - v_prev.len = 0; + ok: + self->private_impl.p_do_tell_me_more = 0; + goto exit; } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -// ‼ WUFFS MULTI-FILE SECTION -arm_neon -// ‼ WUFFS MULTI-FILE SECTION +arm_neon -// -------- func png.decoder.filter_4_distance_4_arm_neon - -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_arm_neon( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint8x8_t v_fa = {0}; - uint8x8_t v_fb = {0}; - uint8x8_t v_fc = {0}; - uint8x8_t v_fx = {0}; - uint16x8_t v_fafb = {0}; - uint16x8_t v_fcfc = {0}; - uint16x8_t v_pa = {0}; - uint16x8_t v_pb = {0}; - uint16x8_t v_pc = {0}; - uint16x8_t v_cmpab = {0}; - uint16x8_t v_cmpac = {0}; - uint8x8_t v_picka = {0}; - uint8x8_t v_pickb = {0}; + goto suspend; + suspend: + self->private_impl.p_do_tell_me_more = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_tell_me_more.v_zlib_status = v_zlib_status; - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_fafb = vaddl_u8(v_fa, v_fb); - v_fcfc = vaddl_u8(v_fc, v_fc); - v_pa = vabdl_u8(v_fb, v_fc); - v_pb = vabdl_u8(v_fa, v_fc); - v_pc = vabdq_u16(v_fafb, v_fcfc); - v_cmpab = vcleq_u16(v_pa, v_pb); - v_cmpac = vcleq_u16(v_pa, v_pc); - v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac)); - v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc)); - v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc))); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u)); - v_fc = v_fb; - v_fa = v_fx; - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 0; - v_prev.len = 0; + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) -// ‼ WUFFS MULTI-FILE SECTION -arm_neon - -// -------- func png.decoder.filter_1 - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - return (*self->private_impl.choosy_filter_1)(self, a_curr); -} - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1__choosy_default( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - uint64_t v_filter_distance = 0; - uint8_t v_fa = 0; - uint64_t v_i_start = 0; - uint64_t v_i = 0; - - v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); - v_i_start = 0u; - while (v_i_start < v_filter_distance) { - v_fa = 0u; - v_i = v_i_start; - while (v_i < ((uint64_t)(a_curr.len))) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa)); - v_fa = a_curr.ptr[v_i]; - v_i += v_filter_distance; - } - v_i_start += 1u; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__make_empty_struct(); -} - -// -------- func png.decoder.filter_1_distance_3_fallback - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_3_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - wuffs_base__slice_u8 v_curr = {0}; - uint8_t v_fa0 = 0; - uint8_t v_fa1 = 0; - uint8_t v_fa2 = 0; - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 3; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - } - v_curr.len = 3; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end1_curr) { - v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - } - v_curr.len = 0; - } - return wuffs_base__make_empty_struct(); + return status; } -// -------- func png.decoder.filter_1_distance_4_fallback +// -------- func png.decoder.workbuf_len WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - wuffs_base__slice_u8 v_curr = {0}; - uint8_t v_fa0 = 0; - uint8_t v_fa1 = 0; - uint8_t v_fa2 = 0; - uint8_t v_fa3 = 0; - - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3u])); - v_curr.ptr[3u] = v_fa3; - v_curr.ptr += 4; - } - v_curr.len = 0; +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_png__decoder__workbuf_len( + const wuffs_png__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); } - return wuffs_base__make_empty_struct(); -} - -// -------- func png.decoder.filter_2 - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_2( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - uint64_t v_n = 0; - uint64_t v_i = 0; - - v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); - v_i = 0u; - while (v_i < v_n) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i])); - v_i += 1u; + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); } - return wuffs_base__make_empty_struct(); + + return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length); } -// -------- func png.decoder.filter_3 +// -------- func png.decoder.filter_and_swizzle WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3( +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle( wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev); + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf) { + return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf); } WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3__choosy_default( +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle__choosy_default( wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - uint64_t v_filter_distance = 0; - uint64_t v_n = 0; - uint64_t v_i = 0; + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__pixel_format v_dst_pixfmt = {0}; + uint32_t v_dst_bits_per_pixel = 0; + uint64_t v_dst_bytes_per_pixel = 0; + uint64_t v_dst_bytes_per_row0 = 0; + uint64_t v_dst_bytes_per_row1 = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + uint32_t v_y = 0; + wuffs_base__slice_u8 v_dst = {0}; + uint8_t v_filter = 0; + wuffs_base__slice_u8 v_curr_row = {0}; + wuffs_base__slice_u8 v_prev_row = {0}; - v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); - if (((uint64_t)(a_prev.len)) == 0u) { - v_i = v_filter_distance; - while (v_i < ((uint64_t)(a_curr.len))) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2u))); - v_i += 1u; - } + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); + } + v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); + v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel); + v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) { + v_tab = wuffs_base__table_u8__subtable_ij(v_tab, + 0u, + 0u, + v_dst_bytes_per_row1, + ((uint64_t)(v_tab.height))); + } + if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) { + v_tab = wuffs_base__table_u8__subtable_ij(v_tab, + v_dst_bytes_per_row0, + 0u, + ((uint64_t)(v_tab.width)), + ((uint64_t)(v_tab.height))); } else { - v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); - v_i = 0u; - while ((v_i < v_n) && (v_i < v_filter_distance)) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2u))); - v_i += 1u; + v_tab = wuffs_base__table_u8__subtable_ij(v_tab, + 0u, + 0u, + 0u, + 0u); + } + v_y = self->private_impl.f_frame_rect_y0; + while (v_y < self->private_impl.f_frame_rect_y1) { + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y); + if (1u > ((uint64_t)(a_workbuf.len))) { + return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); } - v_i = v_filter_distance; - while (v_i < v_n) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2u))))); - v_i += 1u; + v_filter = a_workbuf.ptr[0u]; + a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u); + if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) { + return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); + } + v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row); + a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row); + if (v_filter == 0u) { + } else if (v_filter == 1u) { + wuffs_png__decoder__filter_1(self, v_curr_row); + } else if (v_filter == 2u) { + wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row); + } else if (v_filter == 3u) { + wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row); + } else if (v_filter == 4u) { + wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row); + } else { + return wuffs_base__make_status(wuffs_png__error__bad_filter); } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row); + v_prev_row = v_curr_row; + v_y += 1u; } - return wuffs_base__make_empty_struct(); + return wuffs_base__make_status(NULL); } -// -------- func png.decoder.filter_3_distance_3_fallback +// -------- func png.decoder.filter_and_swizzle_tricky WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_3_fallback( +static wuffs_base__status +wuffs_png__decoder__filter_and_swizzle_tricky( wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint8_t v_fa0 = 0; - uint8_t v_fa1 = 0; - uint8_t v_fa2 = 0; + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__pixel_format v_dst_pixfmt = {0}; + uint32_t v_dst_bits_per_pixel = 0; + uint64_t v_dst_bytes_per_pixel = 0; + uint64_t v_dst_bytes_per_row1 = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + uint64_t v_src_bytes_per_pixel = 0; + uint32_t v_x = 0; + uint32_t v_y = 0; + uint64_t v_i = 0; + wuffs_base__slice_u8 v_dst = {0}; + uint8_t v_filter = 0; + wuffs_base__slice_u8 v_s = {0}; + wuffs_base__slice_u8 v_curr_row = {0}; + wuffs_base__slice_u8 v_prev_row = {0}; + uint8_t v_bits_unpacked[8] = {0}; + uint8_t v_bits_packed = 0; + uint8_t v_packs_remaining = 0; + uint8_t v_multiplier = 0; + uint8_t v_shift = 0; - if (((uint64_t)(a_prev.len)) == 0u) { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 3; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); + } + v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); + v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + v_src_bytes_per_pixel = 1u; + if (self->private_impl.f_depth >= 8u) { + v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)(((uint8_t)(self->private_impl.f_depth >> 3u))))); + } + if (self->private_impl.f_chunk_type_array[0u] == 73u) { + v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5u])); + } else { + v_y = self->private_impl.f_frame_rect_y0; + } + while (v_y < self->private_impl.f_frame_rect_y1) { + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y); + if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1); + } + if (1u > ((uint64_t)(a_workbuf.len))) { + return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); + } + v_filter = a_workbuf.ptr[0u]; + a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u); + if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) { + return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); + } + v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row); + a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row); + if (v_filter == 0u) { + } else if (v_filter == 1u) { + wuffs_png__decoder__filter_1(self, v_curr_row); + } else if (v_filter == 2u) { + wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row); + } else if (v_filter == 3u) { + wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row); + } else if (v_filter == 4u) { + wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row); + } else { + return wuffs_base__make_status(wuffs_png__error__bad_filter); + } + v_s = v_curr_row; + if (self->private_impl.f_chunk_type_array[0u] == 73u) { + v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2u])); + } else { + v_x = self->private_impl.f_frame_rect_x0; + } + if (self->private_impl.f_depth == 8u) { + while (v_x < self->private_impl.f_frame_rect_x1) { + v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); + if (v_i <= ((uint64_t)(v_dst.len))) { + if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) { + if (self->private_impl.f_color_type == 0u) { + if (1u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[0u]; + v_bits_unpacked[1u] = v_s.ptr[0u]; + v_bits_unpacked[2u] = v_s.ptr[0u]; + v_bits_unpacked[3u] = 255u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | + (((uint32_t)(v_bits_unpacked[1u])) << 8u) | + (((uint32_t)(v_bits_unpacked[2u])) << 16u) | + (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { + v_bits_unpacked[0u] = 0u; + v_bits_unpacked[1u] = 0u; + v_bits_unpacked[2u] = 0u; + v_bits_unpacked[3u] = 0u; + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); + } + } else { + if (3u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[2u]; + v_bits_unpacked[1u] = v_s.ptr[1u]; + v_bits_unpacked[2u] = v_s.ptr[0u]; + v_bits_unpacked[3u] = 255u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 3u); + if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | + (((uint32_t)(v_bits_unpacked[1u])) << 8u) | + (((uint32_t)(v_bits_unpacked[2u])) << 16u) | + (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { + v_bits_unpacked[0u] = 0u; + v_bits_unpacked[1u] = 0u; + v_bits_unpacked[2u] = 0u; + v_bits_unpacked[3u] = 0u; + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); + } + } + } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) { + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__slice_u8__subslice_j(v_s, v_src_bytes_per_pixel)); + v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel); + } + } + v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); } - v_curr.len = 3; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end1_curr) { - v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; + } else if (self->private_impl.f_depth < 8u) { + v_multiplier = 1u; + if (self->private_impl.f_color_type == 0u) { + v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth]; } - v_curr.len = 0; - } - } else { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 3; - v_prev.len = 3; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - v_prev.ptr += 3; - v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - v_prev.ptr += 3; + v_shift = ((uint8_t)(((uint8_t)(8u - self->private_impl.f_depth)) & 7u)); + v_packs_remaining = 0u; + while (v_x < self->private_impl.f_frame_rect_x1) { + v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); + if (v_i <= ((uint64_t)(v_dst.len))) { + if ((v_packs_remaining == 0u) && (1u <= ((uint64_t)(v_s.len)))) { + v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth]; + v_bits_packed = v_s.ptr[0u]; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + } + v_bits_unpacked[0u] = ((uint8_t)(((uint8_t)(v_bits_packed >> v_shift)) * v_multiplier)); + v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth)); + v_packs_remaining = ((uint8_t)(v_packs_remaining - 1u)); + if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) { + v_bits_unpacked[1u] = v_bits_unpacked[0u]; + v_bits_unpacked[2u] = v_bits_unpacked[0u]; + v_bits_unpacked[3u] = 255u; + if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | + (((uint32_t)(v_bits_unpacked[1u])) << 8u) | + (((uint32_t)(v_bits_unpacked[2u])) << 16u) | + (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { + v_bits_unpacked[0u] = 0u; + v_bits_unpacked[1u] = 0u; + v_bits_unpacked[2u] = 0u; + v_bits_unpacked[3u] = 0u; + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); + } else { + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 1)); + } + } + v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); } - v_curr.len = 3; - v_prev.len = 3; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end1_curr) { - v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_curr.ptr += 3; - v_prev.ptr += 3; + } else { + while (v_x < self->private_impl.f_frame_rect_x1) { + v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); + if (v_i <= ((uint64_t)(v_dst.len))) { + if (self->private_impl.f_color_type == 0u) { + if (2u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[1u]; + v_bits_unpacked[1u] = v_s.ptr[0u]; + v_bits_unpacked[2u] = v_s.ptr[1u]; + v_bits_unpacked[3u] = v_s.ptr[0u]; + v_bits_unpacked[4u] = v_s.ptr[1u]; + v_bits_unpacked[5u] = v_s.ptr[0u]; + v_bits_unpacked[6u] = 255u; + v_bits_unpacked[7u] = 255u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); + if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) | + (((uint64_t)(v_bits_unpacked[1u])) << 8u) | + (((uint64_t)(v_bits_unpacked[2u])) << 16u) | + (((uint64_t)(v_bits_unpacked[3u])) << 24u) | + (((uint64_t)(v_bits_unpacked[4u])) << 32u) | + (((uint64_t)(v_bits_unpacked[5u])) << 40u) | + (((uint64_t)(v_bits_unpacked[6u])) << 48u) | + (((uint64_t)(v_bits_unpacked[7u])) << 56u))) { + v_bits_unpacked[0u] = 0u; + v_bits_unpacked[1u] = 0u; + v_bits_unpacked[2u] = 0u; + v_bits_unpacked[3u] = 0u; + v_bits_unpacked[4u] = 0u; + v_bits_unpacked[5u] = 0u; + v_bits_unpacked[6u] = 0u; + v_bits_unpacked[7u] = 0u; + } + } + } else if (self->private_impl.f_color_type == 2u) { + if (6u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[5u]; + v_bits_unpacked[1u] = v_s.ptr[4u]; + v_bits_unpacked[2u] = v_s.ptr[3u]; + v_bits_unpacked[3u] = v_s.ptr[2u]; + v_bits_unpacked[4u] = v_s.ptr[1u]; + v_bits_unpacked[5u] = v_s.ptr[0u]; + v_bits_unpacked[6u] = 255u; + v_bits_unpacked[7u] = 255u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u); + if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) | + (((uint64_t)(v_bits_unpacked[1u])) << 8u) | + (((uint64_t)(v_bits_unpacked[2u])) << 16u) | + (((uint64_t)(v_bits_unpacked[3u])) << 24u) | + (((uint64_t)(v_bits_unpacked[4u])) << 32u) | + (((uint64_t)(v_bits_unpacked[5u])) << 40u) | + (((uint64_t)(v_bits_unpacked[6u])) << 48u) | + (((uint64_t)(v_bits_unpacked[7u])) << 56u))) { + v_bits_unpacked[0u] = 0u; + v_bits_unpacked[1u] = 0u; + v_bits_unpacked[2u] = 0u; + v_bits_unpacked[3u] = 0u; + v_bits_unpacked[4u] = 0u; + v_bits_unpacked[5u] = 0u; + v_bits_unpacked[6u] = 0u; + v_bits_unpacked[7u] = 0u; + } + } + } else if (self->private_impl.f_color_type == 4u) { + if (4u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[1u]; + v_bits_unpacked[1u] = v_s.ptr[0u]; + v_bits_unpacked[2u] = v_s.ptr[1u]; + v_bits_unpacked[3u] = v_s.ptr[0u]; + v_bits_unpacked[4u] = v_s.ptr[1u]; + v_bits_unpacked[5u] = v_s.ptr[0u]; + v_bits_unpacked[6u] = v_s.ptr[3u]; + v_bits_unpacked[7u] = v_s.ptr[2u]; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + } else { + if (8u <= ((uint64_t)(v_s.len))) { + v_bits_unpacked[0u] = v_s.ptr[5u]; + v_bits_unpacked[1u] = v_s.ptr[4u]; + v_bits_unpacked[2u] = v_s.ptr[3u]; + v_bits_unpacked[3u] = v_s.ptr[2u]; + v_bits_unpacked[4u] = v_s.ptr[1u]; + v_bits_unpacked[5u] = v_s.ptr[0u]; + v_bits_unpacked[6u] = v_s.ptr[7u]; + v_bits_unpacked[7u] = v_s.ptr[6u]; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u); + } + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 8)); + } + v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); } - v_curr.len = 0; - v_prev.len = 0; } + v_prev_row = v_curr_row; + v_y += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]); } - return wuffs_base__make_empty_struct(); + return wuffs_base__make_status(NULL); } -// -------- func png.decoder.filter_3_distance_4_fallback +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) + +// ---------------- Status Codes Implementations + +const char wuffs_qoi__error__bad_footer[] = "#qoi: bad footer"; +const char wuffs_qoi__error__bad_header[] = "#qoi: bad header"; +const char wuffs_qoi__error__truncated_input[] = "#qoi: truncated input"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint8_t v_fa0 = 0; - uint8_t v_fa1 = 0; - uint8_t v_fa2 = 0; - uint8_t v_fa3 = 0; +static wuffs_base__status +wuffs_qoi__decoder__do_decode_image_config( + wuffs_qoi__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_qoi__decoder__do_decode_frame_config( + wuffs_qoi__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_qoi__decoder__do_decode_frame( + wuffs_qoi__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_qoi__decoder__from_src_to_buffer( + wuffs_qoi__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_qoi__decoder__from_buffer_to_dst( + wuffs_qoi__decoder* self, + wuffs_base__pixel_buffer* a_dst); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_qoi__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_qoi__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_qoi__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_qoi__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_qoi__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_qoi__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_qoi__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_qoi__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_qoi__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_qoi__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_qoi__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_qoi__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_qoi__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_qoi__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_qoi__decoder__initialize( + wuffs_qoi__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } - if (((uint64_t)(a_prev.len)) == 0u) { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_fa3 = ((uint8_t)((v_fa3 / 2u) + v_curr.ptr[3u])); - v_curr.ptr[3u] = v_fa3; - v_curr.ptr += 4; - } - v_curr.len = 0; + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif } else { - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end0_curr) { - v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u])); - v_curr.ptr[0u] = v_fa0; - v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u])); - v_curr.ptr[1u] = v_fa1; - v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u])); - v_curr.ptr[2u] = v_fa2; - v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3u]))) / 2u))) + v_curr.ptr[3u])); - v_curr.ptr[3u] = v_fa3; - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 0; - v_prev.len = 0; + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } } - return wuffs_base__make_empty_struct(); + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_qoi__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); } -// -------- func png.decoder.filter_4 +wuffs_qoi__decoder* +wuffs_qoi__decoder__alloc(void) { + wuffs_qoi__decoder* x = + (wuffs_qoi__decoder*)(calloc(1, sizeof(wuffs_qoi__decoder))); + if (!x) { + return NULL; + } + if (wuffs_qoi__decoder__initialize( + x, sizeof(wuffs_qoi__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev); +size_t +sizeof__wuffs_qoi__decoder(void) { + return sizeof(wuffs_qoi__decoder); } +// ---------------- Function Implementations + +// -------- func qoi.decoder.get_quirk + WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4__choosy_default( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - uint64_t v_filter_distance = 0; - uint64_t v_n = 0; - uint64_t v_i = 0; - uint32_t v_fa = 0; - uint32_t v_fb = 0; - uint32_t v_fc = 0; - uint32_t v_pp = 0; - uint32_t v_pa = 0; - uint32_t v_pb = 0; - uint32_t v_pc = 0; +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_qoi__decoder__get_quirk( + const wuffs_qoi__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } - v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance)); - v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len))); - v_i = 0u; - while ((v_i < v_n) && (v_i < v_filter_distance)) { - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i])); - v_i += 1u; + return 0u; +} + +// -------- func qoi.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_qoi__decoder__set_quirk( + wuffs_qoi__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - v_i = v_filter_distance; - while (v_i < v_n) { - v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])); - v_fb = ((uint32_t)(a_prev.ptr[v_i])); - v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)])); - v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc)); - v_pa = ((uint32_t)(v_pp - v_fa)); - if (v_pa >= 2147483648u) { - v_pa = ((uint32_t)(0u - v_pa)); - } - v_pb = ((uint32_t)(v_pp - v_fb)); - if (v_pb >= 2147483648u) { - v_pb = ((uint32_t)(0u - v_pb)); - } - v_pc = ((uint32_t)(v_pp - v_fc)); - if (v_pc >= 2147483648u) { - v_pc = ((uint32_t)(0u - v_pc)); - } - if ((v_pa <= v_pb) && (v_pa <= v_pc)) { - } else if (v_pb <= v_pc) { - v_fa = v_fb; - } else { - v_fa = v_fc; - } - a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(v_fa)))); - v_i += 1u; + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - return wuffs_base__make_empty_struct(); + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func png.decoder.filter_4_distance_3_fallback +// -------- func qoi.decoder.decode_image_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint32_t v_fa0 = 0; - uint32_t v_fa1 = 0; - uint32_t v_fa2 = 0; - uint32_t v_fb0 = 0; - uint32_t v_fb1 = 0; - uint32_t v_fb2 = 0; - uint32_t v_fc0 = 0; - uint32_t v_fc1 = 0; - uint32_t v_fc2 = 0; - uint32_t v_pp0 = 0; - uint32_t v_pp1 = 0; - uint32_t v_pp2 = 0; - uint32_t v_pa0 = 0; - uint32_t v_pa1 = 0; - uint32_t v_pa2 = 0; - uint32_t v_pb0 = 0; - uint32_t v_pb1 = 0; - uint32_t v_pb2 = 0; - uint32_t v_pc0 = 0; - uint32_t v_pc1 = 0; - uint32_t v_pc2 = 0; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_qoi__decoder__decode_image_config( + wuffs_qoi__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 3; - v_prev.len = 3; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end0_curr) { - v_fb0 = ((uint32_t)(v_prev.ptr[0u])); - v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0)); - v_pa0 = ((uint32_t)(v_pp0 - v_fa0)); - if (v_pa0 >= 2147483648u) { - v_pa0 = ((uint32_t)(0u - v_pa0)); - } - v_pb0 = ((uint32_t)(v_pp0 - v_fb0)); - if (v_pb0 >= 2147483648u) { - v_pb0 = ((uint32_t)(0u - v_pb0)); - } - v_pc0 = ((uint32_t)(v_pp0 - v_fc0)); - if (v_pc0 >= 2147483648u) { - v_pc0 = ((uint32_t)(0u - v_pc0)); - } - if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) { - } else if (v_pb0 <= v_pc0) { - v_fa0 = v_fb0; - } else { - v_fa0 = v_fc0; - } - v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0)))); - v_fa0 = ((uint32_t)(v_curr.ptr[0u])); - v_fc0 = v_fb0; - v_fb1 = ((uint32_t)(v_prev.ptr[1u])); - v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1)); - v_pa1 = ((uint32_t)(v_pp1 - v_fa1)); - if (v_pa1 >= 2147483648u) { - v_pa1 = ((uint32_t)(0u - v_pa1)); - } - v_pb1 = ((uint32_t)(v_pp1 - v_fb1)); - if (v_pb1 >= 2147483648u) { - v_pb1 = ((uint32_t)(0u - v_pb1)); - } - v_pc1 = ((uint32_t)(v_pp1 - v_fc1)); - if (v_pc1 >= 2147483648u) { - v_pc1 = ((uint32_t)(0u - v_pc1)); - } - if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) { - } else if (v_pb1 <= v_pc1) { - v_fa1 = v_fb1; - } else { - v_fa1 = v_fc1; - } - v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1)))); - v_fa1 = ((uint32_t)(v_curr.ptr[1u])); - v_fc1 = v_fb1; - v_fb2 = ((uint32_t)(v_prev.ptr[2u])); - v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2)); - v_pa2 = ((uint32_t)(v_pp2 - v_fa2)); - if (v_pa2 >= 2147483648u) { - v_pa2 = ((uint32_t)(0u - v_pa2)); - } - v_pb2 = ((uint32_t)(v_pp2 - v_fb2)); - if (v_pb2 >= 2147483648u) { - v_pb2 = ((uint32_t)(0u - v_pb2)); - } - v_pc2 = ((uint32_t)(v_pp2 - v_fc2)); - if (v_pc2 >= 2147483648u) { - v_pc2 = ((uint32_t)(0u - v_pc2)); + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; } - if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) { - } else if (v_pb2 <= v_pc2) { - v_fa2 = v_fb2; - } else { - v_fa2 = v_fc2; + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_qoi__error__truncated_input); + goto exit; } - v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2)))); - v_fa2 = ((uint32_t)(v_curr.ptr[2u])); - v_fc2 = v_fb2; - v_curr.ptr += 3; - v_prev.ptr += 3; + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - v_curr.len = 0; - v_prev.len = 0; + + ok: + self->private_impl.p_decode_image_config = 0; + goto exit; } - return wuffs_base__make_empty_struct(); + + goto suspend; + suspend: + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; } -// -------- func png.decoder.filter_4_distance_4_fallback +// -------- func qoi.decoder.do_decode_image_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_fallback( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - uint32_t v_fa0 = 0; - uint32_t v_fa1 = 0; - uint32_t v_fa2 = 0; - uint32_t v_fa3 = 0; - uint32_t v_fb0 = 0; - uint32_t v_fb1 = 0; - uint32_t v_fb2 = 0; - uint32_t v_fb3 = 0; - uint32_t v_fc0 = 0; - uint32_t v_fc1 = 0; - uint32_t v_fc2 = 0; - uint32_t v_fc3 = 0; - uint32_t v_pp0 = 0; - uint32_t v_pp1 = 0; - uint32_t v_pp2 = 0; - uint32_t v_pp3 = 0; - uint32_t v_pa0 = 0; - uint32_t v_pa1 = 0; - uint32_t v_pa2 = 0; - uint32_t v_pa3 = 0; - uint32_t v_pb0 = 0; - uint32_t v_pb1 = 0; - uint32_t v_pb2 = 0; - uint32_t v_pb3 = 0; - uint32_t v_pc0 = 0; - uint32_t v_pc1 = 0; - uint32_t v_pc2 = 0; - uint32_t v_pc3 = 0; +static wuffs_base__status +wuffs_qoi__decoder__do_decode_image_config( + wuffs_qoi__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end0_curr) { - v_fb0 = ((uint32_t)(v_prev.ptr[0u])); - v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0)); - v_pa0 = ((uint32_t)(v_pp0 - v_fa0)); - if (v_pa0 >= 2147483648u) { - v_pa0 = ((uint32_t)(0u - v_pa0)); - } - v_pb0 = ((uint32_t)(v_pp0 - v_fb0)); - if (v_pb0 >= 2147483648u) { - v_pb0 = ((uint32_t)(0u - v_pb0)); - } - v_pc0 = ((uint32_t)(v_pp0 - v_fc0)); - if (v_pc0 >= 2147483648u) { - v_pc0 = ((uint32_t)(0u - v_pc0)); - } - if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) { - } else if (v_pb0 <= v_pc0) { - v_fa0 = v_fb0; - } else { - v_fa0 = v_fc0; - } - v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0)))); - v_fa0 = ((uint32_t)(v_curr.ptr[0u])); - v_fc0 = v_fb0; - v_fb1 = ((uint32_t)(v_prev.ptr[1u])); - v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1)); - v_pa1 = ((uint32_t)(v_pp1 - v_fa1)); - if (v_pa1 >= 2147483648u) { - v_pa1 = ((uint32_t)(0u - v_pa1)); - } - v_pb1 = ((uint32_t)(v_pp1 - v_fb1)); - if (v_pb1 >= 2147483648u) { - v_pb1 = ((uint32_t)(0u - v_pb1)); - } - v_pc1 = ((uint32_t)(v_pp1 - v_fc1)); - if (v_pc1 >= 2147483648u) { - v_pc1 = ((uint32_t)(0u - v_pc1)); - } - if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) { - } else if (v_pb1 <= v_pc1) { - v_fa1 = v_fb1; + uint32_t v_a = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - v_fa1 = v_fc1; - } - v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1)))); - v_fa1 = ((uint32_t)(v_curr.ptr[1u])); - v_fc1 = v_fb1; - v_fb2 = ((uint32_t)(v_prev.ptr[2u])); - v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2)); - v_pa2 = ((uint32_t)(v_pp2 - v_fa2)); - if (v_pa2 >= 2147483648u) { - v_pa2 = ((uint32_t)(0u - v_pa2)); - } - v_pb2 = ((uint32_t)(v_pp2 - v_fb2)); - if (v_pb2 >= 2147483648u) { - v_pb2 = ((uint32_t)(0u - v_pb2)); - } - v_pc2 = ((uint32_t)(v_pp2 - v_fc2)); - if (v_pc2 >= 2147483648u) { - v_pc2 = ((uint32_t)(0u - v_pc2)); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } } - if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) { - } else if (v_pb2 <= v_pc2) { - v_fa2 = v_fb2; + v_a = t_0; + } + if (v_a != 1718185841u) { + status = wuffs_base__make_status(wuffs_qoi__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - v_fa2 = v_fc2; - } - v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2)))); - v_fa2 = ((uint32_t)(v_curr.ptr[2u])); - v_fc2 = v_fb2; - v_fb3 = ((uint32_t)(v_prev.ptr[3u])); - v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3)); - v_pa3 = ((uint32_t)(v_pp3 - v_fa3)); - if (v_pa3 >= 2147483648u) { - v_pa3 = ((uint32_t)(0u - v_pa3)); - } - v_pb3 = ((uint32_t)(v_pp3 - v_fb3)); - if (v_pb3 >= 2147483648u) { - v_pb3 = ((uint32_t)(0u - v_pb3)); - } - v_pc3 = ((uint32_t)(v_pp3 - v_fc3)); - if (v_pc3 >= 2147483648u) { - v_pc3 = ((uint32_t)(0u - v_pc3)); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)); + } } - if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) { - } else if (v_pb3 <= v_pc3) { - v_fa3 = v_fb3; + v_a = t_1; + } + if (v_a > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_width = v_a; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - v_fa3 = v_fc3; + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch >> 32)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)); + } } - v_curr.ptr[3u] = ((uint8_t)(v_curr.ptr[3u] + ((uint8_t)(v_fa3)))); - v_fa3 = ((uint32_t)(v_curr.ptr[3u])); - v_fc3 = v_fb3; - v_curr.ptr += 4; - v_prev.ptr += 4; + v_a = t_2; } - v_curr.len = 0; - v_prev.len = 0; - } - return wuffs_base__make_empty_struct(); -} + if (v_a > 16777215u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); + goto exit; + } + self->private_impl.f_height = v_a; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint32_t t_3 = *iop_a_src++; + v_a = t_3; + } + if (v_a == 3u) { + self->private_impl.f_pixfmt = 2415954056u; + } else if (v_a == 4u) { + self->private_impl.f_pixfmt = 2164295816u; + } else { + status = wuffs_base__make_status(wuffs_qoi__error__bad_header); + goto exit; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src++; + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + 14u, + (self->private_impl.f_pixfmt == 2415954056u)); + } + self->private_impl.f_call_sequence = 32u; -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func png.decoder.filter_1_distance_4_x86_sse42 + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_1_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr) { - wuffs_base__slice_u8 v_curr = {0}; - __m128i v_x128 = {0}; - __m128i v_a128 = {0}; + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_a128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_a128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - } - v_curr.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_a128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - } - v_curr.len = 0; + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return wuffs_base__make_empty_struct(); + + return status; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func png.decoder.filter_3_distance_4_x86_sse42 +// -------- func qoi.decoder.decode_frame_config -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_3_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - __m128i v_x128 = {0}; - __m128i v_a128 = {0}; - __m128i v_b128 = {0}; - __m128i v_p128 = {0}; - __m128i v_k128 = {0}; +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_qoi__decoder__decode_frame_config( + wuffs_qoi__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - if (((uint64_t)(a_prev.len)) == 0u) { - v_k128 = _mm_set1_epi8((int8_t)(254u)); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - v_curr.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - } - v_curr.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - } - v_curr.len = 0; - } - } else { - v_k128 = _mm_set1_epi8((int8_t)(1u)); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_p128 = _mm_avg_epu8(v_a128, v_b128); - v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_p128 = _mm_avg_epu8(v_a128, v_b128); - v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_p128 = _mm_avg_epu8(v_a128, v_b128); - v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128))); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_qoi__error__truncated_input); + goto exit; } - v_curr.len = 0; - v_prev.len = 0; + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func png.decoder.filter_4_distance_3_x86_sse42 + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_3_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - __m128i v_x128 = {0}; - __m128i v_a128 = {0}; - __m128i v_b128 = {0}; - __m128i v_c128 = {0}; - __m128i v_p128 = {0}; - __m128i v_pa128 = {0}; - __m128i v_pb128 = {0}; - __m128i v_pc128 = {0}; - __m128i v_smallest128 = {0}; - __m128i v_z128 = {0}; + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6); - while (v_curr.ptr < i_end0_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 3; - v_prev.ptr += 3; - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3); - while (v_curr.ptr < i_end1_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 3; - v_prev.len = 3; - uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3); - while (v_curr.ptr < i_end2_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 3; - v_prev.ptr += 3; - } - v_curr.len = 0; - v_prev.len = 0; + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return wuffs_base__make_empty_struct(); + return status; } -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 -// ‼ WUFFS MULTI-FILE SECTION +x86_sse42 -// -------- func png.decoder.filter_4_distance_4_x86_sse42 +// -------- func qoi.decoder.do_decode_frame_config -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2") WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_png__decoder__filter_4_distance_4_x86_sse42( - wuffs_png__decoder* self, - wuffs_base__slice_u8 a_curr, - wuffs_base__slice_u8 a_prev) { - wuffs_base__slice_u8 v_curr = {0}; - wuffs_base__slice_u8 v_prev = {0}; - __m128i v_x128 = {0}; - __m128i v_a128 = {0}; - __m128i v_b128 = {0}; - __m128i v_c128 = {0}; - __m128i v_p128 = {0}; - __m128i v_pa128 = {0}; - __m128i v_pb128 = {0}; - __m128i v_pc128 = {0}; - __m128i v_smallest128 = {0}; - __m128i v_z128 = {0}; +static wuffs_base__status +wuffs_qoi__decoder__do_decode_frame_config( + wuffs_qoi__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - { - wuffs_base__slice_u8 i_slice_curr = a_curr; - v_curr.ptr = i_slice_curr.ptr; - wuffs_base__slice_u8 i_slice_prev = a_prev; - v_prev.ptr = i_slice_prev.ptr; - i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len))); - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8); - while (v_curr.ptr < i_end0_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; - } - v_curr.len = 4; - v_prev.len = 4; - uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4); - while (v_curr.ptr < i_end1_curr) { - v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr))); - v_b128 = _mm_unpacklo_epi8(v_b128, v_z128); - v_pa128 = _mm_sub_epi16(v_b128, v_c128); - v_pb128 = _mm_sub_epi16(v_a128, v_c128); - v_pc128 = _mm_add_epi16(v_pa128, v_pb128); - v_pa128 = _mm_abs_epi16(v_pa128); - v_pb128 = _mm_abs_epi16(v_pb128); - v_pc128 = _mm_abs_epi16(v_pc128); - v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128)); - v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128)); - v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr))); - v_x128 = _mm_unpacklo_epi8(v_x128, v_z128); - v_x128 = _mm_add_epi8(v_x128, v_p128); - v_a128 = v_x128; - v_c128 = v_b128; - v_x128 = _mm_packus_epi16(v_x128, v_x128); - wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128)))); - v_curr.ptr += 4; - v_prev.ptr += 4; + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_qoi__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } - v_curr.len = 0; - v_prev.len = 0; - } - return wuffs_base__make_empty_struct(); -} -#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) -// ‼ WUFFS MULTI-FILE SECTION -x86_sse42 - -// -------- func png.decoder.get_quirk - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_png__decoder__get_quirk( - const wuffs_png__decoder* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + 14u, + 0u, + (self->private_impl.f_pixfmt == 2415954056u), + false, + 0u); + } + self->private_impl.f_call_sequence = 64u; - if ((a_key == 1u) && self->private_impl.f_ignore_checksum) { - return 1u; + ok: + self->private_impl.p_do_decode_frame_config = 0; + goto exit; } - return 0u; -} -// -------- func png.decoder.set_quirk + goto suspend; + suspend: + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__set_quirk( - wuffs_png__decoder* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (a_key == 1u) { - self->private_impl.f_ignore_checksum = (a_value > 0u); - wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, a_key, a_value); - return wuffs_base__make_status(NULL); - } - return wuffs_base__make_status(wuffs_base__error__unsupported_option); + return status; } -// -------- func png.decoder.decode_image_config +// -------- func qoi.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__decode_image_config( - wuffs_png__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { +wuffs_qoi__decoder__decode_frame( + wuffs_qoi__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -54464,12 +67805,12 @@ wuffs_png__decoder__decode_image_config( ? wuffs_base__error__disabled_by_previous_error : wuffs_base__error__initialize_not_called); } - if (!a_src) { + if (!a_dst || !a_src) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { + (self->private_impl.active_coroutine != 3)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -54478,17 +67819,22 @@ wuffs_png__decoder__decode_image_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_png__decoder__do_decode_image_config(self, a_dst, a_src); + wuffs_base__status t_0 = wuffs_qoi__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_png__error__truncated_input); + status = wuffs_base__make_status(wuffs_qoi__error__truncated_input); goto exit; } status = v_status; @@ -54496,14 +67842,14 @@ wuffs_png__decoder__decode_image_config( } ok: - self->private_impl.p_decode_image_config[0] = 0; + self->private_impl.p_decode_frame = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; goto exit; exit: @@ -54513,21 +67859,21 @@ wuffs_png__decoder__decode_image_config( return status; } -// -------- func png.decoder.do_decode_image_config +// -------- func qoi.decoder.do_decode_frame WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__do_decode_image_config( - wuffs_png__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { +wuffs_qoi__decoder__do_decode_frame( + wuffs_qoi__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint64_t v_magic = 0; - uint64_t v_mark = 0; - uint32_t v_checksum_have = 0; - uint32_t v_checksum_want = 0; wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint64_t v_c64 = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -54540,281 +67886,332 @@ wuffs_png__decoder__do_decode_image_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; - if (coro_susp_point) { - v_checksum_have = self->private_data.s_do_decode_image_config[0].v_checksum_have; - } + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if ( ! self->private_impl.f_seen_ihdr) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint64_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { - t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); - iop_a_src += 8; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; - if (num_bits_0 == 56) { - t_0 = ((uint64_t)(*scratch)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)) << 56; - } - } - v_magic = t_0; + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (v_magic != 727905341920923785u) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_qoi__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette(a_dst), + wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint64_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { - t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); - iop_a_src += 8; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 56) { - t_1 = ((uint64_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; - } - } - v_magic = t_1; + goto ok; + } + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y = 0u; + self->private_data.f_pixel[0u] = 0u; + self->private_data.f_pixel[1u] = 0u; + self->private_data.f_pixel[2u] = 0u; + self->private_data.f_pixel[3u] = 255u; + wuffs_private_impl__bulk_memset(&self->private_data.f_cache[0], 256u, 0u); + self->private_impl.f_remaining_pixels_times_4 = (((uint64_t)(self->private_impl.f_width)) * ((uint64_t)(self->private_impl.f_height)) * 4u); + while (self->private_impl.f_remaining_pixels_times_4 > 0u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - if (v_magic != 5927942488114331648u) { - if (v_magic == 5278895250759221248u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_cgbi_extension); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_qoi__decoder__from_src_to_buffer(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (self->private_impl.f_remaining_pixels_times_4 < ((uint64_t)(self->private_impl.f_buffer_index))) { + status = wuffs_base__make_status(wuffs_base__error__too_much_data); + goto exit; + } + self->private_impl.f_remaining_pixels_times_4 -= ((uint64_t)(self->private_impl.f_buffer_index)); + v_status = wuffs_qoi__decoder__from_buffer_to_dst(self, a_dst); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; } - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; + goto ok; } - self->private_impl.f_chunk_type_array[0u] = 73u; - self->private_impl.f_chunk_type_array[1u] = 72u; - self->private_impl.f_chunk_type_array[2u] = 68u; - self->private_impl.f_chunk_type_array[3u] = 82u; - wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, - sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); - while (true) { - v_mark = ((uint64_t)(iop_a_src - io0_a_src)); - { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_0 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_decode_frame.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src); - v_status = t_2; - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + uint64_t* scratch = &self->private_data.s_do_decode_frame.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); + if (num_bits_0 == 56) { + t_0 = ((uint64_t)(*scratch >> 0)); + break; } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)); } - if ( ! self->private_impl.f_ignore_checksum) { - v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); - } - if (wuffs_base__status__is_ok(&v_status)) { - break; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); } + v_c64 = t_0; + } + if (v_c64 != 1u) { + status = wuffs_base__make_status(wuffs_qoi__error__bad_footer); + goto exit; + } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func qoi.decoder.from_src_to_buffer + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_qoi__decoder__from_src_to_buffer( + wuffs_qoi__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint8_t v_dg = 0; + uint32_t v_bi = 0; + uint32_t v_bj = 0; + uint32_t v_bk = 0; + uint32_t v_ci = 0; + uint32_t v_hash4 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_from_src_to_buffer; + if (coro_susp_point) { + v_dg = self->private_data.s_from_src_to_buffer.v_dg; + v_bi = self->private_data.s_from_src_to_buffer.v_bi; + v_bk = self->private_data.s_from_src_to_buffer.v_bk; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + v_bk = 7936u; + if (self->private_impl.f_remaining_pixels_times_4 < 7936u) { + v_bk = ((uint32_t)(self->private_impl.f_remaining_pixels_times_4)); + } + while (v_bi < v_bk) { { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)); - } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_checksum_want = t_3; - } - if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) { - status = wuffs_base__make_status(wuffs_png__error__bad_checksum); - goto exit; - } - self->private_impl.f_seen_ihdr = true; - } else if (self->private_impl.f_metadata_fourcc != 0u) { - self->private_impl.f_call_sequence = 16u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; - } - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - continue; + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); - if (self->private_impl.f_chunk_type == 1413563465u) { - if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) { - break; + if (v_c8 == 254u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + self->private_data.f_pixel[2u] = t_1; } - self->private_impl.f_seen_idat = true; - } else if (self->private_impl.f_chunk_type == 1413571686u) { - if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) { - break; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + self->private_data.f_pixel[1u] = t_2; } - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - iop_a_src += 8u; - if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) { - self->private_impl.f_chunk_type_array[0u] = ((uint8_t)((self->private_impl.f_chunk_type >> 0u))); - self->private_impl.f_chunk_type_array[1u] = ((uint8_t)((self->private_impl.f_chunk_type >> 8u))); - self->private_impl.f_chunk_type_array[2u] = ((uint8_t)((self->private_impl.f_chunk_type >> 16u))); - self->private_impl.f_chunk_type_array[3u] = ((uint8_t)((self->private_impl.f_chunk_type >> 24u))); - wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, - sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); - } - while (true) { - v_mark = ((uint64_t)(iop_a_src - io0_a_src)); { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src, false); - v_status = t_4; - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + uint8_t t_3 = *iop_a_src++; + self->private_data.f_pixel[0u] = t_3; + } + } else if (v_c8 == 255u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_4 = *iop_a_src++; + self->private_data.f_pixel[2u] = t_4; } - if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) { - v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + self->private_data.f_pixel[1u] = t_5; } - if (wuffs_base__status__is_ok(&v_status)) { - break; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + self->private_data.f_pixel[0u] = t_6; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); - } - if (self->private_impl.f_metadata_fourcc != 0u) { - self->private_impl.f_call_sequence = 16u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - uint32_t t_5; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); - if (num_bits_5 == 24) { - t_5 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_5 += 8u; - *scratch |= ((uint64_t)(num_bits_5)); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_7 = *iop_a_src++; + self->private_data.f_pixel[3u] = t_7; } - v_checksum_want = t_5; - } - if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u) && (v_checksum_have != v_checksum_want)) { - status = wuffs_base__make_status(wuffs_png__error__bad_checksum); - goto exit; - } - } - if ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte) { - status = wuffs_base__make_status(wuffs_png__error__missing_palette); - goto exit; - } - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position; - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - self->private_impl.f_dst_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_first_config_io_position, - ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns)); - } - if ( ! self->private_impl.f_seen_actl) { - self->private_impl.f_num_animation_frames_value = 1u; - self->private_impl.f_first_rect_x0 = 0u; - self->private_impl.f_first_rect_y0 = 0u; - self->private_impl.f_first_rect_x1 = self->private_impl.f_width; - self->private_impl.f_first_rect_y1 = self->private_impl.f_height; - self->private_impl.f_first_duration = 0u; - self->private_impl.f_first_disposal = 0u; - self->private_impl.f_first_overwrite_instead_of_blend = false; - } - self->private_impl.f_call_sequence = 32u; + } else if (((uint8_t)(v_c8 >> 6u)) == 0u) { + v_ci = (4u * ((uint32_t)(((uint8_t)(v_c8 & 63u))))); + self->private_data.f_pixel[0u] = self->private_data.f_cache[(v_ci + 0u)]; + self->private_data.f_pixel[1u] = self->private_data.f_cache[(v_ci + 1u)]; + self->private_data.f_pixel[2u] = self->private_data.f_cache[(v_ci + 2u)]; + self->private_data.f_pixel[3u] = self->private_data.f_cache[(v_ci + 3u)]; + self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u]; + self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u]; + self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u]; + self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u]; + v_bi += 4u; + continue; + } else if (((uint8_t)(v_c8 >> 6u)) == 1u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_pixel[2u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 4u)) & 3u)) + 254u)); + self->private_data.f_pixel[1u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 2u)) & 3u)) + 254u)); + self->private_data.f_pixel[0u] += ((uint8_t)(((uint8_t)(((uint8_t)(v_c8 >> 0u)) & 3u)) + 254u)); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (((uint8_t)(v_c8 >> 6u)) == 2u) { + v_dg = ((uint8_t)(((uint8_t)(v_c8 & 63u)) + 224u)); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_8 = *iop_a_src++; + v_c8 = t_8; + } +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_data.f_pixel[2u] += ((uint8_t)(((uint8_t)(v_dg + 248u)) + ((uint8_t)(15u & ((uint8_t)(v_c8 >> 4u)))))); + self->private_data.f_pixel[1u] += v_dg; + self->private_data.f_pixel[0u] += ((uint8_t)(((uint8_t)(v_dg + 248u)) + ((uint8_t)(15u & ((uint8_t)(v_c8 >> 0u)))))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + v_bj = (v_bi + (4u * (63u & (1u + ((uint32_t)(v_c8)))))); + while (v_bi < v_bj) { + self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u]; + self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u]; + self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u]; + self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u]; + v_bi += 4u; + } + continue; + } + v_hash4 = (4u * (63u & ((((uint32_t)(self->private_data.f_pixel[2u])) * 3u) + + (((uint32_t)(self->private_data.f_pixel[1u])) * 5u) + + (((uint32_t)(self->private_data.f_pixel[0u])) * 7u) + + (((uint32_t)(self->private_data.f_pixel[3u])) * 11u)))); + self->private_data.f_cache[(v_hash4 + 0u)] = self->private_data.f_pixel[0u]; + self->private_data.f_cache[(v_hash4 + 1u)] = self->private_data.f_pixel[1u]; + self->private_data.f_cache[(v_hash4 + 2u)] = self->private_data.f_pixel[2u]; + self->private_data.f_cache[(v_hash4 + 3u)] = self->private_data.f_pixel[3u]; + self->private_data.f_buffer[(v_bi + 0u)] = self->private_data.f_pixel[0u]; + self->private_data.f_buffer[(v_bi + 1u)] = self->private_data.f_pixel[1u]; + self->private_data.f_buffer[(v_bi + 2u)] = self->private_data.f_pixel[2u]; + self->private_data.f_buffer[(v_bi + 3u)] = self->private_data.f_pixel[3u]; + v_bi += 4u; + } + self->private_impl.f_buffer_index = v_bi; + goto ok; ok: - self->private_impl.p_do_decode_image_config[0] = 0; + self->private_impl.p_from_src_to_buffer = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_image_config[0].v_checksum_have = v_checksum_have; + self->private_impl.p_from_src_to_buffer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_from_src_to_buffer.v_dg = v_dg; + self->private_data.s_from_src_to_buffer.v_bi = v_bi; + self->private_data.s_from_src_to_buffer.v_bk = v_bk; goto exit; exit: @@ -54825,1068 +68222,1113 @@ wuffs_png__decoder__do_decode_image_config( return status; } -// -------- func png.decoder.decode_ihdr +// -------- func qoi.decoder.from_buffer_to_dst WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__decode_ihdr( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_a32 = 0; - uint8_t v_a8 = 0; +wuffs_qoi__decoder__from_buffer_to_dst( + wuffs_qoi__decoder* self, + wuffs_base__pixel_buffer* a_dst) { + 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_bytes_per_row = 0; + wuffs_base__table_u8 v_tab = {0}; + uint32_t v_bi = 0; + uint32_t v_rem_x = 0; + wuffs_base__slice_u8 v_dst = {0}; + wuffs_base__slice_u8 v_src = {0}; + uint32_t v_src_length = 0; + uint64_t v_i = 0; - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } - - uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_ihdr[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - v_a32 = t_0; - } - if ((v_a32 == 0u) || (v_a32 > 2147483647u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; - } else if (v_a32 > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_width = v_a32; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_ihdr[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } - } - v_a32 = t_1; - } - if ((v_a32 == 0u) || (v_a32 > 2147483647u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; - } else if (v_a32 > 16777215u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - self->private_impl.f_height = v_a32; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - v_a8 = t_2; - } - if (v_a8 > 16u) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; - } - self->private_impl.f_depth = v_a8; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_a8 = t_3; - } - if ((v_a8 == 1u) || (v_a8 == 5u) || (v_a8 > 6u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; - } - self->private_impl.f_color_type = v_a8; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_a8 = t_4; - } - if (v_a8 != 0u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + while (v_bi < self->private_impl.f_buffer_index) { + if (self->private_impl.f_width <= self->private_impl.f_dst_x) { + self->private_impl.f_dst_x = 0u; + self->private_impl.f_dst_y += 1u; + if (self->private_impl.f_dst_y >= self->private_impl.f_height) { + break; } - uint8_t t_5 = *iop_a_src++; - v_a8 = t_5; - } - if (v_a8 != 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; + v_rem_x = self->private_impl.f_width; + } else { + v_rem_x = (self->private_impl.f_width - self->private_impl.f_dst_x); } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_6 = *iop_a_src++; - v_a8 = t_6; + v_src = wuffs_base__make_slice_u8_ij(self->private_data.f_buffer, v_bi, self->private_impl.f_buffer_index); + if (((uint64_t)((4u * v_rem_x))) < ((uint64_t)(v_src.len))) { + v_src = wuffs_base__slice_u8__subslice_j(v_src, ((uint64_t)((4u * v_rem_x)))); } - if (v_a8 == 0u) { - self->private_impl.f_interlace_pass = 0u; - } else if (v_a8 == 1u) { - self->private_impl.f_interlace_pass = 1u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - } else { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; + v_src_length = ((uint32_t)(((uint64_t)(v_src.len)))); + v_bi += v_src_length; + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, self->private_impl.f_dst_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); } - self->private_impl.f_filter_distance = 0u; - wuffs_png__decoder__assign_filter_distance(self); - if (self->private_impl.f_filter_distance == 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_header); - goto exit; + v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel))); + self->private_impl.f_dst_x += (v_src_length / 4u); + if (v_i < ((uint64_t)(v_dst.len))) { + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), wuffs_base__pixel_buffer__palette(a_dst), v_src); } - self->private_impl.f_overall_workbuf_length = (((uint64_t)(self->private_impl.f_height)) * (1u + wuffs_png__decoder__calculate_bytes_per_row(self, self->private_impl.f_width))); - wuffs_png__decoder__choose_filter_implementations(self); + } + return wuffs_base__make_status(NULL); +} - goto ok; - ok: - self->private_impl.p_decode_ihdr[0] = 0; - goto exit; +// -------- func qoi.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_qoi__decoder__frame_dirty_rect( + const wuffs_qoi__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); } - goto suspend; - suspend: - self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); +} + +// -------- func qoi.decoder.num_animation_loops + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_qoi__decoder__num_animation_loops( + const wuffs_qoi__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func qoi.decoder.num_decoded_frame_configs + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_qoi__decoder__num_decoded_frame_configs( + const wuffs_qoi__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; +} +// -------- func qoi.decoder.num_decoded_frames + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_qoi__decoder__num_decoded_frames( + const wuffs_qoi__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; +} + +// -------- func qoi.decoder.restart_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_qoi__decoder__restart_frame( + wuffs_qoi__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if ((a_index != 0u) || (a_io_position != 14u)) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + return wuffs_base__make_status(NULL); +} + +// -------- func qoi.decoder.set_report_metadata + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_qoi__decoder__set_report_metadata( + wuffs_qoi__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func qoi.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_qoi__decoder__tell_me_more( + wuffs_qoi__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + + goto ok; + ok: goto exit; exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return status; } -// -------- func png.decoder.assign_filter_distance +// -------- func qoi.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_qoi__decoder__workbuf_len( + const wuffs_qoi__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) + +// ---------------- Status Codes Implementations + +// ---------------- Private Consts + +static const uint32_t +WUFFS_SHA256__INITIAL_SHA256_H[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1779033703u, 3144134277u, 1013904242u, 2773480762u, 1359893119u, 2600822924u, 528734635u, 1541459225u, +}; + +static const uint32_t +WUFFS_SHA256__K[64] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1116352408u, 1899447441u, 3049323471u, 3921009573u, 961987163u, 1508970993u, 2453635748u, 2870763221u, + 3624381080u, 310598401u, 607225278u, 1426881987u, 1925078388u, 2162078206u, 2614888103u, 3248222580u, + 3835390401u, 4022224774u, 264347078u, 604807628u, 770255983u, 1249150122u, 1555081692u, 1996064986u, + 2554220882u, 2821834349u, 2952996808u, 3210313671u, 3336571891u, 3584528711u, 113926993u, 338241895u, + 666307205u, 773529912u, 1294757372u, 1396182291u, 1695183700u, 1986661051u, 2177026350u, 2456956037u, + 2730485921u, 2820302411u, 3259730800u, 3345764771u, 3516065817u, 3600352804u, 4094571909u, 275423344u, + 430227734u, 506948616u, 659060556u, 883997877u, 958139571u, 1322822218u, 1537002063u, 1747873779u, + 1955562222u, 2024104815u, 2227730452u, 2361852424u, 2428436474u, 2756734187u, 3204031479u, 3329325298u, +}; + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_png__decoder__assign_filter_distance( - wuffs_png__decoder* self) { - if (self->private_impl.f_depth < 8u) { - if ((self->private_impl.f_depth != 1u) && (self->private_impl.f_depth != 2u) && (self->private_impl.f_depth != 4u)) { - return wuffs_base__make_empty_struct(); - } else if (self->private_impl.f_color_type == 0u) { - self->private_impl.f_dst_pixfmt = 536870920u; - self->private_impl.f_src_pixfmt = 536870920u; - } else if (self->private_impl.f_color_type == 3u) { - self->private_impl.f_dst_pixfmt = 2198077448u; - self->private_impl.f_src_pixfmt = 2198077448u; +wuffs_sha256__hasher__up( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x); + +// ---------------- VTables + +const wuffs_base__hasher_bitvec256__func_ptrs +wuffs_sha256__hasher__func_ptrs_for__wuffs_base__hasher_bitvec256 = { + (wuffs_base__bitvec256(*)(const void*))(&wuffs_sha256__hasher__checksum_bitvec256), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_sha256__hasher__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_sha256__hasher__set_quirk), + (wuffs_base__empty_struct(*)(void*, + wuffs_base__slice_u8))(&wuffs_sha256__hasher__update), + (wuffs_base__bitvec256(*)(void*, + wuffs_base__slice_u8))(&wuffs_sha256__hasher__update_bitvec256), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_sha256__hasher__initialize( + wuffs_sha256__hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; } else { - return wuffs_base__make_empty_struct(); + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } - self->private_impl.f_filter_distance = 1u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - } else if (self->private_impl.f_color_type == 0u) { - if (self->private_impl.f_depth == 8u) { - self->private_impl.f_dst_pixfmt = 536870920u; - self->private_impl.f_src_pixfmt = 536870920u; - self->private_impl.f_filter_distance = 1u; - } else if (self->private_impl.f_depth == 16u) { - if (self->private_impl.f_interlace_pass == 0u) { - self->private_impl.f_dst_pixfmt = 536870923u; - self->private_impl.f_src_pixfmt = 537919499u; - } else { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__hasher_bitvec256.vtable_name = + wuffs_base__hasher_bitvec256__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_bitvec256.function_pointers = + (const void*)(&wuffs_sha256__hasher__func_ptrs_for__wuffs_base__hasher_bitvec256); + return wuffs_base__make_status(NULL); +} + +wuffs_sha256__hasher* +wuffs_sha256__hasher__alloc(void) { + wuffs_sha256__hasher* x = + (wuffs_sha256__hasher*)(calloc(1, sizeof(wuffs_sha256__hasher))); + if (!x) { + return NULL; + } + if (wuffs_sha256__hasher__initialize( + x, sizeof(wuffs_sha256__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; +} + +size_t +sizeof__wuffs_sha256__hasher(void) { + return sizeof(wuffs_sha256__hasher); +} + +// ---------------- Function Implementations + +// -------- func sha256.hasher.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_sha256__hasher__get_quirk( + const wuffs_sha256__hasher* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func sha256.hasher.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_sha256__hasher__set_quirk( + wuffs_sha256__hasher* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func sha256.hasher.update + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_sha256__hasher__update( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } + + uint64_t v_new_lmu = 0; + + if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) { + self->private_impl.f_h0 = WUFFS_SHA256__INITIAL_SHA256_H[0u]; + self->private_impl.f_h1 = WUFFS_SHA256__INITIAL_SHA256_H[1u]; + self->private_impl.f_h2 = WUFFS_SHA256__INITIAL_SHA256_H[2u]; + self->private_impl.f_h3 = WUFFS_SHA256__INITIAL_SHA256_H[3u]; + self->private_impl.f_h4 = WUFFS_SHA256__INITIAL_SHA256_H[4u]; + self->private_impl.f_h5 = WUFFS_SHA256__INITIAL_SHA256_H[5u]; + self->private_impl.f_h6 = WUFFS_SHA256__INITIAL_SHA256_H[6u]; + self->private_impl.f_h7 = WUFFS_SHA256__INITIAL_SHA256_H[7u]; + } + v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len)))); + self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64); + self->private_impl.f_length_modulo_u64 = v_new_lmu; + if (self->private_impl.f_buf_len != 0u) { + while (self->private_impl.f_buf_len < 64u) { + if (((uint64_t)(a_x.len)) <= 0u) { + return wuffs_base__make_empty_struct(); } - self->private_impl.f_filter_distance = 2u; - } - } else if (self->private_impl.f_color_type == 2u) { - if (self->private_impl.f_depth == 8u) { - self->private_impl.f_dst_pixfmt = 2147485832u; - self->private_impl.f_src_pixfmt = 2684356744u; - self->private_impl.f_filter_distance = 3u; - } else if (self->private_impl.f_depth == 16u) { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; - self->private_impl.f_filter_distance = 6u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - } - } else if (self->private_impl.f_color_type == 3u) { - if (self->private_impl.f_depth == 8u) { - self->private_impl.f_dst_pixfmt = 2198077448u; - self->private_impl.f_src_pixfmt = 2198077448u; - self->private_impl.f_filter_distance = 1u; - } - } else if (self->private_impl.f_color_type == 4u) { - if (self->private_impl.f_depth == 8u) { - self->private_impl.f_dst_pixfmt = 2164295816u; - self->private_impl.f_src_pixfmt = 2164295816u; - self->private_impl.f_filter_distance = 2u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - } else if (self->private_impl.f_depth == 16u) { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; - self->private_impl.f_filter_distance = 4u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - } - } else if (self->private_impl.f_color_type == 6u) { - if (self->private_impl.f_depth == 8u) { - self->private_impl.f_dst_pixfmt = 2164295816u; - self->private_impl.f_src_pixfmt = 2701166728u; - self->private_impl.f_filter_distance = 4u; - } else if (self->private_impl.f_depth == 16u) { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; - self->private_impl.f_filter_distance = 8u; - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); + self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u]; + self->private_impl.f_buf_len += 1u; + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); } + self->private_impl.f_buf_len = 0u; + wuffs_sha256__hasher__up(self, wuffs_base__make_slice_u8(self->private_impl.f_buf_data, 64)); } + wuffs_sha256__hasher__up(self, a_x); return wuffs_base__make_empty_struct(); } -// -------- func png.decoder.calculate_bytes_per_row +// -------- func sha256.hasher.update_bitvec256 WUFFS_BASE__GENERATED_C_CODE -static uint64_t -wuffs_png__decoder__calculate_bytes_per_row( - const wuffs_png__decoder* self, - uint32_t a_width) { - uint64_t v_bytes_per_channel = 0; - - if (self->private_impl.f_depth == 1u) { - return ((uint64_t)(((a_width + 7u) / 8u))); - } else if (self->private_impl.f_depth == 2u) { - return ((uint64_t)(((a_width + 3u) / 4u))); - } else if (self->private_impl.f_depth == 4u) { - return ((uint64_t)(((a_width + 1u) / 2u))); +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_sha256__hasher__update_bitvec256( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); } - v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3u))); - return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type]))); + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); + } + + wuffs_sha256__hasher__update(self, a_x); + return wuffs_sha256__hasher__checksum_bitvec256(self); } -// -------- func png.decoder.choose_filter_implementations +// -------- func sha256.hasher.up WUFFS_BASE__GENERATED_C_CODE static wuffs_base__empty_struct -wuffs_png__decoder__choose_filter_implementations( - wuffs_png__decoder* self) { - if (self->private_impl.f_filter_distance == 3u) { - self->private_impl.choosy_filter_1 = ( - &wuffs_png__decoder__filter_1_distance_3_fallback); - self->private_impl.choosy_filter_3 = ( - &wuffs_png__decoder__filter_3_distance_3_fallback); - self->private_impl.choosy_filter_4 = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 : -#endif - &wuffs_png__decoder__filter_4_distance_3_fallback); - } else if (self->private_impl.f_filter_distance == 4u) { - self->private_impl.choosy_filter_1 = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 : -#endif - &wuffs_png__decoder__filter_1_distance_4_fallback); - self->private_impl.choosy_filter_3 = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 : -#endif - &wuffs_png__decoder__filter_3_distance_4_fallback); - self->private_impl.choosy_filter_4 = ( -#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON) - wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon : -#endif -#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY) - wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 : -#endif - &wuffs_png__decoder__filter_4_distance_4_fallback); +wuffs_sha256__hasher__up( + wuffs_sha256__hasher* self, + wuffs_base__slice_u8 a_x) { + wuffs_base__slice_u8 v_p = {0}; + uint32_t v_w[64] = {0}; + uint32_t v_w2 = 0; + uint32_t v_w15 = 0; + uint32_t v_s0 = 0; + uint32_t v_s1 = 0; + uint32_t v_t1 = 0; + uint32_t v_t2 = 0; + uint32_t v_a = 0; + uint32_t v_b = 0; + uint32_t v_c = 0; + uint32_t v_d = 0; + uint32_t v_e = 0; + uint32_t v_f = 0; + uint32_t v_g = 0; + uint32_t v_h = 0; + uint32_t v_i = 0; + uint32_t v_buf_len = 0; + + v_a = self->private_impl.f_h0; + v_b = self->private_impl.f_h1; + v_c = self->private_impl.f_h2; + v_d = self->private_impl.f_h3; + v_e = self->private_impl.f_h4; + v_f = self->private_impl.f_h5; + v_g = self->private_impl.f_h6; + v_h = self->private_impl.f_h7; + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 64; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64)); + while (v_p.ptr < i_end0_p) { + v_w[0u] = ((((uint32_t)(v_p.ptr[0u])) << 24u) | + (((uint32_t)(v_p.ptr[1u])) << 16u) | + (((uint32_t)(v_p.ptr[2u])) << 8u) | + ((uint32_t)(v_p.ptr[3u]))); + v_w[1u] = ((((uint32_t)(v_p.ptr[4u])) << 24u) | + (((uint32_t)(v_p.ptr[5u])) << 16u) | + (((uint32_t)(v_p.ptr[6u])) << 8u) | + ((uint32_t)(v_p.ptr[7u]))); + v_w[2u] = ((((uint32_t)(v_p.ptr[8u])) << 24u) | + (((uint32_t)(v_p.ptr[9u])) << 16u) | + (((uint32_t)(v_p.ptr[10u])) << 8u) | + ((uint32_t)(v_p.ptr[11u]))); + v_w[3u] = ((((uint32_t)(v_p.ptr[12u])) << 24u) | + (((uint32_t)(v_p.ptr[13u])) << 16u) | + (((uint32_t)(v_p.ptr[14u])) << 8u) | + ((uint32_t)(v_p.ptr[15u]))); + v_w[4u] = ((((uint32_t)(v_p.ptr[16u])) << 24u) | + (((uint32_t)(v_p.ptr[17u])) << 16u) | + (((uint32_t)(v_p.ptr[18u])) << 8u) | + ((uint32_t)(v_p.ptr[19u]))); + v_w[5u] = ((((uint32_t)(v_p.ptr[20u])) << 24u) | + (((uint32_t)(v_p.ptr[21u])) << 16u) | + (((uint32_t)(v_p.ptr[22u])) << 8u) | + ((uint32_t)(v_p.ptr[23u]))); + v_w[6u] = ((((uint32_t)(v_p.ptr[24u])) << 24u) | + (((uint32_t)(v_p.ptr[25u])) << 16u) | + (((uint32_t)(v_p.ptr[26u])) << 8u) | + ((uint32_t)(v_p.ptr[27u]))); + v_w[7u] = ((((uint32_t)(v_p.ptr[28u])) << 24u) | + (((uint32_t)(v_p.ptr[29u])) << 16u) | + (((uint32_t)(v_p.ptr[30u])) << 8u) | + ((uint32_t)(v_p.ptr[31u]))); + v_w[8u] = ((((uint32_t)(v_p.ptr[32u])) << 24u) | + (((uint32_t)(v_p.ptr[33u])) << 16u) | + (((uint32_t)(v_p.ptr[34u])) << 8u) | + ((uint32_t)(v_p.ptr[35u]))); + v_w[9u] = ((((uint32_t)(v_p.ptr[36u])) << 24u) | + (((uint32_t)(v_p.ptr[37u])) << 16u) | + (((uint32_t)(v_p.ptr[38u])) << 8u) | + ((uint32_t)(v_p.ptr[39u]))); + v_w[10u] = ((((uint32_t)(v_p.ptr[40u])) << 24u) | + (((uint32_t)(v_p.ptr[41u])) << 16u) | + (((uint32_t)(v_p.ptr[42u])) << 8u) | + ((uint32_t)(v_p.ptr[43u]))); + v_w[11u] = ((((uint32_t)(v_p.ptr[44u])) << 24u) | + (((uint32_t)(v_p.ptr[45u])) << 16u) | + (((uint32_t)(v_p.ptr[46u])) << 8u) | + ((uint32_t)(v_p.ptr[47u]))); + v_w[12u] = ((((uint32_t)(v_p.ptr[48u])) << 24u) | + (((uint32_t)(v_p.ptr[49u])) << 16u) | + (((uint32_t)(v_p.ptr[50u])) << 8u) | + ((uint32_t)(v_p.ptr[51u]))); + v_w[13u] = ((((uint32_t)(v_p.ptr[52u])) << 24u) | + (((uint32_t)(v_p.ptr[53u])) << 16u) | + (((uint32_t)(v_p.ptr[54u])) << 8u) | + ((uint32_t)(v_p.ptr[55u]))); + v_w[14u] = ((((uint32_t)(v_p.ptr[56u])) << 24u) | + (((uint32_t)(v_p.ptr[57u])) << 16u) | + (((uint32_t)(v_p.ptr[58u])) << 8u) | + ((uint32_t)(v_p.ptr[59u]))); + v_w[15u] = ((((uint32_t)(v_p.ptr[60u])) << 24u) | + (((uint32_t)(v_p.ptr[61u])) << 16u) | + (((uint32_t)(v_p.ptr[62u])) << 8u) | + ((uint32_t)(v_p.ptr[63u]))); + v_i = 16u; + while (v_i < 64u) { + v_w2 = v_w[(v_i - 2u)]; + v_s1 = ((v_w2 >> 10u) ^ (((uint32_t)(v_w2 << 15u)) | (v_w2 >> 17u)) ^ (((uint32_t)(v_w2 << 13u)) | (v_w2 >> 19u))); + v_w15 = v_w[(v_i - 15u)]; + v_s0 = ((v_w15 >> 3u) ^ (((uint32_t)(v_w15 << 25u)) | (v_w15 >> 7u)) ^ (((uint32_t)(v_w15 << 14u)) | (v_w15 >> 18u))); + v_w[v_i] = ((uint32_t)(((uint32_t)(((uint32_t)(v_s1 + v_w[(v_i - 7u)])) + v_s0)) + v_w[(v_i - 16u)])); + v_i += 1u; + } + v_i = 0u; + while (v_i < 64u) { + v_t1 = v_h; + v_t1 += ((((uint32_t)(v_e << 26u)) | (v_e >> 6u)) ^ (((uint32_t)(v_e << 21u)) | (v_e >> 11u)) ^ (((uint32_t)(v_e << 7u)) | (v_e >> 25u))); + v_t1 += ((v_e & v_f) ^ ((4294967295u ^ v_e) & v_g)); + v_t1 += WUFFS_SHA256__K[v_i]; + v_t1 += v_w[v_i]; + v_t2 = ((((uint32_t)(v_a << 30u)) | (v_a >> 2u)) ^ (((uint32_t)(v_a << 19u)) | (v_a >> 13u)) ^ (((uint32_t)(v_a << 10u)) | (v_a >> 22u))); + v_t2 += ((v_a & v_b) ^ (v_a & v_c) ^ (v_b & v_c)); + v_h = v_g; + v_g = v_f; + v_f = v_e; + v_e = ((uint32_t)(v_d + v_t1)); + v_d = v_c; + v_c = v_b; + v_b = v_a; + v_a = ((uint32_t)(v_t1 + v_t2)); + v_i += 1u; + } + v_a += self->private_impl.f_h0; + self->private_impl.f_h0 = v_a; + v_b += self->private_impl.f_h1; + self->private_impl.f_h1 = v_b; + v_c += self->private_impl.f_h2; + self->private_impl.f_h2 = v_c; + v_d += self->private_impl.f_h3; + self->private_impl.f_h3 = v_d; + v_e += self->private_impl.f_h4; + self->private_impl.f_h4 = v_e; + v_f += self->private_impl.f_h5; + self->private_impl.f_h5 = v_f; + v_g += self->private_impl.f_h6; + self->private_impl.f_h6 = v_g; + v_h += self->private_impl.f_h7; + self->private_impl.f_h7 = v_h; + v_p.ptr += 64; + } + v_p.len = 1; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end1_p) { + self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u]; + v_buf_len = ((v_buf_len + 1u) & 63u); + v_p.ptr += 1; + } + v_p.len = 0; } + self->private_impl.f_buf_len = ((uint32_t)((((uint64_t)(a_x.len)) & 63u))); return wuffs_base__make_empty_struct(); } -// -------- func png.decoder.decode_other_chunk +// -------- func sha256.hasher.checksum_bitvec256 WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_other_chunk( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src, - bool a_framy) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +WUFFS_BASE__MAYBE_STATIC wuffs_base__bitvec256 +wuffs_sha256__hasher__checksum_bitvec256( + const wuffs_sha256__hasher* self) { + if (!self) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_bitvec256(0u, 0u, 0u, 0u); } - uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + uint32_t v_buf_len = 0; + uint8_t v_buf_data[64] = {0}; + uint64_t v_length_in_bits = 0; + uint32_t v_w[64] = {0}; + uint32_t v_w2 = 0; + uint32_t v_w15 = 0; + uint32_t v_s0 = 0; + uint32_t v_s1 = 0; + uint32_t v_t1 = 0; + uint32_t v_t2 = 0; + uint32_t v_h0 = 0; + uint32_t v_h1 = 0; + uint32_t v_h2 = 0; + uint32_t v_h3 = 0; + uint32_t v_h4 = 0; + uint32_t v_h5 = 0; + uint32_t v_h6 = 0; + uint32_t v_h7 = 0; + uint32_t v_a = 0; + uint32_t v_b = 0; + uint32_t v_c = 0; + uint32_t v_d = 0; + uint32_t v_e = 0; + uint32_t v_f = 0; + uint32_t v_g = 0; + uint32_t v_h = 0; + uint32_t v_i = 0; + bool v_final_block = false; - if ((self->private_impl.f_chunk_type == 1163152464u) && ! a_framy) { - if (self->private_impl.f_seen_plte) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } else if (self->private_impl.f_color_type == 3u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_png__decoder__decode_plte(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else if ((self->private_impl.f_color_type == 2u) || (self->private_impl.f_color_type == 6u)) { - } else { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_seen_plte = true; - } else if ((self->private_impl.f_chunk_type & 32u) == 0u) { - if (self->private_impl.f_chunk_type != 1413563465u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } + v_i = 0u; + while (v_i < 64u) { + v_buf_data[v_i] = self->private_impl.f_buf_data[v_i]; + v_i += 1u; + } + v_buf_len = (self->private_impl.f_buf_len & 63u); + if (v_buf_len < 56u) { + v_buf_data[v_buf_len] = 128u; + v_buf_len += 1u; + while (v_buf_len < 56u) { + v_buf_data[v_buf_len] = 0u; + v_buf_len += 1u; } - if (self->private_impl.f_chunk_type == 1716082789u) { - if (self->private_impl.f_report_metadata_exif) { - if (self->private_impl.f_seen_exif) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_png__decoder__decode_exif(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_exif = true; - } - } else if ((self->private_impl.f_chunk_type == 1951945833u) || (self->private_impl.f_chunk_type == 1951942004u) || (self->private_impl.f_chunk_type == 1951945850u)) { - if (self->private_impl.f_report_metadata_kvp) { - self->private_impl.f_metadata_flavor = 4u; - self->private_impl.f_metadata_fourcc = 1263947851u; - self->private_impl.f_metadata_x = 0u; - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; - } - } else if ( ! a_framy) { - if (self->private_impl.f_chunk_type == 1280598881u) { - if (self->private_impl.f_seen_actl) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - status = wuffs_png__decoder__decode_actl(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_actl = true; - } else if (self->private_impl.f_chunk_type == 1297238115u) { - if (self->private_impl.f_report_metadata_chrm) { - if (self->private_impl.f_seen_chrm) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - status = wuffs_png__decoder__decode_chrm(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_chrm = true; - } - } else if (self->private_impl.f_chunk_type == 1280598886u) { - if (self->private_impl.f_seen_fctl) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - 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_png__decoder__decode_fctl(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_fctl = true; - } else if (self->private_impl.f_chunk_type == 1095582055u) { - if (self->private_impl.f_report_metadata_gama) { - if (self->private_impl.f_seen_gama) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - status = wuffs_png__decoder__decode_gama(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_gama = true; - } - } else if (self->private_impl.f_chunk_type == 1346585449u) { - if (self->private_impl.f_report_metadata_iccp) { - if (self->private_impl.f_seen_iccp) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - status = wuffs_png__decoder__decode_iccp(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_iccp = true; - } - } else if (self->private_impl.f_chunk_type == 1111970419u) { - if (self->private_impl.f_report_metadata_srgb) { - if (self->private_impl.f_seen_srgb) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - status = wuffs_png__decoder__decode_srgb(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_srgb = true; - } - } else if (self->private_impl.f_chunk_type == 1397641844u) { - if (self->private_impl.f_seen_trns || (self->private_impl.f_color_type > 3u) || ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte)) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_png__decoder__decode_trns(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_impl.f_seen_trns = true; - } + v_final_block = true; + } else { + v_buf_data[v_buf_len] = 128u; + v_buf_len += 1u; + while (v_buf_len < 64u) { + v_buf_data[v_buf_len] = 0u; + v_buf_len += 1u; + } + } + v_h0 = self->private_impl.f_h0; + v_a = v_h0; + v_h1 = self->private_impl.f_h1; + v_b = v_h1; + v_h2 = self->private_impl.f_h2; + v_c = v_h2; + v_h3 = self->private_impl.f_h3; + v_d = v_h3; + v_h4 = self->private_impl.f_h4; + v_e = v_h4; + v_h5 = self->private_impl.f_h5; + v_f = v_h5; + v_h6 = self->private_impl.f_h6; + v_g = v_h6; + v_h7 = self->private_impl.f_h7; + v_h = v_h7; + while (true) { + if (v_final_block) { + v_length_in_bits = ((uint64_t)(self->private_impl.f_length_modulo_u64 * 8u)); + v_buf_data[56u] = ((uint8_t)((v_length_in_bits >> 56u))); + v_buf_data[57u] = ((uint8_t)((v_length_in_bits >> 48u))); + v_buf_data[58u] = ((uint8_t)((v_length_in_bits >> 40u))); + v_buf_data[59u] = ((uint8_t)((v_length_in_bits >> 32u))); + v_buf_data[60u] = ((uint8_t)((v_length_in_bits >> 24u))); + v_buf_data[61u] = ((uint8_t)((v_length_in_bits >> 16u))); + v_buf_data[62u] = ((uint8_t)((v_length_in_bits >> 8u))); + v_buf_data[63u] = ((uint8_t)(v_length_in_bits)); + } + v_w[0u] = ((((uint32_t)(v_buf_data[0u])) << 24u) | + (((uint32_t)(v_buf_data[1u])) << 16u) | + (((uint32_t)(v_buf_data[2u])) << 8u) | + ((uint32_t)(v_buf_data[3u]))); + v_w[1u] = ((((uint32_t)(v_buf_data[4u])) << 24u) | + (((uint32_t)(v_buf_data[5u])) << 16u) | + (((uint32_t)(v_buf_data[6u])) << 8u) | + ((uint32_t)(v_buf_data[7u]))); + v_w[2u] = ((((uint32_t)(v_buf_data[8u])) << 24u) | + (((uint32_t)(v_buf_data[9u])) << 16u) | + (((uint32_t)(v_buf_data[10u])) << 8u) | + ((uint32_t)(v_buf_data[11u]))); + v_w[3u] = ((((uint32_t)(v_buf_data[12u])) << 24u) | + (((uint32_t)(v_buf_data[13u])) << 16u) | + (((uint32_t)(v_buf_data[14u])) << 8u) | + ((uint32_t)(v_buf_data[15u]))); + v_w[4u] = ((((uint32_t)(v_buf_data[16u])) << 24u) | + (((uint32_t)(v_buf_data[17u])) << 16u) | + (((uint32_t)(v_buf_data[18u])) << 8u) | + ((uint32_t)(v_buf_data[19u]))); + v_w[5u] = ((((uint32_t)(v_buf_data[20u])) << 24u) | + (((uint32_t)(v_buf_data[21u])) << 16u) | + (((uint32_t)(v_buf_data[22u])) << 8u) | + ((uint32_t)(v_buf_data[23u]))); + v_w[6u] = ((((uint32_t)(v_buf_data[24u])) << 24u) | + (((uint32_t)(v_buf_data[25u])) << 16u) | + (((uint32_t)(v_buf_data[26u])) << 8u) | + ((uint32_t)(v_buf_data[27u]))); + v_w[7u] = ((((uint32_t)(v_buf_data[28u])) << 24u) | + (((uint32_t)(v_buf_data[29u])) << 16u) | + (((uint32_t)(v_buf_data[30u])) << 8u) | + ((uint32_t)(v_buf_data[31u]))); + v_w[8u] = ((((uint32_t)(v_buf_data[32u])) << 24u) | + (((uint32_t)(v_buf_data[33u])) << 16u) | + (((uint32_t)(v_buf_data[34u])) << 8u) | + ((uint32_t)(v_buf_data[35u]))); + v_w[9u] = ((((uint32_t)(v_buf_data[36u])) << 24u) | + (((uint32_t)(v_buf_data[37u])) << 16u) | + (((uint32_t)(v_buf_data[38u])) << 8u) | + ((uint32_t)(v_buf_data[39u]))); + v_w[10u] = ((((uint32_t)(v_buf_data[40u])) << 24u) | + (((uint32_t)(v_buf_data[41u])) << 16u) | + (((uint32_t)(v_buf_data[42u])) << 8u) | + ((uint32_t)(v_buf_data[43u]))); + v_w[11u] = ((((uint32_t)(v_buf_data[44u])) << 24u) | + (((uint32_t)(v_buf_data[45u])) << 16u) | + (((uint32_t)(v_buf_data[46u])) << 8u) | + ((uint32_t)(v_buf_data[47u]))); + v_w[12u] = ((((uint32_t)(v_buf_data[48u])) << 24u) | + (((uint32_t)(v_buf_data[49u])) << 16u) | + (((uint32_t)(v_buf_data[50u])) << 8u) | + ((uint32_t)(v_buf_data[51u]))); + v_w[13u] = ((((uint32_t)(v_buf_data[52u])) << 24u) | + (((uint32_t)(v_buf_data[53u])) << 16u) | + (((uint32_t)(v_buf_data[54u])) << 8u) | + ((uint32_t)(v_buf_data[55u]))); + v_w[14u] = ((((uint32_t)(v_buf_data[56u])) << 24u) | + (((uint32_t)(v_buf_data[57u])) << 16u) | + (((uint32_t)(v_buf_data[58u])) << 8u) | + ((uint32_t)(v_buf_data[59u]))); + v_w[15u] = ((((uint32_t)(v_buf_data[60u])) << 24u) | + (((uint32_t)(v_buf_data[61u])) << 16u) | + (((uint32_t)(v_buf_data[62u])) << 8u) | + ((uint32_t)(v_buf_data[63u]))); + v_i = 16u; + while (v_i < 64u) { + v_w2 = v_w[(v_i - 2u)]; + v_s1 = ((v_w2 >> 10u) ^ (((uint32_t)(v_w2 << 15u)) | (v_w2 >> 17u)) ^ (((uint32_t)(v_w2 << 13u)) | (v_w2 >> 19u))); + v_w15 = v_w[(v_i - 15u)]; + v_s0 = ((v_w15 >> 3u) ^ (((uint32_t)(v_w15 << 25u)) | (v_w15 >> 7u)) ^ (((uint32_t)(v_w15 << 14u)) | (v_w15 >> 18u))); + v_w[v_i] = ((uint32_t)(((uint32_t)(((uint32_t)(v_s1 + v_w[(v_i - 7u)])) + v_s0)) + v_w[(v_i - 16u)])); + v_i += 1u; } - if (self->private_impl.f_metadata_fourcc == 0u) { - self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_decode_other_chunk[0].scratch; + v_i = 0u; + while (v_i < 64u) { + v_t1 = v_h; + v_t1 += ((((uint32_t)(v_e << 26u)) | (v_e >> 6u)) ^ (((uint32_t)(v_e << 21u)) | (v_e >> 11u)) ^ (((uint32_t)(v_e << 7u)) | (v_e >> 25u))); + v_t1 += ((v_e & v_f) ^ ((4294967295u ^ v_e) & v_g)); + v_t1 += WUFFS_SHA256__K[v_i]; + v_t1 += v_w[v_i]; + v_t2 = ((((uint32_t)(v_a << 30u)) | (v_a >> 2u)) ^ (((uint32_t)(v_a << 19u)) | (v_a >> 13u)) ^ (((uint32_t)(v_a << 10u)) | (v_a >> 22u))); + v_t2 += ((v_a & v_b) ^ (v_a & v_c) ^ (v_b & v_c)); + v_h = v_g; + v_g = v_f; + v_f = v_e; + v_e = ((uint32_t)(v_d + v_t1)); + v_d = v_c; + v_c = v_b; + v_b = v_a; + v_a = ((uint32_t)(v_t1 + v_t2)); + v_i += 1u; + } + v_a += v_h0; + v_b += v_h1; + v_c += v_h2; + v_d += v_h3; + v_e += v_h4; + v_f += v_h5; + v_g += v_h6; + v_h += v_h7; + if (v_final_block) { + break; + } + v_final_block = true; + v_h0 = v_a; + v_h1 = v_b; + v_h2 = v_c; + v_h3 = v_d; + v_h4 = v_e; + v_h5 = v_f; + v_h6 = v_g; + v_h7 = v_h; + v_buf_len = 0u; + while (v_buf_len < 56u) { + v_buf_data[v_buf_len] = 0u; + v_buf_len += 1u; } - - goto ok; - ok: - self->private_impl.p_decode_other_chunk[0] = 0; - goto exit; } + return wuffs_base__utility__make_bitvec256( + (((uint64_t)(v_h)) | (((uint64_t)(v_g)) << 32u)), + (((uint64_t)(v_f)) | (((uint64_t)(v_e)) << 32u)), + (((uint64_t)(v_d)) | (((uint64_t)(v_c)) << 32u)), + (((uint64_t)(v_b)) | (((uint64_t)(v_a)) << 32u))); +} - goto suspend; - suspend: - self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__SHA256) - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) - return status; -} +// ---------------- Status Codes Implementations -// -------- func png.decoder.decode_actl +const char wuffs_tga__error__bad_header[] = "#tga: bad header"; +const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding"; +const char wuffs_tga__error__truncated_input[] = "#tga: truncated input"; +const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file"; + +// ---------------- Private Consts + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__decode_actl( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +wuffs_tga__decoder__do_decode_image_config( + wuffs_tga__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_tga__decoder__do_decode_frame_config( + wuffs_tga__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_tga__decoder__do_decode_frame( + wuffs_tga__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_tga__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_tga__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_tga__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_tga__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_tga__decoder__initialize( + wuffs_tga__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_tga__decoder* +wuffs_tga__decoder__alloc(void) { + wuffs_tga__decoder* x = + (wuffs_tga__decoder*)(calloc(1, sizeof(wuffs_tga__decoder))); + if (!x) { + return NULL; + } + if (wuffs_tga__decoder__initialize( + x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; } + return x; +} - uint32_t coro_susp_point = self->private_impl.p_decode_actl[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +size_t +sizeof__wuffs_tga__decoder(void) { + return sizeof(wuffs_tga__decoder); +} - if (self->private_impl.f_chunk_length != 8u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } else if (self->private_impl.f_interlace_pass > 0u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); - goto exit; - } - self->private_impl.f_chunk_length = 0u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_actl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - self->private_impl.f_num_animation_frames_value = t_0; - } - if (self->private_impl.f_num_animation_frames_value == 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_actl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } - } - self->private_impl.f_num_animation_loops_value = t_1; - } +// ---------------- Function Implementations - goto ok; - ok: - self->private_impl.p_decode_actl[0] = 0; - goto exit; +// -------- func tga.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_tga__decoder__get_quirk( + const wuffs_tga__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - goto suspend; - suspend: - self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + return 0u; +} - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); +// -------- func tga.decoder.set_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__set_quirk( + wuffs_tga__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); } - return status; + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func png.decoder.decode_chrm +// -------- func tga.decoder.decode_image_config WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_chrm( - wuffs_png__decoder* self, +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_image_config( + wuffs_tga__decoder* self, + wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - uint64_t v_u = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_chunk_length != 32u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length = 0u; - self->private_impl.f_metadata_flavor = 5u; - self->private_impl.f_metadata_fourcc = 1128813133u; - self->private_impl.f_metadata_x = 0u; - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint64_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - v_u = t_0; - } - self->private_impl.f_metadata_x |= ((16777215u & v_u) << 0u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint64_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 24) { - t_1 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } - } - v_u = t_1; - } - self->private_impl.f_metadata_x |= ((16777215u & v_u) << 24u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - uint64_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); - if (num_bits_2 == 24) { - t_2 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)); - } - } - v_u = t_2; - } - self->private_impl.f_metadata_x |= ((uint64_t)((16777215u & v_u) << 48u)); - self->private_impl.f_metadata_y |= ((16777215u & v_u) >> 16u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - uint64_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); - if (num_bits_3 == 24) { - t_3 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)); - } - } - v_u = t_3; - } - self->private_impl.f_metadata_y |= ((16777215u & v_u) << 8u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - uint64_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); - if (num_bits_4 == 24) { - t_4 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)); - } - } - v_u = t_4; - } - self->private_impl.f_metadata_y |= ((16777215u & v_u) << 32u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - uint64_t t_5; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); - if (num_bits_5 == 24) { - t_5 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_5 += 8u; - *scratch |= ((uint64_t)(num_bits_5)); - } - } - v_u = t_5; - } - self->private_impl.f_metadata_y |= ((uint64_t)((16777215u & v_u) << 56u)); - self->private_impl.f_metadata_z |= ((16777215u & v_u) >> 8u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); - uint64_t t_6; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6); - if (num_bits_6 == 24) { - t_6 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_6 += 8u; - *scratch |= ((uint64_t)(num_bits_6)); - } + while (true) { + { + wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_image_config(self, a_dst, a_src); + v_status = t_0; } - v_u = t_6; - } - self->private_impl.f_metadata_z |= ((16777215u & v_u) << 16u); - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); - uint64_t t_7; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_chrm[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch; - uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7); - if (num_bits_7 == 24) { - t_7 = ((uint64_t)(*scratch >> 32)); - break; - } - num_bits_7 += 8u; - *scratch |= ((uint64_t)(num_bits_7)); - } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + goto exit; } - v_u = t_7; + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); } - self->private_impl.f_metadata_z |= ((16777215u & v_u) << 40u); - goto ok; ok: - self->private_impl.p_decode_chrm[0] = 0; + self->private_impl.p_decode_image_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func png.decoder.decode_exif - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_exif( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - if (self->private_impl.f_chunk_length < 4u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_metadata_flavor = 3u; - self->private_impl.f_metadata_fourcc = 1163413830u; - self->private_impl.f_metadata_x = 0u; - self->private_impl.f_metadata_y = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - self->private_impl.f_metadata_z = wuffs_base__u64__sat_add(self->private_impl.f_metadata_y, ((uint64_t)(self->private_impl.f_chunk_length))); - self->private_impl.f_chunk_length = 0u; + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - goto ok; - ok: goto exit; exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return status; } -// -------- func png.decoder.decode_fctl +// -------- func tga.decoder.do_decode_image_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__decode_fctl( - wuffs_png__decoder* self, +wuffs_tga__decoder__do_decode_image_config( + wuffs_tga__decoder* self, + wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_x0 = 0; - uint32_t v_y0 = 0; - uint32_t v_x1 = 0; - uint32_t v_y1 = 0; + uint32_t v_c32 = 0; + uint32_t v_c5 = 0; + uint32_t v_i = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -55899,309 +69341,577 @@ wuffs_png__decoder__decode_fctl( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0]; + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; if (coro_susp_point) { - v_x0 = self->private_data.s_decode_fctl[0].v_x0; - v_x1 = self->private_data.s_decode_fctl[0].v_x1; - v_y1 = self->private_data.s_decode_fctl[0].v_y1; + v_i = self->private_data.s_do_decode_image_config.v_i; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_chunk_length != 26u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + if (self->private_impl.f_call_sequence != 0u) { + status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); goto exit; } - self->private_impl.f_chunk_length = 0u; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_x0 = t_0; + uint8_t t_0 = *iop_a_src++; + self->private_impl.f_header_id_length = t_0; } - if (v_x0 != self->private_impl.f_next_animation_seq_num) { - status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); - goto exit; - } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + self->private_impl.f_header_color_map_type = t_1; + } + if (self->private_impl.f_header_color_map_type > 1u) { + status = wuffs_base__make_status(wuffs_tga__error__bad_header); goto exit; } - self->private_impl.f_next_animation_seq_num += 1u; { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_x1 = t_1; + uint8_t t_2 = *iop_a_src++; + self->private_impl.f_header_image_type = t_2; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); - if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)); - } - } - v_y1 = t_2; + if ((self->private_impl.f_header_image_type == 1u) || + (self->private_impl.f_header_image_type == 2u) || + (self->private_impl.f_header_image_type == 3u) || + (self->private_impl.f_header_image_type == 9u) || + (self->private_impl.f_header_image_type == 10u) || + (self->private_impl.f_header_image_type == 11u)) { + } else { + status = wuffs_base__make_status(wuffs_tga__error__bad_header); + goto exit; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + uint16_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + iop_a_src += 2; } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch >> 32)); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 8) { + t_3 = ((uint16_t)(*scratch)); break; } num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)); + *scratch |= ((uint64_t)(num_bits_3)) << 56; } } - v_x0 = t_3; + self->private_impl.f_header_color_map_first_entry_index = t_3; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + uint16_t t_4; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + iop_a_src += 2; } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4); - if (num_bits_4 == 24) { - t_4 = ((uint32_t)(*scratch >> 32)); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; + if (num_bits_4 == 8) { + t_4 = ((uint16_t)(*scratch)); break; } num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)); + *scratch |= ((uint64_t)(num_bits_4)) << 56; } } - v_y0 = t_4; + self->private_impl.f_header_color_map_length = t_4; } - v_x1 += v_x0; - v_y1 += v_y0; - if ((v_x0 >= v_x1) || - (v_x0 > self->private_impl.f_width) || - (v_x1 > self->private_impl.f_width) || - (v_y0 >= v_y1) || - (v_y0 > self->private_impl.f_height) || - (v_y1 > self->private_impl.f_height)) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + self->private_impl.f_header_color_map_entry_size = t_5; } - self->private_impl.f_frame_rect_x0 = v_x0; - self->private_impl.f_frame_rect_y0 = v_y0; - self->private_impl.f_frame_rect_x1 = v_x1; - self->private_impl.f_frame_rect_y1 = v_y1; + if (self->private_impl.f_header_color_map_type != 0u) { + if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length > 256u)) { + status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); + goto exit; + } else if ((self->private_impl.f_header_color_map_entry_size != 15u) && + (self->private_impl.f_header_color_map_entry_size != 16u) && + (self->private_impl.f_header_color_map_entry_size != 24u) && + (self->private_impl.f_header_color_map_entry_size != 32u)) { + status = wuffs_base__make_status(wuffs_tga__error__bad_header); + goto exit; + } + } else { + if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length != 0u) || (self->private_impl.f_header_color_map_entry_size != 0u)) { + status = wuffs_base__make_status(wuffs_tga__error__bad_header); + goto exit; + } + } + self->private_data.s_do_decode_image_config.scratch = 4u; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - uint32_t t_5; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + uint32_t t_6; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); iop_a_src += 2; } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); - if (num_bits_5 == 8) { - t_5 = ((uint32_t)(*scratch >> 48)); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6; + if (num_bits_6 == 8) { + t_6 = ((uint32_t)(*scratch)); break; } - num_bits_5 += 8u; - *scratch |= ((uint64_t)(num_bits_5)); + num_bits_6 += 8u; + *scratch |= ((uint64_t)(num_bits_6)) << 56; } } - v_x0 = t_5; + self->private_impl.f_width = t_6; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); - uint32_t t_6; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + uint32_t t_7; if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); + t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); iop_a_src += 2; } else { - self->private_data.s_decode_fctl[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch; - uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6); - if (num_bits_6 == 8) { - t_6 = ((uint32_t)(*scratch >> 48)); + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; + if (num_bits_7 == 8) { + t_7 = ((uint32_t)(*scratch)); break; } - num_bits_6 += 8u; - *scratch |= ((uint64_t)(num_bits_6)); + num_bits_7 += 8u; + *scratch |= ((uint64_t)(num_bits_7)) << 56; } } - v_x1 = t_6; - } - if (v_x1 <= 0u) { - self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000u); - } else { - self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000u) / ((uint64_t)(v_x1))); + self->private_impl.f_height = t_7; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_7 = *iop_a_src++; - v_x0 = t_7; + uint8_t t_8 = *iop_a_src++; + self->private_impl.f_header_pixel_depth = t_8; } - if (v_x0 == 0u) { - self->private_impl.f_frame_disposal = 0u; - } else if (v_x0 == 1u) { - self->private_impl.f_frame_disposal = 1u; - } else if (v_x0 == 2u) { - self->private_impl.f_frame_disposal = 2u; - } else { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + if ((self->private_impl.f_header_pixel_depth != 1u) && + (self->private_impl.f_header_pixel_depth != 8u) && + (self->private_impl.f_header_pixel_depth != 15u) && + (self->private_impl.f_header_pixel_depth != 16u) && + (self->private_impl.f_header_pixel_depth != 24u) && + (self->private_impl.f_header_pixel_depth != 32u)) { + status = wuffs_base__make_status(wuffs_tga__error__bad_header); goto exit; } + if (((uint8_t)(self->private_impl.f_header_image_type | 8u)) == 9u) { + self->private_impl.f_scratch_bytes_per_pixel = 1u; + self->private_impl.f_src_bytes_per_pixel = 1u; + self->private_impl.f_src_pixfmt = 2164523016u; + self->private_impl.f_opaque = ((self->private_impl.f_header_color_map_entry_size == 15u) || (self->private_impl.f_header_color_map_entry_size == 24u)); + } else if (((uint8_t)(self->private_impl.f_header_image_type | 8u)) == 10u) { + if ((self->private_impl.f_header_pixel_depth == 15u) || (self->private_impl.f_header_pixel_depth == 16u)) { + self->private_impl.f_scratch_bytes_per_pixel = 4u; + self->private_impl.f_src_bytes_per_pixel = 0u; + self->private_impl.f_src_pixfmt = 2164295816u; + } else if (self->private_impl.f_header_pixel_depth == 24u) { + self->private_impl.f_scratch_bytes_per_pixel = 3u; + self->private_impl.f_src_bytes_per_pixel = 3u; + self->private_impl.f_src_pixfmt = 2147485832u; + self->private_impl.f_opaque = true; + } else if (self->private_impl.f_header_pixel_depth == 32u) { + self->private_impl.f_scratch_bytes_per_pixel = 4u; + self->private_impl.f_src_bytes_per_pixel = 4u; + self->private_impl.f_src_pixfmt = 2164295816u; + } else { + status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); + goto exit; + } + } else { + if (self->private_impl.f_header_pixel_depth == 8u) { + self->private_impl.f_scratch_bytes_per_pixel = 1u; + self->private_impl.f_src_bytes_per_pixel = 1u; + self->private_impl.f_src_pixfmt = 536870920u; + self->private_impl.f_opaque = true; + } else { + status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); + goto exit; + } + } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint32_t t_8 = *iop_a_src++; - v_x0 = t_8; - } - if (v_x0 == 0u) { - self->private_impl.f_frame_overwrite_instead_of_blend = true; - } else if (v_x0 == 1u) { - self->private_impl.f_frame_overwrite_instead_of_blend = false; + uint8_t t_9 = *iop_a_src++; + self->private_impl.f_header_image_descriptor = t_9; + } + if (((uint8_t)(self->private_impl.f_header_image_descriptor & 16u)) != 0u) { + status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); + goto exit; + } + self->private_data.s_do_decode_image_config.scratch = ((uint32_t)(self->private_impl.f_header_id_length)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + 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)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_image_config.scratch; + if (self->private_impl.f_header_color_map_type != 0u) { + while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) { + if (self->private_impl.f_header_color_map_entry_size == 24u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); + uint32_t t_10; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { + t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); + iop_a_src += 3; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10; + if (num_bits_10 == 16) { + t_10 = ((uint32_t)(*scratch)); + break; + } + num_bits_10 += 8u; + *scratch |= ((uint64_t)(num_bits_10)) << 56; + } + } + v_c32 = t_10; + } + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c32 >> 0u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c32 >> 8u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c32 >> 16u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u; + } else if (self->private_impl.f_header_color_map_entry_size == 32u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); + uint32_t t_11; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11; + if (num_bits_11 == 24) { + t_11 = ((uint32_t)(*scratch)); + break; + } + num_bits_11 += 8u; + *scratch |= ((uint64_t)(num_bits_11)) << 56; + } + } + v_c32 = t_11; + } + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c32 >> 0u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c32 >> 8u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c32 >> 16u))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = ((uint8_t)((v_c32 >> 24u))); + } else { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); + uint32_t t_12; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12; + if (num_bits_12 == 8) { + t_12 = ((uint32_t)(*scratch)); + break; + } + num_bits_12 += 8u; + *scratch |= ((uint64_t)(num_bits_12)) << 56; + } + } + v_c32 = t_12; + } + v_c5 = (31u & (v_c32 >> 0u)); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 5u)); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 10u)); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u; + } + v_i += 1u; + } + while (v_i < 256u) { + self->private_data.f_src_palette[((v_i * 4u) + 0u)] = 0u; + self->private_data.f_src_palette[((v_i * 4u) + 1u)] = 0u; + self->private_data.f_src_palette[((v_i * 4u) + 2u)] = 0u; + self->private_data.f_src_palette[((v_i * 4u) + 3u)] = 255u; + v_i += 1u; + } + } + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_src_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + self->private_impl.f_opaque); + } + self->private_impl.f_call_sequence = 32u; + + goto ok; + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_image_config.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func tga.decoder.decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_frame_config( + wuffs_tga__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 2)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame_config(self, a_dst, a_src); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func tga.decoder.do_decode_frame_config + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_tga__decoder__do_decode_frame_config( + wuffs_tga__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_tga__decoder__do_decode_image_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); + goto exit; + } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } else { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; } - if (self->private_impl.f_num_decoded_frame_configs_value == 0u) { - self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0; - self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0; - self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1; - self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1; - self->private_impl.f_first_duration = self->private_impl.f_frame_duration; - self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal; - self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend; + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + self->private_impl.f_frame_config_io_position, + 0u, + self->private_impl.f_opaque, + false, + 4278190080u); } + self->private_impl.f_call_sequence = 64u; - goto ok; ok: - self->private_impl.p_decode_fctl[0] = 0; + self->private_impl.p_do_decode_frame_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_fctl[0].v_x0 = v_x0; - self->private_data.s_decode_fctl[0].v_x1 = v_x1; - self->private_data.s_decode_fctl[0].v_y1 = v_y1; + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -56212,15 +69922,114 @@ wuffs_png__decoder__decode_fctl( return status; } -// -------- func png.decoder.decode_gama +// -------- func tga.decoder.decode_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__decode_frame( + wuffs_tga__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_decode_frame; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func tga.decoder.do_decode_frame WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__decode_gama( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { +wuffs_tga__decoder__do_decode_frame( + wuffs_tga__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { wuffs_base__status status = wuffs_base__make_status(NULL); + wuffs_base__status v_status = wuffs_base__make_status(NULL); + wuffs_base__pixel_format v_dst_pixfmt = {0}; + uint32_t v_dst_bits_per_pixel = 0; + uint64_t v_dst_bytes_per_pixel = 0; + uint32_t v_dst_x = 0; + uint32_t v_dst_y = 0; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint64_t v_dst_start = 0; + wuffs_base__slice_u8 v_src_palette = {0}; + uint64_t v_mark = 0; + uint64_t v_num_pixels64 = 0; + uint32_t v_num_pixels32 = 0; + uint32_t v_lit_length = 0; + uint32_t v_run_length = 0; + uint64_t v_num_dst_bytes = 0; + uint32_t v_num_src_bytes = 0; + uint32_t v_c32 = 0; + uint32_t v_c5 = 0; + const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -56232,516 +70041,739 @@ wuffs_png__decoder__decode_gama( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_decode_gama[0]; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + if (coro_susp_point) { + v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel; + v_dst_x = self->private_data.s_do_decode_frame.v_dst_x; + v_dst_y = self->private_data.s_do_decode_frame.v_dst_y; + v_mark = self->private_data.s_do_decode_frame.v_mark; + v_num_pixels32 = self->private_data.s_do_decode_frame.v_num_pixels32; + v_lit_length = self->private_data.s_do_decode_frame.v_lit_length; + v_run_length = self->private_data.s_do_decode_frame.v_run_length; + v_num_dst_bytes = self->private_data.s_do_decode_frame.v_num_dst_bytes; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_chunk_length != 4u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_tga__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + if (self->private_impl.f_header_color_map_type != 0u) { + v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024); + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), + wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), + v_src_palette, + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); goto exit; } - self->private_impl.f_chunk_length = 0u; - self->private_impl.f_metadata_flavor = 5u; - self->private_impl.f_metadata_fourcc = 1195461953u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint64_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src))); - iop_a_src += 4; - } else { - self->private_data.s_decode_gama[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint64_t)(*scratch >> 32)); - break; + v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); + if (((uint8_t)(self->private_impl.f_header_image_descriptor & 32u)) == 0u) { + v_dst_y = ((uint32_t)(self->private_impl.f_height - 1u)); + } + if (((uint8_t)(self->private_impl.f_header_image_type & 8u)) == 0u) { + v_lit_length = self->private_impl.f_width; + } + label__resume__continue:; + while (true) { + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); + while (v_dst_y < self->private_impl.f_height) { + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y); + v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel); + if (v_dst_start <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start); + } else { + v_dst = wuffs_base__utility__empty_slice_u8(); + } + while (v_dst_x < self->private_impl.f_width) { + if (self->private_impl.f_src_bytes_per_pixel > 0u) { + if (v_lit_length > 0u) { + v_mark = ((uint64_t)(iop_a_src - io0_a_src)); + v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel))); + v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length))))); + v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel); + v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel); + self->private_data.s_do_decode_frame.scratch = v_num_src_bytes; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (self->private_data.s_do_decode_frame.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_decode_frame.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_decode_frame.scratch; + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_private_impl__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes); + } else { + v_dst = wuffs_base__utility__empty_slice_u8(); + } + v_dst_x += v_num_pixels32; + v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535u); + if (v_lit_length > 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); + goto label__resume__continue; + } + } else if (v_run_length > 0u) { + v_run_length -= 1u; + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel)); + if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); + } + v_dst_x += 1u; + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); + goto label__resume__continue; + } + if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) { + v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u); + iop_a_src += 1u; + if ((v_lit_length + v_dst_x) > self->private_impl.f_width) { + status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); + goto exit; + } + } else { + if (self->private_impl.f_src_bytes_per_pixel == 1u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + goto label__resume__continue; + } + v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); + iop_a_src += 1u; + self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + } else if (self->private_impl.f_src_bytes_per_pixel == 3u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + goto label__resume__continue; + } + v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); + iop_a_src += 1u; + self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); + goto label__resume__continue; + } + v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); + iop_a_src += 1u; + self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + self->private_data.f_scratch[3u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; + } + if ((v_run_length + v_dst_x) > self->private_impl.f_width) { + status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); + goto exit; + } + } + } + } else { + if (v_lit_length > 0u) { + if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); + goto label__resume__continue; + } + v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2u; + v_c5 = (31u & (v_c32 >> 0u)); + self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 5u)); + self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 10u)); + self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + self->private_data.f_scratch[3u] = 255u; + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 4)); + if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); + } + v_dst_x += 1u; + v_lit_length -= 1u; + } else if (v_run_length > 0u) { + v_run_length -= 1u; + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel)); + if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); + } + v_dst_x += 1u; + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + goto label__resume__continue; + } + if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) { + v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u); + iop_a_src += 1u; + if ((v_lit_length + v_dst_x) > self->private_impl.f_width) { + status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); + goto exit; + } + } else { + if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + goto label__resume__continue; + } + v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); + iop_a_src += 1u; + v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2u; + v_c5 = (31u & (v_c32 >> 0u)); + self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 5u)); + self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + v_c5 = (31u & (v_c32 >> 10u)); + self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); + self->private_data.f_scratch[3u] = 255u; + if ((v_run_length + v_dst_x) > self->private_impl.f_width) { + status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); + goto exit; + } + } + } } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); + } + v_dst_x = 0u; + if (((uint8_t)(self->private_impl.f_header_image_descriptor & 32u)) == 0u) { + v_dst_y -= 1u; + } else { + v_dst_y += 1u; + } + if (((uint8_t)(self->private_impl.f_header_image_type & 8u)) == 0u) { + v_lit_length = self->private_impl.f_width; } } - self->private_impl.f_metadata_x = t_0; + break; } - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel = v_dst_bytes_per_pixel; + self->private_data.s_do_decode_frame.v_dst_x = v_dst_x; + self->private_data.s_do_decode_frame.v_dst_y = v_dst_y; + self->private_data.s_do_decode_frame.v_mark = v_mark; + self->private_data.s_do_decode_frame.v_num_pixels32 = v_num_pixels32; + self->private_data.s_do_decode_frame.v_lit_length = v_lit_length; + self->private_data.s_do_decode_frame.v_run_length = v_run_length; + self->private_data.s_do_decode_frame.v_num_dst_bytes = v_num_dst_bytes; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func tga.decoder.frame_dirty_rect + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 +wuffs_tga__decoder__frame_dirty_rect( + const wuffs_tga__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_rect_ie_u32(); + } + + return wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); +} + +// -------- func tga.decoder.num_animation_loops + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_tga__decoder__num_animation_loops( + const wuffs_tga__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + return 0u; +} + +// -------- func tga.decoder.num_decoded_frame_configs + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_tga__decoder__num_decoded_frame_configs( + const wuffs_tga__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; +} + +// -------- func tga.decoder.num_decoded_frames + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_tga__decoder__num_decoded_frames( + const wuffs_tga__decoder* self) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; +} + +// -------- func tga.decoder.restart_frame + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__restart_frame( + wuffs_tga__decoder* self, + uint64_t a_index, + uint64_t a_io_position) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + if (self->private_impl.f_call_sequence < 32u) { + return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); + } + if (a_index != 0u) { + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + self->private_impl.f_call_sequence = 40u; + self->private_impl.f_frame_config_io_position = a_io_position; + return wuffs_base__make_status(NULL); +} - goto ok; - ok: - self->private_impl.p_decode_gama[0] = 0; - goto exit; +// -------- func tga.decoder.set_report_metadata + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_tga__decoder__set_report_metadata( + wuffs_tga__decoder* self, + uint32_t a_fourcc, + bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func tga.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_tga__decoder__tell_me_more( + wuffs_tga__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - goto suspend; - suspend: - self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + goto ok; + ok: goto exit; exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return status; } -// -------- func png.decoder.decode_iccp +// -------- func tga.decoder.workbuf_len WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_iccp( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint8_t v_c = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_tga__decoder__workbuf_len( + const wuffs_tga__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); } - uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} - while (true) { - if (self->private_impl.f_chunk_length <= 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c == 0u) { - break; - } - } - if (self->private_impl.f_chunk_length <= 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - if (v_c != 0u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); - goto exit; - } - self->private_impl.f_metadata_is_zlib_compressed = true; - self->private_impl.f_metadata_flavor = 4u; - self->private_impl.f_metadata_fourcc = 1229144912u; - self->private_impl.f_metadata_x = 0u; - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) - goto ok; - ok: - self->private_impl.p_decode_iccp[0] = 0; - goto exit; - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) - goto suspend; - suspend: - self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; +// ---------------- Status Codes Implementations - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +// ---------------- Private Consts - return status; -} +// ---------------- Private Initializer Prototypes -// -------- func png.decoder.decode_plte +// ---------------- Private Function Prototypes -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_plte( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +// ---------------- VTables - uint32_t v_num_entries = 0; - uint32_t v_i = 0; - uint32_t v_argb = 0; +// ---------------- Initializer Implementations - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_vp8__placeholder__initialize( + wuffs_vp8__placeholder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - - uint32_t coro_susp_point = self->private_impl.p_decode_plte[0]; - if (coro_susp_point) { - v_num_entries = self->private_data.s_decode_plte[0].v_num_entries; - v_i = self->private_data.s_decode_plte[0].v_i; + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_chunk_length > 768u) || ((self->private_impl.f_chunk_length % 3u) != 0u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3u); - self->private_impl.f_chunk_length = 0u; - while (v_i < v_num_entries) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { - t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src))); - iop_a_src += 3; - } else { - self->private_data.s_decode_plte[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 16) { - t_0 = ((uint32_t)(*scratch >> 40)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - v_argb = t_0; - } - v_argb |= 4278190080u; - self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u))); - self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u))); - self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u))); - self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u))); - v_i += 1u; + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); } - while (v_i < 256u) { - self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u; - self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u; - v_i += 1u; +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } - - goto ok; - ok: - self->private_impl.p_decode_plte[0] = 0; - goto exit; } - goto suspend; - suspend: - self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_plte[0].v_num_entries = v_num_entries; - self->private_data.s_decode_plte[0].v_i = v_i; + self->private_impl.magic = WUFFS_BASE__MAGIC; + return wuffs_base__make_status(NULL); +} - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); +wuffs_vp8__placeholder* +wuffs_vp8__placeholder__alloc(void) { + wuffs_vp8__placeholder* x = + (wuffs_vp8__placeholder*)(calloc(1, sizeof(wuffs_vp8__placeholder))); + if (!x) { + return NULL; } - - return status; + if (wuffs_vp8__placeholder__initialize( + x, sizeof(wuffs_vp8__placeholder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; } -// -------- func png.decoder.decode_srgb - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_srgb( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +size_t +sizeof__wuffs_vp8__placeholder(void) { + return sizeof(wuffs_vp8__placeholder); +} - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +// ---------------- Function Implementations - uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__VP8) - if (self->private_impl.f_chunk_length != 1u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length = 0u; - self->private_impl.f_metadata_flavor = 5u; - self->private_impl.f_metadata_fourcc = 1397901122u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t t_0 = *iop_a_src++; - self->private_impl.f_metadata_x = t_0; - } - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) - goto ok; - ok: - self->private_impl.p_decode_srgb[0] = 0; - goto exit; - } +// ---------------- Status Codes Implementations - goto suspend; - suspend: - self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; +const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header"; +const char wuffs_wbmp__error__truncated_input[] = "#wbmp: truncated input"; - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +// ---------------- Private Consts - return status; -} +// ---------------- Private Initializer Prototypes -// -------- func png.decoder.decode_trns +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__decode_trns( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); +wuffs_wbmp__decoder__do_decode_image_config( + wuffs_wbmp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); - uint32_t v_i = 0; - uint32_t v_n = 0; - uint64_t v_u = 0; +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_wbmp__decoder__do_decode_frame_config( + wuffs_wbmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_wbmp__decoder__do_decode_frame( + wuffs_wbmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); - uint32_t coro_susp_point = self->private_impl.p_decode_trns[0]; - if (coro_susp_point) { - v_i = self->private_data.s_decode_trns[0].v_i; - v_n = self->private_data.s_decode_trns[0].v_n; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +// ---------------- VTables - if (self->private_impl.f_color_type == 0u) { - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - if (self->private_impl.f_depth <= 8u) { - self->private_impl.f_dst_pixfmt = 2164295816u; - self->private_impl.f_src_pixfmt = 2164295816u; - } else { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; - } - if (self->private_impl.f_chunk_length != 2u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length = 0u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint64_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_decode_trns[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 8) { - t_0 = ((uint64_t)(*scratch >> 48)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - v_u = t_0; - } - if (self->private_impl.f_depth <= 1u) { - self->private_impl.f_remap_transparency = (((v_u & 1u) * 16777215u) | 4278190080u); - } else if (self->private_impl.f_depth <= 2u) { - self->private_impl.f_remap_transparency = (((v_u & 3u) * 5592405u) | 4278190080u); - } else if (self->private_impl.f_depth <= 4u) { - self->private_impl.f_remap_transparency = (((v_u & 15u) * 1118481u) | 4278190080u); - } else if (self->private_impl.f_depth <= 8u) { - self->private_impl.f_remap_transparency = (((v_u & 255u) * 65793u) | 4278190080u); - } else { - self->private_impl.f_remap_transparency = ((v_u * 4295032833u) | 18446462598732840960u); - } - } else if (self->private_impl.f_color_type == 2u) { - self->private_impl.choosy_filter_and_swizzle = ( - &wuffs_png__decoder__filter_and_swizzle_tricky); - if (self->private_impl.f_depth <= 8u) { - self->private_impl.f_dst_pixfmt = 2164295816u; - self->private_impl.f_src_pixfmt = 2164295816u; - } else { - self->private_impl.f_dst_pixfmt = 2164308923u; - self->private_impl.f_src_pixfmt = 2164308923u; - } - if (self->private_impl.f_chunk_length != 6u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length = 0u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint64_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) { - t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src))); - iop_a_src += 6; - } else { - self->private_data.s_decode_trns[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 40) { - t_1 = ((uint64_t)(*scratch >> 16)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } - } - v_u = t_1; - } - if (self->private_impl.f_depth <= 8u) { - self->private_impl.f_remap_transparency = ((255u & (v_u >> 0u)) | - (65280u & (v_u >> 8u)) | - (16711680u & (v_u >> 16u)) | - 4278190080u); - } else { - self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u); - } - } else if (self->private_impl.f_color_type == 3u) { - self->private_impl.f_dst_pixfmt = 2164523016u; - self->private_impl.f_src_pixfmt = 2164523016u; - if (self->private_impl.f_chunk_length > 256u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - v_n = ((uint32_t)(self->private_impl.f_chunk_length)); - self->private_impl.f_chunk_length = 0u; - while (v_i < v_n) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - self->private_data.f_src_palette[((4u * v_i) + 3u)] = t_2; - } - v_i += 1u; - } +const wuffs_base__image_decoder__func_ptrs +wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_wbmp__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_wbmp__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_wbmp__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_wbmp__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_wbmp__decoder__initialize( + wuffs_wbmp__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; } else { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; + memset(&(self->private_impl), 0, sizeof(self->private_impl)); } + } - goto ok; - ok: - self->private_impl.p_decode_trns[0] = 0; - goto exit; + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_wbmp__decoder* +wuffs_wbmp__decoder__alloc(void) { + wuffs_wbmp__decoder* x = + (wuffs_wbmp__decoder*)(calloc(1, sizeof(wuffs_wbmp__decoder))); + if (!x) { + return NULL; + } + if (wuffs_wbmp__decoder__initialize( + x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; } + return x; +} - goto suspend; - suspend: - self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_decode_trns[0].v_i = v_i; - self->private_data.s_decode_trns[0].v_n = v_n; +size_t +sizeof__wuffs_wbmp__decoder(void) { + return sizeof(wuffs_wbmp__decoder); +} - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); +// ---------------- Function Implementations + +// -------- func wbmp.decoder.get_quirk + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_wbmp__decoder__get_quirk( + const wuffs_wbmp__decoder* self, + uint32_t a_key) { + if (!self) { + return 0; + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; } - return status; + return 0u; } -// -------- func png.decoder.decode_frame_config +// -------- func wbmp.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__decode_frame_config( - wuffs_png__decoder* self, - wuffs_base__frame_config* a_dst, +wuffs_wbmp__decoder__set_quirk( + wuffs_wbmp__decoder* self, + uint32_t a_key, + uint64_t a_value) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + + return wuffs_base__make_status(wuffs_base__error__unsupported_option); +} + +// -------- func wbmp.decoder.decode_image_config + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__decode_image_config( + wuffs_wbmp__decoder* self, + wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); @@ -56757,7 +70789,7 @@ wuffs_png__decoder__decode_frame_config( return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { + (self->private_impl.active_coroutine != 1)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -56766,17 +70798,17 @@ wuffs_png__decoder__decode_frame_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame_config(self, a_dst, a_src); + wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_image_config(self, a_dst, a_src); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_png__error__truncated_input); + status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); goto exit; } status = v_status; @@ -56784,14 +70816,14 @@ wuffs_png__decoder__decode_frame_config( } ok: - self->private_impl.p_decode_frame_config[0] = 0; + self->private_impl.p_decode_image_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; goto exit; exit: @@ -56801,17 +70833,19 @@ wuffs_png__decoder__decode_frame_config( return status; } -// -------- func png.decoder.do_decode_frame_config +// -------- func wbmp.decoder.do_decode_image_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__do_decode_frame_config( - wuffs_png__decoder* self, - wuffs_base__frame_config* a_dst, +wuffs_wbmp__decoder__do_decode_image_config( + wuffs_wbmp__decoder* self, + wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_checksum_have = 0; + uint8_t v_c8 = 0; + uint32_t v_i = 0; + uint32_t v_p = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -56824,392 +70858,88 @@ wuffs_png__decoder__do_decode_frame_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; + if (coro_susp_point) { + v_i = self->private_data.s_do_decode_image_config.v_i; + v_p = self->private_data.s_do_decode_image_config.v_p; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_call_sequence & 16u) != 0u) { + if (self->private_impl.f_call_sequence != 0u) { status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); goto exit; - } else if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_png__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; - } - } else if (self->private_impl.f_call_sequence == 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - status = wuffs_png__decoder__skip_frame(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - if (self->private_impl.f_metadata_fourcc != 0u) { - self->private_impl.f_call_sequence = 48u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; } - if (self->private_impl.f_num_decoded_frame_configs_value == 0u) { - self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0; - self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0; - self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1; - self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1; - self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position; - self->private_impl.f_frame_duration = self->private_impl.f_first_duration; - self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal; - self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend; - } else { - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_frame_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - self->private_impl.f_chunk_length = t_0; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_frame_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)) << 56; - } - } - self->private_impl.f_chunk_type = t_1; - } - if (self->private_impl.f_chunk_type == 1145980233u) { - if (self->private_impl.f_chunk_length != 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_frame_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; - if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)) << 56; - } - } - v_checksum_have = t_2; - } - if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != 2187346606u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_checksum); - goto exit; - } - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else if (self->private_impl.f_chunk_type == 1413571686u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } else if (self->private_impl.f_chunk_type == 1280598886u) { - self->private_impl.f_frame_config_io_position = ((uint64_t)(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) - 8u)); - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - status = wuffs_png__decoder__decode_fctl(self, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - self->private_data.s_do_decode_frame_config[0].scratch = 4u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch; - break; - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); - status = wuffs_png__decoder__decode_other_chunk(self, a_src, true); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - if (self->private_impl.f_metadata_fourcc != 0u) { - self->private_impl.f_call_sequence = 48u; - status = wuffs_base__make_status(wuffs_base__note__metadata_reported); - goto ok; - } - self->private_data.s_do_decode_frame_config[0].scratch = 4u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; + v_i = 0u; + while (v_i < 2u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch; - self->private_impl.f_chunk_length = 0u; + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - self->private_impl.f_frame_rect_x0, - self->private_impl.f_frame_rect_y0, - self->private_impl.f_frame_rect_x1, - self->private_impl.f_frame_rect_y1), - ((wuffs_base__flicks)(self->private_impl.f_frame_duration)), - ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)), - self->private_impl.f_frame_config_io_position, - self->private_impl.f_frame_disposal, - ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns), - self->private_impl.f_frame_overwrite_instead_of_blend, - 0u); - } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u); - self->private_impl.f_call_sequence = 64u; - - ok: - self->private_impl.p_do_decode_frame_config[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - - return status; -} - -// -------- func png.decoder.skip_frame - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__skip_frame( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - uint32_t v_seq_num = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_skip_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - self->private_impl.f_chunk_type_array[0u] = 0u; - self->private_impl.f_chunk_type_array[1u] = 0u; - self->private_impl.f_chunk_type_array[2u] = 0u; - self->private_impl.f_chunk_type_array[3u] = 0u; - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - continue; + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_wbmp__error__bad_header); + goto exit; } - self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); - if (self->private_impl.f_chunk_type == 1413563465u) { - if (self->private_impl.f_chunk_type_array[0u] == 102u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_type_array[0u] = 73u; - self->private_impl.f_chunk_type_array[1u] = 68u; - self->private_impl.f_chunk_type_array[2u] = 65u; - self->private_impl.f_chunk_type_array[3u] = 84u; - } else if (self->private_impl.f_chunk_type == 1413571686u) { - if (self->private_impl.f_chunk_type_array[0u] == 73u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_type_array[0u] = 102u; - self->private_impl.f_chunk_type_array[1u] = 100u; - self->private_impl.f_chunk_type_array[2u] = 65u; - self->private_impl.f_chunk_type_array[3u] = 84u; - if (self->private_impl.f_chunk_length < 4u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 4u; - iop_a_src += 8u; + v_i += 1u; + } + v_i = 0u; + while (v_i < 2u) { + v_p = 0u; + while (true) { { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_skip_frame[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - v_seq_num = t_0; + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; } - if (v_seq_num != self->private_impl.f_next_animation_seq_num) { - status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); - goto exit; - } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); + v_p |= ((uint32_t)(((uint8_t)(v_c8 & 127u)))); + if (((uint8_t)(v_c8 >> 7u)) == 0u) { + break; + } else if (v_p > 131071u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); goto exit; } - self->private_impl.f_next_animation_seq_num += 1u; - self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4u); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_skip_frame[0].scratch; - self->private_impl.f_chunk_length = 0u; - continue; - } else if (self->private_impl.f_chunk_type_array[0u] != 0u) { - break; - } else if (self->private_impl.f_chunk_type == 1280598886u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; + v_p <<= 7u; } - self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + if (v_i == 0u) { + self->private_impl.f_width = v_p; + } else { + self->private_impl.f_height = v_p; } - iop_a_src += self->private_data.s_skip_frame[0].scratch; - self->private_impl.f_chunk_length = 0u; + v_i += 1u; + } + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + 2198077448u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + true); } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); self->private_impl.f_call_sequence = 32u; + goto ok; ok: - self->private_impl.p_skip_frame[0] = 0; + self->private_impl.p_do_decode_image_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_image_config.v_i = v_i; + self->private_data.s_do_decode_image_config.v_p = v_p; goto exit; exit: @@ -57220,17 +70950,14 @@ wuffs_png__decoder__skip_frame( return status; } -// -------- func png.decoder.decode_frame +// -------- func wbmp.decoder.decode_frame_config WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__decode_frame( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { +wuffs_wbmp__decoder__decode_frame_config( + wuffs_wbmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -57240,12 +70967,12 @@ wuffs_png__decoder__decode_frame( ? wuffs_base__error__disabled_by_previous_error : wuffs_base__error__initialize_not_called); } - if (!a_dst || !a_src) { + if (!a_src) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__bad_argument); } if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { + (self->private_impl.active_coroutine != 2)) { self->private_impl.magic = WUFFS_BASE__DISABLED; return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } @@ -57254,22 +70981,17 @@ wuffs_png__decoder__decode_frame( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); + wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame_config(self, a_dst, a_src); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_png__error__truncated_input); + status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); goto exit; } status = v_status; @@ -57277,14 +70999,14 @@ wuffs_png__decoder__decode_frame( } ok: - self->private_impl.p_decode_frame[0] = 0; + self->private_impl.p_decode_frame_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; goto exit; exit: @@ -57294,24 +71016,16 @@ wuffs_png__decoder__decode_frame( return status; } -// -------- func png.decoder.do_decode_frame +// -------- func wbmp.decoder.do_decode_frame_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__do_decode_frame( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { +wuffs_wbmp__decoder__do_decode_frame_config( + wuffs_wbmp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_seq_num = 0; - wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t v_pass_width = 0; - uint32_t v_pass_height = 0; - const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -57323,210 +71037,62 @@ wuffs_png__decoder__do_decode_frame( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_call_sequence & 16u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } else if (self->private_impl.f_call_sequence >= 96u) { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else if (self->private_impl.f_call_sequence != 64u) { + if (self->private_impl.f_call_sequence == 32u) { + } else if (self->private_impl.f_call_sequence < 32u) { if (a_src) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_png__decoder__do_decode_frame_config(self, NULL, a_src); + status = wuffs_wbmp__decoder__do_decode_image_config(self, NULL, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } if (status.repr) { goto suspend; } - } - while (true) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - continue; - } - self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u))); - if (self->private_impl.f_chunk_type == 1413563465u) { - self->private_impl.f_chunk_type_array[0u] = 73u; - self->private_impl.f_chunk_type_array[1u] = 68u; - self->private_impl.f_chunk_type_array[2u] = 65u; - self->private_impl.f_chunk_type_array[3u] = 84u; - iop_a_src += 8u; - if ( ! self->private_impl.f_ignore_checksum) { - wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, - sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); - } - break; - } else if (self->private_impl.f_chunk_type == 1413571686u) { - self->private_impl.f_chunk_type_array[0u] = 102u; - self->private_impl.f_chunk_type_array[1u] = 100u; - self->private_impl.f_chunk_type_array[2u] = 65u; - self->private_impl.f_chunk_type_array[3u] = 84u; - if (self->private_impl.f_chunk_length < 4u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 4u; - iop_a_src += 8u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_0; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_frame[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch; - uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0); - if (num_bits_0 == 24) { - t_0 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_0 += 8u; - *scratch |= ((uint64_t)(num_bits_0)); - } - } - v_seq_num = t_0; - } - if (v_seq_num != self->private_impl.f_next_animation_seq_num) { - status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); - goto exit; - } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); - goto exit; - } - self->private_impl.f_next_animation_seq_num += 1u; - break; - } else if (self->private_impl.f_chunk_type == 1280598886u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_data.s_do_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame[0].scratch; - self->private_impl.f_chunk_length = 0u; - } - if (self->private_impl.f_zlib_is_dirty) { - wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib, - sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - if (self->private_impl.f_ignore_checksum) { - wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u); - } - } - self->private_impl.f_zlib_is_dirty = true; - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), - wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), - wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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); + } else if (self->private_impl.f_call_sequence == 40u) { + if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_restart); goto exit; } + } else if (self->private_impl.f_call_sequence == 64u) { + self->private_impl.f_call_sequence = 96u; + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); goto ok; } - self->private_impl.f_workbuf_hist_pos_base = 0u; - while (true) { - if (self->private_impl.f_chunk_type_array[0u] == 73u) { - v_pass_width = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][1u])) + self->private_impl.f_width) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u])); - v_pass_height = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][4u])) + self->private_impl.f_height) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u])); - } else { - v_pass_width = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0))); - v_pass_height = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0))); - } - if ((v_pass_width > 0u) && (v_pass_height > 0u)) { - self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width); - self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1u + self->private_impl.f_pass_bytes_per_row)); - while (true) { - { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_1 = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf); - v_status = t_1; - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - if (wuffs_base__status__is_ok(&v_status)) { - break; - } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) { - if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) { - wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi)); - } - if (v_status.repr == wuffs_base__suspension__short_read) { - status = wuffs_base__make_status(wuffs_png__error__truncated_input); - goto exit; - } - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - } - v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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; - } - self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length; - } - if ((self->private_impl.f_interlace_pass == 0u) || (self->private_impl.f_interlace_pass >= 7u)) { - break; - } -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#endif - self->private_impl.f_interlace_pass += 1u; -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif + if (a_dst != NULL) { + wuffs_base__frame_config__set( + a_dst, + wuffs_base__utility__make_rect_ie_u32( + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height), + ((wuffs_base__flicks)(0u)), + 0u, + self->private_impl.f_frame_config_io_position, + 0u, + true, + false, + 4278190080u); } - wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u); - self->private_impl.f_call_sequence = 32u; + self->private_impl.f_call_sequence = 64u; ok: - self->private_impl.p_do_decode_frame[0] = 0; + self->private_impl.p_do_decode_frame_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -57537,338 +71103,217 @@ wuffs_png__decoder__do_decode_frame( return status; } -// -------- func png.decoder.decode_pass +// -------- func wbmp.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_png__decoder__decode_pass( - wuffs_png__decoder* self, +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__decode_frame( + wuffs_wbmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, - wuffs_base__slice_u8 a_workbuf) { + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 3)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_w = &u_w; - uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint64_t v_w_mark = 0; - uint64_t v_r_mark = 0; - wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL); - uint32_t v_checksum_have = 0; - uint32_t v_checksum_want = 0; - uint32_t v_seq_num = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_pass[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - self->private_impl.f_workbuf_wi = 0u; while (true) { - if ((self->private_impl.f_workbuf_wi > self->private_impl.f_pass_workbuf_length) || (self->private_impl.f_pass_workbuf_length > ((uint64_t)(a_workbuf.len)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); - goto exit; - } { - wuffs_base__io_buffer* o_0_v_w = v_w; - uint8_t *o_0_iop_v_w = iop_v_w; - uint8_t *o_0_io0_v_w = io0_v_w; - uint8_t *o_0_io1_v_w = io1_v_w; - uint8_t *o_0_io2_v_w = io2_v_w; - v_w = wuffs_base__io_writer__set( - &u_w, - &iop_v_w, - &io0_v_w, - &io1_v_w, - &io2_v_w, - wuffs_base__slice_u8__subslice_ij(a_workbuf, - self->private_impl.f_workbuf_wi, - self->private_impl.f_pass_workbuf_length), - ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi))); - { - const bool o_1_closed_a_src = a_src->meta.closed; - const uint8_t *o_1_io2_a_src = io2_a_src; - wuffs_base__io_reader__limit(&io2_a_src, iop_a_src, - ((uint64_t)(self->private_impl.f_chunk_length))); - if (a_src) { - size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); - a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); - a_src->meta.wi = n; - } - v_w_mark = ((uint64_t)(iop_v_w - io0_v_w)); - v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); - { - u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr)); - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8()); - v_zlib_status = t_0; - iop_v_w = u_w.data.ptr + u_w.meta.wi; - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - if ( ! self->private_impl.f_ignore_checksum) { - wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); - } - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)))); - io2_a_src = o_1_io2_a_src; - if (a_src) { - a_src->meta.closed = o_1_closed_a_src; - a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); - } - } - v_w = o_0_v_w; - iop_v_w = o_0_iop_v_w; - io0_v_w = o_0_io0_v_w; - io1_v_w = o_0_io1_v_w; - io2_v_w = o_0_io2_v_w; + wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame(self, + a_dst, + a_src, + a_blend, + a_workbuf, + a_opts); + v_status = t_0; } - if (wuffs_base__status__is_ok(&v_zlib_status)) { - if (self->private_impl.f_chunk_length > 0u) { - status = wuffs_base__make_status(wuffs_base__error__too_much_data); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - uint32_t t_1; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_pass[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch; - uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1); - if (num_bits_1 == 24) { - t_1 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_1 += 8u; - *scratch |= ((uint64_t)(num_bits_1)); - } - } - v_checksum_want = t_1; - } - if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) { - v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8()); - if (v_checksum_have != v_checksum_want) { - status = wuffs_base__make_status(wuffs_png__error__bad_checksum); - goto exit; - } - } - break; - } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) { - if ((1u <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6u)) { - break; - } - status = wuffs_base__make_status(wuffs_base__error__too_much_data); + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); goto exit; - } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) { - status = v_zlib_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; - } else if (self->private_impl.f_chunk_length == 0u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - uint32_t t_2; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_pass[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch; - uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2); - if (num_bits_2 == 24) { - t_2 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_2 += 8u; - *scratch |= ((uint64_t)(num_bits_2)); - } - } - v_checksum_want = t_2; - } - if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) { - v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8()); - if (v_checksum_have != v_checksum_want) { - status = wuffs_base__make_status(wuffs_png__error__bad_checksum); - goto exit; - } - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); - uint32_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_pass[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3); - if (num_bits_3 == 24) { - t_3 = ((uint32_t)(*scratch >> 32)); - break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func wbmp.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_wbmp__decoder__do_decode_frame( + wuffs_wbmp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + wuffs_base__pixel_format v_dst_pixfmt = {0}; + uint32_t v_dst_bits_per_pixel = 0; + uint64_t v_dst_bytes_per_pixel = 0; + uint64_t v_dst_x_in_bytes = 0; + uint32_t v_dst_x = 0; + uint32_t v_dst_y = 0; + wuffs_base__table_u8 v_tab = {0}; + wuffs_base__slice_u8 v_dst = {0}; + uint8_t v_src[1] = {0}; + uint8_t v_c8 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + if (coro_susp_point) { + v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel; + v_dst_x = self->private_data.s_do_decode_frame.v_dst_x; + v_dst_y = self->private_data.s_do_decode_frame.v_dst_y; + memcpy(v_src, self->private_data.s_do_decode_frame.v_src, sizeof(v_src)); + v_c8 = self->private_data.s_do_decode_frame.v_c8; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_wbmp__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette(a_dst), + wuffs_base__utility__make_pixel_format(536870920u), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + status = wuffs_base__make_status(wuffs_base__error__unsupported_option); + goto exit; + } + v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); + if (self->private_impl.f_width > 0u) { + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + while (v_dst_y < self->private_impl.f_height) { + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y); + v_dst_x = 0u; + while (v_dst_x < self->private_impl.f_width) { + if ((v_dst_x & 7u) == 0u) { + while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_dst_y); + v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel); + if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes); } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)); } + v_c8 = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); + iop_a_src += 1u; } - self->private_impl.f_chunk_length = t_3; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); - uint32_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; + if (((uint8_t)(v_c8 & 128u)) == 0u) { + v_src[0u] = 0u; } else { - self->private_data.s_decode_pass[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 24) { - t_4 = ((uint32_t)(*scratch)); - break; - } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; - } - } - self->private_impl.f_chunk_type = t_4; - } - if (self->private_impl.f_chunk_type_array[0u] == 73u) { - if (self->private_impl.f_chunk_type != 1413563465u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - if ( ! self->private_impl.f_ignore_checksum) { - wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, - sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4)); - } - } else { - if ((self->private_impl.f_chunk_type != 1413571686u) || (self->private_impl.f_chunk_length < 4u)) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 4u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - uint32_t t_5; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_decode_pass[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch; - uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu)); - *scratch >>= 8; - *scratch <<= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5); - if (num_bits_5 == 24) { - t_5 = ((uint32_t)(*scratch >> 32)); - break; - } - num_bits_5 += 8u; - *scratch |= ((uint64_t)(num_bits_5)); - } - } - v_seq_num = t_5; + v_src[0u] = 255u; } - if (v_seq_num != self->private_impl.f_next_animation_seq_num) { - status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number); - goto exit; - } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file); - goto exit; + v_c8 = ((uint8_t)((((uint32_t)(v_c8)) << 1u))); + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__utility__empty_slice_u8(), wuffs_base__make_slice_u8(v_src, 1)); + if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); } - self->private_impl.f_next_animation_seq_num += 1u; + v_dst_x += 1u; } - continue; - } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0u) { - status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input); - goto exit; - } - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); - } - if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) { - status = wuffs_base__make_status(wuffs_base__error__not_enough_data); - goto exit; - } else if (0u < ((uint64_t)(a_workbuf.len))) { - if (a_workbuf.ptr[0u] == 4u) { - a_workbuf.ptr[0u] = 1u; + v_dst_y += 1u; } } + self->private_impl.f_call_sequence = 96u; ok: - self->private_impl.p_decode_pass[0] = 0; + self->private_impl.p_do_decode_frame = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_frame.v_dst_bytes_per_pixel = v_dst_bytes_per_pixel; + self->private_data.s_do_decode_frame.v_dst_x = v_dst_x; + self->private_data.s_do_decode_frame.v_dst_y = v_dst_y; + memcpy(self->private_data.s_do_decode_frame.v_src, v_src, sizeof(v_src)); + self->private_data.s_do_decode_frame.v_c8 = v_c8; goto exit; exit: @@ -57879,12 +71324,12 @@ wuffs_png__decoder__decode_pass( return status; } -// -------- func png.decoder.frame_dirty_rect +// -------- func wbmp.decoder.frame_dirty_rect WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_png__decoder__frame_dirty_rect( - const wuffs_png__decoder* self) { +wuffs_wbmp__decoder__frame_dirty_rect( + const wuffs_wbmp__decoder* self) { if (!self) { return wuffs_base__utility__empty_rect_ie_u32(); } @@ -57894,18 +71339,18 @@ wuffs_png__decoder__frame_dirty_rect( } return wuffs_base__utility__make_rect_ie_u32( - self->private_impl.f_frame_rect_x0, - self->private_impl.f_frame_rect_y0, - self->private_impl.f_frame_rect_x1, - self->private_impl.f_frame_rect_y1); + 0u, + 0u, + self->private_impl.f_width, + self->private_impl.f_height); } -// -------- func png.decoder.num_animation_loops +// -------- func wbmp.decoder.num_animation_loops WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_png__decoder__num_animation_loops( - const wuffs_png__decoder* self) { +wuffs_wbmp__decoder__num_animation_loops( + const wuffs_wbmp__decoder* self) { if (!self) { return 0; } @@ -57914,15 +71359,15 @@ wuffs_png__decoder__num_animation_loops( return 0; } - return self->private_impl.f_num_animation_loops_value; + return 0u; } -// -------- func png.decoder.num_decoded_frame_configs +// -------- func wbmp.decoder.num_decoded_frame_configs WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_png__decoder__num_decoded_frame_configs( - const wuffs_png__decoder* self) { +wuffs_wbmp__decoder__num_decoded_frame_configs( + const wuffs_wbmp__decoder* self) { if (!self) { return 0; } @@ -57931,15 +71376,18 @@ wuffs_png__decoder__num_decoded_frame_configs( return 0; } - return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)); + if (self->private_impl.f_call_sequence > 32u) { + return 1u; + } + return 0u; } -// -------- func png.decoder.num_decoded_frames +// -------- func wbmp.decoder.num_decoded_frames WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_png__decoder__num_decoded_frames( - const wuffs_png__decoder* self) { +wuffs_wbmp__decoder__num_decoded_frames( + const wuffs_wbmp__decoder* self) { if (!self) { return 0; } @@ -57948,15 +71396,18 @@ wuffs_png__decoder__num_decoded_frames( return 0; } - return ((uint64_t)(self->private_impl.f_num_decoded_frames_value)); + if (self->private_impl.f_call_sequence > 64u) { + return 1u; + } + return 0u; } -// -------- func png.decoder.restart_frame +// -------- func wbmp.decoder.restart_frame WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__restart_frame( - wuffs_png__decoder* self, +wuffs_wbmp__decoder__restart_frame( + wuffs_wbmp__decoder* self, uint64_t a_index, uint64_t a_io_position) { if (!self) { @@ -57971,154 +71422,514 @@ wuffs_png__decoder__restart_frame( if (self->private_impl.f_call_sequence < 32u) { return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } else if ((a_index >= ((uint64_t)(self->private_impl.f_num_animation_frames_value))) || ((a_index == 0u) && (a_io_position != self->private_impl.f_first_config_io_position))) { + } + if (a_index != 0u) { return wuffs_base__make_status(wuffs_base__error__bad_argument); } self->private_impl.f_call_sequence = 40u; - if (self->private_impl.f_interlace_pass >= 1u) { - self->private_impl.f_interlace_pass = 1u; - } self->private_impl.f_frame_config_io_position = a_io_position; - self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)(a_index)); - self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value; return wuffs_base__make_status(NULL); } -// -------- func png.decoder.set_report_metadata +// -------- func wbmp.decoder.set_report_metadata WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_png__decoder__set_report_metadata( - wuffs_png__decoder* self, +wuffs_wbmp__decoder__set_report_metadata( + wuffs_wbmp__decoder* self, uint32_t a_fourcc, bool a_report) { + return wuffs_base__make_empty_struct(); +} + +// -------- func wbmp.decoder.tell_me_more + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_wbmp__decoder__tell_me_more( + wuffs_wbmp__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__more_information* a_minfo, + wuffs_base__io_buffer* a_src) { if (!self) { - return wuffs_base__make_empty_struct(); + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 4)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); - if (a_fourcc == 1128813133u) { - self->private_impl.f_report_metadata_chrm = a_report; - } else if (a_fourcc == 1163413830u) { - self->private_impl.f_report_metadata_exif = a_report; - } else if (a_fourcc == 1195461953u) { - self->private_impl.f_report_metadata_gama = a_report; - } else if (a_fourcc == 1229144912u) { - self->private_impl.f_report_metadata_iccp = a_report; - } else if (a_fourcc == 1263947808u) { - self->private_impl.f_report_metadata_kvp = a_report; - } else if (a_fourcc == 1397901122u) { - self->private_impl.f_report_metadata_srgb = a_report; + status = wuffs_base__make_status(wuffs_base__error__no_more_information); + goto exit; + + goto ok; + ok: + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func wbmp.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_wbmp__decoder__workbuf_len( + const wuffs_wbmp__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_base__utility__make_range_ii_u64(0u, 0u); +} + +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) + +// ---------------- Status Codes Implementations + +const char wuffs_webp__error__bad_huffman_code_over_subscribed[] = "#webp: bad Huffman code (over-subscribed)"; +const char wuffs_webp__error__bad_huffman_code_under_subscribed[] = "#webp: bad Huffman code (under-subscribed)"; +const char wuffs_webp__error__bad_huffman_code[] = "#webp: bad Huffman code"; +const char wuffs_webp__error__bad_back_reference[] = "#webp: bad back-reference"; +const char wuffs_webp__error__bad_color_cache[] = "#webp: bad color cache"; +const char wuffs_webp__error__bad_header[] = "#webp: bad header"; +const char wuffs_webp__error__bad_transform[] = "#webp: bad transform"; +const char wuffs_webp__error__short_chunk[] = "#webp: short chunk"; +const char wuffs_webp__error__truncated_input[] = "#webp: truncated input"; +const char wuffs_webp__error__unsupported_number_of_huffman_groups[] = "#webp: unsupported number of Huffman groups"; +const char wuffs_webp__error__unsupported_transform_after_color_indexing_transform[] = "#webp: unsupported transform after color indexing transform"; +const char wuffs_webp__error__unsupported_webp_file[] = "#webp: unsupported WebP file"; +const char wuffs_webp__error__internal_error_inconsistent_huffman_code[] = "#webp: internal error: inconsistent Huffman code"; +const char wuffs_webp__error__internal_error_inconsistent_dst_buffer[] = "#webp: internal error: inconsistent dst buffer"; +const char wuffs_webp__error__internal_error_inconsistent_n_bits[] = "#webp: internal error: inconsistent n_bits"; + +// ---------------- Private Consts + +static const uint8_t +WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = { + 17u, 18u, 0u, 1u, 2u, 3u, 4u, 5u, + 16u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, + 13u, 14u, 15u, +}; + +static const uint8_t +WUFFS_WEBP__REPEAT_N_BITS[4] WUFFS_BASE__POTENTIALLY_UNUSED = { + 2u, 3u, 7u, 0u, +}; + +static const uint8_t +WUFFS_WEBP__REPEAT_COUNTS[4] WUFFS_BASE__POTENTIALLY_UNUSED = { + 3u, 3u, 11u, 0u, +}; + +static const uint16_t +WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[5] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1612u, 0u, 511u, 1022u, 1533u, +}; + +static const uint8_t +WUFFS_WEBP__DISTANCE_MAP[120] WUFFS_BASE__POTENTIALLY_UNUSED = { + 24u, 7u, 23u, 25u, 40u, 6u, 39u, 41u, + 22u, 26u, 38u, 42u, 56u, 5u, 55u, 57u, + 21u, 27u, 54u, 58u, 37u, 43u, 72u, 4u, + 71u, 73u, 20u, 28u, 53u, 59u, 70u, 74u, + 36u, 44u, 88u, 69u, 75u, 52u, 60u, 3u, + 87u, 89u, 19u, 29u, 86u, 90u, 35u, 45u, + 68u, 76u, 85u, 91u, 51u, 61u, 104u, 2u, + 103u, 105u, 18u, 30u, 102u, 106u, 34u, 46u, + 84u, 92u, 67u, 77u, 101u, 107u, 50u, 62u, + 120u, 1u, 119u, 121u, 83u, 93u, 17u, 31u, + 100u, 108u, 66u, 78u, 118u, 122u, 33u, 47u, + 117u, 123u, 49u, 63u, 99u, 109u, 82u, 94u, + 0u, 116u, 124u, 65u, 79u, 16u, 32u, 98u, + 110u, 48u, 115u, 125u, 81u, 95u, 64u, 114u, + 126u, 97u, 111u, 80u, 113u, 127u, 96u, 112u, +}; + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_huffman_groups( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_n_huffman_groups); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_huffman_tree( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_hg, + uint32_t a_ht); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_huffman_tree_simple( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_hg, + uint32_t a_ht); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_code_length_code_lengths( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__build_code_lengths_huffman_nodes( + wuffs_webp__decoder* self); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__build_huffman_nodes( + wuffs_webp__decoder* self, + uint32_t a_hg, + uint32_t a_ht); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__build_code_lengths( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_pixels_slow( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_dst, + wuffs_base__io_buffer* a_src, + uint32_t a_width, + uint32_t a_height, + wuffs_base__slice_u8 a_tile_data, + uint32_t a_tile_size_log2); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_predictor( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix, + wuffs_base__slice_u8 a_tile_data); + +WUFFS_BASE__GENERATED_C_CODE +static uint32_t +wuffs_webp__decoder__absolute_difference( + const wuffs_webp__decoder* self, + uint32_t a_a, + uint32_t a_b); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_webp__decoder__mode12( + const wuffs_webp__decoder* self, + uint8_t a_l, + uint8_t a_t, + uint8_t a_tl); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_webp__decoder__mode13( + const wuffs_webp__decoder* self, + uint8_t a_l, + uint8_t a_t, + uint8_t a_tl); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_cross_color( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix, + wuffs_base__slice_u8 a_tile_data); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_subtract_green( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_color_indexing( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_image_config( + wuffs_webp__decoder* self, + wuffs_base__image_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_image_config_limited( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_image_config_limited_vp8l( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_frame_config( + wuffs_webp__decoder* self, + wuffs_base__frame_config* a_dst, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_frame( + wuffs_webp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_transform( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_color_cache_parameters( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_hg_table( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_width, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_pixels( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_dst, + wuffs_base__io_buffer* a_src, + uint32_t a_width, + uint32_t a_height, + wuffs_base__slice_u8 a_tile_data, + uint32_t a_tile_size_log2); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__swizzle( + wuffs_webp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_src, + wuffs_base__pixel_blend a_blend); + +// ---------------- VTables + +const wuffs_base__image_decoder__func_ptrs +wuffs_webp__decoder__func_ptrs_for__wuffs_base__image_decoder = { + (wuffs_base__status(*)(void*, + wuffs_base__pixel_buffer*, + wuffs_base__io_buffer*, + wuffs_base__pixel_blend, + wuffs_base__slice_u8, + wuffs_base__decode_frame_options*))(&wuffs_webp__decoder__decode_frame), + (wuffs_base__status(*)(void*, + wuffs_base__frame_config*, + wuffs_base__io_buffer*))(&wuffs_webp__decoder__decode_frame_config), + (wuffs_base__status(*)(void*, + wuffs_base__image_config*, + wuffs_base__io_buffer*))(&wuffs_webp__decoder__decode_image_config), + (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_webp__decoder__frame_dirty_rect), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_webp__decoder__get_quirk), + (uint32_t(*)(const void*))(&wuffs_webp__decoder__num_animation_loops), + (uint64_t(*)(const void*))(&wuffs_webp__decoder__num_decoded_frame_configs), + (uint64_t(*)(const void*))(&wuffs_webp__decoder__num_decoded_frames), + (wuffs_base__status(*)(void*, + uint64_t, + uint64_t))(&wuffs_webp__decoder__restart_frame), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_webp__decoder__set_quirk), + (wuffs_base__empty_struct(*)(void*, + uint32_t, + bool))(&wuffs_webp__decoder__set_report_metadata), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__more_information*, + wuffs_base__io_buffer*))(&wuffs_webp__decoder__tell_me_more), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_webp__decoder__workbuf_len), +}; + +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_webp__decoder__initialize( + wuffs_webp__decoder* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); + } + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + } + + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } + + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = + wuffs_base__image_decoder__vtable_name; + self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = + (const void*)(&wuffs_webp__decoder__func_ptrs_for__wuffs_base__image_decoder); + return wuffs_base__make_status(NULL); +} + +wuffs_webp__decoder* +wuffs_webp__decoder__alloc(void) { + wuffs_webp__decoder* x = + (wuffs_webp__decoder*)(calloc(1, sizeof(wuffs_webp__decoder))); + if (!x) { + return NULL; } - return wuffs_base__make_empty_struct(); + if (wuffs_webp__decoder__initialize( + x, sizeof(wuffs_webp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; + } + return x; } -// -------- func png.decoder.tell_me_more +size_t +sizeof__wuffs_webp__decoder(void) { + return sizeof(wuffs_webp__decoder); +} + +// ---------------- Function Implementations + +// -------- func webp.decoder.decode_huffman_groups WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_png__decoder__tell_me_more( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; +static wuffs_base__status +wuffs_webp__decoder__decode_huffman_groups( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_n_huffman_groups) { wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_hg = 0; + uint32_t v_ht = 0; - uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_huffman_groups; + if (coro_susp_point) { + v_hg = self->private_data.s_decode_huffman_groups.v_hg; + v_ht = self->private_data.s_decode_huffman_groups.v_ht; + } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - while (true) { - { - wuffs_base__status t_0 = wuffs_png__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_png__error__truncated_input); - goto exit; + v_hg = 0u; + while (v_hg < a_n_huffman_groups) { + v_ht = 0u; + while (v_ht < 5u) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_webp__decoder__decode_huffman_tree(self, a_src, v_hg, v_ht); + if (status.repr) { + goto suspend; + } + v_ht += 1u; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + v_hg += 1u; } + goto ok; ok: - self->private_impl.p_tell_me_more[0] = 0; + self->private_impl.p_decode_huffman_groups = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0; + self->private_impl.p_decode_huffman_groups = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_huffman_groups.v_hg = v_hg; + self->private_data.s_decode_huffman_groups.v_ht = v_ht; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } return status; } -// -------- func png.decoder.do_tell_me_more +// -------- func webp.decoder.decode_huffman_tree WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__do_tell_me_more( - wuffs_png__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { +wuffs_webp__decoder__decode_huffman_tree( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_hg, + uint32_t a_ht) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint16_t v_c2 = 0; - wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer(); - wuffs_base__io_buffer* v_w = &u_w; - uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint64_t v_num_written = 0; - uint64_t v_w_mark = 0; - uint64_t v_r_mark = 0; - wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL); + uint8_t v_c8 = 0; + uint32_t v_use_simple = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint8_t* iop_a_dst = NULL; - uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_dst && a_dst->data.ptr) { - io0_a_dst = a_dst->data.ptr; - io1_a_dst = io0_a_dst + a_dst->meta.wi; - iop_a_dst = io1_a_dst; - io2_a_dst = io0_a_dst + a_dst->data.len; - if (a_dst->meta.closed) { - io2_a_dst = iop_a_dst; - } - } const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -58130,462 +71941,105 @@ wuffs_png__decoder__do_tell_me_more( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0]; - if (coro_susp_point) { - v_zlib_status = self->private_data.s_do_tell_me_more[0].v_zlib_status; - } + uint32_t coro_susp_point = self->private_impl.p_decode_huffman_tree; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((self->private_impl.f_call_sequence & 16u) == 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } - if (self->private_impl.f_metadata_fourcc == 0u) { - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; + if (a_ht >= 4u) { + self->private_impl.f_ht_n_symbols = 40u; + } else if (a_ht > 0u) { + self->private_impl.f_ht_n_symbols = 256u; + } else if (self->private_impl.f_color_cache_bits == 0u) { + self->private_impl.f_ht_n_symbols = 280u; + } else { + self->private_impl.f_ht_n_symbols = (280u + (((uint32_t)(1u)) << self->private_impl.f_color_cache_bits)); } - do { - if (self->private_impl.f_metadata_flavor == 3u) { - while (true) { - if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_y) { - status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position); - goto exit; - } else if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - self->private_impl.f_metadata_flavor, - self->private_impl.f_metadata_fourcc, - self->private_impl.f_metadata_x, - self->private_impl.f_metadata_y, - self->private_impl.f_metadata_z); - } - if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) { - goto label__goto_done__break; - } - self->private_impl.f_metadata_y = self->private_impl.f_metadata_z; - status = wuffs_base__make_status(wuffs_base__suspension__even_more_information); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - if (self->private_impl.f_metadata_is_zlib_compressed) { - if (self->private_impl.f_zlib_is_dirty) { - wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib, - sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); - if (self->private_impl.f_ignore_checksum) { - wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u); - } - } - self->private_impl.f_zlib_is_dirty = true; - self->private_impl.f_ztxt_hist_pos = 0u; + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_use_simple = (self->private_impl.f_bits & 1u); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + if (v_use_simple != 0u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - label__loop__continue:; - while (true) { - if (a_minfo != NULL) { - wuffs_base__more_information__set(a_minfo, - self->private_impl.f_metadata_flavor, - self->private_impl.f_metadata_fourcc, - self->private_impl.f_metadata_x, - self->private_impl.f_metadata_y, - self->private_impl.f_metadata_z); - } - if (self->private_impl.f_metadata_flavor != 4u) { - break; - } - if (self->private_impl.f_metadata_is_zlib_compressed) { - if (self->private_impl.f_chunk_type == 1346585449u) { - { - const bool o_0_closed_a_src = a_src->meta.closed; - const uint8_t *o_0_io2_a_src = io2_a_src; - wuffs_base__io_reader__limit(&io2_a_src, iop_a_src, - ((uint64_t)(self->private_impl.f_chunk_length))); - if (a_src) { - size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); - a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); - a_src->meta.wi = n; - } - v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); - { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8()); - v_zlib_status = t_0; - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); - io2_a_src = o_0_io2_a_src; - if (a_src) { - a_src->meta.closed = o_0_closed_a_src; - a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); - } - } - if (wuffs_base__status__is_ok(&v_zlib_status)) { - self->private_impl.f_metadata_is_zlib_compressed = false; - break; - } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { - status = v_zlib_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; - } - status = v_zlib_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - } else if (self->private_impl.f_chunk_type == 1951945833u) { - { - const bool o_1_closed_a_src = a_src->meta.closed; - const uint8_t *o_1_io2_a_src = io2_a_src; - wuffs_base__io_reader__limit(&io2_a_src, iop_a_src, - ((uint64_t)(self->private_impl.f_chunk_length))); - if (a_src) { - size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); - a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); - a_src->meta.wi = n; - } - v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); - { - if (a_dst) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_1 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8()); - v_zlib_status = t_1; - if (a_dst) { - iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; - } - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); - io2_a_src = o_1_io2_a_src; - if (a_src) { - a_src->meta.closed = o_1_closed_a_src; - a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); - } - } - if (wuffs_base__status__is_ok(&v_zlib_status)) { - self->private_impl.f_metadata_is_zlib_compressed = false; - break; - } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { - status = v_zlib_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; - } - status = v_zlib_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - } else if (self->private_impl.f_chunk_type == 1951945850u) { - if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) { - { - wuffs_base__io_buffer* o_2_v_w = v_w; - uint8_t *o_2_iop_v_w = iop_v_w; - uint8_t *o_2_io0_v_w = io0_v_w; - uint8_t *o_2_io1_v_w = io1_v_w; - uint8_t *o_2_io2_v_w = io2_v_w; - v_w = wuffs_base__io_writer__set( - &u_w, - &iop_v_w, - &io0_v_w, - &io1_v_w, - &io2_v_w, - wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), - self->private_impl.f_ztxt_hist_pos); - { - const bool o_3_closed_a_src = a_src->meta.closed; - const uint8_t *o_3_io2_a_src = io2_a_src; - wuffs_base__io_reader__limit(&io2_a_src, iop_a_src, - ((uint64_t)(self->private_impl.f_chunk_length))); - if (a_src) { - size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); - a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); - a_src->meta.wi = n; - } - v_w_mark = ((uint64_t)(iop_v_w - io0_v_w)); - v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); - { - u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr)); - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - wuffs_base__status t_2 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8()); - v_zlib_status = t_2; - iop_v_w = u_w.data.ptr + u_w.meta.wi; - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - } - wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); - v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))); - io2_a_src = o_3_io2_a_src; - if (a_src) { - a_src->meta.closed = o_3_closed_a_src; - a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); - } - } - v_w = o_2_v_w; - iop_v_w = o_2_iop_v_w; - io0_v_w = o_2_io0_v_w; - io1_v_w = o_2_io1_v_w; - io2_v_w = o_2_io2_v_w; - } - if (v_num_written > 1024u) { - status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o); - goto exit; - } - self->private_impl.f_ztxt_ri = 0u; - self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written)); - wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written); - } - while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) { - v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]]; - if (v_c2 == 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1); - goto exit; - } else if (v_c2 <= 127u) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - goto label__loop__continue; - } - self->private_impl.f_ztxt_ri += 1u; - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1); - } else { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - goto label__loop__continue; - } - self->private_impl.f_ztxt_ri += 1u; - (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2); - } - } - if (wuffs_base__status__is_ok(&v_zlib_status)) { - self->private_impl.f_metadata_is_zlib_compressed = false; - break; - } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) { - status = v_zlib_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; - } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) { - status = v_zlib_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - } - } else { - status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type); - goto exit; - } - } else if ((self->private_impl.f_chunk_type == 1951945833u) && (self->private_impl.f_metadata_fourcc == 1263947862u)) { - while (true) { - if (self->private_impl.f_chunk_length <= 0u) { - goto label__loop__break; - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); - goto label__loop__continue; - } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - goto label__loop__continue; - } - self->private_impl.f_chunk_length -= 1u; - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1); - } - } else { - while (true) { - if (self->private_impl.f_chunk_length <= 0u) { - if (self->private_impl.f_metadata_fourcc == 1263947851u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - goto label__loop__break; - } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); - goto label__loop__continue; - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - if (v_c == 0u) { - self->private_impl.f_chunk_length -= 1u; - iop_a_src += 1u; - goto label__loop__break; - } - v_c2 = WUFFS_PNG__LATIN_1[v_c]; - if (v_c2 == 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1); - goto exit; - } else if (v_c2 <= 127u) { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); - goto label__loop__continue; - } - self->private_impl.f_chunk_length -= 1u; - iop_a_src += 1u; - (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1); - } else { - if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_write); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11); - goto label__loop__continue; - } - self->private_impl.f_chunk_length -= 1u; - iop_a_src += 1u; - (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2); - } - } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + status = wuffs_webp__decoder__decode_huffman_tree_simple(self, a_src, a_hg, a_ht); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_webp__decoder__decode_code_length_code_lengths(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + v_status = wuffs_webp__decoder__build_code_lengths_huffman_nodes(self); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; } - label__loop__break:; - if (self->private_impl.f_metadata_fourcc == 1263947851u) { - self->private_impl.f_metadata_fourcc = 1263947862u; - if (self->private_impl.f_chunk_type == 1951945833u) { - if (self->private_impl.f_chunk_length <= 1u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 2u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_3 = *iop_a_src++; - v_c = t_3; - } - if (v_c == 0u) { - self->private_impl.f_metadata_is_zlib_compressed = false; - } else if (v_c == 1u) { - self->private_impl.f_metadata_is_zlib_compressed = true; - } else { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_4 = *iop_a_src++; - v_c = t_4; - } - if ((v_c != 0u) && self->private_impl.f_metadata_is_zlib_compressed) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); - goto exit; - } - self->private_impl.f_metadata_fourcc -= 2u; - while (self->private_impl.f_metadata_fourcc != 1263947862u) { - self->private_impl.f_metadata_fourcc += 1u; - while (true) { - if (self->private_impl.f_chunk_length <= 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_5 = *iop_a_src++; - v_c = t_5; - } - if (v_c == 0u) { - break; - } - } - } - } else if (self->private_impl.f_chunk_type == 1951945850u) { - if (self->private_impl.f_chunk_length <= 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_impl.f_chunk_length -= 1u; - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_6 = *iop_a_src++; - v_c = t_6; - } - if (v_c != 0u) { - status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method); - goto exit; - } - self->private_impl.f_metadata_is_zlib_compressed = true; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_webp__decoder__build_code_lengths(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + v_status = wuffs_webp__decoder__build_huffman_nodes(self, a_hg, a_ht); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; } - self->private_impl.f_call_sequence &= 239u; - status = wuffs_base__make_status(NULL); goto ok; } - } while (0); - label__goto_done__break:; - if (self->private_impl.f_chunk_length != 0u) { - status = wuffs_base__make_status(wuffs_png__error__bad_chunk); - goto exit; - } - self->private_data.s_do_tell_me_more[0].scratch = 4u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - if (self->private_data.s_do_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; } - iop_a_src += self->private_data.s_do_tell_me_more[0].scratch; - self->private_impl.f_metadata_flavor = 0u; - self->private_impl.f_metadata_fourcc = 0u; - self->private_impl.f_metadata_x = 0u; - self->private_impl.f_metadata_y = 0u; - self->private_impl.f_metadata_z = 0u; - self->private_impl.f_call_sequence &= 239u; - status = wuffs_base__make_status(NULL); - goto ok; ok: - self->private_impl.p_do_tell_me_more[0] = 0; + self->private_impl.p_decode_huffman_tree = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_tell_me_more[0].v_zlib_status = v_zlib_status; + self->private_impl.p_decode_huffman_tree = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (a_dst && a_dst->data.ptr) { - a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); - } if (a_src && a_src->data.ptr) { a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } @@ -58593,563 +72047,1574 @@ wuffs_png__decoder__do_tell_me_more( return status; } -// -------- func png.decoder.history_retain_length +// -------- func webp.decoder.decode_huffman_tree_simple WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_png__decoder__history_retain_length( - const wuffs_png__decoder* self) { - if (!self) { - return 0; +static wuffs_base__status +wuffs_webp__decoder__decode_huffman_tree_simple( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + uint32_t a_hg, + uint32_t a_ht) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_use_second_symbol = 0; + uint32_t v_first_symbol_n_bits = 0; + uint32_t v_symbol0 = 0; + uint32_t v_symbol1 = 0; + uint32_t v_base_offset = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + + uint32_t coro_susp_point = self->private_impl.p_decode_huffman_tree_simple; + if (coro_susp_point) { + v_use_second_symbol = self->private_data.s_decode_huffman_tree_simple.v_use_second_symbol; + v_first_symbol_n_bits = self->private_data.s_decode_huffman_tree_simple.v_first_symbol_n_bits; + v_symbol0 = self->private_data.s_decode_huffman_tree_simple.v_symbol0; + v_base_offset = self->private_data.s_decode_huffman_tree_simple.v_base_offset; } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - return 0u; + if (self->private_impl.f_n_bits < 2u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (self->private_impl.f_n_bits >= 2u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_use_second_symbol = (self->private_impl.f_bits & 1u); + v_first_symbol_n_bits = ((((self->private_impl.f_bits & 2u) >> 1u) * 7u) + 1u); + self->private_impl.f_bits >>= 2u; + self->private_impl.f_n_bits -= 2u; + if (self->private_impl.f_n_bits < v_first_symbol_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= v_first_symbol_n_bits) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_symbol0 = (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_first_symbol_n_bits) - 1u)); + self->private_impl.f_bits >>= v_first_symbol_n_bits; + self->private_impl.f_n_bits -= v_first_symbol_n_bits; + v_base_offset = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[a_ht])); + if (v_use_second_symbol != 0u) { + if (self->private_impl.f_n_bits < 8u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (self->private_impl.f_n_bits >= 8u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_symbol1 = (self->private_impl.f_bits & 255u); + self->private_impl.f_bits >>= 8u; + self->private_impl.f_n_bits -= 8u; + self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 0u)] = ((uint16_t)((v_base_offset + 1u))); + self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 1u)] = ((uint16_t)((v_symbol0 | 32768u))); + self->private_data.f_huffman_nodes[a_hg][(v_base_offset + 2u)] = ((uint16_t)((v_symbol1 | 32768u))); + } else { + self->private_data.f_huffman_nodes[a_hg][v_base_offset] = ((uint16_t)((v_symbol0 | 32768u))); + } + + goto ok; + ok: + self->private_impl.p_decode_huffman_tree_simple = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_huffman_tree_simple = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_huffman_tree_simple.v_use_second_symbol = v_use_second_symbol; + self->private_data.s_decode_huffman_tree_simple.v_first_symbol_n_bits = v_first_symbol_n_bits; + self->private_data.s_decode_huffman_tree_simple.v_symbol0 = v_symbol0; + self->private_data.s_decode_huffman_tree_simple.v_base_offset = v_base_offset; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; } -// -------- func png.decoder.workbuf_len +// -------- func webp.decoder.decode_code_length_code_lengths WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_png__decoder__workbuf_len( - const wuffs_png__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); +static wuffs_base__status +wuffs_webp__decoder__decode_code_length_code_lengths( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_n_codes = 0; + uint32_t v_i = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + + uint32_t coro_susp_point = self->private_impl.p_decode_code_length_code_lengths; + if (coro_susp_point) { + v_n_codes = self->private_data.s_decode_code_length_code_lengths.v_n_codes; + v_i = self->private_data.s_decode_code_length_code_lengths.v_i; } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length); + if (self->private_impl.f_n_bits < 4u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (self->private_impl.f_n_bits >= 4u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_n_codes = ((self->private_impl.f_bits & 15u) + 4u); + self->private_impl.f_bits >>= 4u; + self->private_impl.f_n_bits -= 4u; + v_i = 0u; + while (v_i < v_n_codes) { + if (self->private_impl.f_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= 3u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + self->private_impl.f_code_length_code_lengths[WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[v_i]] = ((uint8_t)((self->private_impl.f_bits & 7u))); + self->private_impl.f_bits >>= 3u; + self->private_impl.f_n_bits -= 3u; + v_i += 1u; + } + while (v_i < 19u) { + self->private_impl.f_code_length_code_lengths[WUFFS_WEBP__CODE_LENGTH_CODE_ORDER[v_i]] = 0u; + v_i += 1u; + } + + goto ok; + ok: + self->private_impl.p_decode_code_length_code_lengths = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_code_length_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_code_length_code_lengths.v_n_codes = v_n_codes; + self->private_data.s_decode_code_length_code_lengths.v_i = v_i; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; } -// -------- func png.decoder.filter_and_swizzle +// -------- func webp.decoder.build_code_lengths_huffman_nodes WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf) { - return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf); +wuffs_webp__decoder__build_code_lengths_huffman_nodes( + wuffs_webp__decoder* self) { + uint32_t v_code_bits = 0; + uint32_t v_code_len = 0; + uint32_t v_symbol = 0; + uint32_t v_histogram[8] = {0}; + uint32_t v_n_used_symbols = 0; + uint32_t v_last_used_symbol = 0; + uint32_t v_subscription_weight = 0; + uint32_t v_subscription_total = 0; + uint32_t v_curr_code = 0; + uint32_t v_next_codes[9] = {0}; + uint32_t v_n_branches = 0; + uint32_t v_h = 0; + uint32_t v_children = 0; + uint16_t v_node = 0; + + v_symbol = 0u; + while (v_symbol < 19u) { + v_code_len = ((uint32_t)(self->private_impl.f_code_length_code_lengths[v_symbol])); + if (v_code_len != 0u) { + v_histogram[v_code_len] += 1u; + v_n_used_symbols += 1u; + v_last_used_symbol = v_symbol; + } + v_symbol += 1u; + } + if (v_n_used_symbols < 1u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code); + } else if (v_n_used_symbols == 1u) { + self->private_data.f_code_lengths_huffman_nodes[0u] = ((uint16_t)((v_last_used_symbol | 32768u))); + return wuffs_base__make_status(NULL); + } + v_subscription_weight = 16384u; + v_code_len = 1u; + while (true) { + v_curr_code = ((uint32_t)(((uint32_t)(v_curr_code + v_histogram[v_code_len])) << 1u)); + v_next_codes[(v_code_len + 1u)] = v_curr_code; + v_subscription_total += ((uint32_t)(v_subscription_weight * v_histogram[v_code_len])); + v_subscription_weight >>= 1u; + if (v_code_len >= 7u) { + break; + } + v_code_len += 1u; + } + if (v_subscription_total > 32768u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_over_subscribed); + } else if (v_subscription_total < 32768u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_under_subscribed); + } + self->private_data.f_code_lengths_huffman_nodes[0u] = 0u; + v_symbol = 0u; + while (v_symbol < 19u) { + v_code_len = ((uint32_t)(self->private_impl.f_code_length_code_lengths[v_symbol])); + if (v_code_len > 0u) { + v_code_bits = v_next_codes[v_code_len]; + v_next_codes[v_code_len] += 1u; + v_code_bits <<= (32u - v_code_len); + v_h = 0u; + while (v_code_len > 0u) { + v_node = self->private_data.f_code_lengths_huffman_nodes[v_h]; + if (v_node == 0u) { + v_children = ((uint32_t)(1u + ((uint32_t)(2u * v_n_branches)))); + v_children = wuffs_base__u32__min(v_children, 35u); + self->private_data.f_code_lengths_huffman_nodes[v_h] = ((uint16_t)(v_children)); + self->private_data.f_code_lengths_huffman_nodes[(v_children + 0u)] = 0u; + self->private_data.f_code_lengths_huffman_nodes[(v_children + 1u)] = 0u; + v_h = (v_children + (v_code_bits >> 31u)); + v_n_branches += 1u; + } else { + v_children = ((uint32_t)(v_node)); + v_h = (wuffs_base__u32__min(v_children, 35u) + (v_code_bits >> 31u)); + } + v_code_bits <<= 1u; + v_code_len -= 1u; + } + self->private_data.f_code_lengths_huffman_nodes[v_h] = ((uint16_t)((v_symbol | 32768u))); + } + v_symbol += 1u; + } + return wuffs_base__make_status(NULL); } +// -------- func webp.decoder.build_huffman_nodes + WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle__choosy_default( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf) { - wuffs_base__pixel_format v_dst_pixfmt = {0}; - uint32_t v_dst_bits_per_pixel = 0; - uint64_t v_dst_bytes_per_pixel = 0; - uint64_t v_dst_bytes_per_row0 = 0; - uint64_t v_dst_bytes_per_row1 = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - uint32_t v_y = 0; - wuffs_base__slice_u8 v_dst = {0}; - uint8_t v_filter = 0; - wuffs_base__slice_u8 v_curr_row = {0}; - wuffs_base__slice_u8 v_prev_row = {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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - return wuffs_base__make_status(wuffs_base__error__unsupported_option); +wuffs_webp__decoder__build_huffman_nodes( + wuffs_webp__decoder* self, + uint32_t a_hg, + uint32_t a_ht) { + uint32_t v_base_offset = 0; + uint32_t v_code_bits = 0; + uint32_t v_code_len = 0; + uint32_t v_symbol = 0; + uint32_t v_histogram[16] = {0}; + uint32_t v_n_used_symbols = 0; + uint32_t v_last_used_symbol = 0; + uint32_t v_subscription_weight = 0; + uint32_t v_subscription_total = 0; + uint32_t v_curr_code = 0; + uint32_t v_next_codes[17] = {0}; + uint32_t v_n_branches = 0; + uint32_t v_h = 0; + uint32_t v_children = 0; + uint16_t v_node = 0; + + v_base_offset = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[a_ht])); + v_symbol = 0u; + while (v_symbol < self->private_impl.f_ht_n_symbols) { + v_code_len = ((uint32_t)(((uint16_t)(self->private_data.f_code_lengths[v_symbol] & 15u)))); + if (v_code_len != 0u) { + v_histogram[v_code_len] += 1u; + v_n_used_symbols += 1u; + v_last_used_symbol = v_symbol; + } + v_symbol += 1u; + } + if (v_n_used_symbols < 1u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code); + } else if (v_n_used_symbols == 1u) { + self->private_data.f_huffman_nodes[a_hg][v_base_offset] = ((uint16_t)((v_last_used_symbol | 32768u))); + return wuffs_base__make_status(NULL); } - v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); - v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel); - v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) { - v_tab = wuffs_base__table_u8__subtable_ij(v_tab, - 0u, - 0u, - v_dst_bytes_per_row1, - ((uint64_t)(v_tab.height))); + v_subscription_weight = 16384u; + v_code_len = 1u; + while (true) { + v_curr_code = ((uint32_t)(((uint32_t)(v_curr_code + v_histogram[v_code_len])) << 1u)); + v_next_codes[(v_code_len + 1u)] = v_curr_code; + v_subscription_total += ((uint32_t)(v_subscription_weight * v_histogram[v_code_len])); + v_subscription_weight >>= 1u; + if (v_code_len >= 15u) { + break; + } + v_code_len += 1u; + } + if (v_subscription_total > 32768u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_over_subscribed); + } else if (v_subscription_total < 32768u) { + return wuffs_base__make_status(wuffs_webp__error__bad_huffman_code_under_subscribed); + } + self->private_data.f_huffman_nodes[a_hg][v_base_offset] = 0u; + v_symbol = 0u; + while (v_symbol < self->private_impl.f_ht_n_symbols) { + v_code_len = ((uint32_t)(((uint16_t)(self->private_data.f_code_lengths[v_symbol] & 15u)))); + if (v_code_len != 0u) { + v_code_bits = v_next_codes[v_code_len]; + v_next_codes[v_code_len] += 1u; + v_code_bits <<= (32u - v_code_len); + v_h = v_base_offset; + while (v_code_len > 0u) { + v_node = self->private_data.f_huffman_nodes[a_hg][v_h]; + if (v_node == 0u) { + v_children = ((uint32_t)(v_base_offset + ((uint32_t)(1u + ((uint32_t)(2u * v_n_branches)))))); + v_children = wuffs_base__u32__min(v_children, 6265u); + self->private_data.f_huffman_nodes[a_hg][v_h] = ((uint16_t)(v_children)); + self->private_data.f_huffman_nodes[a_hg][(v_children + 0u)] = 0u; + self->private_data.f_huffman_nodes[a_hg][(v_children + 1u)] = 0u; + v_h = (v_children + (v_code_bits >> 31u)); + v_n_branches += 1u; + } else { + v_children = ((uint32_t)(v_node)); + v_h = (wuffs_base__u32__min(v_children, 6265u) + (v_code_bits >> 31u)); + } + v_code_bits <<= 1u; + v_code_len -= 1u; + } + self->private_data.f_huffman_nodes[a_hg][v_h] = ((uint16_t)((v_symbol | 32768u))); + } + v_symbol += 1u; } - if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) { - v_tab = wuffs_base__table_u8__subtable_ij(v_tab, - v_dst_bytes_per_row0, - 0u, - ((uint64_t)(v_tab.width)), - ((uint64_t)(v_tab.height))); - } else { - v_tab = wuffs_base__table_u8__subtable_ij(v_tab, - 0u, - 0u, - 0u, - 0u); + return wuffs_base__make_status(NULL); +} + +// -------- func webp.decoder.build_code_lengths + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__build_code_lengths( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_use_length = 0; + uint32_t v_length_n_bits = 0; + uint32_t v_length = 0; + uint16_t v_prev_code_length = 0; + uint32_t v_h = 0; + uint32_t v_s = 0; + uint32_t v_s_max = 0; + uint16_t v_node = 0; + uint32_t v_symbol = 0; + uint16_t v_repeat_value = 0; + uint32_t v_repeat_n_bits = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - v_y = self->private_impl.f_frame_rect_y0; - while (v_y < self->private_impl.f_frame_rect_y1) { - v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y); - if (1u > ((uint64_t)(a_workbuf.len))) { - return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); + + uint32_t coro_susp_point = self->private_impl.p_build_code_lengths; + if (coro_susp_point) { + v_length_n_bits = self->private_data.s_build_code_lengths.v_length_n_bits; + v_prev_code_length = self->private_data.s_build_code_lengths.v_prev_code_length; + v_s = self->private_data.s_build_code_lengths.v_s; + v_s_max = self->private_data.s_build_code_lengths.v_s_max; + v_node = self->private_data.s_build_code_lengths.v_node; + v_repeat_value = self->private_data.s_build_code_lengths.v_repeat_value; + v_repeat_n_bits = self->private_data.s_build_code_lengths.v_repeat_n_bits; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; } - v_filter = a_workbuf.ptr[0u]; - a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u); - if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) { - return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); + v_use_length = (self->private_impl.f_bits & 1u); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + self->private_impl.f_ht_code_lengths_remaining = self->private_impl.f_ht_n_symbols; + if (v_use_length != 0u) { + if (self->private_impl.f_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= 3u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_length_n_bits = (((self->private_impl.f_bits & 7u) * 2u) + 2u); + self->private_impl.f_bits >>= 3u; + self->private_impl.f_n_bits -= 3u; + while (self->private_impl.f_n_bits < v_length_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (self->private_impl.f_n_bits >= v_length_n_bits) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_length = ((self->private_impl.f_bits & ((((uint32_t)(1u)) << v_length_n_bits) - 1u)) + 2u); + self->private_impl.f_bits >>= v_length_n_bits; + self->private_impl.f_n_bits -= v_length_n_bits; + if (v_length > self->private_impl.f_ht_n_symbols) { + status = wuffs_base__make_status(wuffs_webp__error__bad_huffman_code); + goto exit; + } + self->private_impl.f_ht_code_lengths_remaining = v_length; } - v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row); - a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row); - if (v_filter == 0u) { - } else if (v_filter == 1u) { - wuffs_png__decoder__filter_1(self, v_curr_row); - } else if (v_filter == 2u) { - wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row); - } else if (v_filter == 3u) { - wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row); - } else if (v_filter == 4u) { - wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row); - } else { - return wuffs_base__make_status(wuffs_png__error__bad_filter); + v_prev_code_length = 8u; + while (v_s < self->private_impl.f_ht_n_symbols) { + if (self->private_impl.f_ht_code_lengths_remaining <= 0u) { + while (v_s < self->private_impl.f_ht_n_symbols) { + self->private_data.f_code_lengths[v_s] = 0u; + v_s += 1u; + } + break; + } + self->private_impl.f_ht_code_lengths_remaining -= 1u; + v_h = 0u; + while (true) { + v_node = self->private_data.f_code_lengths_huffman_nodes[v_h]; + if (v_node >= 32768u) { + break; + } else if (v_node > 35u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_huffman_code); + goto exit; + } + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_h = (((uint32_t)(v_node)) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + } + v_symbol = ((uint32_t)(((uint16_t)(v_node & 32767u)))); + if (v_symbol == 0u) { + self->private_data.f_code_lengths[v_s] = 0u; + v_s += 1u; + continue; + } else if (v_symbol < 16u) { + v_prev_code_length = ((uint16_t)(v_symbol)); + self->private_data.f_code_lengths[v_s] = v_prev_code_length; + v_s += 1u; + continue; + } else if (v_symbol == 16u) { + v_repeat_value = v_prev_code_length; + } else { + v_repeat_value = 0u; + } + v_repeat_n_bits = ((uint32_t)(WUFFS_WEBP__REPEAT_N_BITS[(v_symbol & 3u)])); + v_s_max = ((uint32_t)(((uint32_t)(WUFFS_WEBP__REPEAT_COUNTS[(v_symbol & 3u)])) + v_s)); + if (self->private_impl.f_n_bits < v_repeat_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if (self->private_impl.f_n_bits >= v_repeat_n_bits) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_s_max += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_repeat_n_bits) - 1u)); + self->private_impl.f_bits >>= v_repeat_n_bits; + self->private_impl.f_n_bits -= v_repeat_n_bits; + if (v_s_max > self->private_impl.f_ht_n_symbols) { + status = wuffs_base__make_status(wuffs_webp__error__bad_huffman_code); + goto exit; + } + while (v_s < v_s_max) { + self->private_data.f_code_lengths[v_s] = v_repeat_value; + v_s += 1u; + } } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row); - v_prev_row = v_curr_row; - v_y += 1u; + + goto ok; + ok: + self->private_impl.p_build_code_lengths = 0; + goto exit; } - return wuffs_base__make_status(NULL); + + goto suspend; + suspend: + self->private_impl.p_build_code_lengths = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_build_code_lengths.v_length_n_bits = v_length_n_bits; + self->private_data.s_build_code_lengths.v_prev_code_length = v_prev_code_length; + self->private_data.s_build_code_lengths.v_s = v_s; + self->private_data.s_build_code_lengths.v_s_max = v_s_max; + self->private_data.s_build_code_lengths.v_node = v_node; + self->private_data.s_build_code_lengths.v_repeat_value = v_repeat_value; + self->private_data.s_build_code_lengths.v_repeat_n_bits = v_repeat_n_bits; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; } -// -------- func png.decoder.filter_and_swizzle_tricky +// -------- func webp.decoder.decode_pixels_slow WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_png__decoder__filter_and_swizzle_tricky( - wuffs_png__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__slice_u8 a_workbuf) { - wuffs_base__pixel_format v_dst_pixfmt = {0}; - uint32_t v_dst_bits_per_pixel = 0; - uint64_t v_dst_bytes_per_pixel = 0; - uint64_t v_dst_bytes_per_row1 = 0; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__table_u8 v_tab = {0}; - uint64_t v_src_bytes_per_pixel = 0; +wuffs_webp__decoder__decode_pixels_slow( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_dst, + wuffs_base__io_buffer* a_src, + uint32_t a_width, + uint32_t a_height, + wuffs_base__slice_u8 a_tile_data, + uint32_t a_tile_size_log2) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint64_t v_p = 0; + uint64_t v_p_max = 0; + uint32_t v_tile_size_log2 = 0; + uint32_t v_width_in_tiles = 0; uint32_t v_x = 0; uint32_t v_y = 0; - uint64_t v_i = 0; - wuffs_base__slice_u8 v_dst = {0}; - uint8_t v_filter = 0; - wuffs_base__slice_u8 v_s = {0}; - wuffs_base__slice_u8 v_curr_row = {0}; - wuffs_base__slice_u8 v_prev_row = {0}; - uint8_t v_bits_unpacked[8] = {0}; - uint8_t v_bits_packed = 0; - uint8_t v_packs_remaining = 0; - uint8_t v_multiplier = 0; - uint8_t v_shift = 0; + uint32_t v_i = 0; + uint32_t v_hg = 0; + uint32_t v_h = 0; + uint16_t v_node = 0; + uint32_t v_pixel_g = 0; + uint32_t v_color = 0; + wuffs_base__slice_u8 v_dst_pixel = {0}; + uint32_t v_back_ref_len_n_bits = 0; + uint32_t v_back_ref_len_minus_1 = 0; + uint32_t v_back_ref_dist_n_bits = 0; + uint32_t v_back_ref_dist_sym = 0; + uint32_t v_back_ref_dist_premap_minus_1 = 0; + uint32_t v_back_ref_dist_minus_1 = 0; + uint32_t v_dm = 0; + uint32_t v_dx = 0; + uint32_t v_dy = 0; + uint64_t v_p_end = 0; + uint64_t v_dist4 = 0; + uint64_t v_q = 0; + wuffs_base__slice_u8 v_color_cache_pixels = {0}; + uint64_t v_color_cache_p = 0; + uint32_t v_color_cache_shift = 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - return wuffs_base__make_status(wuffs_base__error__unsupported_option); - } - v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); - v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_src_bytes_per_pixel = 1u; - if (self->private_impl.f_depth >= 8u) { - v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)((self->private_impl.f_depth >> 3u)))); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (self->private_impl.f_chunk_type_array[0u] == 73u) { - v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5u])); - } else { - v_y = self->private_impl.f_frame_rect_y0; + + uint32_t coro_susp_point = self->private_impl.p_decode_pixels_slow; + if (coro_susp_point) { + v_p = self->private_data.s_decode_pixels_slow.v_p; + v_p_max = self->private_data.s_decode_pixels_slow.v_p_max; + v_tile_size_log2 = self->private_data.s_decode_pixels_slow.v_tile_size_log2; + v_width_in_tiles = self->private_data.s_decode_pixels_slow.v_width_in_tiles; + v_x = self->private_data.s_decode_pixels_slow.v_x; + v_y = self->private_data.s_decode_pixels_slow.v_y; + v_hg = self->private_data.s_decode_pixels_slow.v_hg; + v_node = self->private_data.s_decode_pixels_slow.v_node; + v_color = self->private_data.s_decode_pixels_slow.v_color; + v_back_ref_len_n_bits = self->private_data.s_decode_pixels_slow.v_back_ref_len_n_bits; + v_back_ref_len_minus_1 = self->private_data.s_decode_pixels_slow.v_back_ref_len_minus_1; + v_back_ref_dist_n_bits = self->private_data.s_decode_pixels_slow.v_back_ref_dist_n_bits; + v_back_ref_dist_premap_minus_1 = self->private_data.s_decode_pixels_slow.v_back_ref_dist_premap_minus_1; + v_color_cache_p = self->private_data.s_decode_pixels_slow.v_color_cache_p; } - while (v_y < self->private_impl.f_frame_rect_y1) { - v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y); - if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1); - } - if (1u > ((uint64_t)(a_workbuf.len))) { - return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); - } - v_filter = a_workbuf.ptr[0u]; - a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u); - if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) { - return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length); - } - v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row); - a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row); - if (v_filter == 0u) { - } else if (v_filter == 1u) { - wuffs_png__decoder__filter_1(self, v_curr_row); - } else if (v_filter == 2u) { - wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row); - } else if (v_filter == 3u) { - wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row); - } else if (v_filter == 4u) { - wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row); - } else { - return wuffs_base__make_status(wuffs_png__error__bad_filter); + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + v_p_max = ((uint64_t)((4u * a_width * a_height))); + if (((uint64_t)(a_dst.len)) < v_p_max) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer); + goto exit; } - v_s = v_curr_row; - if (self->private_impl.f_chunk_type_array[0u] == 73u) { - v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2u])); + if (a_tile_size_log2 != 0u) { + v_tile_size_log2 = a_tile_size_log2; + v_width_in_tiles = ((a_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2); } else { - v_x = self->private_impl.f_frame_rect_x0; + v_tile_size_log2 = 31u; + v_width_in_tiles = 1u; } - if (self->private_impl.f_depth == 8u) { - while (v_x < self->private_impl.f_frame_rect_x1) { - v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); - if (v_i <= ((uint64_t)(v_dst.len))) { - if (self->private_impl.f_color_type == 4u) { - if (2u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[0u]; - v_bits_unpacked[1u] = v_s.ptr[0u]; - v_bits_unpacked[2u] = v_s.ptr[0u]; - v_bits_unpacked[3u] = v_s.ptr[1u]; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); - } - } else if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) { - if (self->private_impl.f_color_type == 0u) { - if (1u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[0u]; - v_bits_unpacked[1u] = v_s.ptr[0u]; - v_bits_unpacked[2u] = v_s.ptr[0u]; - v_bits_unpacked[3u] = 255u; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); - if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | - (((uint32_t)(v_bits_unpacked[1u])) << 8u) | - (((uint32_t)(v_bits_unpacked[2u])) << 16u) | - (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { - v_bits_unpacked[0u] = 0u; - v_bits_unpacked[1u] = 0u; - v_bits_unpacked[2u] = 0u; - v_bits_unpacked[3u] = 0u; - } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); + while (v_p < v_p_max) { + v_i = ((uint32_t)(((uint32_t)(((uint32_t)(((uint32_t)((v_y >> v_tile_size_log2) * v_width_in_tiles)) + (v_x >> v_tile_size_log2))) * 4u)) + 1u)); + if (((uint64_t)(v_i)) < ((uint64_t)(a_tile_data.len))) { + v_hg = ((uint32_t)(a_tile_data.ptr[((uint64_t)(v_i))])); + } + v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[0u])); + while (true) { + v_node = self->private_data.f_huffman_nodes[v_hg][v_h]; + if (v_node >= 32768u) { + break; + } else if (v_node > 6265u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_huffman_code); + goto exit; + } + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_h = (((uint32_t)(v_node)) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + } + v_pixel_g = ((uint32_t)(((uint16_t)(v_node & 32767u)))); + if (v_pixel_g < 256u) { + v_color = (v_pixel_g << 8u); + v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[1u])); + while (true) { + v_node = self->private_data.f_huffman_nodes[v_hg][v_h]; + if (v_node >= 32768u) { + break; + } + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } - } else { - if (3u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[2u]; - v_bits_unpacked[1u] = v_s.ptr[1u]; - v_bits_unpacked[2u] = v_s.ptr[0u]; - v_bits_unpacked[3u] = 255u; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 3u); - if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | - (((uint32_t)(v_bits_unpacked[1u])) << 8u) | - (((uint32_t)(v_bits_unpacked[2u])) << 16u) | - (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { - v_bits_unpacked[0u] = 0u; - v_bits_unpacked[1u] = 0u; - v_bits_unpacked[2u] = 0u; - v_bits_unpacked[3u] = 0u; - } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + } + v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 16u); + v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[2u])); + while (true) { + v_node = self->private_data.f_huffman_nodes[v_hg][v_h]; + if (v_node >= 32768u) { + break; + } + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; } - } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) { - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__slice_u8__subslice_j(v_s, v_src_bytes_per_pixel)); - v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel); + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; } + v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; } - v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); - } - } else if (self->private_impl.f_depth < 8u) { - v_multiplier = 1u; - if (self->private_impl.f_color_type == 0u) { - v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth]; - } - v_shift = ((8u - self->private_impl.f_depth) & 7u); - v_packs_remaining = 0u; - while (v_x < self->private_impl.f_frame_rect_x1) { - v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); - if (v_i <= ((uint64_t)(v_dst.len))) { - if ((v_packs_remaining == 0u) && (1u <= ((uint64_t)(v_s.len)))) { - v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth]; - v_bits_packed = v_s.ptr[0u]; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 0u); + v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[3u])); + while (true) { + v_node = self->private_data.f_huffman_nodes[v_hg][v_h]; + if (v_node >= 32768u) { + break; } - v_bits_unpacked[0u] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier)); - v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth)); - v_packs_remaining = ((uint8_t)(v_packs_remaining - 1u)); - if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) { - v_bits_unpacked[1u] = v_bits_unpacked[0u]; - v_bits_unpacked[2u] = v_bits_unpacked[0u]; - v_bits_unpacked[3u] = 255u; - if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) | - (((uint32_t)(v_bits_unpacked[1u])) << 8u) | - (((uint32_t)(v_bits_unpacked[2u])) << 16u) | - (((uint32_t)(v_bits_unpacked[3u])) << 24u))) { - v_bits_unpacked[0u] = 0u; - v_bits_unpacked[1u] = 0u; - v_bits_unpacked[2u] = 0u; - v_bits_unpacked[3u] = 0u; + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4)); - } else { - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 1)); + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; } + v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; } - v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); - } - } else { - while (v_x < self->private_impl.f_frame_rect_x1) { - v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel); - if (v_i <= ((uint64_t)(v_dst.len))) { - if (self->private_impl.f_color_type == 0u) { - if (2u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[1u]; - v_bits_unpacked[1u] = v_s.ptr[0u]; - v_bits_unpacked[2u] = v_s.ptr[1u]; - v_bits_unpacked[3u] = v_s.ptr[0u]; - v_bits_unpacked[4u] = v_s.ptr[1u]; - v_bits_unpacked[5u] = v_s.ptr[0u]; - v_bits_unpacked[6u] = 255u; - v_bits_unpacked[7u] = 255u; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); - if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) | - (((uint64_t)(v_bits_unpacked[1u])) << 8u) | - (((uint64_t)(v_bits_unpacked[2u])) << 16u) | - (((uint64_t)(v_bits_unpacked[3u])) << 24u) | - (((uint64_t)(v_bits_unpacked[4u])) << 32u) | - (((uint64_t)(v_bits_unpacked[5u])) << 40u) | - (((uint64_t)(v_bits_unpacked[6u])) << 48u) | - (((uint64_t)(v_bits_unpacked[7u])) << 56u))) { - v_bits_unpacked[0u] = 0u; - v_bits_unpacked[1u] = 0u; - v_bits_unpacked[2u] = 0u; - v_bits_unpacked[3u] = 0u; - v_bits_unpacked[4u] = 0u; - v_bits_unpacked[5u] = 0u; - v_bits_unpacked[6u] = 0u; - v_bits_unpacked[7u] = 0u; + v_color |= (((uint32_t)(((uint16_t)(v_node & 255u)))) << 24u); + } else if (v_pixel_g < 280u) { + if (v_pixel_g < 260u) { + v_back_ref_len_minus_1 = (v_pixel_g - 256u); + } else { + v_back_ref_len_n_bits = ((v_pixel_g - 258u) >> 1u); + v_back_ref_len_minus_1 = ((((uint32_t)(2u)) + (v_pixel_g & 1u)) << v_back_ref_len_n_bits); + while (self->private_impl.f_n_bits < v_back_ref_len_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; } - } else if (self->private_impl.f_color_type == 2u) { - if (6u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[5u]; - v_bits_unpacked[1u] = v_s.ptr[4u]; - v_bits_unpacked[2u] = v_s.ptr[3u]; - v_bits_unpacked[3u] = v_s.ptr[2u]; - v_bits_unpacked[4u] = v_s.ptr[1u]; - v_bits_unpacked[5u] = v_s.ptr[0u]; - v_bits_unpacked[6u] = 255u; - v_bits_unpacked[7u] = 255u; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u); - if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) | - (((uint64_t)(v_bits_unpacked[1u])) << 8u) | - (((uint64_t)(v_bits_unpacked[2u])) << 16u) | - (((uint64_t)(v_bits_unpacked[3u])) << 24u) | - (((uint64_t)(v_bits_unpacked[4u])) << 32u) | - (((uint64_t)(v_bits_unpacked[5u])) << 40u) | - (((uint64_t)(v_bits_unpacked[6u])) << 48u) | - (((uint64_t)(v_bits_unpacked[7u])) << 56u))) { - v_bits_unpacked[0u] = 0u; - v_bits_unpacked[1u] = 0u; - v_bits_unpacked[2u] = 0u; - v_bits_unpacked[3u] = 0u; - v_bits_unpacked[4u] = 0u; - v_bits_unpacked[5u] = 0u; - v_bits_unpacked[6u] = 0u; - v_bits_unpacked[7u] = 0u; + if (self->private_impl.f_n_bits >= v_back_ref_len_n_bits) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_back_ref_len_minus_1 += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_back_ref_len_n_bits) - 1u)); + self->private_impl.f_bits >>= v_back_ref_len_n_bits; + self->private_impl.f_n_bits -= v_back_ref_len_n_bits; + } + v_h = ((uint32_t)(WUFFS_WEBP__HUFFMAN_TABLE_BASE_OFFSETS[4u])); + while (true) { + v_node = self->private_data.f_huffman_nodes[v_hg][v_h]; + if (v_node >= 32768u) { + break; + } + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; } - } else if (self->private_impl.f_color_type == 4u) { - if (4u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[1u]; - v_bits_unpacked[1u] = v_s.ptr[0u]; - v_bits_unpacked[2u] = v_s.ptr[1u]; - v_bits_unpacked[3u] = v_s.ptr[0u]; - v_bits_unpacked[4u] = v_s.ptr[1u]; - v_bits_unpacked[5u] = v_s.ptr[0u]; - v_bits_unpacked[6u] = v_s.ptr[3u]; - v_bits_unpacked[7u] = v_s.ptr[2u]; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_h = ((((uint32_t)(v_node)) & 4095u) + (self->private_impl.f_bits & 1u)); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + } + v_back_ref_dist_sym = ((uint32_t)(((uint16_t)(v_node & 32767u)))); + if (v_back_ref_dist_sym < 4u) { + v_back_ref_dist_premap_minus_1 = v_back_ref_dist_sym; + } else if (v_back_ref_dist_sym < 40u) { + v_back_ref_dist_n_bits = ((v_back_ref_dist_sym - 2u) >> 1u); + v_back_ref_dist_premap_minus_1 = ((((uint32_t)(2u)) + (v_back_ref_dist_sym & 1u)) << v_back_ref_dist_n_bits); + while (self->private_impl.f_n_bits < v_back_ref_dist_n_bits) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; } - } else { - if (8u <= ((uint64_t)(v_s.len))) { - v_bits_unpacked[0u] = v_s.ptr[5u]; - v_bits_unpacked[1u] = v_s.ptr[4u]; - v_bits_unpacked[2u] = v_s.ptr[3u]; - v_bits_unpacked[3u] = v_s.ptr[2u]; - v_bits_unpacked[4u] = v_s.ptr[1u]; - v_bits_unpacked[5u] = v_s.ptr[0u]; - v_bits_unpacked[6u] = v_s.ptr[7u]; - v_bits_unpacked[7u] = v_s.ptr[6u]; - v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u); + if (self->private_impl.f_n_bits >= v_back_ref_dist_n_bits) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; } - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 8)); + v_back_ref_dist_premap_minus_1 += (self->private_impl.f_bits & ((((uint32_t)(1u)) << v_back_ref_dist_n_bits) - 1u)); + self->private_impl.f_bits >>= v_back_ref_dist_n_bits; + self->private_impl.f_n_bits -= v_back_ref_dist_n_bits; } - v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]); + if (v_back_ref_dist_premap_minus_1 >= 120u) { + v_back_ref_dist_minus_1 = (v_back_ref_dist_premap_minus_1 - 120u); + } else { + v_dm = ((uint32_t)(WUFFS_WEBP__DISTANCE_MAP[v_back_ref_dist_premap_minus_1])); + v_dy = (v_dm >> 4u); + v_dx = ((uint32_t)(7u - (v_dm & 15u))); + v_back_ref_dist_minus_1 = ((uint32_t)((a_width * v_dy) + v_dx)); + } + v_p_end = (v_p + ((uint64_t)(((v_back_ref_len_minus_1 + 1u) * 4u)))); + v_dist4 = ((((uint64_t)(v_back_ref_dist_minus_1)) * 4u) + 4u); + if ((v_p_end > v_p_max) || (v_p_end > ((uint64_t)(a_dst.len))) || (v_p < v_dist4)) { + status = wuffs_base__make_status(wuffs_webp__error__bad_back_reference); + goto exit; + } + v_q = (v_p - v_dist4); + while ((v_q < v_p) && (v_p < v_p_end)) { + a_dst.ptr[v_p] = a_dst.ptr[v_q]; + v_p += 1u; + v_q += 1u; + } + v_x += (v_back_ref_len_minus_1 + 1u); + while (v_x >= a_width) { + v_x -= a_width; + v_y += 1u; + } + continue; + } else { + if ((v_color_cache_p > v_p) || (v_p > ((uint64_t)(a_dst.len)))) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer); + goto exit; + } + v_color_cache_pixels = wuffs_base__slice_u8__subslice_ij(a_dst, v_color_cache_p, v_p); + v_color_cache_p = v_p; + v_color_cache_shift = ((32u - self->private_impl.f_color_cache_bits) & 31u); + while (((uint64_t)(v_color_cache_pixels.len)) >= 4u) { + v_color = wuffs_base__peek_u32le__no_bounds_check(v_color_cache_pixels.ptr); + self->private_data.f_color_cache[((((uint32_t)(v_color * 506832829u)) >> v_color_cache_shift) & 2047u)] = v_color; + v_color_cache_pixels = wuffs_base__slice_u8__subslice_i(v_color_cache_pixels, 4u); + } + v_color = self->private_data.f_color_cache[((v_pixel_g - 280u) & 2047u)]; + } + if (v_p > ((uint64_t)(a_dst.len))) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer); + goto exit; + } + v_dst_pixel = wuffs_base__slice_u8__subslice_i(a_dst, v_p); + if (((uint64_t)(v_dst_pixel.len)) < 4u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_dst_buffer); + goto exit; + } + wuffs_base__poke_u32le__no_bounds_check(v_dst_pixel.ptr, v_color); + v_p += 4u; + v_x += 1u; + if (v_x == a_width) { + v_x = 0u; + v_y += 1u; } } - v_prev_row = v_curr_row; - v_y += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]); - } - return wuffs_base__make_status(NULL); -} -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) + goto ok; + ok: + self->private_impl.p_decode_pixels_slow = 0; + goto exit; + } -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) + goto suspend; + suspend: + self->private_impl.p_decode_pixels_slow = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_pixels_slow.v_p = v_p; + self->private_data.s_decode_pixels_slow.v_p_max = v_p_max; + self->private_data.s_decode_pixels_slow.v_tile_size_log2 = v_tile_size_log2; + self->private_data.s_decode_pixels_slow.v_width_in_tiles = v_width_in_tiles; + self->private_data.s_decode_pixels_slow.v_x = v_x; + self->private_data.s_decode_pixels_slow.v_y = v_y; + self->private_data.s_decode_pixels_slow.v_hg = v_hg; + self->private_data.s_decode_pixels_slow.v_node = v_node; + self->private_data.s_decode_pixels_slow.v_color = v_color; + self->private_data.s_decode_pixels_slow.v_back_ref_len_n_bits = v_back_ref_len_n_bits; + self->private_data.s_decode_pixels_slow.v_back_ref_len_minus_1 = v_back_ref_len_minus_1; + self->private_data.s_decode_pixels_slow.v_back_ref_dist_n_bits = v_back_ref_dist_n_bits; + self->private_data.s_decode_pixels_slow.v_back_ref_dist_premap_minus_1 = v_back_ref_dist_premap_minus_1; + self->private_data.s_decode_pixels_slow.v_color_cache_p = v_color_cache_p; -// ---------------- Status Codes Implementations + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } -const char wuffs_tga__error__bad_header[] = "#tga: bad header"; -const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding"; -const char wuffs_tga__error__truncated_input[] = "#tga: truncated input"; -const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file"; + return status; +} -// ---------------- Private Consts +// -------- func webp.decoder.apply_transform_predictor -// ---------------- Private Initializer Prototypes +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_predictor( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix, + wuffs_base__slice_u8 a_tile_data) { + uint64_t v_w4 = 0; + wuffs_base__slice_u8 v_prev_row = {0}; + wuffs_base__slice_u8 v_curr_row = {0}; + uint32_t v_tile_size_log2 = 0; + uint32_t v_tiles_per_row = 0; + uint32_t v_mask = 0; + uint32_t v_y = 0; + uint32_t v_x = 0; + uint64_t v_t = 0; + wuffs_base__slice_u8 v_tile_data = {0}; + uint8_t v_mode = 0; + uint32_t v_l0 = 0; + uint32_t v_l1 = 0; + uint32_t v_l2 = 0; + uint32_t v_l3 = 0; + uint32_t v_c0 = 0; + uint32_t v_c1 = 0; + uint32_t v_c2 = 0; + uint32_t v_c3 = 0; + uint32_t v_t0 = 0; + uint32_t v_t1 = 0; + uint32_t v_t2 = 0; + uint32_t v_t3 = 0; + uint32_t v_sum_l = 0; + uint32_t v_sum_t = 0; + + if ((self->private_impl.f_width <= 0u) || (self->private_impl.f_height <= 0u)) { + return wuffs_base__make_empty_struct(); + } + v_w4 = ((uint64_t)((self->private_impl.f_width * 4u))); + v_curr_row = wuffs_base__utility__empty_slice_u8(); + if (v_w4 <= ((uint64_t)(a_pix.len))) { + v_curr_row = wuffs_base__slice_u8__subslice_j(a_pix, v_w4); + } + if (((uint64_t)(v_curr_row.len)) >= 4u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[3u] += 255u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + while (((uint64_t)(v_curr_row.len)) >= 8u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += v_curr_row.ptr[0u]; + v_curr_row.ptr[5u] += v_curr_row.ptr[1u]; + v_curr_row.ptr[6u] += v_curr_row.ptr[2u]; + v_curr_row.ptr[7u] += v_curr_row.ptr[3u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_curr_row = wuffs_base__slice_u8__subslice_i(v_curr_row, 4u); + } + v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[0u])); + v_tiles_per_row = ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2); + v_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u); + v_y = 1u; + while (v_y < self->private_impl.f_height) { + v_t = ((uint64_t)((4u * (v_y >> v_tile_size_log2) * v_tiles_per_row))); + v_tile_data = wuffs_base__utility__empty_slice_u8(); + if (v_t <= ((uint64_t)(a_tile_data.len))) { + v_tile_data = wuffs_base__slice_u8__subslice_i(a_tile_data, v_t); + if (((uint64_t)(v_tile_data.len)) >= 4u) { + v_mode = ((uint8_t)(v_tile_data.ptr[1u] & 15u)); + v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u); + } + } + if (v_w4 <= ((uint64_t)(a_pix.len))) { + v_prev_row = a_pix; + a_pix = wuffs_base__slice_u8__subslice_i(a_pix, v_w4); + v_curr_row = a_pix; + } + if ((((uint64_t)(v_prev_row.len)) >= 4u) && (((uint64_t)(v_curr_row.len)) >= 4u)) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[0u] += v_prev_row.ptr[0u]; + v_curr_row.ptr[1u] += v_prev_row.ptr[1u]; + v_curr_row.ptr[2u] += v_prev_row.ptr[2u]; + v_curr_row.ptr[3u] += v_prev_row.ptr[3u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + v_x = 1u; + while (v_x < self->private_impl.f_width) { + if (((v_x & v_mask) == 0u) && (((uint64_t)(v_tile_data.len)) >= 4u)) { + v_mode = ((uint8_t)(v_tile_data.ptr[1u] & 15u)); + v_tile_data = wuffs_base__slice_u8__subslice_i(v_tile_data, 4u); + } + if ((((uint64_t)(v_prev_row.len)) < 12u) || (((uint64_t)(v_curr_row.len)) < 8u)) { + break; + } + if (v_mode == 0u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[7u] += 255u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 1u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += v_curr_row.ptr[0u]; + v_curr_row.ptr[5u] += v_curr_row.ptr[1u]; + v_curr_row.ptr[6u] += v_curr_row.ptr[2u]; + v_curr_row.ptr[7u] += v_curr_row.ptr[3u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 2u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += v_prev_row.ptr[4u]; + v_curr_row.ptr[5u] += v_prev_row.ptr[5u]; + v_curr_row.ptr[6u] += v_prev_row.ptr[6u]; + v_curr_row.ptr[7u] += v_prev_row.ptr[7u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 3u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += v_prev_row.ptr[8u]; + v_curr_row.ptr[5u] += v_prev_row.ptr[9u]; + v_curr_row.ptr[6u] += v_prev_row.ptr[10u]; + v_curr_row.ptr[7u] += v_prev_row.ptr[11u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 4u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += v_prev_row.ptr[0u]; + v_curr_row.ptr[5u] += v_prev_row.ptr[1u]; + v_curr_row.ptr[6u] += v_prev_row.ptr[2u]; + v_curr_row.ptr[7u] += v_prev_row.ptr[3u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 5u) { + v_l0 = ((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u); + v_l1 = ((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u); + v_l2 = ((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u); + v_l3 = ((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + ((uint32_t)(v_prev_row.ptr[4u]))) / 2u))); + v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); + v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + ((uint32_t)(v_prev_row.ptr[7u]))) / 2u))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 6u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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))); + v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[1u]))) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[2u]))) / 2u))); + 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 +#endif + } else if (v_mode == 7u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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))); + v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); + 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 +#endif + } else if (v_mode == 8u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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))); + v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[5u]))) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[6u]))) / 2u))); + 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 +#endif + } else if (v_mode == 9u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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))); + v_curr_row.ptr[5u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[5u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((((uint32_t)(v_prev_row.ptr[6u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u))); + 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 +#endif + } else if (v_mode == 10u) { + v_l0 = ((((uint32_t)(v_curr_row.ptr[0u])) + ((uint32_t)(v_prev_row.ptr[0u]))) / 2u); + v_l1 = ((((uint32_t)(v_curr_row.ptr[1u])) + ((uint32_t)(v_prev_row.ptr[1u]))) / 2u); + v_l2 = ((((uint32_t)(v_curr_row.ptr[2u])) + ((uint32_t)(v_prev_row.ptr[2u]))) / 2u); + v_l3 = ((((uint32_t)(v_curr_row.ptr[3u])) + ((uint32_t)(v_prev_row.ptr[3u]))) / 2u); + v_t0 = ((((uint32_t)(v_prev_row.ptr[4u])) + ((uint32_t)(v_prev_row.ptr[8u]))) / 2u); + v_t1 = ((((uint32_t)(v_prev_row.ptr[5u])) + ((uint32_t)(v_prev_row.ptr[9u]))) / 2u); + v_t2 = ((((uint32_t)(v_prev_row.ptr[6u])) + ((uint32_t)(v_prev_row.ptr[10u]))) / 2u); + v_t3 = ((((uint32_t)(v_prev_row.ptr[7u])) + ((uint32_t)(v_prev_row.ptr[11u]))) / 2u); +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += ((uint8_t)(((v_l0 + v_t0) / 2u))); + v_curr_row.ptr[5u] += ((uint8_t)(((v_l1 + v_t1) / 2u))); + v_curr_row.ptr[6u] += ((uint8_t)(((v_l2 + v_t2) / 2u))); + v_curr_row.ptr[7u] += ((uint8_t)(((v_l3 + v_t3) / 2u))); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else if (v_mode == 11u) { + v_l0 = ((uint32_t)(v_curr_row.ptr[0u])); + v_l1 = ((uint32_t)(v_curr_row.ptr[1u])); + v_l2 = ((uint32_t)(v_curr_row.ptr[2u])); + v_l3 = ((uint32_t)(v_curr_row.ptr[3u])); + v_c0 = ((uint32_t)(v_prev_row.ptr[0u])); + v_c1 = ((uint32_t)(v_prev_row.ptr[1u])); + v_c2 = ((uint32_t)(v_prev_row.ptr[2u])); + v_c3 = ((uint32_t)(v_prev_row.ptr[3u])); + v_t0 = ((uint32_t)(v_prev_row.ptr[4u])); + v_t1 = ((uint32_t)(v_prev_row.ptr[5u])); + v_t2 = ((uint32_t)(v_prev_row.ptr[6u])); + v_t3 = ((uint32_t)(v_prev_row.ptr[7u])); + v_sum_l = (wuffs_webp__decoder__absolute_difference(self, v_c0, v_t0) + + wuffs_webp__decoder__absolute_difference(self, v_c1, v_t1) + + wuffs_webp__decoder__absolute_difference(self, v_c2, v_t2) + + wuffs_webp__decoder__absolute_difference(self, v_c3, v_t3)); + v_sum_t = (wuffs_webp__decoder__absolute_difference(self, v_c0, v_l0) + + wuffs_webp__decoder__absolute_difference(self, v_c1, v_l1) + + wuffs_webp__decoder__absolute_difference(self, v_c2, v_l2) + + wuffs_webp__decoder__absolute_difference(self, v_c3, v_l3)); + if (v_sum_l < v_sum_t) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += ((uint8_t)(v_l0)); + v_curr_row.ptr[5u] += ((uint8_t)(v_l1)); + v_curr_row.ptr[6u] += ((uint8_t)(v_l2)); + v_curr_row.ptr[7u] += ((uint8_t)(v_l3)); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_curr_row.ptr[4u] += ((uint8_t)(v_t0)); + v_curr_row.ptr[5u] += ((uint8_t)(v_t1)); + v_curr_row.ptr[6u] += ((uint8_t)(v_t2)); + v_curr_row.ptr[7u] += ((uint8_t)(v_t3)); +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } + } else if (v_mode == 12u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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]); + 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]); + 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]); + 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 +#endif + } else if (v_mode == 13u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#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]); + 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]); + 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]); + 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 +#endif + } + v_curr_row = wuffs_base__slice_u8__subslice_i(v_curr_row, 4u); + v_prev_row = wuffs_base__slice_u8__subslice_i(v_prev_row, 4u); + v_x += 1u; + } + v_y += 1u; + } + return wuffs_base__make_empty_struct(); +} -// ---------------- Private Function Prototypes +// -------- func webp.decoder.absolute_difference WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_tga__decoder__do_decode_image_config( - wuffs_tga__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); +static uint32_t +wuffs_webp__decoder__absolute_difference( + const wuffs_webp__decoder* self, + uint32_t a_a, + uint32_t a_b) { + if (a_a < a_b) { + return (a_b - a_a); + } + return (a_a - a_b); +} -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_tga__decoder__do_decode_frame_config( - wuffs_tga__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); +// -------- func webp.decoder.mode12 WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_tga__decoder__do_decode_frame( - wuffs_tga__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); +static uint8_t +wuffs_webp__decoder__mode12( + const wuffs_webp__decoder* self, + uint8_t a_l, + uint8_t a_t, + uint8_t a_tl) { + uint32_t v_v = 0; -// ---------------- VTables + v_v = ((uint32_t)((((uint32_t)(a_l)) + ((uint32_t)(a_t))) - ((uint32_t)(a_tl)))); + if (v_v < 256u) { + return ((uint8_t)(v_v)); + } else if (v_v < 512u) { + return 255u; + } + return 0u; +} -const wuffs_base__image_decoder__func_ptrs -wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_tga__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_tga__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_tga__decoder__restart_frame), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_tga__decoder__set_quirk), - (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_tga__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len), -}; +// -------- func webp.decoder.mode13 -// ---------------- Initializer Implementations +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_webp__decoder__mode13( + const wuffs_webp__decoder* self, + uint8_t a_l, + uint8_t a_t, + uint8_t a_tl) { + uint32_t v_x = 0; + uint32_t v_y = 0; + uint32_t v_z = 0; + uint32_t v_v = 0; -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_tga__decoder__initialize( - wuffs_tga__decoder* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + v_x = ((((uint32_t)(a_l)) + ((uint32_t)(a_t))) / 2u); + v_y = ((uint32_t)(a_tl)); + v_z = ((uint32_t)(v_x - v_y)); + v_v = ((uint32_t)(v_x + wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(v_z + (v_z >> 31u))), 1u))); + if (v_v < 256u) { + return ((uint8_t)(v_v)); + } else if (v_v < 512u) { + return 255u; } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + return 0u; +} + +// -------- func webp.decoder.apply_transform_cross_color + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_cross_color( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix, + wuffs_base__slice_u8 a_tile_data) { + uint32_t v_tile_size_log2 = 0; + uint32_t v_tiles_per_row = 0; + uint32_t v_mask = 0; + uint32_t v_y = 0; + uint32_t v_x = 0; + uint64_t v_t = 0; + wuffs_base__slice_u8 v_tile_data = {0}; + uint32_t v_g2r = 0; + uint32_t v_g2b = 0; + uint32_t v_r2b = 0; + uint8_t v_b = 0; + uint8_t v_g = 0; + uint8_t v_r = 0; + + v_tile_size_log2 = ((uint32_t)(self->private_impl.f_transform_tile_size_log2[1u])); + v_tiles_per_row = ((self->private_impl.f_width + ((((uint32_t)(1u)) << v_tile_size_log2) - 1u)) >> v_tile_size_log2); + v_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u); + v_y = 0u; + while (v_y < self->private_impl.f_height) { + v_t = ((uint64_t)((4u * (v_y >> v_tile_size_log2) * v_tiles_per_row))); + v_tile_data = wuffs_base__utility__empty_slice_u8(); + if (v_t <= ((uint64_t)(a_tile_data.len))) { + v_tile_data = wuffs_base__slice_u8__subslice_i(a_tile_data, v_t); + } + 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_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) { + v_b = a_pix.ptr[0u]; + v_g = a_pix.ptr[1u]; + v_r = a_pix.ptr[2u]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + 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 + a_pix.ptr[0u] = v_b; + a_pix.ptr[2u] = v_r; + a_pix = wuffs_base__slice_u8__subslice_i(a_pix, 4u); + } + v_x += 1u; + } + v_y += 1u; } + return wuffs_base__make_empty_struct(); +} + +// -------- func webp.decoder.apply_transform_subtract_green + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_subtract_green( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix) { + wuffs_base__slice_u8 v_p = {0}; + uint8_t v_g = 0; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) + { + wuffs_base__slice_u8 i_slice_p = a_pix; + v_p.ptr = i_slice_p.ptr; + v_p.len = 4; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 4) * 4)); + while (v_p.ptr < i_end0_p) { + v_g = v_p.ptr[1u]; +#if defined(__GNUC__) #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wconversion" #endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); - } -#if !defined(__clang__) && defined(__GNUC__) + v_p.ptr[0u] += v_g; + v_p.ptr[2u] += v_g; +#if defined(__GNUC__) #pragma GCC diagnostic pop #endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; - } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + v_p.ptr += 4; } + v_p.len = 0; } - - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder); - return wuffs_base__make_status(NULL); + return wuffs_base__make_empty_struct(); } -wuffs_tga__decoder* -wuffs_tga__decoder__alloc(void) { - wuffs_tga__decoder* x = - (wuffs_tga__decoder*)(calloc(sizeof(wuffs_tga__decoder), 1)); - if (!x) { - return NULL; +// -------- func webp.decoder.apply_transform_color_indexing + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_webp__decoder__apply_transform_color_indexing( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_pix) { + uint32_t v_tile_size_log2 = 0; + uint32_t v_bits_per_pixel = 0; + uint32_t v_x_mask = 0; + uint32_t v_s_mask = 0; + uint64_t v_src_index = 0; + uint32_t v_y = 0; + uint64_t v_di = 0; + uint64_t v_dj = 0; + wuffs_base__slice_u8 v_dst = {0}; + uint32_t v_x = 0; + uint32_t v_s = 0; + uint32_t v_p = 0; + uint8_t v_p0 = 0; + uint8_t v_p1 = 0; + uint8_t v_p2 = 0; + uint8_t v_p3 = 0; + + 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(); } - if (wuffs_tga__decoder__initialize( - x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + v_bits_per_pixel = (((uint32_t)(8u)) >> v_tile_size_log2); + v_x_mask = ((((uint32_t)(1u)) << v_tile_size_log2) - 1u); + v_s_mask = ((((uint32_t)(1u)) << v_bits_per_pixel) - 1u); + v_src_index = ((uint64_t)((self->private_impl.f_workbuf_offset_for_color_indexing + 1u))); + v_y = 0u; + while (v_y < self->private_impl.f_height) { + v_di = ((uint64_t)((4u * (v_y + 0u) * self->private_impl.f_width))); + v_dj = ((uint64_t)((4u * (v_y + 1u) * self->private_impl.f_width))); + if ((v_di > v_dj) || (v_dj > ((uint64_t)(a_pix.len)))) { + break; + } + v_dst = wuffs_base__slice_u8__subslice_ij(a_pix, v_di, v_dj); + v_x = 0u; + while (((uint64_t)(v_dst.len)) >= 4u) { + if (((v_x & v_x_mask) == 0u) && (v_src_index < ((uint64_t)(a_pix.len)))) { + v_s = ((uint32_t)(a_pix.ptr[v_src_index])); + v_src_index += 4u; + } + v_p = ((v_s & v_s_mask) * 4u); + v_s >>= v_bits_per_pixel; + 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 = wuffs_base__slice_u8__subslice_i(v_dst, 4u); + v_x += 1u; + } + v_y += 1u; } - return x; -} - -size_t -sizeof__wuffs_tga__decoder(void) { - return sizeof(wuffs_tga__decoder); + return wuffs_base__make_empty_struct(); } -// ---------------- Function Implementations - -// -------- func tga.decoder.get_quirk +// -------- func webp.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__get_quirk( - const wuffs_tga__decoder* self, +wuffs_webp__decoder__get_quirk( + const wuffs_webp__decoder* self, uint32_t a_key) { if (!self) { return 0; @@ -59162,12 +73627,12 @@ wuffs_tga__decoder__get_quirk( return 0u; } -// -------- func tga.decoder.set_quirk +// -------- func webp.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__set_quirk( - wuffs_tga__decoder* self, +wuffs_webp__decoder__set_quirk( + wuffs_webp__decoder* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -59183,12 +73648,12 @@ wuffs_tga__decoder__set_quirk( return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func tga.decoder.decode_image_config +// -------- func webp.decoder.decode_image_config WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_image_config( - wuffs_tga__decoder* self, +wuffs_webp__decoder__decode_image_config( + wuffs_webp__decoder* self, wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { if (!self) { @@ -59214,17 +73679,17 @@ wuffs_tga__decoder__decode_image_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_image_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_image_config(self, a_dst, a_src); + wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_image_config(self, a_dst, a_src); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + status = wuffs_base__make_status(wuffs_webp__error__truncated_input); goto exit; } status = v_status; @@ -59232,13 +73697,13 @@ wuffs_tga__decoder__decode_image_config( } ok: - self->private_impl.p_decode_image_config[0] = 0; + self->private_impl.p_decode_image_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; goto exit; @@ -59249,19 +73714,19 @@ wuffs_tga__decoder__decode_image_config( return status; } -// -------- func tga.decoder.do_decode_image_config +// -------- func webp.decoder.do_decode_image_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_tga__decoder__do_decode_image_config( - wuffs_tga__decoder* self, +wuffs_webp__decoder__do_decode_image_config( + wuffs_webp__decoder* self, wuffs_base__image_config* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); - uint32_t v_c = 0; - uint32_t v_c5 = 0; - uint32_t v_i = 0; + uint32_t v_c32 = 0; + uint64_t v_r_mark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -59274,10 +73739,7 @@ wuffs_tga__decoder__do_decode_image_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; - if (coro_susp_point) { - v_i = self->private_data.s_do_decode_image_config[0].v_i; - } + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; @@ -59287,411 +73749,446 @@ wuffs_tga__decoder__do_decode_image_config( } { WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - self->private_impl.f_header_id_length = t_0; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - self->private_impl.f_header_color_map_type = t_1; - } - if (self->private_impl.f_header_color_map_type > 1u) { - status = wuffs_base__make_status(wuffs_tga__error__bad_header); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_2 = *iop_a_src++; - self->private_impl.f_header_image_type = t_2; - } - if ((self->private_impl.f_header_image_type == 1u) || - (self->private_impl.f_header_image_type == 2u) || - (self->private_impl.f_header_image_type == 3u) || - (self->private_impl.f_header_image_type == 9u) || - (self->private_impl.f_header_image_type == 10u) || - (self->private_impl.f_header_image_type == 11u)) { - } else { - status = wuffs_base__make_status(wuffs_tga__error__bad_header); - goto exit; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); - uint16_t t_3; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - iop_a_src += 2; + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; - if (num_bits_3 == 8) { - t_3 = ((uint16_t)(*scratch)); + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); break; } - num_bits_3 += 8u; - *scratch |= ((uint64_t)(num_bits_3)) << 56; + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; } } - self->private_impl.f_header_color_map_first_entry_index = t_3; + v_c32 = t_0; + } + if (v_c32 != 1179011410u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); - uint16_t t_4; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); - iop_a_src += 2; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + self->private_data.s_do_decode_image_config.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56)); + uint64_t* scratch = &self->private_data.s_do_decode_image_config.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4; - if (num_bits_4 == 8) { - t_4 = ((uint16_t)(*scratch)); + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); break; } - num_bits_4 += 8u; - *scratch |= ((uint64_t)(num_bits_4)) << 56; + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; } } - self->private_impl.f_header_color_map_length = t_4; + self->private_impl.f_riff_chunk_length = t_1; } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_5 = *iop_a_src++; - self->private_impl.f_header_color_map_entry_size = t_5; + if ((self->private_impl.f_riff_chunk_length & 1u) != 0u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; } - if (self->private_impl.f_header_color_map_type != 0u) { - if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length > 256u)) { - status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); - goto exit; - } else if ((self->private_impl.f_header_color_map_entry_size != 15u) && - (self->private_impl.f_header_color_map_entry_size != 16u) && - (self->private_impl.f_header_color_map_entry_size != 24u) && - (self->private_impl.f_header_color_map_entry_size != 32u)) { - status = wuffs_base__make_status(wuffs_tga__error__bad_header); - goto exit; + while (true) { + { + const bool o_0_closed_a_src = a_src->meta.closed; + const uint8_t* o_0_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_riff_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; + } + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_webp__decoder__do_decode_image_config_limited(self, a_src); + v_status = t_2; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_riff_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + io2_a_src = o_0_io2_a_src; + if (a_src) { + a_src->meta.closed = o_0_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); + } } - } else { - if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length != 0u) || (self->private_impl.f_header_color_map_entry_size != 0u)) { - status = wuffs_base__make_status(wuffs_tga__error__bad_header); + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if ( ! wuffs_base__status__is_suspension(&v_status)) { + status = v_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; + } else if ((v_status.repr == wuffs_base__suspension__short_read) && (self->private_impl.f_riff_chunk_length == 0u)) { + status = wuffs_base__make_status(wuffs_webp__error__short_chunk); goto exit; } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); } - self->private_data.s_do_decode_image_config[0].scratch = 4u; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; + self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); + if (a_dst != NULL) { + wuffs_base__image_config__set( + a_dst, + self->private_impl.f_pixfmt, + 0u, + self->private_impl.f_width, + self->private_impl.f_height, + self->private_impl.f_frame_config_io_position, + false); } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; + self->private_impl.f_call_sequence = 32u; + + ok: + self->private_impl.p_do_decode_image_config = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func webp.decoder.do_decode_image_config_limited + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_image_config_limited( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_c32 = 0; + uint64_t v_r_mark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config_limited; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); - uint32_t t_6; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + self->private_data.s_do_decode_image_config_limited.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56)); + uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6; - if (num_bits_6 == 8) { - t_6 = ((uint32_t)(*scratch)); + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); break; } - num_bits_6 += 8u; - *scratch |= ((uint64_t)(num_bits_6)) << 56; + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; } } - self->private_impl.f_width = t_6; + v_c32 = t_0; + } + if (v_c32 != 1346520407u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; } { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); - uint32_t t_7; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + self->private_data.s_do_decode_image_config_limited.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); while (true) { if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { status = wuffs_base__make_status(wuffs_base__suspension__short_read); goto suspend; } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); + uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); *scratch <<= 8; *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; - if (num_bits_7 == 8) { - t_7 = ((uint32_t)(*scratch)); + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); break; } - num_bits_7 += 8u; - *scratch |= ((uint64_t)(num_bits_7)) << 56; + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; } } - self->private_impl.f_height = t_7; - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_8 = *iop_a_src++; - self->private_impl.f_header_pixel_depth = t_8; + v_c32 = t_1; } - if ((self->private_impl.f_header_pixel_depth != 1u) && - (self->private_impl.f_header_pixel_depth != 8u) && - (self->private_impl.f_header_pixel_depth != 15u) && - (self->private_impl.f_header_pixel_depth != 16u) && - (self->private_impl.f_header_pixel_depth != 24u) && - (self->private_impl.f_header_pixel_depth != 32u)) { - status = wuffs_base__make_status(wuffs_tga__error__bad_header); + if (v_c32 == 540561494u) { + status = wuffs_base__make_status(wuffs_webp__error__unsupported_webp_file); goto exit; - } - if ((self->private_impl.f_header_image_type | 8u) == 9u) { - self->private_impl.f_scratch_bytes_per_pixel = 1u; - self->private_impl.f_src_bytes_per_pixel = 1u; - self->private_impl.f_src_pixfmt = 2164523016u; - self->private_impl.f_opaque = ((self->private_impl.f_header_color_map_entry_size == 15u) || (self->private_impl.f_header_color_map_entry_size == 24u)); - } else if ((self->private_impl.f_header_image_type | 8u) == 10u) { - if ((self->private_impl.f_header_pixel_depth == 15u) || (self->private_impl.f_header_pixel_depth == 16u)) { - self->private_impl.f_scratch_bytes_per_pixel = 4u; - self->private_impl.f_src_bytes_per_pixel = 0u; - self->private_impl.f_src_pixfmt = 2164295816u; - } else if (self->private_impl.f_header_pixel_depth == 24u) { - self->private_impl.f_scratch_bytes_per_pixel = 3u; - self->private_impl.f_src_bytes_per_pixel = 3u; - self->private_impl.f_src_pixfmt = 2147485832u; - self->private_impl.f_opaque = true; - } else if (self->private_impl.f_header_pixel_depth == 32u) { - self->private_impl.f_scratch_bytes_per_pixel = 4u; - self->private_impl.f_src_bytes_per_pixel = 4u; - self->private_impl.f_src_pixfmt = 2164295816u; - } else { - status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); - goto exit; + } else if (v_c32 == 1278758998u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + uint32_t t_2; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config_limited.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited.scratch; + uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2; + if (num_bits_2 == 24) { + t_2 = ((uint32_t)(*scratch)); + break; + } + num_bits_2 += 8u; + *scratch |= ((uint64_t)(num_bits_2)) << 56; + } + } + self->private_impl.f_sub_chunk_length = t_2; } - } else { - if (self->private_impl.f_header_pixel_depth == 8u) { - self->private_impl.f_scratch_bytes_per_pixel = 1u; - self->private_impl.f_src_bytes_per_pixel = 1u; - self->private_impl.f_src_pixfmt = 536870920u; - self->private_impl.f_opaque = true; - } else { - status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); + if (self->private_impl.f_sub_chunk_length < 4u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); goto exit; } - } - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_9 = *iop_a_src++; - self->private_impl.f_header_image_descriptor = t_9; - } - if ((self->private_impl.f_header_image_descriptor & 16u) != 0u) { - status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file); - goto exit; - } - self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_header_id_length)); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); - if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_image_config[0].scratch; - if (self->private_impl.f_header_color_map_type != 0u) { - while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) { - if (self->private_impl.f_header_color_map_entry_size == 24u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); - uint32_t t_10; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) { - t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src))); - iop_a_src += 3; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10; - if (num_bits_10 == 16) { - t_10 = ((uint32_t)(*scratch)); - break; - } - num_bits_10 += 8u; - *scratch |= ((uint64_t)(num_bits_10)) << 56; - } - } - v_c = t_10; + self->private_impl.f_sub_chunk_has_padding = ((self->private_impl.f_sub_chunk_length & 1u) != 0u); + while (true) { + { + const bool o_0_closed_a_src = a_src->meta.closed; + const uint8_t* o_0_io2_a_src = io2_a_src; + wuffs_private_impl__io_reader__limit(&io2_a_src, iop_a_src, + ((uint64_t)(self->private_impl.f_sub_chunk_length))); + if (a_src) { + size_t n = ((size_t)(io2_a_src - a_src->data.ptr)); + a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n); + a_src->meta.wi = n; } - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u; - } else if (self->private_impl.f_header_color_map_entry_size == 32u) { + v_r_mark = ((uint64_t)(iop_a_src - io0_a_src)); { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); - uint32_t t_11; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { - t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); - iop_a_src += 4; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11; - if (num_bits_11 == 24) { - t_11 = ((uint32_t)(*scratch)); - break; - } - num_bits_11 += 8u; - *scratch |= ((uint64_t)(num_bits_11)) << 56; - } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_c = t_11; - } - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = ((uint8_t)((v_c >> 24u))); - } else { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); - uint32_t t_12; - if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { - t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2; - } else { - self->private_data.s_do_decode_image_config[0].scratch = 0; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); - while (true) { - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch; - uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56)); - *scratch <<= 8; - *scratch >>= 8; - *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12; - if (num_bits_12 == 8) { - t_12 = ((uint32_t)(*scratch)); - break; - } - num_bits_12 += 8u; - *scratch |= ((uint64_t)(num_bits_12)) << 56; - } + wuffs_base__status t_3 = wuffs_webp__decoder__do_decode_image_config_limited_vp8l(self, a_src); + v_status = t_3; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - v_c = t_12; } - v_c5 = (31u & (v_c >> 0u)); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 5u)); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 10u)); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u; + wuffs_private_impl__u32__sat_sub_indirect(&self->private_impl.f_sub_chunk_length, ((uint32_t)(wuffs_private_impl__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)))))); + io2_a_src = o_0_io2_a_src; + if (a_src) { + a_src->meta.closed = o_0_closed_a_src; + a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr)); + } + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } else if ( ! wuffs_base__status__is_suspension(&v_status)) { + status = v_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; + } else if ((v_status.repr == wuffs_base__suspension__short_read) && (self->private_impl.f_sub_chunk_length == 0u)) { + status = wuffs_base__make_status(wuffs_webp__error__short_chunk); + goto exit; } - v_i += 1u; + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); } - while (v_i < 256u) { - self->private_data.f_src_palette[((v_i * 4u) + 0u)] = 0u; - self->private_data.f_src_palette[((v_i * 4u) + 1u)] = 0u; - self->private_data.f_src_palette[((v_i * 4u) + 2u)] = 0u; - self->private_data.f_src_palette[((v_i * 4u) + 3u)] = 255u; - v_i += 1u; + } else if (v_c32 == 1480085590u) { + status = wuffs_base__make_status(wuffs_webp__error__unsupported_webp_file); + goto exit; + } else { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; + } + + ok: + self->private_impl.p_do_decode_image_config_limited = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_image_config_limited = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func webp.decoder.do_decode_image_config_limited_vp8l + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_image_config_limited_vp8l( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_c32 = 0; + uint32_t v_transform_size = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config_limited_vp8l; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; } + uint32_t t_0 = *iop_a_src++; + v_c32 = t_0; } - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - self->private_impl.f_src_pixfmt, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - self->private_impl.f_opaque); + if (v_c32 != 47u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; } - self->private_impl.f_call_sequence = 32u; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_decode_image_config_limited_vp8l.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_decode_image_config_limited_vp8l.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 24) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_c32 = t_1; + } + self->private_impl.f_width = ((v_c32 & 16383u) + 1u); + v_c32 >>= 14u; + self->private_impl.f_height = ((v_c32 & 16383u) + 1u); + v_c32 >>= 14u; + self->private_impl.f_pixfmt = 2415954056u; + if ((v_c32 & 1u) != 0u) { + self->private_impl.f_pixfmt = 2164295816u; + } + v_c32 >>= 1u; + if (v_c32 != 0u) { + status = wuffs_base__make_status(wuffs_webp__error__bad_header); + goto exit; + } + v_transform_size = (4u * ((self->private_impl.f_width + 3u) >> 2u) * ((self->private_impl.f_height + 3u) >> 2u)); + self->private_impl.f_workbuf_offset_for_transform[0u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (0u * v_transform_size)); + self->private_impl.f_workbuf_offset_for_transform[1u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (1u * v_transform_size)); + self->private_impl.f_workbuf_offset_for_transform[2u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (2u * v_transform_size)); + self->private_impl.f_workbuf_offset_for_transform[3u] = ((4u * self->private_impl.f_width * self->private_impl.f_height) + (3u * v_transform_size)); goto ok; ok: - self->private_impl.p_do_decode_image_config[0] = 0; + self->private_impl.p_do_decode_image_config_limited_vp8l = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_image_config[0].v_i = v_i; + self->private_impl.p_do_decode_image_config_limited_vp8l = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -59702,12 +74199,12 @@ wuffs_tga__decoder__do_decode_image_config( return status; } -// -------- func tga.decoder.decode_frame_config +// -------- func webp.decoder.decode_frame_config WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_frame_config( - wuffs_tga__decoder* self, +wuffs_webp__decoder__decode_frame_config( + wuffs_webp__decoder* self, wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src) { if (!self) { @@ -59733,17 +74230,17 @@ wuffs_tga__decoder__decode_frame_config( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame_config(self, a_dst, a_src); + wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_frame_config(self, a_dst, a_src); v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + status = wuffs_base__make_status(wuffs_webp__error__truncated_input); goto exit; } status = v_status; @@ -59751,13 +74248,13 @@ wuffs_tga__decoder__decode_frame_config( } ok: - self->private_impl.p_decode_frame_config[0] = 0; + self->private_impl.p_decode_frame_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; goto exit; @@ -59768,12 +74265,12 @@ wuffs_tga__decoder__decode_frame_config( return status; } -// -------- func tga.decoder.do_decode_frame_config +// -------- func webp.decoder.do_decode_frame_config WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_tga__decoder__do_decode_frame_config( - wuffs_tga__decoder* self, +wuffs_webp__decoder__do_decode_frame_config( + wuffs_webp__decoder* self, wuffs_base__frame_config* a_dst, wuffs_base__io_buffer* a_src) { wuffs_base__status status = wuffs_base__make_status(NULL); @@ -59789,7 +74286,7 @@ wuffs_tga__decoder__do_decode_frame_config( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; @@ -59799,7 +74296,7 @@ wuffs_tga__decoder__do_decode_frame_config( a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_tga__decoder__do_decode_image_config(self, NULL, a_src); + status = wuffs_webp__decoder__do_decode_image_config(self, NULL, a_src); if (a_src) { iop_a_src = a_src->data.ptr + a_src->meta.ri; } @@ -59831,20 +74328,20 @@ wuffs_tga__decoder__do_decode_frame_config( 0u, self->private_impl.f_frame_config_io_position, 0u, - self->private_impl.f_opaque, false, - 4278190080u); + false, + 0u); } self->private_impl.f_call_sequence = 64u; ok: - self->private_impl.p_do_decode_frame_config[0] = 0; + self->private_impl.p_do_decode_frame_config = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.p_do_decode_frame_config = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: @@ -59855,12 +74352,12 @@ wuffs_tga__decoder__do_decode_frame_config( return status; } -// -------- func tga.decoder.decode_frame +// -------- func webp.decoder.decode_frame WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__decode_frame( - wuffs_tga__decoder* self, +wuffs_webp__decoder__decode_frame( + wuffs_webp__decoder* self, wuffs_base__pixel_buffer* a_dst, wuffs_base__io_buffer* a_src, wuffs_base__pixel_blend a_blend, @@ -59889,13 +74386,13 @@ wuffs_tga__decoder__decode_frame( wuffs_base__status v_status = wuffs_base__make_status(NULL); - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_frame; switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; while (true) { { - wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame(self, + wuffs_base__status t_0 = wuffs_webp__decoder__do_decode_frame(self, a_dst, a_src, a_blend, @@ -59904,64 +74401,627 @@ wuffs_tga__decoder__decode_frame( v_status = t_0; } if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_tga__error__truncated_input); + status = wuffs_base__make_status(wuffs_webp__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + } + return status; +} + +// -------- func webp.decoder.do_decode_frame + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__do_decode_frame( + wuffs_webp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__pixel_blend a_blend, + wuffs_base__slice_u8 a_workbuf, + wuffs_base__decode_frame_options* a_opts) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_has_more = 0; + uint32_t v_width = 0; + wuffs_base__slice_u8 v_dst = {0}; + wuffs_base__slice_u8 v_tile_data = {0}; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + wuffs_base__slice_u8 v_pix = {0}; + uint32_t v_which = 0; + uint32_t v_transform_type = 0; + uint64_t v_ti = 0; + uint64_t v_tj = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_do_decode_frame; + if (coro_susp_point) { + v_width = self->private_data.s_do_decode_frame.v_width; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_call_sequence == 64u) { + } else if (self->private_impl.f_call_sequence < 64u) { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_webp__decoder__do_decode_frame_config(self, NULL, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } else { + status = wuffs_base__make_status(wuffs_base__note__end_of_data); + goto ok; + } + self->private_impl.f_seen_transform[0u] = false; + self->private_impl.f_seen_transform[1u] = false; + self->private_impl.f_seen_transform[2u] = false; + self->private_impl.f_seen_transform[3u] = false; + self->private_impl.f_n_transforms = 0u; + while (true) { + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_has_more = (self->private_impl.f_bits & 1u); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + if (v_has_more == 0u) { + break; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_webp__decoder__decode_transform(self, a_src, a_workbuf); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + } + v_width = self->private_impl.f_width; + if (self->private_impl.f_seen_transform[3u]) { + v_width = self->private_impl.f_color_indexing_width; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_overall_color_cache_bits = self->private_impl.f_color_cache_bits; + 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_hg_table(self, a_src, v_width, a_workbuf); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + self->private_impl.f_color_cache_bits = self->private_impl.f_overall_color_cache_bits; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, self->private_impl.f_overall_n_huffman_groups); + 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_color_indexing)) > ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u]))) || + (((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))) || + (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(a_workbuf.len)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + v_dst = wuffs_base__slice_u8__subslice_ij(a_workbuf, + ((uint64_t)(self->private_impl.f_workbuf_offset_for_color_indexing)), + ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u]))); + v_tile_data = 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]))); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_1 = wuffs_webp__decoder__decode_pixels(self, + v_dst, + a_src, + v_width, + self->private_impl.f_height, + v_tile_data, + self->private_impl.f_overall_tile_size_log2); + v_status = t_1; + 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(7); + } + if (((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u])) > ((uint64_t)(a_workbuf.len))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + v_pix = wuffs_base__slice_u8__subslice_j(a_workbuf, ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[0u]))); + v_which = self->private_impl.f_n_transforms; + while (v_which > 0u) { + v_which -= 1u; + v_transform_type = ((uint32_t)(self->private_impl.f_transform_type[v_which])); + v_tile_data = wuffs_base__utility__empty_slice_u8(); + if (v_transform_type < 2u) { + v_ti = ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 1u)])); + v_tj = ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[(v_transform_type + 2u)])); + if ((v_ti <= v_tj) && (v_tj <= ((uint64_t)(a_workbuf.len)))) { + v_tile_data = wuffs_base__slice_u8__subslice_ij(a_workbuf, v_ti, v_tj); + } + } + if (v_transform_type == 0u) { + wuffs_webp__decoder__apply_transform_predictor(self, v_pix, v_tile_data); + } else if (v_transform_type == 1u) { + wuffs_webp__decoder__apply_transform_cross_color(self, v_pix, v_tile_data); + } else if (v_transform_type == 2u) { + wuffs_webp__decoder__apply_transform_subtract_green(self, v_pix); + } else { + wuffs_webp__decoder__apply_transform_color_indexing(self, v_pix); + v_width = self->private_impl.f_width; + } + } + v_status = wuffs_webp__decoder__swizzle(self, a_dst, v_pix, a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = v_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; + } + self->private_impl.f_call_sequence = 96u; + + ok: + self->private_impl.p_do_decode_frame = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_do_decode_frame = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_decode_frame.v_width = v_width; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func webp.decoder.decode_transform + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_transform( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src, + 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; + wuffs_base__slice_u8 v_p = {0}; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_transform; + if (coro_susp_point) { + v_transform_type = self->private_data.s_decode_transform.v_transform_type; + v_tile_size_log2 = self->private_data.s_decode_transform.v_tile_size_log2; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_n_bits < 2u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (self->private_impl.f_n_bits >= 2u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_transform_type = (self->private_impl.f_bits & 3u); + self->private_impl.f_bits >>= 2u; + self->private_impl.f_n_bits -= 2u; + if (self->private_impl.f_seen_transform[v_transform_type] || (self->private_impl.f_n_transforms >= 4u)) { + status = wuffs_base__make_status(wuffs_webp__error__bad_transform); + goto exit; + } else if (self->private_impl.f_seen_transform[3u]) { + status = wuffs_base__make_status(wuffs_webp__error__unsupported_transform_after_color_indexing_transform); + goto exit; + } + self->private_impl.f_seen_transform[v_transform_type] = true; + self->private_impl.f_transform_type[self->private_impl.f_n_transforms] = ((uint8_t)(v_transform_type)); + self->private_impl.f_n_transforms += 1u; + if (v_transform_type < 2u) { + if (self->private_impl.f_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= 3u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_tile_size_log2 = ((self->private_impl.f_bits & 7u) + 2u); + self->private_impl.f_transform_tile_size_log2[v_transform_type] = ((uint8_t)(v_tile_size_log2)); + self->private_impl.f_bits >>= 3u; + self->private_impl.f_n_bits -= 3u; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u); + 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 { + if (self->private_impl.f_n_bits < 8u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + 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); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + self->private_impl.f_color_indexing_palette_size = ((self->private_impl.f_bits & 255u) + 1u); + self->private_impl.f_bits >>= 8u; + self->private_impl.f_n_bits -= 8u; + if (self->private_impl.f_color_indexing_palette_size <= 2u) { + self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 7u) / 8u); + self->private_impl.f_transform_tile_size_log2[3u] = 3u; + } else if (self->private_impl.f_color_indexing_palette_size <= 4u) { + self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 3u) / 4u); + self->private_impl.f_transform_tile_size_log2[3u] = 2u; + } else if (self->private_impl.f_color_indexing_palette_size <= 16u) { + self->private_impl.f_color_indexing_width = ((self->private_impl.f_width + 1u) / 2u); + self->private_impl.f_transform_tile_size_log2[3u] = 1u; + } else { + self->private_impl.f_color_indexing_width = self->private_impl.f_width; + self->private_impl.f_transform_tile_size_log2[3u] = 0u; + } + if (self->private_impl.f_width >= self->private_impl.f_color_indexing_width) { + self->private_impl.f_workbuf_offset_for_color_indexing = (4u * (self->private_impl.f_width - self->private_impl.f_color_indexing_width) * self->private_impl.f_height); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + status = wuffs_webp__decoder__decode_pixels(self, + wuffs_base__make_slice_u8(self->private_data.f_palette, (4u * self->private_impl.f_color_indexing_palette_size)), + a_src, + self->private_impl.f_color_indexing_palette_size, + 1u, + 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; + } + wuffs_private_impl__bulk_memset(&self->private_data.f_palette[(4u * self->private_impl.f_color_indexing_palette_size)], (1024u - (4u * self->private_impl.f_color_indexing_palette_size)), 0u); + v_p = wuffs_base__make_slice_u8(self->private_data.f_palette, (4u * self->private_impl.f_color_indexing_palette_size)); + while (((uint64_t)(v_p.len)) >= 8u) { +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_p.ptr[4u] += v_p.ptr[0u]; + v_p.ptr[5u] += v_p.ptr[1u]; + v_p.ptr[6u] += v_p.ptr[2u]; + v_p.ptr[7u] += v_p.ptr[3u]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + v_p = wuffs_base__slice_u8__subslice_i(v_p, 4u); + } + } + + ok: + self->private_impl.p_decode_transform = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_transform = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_transform.v_transform_type = v_transform_type; + self->private_data.s_decode_transform.v_tile_size_log2 = v_tile_size_log2; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + + return status; +} + +// -------- func webp.decoder.decode_color_cache_parameters + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_color_cache_parameters( + wuffs_webp__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint8_t v_c8 = 0; + uint32_t v_use_color_cache = 0; + uint32_t v_color_cache_bits = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_decode_color_cache_parameters; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_use_color_cache = (self->private_impl.f_bits & 1u); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + self->private_impl.f_color_cache_bits = 0u; + if (v_use_color_cache != 0u) { + if (self->private_impl.f_n_bits < 4u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= 4u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); + goto exit; + } + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; + } + v_color_cache_bits = (self->private_impl.f_bits & 15u); + self->private_impl.f_bits >>= 4u; + self->private_impl.f_n_bits -= 4u; + if ((v_color_cache_bits < 1u) || (11u < v_color_cache_bits)) { + status = wuffs_base__make_status(wuffs_webp__error__bad_color_cache); goto exit; } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + self->private_impl.f_color_cache_bits = v_color_cache_bits; } + goto ok; ok: - self->private_impl.p_decode_frame[0] = 0; + self->private_impl.p_decode_color_cache_parameters = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; + self->private_impl.p_decode_color_cache_parameters = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; goto exit; exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } + return status; } -// -------- func tga.decoder.do_decode_frame +// -------- func webp.decoder.decode_hg_table WUFFS_BASE__GENERATED_C_CODE static wuffs_base__status -wuffs_tga__decoder__do_decode_frame( - wuffs_tga__decoder* self, - wuffs_base__pixel_buffer* a_dst, +wuffs_webp__decoder__decode_hg_table( + wuffs_webp__decoder* self, wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { + uint32_t a_width, + 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); - wuffs_base__pixel_format v_dst_pixfmt = {0}; - uint32_t v_dst_bits_per_pixel = 0; - uint64_t v_dst_bytes_per_pixel = 0; - uint32_t v_dst_x = 0; - uint32_t v_dst_y = 0; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst_palette = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint64_t v_dst_start = 0; - wuffs_base__slice_u8 v_src_palette = {0}; - uint64_t v_mark = 0; - uint64_t v_num_pixels64 = 0; - uint32_t v_num_pixels32 = 0; - uint32_t v_lit_length = 0; - uint32_t v_run_length = 0; - uint64_t v_num_dst_bytes = 0; - uint32_t v_num_src_bytes = 0; - uint32_t v_c = 0; - uint32_t v_c5 = 0; + uint8_t v_c8 = 0; + uint32_t v_use_hg_table = 0; + uint32_t v_tile_size_log2 = 0; + wuffs_base__slice_u8 v_hg_pixels = {0}; + uint64_t v_n = 0; + wuffs_base__slice_u8 v_p = {0}; + uint32_t v_hg_plus_1 = 0; const uint8_t* iop_a_src = NULL; const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; @@ -59974,276 +75034,155 @@ wuffs_tga__decoder__do_decode_frame( io2_a_src = io0_a_src + a_src->meta.wi; } - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; + uint32_t coro_susp_point = self->private_impl.p_decode_hg_table; if (coro_susp_point) { - v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel; - v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x; - v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y; - v_mark = self->private_data.s_do_decode_frame[0].v_mark; - v_num_pixels32 = self->private_data.s_do_decode_frame[0].v_num_pixels32; - v_lit_length = self->private_data.s_do_decode_frame[0].v_lit_length; - v_run_length = self->private_data.s_do_decode_frame[0].v_run_length; - v_num_dst_bytes = self->private_data.s_do_decode_frame[0].v_num_dst_bytes; + v_tile_size_log2 = self->private_data.s_decode_hg_table.v_tile_size_log2; } switch (coro_susp_point) { WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + if (self->private_impl.f_n_bits < 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_tga__decoder__do_decode_frame_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; + self->private_impl.f_bits = ((uint32_t)(v_c8)); + self->private_impl.f_n_bits = 8u; + } + v_use_hg_table = (self->private_impl.f_bits & 1u); + self->private_impl.f_bits >>= 1u; + self->private_impl.f_n_bits -= 1u; + if (v_use_hg_table == 0u) { + self->private_impl.f_overall_n_huffman_groups = 1u; + self->private_impl.f_overall_tile_size_log2 = 0u; + 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 (status.repr) { - goto suspend; + v_hg_pixels = 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]))); + if (((uint64_t)(v_hg_pixels.len)) >= 4u) { + v_hg_pixels.ptr[0u] = 0u; + v_hg_pixels.ptr[1u] = 0u; + v_hg_pixels.ptr[2u] = 0u; + v_hg_pixels.ptr[3u] = 0u; } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); + status = wuffs_base__make_status(NULL); goto ok; } - if (self->private_impl.f_header_color_map_type != 0u) { - v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024); - } - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), - wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt), - v_src_palette, - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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); + if (self->private_impl.f_n_bits < 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (self->private_impl.f_n_bits >= 3u) { + status = wuffs_base__make_status(wuffs_webp__error__internal_error_inconsistent_n_bits); goto exit; } - goto ok; + self->private_impl.f_bits |= (((uint32_t)(v_c8)) << self->private_impl.f_n_bits); + self->private_impl.f_n_bits += 8u; } - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; + v_tile_size_log2 = ((self->private_impl.f_bits & 7u) + 2u); + self->private_impl.f_bits >>= 3u; + self->private_impl.f_n_bits -= 3u; + self->private_impl.f_overall_tile_size_log2 = v_tile_size_log2; + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); - if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) { - v_dst_y = ((uint32_t)(self->private_impl.f_height - 1u)); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + status = wuffs_webp__decoder__decode_color_cache_parameters(self, a_src); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; } - if ((self->private_impl.f_header_image_type & 8u) == 0u) { - v_lit_length = self->private_impl.f_width; + if (status.repr) { + goto suspend; + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + status = wuffs_webp__decoder__decode_huffman_groups(self, a_src, 1u); + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + if (status.repr) { + goto suspend; } - label__resume__continue:; while (true) { - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)); - while (v_dst_y < self->private_impl.f_height) { - v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y); - v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel); - if (v_dst_start <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start); - } else { - v_dst = wuffs_base__utility__empty_slice_u8(); - } - while (v_dst_x < self->private_impl.f_width) { - if (self->private_impl.f_src_bytes_per_pixel > 0u) { - if (v_lit_length > 0u) { - v_mark = ((uint64_t)(iop_a_src - io0_a_src)); - v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel))); - v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length))))); - v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel); - v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel); - self->private_data.s_do_decode_frame[0].scratch = v_num_src_bytes; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) { - self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src)); - iop_a_src = io2_a_src; - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - iop_a_src += self->private_data.s_do_decode_frame[0].scratch; - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); - if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes); - } else { - v_dst = wuffs_base__utility__empty_slice_u8(); - } - v_dst_x += v_num_pixels32; - v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535u); - if (v_lit_length > 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3); - goto label__resume__continue; - } - } else if (v_run_length > 0u) { - v_run_length -= 1u; - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel)); - if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); - } - v_dst_x += 1u; - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4); - goto label__resume__continue; - } - if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) { - v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u); - iop_a_src += 1u; - if ((v_lit_length + v_dst_x) > self->private_impl.f_width) { - status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); - goto exit; - } - } else { - if (self->private_impl.f_src_bytes_per_pixel == 1u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); - goto label__resume__continue; - } - v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); - iop_a_src += 1u; - self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - } else if (self->private_impl.f_src_bytes_per_pixel == 3u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); - goto label__resume__continue; - } - v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); - iop_a_src += 1u; - self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7); - goto label__resume__continue; - } - v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); - iop_a_src += 1u; - self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - self->private_data.f_scratch[3u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - } - if ((v_run_length + v_dst_x) > self->private_impl.f_width) { - status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); - goto exit; - } - } - } - } else { - if (v_lit_length > 0u) { - if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8); - goto label__resume__continue; - } - v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2u; - v_c5 = (31u & (v_c >> 0u)); - self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 5u)); - self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 10u)); - self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - self->private_data.f_scratch[3u] = 255u; - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 4)); - if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); - } - v_dst_x += 1u; - v_lit_length -= 1u; - } else if (v_run_length > 0u) { - v_run_length -= 1u; - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel)); - if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); - } - v_dst_x += 1u; - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); - goto label__resume__continue; - } - if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) { - v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u); - iop_a_src += 1u; - if ((v_lit_length + v_dst_x) > self->private_impl.f_width) { - status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); - goto exit; - } - } else { - if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); - goto label__resume__continue; - } - v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u); - iop_a_src += 1u; - v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); - iop_a_src += 2u; - v_c5 = (31u & (v_c >> 0u)); - self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 5u)); - self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - v_c5 = (31u & (v_c >> 10u)); - self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u)))); - self->private_data.f_scratch[3u] = 255u; - if ((v_run_length + v_dst_x) > self->private_impl.f_width) { - status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding); - goto exit; - } - } - } - } - } - v_dst_x = 0u; - if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) { - v_dst_y -= 1u; - } else { - v_dst_y += 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)))) { + 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)); } - if ((self->private_impl.f_header_image_type & 8u) == 0u) { - v_lit_length = self->private_impl.f_width; + 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; } } - break; + 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)))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + v_hg_pixels = 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]))); + v_n = ((uint64_t)((((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) * 4u))); + if (v_n > ((uint64_t)(v_hg_pixels.len))) { + status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length); + goto exit; + } + v_p = wuffs_base__slice_u8__subslice_j(v_hg_pixels, v_n); + while (((uint64_t)(v_p.len)) >= 4u) { + if (v_p.ptr[2u] != 0u) { + status = wuffs_base__make_status(wuffs_webp__error__unsupported_number_of_huffman_groups); + goto exit; + } + v_hg_plus_1 = (((uint32_t)(v_p.ptr[1u])) + 1u); + if (self->private_impl.f_overall_n_huffman_groups < v_hg_plus_1) { + self->private_impl.f_overall_n_huffman_groups = v_hg_plus_1; + } + v_p = wuffs_base__slice_u8__subslice_i(v_p, 4u); } - self->private_impl.f_call_sequence = 96u; ok: - self->private_impl.p_do_decode_frame[0] = 0; + self->private_impl.p_decode_hg_table = 0; goto exit; } goto suspend; suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel; - self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x; - self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y; - self->private_data.s_do_decode_frame[0].v_mark = v_mark; - self->private_data.s_do_decode_frame[0].v_num_pixels32 = v_num_pixels32; - self->private_data.s_do_decode_frame[0].v_lit_length = v_lit_length; - self->private_data.s_do_decode_frame[0].v_run_length = v_run_length; - self->private_data.s_do_decode_frame[0].v_num_dst_bytes = v_num_dst_bytes; + self->private_impl.p_decode_hg_table = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_hg_table.v_tile_size_log2 = v_tile_size_log2; goto exit; exit: @@ -60254,12 +75193,117 @@ wuffs_tga__decoder__do_decode_frame( return status; } -// -------- func tga.decoder.frame_dirty_rect +// -------- func webp.decoder.decode_pixels + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__decode_pixels( + wuffs_webp__decoder* self, + wuffs_base__slice_u8 a_dst, + wuffs_base__io_buffer* a_src, + uint32_t a_width, + uint32_t a_height, + wuffs_base__slice_u8 a_tile_data, + uint32_t a_tile_size_log2) { + wuffs_base__status status = wuffs_base__make_status(NULL); + + uint32_t v_i = 0; + uint32_t v_n = 0; + + uint32_t coro_susp_point = self->private_impl.p_decode_pixels; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + v_i = 0u; + v_n = (((uint32_t)(1u)) << self->private_impl.f_color_cache_bits); + while (v_i < v_n) { + self->private_data.f_color_cache[v_i] = 0u; + v_i += 1u; + } + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + status = wuffs_webp__decoder__decode_pixels_slow(self, + a_dst, + a_src, + a_width, + a_height, + a_tile_data, + a_tile_size_log2); + if (status.repr) { + goto suspend; + } + + goto ok; + ok: + self->private_impl.p_decode_pixels = 0; + goto exit; + } + + goto suspend; + suspend: + self->private_impl.p_decode_pixels = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + + goto exit; + exit: + return status; +} + +// -------- func webp.decoder.swizzle + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_webp__decoder__swizzle( + wuffs_webp__decoder* self, + wuffs_base__pixel_buffer* a_dst, + wuffs_base__slice_u8 a_src, + wuffs_base__pixel_blend a_blend) { + wuffs_base__status v_status = wuffs_base__make_status(NULL); + 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_bytes_per_row = 0; + wuffs_base__slice_u8 v_dst_palette = {0}; + wuffs_base__table_u8 v_tab = {0}; + uint64_t v_src_bytes_per_row = 0; + wuffs_base__slice_u8 v_dst = {0}; + uint32_t v_y = 0; + + v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, + wuffs_base__pixel_buffer__pixel_format(a_dst), + wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_palette, 1024)), + wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt), + wuffs_base__utility__empty_slice_u8(), + a_blend); + if ( ! wuffs_base__status__is_ok(&v_status)) { + return wuffs_private_impl__status__ensure_not_a_suspension(v_status); + } + 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); + if ((v_dst_bits_per_pixel & 7u) != 0u) { + return wuffs_base__make_status(wuffs_base__error__unsupported_option); + } + v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u); + v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel))); + v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_palette, 1024)); + v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); + v_src_bytes_per_row = ((uint64_t)((self->private_impl.f_width * 4u))); + while (v_src_bytes_per_row <= ((uint64_t)(a_src.len))) { + v_dst = wuffs_private_impl__table_u8__row_u32(v_tab, v_y); + if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) { + v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row); + } + wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__slice_u8__subslice_j(a_src, v_src_bytes_per_row)); + a_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_bytes_per_row); + v_y += 1u; + } + return wuffs_base__make_status(NULL); +} + +// -------- func webp.decoder.frame_dirty_rect WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_tga__decoder__frame_dirty_rect( - const wuffs_tga__decoder* self) { +wuffs_webp__decoder__frame_dirty_rect( + const wuffs_webp__decoder* self) { if (!self) { return wuffs_base__utility__empty_rect_ie_u32(); } @@ -60275,12 +75319,12 @@ wuffs_tga__decoder__frame_dirty_rect( self->private_impl.f_height); } -// -------- func tga.decoder.num_animation_loops +// -------- func webp.decoder.num_animation_loops WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_tga__decoder__num_animation_loops( - const wuffs_tga__decoder* self) { +wuffs_webp__decoder__num_animation_loops( + const wuffs_webp__decoder* self) { if (!self) { return 0; } @@ -60292,12 +75336,12 @@ wuffs_tga__decoder__num_animation_loops( return 0u; } -// -------- func tga.decoder.num_decoded_frame_configs +// -------- func webp.decoder.num_decoded_frame_configs WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__num_decoded_frame_configs( - const wuffs_tga__decoder* self) { +wuffs_webp__decoder__num_decoded_frame_configs( + const wuffs_webp__decoder* self) { if (!self) { return 0; } @@ -60312,12 +75356,12 @@ wuffs_tga__decoder__num_decoded_frame_configs( return 0u; } -// -------- func tga.decoder.num_decoded_frames +// -------- func webp.decoder.num_decoded_frames WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__num_decoded_frames( - const wuffs_tga__decoder* self) { +wuffs_webp__decoder__num_decoded_frames( + const wuffs_webp__decoder* self) { if (!self) { return 0; } @@ -60332,12 +75376,12 @@ wuffs_tga__decoder__num_decoded_frames( return 0u; } -// -------- func tga.decoder.restart_frame +// -------- func webp.decoder.restart_frame WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__restart_frame( - wuffs_tga__decoder* self, +wuffs_webp__decoder__restart_frame( + wuffs_webp__decoder* self, uint64_t a_index, uint64_t a_io_position) { if (!self) { @@ -60353,31 +75397,30 @@ wuffs_tga__decoder__restart_frame( if (self->private_impl.f_call_sequence < 32u) { return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); } - if (a_index != 0u) { + if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) { return wuffs_base__make_status(wuffs_base__error__bad_argument); } self->private_impl.f_call_sequence = 40u; - self->private_impl.f_frame_config_io_position = a_io_position; return wuffs_base__make_status(NULL); } -// -------- func tga.decoder.set_report_metadata +// -------- func webp.decoder.set_report_metadata WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_tga__decoder__set_report_metadata( - wuffs_tga__decoder* self, +wuffs_webp__decoder__set_report_metadata( + wuffs_webp__decoder* self, uint32_t a_fourcc, bool a_report) { return wuffs_base__make_empty_struct(); } -// -------- func tga.decoder.tell_me_more +// -------- func webp.decoder.tell_me_more WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_tga__decoder__tell_me_more( - wuffs_tga__decoder* self, +wuffs_webp__decoder__tell_me_more( + wuffs_webp__decoder* self, wuffs_base__io_buffer* a_dst, wuffs_base__more_information* a_minfo, wuffs_base__io_buffer* a_src) { @@ -60415,29 +75458,12 @@ wuffs_tga__decoder__tell_me_more( return status; } -// -------- func tga.decoder.history_retain_length - -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_tga__decoder__history_retain_length( - const wuffs_tga__decoder* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; - } - - return 0u; -} - -// -------- func tga.decoder.workbuf_len +// -------- func webp.decoder.workbuf_len WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_tga__decoder__workbuf_len( - const wuffs_tga__decoder* self) { +wuffs_webp__decoder__workbuf_len( + const wuffs_webp__decoder* self) { if (!self) { return wuffs_base__utility__empty_range_ii_u64(); } @@ -60446,92 +75472,66 @@ wuffs_tga__decoder__workbuf_len( return wuffs_base__utility__empty_range_ii_u64(); } - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + return wuffs_base__utility__make_range_ii_u64(((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[3u])), ((uint64_t)(self->private_impl.f_workbuf_offset_for_transform[3u]))); } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) // ---------------- Status Codes Implementations -const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header"; -const char wuffs_wbmp__error__truncated_input[] = "#wbmp: truncated input"; - // ---------------- Private Consts -// ---------------- Private Initializer Prototypes +#define WUFFS_XXHASH32__XXH_PRIME32_1 2654435761u -// ---------------- Private Function Prototypes +#define WUFFS_XXHASH32__XXH_PRIME32_2 2246822519u -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_image_config( - wuffs_wbmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src); +#define WUFFS_XXHASH32__XXH_PRIME32_3 3266489917u -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_frame_config( - wuffs_wbmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src); +#define WUFFS_XXHASH32__XXH_PRIME32_4 668265263u + +#define WUFFS_XXHASH32__XXH_PRIME32_5 374761393u + +#define WUFFS_XXHASH32__INITIAL_V0 606290984u + +#define WUFFS_XXHASH32__INITIAL_V1 2246822519u + +#define WUFFS_XXHASH32__INITIAL_V2 0u + +#define WUFFS_XXHASH32__INITIAL_V3 1640531535u + +// ---------------- Private Initializer Prototypes + +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_frame( - wuffs_wbmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts); +static wuffs_base__empty_struct +wuffs_xxhash32__hasher__up( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x); // ---------------- VTables -const wuffs_base__image_decoder__func_ptrs -wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = { - (wuffs_base__status(*)(void*, - wuffs_base__pixel_buffer*, - wuffs_base__io_buffer*, - wuffs_base__pixel_blend, - wuffs_base__slice_u8, - wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame), - (wuffs_base__status(*)(void*, - wuffs_base__frame_config*, - wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config), - (wuffs_base__status(*)(void*, - wuffs_base__image_config*, - wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config), - (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect), +const wuffs_base__hasher_u32__func_ptrs +wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = { + (uint32_t(*)(const void*))(&wuffs_xxhash32__hasher__checksum_u32), (uint64_t(*)(const void*, - uint32_t))(&wuffs_wbmp__decoder__get_quirk), - (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__history_retain_length), - (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops), - (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs), - (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames), - (wuffs_base__status(*)(void*, - uint64_t, - uint64_t))(&wuffs_wbmp__decoder__restart_frame), + uint32_t))(&wuffs_xxhash32__hasher__get_quirk), (wuffs_base__status(*)(void*, uint32_t, - uint64_t))(&wuffs_wbmp__decoder__set_quirk), + uint64_t))(&wuffs_xxhash32__hasher__set_quirk), (wuffs_base__empty_struct(*)(void*, - uint32_t, - bool))(&wuffs_wbmp__decoder__set_report_metadata), - (wuffs_base__status(*)(void*, - wuffs_base__io_buffer*, - wuffs_base__more_information*, - wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more), - (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len), + wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update), + (uint32_t(*)(void*, + wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update_u32), }; // ---------------- Initializer Implementations wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_wbmp__decoder__initialize( - wuffs_wbmp__decoder* self, +wuffs_xxhash32__hasher__initialize( + wuffs_xxhash32__hasher* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options){ @@ -60569,22 +75569,22 @@ wuffs_wbmp__decoder__initialize( } self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name = - wuffs_base__image_decoder__vtable_name; - self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers = - (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder); + self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = + wuffs_base__hasher_u32__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = + (const void*)(&wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32); return wuffs_base__make_status(NULL); } -wuffs_wbmp__decoder* -wuffs_wbmp__decoder__alloc(void) { - wuffs_wbmp__decoder* x = - (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1)); +wuffs_xxhash32__hasher* +wuffs_xxhash32__hasher__alloc(void) { + wuffs_xxhash32__hasher* x = + (wuffs_xxhash32__hasher*)(calloc(1, sizeof(wuffs_xxhash32__hasher))); if (!x) { return NULL; } - if (wuffs_wbmp__decoder__initialize( - x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + if (wuffs_xxhash32__hasher__initialize( + x, sizeof(wuffs_xxhash32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { free(x); return NULL; } @@ -60592,18 +75592,18 @@ wuffs_wbmp__decoder__alloc(void) { } size_t -sizeof__wuffs_wbmp__decoder(void) { - return sizeof(wuffs_wbmp__decoder); +sizeof__wuffs_xxhash32__hasher(void) { + return sizeof(wuffs_xxhash32__hasher); } // ---------------- Function Implementations -// -------- func wbmp.decoder.get_quirk +// -------- func xxhash32.hasher.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__get_quirk( - const wuffs_wbmp__decoder* self, +wuffs_xxhash32__hasher__get_quirk( + const wuffs_xxhash32__hasher* self, uint32_t a_key) { if (!self) { return 0; @@ -60616,12 +75616,12 @@ wuffs_wbmp__decoder__get_quirk( return 0u; } -// -------- func wbmp.decoder.set_quirk +// -------- func xxhash32.hasher.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__set_quirk( - wuffs_wbmp__decoder* self, +wuffs_xxhash32__hasher__set_quirk( + wuffs_xxhash32__hasher* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -60637,627 +75637,387 @@ wuffs_wbmp__decoder__set_quirk( return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func wbmp.decoder.decode_image_config +// -------- func xxhash32.hasher.update WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_image_config( - wuffs_wbmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct +wuffs_xxhash32__hasher__update( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return wuffs_base__make_empty_struct(); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 1)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_image_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } - - ok: - self->private_impl.p_decode_image_config[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_empty_struct(); } - return status; -} - -// -------- func wbmp.decoder.do_decode_image_config - -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_image_config( - wuffs_wbmp__decoder* self, - wuffs_base__image_config* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - uint8_t v_c = 0; - uint32_t v_i = 0; - uint32_t v_p = 0; - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } + wuffs_base__slice_u8 v_remaining = {0}; - uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0]; - if (coro_susp_point) { - v_i = self->private_data.s_do_decode_image_config[0].v_i; - v_p = self->private_data.s_do_decode_image_config[0].v_p; + if ((self->private_impl.f_length_modulo_u32 == 0u) && ! self->private_impl.f_length_overflows_u32) { + self->private_impl.f_v0 = 606290984u; + self->private_impl.f_v1 = 2246822519u; + self->private_impl.f_v2 = 0u; + self->private_impl.f_v3 = 1640531535u; } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - if (self->private_impl.f_call_sequence != 0u) { - status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - goto exit; - } - v_i = 0u; - while (v_i < 2u) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_0 = *iop_a_src++; - v_c = t_0; - } - if (v_c != 0u) { - status = wuffs_base__make_status(wuffs_wbmp__error__bad_header); - goto exit; - } - v_i += 1u; - } - v_i = 0u; - while (v_i < 2u) { - v_p = 0u; - while (true) { - { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); - if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - goto suspend; - } - uint8_t t_1 = *iop_a_src++; - v_c = t_1; - } - v_p |= ((uint32_t)((v_c & 127u))); - if ((v_c >> 7u) == 0u) { - break; - } else if (v_p > 131071u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension); - goto exit; - } - v_p <<= 7u; - } - if (v_i == 0u) { - self->private_impl.f_width = v_p; - } else { - self->private_impl.f_height = v_p; - } - v_i += 1u; - } - self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))); - if (a_dst != NULL) { - wuffs_base__image_config__set( - a_dst, - 2198077448u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height, - self->private_impl.f_frame_config_io_position, - true); + while (((uint64_t)(a_x.len)) > 0u) { + v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); + if (((uint64_t)(a_x.len)) > 16777216u) { + v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 16777216u); + a_x = wuffs_base__slice_u8__subslice_j(a_x, 16777216u); } - self->private_impl.f_call_sequence = 32u; - - goto ok; - ok: - self->private_impl.p_do_decode_image_config[0] = 0; - goto exit; - } - - goto suspend; - suspend: - self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_image_config[0].v_i = v_i; - self->private_data.s_do_decode_image_config[0].v_p = v_p; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + wuffs_xxhash32__hasher__up(self, a_x); + a_x = v_remaining; } - - return status; + return wuffs_base__make_empty_struct(); } -// -------- func wbmp.decoder.decode_frame_config +// -------- func xxhash32.hasher.update_u32 WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_frame_config( - wuffs_wbmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_xxhash32__hasher__update_u32( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return 0; } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 2)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); - } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - - while (true) { - { - wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame_config(self, a_dst, a_src); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } - - ok: - self->private_impl.p_decode_frame_config[0] = 0; - goto exit; + return 0; } - goto suspend; - suspend: - self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0; - - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; + wuffs_xxhash32__hasher__update(self, a_x); + return wuffs_xxhash32__hasher__checksum_u32(self); } -// -------- func wbmp.decoder.do_decode_frame_config +// -------- func xxhash32.hasher.up WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_frame_config( - wuffs_wbmp__decoder* self, - wuffs_base__frame_config* a_dst, - wuffs_base__io_buffer* a_src) { - wuffs_base__status status = wuffs_base__make_status(NULL); - - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } - - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +static wuffs_base__empty_struct +wuffs_xxhash32__hasher__up( + wuffs_xxhash32__hasher* self, + wuffs_base__slice_u8 a_x) { + uint32_t v_new_lmu = 0; + uint32_t v_buf_u32 = 0; + uint32_t v_buf_len = 0; + uint32_t v_v0 = 0; + uint32_t v_v1 = 0; + uint32_t v_v2 = 0; + uint32_t v_v3 = 0; + wuffs_base__slice_u8 v_p = {0}; - if (self->private_impl.f_call_sequence == 32u) { - } else if (self->private_impl.f_call_sequence < 32u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_wbmp__decoder__do_decode_image_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else if (self->private_impl.f_call_sequence == 40u) { - if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) { - status = wuffs_base__make_status(wuffs_base__error__bad_restart); - goto exit; - } - } else if (self->private_impl.f_call_sequence == 64u) { - self->private_impl.f_call_sequence = 96u; - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; + v_new_lmu = ((uint32_t)(self->private_impl.f_length_modulo_u32 + ((uint32_t)(((uint64_t)(a_x.len)))))); + self->private_impl.f_length_overflows_u32 = ((v_new_lmu < self->private_impl.f_length_modulo_u32) || self->private_impl.f_length_overflows_u32); + self->private_impl.f_length_modulo_u32 = v_new_lmu; + while (true) { + if (self->private_impl.f_buf_len >= 16u) { + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) | + (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u)); + v_v0 = ((uint32_t)(self->private_impl.f_v0 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u)); + self->private_impl.f_v0 = ((uint32_t)(v_v0 * 2654435761u)); + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) | + (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u)); + v_v1 = ((uint32_t)(self->private_impl.f_v1 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u)); + self->private_impl.f_v1 = ((uint32_t)(v_v1 * 2654435761u)); + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) | + (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u)); + v_v2 = ((uint32_t)(self->private_impl.f_v2 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u)); + self->private_impl.f_v2 = ((uint32_t)(v_v2 * 2654435761u)); + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[12u])) | + (((uint32_t)(self->private_impl.f_buf_data[13u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[14u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[15u])) << 24u)); + v_v3 = ((uint32_t)(self->private_impl.f_v3 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u)); + self->private_impl.f_v3 = ((uint32_t)(v_v3 * 2654435761u)); + self->private_impl.f_buf_len = 0u; + break; } - if (a_dst != NULL) { - wuffs_base__frame_config__set( - a_dst, - wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height), - ((wuffs_base__flicks)(0u)), - 0u, - self->private_impl.f_frame_config_io_position, - 0u, - true, - false, - 4278190080u); + if (((uint64_t)(a_x.len)) <= 0u) { + return wuffs_base__make_empty_struct(); } - self->private_impl.f_call_sequence = 64u; - - ok: - self->private_impl.p_do_decode_frame_config[0] = 0; - goto exit; + self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + self->private_impl.f_buf_len += 1u; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); } - - goto suspend; - suspend: - self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + v_buf_len = ((uint32_t)(((uint8_t)(self->private_impl.f_buf_len & 15u)))); + v_v0 = self->private_impl.f_v0; + v_v1 = self->private_impl.f_v1; + v_v2 = self->private_impl.f_v2; + v_v3 = self->private_impl.f_v3; + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 16; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16)); + while (v_p.ptr < i_end0_p) { + v_buf_u32 = (((uint32_t)(v_p.ptr[0u])) | + (((uint32_t)(v_p.ptr[1u])) << 8u) | + (((uint32_t)(v_p.ptr[2u])) << 16u) | + (((uint32_t)(v_p.ptr[3u])) << 24u)); + v_v0 = ((uint32_t)(v_v0 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u)); + v_v0 = ((uint32_t)(v_v0 * 2654435761u)); + v_buf_u32 = (((uint32_t)(v_p.ptr[4u])) | + (((uint32_t)(v_p.ptr[5u])) << 8u) | + (((uint32_t)(v_p.ptr[6u])) << 16u) | + (((uint32_t)(v_p.ptr[7u])) << 24u)); + v_v1 = ((uint32_t)(v_v1 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u)); + v_v1 = ((uint32_t)(v_v1 * 2654435761u)); + v_buf_u32 = (((uint32_t)(v_p.ptr[8u])) | + (((uint32_t)(v_p.ptr[9u])) << 8u) | + (((uint32_t)(v_p.ptr[10u])) << 16u) | + (((uint32_t)(v_p.ptr[11u])) << 24u)); + v_v2 = ((uint32_t)(v_v2 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u)); + v_v2 = ((uint32_t)(v_v2 * 2654435761u)); + v_buf_u32 = (((uint32_t)(v_p.ptr[12u])) | + (((uint32_t)(v_p.ptr[13u])) << 8u) | + (((uint32_t)(v_p.ptr[14u])) << 16u) | + (((uint32_t)(v_p.ptr[15u])) << 24u)); + v_v3 = ((uint32_t)(v_v3 + ((uint32_t)(v_buf_u32 * 2246822519u)))); + v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u)); + v_v3 = ((uint32_t)(v_v3 * 2654435761u)); + v_p.ptr += 16; + } + v_p.len = 1; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end1_p) { + self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u]; + v_buf_len = ((v_buf_len + 1u) & 15u); + v_p.ptr += 1; + } + v_p.len = 0; } - - return status; + self->private_impl.f_buf_len = ((uint8_t)(v_buf_len)); + self->private_impl.f_v0 = v_v0; + self->private_impl.f_v1 = v_v1; + self->private_impl.f_v2 = v_v2; + self->private_impl.f_v3 = v_v3; + return wuffs_base__make_empty_struct(); } -// -------- func wbmp.decoder.decode_frame +// -------- func xxhash32.hasher.checksum_u32 WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__decode_frame( - wuffs_wbmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { +WUFFS_BASE__MAYBE_STATIC uint32_t +wuffs_xxhash32__hasher__checksum_u32( + const wuffs_xxhash32__hasher* self) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return 0; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return 0; + } + + uint32_t v_ret = 0; + uint32_t v_i = 0; + uint32_t v_n = 0; + uint32_t v_buf_u32 = 0; + + if ((self->private_impl.f_length_modulo_u32 >= 16u) || self->private_impl.f_length_overflows_u32) { + v_ret += (((uint32_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 31u)); + v_ret += (((uint32_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 25u)); + v_ret += (((uint32_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 20u)); + v_ret += (((uint32_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 14u)); + v_ret += self->private_impl.f_length_modulo_u32; + } else { + v_ret += 374761393u; + v_ret += self->private_impl.f_length_modulo_u32; + } + v_n = 16u; + v_n = wuffs_base__u32__min(v_n, ((uint32_t)(self->private_impl.f_buf_len))); + if (4u <= v_n) { + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) | + (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u)); + v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); + v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); + v_ret *= 668265263u; + v_i = 4u; + } + if (8u <= v_n) { + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) | + (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u)); + v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); + v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); + v_ret *= 668265263u; + v_i = 8u; } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); + if (12u <= v_n) { + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) | + (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u)); + v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); + v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); + v_ret *= 668265263u; + v_i = 12u; } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 3)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + while (v_i < v_n) { + v_ret += ((uint32_t)(((uint32_t)(self->private_impl.f_buf_data[v_i])) * 374761393u)); + v_ret = (((uint32_t)(v_ret << 11u)) | (v_ret >> 21u)); + v_ret *= 2654435761u; + v_i += 1u; } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - - wuffs_base__status v_status = wuffs_base__make_status(NULL); - - uint32_t coro_susp_point = self->private_impl.p_decode_frame[0]; - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + v_ret ^= (v_ret >> 15u); + v_ret *= 2246822519u; + v_ret ^= (v_ret >> 13u); + v_ret *= 3266489917u; + v_ret ^= (v_ret >> 16u); + return v_ret; +} - while (true) { - { - wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame(self, - a_dst, - a_src, - a_blend, - a_workbuf, - a_opts); - v_status = t_0; - } - if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { - status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input); - goto exit; - } - status = v_status; - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); - } +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) - ok: - self->private_impl.p_decode_frame[0] = 0; - goto exit; - } +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) - goto suspend; - suspend: - self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0; +// ---------------- Status Codes Implementations - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - } - return status; -} +// ---------------- Private Consts -// -------- func wbmp.decoder.do_decode_frame +#define WUFFS_XXHASH64__XXH_PRIME64_1 11400714785074694791u -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__status -wuffs_wbmp__decoder__do_decode_frame( - wuffs_wbmp__decoder* self, - wuffs_base__pixel_buffer* a_dst, - wuffs_base__io_buffer* a_src, - wuffs_base__pixel_blend a_blend, - wuffs_base__slice_u8 a_workbuf, - wuffs_base__decode_frame_options* a_opts) { - wuffs_base__status status = wuffs_base__make_status(NULL); +#define WUFFS_XXHASH64__XXH_PRIME64_2 14029467366897019727u - wuffs_base__status v_status = wuffs_base__make_status(NULL); - wuffs_base__pixel_format v_dst_pixfmt = {0}; - uint32_t v_dst_bits_per_pixel = 0; - uint64_t v_dst_bytes_per_pixel = 0; - uint64_t v_dst_x_in_bytes = 0; - uint32_t v_dst_x = 0; - uint32_t v_dst_y = 0; - wuffs_base__table_u8 v_tab = {0}; - wuffs_base__slice_u8 v_dst = {0}; - uint8_t v_src[1] = {0}; - uint8_t v_c = 0; +#define WUFFS_XXHASH64__XXH_PRIME64_3 1609587929392839161u - const uint8_t* iop_a_src = NULL; - const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; - if (a_src && a_src->data.ptr) { - io0_a_src = a_src->data.ptr; - io1_a_src = io0_a_src + a_src->meta.ri; - iop_a_src = io1_a_src; - io2_a_src = io0_a_src + a_src->meta.wi; - } +#define WUFFS_XXHASH64__XXH_PRIME64_4 9650029242287828579u - uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0]; - if (coro_susp_point) { - v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel; - v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x; - v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y; - memcpy(v_src, self->private_data.s_do_decode_frame[0].v_src, sizeof(v_src)); - v_c = self->private_data.s_do_decode_frame[0].v_c; - } - switch (coro_susp_point) { - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; +#define WUFFS_XXHASH64__XXH_PRIME64_5 2870177450012600261u - if (self->private_impl.f_call_sequence == 64u) { - } else if (self->private_impl.f_call_sequence < 64u) { - if (a_src) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } - WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); - status = wuffs_wbmp__decoder__do_decode_frame_config(self, NULL, a_src); - if (a_src) { - iop_a_src = a_src->data.ptr + a_src->meta.ri; - } - if (status.repr) { - goto suspend; - } - } else { - status = wuffs_base__make_status(wuffs_base__note__end_of_data); - goto ok; - } - v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler, - wuffs_base__pixel_buffer__pixel_format(a_dst), - wuffs_base__pixel_buffer__palette(a_dst), - wuffs_base__utility__make_pixel_format(536870920u), - wuffs_base__utility__empty_slice_u8(), - a_blend); - if ( ! wuffs_base__status__is_ok(&v_status)) { - status = v_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; - } - 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); - if ((v_dst_bits_per_pixel & 7u) != 0u) { - status = wuffs_base__make_status(wuffs_base__error__unsupported_option); - goto exit; - } - v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u))); - if (self->private_impl.f_width > 0u) { - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - while (v_dst_y < self->private_impl.f_height) { - v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y); - v_dst_x = 0u; - while (v_dst_x < self->private_impl.f_width) { - if ((v_dst_x & 7u) == 0u) { - while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { - status = wuffs_base__make_status(wuffs_base__suspension__short_read); - WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); - v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u); - v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y); - v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel); - if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes); - } - } - v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src); - iop_a_src += 1u; - } - if ((v_c & 128u) == 0u) { - v_src[0u] = 0u; - } else { - v_src[0u] = 255u; - } - v_c = ((uint8_t)((((uint32_t)(v_c)) << 1u))); - wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__utility__empty_slice_u8(), wuffs_base__make_slice_u8(v_src, 1)); - if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) { - v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel); - } - v_dst_x += 1u; - } - v_dst_y += 1u; - } - } - self->private_impl.f_call_sequence = 96u; +#define WUFFS_XXHASH64__INITIAL_V0 6983438078262162902u - ok: - self->private_impl.p_do_decode_frame[0] = 0; - goto exit; - } +#define WUFFS_XXHASH64__INITIAL_V1 14029467366897019727u - goto suspend; - suspend: - self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel; - self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x; - self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y; - memcpy(self->private_data.s_do_decode_frame[0].v_src, v_src, sizeof(v_src)); - self->private_data.s_do_decode_frame[0].v_c = v_c; +#define WUFFS_XXHASH64__INITIAL_V2 0u - goto exit; - exit: - if (a_src && a_src->data.ptr) { - a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); - } +#define WUFFS_XXHASH64__INITIAL_V3 7046029288634856825u - return status; -} +// ---------------- Private Initializer Prototypes -// -------- func wbmp.decoder.frame_dirty_rect +// ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 -wuffs_wbmp__decoder__frame_dirty_rect( - const wuffs_wbmp__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_rect_ie_u32(); - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_rect_ie_u32(); - } +static wuffs_base__empty_struct +wuffs_xxhash64__hasher__up( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x); - return wuffs_base__utility__make_rect_ie_u32( - 0u, - 0u, - self->private_impl.f_width, - self->private_impl.f_height); -} +// ---------------- VTables -// -------- func wbmp.decoder.num_animation_loops +const wuffs_base__hasher_u64__func_ptrs +wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64 = { + (uint64_t(*)(const void*))(&wuffs_xxhash64__hasher__checksum_u64), + (uint64_t(*)(const void*, + uint32_t))(&wuffs_xxhash64__hasher__get_quirk), + (wuffs_base__status(*)(void*, + uint32_t, + uint64_t))(&wuffs_xxhash64__hasher__set_quirk), + (wuffs_base__empty_struct(*)(void*, + wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update), + (uint64_t(*)(void*, + wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update_u64), +}; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_wbmp__decoder__num_animation_loops( - const wuffs_wbmp__decoder* self) { +// ---------------- Initializer Implementations + +wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT +wuffs_xxhash64__hasher__initialize( + wuffs_xxhash64__hasher* self, + size_t sizeof_star_self, + uint64_t wuffs_version, + uint32_t options){ if (!self) { - return 0; + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (sizeof(*self) != sizeof_star_self) { + return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + } + if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || + (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { + return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); } - return 0u; -} + if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { + // The whole point of this if-check is to detect an uninitialized *self. + // We disable the warning on GCC. Clang-5.0 does not have this warning. +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + if (self->private_impl.magic != 0) { + return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + } +#if !defined(__clang__) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + } else { + if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { + memset(self, 0, sizeof(*self)); + options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + } else { + memset(&(self->private_impl), 0, sizeof(self->private_impl)); + } + } -// -------- func wbmp.decoder.num_decoded_frame_configs + self->private_impl.magic = WUFFS_BASE__MAGIC; + self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name = + wuffs_base__hasher_u64__vtable_name; + self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers = + (const void*)(&wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64); + return wuffs_base__make_status(NULL); +} -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__num_decoded_frame_configs( - const wuffs_wbmp__decoder* self) { - if (!self) { - return 0; +wuffs_xxhash64__hasher* +wuffs_xxhash64__hasher__alloc(void) { + wuffs_xxhash64__hasher* x = + (wuffs_xxhash64__hasher*)(calloc(1, sizeof(wuffs_xxhash64__hasher))); + if (!x) { + return NULL; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + if (wuffs_xxhash64__hasher__initialize( + x, sizeof(wuffs_xxhash64__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + free(x); + return NULL; } + return x; +} - if (self->private_impl.f_call_sequence > 32u) { - return 1u; - } - return 0u; +size_t +sizeof__wuffs_xxhash64__hasher(void) { + return sizeof(wuffs_xxhash64__hasher); } -// -------- func wbmp.decoder.num_decoded_frames +// ---------------- Function Implementations + +// -------- func xxhash64.hasher.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__num_decoded_frames( - const wuffs_wbmp__decoder* self) { +wuffs_xxhash64__hasher__get_quirk( + const wuffs_xxhash64__hasher* self, + uint32_t a_key) { if (!self) { return 0; } @@ -61266,20 +76026,17 @@ wuffs_wbmp__decoder__num_decoded_frames( return 0; } - if (self->private_impl.f_call_sequence > 64u) { - return 1u; - } return 0u; } -// -------- func wbmp.decoder.restart_frame +// -------- func xxhash64.hasher.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__restart_frame( - wuffs_wbmp__decoder* self, - uint64_t a_index, - uint64_t a_io_position) { +wuffs_xxhash64__hasher__set_quirk( + wuffs_xxhash64__hasher* self, + uint32_t a_key, + uint64_t a_value) { if (!self) { return wuffs_base__make_status(wuffs_base__error__bad_receiver); } @@ -61290,77 +76047,206 @@ wuffs_wbmp__decoder__restart_frame( : wuffs_base__error__initialize_not_called); } - if (self->private_impl.f_call_sequence < 32u) { - return wuffs_base__make_status(wuffs_base__error__bad_call_sequence); - } - if (a_index != 0u) { - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - self->private_impl.f_call_sequence = 40u; - self->private_impl.f_frame_config_io_position = a_io_position; - return wuffs_base__make_status(NULL); + return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func wbmp.decoder.set_report_metadata +// -------- func xxhash64.hasher.update WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_wbmp__decoder__set_report_metadata( - wuffs_wbmp__decoder* self, - uint32_t a_fourcc, - bool a_report) { +wuffs_xxhash64__hasher__update( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x) { + if (!self) { + return wuffs_base__make_empty_struct(); + } + if (self->private_impl.magic != WUFFS_BASE__MAGIC) { + return wuffs_base__make_empty_struct(); + } + + if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) { + self->private_impl.f_v0 = 6983438078262162902u; + self->private_impl.f_v1 = 14029467366897019727u; + self->private_impl.f_v2 = 0u; + self->private_impl.f_v3 = 7046029288634856825u; + } + wuffs_xxhash64__hasher__up(self, a_x); return wuffs_base__make_empty_struct(); } -// -------- func wbmp.decoder.tell_me_more +// -------- func xxhash64.hasher.update_u64 WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_wbmp__decoder__tell_me_more( - wuffs_wbmp__decoder* self, - wuffs_base__io_buffer* a_dst, - wuffs_base__more_information* a_minfo, - wuffs_base__io_buffer* a_src) { +WUFFS_BASE__MAYBE_STATIC uint64_t +wuffs_xxhash64__hasher__update_u64( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x) { if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); + return 0; } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - if (!a_dst || !a_src) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__bad_argument); - } - if ((self->private_impl.active_coroutine != 0) && - (self->private_impl.active_coroutine != 4)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; - return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + return 0; } - self->private_impl.active_coroutine = 0; - wuffs_base__status status = wuffs_base__make_status(NULL); - status = wuffs_base__make_status(wuffs_base__error__no_more_information); - goto exit; + wuffs_xxhash64__hasher__update(self, a_x); + return wuffs_xxhash64__hasher__checksum_u64(self); +} - goto ok; - ok: - goto exit; - exit: - if (wuffs_base__status__is_error(&status)) { - self->private_impl.magic = WUFFS_BASE__DISABLED; +// -------- func xxhash64.hasher.up + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__empty_struct +wuffs_xxhash64__hasher__up( + wuffs_xxhash64__hasher* self, + wuffs_base__slice_u8 a_x) { + uint64_t v_new_lmu = 0; + uint64_t v_buf_u64 = 0; + uint32_t v_buf_len = 0; + uint64_t v_v0 = 0; + uint64_t v_v1 = 0; + uint64_t v_v2 = 0; + uint64_t v_v3 = 0; + wuffs_base__slice_u8 v_p = {0}; + + v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len)))); + self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64); + self->private_impl.f_length_modulo_u64 = v_new_lmu; + while (true) { + if (self->private_impl.f_buf_len >= 32u) { + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) | + (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u)); + v_v0 = ((uint64_t)(self->private_impl.f_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); + self->private_impl.f_v0 = ((uint64_t)(v_v0 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) | + (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u)); + v_v1 = ((uint64_t)(self->private_impl.f_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); + self->private_impl.f_v1 = ((uint64_t)(v_v1 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) | + (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u)); + v_v2 = ((uint64_t)(self->private_impl.f_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); + self->private_impl.f_v2 = ((uint64_t)(v_v2 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[24u])) | + (((uint64_t)(self->private_impl.f_buf_data[25u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[26u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[27u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[28u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[29u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[30u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[31u])) << 56u)); + v_v3 = ((uint64_t)(self->private_impl.f_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); + self->private_impl.f_v3 = ((uint64_t)(v_v3 * 11400714785074694791u)); + self->private_impl.f_buf_len = 0u; + break; + } + if (((uint64_t)(a_x.len)) <= 0u) { + return wuffs_base__make_empty_struct(); + } + self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u]; + self->private_impl.f_buf_len += 1u; + a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); + } + v_buf_len = (self->private_impl.f_buf_len & 31u); + v_v0 = self->private_impl.f_v0; + v_v1 = self->private_impl.f_v1; + v_v2 = self->private_impl.f_v2; + v_v3 = self->private_impl.f_v3; + { + wuffs_base__slice_u8 i_slice_p = a_x; + v_p.ptr = i_slice_p.ptr; + v_p.len = 32; + const uint8_t* i_end0_p = wuffs_private_impl__ptr_u8_plus_len(v_p.ptr, (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32)); + while (v_p.ptr < i_end0_p) { + v_buf_u64 = (((uint64_t)(v_p.ptr[0u])) | + (((uint64_t)(v_p.ptr[1u])) << 8u) | + (((uint64_t)(v_p.ptr[2u])) << 16u) | + (((uint64_t)(v_p.ptr[3u])) << 24u) | + (((uint64_t)(v_p.ptr[4u])) << 32u) | + (((uint64_t)(v_p.ptr[5u])) << 40u) | + (((uint64_t)(v_p.ptr[6u])) << 48u) | + (((uint64_t)(v_p.ptr[7u])) << 56u)); + v_v0 = ((uint64_t)(v_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); + v_v0 = ((uint64_t)(v_v0 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(v_p.ptr[8u])) | + (((uint64_t)(v_p.ptr[9u])) << 8u) | + (((uint64_t)(v_p.ptr[10u])) << 16u) | + (((uint64_t)(v_p.ptr[11u])) << 24u) | + (((uint64_t)(v_p.ptr[12u])) << 32u) | + (((uint64_t)(v_p.ptr[13u])) << 40u) | + (((uint64_t)(v_p.ptr[14u])) << 48u) | + (((uint64_t)(v_p.ptr[15u])) << 56u)); + v_v1 = ((uint64_t)(v_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); + v_v1 = ((uint64_t)(v_v1 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(v_p.ptr[16u])) | + (((uint64_t)(v_p.ptr[17u])) << 8u) | + (((uint64_t)(v_p.ptr[18u])) << 16u) | + (((uint64_t)(v_p.ptr[19u])) << 24u) | + (((uint64_t)(v_p.ptr[20u])) << 32u) | + (((uint64_t)(v_p.ptr[21u])) << 40u) | + (((uint64_t)(v_p.ptr[22u])) << 48u) | + (((uint64_t)(v_p.ptr[23u])) << 56u)); + v_v2 = ((uint64_t)(v_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); + v_v2 = ((uint64_t)(v_v2 * 11400714785074694791u)); + v_buf_u64 = (((uint64_t)(v_p.ptr[24u])) | + (((uint64_t)(v_p.ptr[25u])) << 8u) | + (((uint64_t)(v_p.ptr[26u])) << 16u) | + (((uint64_t)(v_p.ptr[27u])) << 24u) | + (((uint64_t)(v_p.ptr[28u])) << 32u) | + (((uint64_t)(v_p.ptr[29u])) << 40u) | + (((uint64_t)(v_p.ptr[30u])) << 48u) | + (((uint64_t)(v_p.ptr[31u])) << 56u)); + v_v3 = ((uint64_t)(v_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); + v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); + v_v3 = ((uint64_t)(v_v3 * 11400714785074694791u)); + v_p.ptr += 32; + } + v_p.len = 1; + const uint8_t* i_end1_p = wuffs_private_impl__ptr_u8_plus_len(i_slice_p.ptr, i_slice_p.len); + while (v_p.ptr < i_end1_p) { + self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u]; + v_buf_len = ((v_buf_len + 1u) & 31u); + v_p.ptr += 1; + } + v_p.len = 0; } - return status; + self->private_impl.f_buf_len = v_buf_len; + self->private_impl.f_v0 = v_v0; + self->private_impl.f_v1 = v_v1; + self->private_impl.f_v2 = v_v2; + self->private_impl.f_v3 = v_v3; + return wuffs_base__make_empty_struct(); } -// -------- func wbmp.decoder.history_retain_length +// -------- func xxhash64.hasher.checksum_u64 WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_wbmp__decoder__history_retain_length( - const wuffs_wbmp__decoder* self) { +wuffs_xxhash64__hasher__checksum_u64( + const wuffs_xxhash64__hasher* self) { if (!self) { return 0; } @@ -61369,83 +76255,307 @@ wuffs_wbmp__decoder__history_retain_length( return 0; } - return 0u; -} - -// -------- func wbmp.decoder.workbuf_len + uint64_t v_ret = 0; + uint64_t v_v0 = 0; + uint64_t v_v1 = 0; + uint64_t v_v2 = 0; + uint64_t v_v3 = 0; + uint32_t v_i = 0; + uint32_t v_i8 = 0; + uint32_t v_n = 0; + uint32_t v_buf_u32 = 0; + uint64_t v_buf_u64 = 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 -wuffs_wbmp__decoder__workbuf_len( - const wuffs_wbmp__decoder* self) { - if (!self) { - return wuffs_base__utility__empty_range_ii_u64(); + if ((self->private_impl.f_length_modulo_u64 >= 32u) || self->private_impl.f_length_overflows_u64) { + v_ret += (((uint64_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 63u)); + v_ret += (((uint64_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 57u)); + v_ret += (((uint64_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 52u)); + v_ret += (((uint64_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 46u)); + v_v0 = ((uint64_t)(self->private_impl.f_v0 * 14029467366897019727u)); + v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); + v_v0 *= 11400714785074694791u; + v_v1 = ((uint64_t)(self->private_impl.f_v1 * 14029467366897019727u)); + v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); + v_v1 *= 11400714785074694791u; + v_v2 = ((uint64_t)(self->private_impl.f_v2 * 14029467366897019727u)); + v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); + v_v2 *= 11400714785074694791u; + v_v3 = ((uint64_t)(self->private_impl.f_v3 * 14029467366897019727u)); + v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); + v_v3 *= 11400714785074694791u; + v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v0) * 11400714785074694791u)) + 9650029242287828579u)); + v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v1) * 11400714785074694791u)) + 9650029242287828579u)); + v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v2) * 11400714785074694791u)) + 9650029242287828579u)); + v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v3) * 11400714785074694791u)) + 9650029242287828579u)); + v_ret += self->private_impl.f_length_modulo_u64; + } else { + v_ret += 2870177450012600261u; + v_ret += self->private_impl.f_length_modulo_u64; } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return wuffs_base__utility__empty_range_ii_u64(); + v_n = 32u; + v_n = wuffs_base__u32__min(v_n, self->private_impl.f_buf_len); + if (8u <= v_n) { + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) | + (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u)); + v_buf_u64 *= 14029467366897019727u; + v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); + v_buf_u64 *= 11400714785074694791u; + v_ret ^= v_buf_u64; + v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); + v_ret *= 11400714785074694791u; + v_ret += 9650029242287828579u; + v_i = 8u; } - - return wuffs_base__utility__make_range_ii_u64(0u, 0u); + if (16u <= v_n) { + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) | + (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u)); + v_buf_u64 *= 14029467366897019727u; + v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); + v_buf_u64 *= 11400714785074694791u; + v_ret ^= v_buf_u64; + v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); + v_ret *= 11400714785074694791u; + v_ret += 9650029242287828579u; + v_i = 16u; + } + if (24u <= v_n) { + v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) | + (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) | + (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) | + (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) | + (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) | + (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) | + (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) | + (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u)); + v_buf_u64 *= 14029467366897019727u; + v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); + v_buf_u64 *= 11400714785074694791u; + v_ret ^= v_buf_u64; + v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); + v_ret *= 11400714785074694791u; + v_ret += 9650029242287828579u; + v_i = 24u; + } + if ((v_n & 4u) != 0u) { + v_i8 = (v_i & 24u); + v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 0u)])) | + (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 1u)])) << 8u) | + (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 2u)])) << 16u) | + (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 3u)])) << 24u)); + v_ret ^= ((uint64_t)(((uint64_t)(v_buf_u32)) * 11400714785074694791u)); + v_ret = (((uint64_t)(v_ret << 23u)) | (v_ret >> 41u)); + v_ret *= 14029467366897019727u; + v_ret += 1609587929392839161u; + v_i = (v_i8 + 4u); + } + while (v_i < v_n) { + v_ret ^= ((uint64_t)(((uint64_t)(self->private_impl.f_buf_data[v_i])) * 2870177450012600261u)); + v_ret = (((uint64_t)(v_ret << 11u)) | (v_ret >> 53u)); + v_ret *= 11400714785074694791u; + v_i += 1u; + } + v_ret ^= (v_ret >> 33u); + v_ret *= 14029467366897019727u; + v_ret ^= (v_ret >> 29u); + v_ret *= 1609587929392839161u; + v_ret ^= (v_ret >> 32u); + return ((uint64_t)(v_ret)); } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) // ---------------- Status Codes Implementations -// ---------------- Private Consts +const char wuffs_xz__error__bad_bcj_offset[] = "#xz: bad BCJ offset"; +const char wuffs_xz__error__bad_block_header[] = "#xz: bad block header"; +const char wuffs_xz__error__bad_checksum[] = "#xz: bad checksum"; +const char wuffs_xz__error__bad_filter[] = "#xz: bad filter"; +const char wuffs_xz__error__bad_footer[] = "#xz: bad footer"; +const char wuffs_xz__error__bad_header[] = "#xz: bad header"; +const char wuffs_xz__error__bad_header_concatenated_stream[] = "#xz: bad header (concatenated stream)"; +const char wuffs_xz__error__bad_index[] = "#xz: bad index"; +const char wuffs_xz__error__bad_padding[] = "#xz: bad padding"; +const char wuffs_xz__error__truncated_input[] = "#xz: truncated input"; +const char wuffs_xz__error__unsupported_checksum_algorithm[] = "#xz: unsupported checksum algorithm"; +const char wuffs_xz__error__unsupported_filter[] = "#xz: unsupported filter"; +const char wuffs_xz__error__unsupported_filter_combination[] = "#xz: unsupported filter combination"; +const char wuffs_xz__error__internal_error_inconsistent_bcj_filter_state[] = "#xz: internal error: inconsistent BCJ filter state"; -#define WUFFS_XXHASH32__XXH_PRIME32_1 2654435761 +// ---------------- Private Consts -#define WUFFS_XXHASH32__XXH_PRIME32_2 2246822519 +static const bool +WUFFS_XZ__FILTER_04_X86_MASK_TO_ALLOWED_STATUS[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 1u, 1u, 1u, 0u, 1u, 0u, 0u, 0u, +}; -#define WUFFS_XXHASH32__XXH_PRIME32_3 3266489917 +static const uint8_t +WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 1u, 2u, 2u, 3u, 3u, 3u, 3u, +}; -#define WUFFS_XXHASH32__XXH_PRIME32_4 668265263 +static const uint32_t +WUFFS_XZ__FILTER_04_X86_MASK_TO_XOR_OPERAND[8] WUFFS_BASE__POTENTIALLY_UNUSED = { + 4294967295u, 16777215u, 65535u, 65535u, 255u, 255u, 255u, 255u, +}; -#define WUFFS_XXHASH32__XXH_PRIME32_5 374761393 +static const uint8_t +WUFFS_XZ__FILTER_06_IA64_BRANCH_TABLE[32] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 4u, 4u, 6u, 6u, 0u, 0u, 7u, 7u, + 4u, 4u, 0u, 0u, 4u, 4u, 0u, 0u, +}; -#define WUFFS_XXHASH32__INITIAL_V0 606290984 +#define WUFFS_XZ__QUIRKS_BASE 2021322752u -#define WUFFS_XXHASH32__INITIAL_V1 2246822519 +static const uint8_t +WUFFS_XZ__CHECKSUM_LENGTH[4] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 4u, 8u, 32u, +}; -#define WUFFS_XXHASH32__INITIAL_V2 0 +static const uint8_t +WUFFS_XZ__ZEROES[3] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, +}; -#define WUFFS_XXHASH32__INITIAL_V3 1640531535 +static const uint8_t +WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[12] WUFFS_BASE__POTENTIALLY_UNUSED = { + 0u, 0u, 0u, 0u, 1u, 4u, 16u, 4u, + 2u, 4u, 4u, 2u, +}; // ---------------- Private Initializer Prototypes // ---------------- Private Function Prototypes WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_xxhash32__hasher__up( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x); +static uint8_t +wuffs_xz__decoder__apply_non_final_filters( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_non_final_filters__choosy_default( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_04_x86( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_05_powerpc( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_06_ia64( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_07_arm( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_08_armthumb( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_09_sparc( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_0a_arm64( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_0b_riscv( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__do_transform_io( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__decode_block_header_with_padding( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__decode_block_header_sans_padding( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__verify_index( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src); + +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__verify_footer( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src); // ---------------- VTables -const wuffs_base__hasher_u32__func_ptrs -wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = { - (uint32_t(*)(const void*))(&wuffs_xxhash32__hasher__checksum_u32), +const wuffs_base__io_transformer__func_ptrs +wuffs_xz__decoder__func_ptrs_for__wuffs_base__io_transformer = { + (wuffs_base__optional_u63(*)(const void*))(&wuffs_xz__decoder__dst_history_retain_length), (uint64_t(*)(const void*, - uint32_t))(&wuffs_xxhash32__hasher__get_quirk), + uint32_t))(&wuffs_xz__decoder__get_quirk), (wuffs_base__status(*)(void*, uint32_t, - uint64_t))(&wuffs_xxhash32__hasher__set_quirk), - (wuffs_base__empty_struct(*)(void*, - wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update), - (uint32_t(*)(void*, - wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update_u32), + uint64_t))(&wuffs_xz__decoder__set_quirk), + (wuffs_base__status(*)(void*, + wuffs_base__io_buffer*, + wuffs_base__io_buffer*, + wuffs_base__slice_u8))(&wuffs_xz__decoder__transform_io), + (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_xz__decoder__workbuf_len), }; // ---------------- Initializer Implementations wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_xxhash32__hasher__initialize( - wuffs_xxhash32__hasher* self, +wuffs_xz__decoder__initialize( + wuffs_xz__decoder* self, size_t sizeof_star_self, uint64_t wuffs_version, uint32_t options){ @@ -61482,23 +76592,53 @@ wuffs_xxhash32__hasher__initialize( } } + self->private_impl.choosy_apply_non_final_filters = &wuffs_xz__decoder__apply_non_final_filters__choosy_default; + + { + wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize( + &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_crc64__ecma_hasher__initialize( + &self->private_data.f_crc64, sizeof(self->private_data.f_crc64), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_sha256__hasher__initialize( + &self->private_data.f_sha256, sizeof(self->private_data.f_sha256), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } + { + wuffs_base__status z = wuffs_lzma__decoder__initialize( + &self->private_data.f_lzma, sizeof(self->private_data.f_lzma), WUFFS_VERSION, options); + if (z.repr) { + return z; + } + } self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name = - wuffs_base__hasher_u32__vtable_name; - self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers = - (const void*)(&wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32); + self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name = + wuffs_base__io_transformer__vtable_name; + self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers = + (const void*)(&wuffs_xz__decoder__func_ptrs_for__wuffs_base__io_transformer); return wuffs_base__make_status(NULL); } -wuffs_xxhash32__hasher* -wuffs_xxhash32__hasher__alloc(void) { - wuffs_xxhash32__hasher* x = - (wuffs_xxhash32__hasher*)(calloc(sizeof(wuffs_xxhash32__hasher), 1)); +wuffs_xz__decoder* +wuffs_xz__decoder__alloc(void) { + wuffs_xz__decoder* x = + (wuffs_xz__decoder*)(calloc(1, sizeof(wuffs_xz__decoder))); if (!x) { return NULL; } - if (wuffs_xxhash32__hasher__initialize( - x, sizeof(wuffs_xxhash32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { + if (wuffs_xz__decoder__initialize( + x, sizeof(wuffs_xz__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { free(x); return NULL; } @@ -61506,18 +76646,511 @@ wuffs_xxhash32__hasher__alloc(void) { } size_t -sizeof__wuffs_xxhash32__hasher(void) { - return sizeof(wuffs_xxhash32__hasher); +sizeof__wuffs_xz__decoder(void) { + return sizeof(wuffs_xz__decoder); } // ---------------- Function Implementations -// -------- func xxhash32.hasher.get_quirk +// -------- func xz.decoder.apply_non_final_filters + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_non_final_filters( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + return (*self->private_impl.choosy_apply_non_final_filters)(self, a_dst_slice); +} + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_non_final_filters__choosy_default( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + uint32_t v_f = 0; + uint64_t v_i = 0; + uint32_t v_filter_id = 0; + uint32_t v_delta_dist = 0; + uint32_t v_delta_pos = 0; + uint8_t v_c8 = 0; + + if (self->private_impl.f_num_non_final_filters <= 0u) { + return 0u; + } + v_f = (self->private_impl.f_num_non_final_filters - 1u); + while (true) { + v_filter_id = (self->private_impl.f_filters[v_f] & 127u); + if (v_filter_id == 3u) { + v_delta_dist = (((self->private_impl.f_filters[v_f] >> 8u) & 255u) + 1u); + v_delta_pos = (self->private_impl.f_filters[v_f] >> 24u); + v_i = 0u; + while (v_i < ((uint64_t)(a_dst_slice.len))) { + v_c8 = a_dst_slice.ptr[v_i]; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + v_c8 += self->private_data.f_filter_data[v_f][(((uint32_t)(v_delta_dist + v_delta_pos)) & 255u)]; +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + self->private_data.f_filter_data[v_f][(v_delta_pos & 255u)] = v_c8; + v_delta_pos -= 1u; + a_dst_slice.ptr[v_i] = v_c8; + v_i += 1u; + } + self->private_impl.f_filters[v_f] &= 65535u; + self->private_impl.f_filters[v_f] |= ((uint32_t)(v_delta_pos << 24u)); + } + if (v_f <= 0u) { + break; + } + v_f -= 1u; + } + return 0u; +} + +// -------- func xz.decoder.apply_filter_04_x86 + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_04_x86( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint64_t v_i = 0; + uint64_t v_prev_pos = 0; + uint32_t v_prev_mask = 0; + uint8_t v_c8 = 0; + uint32_t v_src = 0; + uint32_t v_dst = 0; + uint32_t v_bit_num = 0; + + v_s = a_dst_slice; + v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 5u)); + v_prev_pos = 18446744073709551615u; + v_prev_mask = self->private_impl.f_bcj_x86_prev_mask; + while (((uint64_t)(v_s.len)) >= 5u) { + if (((uint8_t)(v_s.ptr[0u] & 254u)) != 232u) { + v_i += 1u; + v_p += 1u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + continue; + } + v_prev_pos = ((uint64_t)(v_i - v_prev_pos)); + if (v_prev_pos > 3u) { + v_prev_mask = 0u; + } else if (v_prev_pos > 0u) { + v_prev_mask = (((uint32_t)(v_prev_mask << (v_prev_pos - 1u))) & 7u); + if (v_prev_mask != 0u) { + v_c8 = v_s.ptr[((uint8_t)(4u - WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[(v_prev_mask & 7u)]))]; + if ( ! WUFFS_XZ__FILTER_04_X86_MASK_TO_ALLOWED_STATUS[(v_prev_mask & 7u)] || (v_c8 == 0u) || (v_c8 == 255u)) { + v_prev_pos = v_i; + v_prev_mask = (((uint32_t)(v_prev_mask << 1u)) | 1u); + v_i += 1u; + v_p += 1u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + continue; + } + } + } + v_prev_pos = v_i; + v_c8 = v_s.ptr[4u]; + if ((v_c8 != 0u) && (v_c8 != 255u)) { + v_prev_mask = (((uint32_t)(v_prev_mask << 1u)) | 1u); + v_i += 1u; + v_p += 1u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u); + continue; + } + v_src = ((((uint32_t)(v_s.ptr[1u])) << 0u) | + (((uint32_t)(v_s.ptr[2u])) << 8u) | + (((uint32_t)(v_s.ptr[3u])) << 16u) | + (((uint32_t)(v_s.ptr[4u])) << 24u)); + while (true) { + v_dst = ((uint32_t)(v_src - v_p)); + if (v_prev_mask == 0u) { + break; + } + v_bit_num = ((uint32_t)(WUFFS_XZ__FILTER_04_X86_MASK_TO_BIT_NUM[(v_prev_mask & 7u)])); + v_c8 = ((uint8_t)((v_dst >> (24u - (v_bit_num * 8u))))); + if ((v_c8 != 0u) && (v_c8 != 255u)) { + break; + } + v_src = (v_dst ^ WUFFS_XZ__FILTER_04_X86_MASK_TO_XOR_OPERAND[(v_prev_mask & 7u)]); + } + v_dst &= 33554431u; + v_dst |= ((uint32_t)(0u - (v_dst & 16777216u))); + v_s.ptr[1u] = ((uint8_t)((v_dst >> 0u))); + v_s.ptr[2u] = ((uint8_t)((v_dst >> 8u))); + v_s.ptr[3u] = ((uint8_t)((v_dst >> 16u))); + v_s.ptr[4u] = ((uint8_t)((v_dst >> 24u))); + v_i += 5u; + v_p += 5u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 5u); + } + v_prev_pos = ((uint64_t)(v_i - v_prev_pos)); + if (v_prev_pos > 3u) { + self->private_impl.f_bcj_x86_prev_mask = 0u; + } else if (v_prev_pos > 0u) { + self->private_impl.f_bcj_x86_prev_mask = ((uint32_t)(v_prev_mask << (v_prev_pos - 1u))); + } + self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 5u)); + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_05_powerpc + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_05_powerpc( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + + v_s = a_dst_slice; + v_p = self->private_impl.f_bcj_pos; + while (((uint64_t)(v_s.len)) >= 4u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 24u) | + (((uint32_t)(v_s.ptr[1u])) << 16u) | + (((uint32_t)(v_s.ptr[2u])) << 8u) | + (((uint32_t)(v_s.ptr[3u])) << 0u)); + if ((v_x & 4227858435u) == 1207959553u) { + v_x = ((((uint32_t)((v_x & 67108860u) - v_p)) & 67108860u) | 1207959553u); + v_s.ptr[0u] = ((uint8_t)((v_x >> 24u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 0u))); + } + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + self->private_impl.f_bcj_pos = v_p; + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_06_ia64 + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_06_ia64( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_mask = 0; + uint32_t v_slot = 0; + uint32_t v_bit_pos = 0; + uint32_t v_byte_pos = 0; + uint32_t v_bit_res = 0; + uint64_t v_x = 0; + uint32_t v_j = 0; + uint64_t v_norm = 0; + uint32_t v_addr = 0; + + v_s = a_dst_slice; + v_p = self->private_impl.f_bcj_pos; + while (((uint64_t)(v_s.len)) >= 16u) { + v_mask = ((uint32_t)(WUFFS_XZ__FILTER_06_IA64_BRANCH_TABLE[((uint8_t)(v_s.ptr[0u] & 31u))])); + v_slot = 0u; + while (true) { + do { + if (((v_mask >> v_slot) & 1u) == 0u) { + break; + } + v_bit_pos = ((v_slot * 41u) + 5u); + v_byte_pos = (v_bit_pos >> 3u); + v_bit_res = (v_bit_pos & 7u); + v_x = 0u; + v_j = 0u; + while (v_j < 6u) { + v_x |= (((uint64_t)(v_s.ptr[(v_j + v_byte_pos)])) << (8u * v_j)); + v_j += 1u; + } + v_norm = (v_x >> v_bit_res); + if ((((v_norm >> 37u) & 15u) != 5u) || (((v_norm >> 9u) & 7u) != 0u)) { + break; + } + v_addr = ((uint32_t)(((v_norm >> 13u) & 1048575u))); + v_addr |= (((uint32_t)(((v_norm >> 36u) & 1u))) << 20u); + v_addr <<= 4u; + v_addr -= v_p; + v_addr >>= 4u; + v_norm &= 18446743996400148479u; + v_norm |= (((uint64_t)((v_addr & 1048575u))) << 13u); + v_norm |= (((uint64_t)((v_addr & 1048576u))) << 16u); + v_x &= ((((uint64_t)(1u)) << v_bit_res) - 1u); + v_x |= ((uint64_t)(v_norm << v_bit_res)); + v_j = 0u; + while (v_j < 6u) { + v_s.ptr[(v_j + v_byte_pos)] = ((uint8_t)((v_x >> (8u * v_j)))); + v_j += 1u; + } + } while (0); + if (v_slot >= 2u) { + break; + } + v_slot += 1u; + } + v_p += 16u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 16u); + } + self->private_impl.f_bcj_pos = v_p; + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_07_arm + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_07_arm( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + + v_s = a_dst_slice; + v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 8u)); + while (((uint64_t)(v_s.len)) >= 4u) { + if (v_s.ptr[3u] == 235u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) | + (((uint32_t)(v_s.ptr[1u])) << 8u) | + (((uint32_t)(v_s.ptr[2u])) << 16u) | + (((uint32_t)(v_s.ptr[3u])) << 24u)); + v_x = (((uint32_t)(((v_x & 16777215u) << 2u) - v_p)) >> 2u); + v_s.ptr[0u] = ((uint8_t)((v_x >> 0u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 16u))); + } + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 8u)); + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_08_armthumb + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_08_armthumb( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + uint32_t v_y = 0; + + v_s = a_dst_slice; + v_p = ((uint32_t)(self->private_impl.f_bcj_pos + 4u)); + while (((uint64_t)(v_s.len)) >= 4u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) | + (((uint32_t)(v_s.ptr[1u])) << 8u) | + (((uint32_t)(v_s.ptr[2u])) << 16u) | + (((uint32_t)(v_s.ptr[3u])) << 24u)); + if ((v_x & 4160813056u) != 4160811008u) { + v_p += 2u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); + continue; + } + v_y = ((((uint32_t)(((uint8_t)(v_s.ptr[0u] & 255u)))) << 11u) | + (((uint32_t)(((uint8_t)(v_s.ptr[1u] & 7u)))) << 19u) | + (((uint32_t)(((uint8_t)(v_s.ptr[2u] & 255u)))) << 0u) | + (((uint32_t)(((uint8_t)(v_s.ptr[3u] & 7u)))) << 8u)); + v_y = (((uint32_t)(((uint32_t)(v_y << 1u)) - v_p)) >> 1u); + v_s.ptr[0u] = ((uint8_t)((v_y >> 11u))); + v_s.ptr[1u] = ((uint8_t)((((v_y >> 19u) & 7u) | 240u))); + v_s.ptr[2u] = ((uint8_t)((v_y >> 0u))); + v_s.ptr[3u] = ((uint8_t)((((v_y >> 8u) & 7u) | 248u))); + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + self->private_impl.f_bcj_pos = ((uint32_t)(v_p - 4u)); + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_09_sparc + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_09_sparc( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + + v_s = a_dst_slice; + v_p = self->private_impl.f_bcj_pos; + while (((uint64_t)(v_s.len)) >= 4u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 24u) | + (((uint32_t)(v_s.ptr[1u])) << 16u) | + (((uint32_t)(v_s.ptr[2u])) << 8u) | + (((uint32_t)(v_s.ptr[3u])) << 0u)); + if (((v_x >> 22u) == 256u) || ((v_x >> 22u) == 511u)) { + v_x = (((uint32_t)(((uint32_t)(v_x << 2u)) - v_p)) >> 2u); + v_x = ((1073741824u - (v_x & 4194304u)) | 1073741824u | (v_x & 4194303u)); + v_s.ptr[0u] = ((uint8_t)((v_x >> 24u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 0u))); + } + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + self->private_impl.f_bcj_pos = v_p; + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_0a_arm64 + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_0a_arm64( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + uint32_t v_y = 0; + + v_s = a_dst_slice; + v_p = self->private_impl.f_bcj_pos; + while (((uint64_t)(v_s.len)) >= 4u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) | + (((uint32_t)(v_s.ptr[1u])) << 8u) | + (((uint32_t)(v_s.ptr[2u])) << 16u) | + (((uint32_t)(v_s.ptr[3u])) << 24u)); + if ((v_x >> 26u) == 37u) { + v_y = ((uint32_t)(v_x - (v_p >> 2u))); + v_x = (2483027968u | (v_y & 67108863u)); + v_s.ptr[0u] = ((uint8_t)((v_x >> 0u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 24u))); + } else if ((v_x & 2667577344u) == 2415919104u) { + v_y = (((v_x >> 29u) & 3u) | ((v_x >> 3u) & 2097148u)); + if ((((uint32_t)(v_y + 131072u)) & 1835008u) == 0u) { + v_y -= (v_p >> 12u); + v_x &= 2415919135u; + v_x |= ((v_y & 3u) << 29u); + v_x |= ((v_y & 262140u) << 3u); + v_x |= (((uint32_t)(0u - (v_y & 131072u))) & 14680064u); + v_s.ptr[0u] = ((uint8_t)((v_x >> 0u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 24u))); + } + } + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + } + self->private_impl.f_bcj_pos = v_p; + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.apply_filter_0b_riscv + +WUFFS_BASE__GENERATED_C_CODE +static uint8_t +wuffs_xz__decoder__apply_filter_0b_riscv( + wuffs_xz__decoder* self, + wuffs_base__slice_u8 a_dst_slice) { + wuffs_base__slice_u8 v_s = {0}; + uint32_t v_p = 0; + uint32_t v_x = 0; + uint32_t v_x27 = 0; + uint32_t v_y = 0; + uint32_t v_addr = 0; + + v_s = a_dst_slice; + v_p = self->private_impl.f_bcj_pos; + while (((uint64_t)(v_s.len)) >= 8u) { + if (v_s.ptr[0u] == 239u) { + if (((uint8_t)(v_s.ptr[1u] & 13u)) != 0u) { + v_p += 2u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); + continue; + } + v_addr = ((((uint32_t)(((uint8_t)(v_s.ptr[1u] & 240u)))) << 13u) | (((uint32_t)(v_s.ptr[2u])) << 9u) | (((uint32_t)(v_s.ptr[3u])) << 1u)); + v_addr -= v_p; + v_s.ptr[1u] = ((uint8_t)(((uint8_t)(v_s.ptr[1u] & 15u)) | ((uint8_t)(((v_addr >> 8u) & 240u))))); + v_s.ptr[2u] = ((uint8_t)((((v_addr >> 16u) & 15u) | ((v_addr >> 7u) & 16u) | (((uint32_t)(v_addr << 4u)) & 224u)))); + v_s.ptr[3u] = ((uint8_t)((((v_addr >> 4u) & 127u) | ((v_addr >> 13u) & 128u)))); + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + continue; + } else if (((uint8_t)(v_s.ptr[0u] & 127u)) == 23u) { + v_x = ((((uint32_t)(v_s.ptr[0u])) << 0u) | + (((uint32_t)(v_s.ptr[1u])) << 8u) | + (((uint32_t)(v_s.ptr[2u])) << 16u) | + (((uint32_t)(v_s.ptr[3u])) << 24u)); + if ((v_x & 3712u) != 0u) { + v_y = ((((uint32_t)(v_s.ptr[4u])) << 0u) | + (((uint32_t)(v_s.ptr[5u])) << 8u) | + (((uint32_t)(v_s.ptr[6u])) << 16u) | + (((uint32_t)(v_s.ptr[7u])) << 24u)); + if (((((uint32_t)(v_x << 8u)) ^ ((uint32_t)(v_y - 3u))) & 1015811u) != 0u) { + v_p += 6u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u); + continue; + } + v_addr = ((v_x & 4294963200u) | (v_y >> 20u)); + v_x = (279u | ((uint32_t)(v_y << 12u))); + v_s.ptr[0u] = ((uint8_t)((v_x >> 0u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 24u))); + v_s.ptr[4u] = ((uint8_t)((v_addr >> 0u))); + v_s.ptr[5u] = ((uint8_t)((v_addr >> 8u))); + v_s.ptr[6u] = ((uint8_t)((v_addr >> 16u))); + v_s.ptr[7u] = ((uint8_t)((v_addr >> 24u))); + v_p += 8u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u); + continue; + } + v_x27 = (v_x >> 27u); + if (((uint32_t)(((uint32_t)(v_x - 12567u)) << 18u)) >= (v_x27 & 29u)) { + v_p += 4u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u); + continue; + } + v_addr = ((((uint32_t)(v_s.ptr[4u])) << 24u) | + (((uint32_t)(v_s.ptr[5u])) << 16u) | + (((uint32_t)(v_s.ptr[6u])) << 8u) | + (((uint32_t)(v_s.ptr[7u])) << 0u)); + v_addr -= v_p; + v_y = ((v_x >> 12u) | ((uint32_t)(v_addr << 20u))); + v_x = (23u | (v_x27 << 7u) | (((uint32_t)(v_addr + 2048u)) & 4294963200u)); + v_s.ptr[0u] = ((uint8_t)((v_x >> 0u))); + v_s.ptr[1u] = ((uint8_t)((v_x >> 8u))); + v_s.ptr[2u] = ((uint8_t)((v_x >> 16u))); + v_s.ptr[3u] = ((uint8_t)((v_x >> 24u))); + v_s.ptr[4u] = ((uint8_t)((v_y >> 0u))); + v_s.ptr[5u] = ((uint8_t)((v_y >> 8u))); + v_s.ptr[6u] = ((uint8_t)((v_y >> 16u))); + v_s.ptr[7u] = ((uint8_t)((v_y >> 24u))); + v_p += 8u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u); + continue; + } + v_p += 2u; + v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u); + } + self->private_impl.f_bcj_pos = v_p; + return ((uint8_t)(((uint64_t)(v_s.len)))); +} + +// -------- func xz.decoder.get_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash32__hasher__get_quirk( - const wuffs_xxhash32__hasher* self, +wuffs_xz__decoder__get_quirk( + const wuffs_xz__decoder* self, uint32_t a_key) { if (!self) { return 0; @@ -61527,15 +77160,24 @@ wuffs_xxhash32__hasher__get_quirk( return 0; } + if (a_key == 1u) { + if (self->private_impl.f_ignore_checksum) { + return 1u; + } + } else if (a_key == 2021322752u) { + if (self->private_impl.f_standalone_format) { + return 1u; + } + } return 0u; } -// -------- func xxhash32.hasher.set_quirk +// -------- func xz.decoder.set_quirk WUFFS_BASE__GENERATED_C_CODE WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_xxhash32__hasher__set_quirk( - wuffs_xxhash32__hasher* self, +wuffs_xz__decoder__set_quirk( + wuffs_xz__decoder* self, uint32_t a_key, uint64_t a_value) { if (!self) { @@ -61548,747 +77190,1667 @@ wuffs_xxhash32__hasher__set_quirk( : wuffs_base__error__initialize_not_called); } + if (a_key == 1u) { + self->private_impl.f_ignore_checksum = (a_value > 0u); + return wuffs_base__make_status(NULL); + } else if (a_key == 2021322752u) { + self->private_impl.f_standalone_format = (a_value > 0u); + return wuffs_base__make_status(NULL); + } return wuffs_base__make_status(wuffs_base__error__unsupported_option); } -// -------- func xxhash32.hasher.update +// -------- func xz.decoder.dst_history_retain_length WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_xxhash32__hasher__update( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x) { +WUFFS_BASE__MAYBE_STATIC wuffs_base__optional_u63 +wuffs_xz__decoder__dst_history_retain_length( + const wuffs_xz__decoder* self) { if (!self) { - return wuffs_base__make_empty_struct(); + return wuffs_base__utility__make_optional_u63(false, 0u); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__make_optional_u63(false, 0u); + } + + return wuffs_lzma__decoder__dst_history_retain_length(&self->private_data.f_lzma); +} + +// -------- func xz.decoder.workbuf_len + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 +wuffs_xz__decoder__workbuf_len( + const wuffs_xz__decoder* self) { + if (!self) { + return wuffs_base__utility__empty_range_ii_u64(); + } + if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && + (self->private_impl.magic != WUFFS_BASE__DISABLED)) { + return wuffs_base__utility__empty_range_ii_u64(); + } + + return wuffs_lzma__decoder__workbuf_len(&self->private_data.f_lzma); +} + +// -------- func xz.decoder.transform_io + +WUFFS_BASE__GENERATED_C_CODE +WUFFS_BASE__MAYBE_STATIC wuffs_base__status +wuffs_xz__decoder__transform_io( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + if (!self) { + return wuffs_base__make_status(wuffs_base__error__bad_receiver); } if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + return wuffs_base__make_status( + (self->private_impl.magic == WUFFS_BASE__DISABLED) + ? wuffs_base__error__disabled_by_previous_error + : wuffs_base__error__initialize_not_called); + } + if (!a_dst || !a_src) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__bad_argument); + } + if ((self->private_impl.active_coroutine != 0) && + (self->private_impl.active_coroutine != 1)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; + return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls); + } + self->private_impl.active_coroutine = 0; + wuffs_base__status status = wuffs_base__make_status(NULL); + + wuffs_base__status v_status = wuffs_base__make_status(NULL); + + uint32_t coro_susp_point = self->private_impl.p_transform_io; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + while (true) { + { + wuffs_base__status t_0 = wuffs_xz__decoder__do_transform_io(self, a_dst, a_src, a_workbuf); + v_status = t_0; + } + if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) { + status = wuffs_base__make_status(wuffs_xz__error__truncated_input); + goto exit; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1); + } + + ok: + self->private_impl.p_transform_io = 0; + goto exit; } - wuffs_base__slice_u8 v_remaining = {0}; + goto suspend; + suspend: + self->private_impl.p_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0; - if ((self->private_impl.f_length_modulo_u32 == 0u) && ! self->private_impl.f_length_overflows_u32) { - self->private_impl.f_v0 = 606290984u; - self->private_impl.f_v1 = 2246822519u; - self->private_impl.f_v2 = 0u; - self->private_impl.f_v3 = 1640531535u; - } - while (((uint64_t)(a_x.len)) > 0u) { - v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u); - if (((uint64_t)(a_x.len)) > 16777216u) { - v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 16777216u); - a_x = wuffs_base__slice_u8__subslice_j(a_x, 16777216u); - } - wuffs_xxhash32__hasher__up(self, a_x); - a_x = v_remaining; + goto exit; + exit: + if (wuffs_base__status__is_error(&status)) { + self->private_impl.magic = WUFFS_BASE__DISABLED; } - return wuffs_base__make_empty_struct(); + return status; } -// -------- func xxhash32.hasher.update_u32 +// -------- func xz.decoder.do_transform_io WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_xxhash32__hasher__update_u32( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return 0; - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; - } +static wuffs_base__status +wuffs_xz__decoder__do_transform_io( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_dst, + wuffs_base__io_buffer* a_src, + wuffs_base__slice_u8 a_workbuf) { + wuffs_base__status status = wuffs_base__make_status(NULL); - wuffs_xxhash32__hasher__update(self, a_x); - return wuffs_xxhash32__hasher__checksum_u32(self); -} + uint64_t v_header_magic = 0; + uint64_t v_dmark = 0; + uint64_t v_smark = 0; + uint8_t v_i8 = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_checksum32_have = 0; + uint32_t v_checksum32_want = 0; + uint64_t v_checksum64_have = 0; + uint64_t v_checksum64_want = 0; + wuffs_base__bitvec256 v_checksum256_have = {0}; + uint64_t v_compressed_size = 0; + uint64_t v_uncompressed_size = 0; + uint32_t v_hash = 0; + uint8_t v_c8 = 0; + uint32_t v_c32 = 0; + uint16_t v_footer_magic = 0; -// -------- func xxhash32.hasher.up + uint8_t* iop_a_dst = NULL; + uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_dst && a_dst->data.ptr) { + io0_a_dst = a_dst->data.ptr; + io1_a_dst = io0_a_dst + a_dst->meta.wi; + iop_a_dst = io1_a_dst; + io2_a_dst = io0_a_dst + a_dst->data.len; + if (a_dst->meta.closed) { + io2_a_dst = iop_a_dst; + } + } + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_xxhash32__hasher__up( - wuffs_xxhash32__hasher* self, - wuffs_base__slice_u8 a_x) { - uint32_t v_new_lmu = 0; - uint32_t v_buf_u32 = 0; - uint32_t v_buf_len = 0; - uint32_t v_v0 = 0; - uint32_t v_v1 = 0; - uint32_t v_v2 = 0; - uint32_t v_v3 = 0; - wuffs_base__slice_u8 v_p = {0}; + uint32_t coro_susp_point = self->private_impl.p_do_transform_io; + if (coro_susp_point) { + v_checksum32_have = self->private_data.s_do_transform_io.v_checksum32_have; + v_checksum32_want = self->private_data.s_do_transform_io.v_checksum32_want; + v_checksum256_have = self->private_data.s_do_transform_io.v_checksum256_have; + v_compressed_size = self->private_data.s_do_transform_io.v_compressed_size; + v_uncompressed_size = self->private_data.s_do_transform_io.v_uncompressed_size; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - v_new_lmu = ((uint32_t)(self->private_impl.f_length_modulo_u32 + ((uint32_t)(((uint64_t)(a_x.len)))))); - self->private_impl.f_length_overflows_u32 = ((v_new_lmu < self->private_impl.f_length_modulo_u32) || self->private_impl.f_length_overflows_u32); - self->private_impl.f_length_modulo_u32 = v_new_lmu; - while (true) { - if (self->private_impl.f_buf_len >= 16u) { - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) | - (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u)); - v_v0 = ((uint32_t)(self->private_impl.f_v0 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u)); - self->private_impl.f_v0 = ((uint32_t)(v_v0 * 2654435761u)); - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) | - (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u)); - v_v1 = ((uint32_t)(self->private_impl.f_v1 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u)); - self->private_impl.f_v1 = ((uint32_t)(v_v1 * 2654435761u)); - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) | - (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u)); - v_v2 = ((uint32_t)(self->private_impl.f_v2 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u)); - self->private_impl.f_v2 = ((uint32_t)(v_v2 * 2654435761u)); - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[12u])) | - (((uint32_t)(self->private_impl.f_buf_data[13u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[14u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[15u])) << 24u)); - v_v3 = ((uint32_t)(self->private_impl.f_v3 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u)); - self->private_impl.f_v3 = ((uint32_t)(v_v3 * 2654435761u)); - self->private_impl.f_buf_len = 0u; - break; - } - if (((uint64_t)(a_x.len)) <= 0u) { - return wuffs_base__make_empty_struct(); - } - self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u]; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint64_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) { + t_0 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))); + iop_a_src += 6; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 40) { + t_0 = ((uint64_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_header_magic = t_0; + } + if (v_header_magic != 388031461373u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_header); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint64_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) { + t_1 = ((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))); + iop_a_src += 6; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 40) { + t_1 = ((uint64_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_header_magic = t_1; + } + if (v_header_magic == 72400582410240u) { + self->private_impl.f_checksummer = 0u; + } else if (v_header_magic == 60327687946496u) { + self->private_impl.f_checksummer = 1u; + } else if (v_header_magic == 77742513456128u) { + self->private_impl.f_checksummer = 2u; + } else if (v_header_magic == 177077137508864u) { + self->private_impl.f_checksummer = 3u; + } else if ((v_header_magic & 61695u) != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_header); + goto exit; + } else { + v_header_magic = (15u & (v_header_magic >> 8u)); + if ((v_header_magic != 0u) && + (v_header_magic != 1u) && + (v_header_magic != 4u) && + (v_header_magic != 10u)) { + status = wuffs_base__make_status(wuffs_xz__error__unsupported_checksum_algorithm); + goto exit; + } + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + self->private_impl.f_flags = ((uint16_t)(v_header_magic)); + self->private_impl.f_num_actual_blocks = 0u; + while (true) { + if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5); + continue; + } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) == 0u) { + break; + } + self->private_impl.f_num_actual_blocks += 1u; + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + self->private_impl.f_compressed_size_for_index = 4u; + while (true) { + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_2 = wuffs_xz__decoder__decode_block_header_with_padding(self, a_src); + v_status = t_2; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)))); + if ( ! self->private_impl.f_ignore_checksum) { + v_checksum32_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + uint32_t t_3; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3; + if (num_bits_3 == 24) { + t_3 = ((uint32_t)(*scratch)); + break; + } + num_bits_3 += 8u; + *scratch |= ((uint64_t)(num_bits_3)) << 56; + } + } + v_checksum32_want = t_3; + } + if (self->private_impl.f_ignore_checksum) { + } else if (v_checksum32_have != v_checksum32_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } else { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_private_impl__ignore_status(wuffs_crc64__ecma_hasher__initialize(&self->private_data.f_crc64, + sizeof (wuffs_crc64__ecma_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + wuffs_private_impl__ignore_status(wuffs_sha256__hasher__initialize(&self->private_data.f_sha256, + sizeof (wuffs_sha256__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + v_compressed_size = 0u; + v_uncompressed_size = 0u; + while (true) { + if (((uint64_t)(self->private_impl.f_bcj_undo_index)) > ((uint64_t)(io2_a_dst - iop_a_dst))) { + status = wuffs_base__make_status(wuffs_base__suspension__short_write); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9); + continue; + } + v_dmark = ((uint64_t)(iop_a_dst - io0_a_dst)); + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + if (self->private_impl.f_num_non_final_filters == 0u) { + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_4 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf); + v_status = t_4; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + } else { + if (self->private_impl.f_bcj_undo_index > 0u) { + wuffs_private_impl__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,wuffs_base__make_slice_u8(self->private_data.f_filter_data[0u], self->private_impl.f_bcj_undo_index)); + self->private_impl.f_bcj_undo_index = 0u; + } + { + uint8_t* o_0_io0_a_dst = io0_a_dst; + uint8_t* o_0_io1_a_dst = io1_a_dst; + io0_a_dst = iop_a_dst; + io1_a_dst = iop_a_dst; + wuffs_base__io_buffer o_0_a_dst; + if (a_dst) { + memcpy(&o_0_a_dst, a_dst, sizeof(*a_dst)); + size_t wi0 = a_dst->meta.wi; + a_dst->data.ptr += wi0; + a_dst->data.len -= wi0; + a_dst->meta.ri = 0; + a_dst->meta.wi = 0; + a_dst->meta.pos = wuffs_base__u64__sat_add(a_dst->meta.pos, wi0); + } + { + if (a_dst) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + } + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_5 = wuffs_lzma__decoder__transform_io(&self->private_data.f_lzma, a_dst, a_src, a_workbuf); + v_status = t_5; + if (a_dst) { + iop_a_dst = a_dst->data.ptr + a_dst->meta.wi; + } + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if (a_dst) { + memcpy(a_dst, &o_0_a_dst, sizeof(*a_dst)); + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); + io0_a_dst = o_0_io0_a_dst; + io1_a_dst = o_0_io1_a_dst; + } + } + self->private_impl.f_bcj_undo_index = wuffs_xz__decoder__apply_non_final_filters(self, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + if ((self->private_impl.f_bcj_undo_index > 0u) && ! wuffs_base__status__is_ok(&v_status)) { + v_i8 = ((uint8_t)(self->private_impl.f_bcj_undo_index - 1u)); + while (true) { + if ( ! (iop_a_dst > io1_a_dst)) { + status = wuffs_base__make_status(wuffs_xz__error__internal_error_inconsistent_bcj_filter_state); + goto exit; + } + self->private_data.f_filter_data[0u][v_i8] = iop_a_dst[-1]; + iop_a_dst--; + if (v_i8 <= 0u) { + break; + } #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif - self->private_impl.f_buf_len += 1u; + v_i8 -= 1u; #if defined(__GNUC__) #pragma GCC diagnostic pop #endif - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); - } - v_buf_len = ((uint32_t)((self->private_impl.f_buf_len & 15u))); - v_v0 = self->private_impl.f_v0; - v_v1 = self->private_impl.f_v1; - v_v2 = self->private_impl.f_v2; - v_v3 = self->private_impl.f_v3; - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 16; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16); - while (v_p.ptr < i_end0_p) { - v_buf_u32 = (((uint32_t)(v_p.ptr[0u])) | - (((uint32_t)(v_p.ptr[1u])) << 8u) | - (((uint32_t)(v_p.ptr[2u])) << 16u) | - (((uint32_t)(v_p.ptr[3u])) << 24u)); - v_v0 = ((uint32_t)(v_v0 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u)); - v_v0 = ((uint32_t)(v_v0 * 2654435761u)); - v_buf_u32 = (((uint32_t)(v_p.ptr[4u])) | - (((uint32_t)(v_p.ptr[5u])) << 8u) | - (((uint32_t)(v_p.ptr[6u])) << 16u) | - (((uint32_t)(v_p.ptr[7u])) << 24u)); - v_v1 = ((uint32_t)(v_v1 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u)); - v_v1 = ((uint32_t)(v_v1 * 2654435761u)); - v_buf_u32 = (((uint32_t)(v_p.ptr[8u])) | - (((uint32_t)(v_p.ptr[9u])) << 8u) | - (((uint32_t)(v_p.ptr[10u])) << 16u) | - (((uint32_t)(v_p.ptr[11u])) << 24u)); - v_v2 = ((uint32_t)(v_v2 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u)); - v_v2 = ((uint32_t)(v_v2 * 2654435761u)); - v_buf_u32 = (((uint32_t)(v_p.ptr[12u])) | - (((uint32_t)(v_p.ptr[13u])) << 8u) | - (((uint32_t)(v_p.ptr[14u])) << 16u) | - (((uint32_t)(v_p.ptr[15u])) << 24u)); - v_v3 = ((uint32_t)(v_v3 + ((uint32_t)(v_buf_u32 * 2246822519u)))); - v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u)); - v_v3 = ((uint32_t)(v_v3 * 2654435761u)); - v_p.ptr += 16; - } - v_p.len = 1; - uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end1_p) { - self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u]; - v_buf_len = ((v_buf_len + 1u) & 15u); - v_p.ptr += 1; + } + } + } + v_compressed_size += wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src))); + v_uncompressed_size += wuffs_private_impl__io__count_since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst))); + if (self->private_impl.f_ignore_checksum) { + } else if (self->private_impl.f_checksummer == 1u) { + wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + } else if (self->private_impl.f_checksummer == 2u) { + wuffs_crc64__ecma_hasher__update(&self->private_data.f_crc64, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + } else if (self->private_impl.f_checksummer == 3u) { + wuffs_sha256__hasher__update(&self->private_data.f_sha256, wuffs_private_impl__io__since(v_dmark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10); + } + if ((self->private_impl.f_block_has_compressed_size && (self->private_impl.f_block_compressed_size != v_compressed_size)) || (self->private_impl.f_block_has_uncompressed_size && (self->private_impl.f_block_uncompressed_size != v_uncompressed_size))) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, v_compressed_size); + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_compressed_size_for_index, ((uint64_t)(WUFFS_XZ__CHECKSUM_LENGTH[self->private_impl.f_checksummer]))); + self->private_impl.f_verification_have_total_sizes[0u] += self->private_impl.f_compressed_size_for_index; + v_hash = ((uint32_t)((self->private_impl.f_compressed_size_for_index ^ (self->private_impl.f_compressed_size_for_index >> 32u)))); + v_hash *= 3432918353u; + v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u)); + v_hash *= 461845907u; + v_hash ^= self->private_impl.f_verification_have_hashed_sizes[0u]; + v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u)); + self->private_impl.f_verification_have_hashed_sizes[0u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u)); + self->private_impl.f_verification_have_total_sizes[1u] += v_uncompressed_size; + v_hash = ((uint32_t)((v_uncompressed_size ^ (v_uncompressed_size >> 32u)))); + v_hash *= 3432918353u; + v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u)); + v_hash *= 461845907u; + v_hash ^= self->private_impl.f_verification_have_hashed_sizes[1u]; + v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u)); + self->private_impl.f_verification_have_hashed_sizes[1u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u)); + while ((v_compressed_size & 3u) != 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_padding); + goto exit; + } + v_compressed_size += 1u; + } + self->private_impl.f_lzma_needs_reset = true; + if (self->private_impl.f_ignore_checksum) { + self->private_data.s_do_transform_io.scratch = ((uint32_t)(WUFFS_XZ__CHECKSUM_LENGTH[self->private_impl.f_checksummer])); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (self->private_data.s_do_transform_io.scratch > ((uint64_t)(io2_a_src - iop_a_src))) { + self->private_data.s_do_transform_io.scratch -= ((uint64_t)(io2_a_src - iop_a_src)); + iop_a_src = io2_a_src; + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + iop_a_src += self->private_data.s_do_transform_io.scratch; + } else if (self->private_impl.f_checksummer == 1u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13); + uint32_t t_7; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; + if (num_bits_7 == 24) { + t_7 = ((uint32_t)(*scratch)); + break; + } + num_bits_7 += 8u; + *scratch |= ((uint64_t)(num_bits_7)) << 56; + } + } + v_checksum32_want = t_7; + } + v_checksum32_have = wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32); + if (v_checksum32_have != v_checksum32_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + } else if (self->private_impl.f_checksummer == 2u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15); + uint64_t t_8; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_8 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8; + if (num_bits_8 == 56) { + t_8 = ((uint64_t)(*scratch)); + break; + } + num_bits_8 += 8u; + *scratch |= ((uint64_t)(num_bits_8)) << 56; + } + } + v_checksum64_want = t_8; + } + v_checksum64_have = wuffs_crc64__ecma_hasher__checksum_u64(&self->private_data.f_crc64); + if (v_checksum64_have != v_checksum64_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + } else if (self->private_impl.f_checksummer == 3u) { + v_checksum256_have = wuffs_sha256__hasher__checksum_bitvec256(&self->private_data.f_sha256); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17); + uint64_t t_9; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_9 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_9 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_9); + if (num_bits_9 == 56) { + t_9 = ((uint64_t)(*scratch >> 0)); + break; + } + num_bits_9 += 8u; + *scratch |= ((uint64_t)(num_bits_9)); + } + } + v_checksum64_want = t_9; + } + if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 3u) != v_checksum64_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19); + uint64_t t_10; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_10 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_10 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_10); + if (num_bits_10 == 56) { + t_10 = ((uint64_t)(*scratch >> 0)); + break; + } + num_bits_10 += 8u; + *scratch |= ((uint64_t)(num_bits_10)); + } + } + v_checksum64_want = t_10; + } + if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 2u) != v_checksum64_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21); + uint64_t t_11; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_11 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_11 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_11); + if (num_bits_11 == 56) { + t_11 = ((uint64_t)(*scratch >> 0)); + break; + } + num_bits_11 += 8u; + *scratch |= ((uint64_t)(num_bits_11)); + } + } + v_checksum64_want = t_11; + } + if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 1u) != v_checksum64_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23); + uint64_t t_12; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) { + t_12 = wuffs_base__peek_u64be__no_bounds_check(iop_a_src); + iop_a_src += 8; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_12 = ((uint32_t)(*scratch & 0xFFu)); + *scratch >>= 8; + *scratch <<= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_12); + if (num_bits_12 == 56) { + t_12 = ((uint64_t)(*scratch >> 0)); + break; + } + num_bits_12 += 8u; + *scratch |= ((uint64_t)(num_bits_12)); + } + } + v_checksum64_want = t_12; + } + if (wuffs_base__bitvec256__get_u64(&v_checksum256_have, 0u) != v_checksum64_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + } + } + self->private_impl.f_backwards_size = 0u; + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + while (true) { + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_13 = wuffs_xz__decoder__verify_index(self, a_src); + v_status = t_13; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u64__sat_add_indirect(&self->private_impl.f_backwards_size, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)))); + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(25); + } + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_XZ__ZEROES), (3u & ((uint64_t)(0u - (3u & self->private_impl.f_backwards_size)))))); + } + while ((self->private_impl.f_backwards_size & 3u) != 0u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_14 = *iop_a_src++; + v_c8 = t_14; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + self->private_impl.f_backwards_size += 1u; + } + self->private_impl.f_backwards_size >>= 2u; + if ((self->private_impl.f_backwards_size == 0u) || (self->private_impl.f_backwards_size > 4294967295u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27); + uint32_t t_15; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15; + if (num_bits_15 == 24) { + t_15 = ((uint32_t)(*scratch)); + break; + } + num_bits_15 += 8u; + *scratch |= ((uint64_t)(num_bits_15)) << 56; + } + } + v_checksum32_want = t_15; + } + if (self->private_impl.f_ignore_checksum) { + } else if (v_checksum32_want != wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } else { + wuffs_private_impl__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32, + sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29); + uint32_t t_16; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16; + if (num_bits_16 == 24) { + t_16 = ((uint32_t)(*scratch)); + break; + } + num_bits_16 += 8u; + *scratch |= ((uint64_t)(num_bits_16)) << 56; + } + } + v_checksum32_want = t_16; + } + while (true) { + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_17 = wuffs_xz__decoder__verify_footer(self, a_src); + v_status = t_17; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + if ( ! self->private_impl.f_ignore_checksum) { + wuffs_crc32__ieee_hasher__update(&self->private_data.f_crc32, wuffs_private_impl__io__since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src)); + } + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(31); + } + if ( ! self->private_impl.f_ignore_checksum && (v_checksum32_want != wuffs_crc32__ieee_hasher__checksum_u32(&self->private_data.f_crc32))) { + status = wuffs_base__make_status(wuffs_xz__error__bad_checksum); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32); + uint16_t t_18; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_18 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src); + iop_a_src += 2; + } else { + self->private_data.s_do_transform_io.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_do_transform_io.scratch; + uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18; + if (num_bits_18 == 8) { + t_18 = ((uint16_t)(*scratch)); + break; + } + num_bits_18 += 8u; + *scratch |= ((uint64_t)(num_bits_18)) << 56; + } + } + v_footer_magic = t_18; + } + if (v_footer_magic != 23129u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_footer); + goto exit; + } + if ( ! self->private_impl.f_standalone_format) { + break; + } + while (true) { + while (((uint64_t)(io2_a_src - iop_a_src)) < 4u) { + if (a_src && a_src->meta.closed) { + if (((uint64_t)(io2_a_src - iop_a_src)) == 0u) { + goto label__streams__break; + } else { + status = wuffs_base__make_status(wuffs_xz__error__truncated_input); + goto exit; + } + } + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(34); + } + v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + if (v_c32 == 1484404733u) { + break; + } else if (v_c32 != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_header_concatenated_stream); + goto exit; + } + iop_a_src += 4u; + } + self->private_impl.f_started_verify_index = false; } - v_p.len = 0; - } - self->private_impl.f_buf_len = ((uint8_t)(v_buf_len)); - self->private_impl.f_v0 = v_v0; - self->private_impl.f_v1 = v_v1; - self->private_impl.f_v2 = v_v2; - self->private_impl.f_v3 = v_v3; - return wuffs_base__make_empty_struct(); -} - -// -------- func xxhash32.hasher.checksum_u32 + label__streams__break:; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint32_t -wuffs_xxhash32__hasher__checksum_u32( - const wuffs_xxhash32__hasher* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + ok: + self->private_impl.p_do_transform_io = 0; + goto exit; } - uint32_t v_ret = 0; - uint32_t v_i = 0; - uint32_t v_n = 0; - uint32_t v_buf_u32 = 0; + goto suspend; + suspend: + self->private_impl.p_do_transform_io = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_do_transform_io.v_checksum32_have = v_checksum32_have; + self->private_data.s_do_transform_io.v_checksum32_want = v_checksum32_want; + self->private_data.s_do_transform_io.v_checksum256_have = v_checksum256_have; + self->private_data.s_do_transform_io.v_compressed_size = v_compressed_size; + self->private_data.s_do_transform_io.v_uncompressed_size = v_uncompressed_size; - if ((self->private_impl.f_length_modulo_u32 >= 16u) || self->private_impl.f_length_overflows_u32) { - v_ret += (((uint32_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 31u)); - v_ret += (((uint32_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 25u)); - v_ret += (((uint32_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 20u)); - v_ret += (((uint32_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 14u)); - v_ret += self->private_impl.f_length_modulo_u32; - } else { - v_ret += 374761393u; - v_ret += self->private_impl.f_length_modulo_u32; - } - v_n = 16u; - v_n = wuffs_base__u32__min(v_n, ((uint32_t)(self->private_impl.f_buf_len))); - if (4u <= v_n) { - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) | - (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u)); - v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); - v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); - v_ret *= 668265263u; - v_i = 4u; - } - if (8u <= v_n) { - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) | - (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u)); - v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); - v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); - v_ret *= 668265263u; - v_i = 8u; - } - if (12u <= v_n) { - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) | - (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u)); - v_ret += ((uint32_t)(v_buf_u32 * 3266489917u)); - v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u)); - v_ret *= 668265263u; - v_i = 12u; + goto exit; + exit: + if (a_dst && a_dst->data.ptr) { + a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr)); } - while (v_i < v_n) { - v_ret += ((uint32_t)(((uint32_t)(self->private_impl.f_buf_data[v_i])) * 374761393u)); - v_ret = (((uint32_t)(v_ret << 11u)) | (v_ret >> 21u)); - v_ret *= 2654435761u; - v_i += 1u; + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_ret ^= (v_ret >> 15u); - v_ret *= 2246822519u; - v_ret ^= (v_ret >> 13u); - v_ret *= 3266489917u; - v_ret ^= (v_ret >> 16u); - return v_ret; -} - -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) - -#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) - -// ---------------- Status Codes Implementations -// ---------------- Private Consts + return status; +} -#define WUFFS_XXHASH64__XXH_PRIME64_1 11400714785074694791 +// -------- func xz.decoder.decode_block_header_with_padding -#define WUFFS_XXHASH64__XXH_PRIME64_2 14029467366897019727 +WUFFS_BASE__GENERATED_C_CODE +static wuffs_base__status +wuffs_xz__decoder__decode_block_header_with_padding( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -#define WUFFS_XXHASH64__XXH_PRIME64_3 1609587929392839161 + uint8_t v_c8 = 0; + uint64_t v_padded_size_have = 0; + uint64_t v_padded_size_want = 0; + uint64_t v_smark = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); -#define WUFFS_XXHASH64__XXH_PRIME64_4 9650029242287828579 + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } -#define WUFFS_XXHASH64__XXH_PRIME64_5 2870177450012600261 + uint32_t coro_susp_point = self->private_impl.p_decode_block_header_with_padding; + if (coro_susp_point) { + v_padded_size_have = self->private_data.s_decode_block_header_with_padding.v_padded_size_have; + v_padded_size_want = self->private_data.s_decode_block_header_with_padding.v_padded_size_want; + } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -#define WUFFS_XXHASH64__INITIAL_V0 6983438078262162902 + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + v_padded_size_want = ((uint64_t)((((uint64_t)(v_c8)) * 4u) - 1u)); + while (true) { + v_smark = ((uint64_t)(iop_a_src - io0_a_src)); + { + if (a_src) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } + wuffs_base__status t_1 = wuffs_xz__decoder__decode_block_header_sans_padding(self, a_src); + v_status = t_1; + if (a_src) { + iop_a_src = a_src->data.ptr + a_src->meta.ri; + } + } + wuffs_private_impl__u64__sat_add_indirect(&v_padded_size_have, wuffs_private_impl__io__count_since(v_smark, ((uint64_t)(iop_a_src - io0_a_src)))); + if (wuffs_base__status__is_ok(&v_status)) { + break; + } + status = v_status; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2); + } + if (v_padded_size_have > v_padded_size_want) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + while (v_padded_size_have < v_padded_size_want) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + v_padded_size_have += 1u; + } -#define WUFFS_XXHASH64__INITIAL_V1 14029467366897019727 + ok: + self->private_impl.p_decode_block_header_with_padding = 0; + goto exit; + } -#define WUFFS_XXHASH64__INITIAL_V2 0 + goto suspend; + suspend: + self->private_impl.p_decode_block_header_with_padding = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_block_header_with_padding.v_padded_size_have = v_padded_size_have; + self->private_data.s_decode_block_header_with_padding.v_padded_size_want = v_padded_size_want; -#define WUFFS_XXHASH64__INITIAL_V3 7046029288634856825 + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); + } -// ---------------- Private Initializer Prototypes + return status; +} -// ---------------- Private Function Prototypes +// -------- func xz.decoder.decode_block_header_sans_padding WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_xxhash64__hasher__up( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x); - -// ---------------- VTables - -const wuffs_base__hasher_u64__func_ptrs -wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64 = { - (uint64_t(*)(const void*))(&wuffs_xxhash64__hasher__checksum_u64), - (uint64_t(*)(const void*, - uint32_t))(&wuffs_xxhash64__hasher__get_quirk), - (wuffs_base__status(*)(void*, - uint32_t, - uint64_t))(&wuffs_xxhash64__hasher__set_quirk), - (wuffs_base__empty_struct(*)(void*, - wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update), - (uint64_t(*)(void*, - wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update_u64), -}; +static wuffs_base__status +wuffs_xz__decoder__decode_block_header_sans_padding( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// ---------------- Initializer Implementations + uint8_t v_c8 = 0; + uint32_t v_c32 = 0; + uint32_t v_alignment = 0; + uint8_t v_flags = 0; + uint8_t v_filter_id = 0; + wuffs_base__status v_status = wuffs_base__make_status(NULL); + uint32_t v_shift = 0; + uint32_t v_f = 0; + uint32_t v_k = 0; -wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT -wuffs_xxhash64__hasher__initialize( - wuffs_xxhash64__hasher* self, - size_t sizeof_star_self, - uint64_t wuffs_version, - uint32_t options){ - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (sizeof(*self) != sizeof_star_self) { - return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) || - (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) { - return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version); + + uint32_t coro_susp_point = self->private_impl.p_decode_block_header_sans_padding; + if (coro_susp_point) { + v_flags = self->private_data.s_decode_block_header_sans_padding.v_flags; + v_filter_id = self->private_data.s_decode_block_header_sans_padding.v_filter_id; + v_shift = self->private_data.s_decode_block_header_sans_padding.v_shift; + v_f = self->private_data.s_decode_block_header_sans_padding.v_f; } + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; - if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) { - // The whole point of this if-check is to detect an uninitialized *self. - // We disable the warning on GCC. Clang-5.0 does not have this warning. -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - if (self->private_impl.magic != 0) { - return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed); + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_flags = t_0; } -#if !defined(__clang__) && defined(__GNUC__) -#pragma GCC diagnostic pop -#endif - } else { - if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) { - memset(self, 0, sizeof(*self)); - options |= WUFFS_INITIALIZE__ALREADY_ZEROED; + self->private_impl.f_num_non_final_filters = ((uint32_t)(((uint8_t)(v_flags & 3u)))); + if (((uint8_t)(v_flags & 60u)) != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + self->private_impl.f_block_has_compressed_size = (((uint8_t)(v_flags & 64u)) != 0u); + if (self->private_impl.f_block_has_compressed_size) { + self->private_impl.f_block_compressed_size = 0u; + v_shift = 0u; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (v_shift <= 56u) { + self->private_impl.f_block_compressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift); + if (v_c8 >= 128u) { + v_shift += 7u; + continue; + } else if ((v_c8 == 0u) && (v_shift > 0u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + break; + } else if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + self->private_impl.f_block_compressed_size |= (((uint64_t)(1u)) << 63u); + break; + } + } + self->private_impl.f_block_has_uncompressed_size = (((uint8_t)(v_flags & 128u)) != 0u); + if (self->private_impl.f_block_has_uncompressed_size) { + self->private_impl.f_block_uncompressed_size = 0u; + v_shift = 0u; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (v_shift <= 56u) { + self->private_impl.f_block_uncompressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift); + if (v_c8 >= 128u) { + v_shift += 7u; + continue; + } else if ((v_c8 == 0u) && (v_shift > 0u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + break; + } else if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_block_header); + goto exit; + } + self->private_impl.f_block_uncompressed_size |= (((uint64_t)(1u)) << 63u); + break; + } + } + self->private_impl.f_bcj_x86_prev_mask = 0u; + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_non_final_filters__choosy_default); + v_f = 0u; + while (v_f < self->private_impl.f_num_non_final_filters) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_filter_id = t_3; + } + if (v_filter_id == 33u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_filter); + goto exit; + } else if (v_filter_id == 3u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_4 = *iop_a_src++; + v_c8 = t_4; + } + if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_filter); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_5 = *iop_a_src++; + v_c8 = t_5; + } + self->private_impl.f_filters[v_f] = ((((uint32_t)(v_c8)) << 8u) | 3u); + v_k = 0u; + while (v_k < 256u) { + self->private_data.f_filter_data[v_f][v_k] = 0u; + v_k += 1u; + } + } else if ((v_filter_id < 3u) || (11u < v_filter_id)) { + status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter); + goto exit; + } else if (v_f != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter_combination); + goto exit; + } else { + self->private_impl.f_filters[v_f] = ((uint32_t)(v_filter_id)); + if (v_filter_id == 4u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_04_x86); + } else if (v_filter_id == 5u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_05_powerpc); + } else if (v_filter_id == 6u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_06_ia64); + } else if (v_filter_id == 7u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_07_arm); + } else if (v_filter_id == 8u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_08_armthumb); + } else if (v_filter_id == 9u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_09_sparc); + } else if (v_filter_id == 10u) { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_0a_arm64); + } else { + self->private_impl.choosy_apply_non_final_filters = ( + &wuffs_xz__decoder__apply_filter_0b_riscv); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_6 = *iop_a_src++; + v_c8 = t_6; + } + if (v_c8 == 0u) { + self->private_impl.f_bcj_pos = 0u; + } else if (v_c8 == 4u) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8); + uint32_t t_7; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_decode_block_header_sans_padding.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_decode_block_header_sans_padding.scratch; + uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7; + if (num_bits_7 == 24) { + t_7 = ((uint32_t)(*scratch)); + break; + } + num_bits_7 += 8u; + *scratch |= ((uint64_t)(num_bits_7)) << 56; + } + } + v_c32 = t_7; + } + v_alignment = ((uint32_t)(WUFFS_XZ__BCJ_OFFSET_ALIGNMENT[v_filter_id])); + if (v_alignment > 0u) { + if ((v_c32 % v_alignment) != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_bcj_offset); + goto exit; + } + } + self->private_impl.f_bcj_pos = v_c32; + } else { + status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter); + goto exit; + } + } + v_f += 1u; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_8 = *iop_a_src++; + v_filter_id = t_8; + } + if (v_filter_id == 33u) { + if (self->private_impl.f_lzma_needs_reset) { + wuffs_private_impl__ignore_status(wuffs_lzma__decoder__initialize(&self->private_data.f_lzma, + sizeof (wuffs_lzma__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED)); + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_9 = *iop_a_src++; + v_c8 = t_9; + } + if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_filter); + goto exit; + } + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_10 = *iop_a_src++; + v_c8 = t_10; + } + v_status = wuffs_lzma__decoder__set_quirk(&self->private_data.f_lzma, 1348001793u, (2u | (((uint64_t)(v_c8)) << 8u))); + if ( ! wuffs_base__status__is_ok(&v_status)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_filter); + goto exit; + } + } else if ((v_filter_id < 3u) || (11u < v_filter_id)) { + status = wuffs_base__make_status(wuffs_xz__error__unsupported_filter); + goto exit; } else { - memset(&(self->private_impl), 0, sizeof(self->private_impl)); + status = wuffs_base__make_status(wuffs_xz__error__bad_filter); + goto exit; } - } - self->private_impl.magic = WUFFS_BASE__MAGIC; - self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name = - wuffs_base__hasher_u64__vtable_name; - self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers = - (const void*)(&wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64); - return wuffs_base__make_status(NULL); -} - -wuffs_xxhash64__hasher* -wuffs_xxhash64__hasher__alloc(void) { - wuffs_xxhash64__hasher* x = - (wuffs_xxhash64__hasher*)(calloc(sizeof(wuffs_xxhash64__hasher), 1)); - if (!x) { - return NULL; - } - if (wuffs_xxhash64__hasher__initialize( - x, sizeof(wuffs_xxhash64__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) { - free(x); - return NULL; + goto ok; + ok: + self->private_impl.p_decode_block_header_sans_padding = 0; + goto exit; } - return x; -} - -size_t -sizeof__wuffs_xxhash64__hasher(void) { - return sizeof(wuffs_xxhash64__hasher); -} -// ---------------- Function Implementations - -// -------- func xxhash64.hasher.get_quirk + goto suspend; + suspend: + self->private_impl.p_decode_block_header_sans_padding = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_decode_block_header_sans_padding.v_flags = v_flags; + self->private_data.s_decode_block_header_sans_padding.v_filter_id = v_filter_id; + self->private_data.s_decode_block_header_sans_padding.v_shift = v_shift; + self->private_data.s_decode_block_header_sans_padding.v_f = v_f; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__get_quirk( - const wuffs_xxhash64__hasher* self, - uint32_t a_key) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - return 0u; + return status; } -// -------- func xxhash64.hasher.set_quirk +// -------- func xz.decoder.verify_index WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__status -wuffs_xxhash64__hasher__set_quirk( - wuffs_xxhash64__hasher* self, - uint32_t a_key, - uint64_t a_value) { - if (!self) { - return wuffs_base__make_status(wuffs_base__error__bad_receiver); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_status( - (self->private_impl.magic == WUFFS_BASE__DISABLED) - ? wuffs_base__error__disabled_by_previous_error - : wuffs_base__error__initialize_not_called); - } - - return wuffs_base__make_status(wuffs_base__error__unsupported_option); -} +static wuffs_base__status +wuffs_xz__decoder__verify_index( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); -// -------- func xxhash64.hasher.update + uint8_t v_c8 = 0; + uint32_t v_shift = 0; + uint32_t v_hash = 0; -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct -wuffs_xxhash64__hasher__update( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return wuffs_base__make_empty_struct(); - } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return wuffs_base__make_empty_struct(); + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; } - if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) { - self->private_impl.f_v0 = 6983438078262162902u; - self->private_impl.f_v1 = 14029467366897019727u; - self->private_impl.f_v2 = 0u; - self->private_impl.f_v3 = 7046029288634856825u; + uint32_t coro_susp_point = self->private_impl.p_verify_index; + if (coro_susp_point) { + v_shift = self->private_data.s_verify_index.v_shift; } - wuffs_xxhash64__hasher__up(self, a_x); - return wuffs_base__make_empty_struct(); -} + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; -// -------- func xxhash64.hasher.update_u64 + if ( ! self->private_impl.f_started_verify_index) { + self->private_impl.f_started_verify_index = true; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_0 = *iop_a_src++; + v_c8 = t_0; + } + if (v_c8 != 0u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + self->private_impl.f_num_index_blocks = 0u; + v_shift = 0u; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_1 = *iop_a_src++; + v_c8 = t_1; + } + if (v_shift <= 56u) { + self->private_impl.f_num_index_blocks |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift); + if (v_c8 >= 128u) { + v_shift += 7u; + continue; + } else if ((v_c8 == 0u) && (v_shift > 0u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + break; + } else if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + self->private_impl.f_num_index_blocks |= (((uint64_t)(1u)) << 63u); + break; + } + if (self->private_impl.f_num_index_blocks != self->private_impl.f_num_actual_blocks) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + } + while (self->private_impl.f_num_index_blocks > 0u) { + self->private_impl.f_num_index_blocks -= 1u; + self->private_impl.f_index_block_compressed_size = 0u; + v_shift = 0u; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_2 = *iop_a_src++; + v_c8 = t_2; + } + if (v_shift <= 56u) { + self->private_impl.f_index_block_compressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift); + if (v_c8 >= 128u) { + v_shift += 7u; + continue; + } else if ((v_c8 == 0u) && (v_shift > 0u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + break; + } else if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + self->private_impl.f_index_block_compressed_size |= (((uint64_t)(1u)) << 63u); + break; + } + self->private_impl.f_index_block_uncompressed_size = 0u; + v_shift = 0u; + while (true) { + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint8_t t_3 = *iop_a_src++; + v_c8 = t_3; + } + if (v_shift <= 56u) { + self->private_impl.f_index_block_uncompressed_size |= (((uint64_t)(((uint8_t)(v_c8 & 127u)))) << v_shift); + if (v_c8 >= 128u) { + v_shift += 7u; + continue; + } else if ((v_c8 == 0u) && (v_shift > 0u)) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + break; + } else if (v_c8 != 1u) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } + self->private_impl.f_index_block_uncompressed_size |= (((uint64_t)(1u)) << 63u); + break; + } + self->private_impl.f_verification_want_total_sizes[0u] += self->private_impl.f_index_block_compressed_size; + v_hash = ((uint32_t)((self->private_impl.f_index_block_compressed_size ^ (self->private_impl.f_index_block_compressed_size >> 32u)))); + v_hash *= 3432918353u; + v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u)); + v_hash *= 461845907u; + v_hash ^= self->private_impl.f_verification_want_hashed_sizes[0u]; + v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u)); + self->private_impl.f_verification_want_hashed_sizes[0u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u)); + self->private_impl.f_verification_want_total_sizes[1u] += self->private_impl.f_index_block_uncompressed_size; + v_hash = ((uint32_t)((self->private_impl.f_index_block_uncompressed_size ^ (self->private_impl.f_index_block_uncompressed_size >> 32u)))); + v_hash *= 3432918353u; + v_hash = (((uint32_t)(v_hash << 15u)) | (v_hash >> 17u)); + v_hash *= 461845907u; + v_hash ^= self->private_impl.f_verification_want_hashed_sizes[1u]; + v_hash = (((uint32_t)(v_hash << 13u)) | (v_hash >> 19u)); + self->private_impl.f_verification_want_hashed_sizes[1u] = ((uint32_t)(((uint32_t)(v_hash * 5u)) + 3864292196u)); + } + if ((self->private_impl.f_verification_have_hashed_sizes[0u] != self->private_impl.f_verification_want_hashed_sizes[0u]) || + (self->private_impl.f_verification_have_hashed_sizes[1u] != self->private_impl.f_verification_want_hashed_sizes[1u]) || + (self->private_impl.f_verification_have_total_sizes[0u] != self->private_impl.f_verification_want_total_sizes[0u]) || + (self->private_impl.f_verification_have_total_sizes[1u] != self->private_impl.f_verification_want_total_sizes[1u])) { + status = wuffs_base__make_status(wuffs_xz__error__bad_index); + goto exit; + } -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__update_u64( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x) { - if (!self) { - return 0; + goto ok; + ok: + self->private_impl.p_verify_index = 0; + goto exit; } - if (self->private_impl.magic != WUFFS_BASE__MAGIC) { - return 0; + + goto suspend; + suspend: + self->private_impl.p_verify_index = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; + self->private_data.s_verify_index.v_shift = v_shift; + + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - wuffs_xxhash64__hasher__update(self, a_x); - return wuffs_xxhash64__hasher__checksum_u64(self); + return status; } -// -------- func xxhash64.hasher.up +// -------- func xz.decoder.verify_footer WUFFS_BASE__GENERATED_C_CODE -static wuffs_base__empty_struct -wuffs_xxhash64__hasher__up( - wuffs_xxhash64__hasher* self, - wuffs_base__slice_u8 a_x) { - uint64_t v_new_lmu = 0; - uint64_t v_buf_u64 = 0; - uint32_t v_buf_len = 0; - uint64_t v_v0 = 0; - uint64_t v_v1 = 0; - uint64_t v_v2 = 0; - uint64_t v_v3 = 0; - wuffs_base__slice_u8 v_p = {0}; +static wuffs_base__status +wuffs_xz__decoder__verify_footer( + wuffs_xz__decoder* self, + wuffs_base__io_buffer* a_src) { + wuffs_base__status status = wuffs_base__make_status(NULL); - v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len)))); - self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64); - self->private_impl.f_length_modulo_u64 = v_new_lmu; - while (true) { - if (self->private_impl.f_buf_len >= 32u) { - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) | - (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u)); - v_v0 = ((uint64_t)(self->private_impl.f_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); - self->private_impl.f_v0 = ((uint64_t)(v_v0 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) | - (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u)); - v_v1 = ((uint64_t)(self->private_impl.f_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); - self->private_impl.f_v1 = ((uint64_t)(v_v1 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) | - (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u)); - v_v2 = ((uint64_t)(self->private_impl.f_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); - self->private_impl.f_v2 = ((uint64_t)(v_v2 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[24u])) | - (((uint64_t)(self->private_impl.f_buf_data[25u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[26u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[27u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[28u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[29u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[30u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[31u])) << 56u)); - v_v3 = ((uint64_t)(self->private_impl.f_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); - self->private_impl.f_v3 = ((uint64_t)(v_v3 * 11400714785074694791u)); - self->private_impl.f_buf_len = 0u; - break; + uint32_t v_c32 = 0; + + const uint8_t* iop_a_src = NULL; + const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL; + if (a_src && a_src->data.ptr) { + io0_a_src = a_src->data.ptr; + io1_a_src = io0_a_src + a_src->meta.ri; + iop_a_src = io1_a_src; + io2_a_src = io0_a_src + a_src->meta.wi; + } + + uint32_t coro_susp_point = self->private_impl.p_verify_footer; + switch (coro_susp_point) { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0; + + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1); + uint32_t t_0; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) { + t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src); + iop_a_src += 4; + } else { + self->private_data.s_verify_footer.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_verify_footer.scratch; + uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0; + if (num_bits_0 == 24) { + t_0 = ((uint32_t)(*scratch)); + break; + } + num_bits_0 += 8u; + *scratch |= ((uint64_t)(num_bits_0)) << 56; + } + } + v_c32 = t_0; } - if (((uint64_t)(a_x.len)) <= 0u) { - return wuffs_base__make_empty_struct(); + if (v_c32 != ((uint32_t)(self->private_impl.f_backwards_size))) { + status = wuffs_base__make_status(wuffs_xz__error__bad_footer); + goto exit; } - self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u]; - self->private_impl.f_buf_len += 1u; - a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u); - } - v_buf_len = (self->private_impl.f_buf_len & 31u); - v_v0 = self->private_impl.f_v0; - v_v1 = self->private_impl.f_v1; - v_v2 = self->private_impl.f_v2; - v_v3 = self->private_impl.f_v3; - { - wuffs_base__slice_u8 i_slice_p = a_x; - v_p.ptr = i_slice_p.ptr; - v_p.len = 32; - uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32); - while (v_p.ptr < i_end0_p) { - v_buf_u64 = (((uint64_t)(v_p.ptr[0u])) | - (((uint64_t)(v_p.ptr[1u])) << 8u) | - (((uint64_t)(v_p.ptr[2u])) << 16u) | - (((uint64_t)(v_p.ptr[3u])) << 24u) | - (((uint64_t)(v_p.ptr[4u])) << 32u) | - (((uint64_t)(v_p.ptr[5u])) << 40u) | - (((uint64_t)(v_p.ptr[6u])) << 48u) | - (((uint64_t)(v_p.ptr[7u])) << 56u)); - v_v0 = ((uint64_t)(v_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); - v_v0 = ((uint64_t)(v_v0 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(v_p.ptr[8u])) | - (((uint64_t)(v_p.ptr[9u])) << 8u) | - (((uint64_t)(v_p.ptr[10u])) << 16u) | - (((uint64_t)(v_p.ptr[11u])) << 24u) | - (((uint64_t)(v_p.ptr[12u])) << 32u) | - (((uint64_t)(v_p.ptr[13u])) << 40u) | - (((uint64_t)(v_p.ptr[14u])) << 48u) | - (((uint64_t)(v_p.ptr[15u])) << 56u)); - v_v1 = ((uint64_t)(v_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); - v_v1 = ((uint64_t)(v_v1 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(v_p.ptr[16u])) | - (((uint64_t)(v_p.ptr[17u])) << 8u) | - (((uint64_t)(v_p.ptr[18u])) << 16u) | - (((uint64_t)(v_p.ptr[19u])) << 24u) | - (((uint64_t)(v_p.ptr[20u])) << 32u) | - (((uint64_t)(v_p.ptr[21u])) << 40u) | - (((uint64_t)(v_p.ptr[22u])) << 48u) | - (((uint64_t)(v_p.ptr[23u])) << 56u)); - v_v2 = ((uint64_t)(v_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); - v_v2 = ((uint64_t)(v_v2 * 11400714785074694791u)); - v_buf_u64 = (((uint64_t)(v_p.ptr[24u])) | - (((uint64_t)(v_p.ptr[25u])) << 8u) | - (((uint64_t)(v_p.ptr[26u])) << 16u) | - (((uint64_t)(v_p.ptr[27u])) << 24u) | - (((uint64_t)(v_p.ptr[28u])) << 32u) | - (((uint64_t)(v_p.ptr[29u])) << 40u) | - (((uint64_t)(v_p.ptr[30u])) << 48u) | - (((uint64_t)(v_p.ptr[31u])) << 56u)); - v_v3 = ((uint64_t)(v_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u)))); - v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); - v_v3 = ((uint64_t)(v_v3 * 11400714785074694791u)); - v_p.ptr += 32; + { + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3); + uint32_t t_1; + if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) { + t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src))); + iop_a_src += 2; + } else { + self->private_data.s_verify_footer.scratch = 0; + WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4); + while (true) { + if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) { + status = wuffs_base__make_status(wuffs_base__suspension__short_read); + goto suspend; + } + uint64_t* scratch = &self->private_data.s_verify_footer.scratch; + uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56)); + *scratch <<= 8; + *scratch >>= 8; + *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1; + if (num_bits_1 == 8) { + t_1 = ((uint32_t)(*scratch)); + break; + } + num_bits_1 += 8u; + *scratch |= ((uint64_t)(num_bits_1)) << 56; + } + } + v_c32 = t_1; } - v_p.len = 1; - uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len; - while (v_p.ptr < i_end1_p) { - self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u]; - v_buf_len = ((v_buf_len + 1u) & 31u); - v_p.ptr += 1; + if (v_c32 != ((uint32_t)(self->private_impl.f_flags))) { + status = wuffs_base__make_status(wuffs_xz__error__bad_footer); + goto exit; } - v_p.len = 0; - } - self->private_impl.f_buf_len = v_buf_len; - self->private_impl.f_v0 = v_v0; - self->private_impl.f_v1 = v_v1; - self->private_impl.f_v2 = v_v2; - self->private_impl.f_v3 = v_v3; - return wuffs_base__make_empty_struct(); -} - -// -------- func xxhash64.hasher.checksum_u64 -WUFFS_BASE__GENERATED_C_CODE -WUFFS_BASE__MAYBE_STATIC uint64_t -wuffs_xxhash64__hasher__checksum_u64( - const wuffs_xxhash64__hasher* self) { - if (!self) { - return 0; - } - if ((self->private_impl.magic != WUFFS_BASE__MAGIC) && - (self->private_impl.magic != WUFFS_BASE__DISABLED)) { - return 0; + goto ok; + ok: + self->private_impl.p_verify_footer = 0; + goto exit; } - uint64_t v_ret = 0; - uint64_t v_v0 = 0; - uint64_t v_v1 = 0; - uint64_t v_v2 = 0; - uint64_t v_v3 = 0; - uint32_t v_i = 0; - uint32_t v_i8 = 0; - uint32_t v_n = 0; - uint32_t v_buf_u32 = 0; - uint64_t v_buf_u64 = 0; + goto suspend; + suspend: + self->private_impl.p_verify_footer = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0; - if ((self->private_impl.f_length_modulo_u64 >= 32u) || self->private_impl.f_length_overflows_u64) { - v_ret += (((uint64_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 63u)); - v_ret += (((uint64_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 57u)); - v_ret += (((uint64_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 52u)); - v_ret += (((uint64_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 46u)); - v_v0 = ((uint64_t)(self->private_impl.f_v0 * 14029467366897019727u)); - v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u)); - v_v0 *= 11400714785074694791u; - v_v1 = ((uint64_t)(self->private_impl.f_v1 * 14029467366897019727u)); - v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u)); - v_v1 *= 11400714785074694791u; - v_v2 = ((uint64_t)(self->private_impl.f_v2 * 14029467366897019727u)); - v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u)); - v_v2 *= 11400714785074694791u; - v_v3 = ((uint64_t)(self->private_impl.f_v3 * 14029467366897019727u)); - v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u)); - v_v3 *= 11400714785074694791u; - v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v0) * 11400714785074694791u)) + 9650029242287828579u)); - v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v1) * 11400714785074694791u)) + 9650029242287828579u)); - v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v2) * 11400714785074694791u)) + 9650029242287828579u)); - v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v3) * 11400714785074694791u)) + 9650029242287828579u)); - v_ret += self->private_impl.f_length_modulo_u64; - } else { - v_ret += 2870177450012600261u; - v_ret += self->private_impl.f_length_modulo_u64; - } - v_n = 32u; - v_n = wuffs_base__u32__min(v_n, self->private_impl.f_buf_len); - if (8u <= v_n) { - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) | - (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u)); - v_buf_u64 *= 14029467366897019727u; - v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); - v_buf_u64 *= 11400714785074694791u; - v_ret ^= v_buf_u64; - v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); - v_ret *= 11400714785074694791u; - v_ret += 9650029242287828579u; - v_i = 8u; - } - if (16u <= v_n) { - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) | - (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u)); - v_buf_u64 *= 14029467366897019727u; - v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); - v_buf_u64 *= 11400714785074694791u; - v_ret ^= v_buf_u64; - v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); - v_ret *= 11400714785074694791u; - v_ret += 9650029242287828579u; - v_i = 16u; - } - if (24u <= v_n) { - v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) | - (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) | - (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) | - (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) | - (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) | - (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) | - (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) | - (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u)); - v_buf_u64 *= 14029467366897019727u; - v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u)); - v_buf_u64 *= 11400714785074694791u; - v_ret ^= v_buf_u64; - v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u)); - v_ret *= 11400714785074694791u; - v_ret += 9650029242287828579u; - v_i = 24u; - } - if ((v_n & 4u) != 0u) { - v_i8 = (v_i & 24u); - v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 0u)])) | - (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 1u)])) << 8u) | - (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 2u)])) << 16u) | - (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 3u)])) << 24u)); - v_ret ^= ((uint64_t)(((uint64_t)(v_buf_u32)) * 11400714785074694791u)); - v_ret = (((uint64_t)(v_ret << 23u)) | (v_ret >> 41u)); - v_ret *= 14029467366897019727u; - v_ret += 1609587929392839161u; - v_i = (v_i8 + 4u); - } - while (v_i < v_n) { - v_ret ^= ((uint64_t)(((uint64_t)(self->private_impl.f_buf_data[v_i])) * 2870177450012600261u)); - v_ret = (((uint64_t)(v_ret << 11u)) | (v_ret >> 53u)); - v_ret *= 11400714785074694791u; - v_i += 1u; + goto exit; + exit: + if (a_src && a_src->data.ptr) { + a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr)); } - v_ret ^= (v_ret >> 33u); - v_ret *= 14029467366897019727u; - v_ret ^= (v_ret >> 29u); - v_ret *= 1609587929392839161u; - v_ret ^= (v_ret >> 32u); - return ((uint64_t)(v_ret)); + + return status; } -#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) +#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XZ) #if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR) @@ -62309,16 +78871,12 @@ DynIOBuffer::DynIOBuffer(uint64_t max_incl) : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {} DynIOBuffer::~DynIOBuffer() { - if (m_buf.data.ptr) { - free(m_buf.data.ptr); - } + free(m_buf.data.ptr); } void // DynIOBuffer::drop() { - if (m_buf.data.ptr) { - free(m_buf.data.ptr); - } + free(m_buf.data.ptr); m_buf = wuffs_base__empty_io_buffer(); } @@ -62329,13 +78887,16 @@ DynIOBuffer::grow(uint64_t min_incl) { return ((min_incl == 0) && (m_max_incl == 0)) ? DynIOBuffer::GrowResult::OK : DynIOBuffer::GrowResult::FailedMaxInclExceeded; + } else if (n > SIZE_MAX) { + return DynIOBuffer::GrowResult::FailedOutOfMemory; } else if (n > m_buf.data.len) { - uint8_t* ptr = static_cast(realloc(m_buf.data.ptr, n)); + uint8_t* ptr = + static_cast(realloc(m_buf.data.ptr, static_cast(n))); if (!ptr) { return DynIOBuffer::GrowResult::FailedOutOfMemory; } m_buf.data.ptr = ptr; - m_buf.data.len = n; + m_buf.data.len = static_cast(n); } return DynIOBuffer::GrowResult::OK; } @@ -62382,7 +78943,7 @@ Input::BringsItsOwnIOBuffer() { FileInput::FileInput(FILE* f) : m_f(f) {} std::string // -FileInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) { +FileInput::CopyIn(IOBuffer* dst) { if (!m_f) { return "wuffs_aux::sync_io::FileInput: nullptr file"; } else if (!dst) { @@ -62390,7 +78951,7 @@ FileInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) { } else if (dst->meta.closed) { return "wuffs_aux::sync_io::FileInput: end of file"; } else { - dst->compact_retaining(history_retain_length); + dst->compact(); size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f); dst->meta.wi += n; dst->meta.closed = feof(m_f); @@ -62418,7 +78979,7 @@ MemoryInput::BringsItsOwnIOBuffer() { } std::string // -MemoryInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) { +MemoryInput::CopyIn(IOBuffer* dst) { if (!dst) { return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer"; } else if (dst->meta.closed) { @@ -62428,7 +78989,7 @@ MemoryInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) { // to it. return "wuffs_aux::sync_io::MemoryInput: overlapping buffers"; } else { - dst->compact_retaining(history_retain_length); + dst->compact(); size_t nd = dst->writer_length(); size_t ns = m_io.reader_length(); size_t n = (nd < ns) ? nd : ns; @@ -62483,7 +79044,7 @@ AdvanceIOBufferTo(const ErrorMessages& error_messages, if (!input.BringsItsOwnIOBuffer()) { io_buf.compact(); } - std::string error_message = input.CopyIn(&io_buf, 0); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return error_message; } @@ -62566,7 +79127,7 @@ HandleMetadata( } else if (!input.BringsItsOwnIOBuffer()) { io_buf.compact(); } - std::string error_message = input.CopyIn(&io_buf, 0); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return error_message; } @@ -62627,15 +79188,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 // @@ -62664,8 +79223,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. @@ -62710,14 +79269,14 @@ DecodeCbor(DecodeCborCallbacks& callbacks, "wuffs_aux::DecodeCbor: internal error: io_buf is closed"; goto done; } - io_buf->compact_retaining(dec->history_retain_length()); + io_buf->compact(); if (io_buf->meta.wi >= io_buf->data.len) { ret_error_message = "wuffs_aux::DecodeCbor: internal error: io_buf is full"; goto done; } cursor_index = io_buf->meta.ri; - io_error_message = input.CopyIn(io_buf, dec->history_retain_length()); + io_error_message = input.CopyIn(io_buf); } else { ret_error_message = tok_status.message(); goto done; @@ -62796,7 +79355,7 @@ DecodeCbor(DecodeCborCallbacks& callbacks, goto done; } depth++; - if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) { + if (depth > (int32_t)WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) { ret_error_message = "wuffs_aux::DecodeCbor: internal error: bad depth"; goto done; @@ -63052,6 +79611,11 @@ DecodeImageCallbacks::SelectDecoder(uint32_t fourcc, } #endif +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__QOI) + case WUFFS_BASE__FOURCC__QOI: + return wuffs_qoi__decoder::alloc_as__wuffs_base__image_decoder(); +#endif + #if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) case WUFFS_BASE__FOURCC__TGA: return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder(); @@ -63061,6 +79625,11 @@ DecodeImageCallbacks::SelectDecoder(uint32_t fourcc, case WUFFS_BASE__FOURCC__WBMP: return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder(); #endif + +#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WEBP) + case WUFFS_BASE__FOURCC__WEBP: + return wuffs_webp__decoder::alloc_as__wuffs_base__image_decoder(); +#endif } return wuffs_base__image_decoder::unique_ptr(nullptr); @@ -63091,7 +79660,7 @@ DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config, return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration); } void* ptr = - allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1); + allow_uninitialized_memory ? malloc((size_t)len) : calloc(1, (size_t)len); if (!ptr) { return AllocPixbufResult(DecodeImage_OutOfMemory); } @@ -63116,7 +79685,7 @@ DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range, return AllocWorkbufResult(DecodeImage_OutOfMemory); } void* ptr = - allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1); + allow_uninitialized_memory ? malloc((size_t)len) : calloc(1, (size_t)len); if (!ptr) { return AllocWorkbufResult(DecodeImage_OutOfMemory); } @@ -63153,15 +79722,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) {} @@ -63259,7 +79826,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, @@ -63301,7 +79869,7 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, fourcc = 0; break; } - std::string error_message = input.CopyIn(&io_buf, 0); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return DecodeImageResult(std::move(error_message)); } @@ -63342,8 +79910,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. @@ -63397,8 +79965,7 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, } else if (io_buf.meta.closed) { return DecodeImageResult(DecodeImage_UnexpectedEndOfFile); } else { - std::string error_message = - input.CopyIn(&io_buf, image_decoder->history_retain_length()); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return DecodeImageResult(std::move(error_message)); } @@ -63480,8 +80047,7 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, } else if (io_buf.meta.closed) { return DecodeImageResult(DecodeImage_UnexpectedEndOfFile); } else { - std::string error_message = - input.CopyIn(&io_buf, image_decoder->history_retain_length()); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return DecodeImageResult(std::move(error_message)); } @@ -63510,8 +80076,7 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, message = DecodeImage_UnexpectedEndOfFile; break; } else { - std::string error_message = - input.CopyIn(&io_buf, image_decoder->history_retain_length()); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { message = std::move(error_message); break; @@ -63539,8 +80104,7 @@ DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder, } else if (io_buf.meta.closed) { return DecodeImageResult(DecodeImage_UnexpectedEndOfFile); } else { - std::string error_message = - input.CopyIn(&io_buf, image_decoder->history_retain_length()); + std::string error_message = input.CopyIn(&io_buf); if (!error_message.empty()) { return DecodeImageResult(std::move(error_message)); } @@ -63574,10 +80138,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; } @@ -63612,15 +80176,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) @@ -63633,58 +80195,58 @@ DecodeJsonArgJsonPointer::DefaultValue() { // -------- -#define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \ - while (tok_buf.meta.ri >= tok_buf.meta.wi) { \ - if (tok_status.repr == nullptr) { \ - goto done; \ - } else if (tok_status.repr == wuffs_base__suspension__short_write) { \ - tok_buf.compact(); \ - } else if (tok_status.repr == wuffs_base__suspension__short_read) { \ - if (!io_error_message.empty()) { \ - ret_error_message = std::move(io_error_message); \ - goto done; \ - } else if (cursor_index != io_buf->meta.ri) { \ - ret_error_message = \ - "wuffs_aux::DecodeJson: internal error: bad cursor_index"; \ - goto done; \ - } else if (io_buf->meta.closed) { \ - ret_error_message = \ - "wuffs_aux::DecodeJson: internal error: io_buf is closed"; \ - goto done; \ - } \ - io_buf->compact_retaining(dec->history_retain_length()); \ - if (io_buf->meta.wi >= io_buf->data.len) { \ - ret_error_message = \ - "wuffs_aux::DecodeJson: internal error: io_buf is full"; \ - goto done; \ - } \ - cursor_index = io_buf->meta.ri; \ - io_error_message = input.CopyIn(io_buf, dec->history_retain_length()); \ - } else { \ - ret_error_message = tok_status.message(); \ - goto done; \ - } \ - tok_status = \ - dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \ - if ((tok_buf.meta.ri > tok_buf.meta.wi) || \ - (tok_buf.meta.wi > tok_buf.data.len) || \ - (io_buf->meta.ri > io_buf->meta.wi) || \ - (io_buf->meta.wi > io_buf->data.len)) { \ - ret_error_message = \ - "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \ - goto done; \ - } \ - } \ - wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \ - uint64_t token_len = token.length(); \ - if ((io_buf->meta.ri < cursor_index) || \ - ((io_buf->meta.ri - cursor_index) < token_len)) { \ - ret_error_message = \ - "wuffs_aux::DecodeJson: internal error: bad token indexes"; \ - goto done; \ - } \ - uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \ - (void)(token_ptr); \ +#define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \ + while (tok_buf.meta.ri >= tok_buf.meta.wi) { \ + if (tok_status.repr == nullptr) { \ + goto done; \ + } else if (tok_status.repr == wuffs_base__suspension__short_write) { \ + tok_buf.compact(); \ + } else if (tok_status.repr == wuffs_base__suspension__short_read) { \ + if (!io_error_message.empty()) { \ + ret_error_message = std::move(io_error_message); \ + goto done; \ + } else if (cursor_index != io_buf->meta.ri) { \ + ret_error_message = \ + "wuffs_aux::DecodeJson: internal error: bad cursor_index"; \ + goto done; \ + } else if (io_buf->meta.closed) { \ + ret_error_message = \ + "wuffs_aux::DecodeJson: internal error: io_buf is closed"; \ + goto done; \ + } \ + io_buf->compact(); \ + if (io_buf->meta.wi >= io_buf->data.len) { \ + ret_error_message = \ + "wuffs_aux::DecodeJson: internal error: io_buf is full"; \ + goto done; \ + } \ + cursor_index = io_buf->meta.ri; \ + io_error_message = input.CopyIn(io_buf); \ + } else { \ + ret_error_message = tok_status.message(); \ + goto done; \ + } \ + tok_status = \ + dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \ + if ((tok_buf.meta.ri > tok_buf.meta.wi) || \ + (tok_buf.meta.wi > tok_buf.data.len) || \ + (io_buf->meta.ri > io_buf->meta.wi) || \ + (io_buf->meta.wi > io_buf->data.len)) { \ + ret_error_message = \ + "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \ + goto done; \ + } \ + } \ + wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \ + uint64_t token_len = token.length(); \ + if ((io_buf->meta.ri < cursor_index) || \ + ((io_buf->meta.ri - cursor_index) < token_len)) { \ + ret_error_message = \ + "wuffs_aux::DecodeJson: internal error: bad token indexes"; \ + goto done; \ + } \ + uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \ + (void)(token_ptr); \ cursor_index += static_cast(token_len) // -------- @@ -63965,11 +80527,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); } } @@ -64025,7 +80587,7 @@ DecodeJson(DecodeJsonCallbacks& callbacks, goto done; } depth++; - if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) { + if (depth > (int32_t)WUFFS_JSON__DECODER_DEPTH_MAX_INCL) { ret_error_message = "wuffs_aux::DecodeJson: internal error: bad depth"; goto done; From 048ca832325d716fcab596822b10f5d493fc2312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kope=C4=87?= Date: Wed, 15 Jan 2025 14:56:46 +0100 Subject: [PATCH 15/15] mb/clevo/mtl-h/variants/igpu/data.vbt: Disable secondary display feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Kopeć --- .../clevo/mtl-h/variants/igpu/data.vbt | Bin 7680 -> 7680 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/mainboard/clevo/mtl-h/variants/igpu/data.vbt b/src/mainboard/clevo/mtl-h/variants/igpu/data.vbt index b6e6be3335790f0c8e697a81e8cfe4a5e6e9396a..4151d024a9a9fade7a8dfce32ff3c6c7ea26ce93 100644 GIT binary patch delta 84 zcmZp$X|S0f#oW$dFqx5Ac%y+hBQpa-!{jtZc_{`ozy#tmf{4w{jPcAIjQ{70tYTo3 WnQX@zGFgC`eKIer@8(IYc@h9ucnB#&lg$6z$P=