Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add libavif/0.9.3 #9225

Merged
merged 7 commits into from
Feb 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions recipes/libavif/all/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.1)
project(libavif_wrapper C)

include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
conan_basic_setup(TARGETS KEEP_RPATHS)

add_subdirectory(source_subfolder)
10 changes: 10 additions & 0 deletions recipes/libavif/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sources:
"0.9.3":
sha256: "bcd9a1f57f982a9615eb7e2faf87236dc88eb1d0c886f3471c7440ead605060d"
url: https://github.com/AOMediaCodec/libavif/archive/refs/tags/v0.9.3.tar.gz
patches:
"0.9.3":
- patch_file: patches/0001-disable-developer-only-codepaths.patch
base_path: source_subfolder
- patch_file: patches/0002-fix-libyuv-version-handling.patch
base_path: source_subfolder
123 changes: 123 additions & 0 deletions recipes/libavif/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import functools
import os
import textwrap

from conans import ConanFile, CMake, tools

required_conan_version = ">=1.43.0"


class LibAVIFConan(ConanFile):
name = "libavif"
description = "Library for encoding and decoding .avif files"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/AOMediaCodec/libavif"
topics = "avif"
license = "BSD-2-Clause"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_decoder": ["aom", "dav1d"],
}
default_options = {
"shared": False,
"fPIC": True,
"with_decoder": "dav1d",
}
generators = "cmake", "cmake_find_package_multi"
exports_sources = "CMakeLists.txt", "patches/*"

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if self.options.shared:
del self.options.fPIC
del self.settings.compiler.libcxx
del self.settings.compiler.cppstd

@property
def _has_dav1d(self):
return self.options.with_decoder == "dav1d"

def requirements(self):
self.requires("libaom-av1/3.1.2")
self.requires("libyuv/cci.20201106")
if self._has_dav1d:
self.requires("dav1d/0.9.1")

@property
def _source_subfolder(self):
return "source_subfolder"

def source(self):
root = self._source_subfolder
get_args = self.conan_data["sources"][self.version]
tools.get(**get_args, destination=root, strip_root=True)

@functools.lru_cache(1)
def _configure_cmake(self):
cmake = CMake(self)
cmake.definitions["AVIF_CODEC_AOM"] = True

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If self.options.shared is true, should we pass -DBUILD_SHARED_LIBS=ON to the cmake command for libavif?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's handled automatically by Conan.

if self._has_dav1d:
cmake.definitions["AVIF_CODEC_DAV1D"] = True
cmake.definitions["AVIF_CODEC_AOM_DECODE"] = False
cmake.configure()
return cmake

def build(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
self._configure_cmake().build()

@property
def _alias_path(self):
return os.path.join("lib", "conan-official-avif-targets.cmake")

def package(self):
self.copy("LICENSE", "licenses", self._source_subfolder)
self._configure_cmake().install()
tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig"))

# TODO: remove in conan v2
alias = os.path.join(self.package_folder, self._alias_path)
content = textwrap.dedent("""\
if(TARGET avif::avif AND NOT TARGET avif)
add_library(avif INTERFACE IMPORTED)
set_property(
TARGET avif PROPERTY
INTERFACE_LINK_LIBRARIES avif::avif
)
endif()
""")
tools.save(alias, content)

def package_info(self):
self.cpp_info.requires = ["libyuv::libyuv", "libaom-av1::libaom-av1"]
if self._has_dav1d:
self.cpp_info.requires.append("dav1d::dav1d")

self.cpp_info.libs = ["avif"]
if self.options.shared:
self.cpp_info.defines = ["AVIF_DLL"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<avif/avif.h> has the following comment:

// AVIF_DLL should be defined if libavif is a shared library. If you are using
// libavif as CMake dependency, through CMake package config file or through
// pkg-config, this is defined automatically.

Since you seem to be defining AVIF_DLL manually, does this mean you are not using libavif as CMake dependency or through pkg-config?

Copy link
Contributor Author

@friendlyanon friendlyanon Feb 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMake package configs generated by projects are discarded as per Conan Center Index policy. Conan regenerates CMake package configs at install time using its own generators.

if self.settings.os != "Windows":
self.cpp_info.system_libs = ["pthread", "m"]
if self.settings.os == "Linux" and self._has_dav1d:
self.cpp_info.system_libs.append("dl")

self.cpp_info.set_property("cmake_file_name", "libavif")
self.cpp_info.set_property("cmake_target_name", "avif")

# TODO: remove in conan v2
self.cpp_info.names["cmake_find_package"] = "avif"
self.cpp_info.names["cmake_find_package_multi"] = "avif"
self.cpp_info.filenames["cmake_find_package"] = "libavif"
self.cpp_info.filenames["cmake_find_package_multi"] = "libavif"
self.cpp_info.build_modules["cmake"] = [self._alias_path]
self.cpp_info.build_modules["cmake_find_package"] = [self._alias_path]
self.cpp_info.build_modules["cmake_find_package_multi"] = \
[self._alias_path]
self.cpp_info.builddirs = ["lib"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -48,7 +48,7 @@
if(AVIF_LOCAL_LIBGAV1)
enable_language(CXX)
endif()
-
+if("0")
if(APPLE)
set(XCRUN xcrun)
else()
@@ -193,7 +193,7 @@
message(WARNING "libavif: Ignoring request for coverage (AVIF_ENABLE_COVERAGE); only clang is currently supported.")
endif()
endif()
-
+endif()
set(AVIF_SRCS
src/alpha.c
src/avif.c
73 changes: 73 additions & 0 deletions recipes/libavif/all/patches/0002-fix-libyuv-version-handling.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
From ded15fb7b41b0513e138ba457034a2fb91c1f2c9 Mon Sep 17 00:00:00 2001
From: Bruno Pagani <bruno.n.pagani@gmail.com>
Date: Thu, 4 Nov 2021 21:05:15 +0400
Subject: [PATCH] =?UTF-8?q?Fix=20compilation=20with=201755=20=E2=89=A4=20L?=
=?UTF-8?q?IBYUV=5FVERSION=20<=201774?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ScalePlane_12 only provide optimization for 2x scale up using
linear/bilinear filter (when scaling up, box and bilinear are the same),
and for the rest cases, it simply calls ScalePlane_16, which handles 2x
scale up just fine (slower though).

This optimization is thus optional and compilation can be allowed for
libyuv versions not providing it.

Fixes GH-781 (the function was introduced in libavif
https://github.com/AOMediaCodec/libavif/commit/46104d6db42ec2a94a7da6fc0693f24fa90a1b98).
---
CMakeLists.txt | 4 ++++
src/scale.c | 8 ++++++++
2 files changed, 12 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3fc76dfb..e18156d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -233,12 +233,16 @@ endif()
find_package(libyuv QUIET) # not required
if(libyuv_FOUND)
# libyuv 1755 exposed all of the I*Matrix() functions, which libavif relies on.
+ # libyuv 1774 exposed ScalePlane_12 function, which libavif can use for some additional optimizations.
if(NOT LIBYUV_VERSION)
message(STATUS "libavif: libyuv found, but version unknown; libyuv-based fast paths disabled.")
elseif(LIBYUV_VERSION LESS 1755)
message(STATUS "libavif: libyuv (${LIBYUV_VERSION}) found, but is too old; libyuv-based fast paths disabled.")
else()
message(STATUS "libavif: libyuv (${LIBYUV_VERSION}) found; libyuv-based fast paths enabled.")
+ if(LIBYUV_VERSION LESS 1774)
+ message(STATUS "libavif: some libyuv optimizations require at least version 1774 to work.")
+ endif()
set(AVIF_PLATFORM_DEFINITIONS ${AVIF_PLATFORM_DEFINITIONS} -DAVIF_LIBYUV_ENABLED=1)
set(AVIF_PLATFORM_INCLUDES ${AVIF_PLATFORM_INCLUDES} ${LIBYUV_INCLUDE_DIR})
set(AVIF_PLATFORM_LIBRARIES ${AVIF_PLATFORM_LIBRARIES} ${LIBYUV_LIBRARY})
diff --git a/src/scale.c b/src/scale.c
index 6ca651b2..1bbbdd86 100644
--- a/src/scale.c
+++ b/src/scale.c
@@ -107,7 +107,11 @@ avifBool avifImageScale(avifImage * image, uint32_t dstWidth, uint32_t dstHeight
const uint32_t srcStride = srcYUVRowBytes[i] / 2;
uint16_t * const dstPlane = (uint16_t *)image->yuvPlanes[i];
const uint32_t dstStride = image->yuvRowBytes[i] / 2;
+#if LIBYUV_VERSION >= 1774
ScalePlane_12(srcPlane, srcStride, srcW, srcH, dstPlane, dstStride, dstW, dstH, AVIF_LIBYUV_FILTER_MODE);
+#else
+ ScalePlane_16(srcPlane, srcStride, srcW, srcH, dstPlane, dstStride, dstW, dstH, AVIF_LIBYUV_FILTER_MODE);
+#endif
} else {
uint8_t * const srcPlane = srcYUVPlanes[i];
const uint32_t srcStride = srcYUVRowBytes[i];
@@ -130,7 +134,11 @@ avifBool avifImageScale(avifImage * image, uint32_t dstWidth, uint32_t dstHeight
const uint32_t srcStride = srcAlphaRowBytes / 2;
uint16_t * const dstPlane = (uint16_t *)image->alphaPlane;
const uint32_t dstStride = image->alphaRowBytes / 2;
+#if LIBYUV_VERSION >= 1774
ScalePlane_12(srcPlane, srcStride, srcWidth, srcHeight, dstPlane, dstStride, dstWidth, dstHeight, AVIF_LIBYUV_FILTER_MODE);
+#else
+ ScalePlane_16(srcPlane, srcStride, srcWidth, srcHeight, dstPlane, dstStride, dstWidth, dstHeight, AVIF_LIBYUV_FILTER_MODE);
+#endif
} else {
uint8_t * const srcPlane = srcAlphaPlane;
const uint32_t srcStride = srcAlphaRowBytes;
10 changes: 10 additions & 0 deletions recipes/libavif/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.1)
project(test_package C)

include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
conan_basic_setup(TARGETS KEEP_RPATHS)

find_package(libavif REQUIRED CONFIG)

add_executable(test_package test_package.c)
target_link_libraries(test_package PRIVATE avif)
18 changes: 18 additions & 0 deletions recipes/libavif/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os

from conans import ConanFile, CMake, tools


class TestPackageConan(ConanFile):
settings = ("os", "compiler", "build_type", "arch")
generators = ("cmake", "cmake_find_package_multi")

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
12 changes: 12 additions & 0 deletions recipes/libavif/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <avif/avif.h>
#include <stddef.h>

int main(int argc, char const* argv[])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard prototype of the main() function does not have the "const":

int main(int argc, char* argv[])

See https://en.cppreference.com/w/c/language/main_function

Also, there is an alternative prototype that you can use here to avoid the (void)argc and (void)argv casts.

int main(void)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All true, I just had such a template I have been using to make recipes. Adding const is also inconsequential in C.
Regardless, I have edited my template and will avoid doing this in the future.

{
(void)argc;
(void)argv;

avifFree(NULL);

return 0;
}
3 changes: 3 additions & 0 deletions recipes/libavif/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"0.9.3":
folder: all