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.)