Browse Source

Added option to build with libheif.

Бранимир Караџић 1 year ago
parent
commit
c4268ed766
5 changed files with 78 additions and 3 deletions
  1. 6 0
      scripts/bimg_decode.lua
  2. 5 0
      scripts/genie.lua
  3. 8 0
      scripts/texturec.lua
  4. 4 0
      src/config.h
  5. 55 3
      src/image_decode.cpp

+ 6 - 0
scripts/bimg_decode.lua

@@ -17,6 +17,12 @@ project "bimg_decode"
 		path.join(BIMG_DIR, "src/image_decode.*"),
 	}
 
+	if _OPTIONS["with-libheif"] then
+		defines {
+			"BIMG_DECODE_HEIF=1",
+		}
+	end
+
 	using_bx()
 
 	configuration { "linux-*" }

+ 5 - 0
scripts/genie.lua

@@ -18,6 +18,11 @@ newoption {
 	description = "Enable building tools.",
 }
 
+newoption {
+	trigger = "with-libheif",
+	description = "Enable building with libheif HEIF and AVIF file format decoder.",
+}
+
 solution "bimg"
 	configurations {
 		"Debug",

+ 8 - 0
scripts/texturec.lua

@@ -21,6 +21,14 @@ project "texturec"
 		"bimg",
 	}
 
+	if _OPTIONS["with-libheif"] then
+		links {
+			"heif",
+		}
+
+		configuration {}
+	end
+
 	using_bx()
 
 	configuration { "mingw-*" }

+ 4 - 0
src/config.h

@@ -56,4 +56,8 @@
 #	define BIMG_DECODE_ETC2 BIMG_DECODE_ENABLE
 #endif // BIMG_DECODE_ETC2
 
+#ifndef BIMG_DECODE_HEIF
+#	define BIMG_DECODE_HEIF 0
+#endif // BIMG_DECODE_HEIF
+
 #endif // BIMG_CONFIG_H_HEADER_GUARD

+ 55 - 3
src/image_decode.cpp

@@ -34,6 +34,10 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4334) // warning C4334: '<<' : result of 32 -
 #include <lodepng/lodepng.cpp>
 BX_PRAGMA_DIAGNOSTIC_POP();
 
+#if BIMG_DECODE_HEIF
+#	include <libheif/heif.h>
+#endif // BIMG_DECODE_HEIF
+
 void* lodepng_malloc(size_t _size)
 {
 	return ::malloc(_size);
@@ -632,7 +636,6 @@ namespace bimg
 			output->m_hasAlpha = hasAlpha;
 		}
 
-
 		return output;
 	}
 
@@ -679,8 +682,8 @@ namespace bimg
 
 		ImageContainer* output = imageAlloc(_allocator
 			, format
-			, uint16_t(width)
-			, uint16_t(height)
+			, bx::narrowCast<uint16_t>(width)
+			, bx::narrowCast<uint16_t>(height)
 			, 0
 			, 1
 			, false
@@ -828,6 +831,54 @@ namespace bimg
 		return image;
 	}
 
+	static ImageContainer* imageParseLibHeif(bx::AllocatorI* _allocator, const void* _data, uint32_t _size, bx::Error* _err)
+	{
+#if BIMG_DECODE_HEIF
+		heif_context* ctx = heif_context_alloc();
+
+		heif_context_read_from_memory_without_copy(ctx, _data, _size, NULL);
+
+		heif_image_handle* handle;
+		heif_context_get_primary_image_handle(ctx, &handle);
+
+		heif_image* image;
+		heif_decode_image(handle, &image, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, NULL);
+
+		int32_t stride;
+		const uint8_t* data = heif_image_get_plane_readonly(image, heif_channel_interleaved, &stride);
+
+		ImageContainer* output = NULL;
+		if (NULL != data)
+		{
+			const bimg::TextureFormat::Enum format = bimg::TextureFormat::RGBA8;
+			const int32_t width  = heif_image_handle_get_width(handle);
+			const int32_t height = heif_image_handle_get_height(handle);
+
+			output = imageAlloc(_allocator
+				, format
+				, bx::narrowCast<uint16_t>(width)
+				, bx::narrowCast<uint16_t>(height)
+				, 0
+				, 1
+				, false
+				, false
+				, data
+				);
+		}
+
+		heif_image_release(image);
+		heif_image_handle_release(handle);
+
+		heif_context_free(ctx);
+
+		BX_UNUSED(_err);
+		return output;
+#else
+		BX_UNUSED(_allocator, _data, _size, _err);
+		return NULL;
+#endif // BIMG_DECODE_HEIF
+	}
+
 	ImageContainer* imageParse(bx::AllocatorI* _allocator, const void* _data, uint32_t _size, TextureFormat::Enum _dstFormat, bx::Error* _err)
 	{
 		BX_ERROR_SCOPE(_err);
@@ -840,6 +891,7 @@ namespace bimg
 		input = NULL == input ? imageParseTinyExr (_allocator, _data, _size, _err) : input;
 		input = NULL == input ? imageParseJpeg    (_allocator, _data, _size, _err) : input;
 		input = NULL == input ? imageParseStbImage(_allocator, _data, _size, _err) : input;
+		input = NULL == input ? imageParseLibHeif (_allocator, _data, _size, _err) : input;
 
 		if (NULL == input)
 		{