Skip to content

Commit

Permalink
Use local copies of ScalePlane* functions when libyuv is not found
Browse files Browse the repository at this point in the history
Partial import of libyuv to third_party/libyuv (new LICENSE).
Implement avifImageScale() fallback when libyuv is not available.
  • Loading branch information
Cacodemon345 committed Sep 8, 2023
1 parent a120c6f commit 808bf58
Show file tree
Hide file tree
Showing 19 changed files with 2,250 additions and 27 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Add the headerFormat member of new type avifHeaderFormat to avifEncoder.
* Add experimental API for reading and writing "avir"-branded AVIF files
behind the compilation flag AVIF_ENABLE_EXPERIMENTAL_AVIR.
* Implement avifImageScale() fallback when libyuv is not available.
* Partial import of libyuv to third_party/libyuv (new LICENSE).
* Add avifenc flag suffixes ":update" and ":u". Quality-relative,
tiling-relative and codec-specific flags can now be positional, relative to
input files.
Expand Down
20 changes: 20 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,23 @@ set(AVIF_CODEC_DEFINITIONS)
set(AVIF_CODEC_INCLUDES)
set(AVIF_CODEC_LIBRARIES)

if(NOT libyuv_FOUND)
set(AVIF_SRCS ${AVIF_SRCS}
third_party/libyuv/source/scale.c
third_party/libyuv/source/scale_common.c
third_party/libyuv/source/scale_any.c
third_party/libyuv/source/row_common.c
third_party/libyuv/source/planar_functions.c
)
if(DEFINED ANDROID_ABI OR DEFINED APPLE)
# When building third_party/libyuv/source/scale.c, some functions use
# some of the parameters only inside an assert statement. This causes
# unused parameter warnings when building for Android. Suppress the
# warning in that case.
add_compile_options(-Wno-unused-parameter)
endif()
endif()

if(AVIF_CODEC_DAV1D)
set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_DAV1D=1)
set(AVIF_SRCS ${AVIF_SRCS} src/codec_dav1d.c)
Expand Down Expand Up @@ -537,6 +554,9 @@ target_include_directories(
avif PUBLIC $<BUILD_INTERFACE:${libavif_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include> PRIVATE ${AVIF_PLATFORM_INCLUDES}
${AVIF_CODEC_INCLUDES}
)
if(NOT libyuv_FOUND)
target_include_directories(avif PRIVATE ${libavif_SOURCE_DIR}/third_party/libyuv/include/)
endif()
set(AVIF_PKG_CONFIG_EXTRA_CFLAGS "")
if(BUILD_SHARED_LIBS)
target_compile_definitions(avif PUBLIC AVIF_DLL PRIVATE AVIF_BUILDING_SHARED_LIBS)
Expand Down
23 changes: 0 additions & 23 deletions src/scale.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,6 @@
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/internal.h"

#if !defined(AVIF_LIBYUV_ENABLED)

avifBool avifImageScale(avifImage * image,
uint32_t dstWidth,
uint32_t dstHeight,
uint32_t imageSizeLimit,
uint32_t imageDimensionLimit,
avifDiagnostics * diag)
{
(void)image;
(void)dstWidth;
(void)dstHeight;
(void)imageSizeLimit;
(void)imageDimensionLimit;
avifDiagnosticsPrintf(diag, "avifImageScale() called, but is unimplemented without libyuv!");
return AVIF_FALSE;
}

#else

#include <limits.h>

#if defined(__clang__)
Expand Down Expand Up @@ -173,5 +152,3 @@ avifBool avifImageScale(avifImage * image,

return AVIF_TRUE;
}

#endif
4 changes: 0 additions & 4 deletions tests/gtest/avifscaletest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ class ScaleTest
/*create_alpha=*/bool>> {};

TEST_P(ScaleTest, Roundtrip) {
if (avifLibYUVVersion() == 0) {
GTEST_SKIP() << "libyuv not available, skip test.";
}

const int bit_depth = std::get<0>(GetParam());
const avifPixelFormat yuv_format = std::get<1>(GetParam());
const bool create_alpha = std::get<2>(GetParam());
Expand Down
17 changes: 17 additions & 0 deletions third_party/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# libavif third party sources

Anything in this directory is imported from third party sources with minimal changes.

See `LICENSE` file of respective subdirectories of this directory for license information.

# libyuv
This subdirectory contains source code imported from libyuv as of `c60323de1756f489bd061e66aea9c3c73a8ef72c`, with modifications intended to keep them relatively small and simple.

# Importing from upstream

This comment has been minimized.

Copy link
@wantehchang

wantehchang Sep 12, 2023

Collaborator

This should be a subsection (with two # signs) within the "libyuv" section that starts at line 7, otherwise the heading looks like general guidance on importing third-party sources from upstream:

## Importing from upstream

Also, it seems better to move the libyuv part of this file (lines 7-17) into the third_party/libyuv/ directory, perhaps renamed README.libavif.md.

This comment has been minimized.

Copy link
@y-guyon

y-guyon Sep 12, 2023

Collaborator

Also, it seems better to move the libyuv part of this file (lines 7-17) into the third_party/libyuv/ directory, perhaps renamed README.libavif.md.

I suggested the opposite in #1534 (comment).

This comment has been minimized.

Copy link
@wantehchang

wantehchang Sep 12, 2023

Collaborator

In the Chromium source tree and Google's internal repository, this is handled by naming the additional README files "README.chromium" and "README.google" or "README.google.md", respectively. Under this convention, we would name our additional README file "README.libavif.md".

The current setup is also fine.

When importing source code from upstream libyuv, the following changes must be done:
1. Source hierachy is to be kept the same as in libyuv.
2. The only APIs that are called by libavif for scaling are `ScalePlane` and `ScalePlane_12`. Anything else must be left out.
3. In function `ScalePlane` and `ScalePlane_16`, only the `ScalePlaneVertical`, `CopyPlane`, `ScalePlaneBox`, `ScalePlaneUp2_Linear`, `ScalePlaneUp2_Bilinear`, `ScalePlaneBilinearUp`, `ScalePlaneBilinearDown` and `ScalePlaneSimple` paths (and their `_16` equivalents) from libyuv must be kept; any other paths are to be stripped out (including SIMD).
4. The commit hash of libyuv from where the files got imported in this README.md file must be updated if possible.
5. `LIBYUV_API` must be removed from any and all imported functions as these files are always built static.
6. Replace .cc file extension by .c.
6 changes: 6 additions & 0 deletions third_party/libyuv/AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Names should be added to this file like so:
# Name or Organization <email address>

Google Inc.

Ivan Pavlotskiy <ivan.pavlotskiy@lgepartner.com>
29 changes: 29 additions & 0 deletions third_party/libyuv/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Copyright 2011 The LibYuv Project Authors. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

* Neither the name of Google nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 changes: 21 additions & 0 deletions third_party/libyuv/include/libyuv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#ifndef INCLUDE_LIBYUV_H_
#define INCLUDE_LIBYUV_H_

#include "libyuv/basic_types.h"
#include "libyuv/planar_functions.h"
#include "libyuv/row.h"
#include "libyuv/scale.h"
#include "libyuv/scale_row.h"
#include "libyuv/version.h"

#endif // INCLUDE_LIBYUV_H_
68 changes: 68 additions & 0 deletions third_party/libyuv/include/libyuv/basic_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_
#define INCLUDE_LIBYUV_BASIC_TYPES_H_

#include <stddef.h> // For size_t and NULL

#if !defined(INT_TYPES_DEFINED) && !defined(GG_LONGLONG)
#define INT_TYPES_DEFINED

#if defined(_MSC_VER) && (_MSC_VER < 1600)
#include <sys/types.h> // for uintptr_t on x86
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
#else
#include <stdint.h> // for uintptr_t and C99 types
#endif // defined(_MSC_VER) && (_MSC_VER < 1600)
// Types are deprecated. Enable this macro for legacy types.
#ifdef LIBYUV_LEGACY_TYPES
typedef uint64_t uint64;
typedef int64_t int64;
typedef uint32_t uint32;
typedef int32_t int32;
typedef uint16_t uint16;
typedef int16_t int16;
typedef uint8_t uint8;
typedef int8_t int8;
#endif // LIBYUV_LEGACY_TYPES
#endif // INT_TYPES_DEFINED

#if !defined(LIBYUV_API)
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(LIBYUV_BUILDING_SHARED_LIBRARY)
#define LIBYUV_API __declspec(dllexport)
#elif defined(LIBYUV_USING_SHARED_LIBRARY)
#define LIBYUV_API __declspec(dllimport)
#else
#define LIBYUV_API
#endif // LIBYUV_BUILDING_SHARED_LIBRARY
#elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__APPLE__) && \
(defined(LIBYUV_BUILDING_SHARED_LIBRARY) || \
defined(LIBYUV_USING_SHARED_LIBRARY))
#define LIBYUV_API __attribute__((visibility("default")))
#else
#define LIBYUV_API
#endif // __GNUC__
#endif // LIBYUV_API

// TODO(fbarchard): Remove bool macros.
#define LIBYUV_BOOL int
#define LIBYUV_FALSE 0
#define LIBYUV_TRUE 1

#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_
30 changes: 30 additions & 0 deletions third_party/libyuv/include/libyuv/planar_functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
#define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_

#include "libyuv/basic_types.h"

void CopyPlane(const uint8_t* src_y,
int src_stride_y,
uint8_t* dst_y,
int dst_stride_y,
int width,
int height);

void CopyPlane_16(const uint16_t* src_y,
int src_stride_y,
uint16_t* dst_y,
int dst_stride_y,
int width,
int height);

#endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
49 changes: 49 additions & 0 deletions third_party/libyuv/include/libyuv/row.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#ifndef INCLUDE_LIBYUV_ROW_H_
#define INCLUDE_LIBYUV_ROW_H_

#include <stddef.h> // For NULL
#include <stdlib.h> // For malloc

#include "libyuv/basic_types.h"

#define align_buffer_64(var, size) \
void* var##_mem = malloc((size) + 63); /* NOLINT */ \
uint8_t* var = (uint8_t*)(((intptr_t)var##_mem + 63) & ~63) /* NOLINT */

#define free_aligned_buffer_64(var) \
free(var##_mem); \
var = NULL

#define align_buffer_64_16(var, size) \
void* var##_mem = malloc((size)*2 + 63); /* NOLINT */ \
uint16_t* var = (uint16_t*)(((intptr_t)var##_mem + 63) & ~63) /* NOLINT */

#define free_aligned_buffer_64_16(var) \
free(var##_mem); \
var = NULL

void CopyRow_C(const uint8_t* src, uint8_t* dst, int count);

void InterpolateRow_C(uint8_t* dst_ptr,
const uint8_t* src_ptr,
ptrdiff_t src_stride,
int width,
int source_y_fraction);

void InterpolateRow_16_C(uint16_t* dst_ptr,
const uint16_t* src_ptr,
ptrdiff_t src_stride,
int width,
int source_y_fraction);

#endif // INCLUDE_LIBYUV_ROW_H_
44 changes: 44 additions & 0 deletions third_party/libyuv/include/libyuv/scale.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#ifndef INCLUDE_LIBYUV_SCALE_H_
#define INCLUDE_LIBYUV_SCALE_H_

#include "libyuv/basic_types.h"

// Supported filtering.
typedef enum FilterMode {
kFilterNone = 0, // Point sample; Fastest.
kFilterLinear = 1, // Filter horizontally only.
kFilterBilinear = 2, // Faster than box, but lower quality scaling down.
kFilterBox = 3 // Highest quality.
} FilterModeEnum;

void ScalePlane(const uint8_t* src,
int src_stride,
int src_width,
int src_height,
uint8_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);

void ScalePlane_12(const uint16_t* src,
int src_stride,
int src_width,
int src_height,
uint16_t* dst,
int dst_stride,
int dst_width,
int dst_height,
enum FilterMode filtering);

#endif // INCLUDE_LIBYUV_SCALE_H_
Loading

0 comments on commit 808bf58

Please sign in to comment.