SDL_image: Xcode and Visual Studio project file fixes/updates from SDL3 branch

From 02b943216a8cd9333a82c468e08521cf1f685647 Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Fri, 25 Aug 2023 23:00:32 +0300
Subject: [PATCH] Xcode and Visual Studio project file fixes/updates from SDL3
 branch

Xcode:
- added missing webpdemux sources
- fixed showimage.c path

Visual Studio:
- added avif support
- added missing webpdemux dependencies and defines
- fixed showimage.c path
---
 VisualC/SDL_image.vcxproj                     |    8 +-
 VisualC/external/include/avif/avif.h          | 1115 +++++++++++++++++
 .../external/optional/x64/LICENSE.avif.txt    |  353 ++++++
 .../external/optional/x64/LICENSE.dav1d.txt   |   23 +
 VisualC/external/optional/x64/libavif.dll     |  Bin 0 -> 2232320 bytes
 .../external/optional/x64/libwebpdemux-2.dll  |  Bin 0 -> 21504 bytes
 .../external/optional/x86/LICENSE.avif.txt    |  353 ++++++
 .../external/optional/x86/LICENSE.dav1d.txt   |   23 +
 VisualC/external/optional/x86/libavif.dll     |  Bin 0 -> 1515520 bytes
 .../external/optional/x86/libwebpdemux-2.dll  |  Bin 0 -> 19968 bytes
 VisualC/showimage/showimage.vcxproj           |    2 +-
 VisualC/showimage/showimage.vcxproj.filters   |    2 +-
 .../showimage.xcodeproj/project.pbxproj       |    2 +-
 Xcode/webp/webp.xcodeproj/project.pbxproj     |    8 +
 14 files changed, 1882 insertions(+), 7 deletions(-)
 create mode 100644 VisualC/external/include/avif/avif.h
 create mode 100644 VisualC/external/optional/x64/LICENSE.avif.txt
 create mode 100644 VisualC/external/optional/x64/LICENSE.dav1d.txt
 create mode 100644 VisualC/external/optional/x64/libavif.dll
 create mode 100644 VisualC/external/optional/x64/libwebpdemux-2.dll
 create mode 100644 VisualC/external/optional/x86/LICENSE.avif.txt
 create mode 100644 VisualC/external/optional/x86/LICENSE.dav1d.txt
 create mode 100644 VisualC/external/optional/x86/libavif.dll
 create mode 100644 VisualC/external/optional/x86/libwebpdemux-2.dll

diff --git a/VisualC/SDL_image.vcxproj b/VisualC/SDL_image.vcxproj
index b53541a9..f12066bd 100644
--- a/VisualC/SDL_image.vcxproj
+++ b/VisualC/SDL_image.vcxproj
@@ -108,7 +108,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\include;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="libavif.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="libwebpdemux-2.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -136,7 +136,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\include;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="libavif.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="libwebpdemux-2.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
@@ -165,7 +165,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\include;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="libavif.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="libwebpdemux-2.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
@@ -191,7 +191,7 @@
     </Midl>
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\include;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="libavif.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="libwebpdemux-2.dll";LOAD_XCF;LOAD_XPM;LOAD_XV;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
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 plane is fed into another. These operations happen serially, so only one
+// of these AV1 encoders is ever active at a time. However, the AV1 encoders might pre-create a
+// pool of worker threads upon initialization, so during this process, twice the amount of worker
+// threads actually simultaneously exist on the machine, but half of them are guaranteed to be
+// sleeping.
+//
+// This design ensures that AV1 implementations are given as many threads as possible to ensure a
+// speedy encode or decode, despite the complexities of occasionally needing two AV1 codec instances
+// (due to alpha payloads being separate from color payloads). If your system has a hard ceiling on
+// the number of threads that can ever be in flight at a given time, please account for this
+// accordingly.
+
+// ---------------------------------------------------------------------------
+// Optional YUV<->RGB support
+
+// To convert to/from RGB, create an avifRGBImage on the stack, call avifRGBImageSetDefaults() on
+// it, and then tweak the values inside of it accordingly. At a minimum, you should populate
+// ->pixels and ->rowBytes with an appropriately sized pixel buffer, which should be at least
+// (->rowBytes * ->height) bytes, where ->rowBytes is at least (->width * avifRGBImagePixelSize()).
+// If you don't want to supply your own pixel buffer, you can use the
+// avifRGBImageAllocatePixels()/avifRGBImageFreePixels() convenience functions.
+
+// avifImageRGBToYUV() and avifImageYUVToRGB() will perform depth rescaling and limited<->full range
+// conversion, if necessary. Pixels in an avifRGBImage buffer are always full range, and conversion
+// routines will fail if the width and height don't match the associated avifImage.
+
+// If libavif is built with a version of libyuv offering a fast conversion between RGB and YUV for
+// the given inputs, libavif will use it. See reformat_libyuv.c for the details.
+// libyuv is faster but may have slightly less precision than built-in conversion, so avoidLibYUV
+// can be set to AVIF_TRUE when AVIF_CHROMA_UPSAMPLING_BEST_QUALITY or
+// AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY is used, to get the most precise but slowest results.
+
+// 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 avifRGBFormat
+{
+    AVIF_RGB_FORMAT_RGB = 0,
+    AVIF_RGB_FORMAT_RGBA, // This is the default format set in avifRGBImageSetDefaults().
+    AVIF_RGB_FORMAT_ARGB,
+    AVIF_RGB_FORMAT_BGR,
+    AVIF_RGB_FORMAT_BGRA,
+    AVIF_RGB_FORMAT_ABGR,
+    // RGB_565 format uses five bits for the red and blue components and six
+    // bits for the green component. Each RGB pixel is 16 bits (2 bytes), which
+    // is packed as follows:
+    //   uint16_t: [r4 r3 r2 r1 r0 g5 g4 g3 g2 g1 g0 b4 b3 b2 b1 b0]
+    //   r4 and r0 are the MSB and LSB of the red component respectively.
+    //   g5 and g0 are the MSB and LSB of the green component respectively.
+    //   b4 and b0 are the MSB and LSB of the blue component respectively.
+    // This format is only supported for YUV -> RGB conversion and when
+    // avifRGBImage.depth is set to 8.
+    AVIF_RGB_FORMAT_RGB_565,
+    AVIF_RGB_FORMAT_COUNT
+} avifRGBFormat;
+AVIF_API uint32_t avifRGBFormatChannelCount(avifRGBFormat format);
+AVIF_API avifBool avifRGBFormatHasAlpha(avifRGBFormat format);
+
+typedef enum avifChromaUpsampling
+{
+    AVIF_CHROMA_UPSAMPLING_AUTOMATIC = 0,    // Chooses best trade off of speed/quality (uses BILINEAR libyuv if available,
+                                             // or falls back to NEAREST libyuv if available, or falls back to BILINEAR built-in)
+    AVIF_CHROMA_UPSAMPLING_FASTEST = 1,      // Chooses speed over quality (same as NEAREST)
+    AVIF_CHROMA_UPSAMPLING_BEST_QUALITY = 2, // Chooses the best quality upsampling, given settings (same as BILINEAR)
+    AVIF_CHROMA_UPSAMPLING_NEAREST = 3,      // Uses nearest-neighbor filter
+    AVIF_CHROMA_UPSAMPLING_BILINEAR = 4      // Uses bilinear filter
+} avifChromaUpsampling;
+
+typedef enum avifChromaDownsampling
+{
+    AVIF_CHROMA_DOWNSAMPLING_AUTOMATI

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