SDL_image: Updated Visual Studio project and added optional avif support

From 6d509770384c984bf56d56d632fe44893af17e17 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 5 Aug 2023 09:59:56 -0700
Subject: [PATCH] Updated Visual Studio project and added optional avif support

---
 VisualC/SDL_image.sln                         |   19 +-
 VisualC/SDL_image.vcxproj                     |   31 +-
 VisualC/external/include/avif/avif.h          | 1115 +++++++++++++++++
 VisualC/external/include/avif/internal.h      |  482 +++++++
 .../external/optional/x64/LICENSE.avif.txt    |  353 ++++++
 VisualC/external/optional/x64/avif.dll        |  Bin 0 -> 10063360 bytes
 .../external/optional/x86/LICENSE.avif.txt    |  353 ++++++
 VisualC/external/optional/x86/avif.dll        |  Bin 0 -> 9044480 bytes
 VisualC/showimage/showimage.vcxproj           |   32 +-
 VisualC/showimage/showimage.vcxproj.filters   |    2 +-
 src/IMG_avif.c                                |    4 +-
 11 files changed, 2356 insertions(+), 35 deletions(-)
 create mode 100644 VisualC/external/include/avif/avif.h
 create mode 100644 VisualC/external/include/avif/internal.h
 create mode 100644 VisualC/external/optional/x64/LICENSE.avif.txt
 create mode 100755 VisualC/external/optional/x64/avif.dll
 create mode 100644 VisualC/external/optional/x86/LICENSE.avif.txt
 create mode 100755 VisualC/external/optional/x86/avif.dll

diff --git a/VisualC/SDL_image.sln b/VisualC/SDL_image.sln
index d5c212a7..ba40ec77 100644
--- a/VisualC/SDL_image.sln
+++ b/VisualC/SDL_image.sln
@@ -1,10 +1,14 @@
 
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.33920.266
+MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL3_image", "SDL_image.vcxproj", "{2BD5534E-00E2-4BEA-AC96-D9A92EA24696}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "showimage", "showimage\showimage.vcxproj", "{FEE80C5D-762E-4E57-9BCB-928749E8203F}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL3", "..\external\SDL\VisualC\SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -29,8 +33,19 @@ Global
 		{FEE80C5D-762E-4E57-9BCB-928749E8203F}.Release|Win32.Build.0 = Release|Win32
 		{FEE80C5D-762E-4E57-9BCB-928749E8203F}.Release|x64.ActiveCfg = Release|x64
 		{FEE80C5D-762E-4E57-9BCB-928749E8203F}.Release|x64.Build.0 = Release|x64
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64
+		{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {3EDEF78E-211F-4AA9-98F3-D35AB42F75AE}
+	EndGlobalSection
 EndGlobal
diff --git a/VisualC/SDL_image.vcxproj b/VisualC/SDL_image.vcxproj
index 889f63a1..be183ead 100644
--- a/VisualC/SDL_image.vcxproj
+++ b/VisualC/SDL_image.vcxproj
@@ -85,20 +85,20 @@
     <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\external\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\external\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\external\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\..\SDL\include;$(IncludePath)</IncludePath>
-    <LibraryPath>$(SolutionDir)..\..\SDL\VisualC\$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
+    <IncludePath>$(ProjectDir)..\include;$(SolutionDir)..\external\SDL\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)$(PlatformName)\$(Configuration);$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Midl>
@@ -113,7 +113,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_AVIF;LOAD_AVIF_DYNAMIC="avif.dll";LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_WEBPDEMUX_DYNAMIC="libwebdemux-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -141,7 +141,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_AVIF;LOAD_AVIF_DYNAMIC="avif.dll";LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_WEBPDEMUX_DYNAMIC="libwebdemux-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
@@ -170,7 +170,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_AVIF;LOAD_AVIF_DYNAMIC="avif.dll";LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_WEBPDEMUX_DYNAMIC="libwebdemux-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
@@ -196,7 +196,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;USE_STBIMAGE;LOAD_AVIF;LOAD_AVIF_DYNAMIC="avif.dll";LOAD_BMP;LOAD_GIF;LOAD_JPG;LOAD_LBM;LOAD_PCX;LOAD_PNG;LOAD_PNM;LOAD_QOI;LOAD_SVG;LOAD_TGA;LOAD_TIF;LOAD_TIF_DYNAMIC="libtiff-5.dll";LOAD_WEBP;LOAD_WEBP_DYNAMIC="libwebp-7.dll";LOAD_WEBPDEMUX_DYNAMIC="libwebdemux-7.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
@@ -238,7 +238,12 @@
   <ItemGroup>
     <ClInclude Include="..\include\SDL3_image\SDL_image.h" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\external\SDL\VisualC\SDL\SDL.vcxproj">
+      <Project>{81ce8daf-ebb2-4761-8e45-b71abcca8c68}</Project>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/VisualC/external/include/avif/avif.h b/VisualC/external/include/avif/avif.h
new file mode 100644
index 00000000..60641bcb
--- /dev/null
+++ b/VisualC/external/include/avif/avif.h
@@ -0,0 +1,1115 @@
+// Copyright 2019 Joe Drago. All rights reserved.
+// SPDX-License-Identifier: BSD-2-Clause
+
+#ifndef AVIF_AVIF_H
+#define AVIF_AVIF_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+// Export macros
+
+// AVIF_BUILDING_SHARED_LIBS should only be defined when libavif is being built
+// as a shared library.
+// AVIF_DLL should be defined if libavif is a shared library. If you are using
+// libavif as a CMake dependency, through a CMake package config file or through
+// pkg-config, this is defined automatically.
+//
+// Here's what AVIF_API will be defined as in shared build:
+// |       |        Windows        |                  Unix                  |
+// | Build | __declspec(dllexport) | __attribute__((visibility("default"))) |
+// |  Use  | __declspec(dllimport) |                                        |
+//
+// For static build, AVIF_API is always defined as nothing.
+
+#if defined(_WIN32)
+#define AVIF_HELPER_EXPORT __declspec(dllexport)
+#define AVIF_HELPER_IMPORT __declspec(dllimport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+#define AVIF_HELPER_EXPORT __attribute__((visibility("default")))
+#define AVIF_HELPER_IMPORT
+#else
+#define AVIF_HELPER_EXPORT
+#define AVIF_HELPER_IMPORT
+#endif
+
+#if defined(AVIF_DLL)
+#if defined(AVIF_BUILDING_SHARED_LIBS)
+#define AVIF_API AVIF_HELPER_EXPORT
+#else
+#define AVIF_API AVIF_HELPER_IMPORT
+#endif // defined(AVIF_BUILDING_SHARED_LIBS)
+#else
+#define AVIF_API
+#endif // defined(AVIF_DLL)
+
+// ---------------------------------------------------------------------------
+// Constants
+
+// AVIF_VERSION_DEVEL should always be 0 for official releases / version tags,
+// and non-zero during development of the next release. This should allow for
+// downstream projects to do greater-than preprocessor checks on AVIF_VERSION
+// to leverage in-development code without breaking their stable builds.
+#define AVIF_VERSION_MAJOR 0
+#define AVIF_VERSION_MINOR 11
+#define AVIF_VERSION_PATCH 1
+#define AVIF_VERSION_DEVEL 0
+#define AVIF_VERSION \
+    ((AVIF_VERSION_MAJOR * 1000000) + (AVIF_VERSION_MINOR * 10000) + (AVIF_VERSION_PATCH * 100) + AVIF_VERSION_DEVEL)
+
+typedef int avifBool;
+#define AVIF_TRUE 1
+#define AVIF_FALSE 0
+
+#define AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE 256
+
+// A reasonable default for maximum image size (in pixel count) to avoid out-of-memory errors or
+// integer overflow in (32-bit) int or unsigned int arithmetic operations.
+#define AVIF_DEFAULT_IMAGE_SIZE_LIMIT (16384 * 16384)
+
+// A reasonable default for maximum image dimension (width or height).
+#define AVIF_DEFAULT_IMAGE_DIMENSION_LIMIT 32768
+
+// a 12 hour AVIF image sequence, running at 60 fps (a basic sanity check as this is quite ridiculous)
+#define AVIF_DEFAULT_IMAGE_COUNT_LIMIT (12 * 3600 * 60)
+
+#define AVIF_QUANTIZER_LOSSLESS 0
+#define AVIF_QUANTIZER_BEST_QUALITY 0
+#define AVIF_QUANTIZER_WORST_QUALITY 63
+
+#define AVIF_PLANE_COUNT_YUV 3
+
+#define AVIF_SPEED_DEFAULT -1
+#define AVIF_SPEED_SLOWEST 0
+#define AVIF_SPEED_FASTEST 10
+
+typedef enum avifPlanesFlag
+{
+    AVIF_PLANES_YUV = (1 << 0),
+    AVIF_PLANES_A = (1 << 1),
+
+    AVIF_PLANES_ALL = 0xff
+} avifPlanesFlag;
+typedef uint32_t avifPlanesFlags;
+
+typedef enum avifChannelIndex
+{
+    // These can be used as the index for the yuvPlanes and yuvRowBytes arrays in avifImage.
+    AVIF_CHAN_Y = 0,
+    AVIF_CHAN_U = 1,
+    AVIF_CHAN_V = 2
+} avifChannelIndex;
+
+// ---------------------------------------------------------------------------
+// Version
+
+AVIF_API const char * avifVersion(void);
+AVIF_API void avifCodecVersions(char outBuffer[256]);
+AVIF_API unsigned int avifLibYUVVersion(void); // returns 0 if libavif wasn't compiled with libyuv support
+
+// ---------------------------------------------------------------------------
+// Memory management
+
+AVIF_API void * avifAlloc(size_t size);
+AVIF_API void avifFree(void * p);
+
+// ---------------------------------------------------------------------------
+// avifResult
+
+typedef enum avifResult
+{
+    AVIF_RESULT_OK = 0,
+    AVIF_RESULT_UNKNOWN_ERROR,
+    AVIF_RESULT_INVALID_FTYP,
+    AVIF_RESULT_NO_CONTENT,
+    AVIF_RESULT_NO_YUV_FORMAT_SELECTED,
+    AVIF_RESULT_REFORMAT_FAILED,
+    AVIF_RESULT_UNSUPPORTED_DEPTH,
+    AVIF_RESULT_ENCODE_COLOR_FAILED,
+    AVIF_RESULT_ENCODE_ALPHA_FAILED,
+    AVIF_RESULT_BMFF_PARSE_FAILED,
+    AVIF_RESULT_NO_AV1_ITEMS_FOUND,
+    AVIF_RESULT_DECODE_COLOR_FAILED,
+    AVIF_RESULT_DECODE_ALPHA_FAILED,
+    AVIF_RESULT_COLOR_ALPHA_SIZE_MISMATCH,
+    AVIF_RESULT_ISPE_SIZE_MISMATCH,
+    AVIF_RESULT_NO_CODEC_AVAILABLE,
+    AVIF_RESULT_NO_IMAGES_REMAINING,
+    AVIF_RESULT_INVALID_EXIF_PAYLOAD,
+    AVIF_RESULT_INVALID_IMAGE_GRID,
+    AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION,
+    AVIF_RESULT_TRUNCATED_DATA,
+    AVIF_RESULT_IO_NOT_SET, // the avifIO field of avifDecoder is not set
+    AVIF_RESULT_IO_ERROR,
+    AVIF_RESULT_WAITING_ON_IO, // similar to EAGAIN/EWOULDBLOCK, this means the avifIO doesn't have necessary data available yet
+    AVIF_RESULT_INVALID_ARGUMENT, // an argument passed into this function is invalid
+    AVIF_RESULT_NOT_IMPLEMENTED,  // a requested code path is not (yet) implemented
+    AVIF_RESULT_OUT_OF_MEMORY,
+    AVIF_RESULT_CANNOT_CHANGE_SETTING, // a setting that can't change is changed during encoding
+    AVIF_RESULT_INCOMPATIBLE_IMAGE     // the image is incompatible with already encoded images
+} avifResult;
+
+AVIF_API const char * avifResultToString(avifResult result);
+
+// ---------------------------------------------------------------------------
+// avifROData/avifRWData: Generic raw memory storage
+
+typedef struct avifROData
+{
+    const uint8_t * data;
+    size_t size;
+} avifROData;
+
+// Note: Use avifRWDataFree() if any avif*() function populates one of these.
+
+typedef struct avifRWData
+{
+    uint8_t * data;
+    size_t size;
+} avifRWData;
+
+// clang-format off
+// Initialize avifROData/avifRWData on the stack with this
+#define AVIF_DATA_EMPTY { NULL, 0 }
+// clang-format on
+
+// The avifRWData input must be zero-initialized before being manipulated with these functions.
+AVIF_API void avifRWDataRealloc(avifRWData * raw, size_t newSize);
+AVIF_API void avifRWDataSet(avifRWData * raw, const uint8_t * data, size_t len);
+AVIF_API void avifRWDataFree(avifRWData * raw);
+
+// ---------------------------------------------------------------------------
+// avifPixelFormat
+//
+// Note to libavif maintainers: The lookup tables in avifImageYUVToRGBLibYUV
+// rely on the ordering of this enum values for their correctness. So changing
+// the values in this enum will require auditing avifImageYUVToRGBLibYUV for
+// correctness.
+typedef enum avifPixelFormat
+{
+    // No YUV pixels are present. Alpha plane can still be present.
+    AVIF_PIXEL_FORMAT_NONE = 0,
+
+    AVIF_PIXEL_FORMAT_YUV444,
+    AVIF_PIXEL_FORMAT_YUV422,
+    AVIF_PIXEL_FORMAT_YUV420,
+    AVIF_PIXEL_FORMAT_YUV400,
+    AVIF_PIXEL_FORMAT_COUNT
+} avifPixelFormat;
+AVIF_API const char * avifPixelFormatToString(avifPixelFormat format);
+
+typedef struct avifPixelFormatInfo
+{
+    avifBool monochrome;
+    int chromaShiftX;
+    int chromaShiftY;
+} avifPixelFormatInfo;
+
+AVIF_API void avifGetPixelFormatInfo(avifPixelFormat format, avifPixelFormatInfo * info);
+
+// ---------------------------------------------------------------------------
+// avifChromaSamplePosition
+
+typedef enum avifChromaSamplePosition
+{
+    AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN = 0,
+    AVIF_CHROMA_SAMPLE_POSITION_VERTICAL = 1,
+    AVIF_CHROMA_SAMPLE_POSITION_COLOCATED = 2
+} avifChromaSamplePosition;
+
+// ---------------------------------------------------------------------------
+// avifRange
+
+typedef enum avifRange
+{
+    AVIF_RANGE_LIMITED = 0,
+    AVIF_RANGE_FULL = 1
+} avifRange;
+
+// ---------------------------------------------------------------------------
+// CICP enums - https://www.itu.int/rec/T-REC-H.273-201612-I/en
+
+enum
+{
+    // This is actually reserved, but libavif uses it as a sentinel value.
+    AVIF_COLOR_PRIMARIES_UNKNOWN = 0,
+
+    AVIF_COLOR_PRIMARIES_BT709 = 1,
+    AVIF_COLOR_PRIMARIES_IEC61966_2_4 = 1,
+    AVIF_COLOR_PRIMARIES_UNSPECIFIED = 2,
+    AVIF_COLOR_PRIMARIES_BT470M = 4,
+    AVIF_COLOR_PRIMARIES_BT470BG = 5,
+    AVIF_COLOR_PRIMARIES_BT601 = 6,
+    AVIF_COLOR_PRIMARIES_SMPTE240 = 7,
+    AVIF_COLOR_PRIMARIES_GENERIC_FILM = 8,
+    AVIF_COLOR_PRIMARIES_BT2020 = 9,
+    AVIF_COLOR_PRIMARIES_XYZ = 10,
+    AVIF_COLOR_PRIMARIES_SMPTE431 = 11,
+    AVIF_COLOR_PRIMARIES_SMPTE432 = 12, // DCI P3
+    AVIF_COLOR_PRIMARIES_EBU3213 = 22
+};
+typedef uint16_t avifColorPrimaries; // AVIF_COLOR_PRIMARIES_*
+
+// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY
+AVIF_API void avifColorPrimariesGetValues(avifColorPrimaries acp, float outPrimaries[8]);
+AVIF_API avifColorPrimaries avifColorPrimariesFind(const float inPrimaries[8], const char ** outName);
+
+enum
+{
+    // This is actually reserved, but libavif uses it as a sentinel value.
+    AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN = 0,
+
+    AVIF_TRANSFER_CHARACTERISTICS_BT709 = 1,
+    AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED = 2,
+    AVIF_TRANSFER_CHARACTERISTICS_BT470M = 4,  // 2.2 gamma
+    AVIF_TRANSFER_CHARACTERISTICS_BT470BG = 5, // 2.8 gamma
+    AVIF_TRANSFER_CHARACTERISTICS_BT601 = 6,
+    AVIF_TRANSFER_CHARACTERISTICS_SMPTE240 = 7,
+    AVIF_TRANSFER_CHARACTERISTICS_LINEAR = 8,
+    AVIF_TRANSFER_CHARACTERISTICS_LOG100 = 9,
+    AVIF_TRANSFER_CHARACTERISTICS_LOG100_SQRT10 = 10,
+    AVIF_TRANSFER_CHARACTERISTICS_IEC61966 = 11,
+    AVIF_TRANSFER_CHARACTERISTICS_BT1361 = 12,
+    AVIF_TRANSFER_CHARACTERISTICS_SRGB = 13,
+    AVIF_TRANSFER_CHARACTERISTICS_BT2020_10BIT = 14,
+    AVIF_TRANSFER_CHARACTERISTICS_BT2020_12BIT = 15,
+    AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084 = 16, // PQ
+    AVIF_TRANSFER_CHARACTERISTICS_SMPTE428 = 17,
+    AVIF_TRANSFER_CHARACTERISTICS_HLG = 18
+};
+typedef uint16_t avifTransferCharacteristics; // AVIF_TRANSFER_CHARACTERISTICS_*
+
+enum
+{
+    AVIF_MATRIX_COEFFICIENTS_IDENTITY = 0,
+    AVIF_MATRIX_COEFFICIENTS_BT709 = 1,
+    AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED = 2,
+    AVIF_MATRIX_COEFFICIENTS_FCC = 4,
+    AVIF_MATRIX_COEFFICIENTS_BT470BG = 5,
+    AVIF_MATRIX_COEFFICIENTS_BT601 = 6,
+    AVIF_MATRIX_COEFFICIENTS_SMPTE240 = 7,
+    AVIF_MATRIX_COEFFICIENTS_YCGCO = 8,
+    AVIF_MATRIX_COEFFICIENTS_BT2020_NCL = 9,
+    AVIF_MATRIX_COEFFICIENTS_BT2020_CL = 10,
+    AVIF_MATRIX_COEFFICIENTS_SMPTE2085 = 11,
+    AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL = 12,
+    AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL = 13,
+    AVIF_MATRIX_COEFFICIENTS_ICTCP = 14
+};
+typedef uint16_t avifMatrixCoefficients; // AVIF_MATRIX_COEFFICIENTS_*
+
+// ---------------------------------------------------------------------------
+// avifDiagnostics
+
+typedef struct avifDiagnostics
+{
+    // Upon receiving an error from any non-const libavif API call, if the toplevel structure used
+    // in the API call (avifDecoder, avifEncoder) contains a diag member, this buffer may be
+    // populated with a NULL-terminated, freeform error string explaining the most recent error in
+    // more detail. It will be cleared at the beginning of every non-const API call.
+    //
+    // Note: If an error string contains the "[Strict]" prefix, it means that you encountered an
+    // error that only occurs during strict decoding. If you disable strict mode, you will no
+    // longer encounter this error.
+    char error[AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE];
+} avifDiagnostics;
+
+AVIF_API void avifDiagnosticsClearError(avifDiagnostics * diag);
+
+// ---------------------------------------------------------------------------
+// Optional transformation structs
+
+typedef enum avifTransformFlag
+{
+    AVIF_TRANSFORM_NONE = 0,
+
+    AVIF_TRANSFORM_PASP = (1 << 0),
+    AVIF_TRANSFORM_CLAP = (1 << 1),
+    AVIF_TRANSFORM_IROT = (1 << 2),
+    AVIF_TRANSFORM_IMIR = (1 << 3)
+} avifTransformFlag;
+typedef uint32_t avifTransformFlags;
+
+typedef struct avifPixelAspectRatioBox
+{
+    // 'pasp' from ISO/IEC 14496-12:2015 12.1.4.3
+
+    // define the relative width and height of a pixel
+    uint32_t hSpacing;
+    uint32_t vSpacing;
+} avifPixelAspectRatioBox;
+
+typedef struct avifCleanApertureBox
+{
+    // 'clap' from ISO/IEC 14496-12:2015 12.1.4.3
+
+    // a fractional number which defines the exact clean aperture width, in counted pixels, of the video image
+    uint32_t widthN;
+    uint32_t widthD;
+
+    // a fractional number which defines the exact clean aperture height, in counted pixels, of the video image
+    uint32_t heightN;
+    uint32_t heightD;
+
+    // a fractional number which defines the horizontal offset of clean aperture centre minus (width-1)/2. Typically 0.
+    uint32_t horizOffN;
+    uint32_t horizOffD;
+
+    // a fractional number which defines the vertical offset of clean aperture centre minus (height-1)/2. Typically 0.
+    uint32_t vertOffN;
+    uint32_t vertOffD;
+} avifCleanApertureBox;
+
+typedef struct avifImageRotation
+{
+    // 'irot' from ISO/IEC 23008-12:2017 6.5.10
+
+    // angle * 90 specifies the angle (in anti-clockwise direction) in units of degrees.
+    uint8_t angle; // legal values: [0-3]
+} avifImageRotation;
+
+typedef struct avifImageMirror
+{
+    // 'imir' from ISO/IEC 23008-12:2017 6.5.12 (Draft Amendment 2):
+    //
+    //     'mode' specifies how the mirroring is performed:
+    //
+    //     0 indicates that the top and bottom parts of the image are exchanged;
+    //     1 specifies that the left and right parts are exchanged.
+    //
+    //     NOTE In Exif, orientation tag can be used to signal mirroring operations. Exif
+    //     orientation tag 4 corresponds to mode = 0 of ImageMirror, and Exif orientation tag 2
+    //     corresponds to mode = 1 accordingly.
+    //
+    // Legal values: [0, 1]
+    //
+    // NOTE: As of HEIF Draft Amendment 2, the name of this variable has changed from 'axis' to 'mode' as
+    //       the logic behind it has been *inverted*. Please use the wording above describing the legal
+    //       values for 'mode' and update any code that previously may have used `axis` to use
+    //       the *opposite* value (0 now means top-to-bottom, where it used to mean left-to-right).
+    uint8_t mode;
+} avifImageMirror;
+
+// ---------------------------------------------------------------------------
+// avifCropRect - Helper struct/functions to work with avifCleanApertureBox
+
+typedef struct avifCropRect
+{
+    uint32_t x;
+    uint32_t y;
+    uint32_t width;
+    uint32_t height;
+} avifCropRect;
+
+// These will return AVIF_FALSE if the resultant values violate any standards, and if so, the output
+// values are not guaranteed to be complete or correct and should not be used.
+AVIF_API avifBool avifCropRectConvertCleanApertureBox(avifCropRect * cropRect,
+                                                      const avifCleanApertureBox * clap,
+                                                      uint32_t imageW,
+                                                      uint32_t imageH,
+                                                      avifPixelFormat yuvFormat,
+                                                      avifDiagnostics * diag);
+AVIF_API avifBool avifCleanApertureBoxConvertCropRect(avifCleanApertureBox * clap,
+                                                      const avifCropRect * cropRect,
+                                                      uint32_t imageW,
+                                                      uint32_t imageH,
+                                                      avifPixelFormat yuvFormat,
+                                                      avifDiagnostics * diag);
+
+// ---------------------------------------------------------------------------
+// avifImage
+
+typedef struct avifImage
+{
+    // Image information
+    uint32_t width;
+    uint32_t height;
+    uint32_t depth; // all planes must share this depth; if depth>8, all planes are uint16_t internally
+
+    avifPixelFormat yuvFormat;
+    avifRange yuvRange;
+    avifChromaSamplePosition yuvChromaSamplePosition;
+    uint8_t * yuvPlanes[AVIF_PLANE_COUNT_YUV];
+    uint32_t yuvRowBytes[AVIF_PLANE_COUNT_YUV];
+    avifBool imageOwnsYUVPlanes;
+
+    uint8_t * alphaPlane;
+    uint32_t alphaRowBytes;
+    avifBool imageOwnsAlphaPlane;
+    avifBool alphaPremultiplied;
+
+    // ICC Profile
+    avifRWData icc;
+
+    // CICP information:
+    // These are stored in the AV1 payload and used to signal YUV conversion. Additionally, if an
+    // ICC profile is not specified, these will be stored in the AVIF container's `colr` box with
+    // a type of `nclx`. If your system supports ICC profiles, be sure to check for the existence
+    // of one (avifImage.icc) before relying on the values listed here!
+    avifColorPrimaries colorPrimaries;
+    avifTransferCharacteristics transferCharacteristics;
+    avifMatrixCoefficients matrixCoefficients;
+
+    // Transformations - These metadata values are encoded/decoded when transformFlags are set
+    // appropriately, but do not impact/adjust the actual pixel buffers used (images won't be
+    // pre-cropped or mirrored upon decode). Basic explanations from the standards are offered in
+    // comments above, but for detailed explanations, please refer to the HEIF standard (ISO/IEC
+    // 23008-12:2017) and the BMFF standard (ISO/IEC 14496-12:2015).
+    //
+    // To encode any of these boxes, set the values in the associated box, then enable the flag in
+    // transformFlags. On decode, only honor the values in boxes with the associated transform flag set.
+    avifTransformFlags transformFlags;
+    avifPixelAspectRatioBox pasp;
+    avifCleanApertureBox clap;
+    avifImageRotation irot;
+    avifImageMirror imir;
+
+    // Metadata - set with avifImageSetMetadata*() before write, check .size>0 for existence after read
+    avifRWData exif;
+    avifRWData xmp;
+} avifImage;
+
+AVIF_API avifImage * avifImageCreate(uint32_t width, uint32_t height, uint32_t depth, avifPixelFormat yuvFormat);
+AVIF_API avifImage * avifImageCreateEmpty(void); // helper for making an image to decode into
+AVIF_API avifResult avifImageCopy(avifImage * dstImage, const avifImage * srcImage, avifPlanesFlags planes); // deep copy
+AVIF_API avifResult avifImageSetViewRect(avifImage * dstImage, const avifImage * srcImage, const avifCropRect * rect); // shallow copy, no metadata
+AVIF_API void avifImageDestroy(avifImage * image);
+
+AVIF_API void avifImageSetProfileICC(avifImage * image, const uint8_t * icc, size_t iccSize);
+// Sets Exif metadata. Attempts to parse the Exif metadata for Exif orientation. Sets
+// image->transformFlags, image->irot and image->imir if the Exif metadata is parsed successfully,
+// otherwise leaves image->transformFlags, image->irot and image->imir unchanged.
+// Warning: If the Exif payload is set and invalid, avifEncoderWrite() may return AVIF_RESULT_INVALID_EXIF_PAYLOAD.
+AVIF_API void avifImageSetMetadataExif(avifImage * image, const uint8_t * exif, size_t exifSize);
+// Sets XMP metadata.
+AVIF_API void avifImageSetMetadataXMP(avifImage * image, const uint8_t * xmp, size_t xmpSize);
+
+AVIF_API avifResult avifImageAllocatePlanes(avifImage * image, avifPlanesFlags planes); // Ignores any pre-existing planes
+AVIF_API void avifImageFreePlanes(avifImage * image, avifPlanesFlags planes);           // Ignores already-freed planes
+AVIF_API void avifImageStealPlanes(avifImage * dstImage, avifImage * srcImage, avifPlanesFlags planes);
+
+// ---------------------------------------------------------------------------
+// Understanding maxThreads
+//
+// libavif's structures and API use the setting 'maxThreads' in a few places. The intent of this
+// setting is to limit concurrent thread activity/usage, not necessarily to put a hard ceiling on
+// how many sleeping threads happen to exist behind the scenes. The goal of this setting is to
+// ensure that at any given point during libavif's encoding or decoding, no more than *maxThreads*
+// threads are simultaneously **active and taking CPU time**.
+//
+// As an important example, when encoding an image sequence that has an alpha channel, two
+// long-lived underlying AV1 encoders must simultaneously exist (one for color, one for alpha). For
+// each additional frame fed into libavif, its YUV planes are fed into one instance of the AV1
+// encoder, and its alpha pla

(Patch may be truncated, please check the link at the top of this post.)