This commit is contained in:
Mike Jerris 2016-09-27 13:08:00 -04:00
parent d6bf6705de
commit 93591e2f47
93 changed files with 3194 additions and 2023 deletions

View File

@ -53,6 +53,12 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
source/scale_neon.cc.neon source/scale_neon.cc.neon
endif endif
ifeq ($(TARGET_ARCH_ABI),mips)
LOCAL_CFLAGS += -DLIBYUV_MSA
LOCAL_SRC_FILES += \
source/row_msa.cc
endif
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_C_INCLUDES += $(LOCAL_PATH)/include

View File

@ -6,19 +6,20 @@
# in the file PATENTS. All contributing project authors may # in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree. # be found in the AUTHORS file in the root of the source tree.
import("//build/config/arm.gni") import("libyuv.gni")
import("//build/config/sanitizers/sanitizers.gni") import("//testing/test.gni")
config("libyuv_config") { config("libyuv_config") {
include_dirs = [ include_dirs = [ "include" ]
".", if (is_android && current_cpu=="arm64") {
"include", ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64" ]
] }
if (is_android && current_cpu != "arm64") {
ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker" ]
}
} }
use_neon = current_cpu == "arm64" || (current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon)) static_library("libyuv") {
source_set("libyuv") {
sources = [ sources = [
# Headers # Headers
"include/libyuv.h", "include/libyuv.h",
@ -79,31 +80,24 @@ source_set("libyuv") {
"source/video_common.cc", "source/video_common.cc",
] ]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
public_configs = [ ":libyuv_config" ] public_configs = [ ":libyuv_config" ]
defines = [] defines = []
deps = []
if (!is_ios) { if (!is_ios) {
defines += [ "HAVE_JPEG" ] defines += [ "HAVE_JPEG" ]
deps += [ "//third_party:jpeg" ]
} }
if (is_msan) { if (libyuv_use_neon) {
# MemorySanitizer does not support assembly code yet.
# http://crbug.com/344505
defines += [ "LIBYUV_DISABLE_X86" ]
}
deps = [
"//third_party:jpeg",
]
if (use_neon) {
deps += [ ":libyuv_neon" ] deps += [ ":libyuv_neon" ]
} }
if (libyuv_use_msa) {
deps += [ ":libyuv_msa" ]
}
if (is_nacl) { if (is_nacl) {
# Always enable optimization under NaCl to workaround crbug.com/538243 . # Always enable optimization under NaCl to workaround crbug.com/538243 .
configs -= [ "//build/config/compiler:default_optimization" ] configs -= [ "//build/config/compiler:default_optimization" ]
@ -111,7 +105,7 @@ source_set("libyuv") {
} }
} }
if (use_neon) { if (libyuv_use_neon) {
static_library("libyuv_neon") { static_library("libyuv_neon") {
sources = [ sources = [
# ARM Source Files # ARM Source Files
@ -133,3 +127,147 @@ if (use_neon) {
} }
} }
} }
if (libyuv_use_msa) {
static_library("libyuv_msa") {
sources = [
# MSA Source Files
"source/row_msa.cc",
]
public_configs = [ ":libyuv_config" ]
}
}
if (libyuv_include_tests) {
config("libyuv_unittest_warnings_config") {
if (!is_win) {
cflags = [
# TODO(fbarchard): Fix sign and unused variable warnings.
"-Wno-sign-compare",
"-Wno-unused-variable"
]
}
if (is_win) {
cflags = [
"/wd4245", # signed/unsigned mismatch
"/wd4189", # local variable is initialized but not referenced
]
}
}
config("libyuv_unittest_config") {
defines = [ "GTEST_RELATIVE_PATH" ]
}
test("libyuv_unittest") {
testonly = true
sources = [
# headers
"unit_test/unit_test.h",
# sources
"unit_test/basictypes_test.cc",
"unit_test/compare_test.cc",
"unit_test/color_test.cc",
"unit_test/convert_test.cc",
"unit_test/cpu_test.cc",
"unit_test/math_test.cc",
"unit_test/planar_test.cc",
"unit_test/rotate_argb_test.cc",
"unit_test/rotate_test.cc",
"unit_test/scale_argb_test.cc",
"unit_test/scale_test.cc",
"unit_test/unit_test.cc",
"unit_test/video_common_test.cc",
]
deps = [
":libyuv",
"//testing/gtest",
"//third_party/gflags",
]
configs += [ ":libyuv_unittest_warnings_config" ]
public_deps = [ "//testing/gtest" ]
public_configs = [ ":libyuv_unittest_config" ]
defines = []
if (is_linux) {
cflags = [ "-fexceptions" ]
}
if (is_ios) {
configs -= [ "//build/config/compiler:default_symbols" ]
configs += [ "//build/config/compiler:symbols" ]
cflags = [ "-Wno-sometimes-uninitialized" ]
}
if (!is_ios && !libyuv_disable_jpeg) {
defines += [ "HAVE_JPEG" ]
}
if (is_android) {
deps += [ "//testing/android/native_test:native_test_native_code" ]
}
# TODO(YangZhang): These lines can be removed when high accuracy
# YUV to RGB to Neon is ported.
if ((target_cpu=="armv7" || target_cpu=="armv7s" ||
(target_cpu=="arm" && arm_version >= 7) || target_cpu=="arm64") &&
(arm_use_neon || arm_optionally_use_neon)) {
defines += [ "LIBYUV_NEON" ]
}
defines += [
# Enable the following 3 macros to turn off assembly for specified CPU.
# "LIBYUV_DISABLE_X86",
# "LIBYUV_DISABLE_NEON",
# "LIBYUV_DISABLE_MIPS",
# Enable the following macro to build libyuv as a shared library (dll).
# "LIBYUV_USING_SHARED_LIBRARY"
]
}
executable("compare") {
sources = [
# sources
"util/compare.cc"
]
deps = [ ":libyuv" ]
if (is_linux) {
cflags = [ "-fexceptions" ]
}
}
executable("convert") {
sources = [
# sources
"util/convert.cc"
]
deps = [ ":libyuv" ]
if (is_linux) {
cflags = [ "-fexceptions" ]
}
}
executable("psnr") {
sources = [
# sources
"util/psnr_main.cc",
"util/psnr.cc",
"util/ssim.cc"
]
deps = [ ":libyuv" ]
if (!is_ios && !libyuv_disable_jpeg) {
defines = [ "HAVE_JPEG" ]
}
}
executable("cpuid") {
sources = [
# sources
"util/cpuid.c"
]
deps = [ ":libyuv" ]
}
}

View File

@ -40,6 +40,7 @@ set(ly_source_files
${ly_src_dir}/row_any.cc ${ly_src_dir}/row_any.cc
${ly_src_dir}/row_common.cc ${ly_src_dir}/row_common.cc
${ly_src_dir}/row_mips.cc ${ly_src_dir}/row_mips.cc
${ly_src_dir}/row_msa.cc
${ly_src_dir}/row_neon.cc ${ly_src_dir}/row_neon.cc
${ly_src_dir}/row_neon64.cc ${ly_src_dir}/row_neon64.cc
${ly_src_dir}/row_gcc.cc ${ly_src_dir}/row_gcc.cc
@ -80,6 +81,7 @@ set(ly_header_files
${ly_inc_dir}/libyuv/convert_from.h ${ly_inc_dir}/libyuv/convert_from.h
${ly_inc_dir}/libyuv/convert_from_argb.h ${ly_inc_dir}/libyuv/convert_from_argb.h
${ly_inc_dir}/libyuv/cpu_id.h ${ly_inc_dir}/libyuv/cpu_id.h
${ly_inc_dir}/libyuv/macros_msa.h
${ly_inc_dir}/libyuv/planar_functions.h ${ly_inc_dir}/libyuv/planar_functions.h
${ly_inc_dir}/libyuv/rotate.h ${ly_inc_dir}/libyuv/rotate.h
${ly_inc_dir}/libyuv/rotate_argb.h ${ly_inc_dir}/libyuv/rotate_argb.h

View File

@ -7,14 +7,14 @@ vars = {
# Roll the Chromium Git hash to pick up newer versions of all the # Roll the Chromium Git hash to pick up newer versions of all the
# dependencies and tools linked to in setup_links.py. # dependencies and tools linked to in setup_links.py.
'chromium_revision': '1d144ca7f86e0c684c67d6c1b6d5414ca9074615', 'chromium_revision': '941118827f5240dedb40082cffb1ead6c6d621cc',
} }
# NOTE: Prefer revision numbers to tags for svn deps. Use http rather than # NOTE: Use http rather than https; the latter can cause problems for users
# https; the latter can cause problems for users behind proxies. # behind proxies.
deps = { deps = {
Var('root_dir') + '/third_party/gflags/src': Var('root_dir') + '/third_party/gflags/src':
Var('chromium_git') + '/external/gflags/src@e7390f9185c75f8d902c05ed7d20bb94eb914d0c', # from svn revision 82 Var('chromium_git') + '/external/github.com/gflags/gflags@03bebcb065c83beff83d50ae025a55a4bf94dfca',
} }
# Define rules for which include paths are allowed in our source. # Define rules for which include paths are allowed in our source.

View File

@ -28,6 +28,9 @@ def GetPreferredTryMasters(project, change):
'win_x64_rel', 'win_x64_rel',
'win_x64_gn', 'win_x64_gn',
'win_x64_gn_rel', 'win_x64_gn_rel',
'win_clang',
'win_clang_rel',
'win_x64_clang_rel',
'mac', 'mac',
'mac_rel', 'mac_rel',
'mac_gn', 'mac_gn',
@ -51,6 +54,9 @@ def GetPreferredTryMasters(project, change):
'android_rel', 'android_rel',
'android_clang', 'android_clang',
'android_arm64', 'android_arm64',
'android_mips',
'android_x64',
'android_x86',
'android_gn', 'android_gn',
'android_gn_rel', 'android_gn_rel',
] ]

View File

@ -1,6 +1,6 @@
Name: libyuv Name: libyuv
URL: http://code.google.com/p/libyuv/ URL: http://code.google.com/p/libyuv/
Version: 1586 Version: 1620
License: BSD License: BSD
License File: LICENSE License File: LICENSE

View File

@ -13,3 +13,10 @@
# remove this when Chromium drops 10.6 support and also requires 10.7. # remove this when Chromium drops 10.6 support and also requires 10.7.
mac_sdk_min_build_override = "10.11" mac_sdk_min_build_override = "10.11"
mac_deployment_target_build_override = "10.7" mac_deployment_target_build_override = "10.7"
# Variable that can be used to support multiple build scenarios, like having
# Chromium specific targets in a client project's GN file etc.
build_with_chromium = false
# Some non-Chromium builds don't support building java targets.
enable_java_templates = true

View File

@ -0,0 +1,19 @@
# Copyright (c) 2016 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.
# Include support for registering main function in multi-process tests.
gtest_include_multiprocess = true
# Include support for platform-specific operations across unit tests.
gtest_include_platform_test = true
# Exclude support for testing Objective C code on OS X and iOS.
gtest_include_objc_support = true
# Exclude support for flushing coverage files on iOS.
gtest_include_ios_coverage = true

View File

@ -7,6 +7,5 @@ FORCE_HTTPS_COMMIT_URL: True
PROJECT: libyuv PROJECT: libyuv
TRY_ON_UPLOAD: False TRY_ON_UPLOAD: False
TRYSERVER_ROOT: src TRYSERVER_ROOT: src
TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-libyuv
#GITCL_PREUPLOAD: #GITCL_PREUPLOAD:
#GITCL_PREDCOMMIT: #GITCL_PREDCOMMIT:

View File

@ -22,7 +22,7 @@ By default the cpu is detected and the most advanced form of SIMD is used. But
# Test Width/Height/Repeat # Test Width/Height/Repeat
The unittests default to a small image (32x18) to run fast. This can be set by environment variable to test a specific resolutions. The unittests default to a small image (128x72) to run fast. This can be set by environment variable to test a specific resolutions.
You can also repeat the test a specified number of iterations, allowing benchmarking and profiling. You can also repeat the test a specified number of iterations, allowing benchmarking and profiling.
set LIBYUV_WIDTH=1280 set LIBYUV_WIDTH=1280

View File

@ -102,6 +102,15 @@ The following is extracted from video_common.h as a complete list of formats sup
// 1 Auxiliary compressed YUV format set aside for capturer. // 1 Auxiliary compressed YUV format set aside for capturer.
FOURCC_H264 = FOURCC('H', '2', '6', '4'), FOURCC_H264 = FOURCC('H', '2', '6', '4'),
# Planar YUV
The following formats contains a full size Y plane followed by 1 or 2
planes for UV: I420, I422, I444, I411, I400, NV21, NV12, I400
The size (subsampling) of the UV varies.
I420, NV12 and NV21 are half width, half height
I422, NV16 and NV61 are half width, full height
I444, NV24 and NV42 are full width, full height
I400 and J400 have no chroma channel.
# The ARGB FOURCC # The ARGB FOURCC
There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers. There are 4 ARGB layouts - ARGB, BGRA, ABGR and RGBA. ARGB is most common by far, used for screen formats, and windows webcam drivers.

View File

@ -55,6 +55,7 @@ Then run:
gclient sync gclient sync
Caveat: Theres an error with Google Play services updates. If you get the error "Your version of the Google Play services library is not up to date", run the following: Caveat: Theres an error with Google Play services updates. If you get the error "Your version of the Google Play services library is not up to date", run the following:
cd chromium/src cd chromium/src
./build/android/play_services/update.py download ./build/android/play_services/update.py download
cd ../.. cd ../..
@ -64,6 +65,7 @@ For Windows the gclient sync must be done from an Administrator command prompt.
The sync will generate native build files for your environment using gyp (Windows: Visual Studio, OSX: XCode, Linux: make). This generation can also be forced manually: `gclient runhooks` The sync will generate native build files for your environment using gyp (Windows: Visual Studio, OSX: XCode, Linux: make). This generation can also be forced manually: `gclient runhooks`
To get just the source (not buildable): To get just the source (not buildable):
git clone https://chromium.googlesource.com/libyuv/libyuv git clone https://chromium.googlesource.com/libyuv/libyuv
@ -82,8 +84,7 @@ To get just the source (not buildable):
ninja -C out\Release_x64 ninja -C out\Release_x64
#### Building with clangcl #### Building with clangcl
set GYP_DEFINES=clang=1 target_arch=ia32 libyuv_enable_svn=1 set GYP_DEFINES=clang=1 target_arch=ia32
set LLVM_REPO_URL=svn://svn.chromium.org/llvm-project
call python tools\clang\scripts\update.py call python tools\clang\scripts\update.py
call python gyp_libyuv -fninja libyuv_test.gyp call python gyp_libyuv -fninja libyuv_test.gyp
ninja -C out\Debug ninja -C out\Debug
@ -138,29 +139,29 @@ Add to .gclient last line: `target_os=['android'];`
armv7 armv7
GYP_DEFINES="OS=android" GYP_CROSSCOMPILE=1 ./gyp_libyuv GYP_DEFINES="OS=android" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk ninja -j7 -C out/Release yuv_unittest_apk
arm64 arm64
GYP_DEFINES="OS=android target_arch=arm64 target_subarch=arm64" GYP_CROSSCOMPILE=1 ./gyp_libyuv GYP_DEFINES="OS=android target_arch=arm64 target_subarch=arm64" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk ninja -j7 -C out/Release yuv_unittest_apk
ia32 ia32
GYP_DEFINES="OS=android target_arch=ia32" GYP_CROSSCOMPILE=1 ./gyp_libyuv GYP_DEFINES="OS=android target_arch=ia32" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk ninja -j7 -C out/Release yuv_unittest_apk
GYP_DEFINES="OS=android target_arch=ia32 android_full_debug=1" GYP_CROSSCOMPILE=1 ./gyp_libyuv GYP_DEFINES="OS=android target_arch=ia32 android_full_debug=1" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk ninja -j7 -C out/Debug yuv_unittest_apk
mipsel mipsel
GYP_DEFINES="OS=android target_arch=mipsel" GYP_CROSSCOMPILE=1 ./gyp_libyuv GYP_DEFINES="OS=android target_arch=mipsel" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk ninja -j7 -C out/Debug yuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk ninja -j7 -C out/Release yuv_unittest_apk
arm32 disassembly: arm32 disassembly:
@ -180,7 +181,7 @@ Running test as benchmark:
Running test with C code: Running test with C code:
util/android/test_runner.py gtest -s libyuv_unittest -t 7200 --verbose --release --gtest_filter=* -a "--libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=999 --libyuv_flags=0 --libyuv_cpu_info=0" util/android/test_runner.py gtest -s libyuv_unittest -t 7200 --verbose --release --gtest_filter=* -a "--libyuv_width=1280 --libyuv_height=720 --libyuv_repeat=999 --libyuv_flags=1 --libyuv_cpu_info=1"
#### Building with GN #### Building with GN
@ -194,6 +195,16 @@ Running test with C code:
gn gen out/Official "--args=is_debug=false is_official_build=true is_chrome_branded=true" gn gen out/Official "--args=is_debug=false is_official_build=true is_chrome_branded=true"
ninja -C out/Official ninja -C out/Official
#### Building mips with GN
mipsel
gn gen out/Default "--args=is_debug=false target_cpu=\"mipsel\" target_os = \"android\" mips_arch_variant = \"r6\" mips_use_msa = true is_component_build = true is_clang = false"
ninja -C out/Default
mips64el
gn gen out/Default "--args=is_debug=false target_cpu=\"mips64el\" target_os = \"android\" mips_arch_variant = \"r6\" mips_use_msa = true is_component_build = true is_clang = false"
ninja -C out/Default
### Linux ### Linux
GYP_DEFINES="target_arch=x64" ./gyp_libyuv GYP_DEFINES="target_arch=x64" ./gyp_libyuv

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_H_ // NOLINT #ifndef INCLUDE_LIBYUV_H_
#define INCLUDE_LIBYUV_H_ #define INCLUDE_LIBYUV_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -29,4 +29,4 @@
#include "libyuv/version.h" #include "libyuv/version.h"
#include "libyuv/video_common.h" #include "libyuv/video_common.h"
#endif // INCLUDE_LIBYUV_H_ NOLINT #endif // INCLUDE_LIBYUV_H_

View File

@ -8,12 +8,12 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ // NOLINT #ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_
#define INCLUDE_LIBYUV_BASIC_TYPES_H_ #define INCLUDE_LIBYUV_BASIC_TYPES_H_
#include <stddef.h> // for NULL, size_t #include <stddef.h> // for NULL, size_t
#if defined(__ANDROID__) || (defined(_MSC_VER) && (_MSC_VER < 1600)) #if defined(_MSC_VER) && (_MSC_VER < 1600)
#include <sys/types.h> // for uintptr_t on x86 #include <sys/types.h> // for uintptr_t on x86
#else #else
#include <stdint.h> // for uintptr_t #include <stdint.h> // for uintptr_t
@ -115,4 +115,4 @@ typedef signed char int8;
#define LIBYUV_LITTLE_ENDIAN #define LIBYUV_LITTLE_ENDIAN
#endif #endif
#endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ NOLINT #endif // INCLUDE_LIBYUV_BASIC_TYPES_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_COMPARE_H_ // NOLINT #ifndef INCLUDE_LIBYUV_COMPARE_H_
#define INCLUDE_LIBYUV_COMPARE_H_ #define INCLUDE_LIBYUV_COMPARE_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -75,4 +75,4 @@ double I420Ssim(const uint8* src_y_a, int stride_y_a,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_COMPARE_H_ NOLINT #endif // INCLUDE_LIBYUV_COMPARE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_ // NOLINT #ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_
#define INCLUDE_LIBYUV_COMPARE_ROW_H_ #define INCLUDE_LIBYUV_COMPARE_ROW_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -81,4 +81,4 @@ uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed);
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_COMPARE_ROW_H_ NOLINT #endif // INCLUDE_LIBYUV_COMPARE_ROW_H_

View File

@ -8,14 +8,17 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_CONVERT_H_ // NOLINT #ifndef INCLUDE_LIBYUV_CONVERT_H_
#define INCLUDE_LIBYUV_CONVERT_H_ #define INCLUDE_LIBYUV_CONVERT_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes.
#include "libyuv/convert_from.h" #include "libyuv/rotate.h" // For enum RotationMode.
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h" // TODO(fbarchard): fix WebRTC source to include following libyuv headers:
#include "libyuv/convert_argb.h" // For WebRTC I420ToARGB. b/620
#include "libyuv/convert_from.h" // For WebRTC ConvertFromI420. b/620
#include "libyuv/planar_functions.h" // For WebRTC I420Rect, CopyPlane. b/618
#ifdef __cplusplus #ifdef __cplusplus
namespace libyuv { namespace libyuv {
@ -115,6 +118,17 @@ int M420ToI420(const uint8* src_m420, int src_stride_m420,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height); int width, int height);
// Convert Android420 to I420.
LIBYUV_API
int Android420ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
int pixel_stride_uv,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// ARGB little endian (bgra in memory) to I420. // ARGB little endian (bgra in memory) to I420.
LIBYUV_API LIBYUV_API
int ARGBToI420(const uint8* src_frame, int src_stride_frame, int ARGBToI420(const uint8* src_frame, int src_stride_frame,
@ -242,4 +256,4 @@ int ConvertToI420(const uint8* src_frame, size_t src_size,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_CONVERT_H_ NOLINT #endif // INCLUDE_LIBYUV_CONVERT_H_

View File

@ -8,14 +8,12 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_CONVERT_ARGB_H_ // NOLINT #ifndef INCLUDE_LIBYUV_CONVERT_ARGB_H_
#define INCLUDE_LIBYUV_CONVERT_ARGB_H_ #define INCLUDE_LIBYUV_CONVERT_ARGB_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes
#include "libyuv/convert_from.h" #include "libyuv/rotate.h" // For enum RotationMode.
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
// TODO(fbarchard): This set of functions should exactly match convert.h // TODO(fbarchard): This set of functions should exactly match convert.h
// TODO(fbarchard): Add tests. Create random content of right size and convert // TODO(fbarchard): Add tests. Create random content of right size and convert
@ -44,6 +42,14 @@ int I420ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb, uint8* dst_argb, int dst_stride_argb,
int width, int height); int width, int height);
// Duplicate prototype for function in convert_from.h for remoting.
LIBYUV_API
int I420ToABGR(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert I422 to ARGB. // Convert I422 to ARGB.
LIBYUV_API LIBYUV_API
int I422ToARGB(const uint8* src_y, int src_stride_y, int I422ToARGB(const uint8* src_y, int src_stride_y,
@ -310,4 +316,4 @@ int ConvertToARGB(const uint8* src_frame, size_t src_size,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_CONVERT_ARGB_H_ NOLINT #endif // INCLUDE_LIBYUV_CONVERT_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_ // NOLINT #ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_
#define INCLUDE_LIBYUV_CONVERT_FROM_H_ #define INCLUDE_LIBYUV_CONVERT_FROM_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -56,8 +56,6 @@ int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
int width, int height); int width, int height);
// TODO(fbarchard): I420ToM420
LIBYUV_API LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y, int I420ToNV12(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u, const uint8* src_u, int src_stride_u,
@ -178,4 +176,4 @@ int ConvertFromI420(const uint8* y, int y_stride,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_H_ NOLINT #endif // INCLUDE_LIBYUV_CONVERT_FROM_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ // NOLINT #ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_
#define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ #define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -187,4 +187,4 @@ int ARGBToUYVY(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ NOLINT #endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_CPU_ID_H_ // NOLINT #ifndef INCLUDE_LIBYUV_CPU_ID_H_
#define INCLUDE_LIBYUV_CPU_ID_H_ #define INCLUDE_LIBYUV_CPU_ID_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -42,6 +42,7 @@ static const int kCpuHasAVX3 = 0x2000;
// These flags are only valid on MIPS processors. // These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x10000; static const int kCpuHasMIPS = 0x10000;
static const int kCpuHasDSPR2 = 0x20000; static const int kCpuHasDSPR2 = 0x20000;
static const int kCpuHasMSA = 0x40000;
// Internal function used to auto-init. // Internal function used to auto-init.
LIBYUV_API LIBYUV_API
@ -62,7 +63,7 @@ static __inline int TestCpuFlag(int test_flag) {
// For testing, allow CPU flags to be disabled. // For testing, allow CPU flags to be disabled.
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3. // ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
// MaskCpuFlags(-1) to enable all cpu specific optimizations. // MaskCpuFlags(-1) to enable all cpu specific optimizations.
// MaskCpuFlags(0) to disable all cpu specific optimizations. // MaskCpuFlags(1) to disable all cpu specific optimizations.
LIBYUV_API LIBYUV_API
void MaskCpuFlags(int enable_flags); void MaskCpuFlags(int enable_flags);
@ -77,4 +78,4 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info);
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_CPU_ID_H_ NOLINT #endif // INCLUDE_LIBYUV_CPU_ID_H_

View File

@ -0,0 +1,76 @@
/*
* Copyright 2016 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_MACROS_MSA_H_
#define INCLUDE_LIBYUV_MACROS_MSA_H_
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#include <stdint.h>
#include <msa.h>
#define LD_B(RTYPE, psrc) *((RTYPE*)(psrc)) /* NOLINT */
#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
#define ST_B(RTYPE, in, pdst) *((RTYPE*)(pdst)) = (in) /* NOLINT */
#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
/* Description : Load two vectors with 16 'byte' sized elements
Arguments : Inputs - psrc, stride
Outputs - out0, out1
Return Type - as per RTYPE
Details : Load 16 byte elements in 'out0' from (psrc)
Load 16 byte elements in 'out1' from (psrc + stride)
*/
#define LD_B2(RTYPE, psrc, stride, out0, out1) { \
out0 = LD_B(RTYPE, (psrc)); \
out1 = LD_B(RTYPE, (psrc) + stride); \
}
#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) { \
LD_B2(RTYPE, (psrc), stride, out0, out1); \
LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \
}
#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
/* Description : Store two vectors with stride each having 16 'byte' sized
elements
Arguments : Inputs - in0, in1, pdst, stride
Details : Store 16 byte elements from 'in0' to (pdst)
Store 16 byte elements from 'in1' to (pdst + stride)
*/
#define ST_B2(RTYPE, in0, in1, pdst, stride) { \
ST_B(RTYPE, in0, (pdst)); \
ST_B(RTYPE, in1, (pdst) + stride); \
}
#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
#
#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) { \
ST_B2(RTYPE, in0, in1, (pdst), stride); \
ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \
}
#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
#
/* Description : Shuffle byte vector elements as per mask vector
Arguments : Inputs - in0, in1, in2, in3, mask0, mask1
Outputs - out0, out1
Return Type - as per RTYPE
Details : Byte elements from 'in0' & 'in1' are copied selectively to
'out0' as per control vector 'mask0'
*/
#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) { \
out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \
out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \
}
#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
#endif /* !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) */
#endif // INCLUDE_LIBYUV_MACROS_MSA_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_ // NOLINT #ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_
#define INCLUDE_LIBYUV_MJPEG_DECODER_H_ #define INCLUDE_LIBYUV_MJPEG_DECODER_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -189,4 +189,4 @@ class LIBYUV_API MJpegDecoder {
} // namespace libyuv } // namespace libyuv
#endif // __cplusplus #endif // __cplusplus
#endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_ NOLINT #endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ // NOLINT #ifndef INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
#define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ #define INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -39,6 +39,20 @@ void SetPlane(uint8* dst_y, int dst_stride_y,
int width, int height, int width, int height,
uint32 value); uint32 value);
// Split interleaved UV plane into separate U and V planes.
LIBYUV_API
void SplitUVPlane(const uint8* src_uv, int src_stride_uv,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Merge separate U and V planes into one interleaved UV plane.
LIBYUV_API
void MergeUVPlane(const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_uv, int dst_stride_uv,
int width, int height);
// Copy I400. Supports inverting. // Copy I400. Supports inverting.
LIBYUV_API LIBYUV_API
int I400ToI400(const uint8* src_y, int src_stride_y, int I400ToI400(const uint8* src_y, int src_stride_y,
@ -288,6 +302,12 @@ int ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb, uint8* dst_argb, int dst_stride_argb,
int width, int height); int width, int height);
// Extract the alpha channel from ARGB.
LIBYUV_API
int ARGBExtractAlpha(const uint8* src_argb, int src_stride_argb,
uint8* dst_a, int dst_stride_a,
int width, int height);
// Copy Y channel to Alpha of ARGB. // Copy Y channel to Alpha of ARGB.
LIBYUV_API LIBYUV_API
int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y, int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
@ -498,4 +518,4 @@ int ARGBSobelXY(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_ NOLINT #endif // INCLUDE_LIBYUV_PLANAR_FUNCTIONS_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_ROTATE_H_ // NOLINT #ifndef INCLUDE_LIBYUV_ROTATE_H_
#define INCLUDE_LIBYUV_ROTATE_H_ #define INCLUDE_LIBYUV_ROTATE_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -114,4 +114,4 @@ void TransposeUV(const uint8* src, int src_stride,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_ROTATE_H_ NOLINT #endif // INCLUDE_LIBYUV_ROTATE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_ // NOLINT #ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_
#define INCLUDE_LIBYUV_ROTATE_ARGB_H_ #define INCLUDE_LIBYUV_ROTATE_ARGB_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -30,4 +30,4 @@ int ARGBRotate(const uint8* src_argb, int src_stride_argb,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_ NOLINT #endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_ // NOLINT #ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_
#define INCLUDE_LIBYUV_ROTATE_ROW_H_ #define INCLUDE_LIBYUV_ROTATE_ROW_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -118,4 +118,4 @@ void TransposeUVWx8_Any_DSPR2(const uint8* src, int src_stride,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_ NOLINT #endif // INCLUDE_LIBYUV_ROTATE_ROW_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_ROW_H_ // NOLINT #ifndef INCLUDE_LIBYUV_ROW_H_
#define INCLUDE_LIBYUV_ROW_H_ #define INCLUDE_LIBYUV_ROW_H_
#include <stdlib.h> // For malloc. #include <stdlib.h> // For malloc.
@ -22,16 +22,9 @@ extern "C" {
#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1))) #define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
#ifdef __cplusplus
#define align_buffer_64(var, size) \
uint8* var##_mem = reinterpret_cast<uint8*>(malloc((size) + 63)); \
uint8* var = reinterpret_cast<uint8*> \
((reinterpret_cast<intptr_t>(var##_mem) + 63) & ~63)
#else
#define align_buffer_64(var, size) \ #define align_buffer_64(var, size) \
uint8* var##_mem = (uint8*)(malloc((size) + 63)); /* NOLINT */ \ uint8* var##_mem = (uint8*)(malloc((size) + 63)); /* NOLINT */ \
uint8* var = (uint8*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */ uint8* var = (uint8*)(((intptr_t)(var##_mem) + 63) & ~63) /* NOLINT */
#endif
#define free_aligned_buffer_64(var) \ #define free_aligned_buffer_64(var) \
free(var##_mem); \ free(var##_mem); \
@ -104,6 +97,7 @@ extern "C" {
#define HAS_ARGBTOUVROW_SSSE3 #define HAS_ARGBTOUVROW_SSSE3
#define HAS_ARGBTOYJROW_SSSE3 #define HAS_ARGBTOYJROW_SSSE3
#define HAS_ARGBTOYROW_SSSE3 #define HAS_ARGBTOYROW_SSSE3
#define HAS_ARGBEXTRACTALPHAROW_SSE2
#define HAS_BGRATOUVROW_SSSE3 #define HAS_BGRATOUVROW_SSSE3
#define HAS_BGRATOYROW_SSSE3 #define HAS_BGRATOYROW_SSSE3
#define HAS_COPYROW_ERMS #define HAS_COPYROW_ERMS
@ -261,7 +255,7 @@ extern "C" {
#endif #endif
// The following are also available on x64 Visual C. // The following are also available on x64 Visual C.
#if !defined(LIBYUV_DISABLE_X86) && defined (_M_X64) && \ #if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && defined(_M_X64) && \
(!defined(__clang__) || defined(__SSSE3__)) (!defined(__clang__) || defined(__SSSE3__))
#define HAS_I422ALPHATOARGBROW_SSSE3 #define HAS_I422ALPHATOARGBROW_SSSE3
#define HAS_I422TOARGBROW_SSSE3 #define HAS_I422TOARGBROW_SSSE3
@ -291,6 +285,7 @@ extern "C" {
#define HAS_ARGBTOUVROW_NEON #define HAS_ARGBTOUVROW_NEON
#define HAS_ARGBTOYJROW_NEON #define HAS_ARGBTOYJROW_NEON
#define HAS_ARGBTOYROW_NEON #define HAS_ARGBTOYROW_NEON
#define HAS_ARGBEXTRACTALPHAROW_NEON
#define HAS_BGRATOUVROW_NEON #define HAS_BGRATOUVROW_NEON
#define HAS_BGRATOYROW_NEON #define HAS_BGRATOYROW_NEON
#define HAS_COPYROW_NEON #define HAS_COPYROW_NEON
@ -370,9 +365,17 @@ extern "C" {
#endif #endif
#endif #endif
#if defined(_MSC_VER) && !defined(__CLR_VER) #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#define HAS_MIRRORROW_MSA
#define HAS_ARGBMIRRORROW_MSA
#endif
#if defined(_MSC_VER) && !defined(__CLR_VER) && !defined(__clang__)
#if defined(VISUALC_HAS_AVX2)
#define SIMD_ALIGNED(var) __declspec(align(32)) var
#else
#define SIMD_ALIGNED(var) __declspec(align(16)) var #define SIMD_ALIGNED(var) __declspec(align(16)) var
#define SIMD_ALIGNED32(var) __declspec(align(64)) var #endif
typedef __declspec(align(16)) int16 vec16[8]; typedef __declspec(align(16)) int16 vec16[8];
typedef __declspec(align(16)) int32 vec32[4]; typedef __declspec(align(16)) int32 vec32[4];
typedef __declspec(align(16)) int8 vec8[16]; typedef __declspec(align(16)) int8 vec8[16];
@ -385,10 +388,13 @@ typedef __declspec(align(32)) int8 lvec8[32];
typedef __declspec(align(32)) uint16 ulvec16[16]; typedef __declspec(align(32)) uint16 ulvec16[16];
typedef __declspec(align(32)) uint32 ulvec32[8]; typedef __declspec(align(32)) uint32 ulvec32[8];
typedef __declspec(align(32)) uint8 ulvec8[32]; typedef __declspec(align(32)) uint8 ulvec8[32];
#elif defined(__GNUC__) && !defined(__pnacl__) #elif !defined(__pnacl__) && (defined(__GNUC__) || defined(__clang__))
// Caveat GCC 4.2 to 4.7 have a known issue using vectors with const. // Caveat GCC 4.2 to 4.7 have a known issue using vectors with const.
#if defined(CLANG_HAS_AVX2) || defined(GCC_HAS_AVX2)
#define SIMD_ALIGNED(var) var __attribute__((aligned(32)))
#else
#define SIMD_ALIGNED(var) var __attribute__((aligned(16))) #define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#define SIMD_ALIGNED32(var) var __attribute__((aligned(64))) #endif
typedef int16 __attribute__((vector_size(16))) vec16; typedef int16 __attribute__((vector_size(16))) vec16;
typedef int32 __attribute__((vector_size(16))) vec32; typedef int32 __attribute__((vector_size(16))) vec32;
typedef int8 __attribute__((vector_size(16))) vec8; typedef int8 __attribute__((vector_size(16))) vec8;
@ -403,7 +409,6 @@ typedef uint32 __attribute__((vector_size(32))) ulvec32;
typedef uint8 __attribute__((vector_size(32))) ulvec8; typedef uint8 __attribute__((vector_size(32))) ulvec8;
#else #else
#define SIMD_ALIGNED(var) var #define SIMD_ALIGNED(var) var
#define SIMD_ALIGNED32(var) var
typedef int16 vec16[8]; typedef int16 vec16[8];
typedef int32 vec32[4]; typedef int32 vec32[4];
typedef int8 vec8[16]; typedef int8 vec8[16];
@ -439,13 +444,13 @@ struct YuvConstants {
#else #else
// This struct is for Intel color conversion. // This struct is for Intel color conversion.
struct YuvConstants { struct YuvConstants {
lvec8 kUVToB; int8 kUVToB[32];
lvec8 kUVToG; int8 kUVToG[32];
lvec8 kUVToR; int8 kUVToR[32];
lvec16 kUVBiasB; int16 kUVBiasB[16];
lvec16 kUVBiasG; int16 kUVBiasG[16];
lvec16 kUVBiasR; int16 kUVBiasR[16];
lvec16 kYToRgb; int16 kYToRgb[16];
}; };
// Offsets into YuvConstants structure // Offsets into YuvConstants structure
@ -459,14 +464,14 @@ struct YuvConstants {
#endif #endif
// Conversion matrix for YUV to RGB // Conversion matrix for YUV to RGB
extern const struct YuvConstants kYuvI601Constants; // BT.601 extern const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants); // BT.601
extern const struct YuvConstants kYuvJPEGConstants; // JPeg color space extern const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants); // JPeg
extern const struct YuvConstants kYuvH709Constants; // BT.709 extern const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants); // BT.709
// Conversion matrix for YVU to BGR // Conversion matrix for YVU to BGR
extern const struct YuvConstants kYvuI601Constants; // BT.601 extern const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants); // BT.601
extern const struct YuvConstants kYvuJPEGConstants; // JPeg color space extern const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants); // JPeg
extern const struct YuvConstants kYvuH709Constants; // BT.709 extern const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants); // BT.709
#if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__) #if defined(__APPLE__) || defined(__x86_64__) || defined(__llvm__)
#define OMITFP #define OMITFP
@ -802,11 +807,13 @@ void MirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width); void MirrorRow_SSSE3(const uint8* src, uint8* dst, int width);
void MirrorRow_NEON(const uint8* src, uint8* dst, int width); void MirrorRow_NEON(const uint8* src, uint8* dst, int width);
void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width); void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width);
void MirrorRow_MSA(const uint8* src, uint8* dst, int width);
void MirrorRow_C(const uint8* src, uint8* dst, int width); void MirrorRow_C(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width); void MirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_SSSE3(const uint8* src, uint8* dst, int width); void MirrorRow_Any_SSSE3(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width); void MirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_NEON(const uint8* src, uint8* dst, int width); void MirrorRow_Any_NEON(const uint8* src, uint8* dst, int width);
void MirrorRow_Any_MSA(const uint8* src, uint8* dst, int width);
void MirrorUVRow_SSSE3(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void MirrorUVRow_SSSE3(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width); int width);
@ -819,10 +826,12 @@ void MirrorUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width);
void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_AVX2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_SSE2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_C(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_Any_AVX2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_Any_SSE2(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_NEON(const uint8* src, uint8* dst, int width); void ARGBMirrorRow_Any_NEON(const uint8* src, uint8* dst, int width);
void ARGBMirrorRow_Any_MSA(const uint8* src, uint8* dst, int width);
void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width); void SplitUVRow_C(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int width);
void SplitUVRow_SSE2(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void SplitUVRow_SSE2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
@ -877,6 +886,14 @@ void ARGBCopyAlphaRow_Any_SSE2(const uint8* src_argb, uint8* dst_argb,
void ARGBCopyAlphaRow_Any_AVX2(const uint8* src_argb, uint8* dst_argb, void ARGBCopyAlphaRow_Any_AVX2(const uint8* src_argb, uint8* dst_argb,
int width); int width);
void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width);
void ARGBExtractAlphaRow_Any_SSE2(const uint8* src_argb, uint8* dst_a,
int width);
void ARGBExtractAlphaRow_Any_NEON(const uint8* src_argb, uint8* dst_a,
int width);
void ARGBCopyYToAlphaRow_C(const uint8* src_y, uint8* dst_argb, int width); void ARGBCopyYToAlphaRow_C(const uint8* src_y, uint8* dst_argb, int width);
void ARGBCopyYToAlphaRow_SSE2(const uint8* src_y, uint8* dst_argb, int width); void ARGBCopyYToAlphaRow_SSE2(const uint8* src_y, uint8* dst_argb, int width);
void ARGBCopyYToAlphaRow_AVX2(const uint8* src_y, uint8* dst_argb, int width); void ARGBCopyYToAlphaRow_AVX2(const uint8* src_y, uint8* dst_argb, int width);
@ -1926,4 +1943,4 @@ void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_ROW_H_ NOLINT #endif // INCLUDE_LIBYUV_ROW_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_SCALE_H_ // NOLINT #ifndef INCLUDE_LIBYUV_SCALE_H_
#define INCLUDE_LIBYUV_SCALE_H_ #define INCLUDE_LIBYUV_SCALE_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -100,4 +100,4 @@ void SetUseReferenceImpl(LIBYUV_BOOL use);
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_SCALE_H_ NOLINT #endif // INCLUDE_LIBYUV_SCALE_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_ // NOLINT #ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_
#define INCLUDE_LIBYUV_SCALE_ARGB_H_ #define INCLUDE_LIBYUV_SCALE_ARGB_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -53,4 +53,4 @@ int YUVToARGBScaleClip(const uint8* src_y, int src_stride_y,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_SCALE_ARGB_H_ NOLINT #endif // INCLUDE_LIBYUV_SCALE_ARGB_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_SCALE_ROW_H_ // NOLINT #ifndef INCLUDE_LIBYUV_SCALE_ROW_H_
#define INCLUDE_LIBYUV_SCALE_ROW_H_ #define INCLUDE_LIBYUV_SCALE_ROW_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -500,4 +500,4 @@ void ScaleRowDown38_3_Box_DSPR2(const uint8* src_ptr, ptrdiff_t src_stride,
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_SCALE_ROW_H_ NOLINT #endif // INCLUDE_LIBYUV_SCALE_ROW_H_

View File

@ -8,9 +8,9 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 1586 #define LIBYUV_VERSION 1620
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT #endif // INCLUDE_LIBYUV_VERSION_H_

View File

@ -10,7 +10,7 @@
// Common definitions for video, including fourcc and VideoFormat. // Common definitions for video, including fourcc and VideoFormat.
#ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_ // NOLINT #ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_
#define INCLUDE_LIBYUV_VIDEO_COMMON_H_ #define INCLUDE_LIBYUV_VIDEO_COMMON_H_
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
@ -181,4 +181,4 @@ LIBYUV_API uint32 CanonicalFourCC(uint32 fourcc);
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_ NOLINT #endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_

20
libs/libyuv/libyuv.gni Normal file
View File

@ -0,0 +1,20 @@
# Copyright 2016 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.
import("//build_overrides/build.gni")
import("//build/config/arm.gni")
import("//build/config/mips.gni")
declare_args() {
libyuv_include_tests = !build_with_chromium
libyuv_disable_jpeg = false
libyuv_use_neon = (current_cpu == "arm64" ||
(current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon)))
libyuv_use_msa = (current_cpu == "mips64el" || current_cpu == "mipsel") &&
mips_use_msa
}

View File

@ -25,14 +25,20 @@
'clang%': 0, 'clang%': 0,
# Link-Time Optimizations. # Link-Time Optimizations.
'use_lto%': 0, 'use_lto%': 0,
'mips_msa%': 0, # Default to msa off.
'build_neon': 0, 'build_neon': 0,
'build_msa': 0,
'conditions': [ 'conditions': [
['(target_arch == "armv7" or target_arch == "armv7s" or \ ['(target_arch == "armv7" or target_arch == "armv7s" or \
(target_arch == "arm" and arm_version >= 7) or target_arch == "arm64")\ (target_arch == "arm" and arm_version >= 7) or target_arch == "arm64")\
and (arm_neon == 1 or arm_neon_optional == 1)', and (arm_neon == 1 or arm_neon_optional == 1)', {
{
'build_neon': 1, 'build_neon': 1,
}], }],
['(target_arch == "mipsel" or target_arch == "mips64el")\
and (mips_msa == 1)',
{
'build_msa': 1,
}],
], ],
}, },
@ -61,6 +67,7 @@
'-mfpu=vfp', '-mfpu=vfp',
'-mfpu=vfpv3', '-mfpu=vfpv3',
'-mfpu=vfpv3-d16', '-mfpu=vfpv3-d16',
# '-mthumb', # arm32 not thumb
], ],
'conditions': [ 'conditions': [
# Disable LTO in libyuv_neon target due to gcc 4.9 compiler bug. # Disable LTO in libyuv_neon target due to gcc 4.9 compiler bug.
@ -74,10 +81,16 @@
['target_arch != "arm64"', { ['target_arch != "arm64"', {
'cflags': [ 'cflags': [
'-mfpu=neon', '-mfpu=neon',
# '-marm', # arm32 not thumb
], ],
}], }],
], ],
}], }],
['build_msa != 0', {
'defines': [
'LIBYUV_MSA',
],
}],
['OS != "ios" and libyuv_disable_jpeg != 1', { ['OS != "ios" and libyuv_disable_jpeg != 1', {
'defines': [ 'defines': [
'HAVE_JPEG' 'HAVE_JPEG'

View File

@ -18,6 +18,7 @@
'include/libyuv/convert_from.h', 'include/libyuv/convert_from.h',
'include/libyuv/convert_from_argb.h', 'include/libyuv/convert_from_argb.h',
'include/libyuv/cpu_id.h', 'include/libyuv/cpu_id.h',
'include/libyuv/macros_msa.h',
'include/libyuv/mjpeg_decoder.h', 'include/libyuv/mjpeg_decoder.h',
'include/libyuv/planar_functions.h', 'include/libyuv/planar_functions.h',
'include/libyuv/rotate.h', 'include/libyuv/rotate.h',
@ -61,6 +62,7 @@
'source/row_common.cc', 'source/row_common.cc',
'source/row_gcc.cc', 'source/row_gcc.cc',
'source/row_mips.cc', 'source/row_mips.cc',
'source/row_msa.cc',
'source/row_neon.cc', 'source/row_neon.cc',
'source/row_neon64.cc', 'source/row_neon64.cc',
'source/row_win.cc', 'source/row_win.cc',

View File

@ -9,6 +9,7 @@
{ {
'variables': { 'variables': {
'libyuv_disable_jpeg%': 0, 'libyuv_disable_jpeg%': 0,
'mips_msa%': 0, # Default to msa off.
}, },
'targets': [ 'targets': [
{ {
@ -52,11 +53,6 @@
'-fexceptions', '-fexceptions',
], ],
}], }],
[ 'OS == "ios" and target_subarch == 64', {
'defines': [
'LIBYUV_DISABLE_NEON'
],
}],
[ 'OS == "ios"', { [ 'OS == "ios"', {
'xcode_settings': { 'xcode_settings': {
'DEBUGGING_SYMBOLS': 'YES', 'DEBUGGING_SYMBOLS': 'YES',
@ -91,6 +87,12 @@
'LIBYUV_NEON' 'LIBYUV_NEON'
], ],
}], }],
[ '(target_arch == "mipsel" or target_arch == "mips64el") \
and (mips_msa == 1)', {
'defines': [
'LIBYUV_MSA'
],
}],
], # conditions ], # conditions
'defines': [ 'defines': [
# Enable the following 3 macros to turn off assembly for specified CPU. # Enable the following 3 macros to turn off assembly for specified CPU.
@ -151,12 +153,6 @@
'libyuv.gyp:libyuv', 'libyuv.gyp:libyuv',
], ],
'conditions': [ 'conditions': [
[ 'OS == "ios" and target_subarch == 64', {
'defines': [
'LIBYUV_DISABLE_NEON'
],
}],
[ 'OS != "ios" and libyuv_disable_jpeg != 1', { [ 'OS != "ios" and libyuv_disable_jpeg != 1', {
'defines': [ 'defines': [
'HAVE_JPEG', 'HAVE_JPEG',
@ -181,30 +177,16 @@
['OS=="android"', { ['OS=="android"', {
'targets': [ 'targets': [
{ {
# TODO(kjellander): Figure out what to change in build/apk_test.gypi 'target_name': 'yuv_unittest_apk',
# to it can be used instead of the copied code below. Using it in its
# current version was not possible, since the target starts with 'lib',
# which somewhere confuses the variables.
'target_name': 'libyuv_unittest_apk',
'type': 'none', 'type': 'none',
'variables': { 'variables': {
# These are used to configure java_apk.gypi included below. 'test_suite_name': 'yuv_unittest',
'test_type': 'gtest', 'input_shlib_path': '<(SHARED_LIB_DIR)/(SHARED_LIB_PREFIX)libyuv_unittest<(SHARED_LIB_SUFFIX)',
'apk_name': 'libyuv_unittest',
'intermediate_dir': '<(PRODUCT_DIR)/libyuv_unittest_apk',
'final_apk_path': '<(intermediate_dir)/libyuv_unittest-debug.apk',
'java_in_dir': '<(DEPTH)/testing/android/native_test/java',
'native_lib_target': 'libyuv_unittest',
'gyp_managed_install': 0,
}, },
'includes': [ 'build/java_apk.gypi' ], 'includes': [
'build/apk_test.gypi',
],
'dependencies': [ 'dependencies': [
'<(DEPTH)/base/base.gyp:base_java',
'<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
'<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
'<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
'<(DEPTH)/testing/android/on_device_instrumentation.gyp:reporter_java',
'<(DEPTH)/tools/android/android_tools.gyp:android_tools',
'libyuv_unittest', 'libyuv_unittest',
], ],
}, },

View File

@ -74,6 +74,8 @@ psnr: util/psnr.cc
$(CXX) $(CXXFLAGS) -Iutil/ -o $@ util/psnr.cc util/psnr_main.cc util/ssim.cc $(CXX) $(CXXFLAGS) -Iutil/ -o $@ util/psnr.cc util/psnr_main.cc util/ssim.cc
# A C test utility that uses libyuv conversion from C. # A C test utility that uses libyuv conversion from C.
# gcc 4.4 and older require -fno-exceptions to avoid link error on __gxx_personality_v0
# CC=gcc-4.4 CXXFLAGS=-fno-exceptions CXX=g++-4.4 make -f linux.mk
cpuid: util/cpuid.c libyuv.a cpuid: util/cpuid.c libyuv.a
$(CC) $(CFLAGS) -o $@ util/cpuid.c libyuv.a $(CC) $(CFLAGS) -o $@ util/cpuid.c libyuv.a

View File

@ -13,9 +13,6 @@ WebRTC standalone shares a lot of dependencies and build tools with Chromium.
To do this, many of the paths of a Chromium checkout is emulated by creating To do this, many of the paths of a Chromium checkout is emulated by creating
symlinks to files and directories. This script handles the setup of symlinks to symlinks to files and directories. This script handles the setup of symlinks to
achieve this. achieve this.
It also handles cleanup of the legacy Subversion-based approach that was used
before Chrome switched over their master repo from Subversion to Git.
""" """
@ -34,43 +31,25 @@ import textwrap
DIRECTORIES = [ DIRECTORIES = [
'build', 'build',
'buildtools', 'buildtools',
'google_apis', # Needed by build/common.gypi. 'mojo', # TODO(kjellander): Remove, see webrtc:5629.
'native_client', 'native_client',
'net', 'net',
'testing', 'testing',
'third_party/binutils', 'third_party/binutils',
'third_party/boringssl',
'third_party/colorama',
'third_party/drmemory', 'third_party/drmemory',
'third_party/expat',
'third_party/icu',
'third_party/instrumented_libraries', 'third_party/instrumented_libraries',
'third_party/jsoncpp',
'third_party/libjpeg', 'third_party/libjpeg',
'third_party/libjpeg_turbo', 'third_party/libjpeg_turbo',
'third_party/libsrtp',
'third_party/libudev',
'third_party/libvpx',
'third_party/libyuv',
'third_party/llvm-build', 'third_party/llvm-build',
'third_party/lss', 'third_party/lss',
'third_party/nss',
'third_party/ocmock',
'third_party/openmax_dl',
'third_party/opus',
'third_party/proguard', 'third_party/proguard',
'third_party/protobuf', 'third_party/tcmalloc',
'third_party/sqlite',
'third_party/syzygy',
'third_party/usrsctp',
'third_party/yasm', 'third_party/yasm',
'third_party/zlib', 'third_party/WebKit', # TODO(kjellander): Remove, see webrtc:5629.
'tools/clang', 'tools/clang',
'tools/generate_library_loader',
'tools/gn', 'tools/gn',
'tools/gyp', 'tools/gyp',
'tools/memory', 'tools/memory',
'tools/protoc_wrapper',
'tools/python', 'tools/python',
'tools/swarming_client', 'tools/swarming_client',
'tools/valgrind', 'tools/valgrind',
@ -83,31 +62,40 @@ target_os = get_target_os_list()
if 'android' in target_os: if 'android' in target_os:
DIRECTORIES += [ DIRECTORIES += [
'base', 'base',
'third_party/accessibility_test_framework',
'third_party/android_platform', 'third_party/android_platform',
'third_party/android_testrunner',
'third_party/android_tools', 'third_party/android_tools',
'third_party/apache_velocity',
'third_party/appurify-python', 'third_party/appurify-python',
'third_party/ashmem', 'third_party/ashmem',
'third_party/bouncycastle',
'third_party/catapult', 'third_party/catapult',
'third_party/ced',
'third_party/closure_compiler',
'third_party/guava',
'third_party/hamcrest',
'third_party/icu',
'third_party/icu4j',
'third_party/ijar', 'third_party/ijar',
'third_party/intellij',
'third_party/jsr-305', 'third_party/jsr-305',
'third_party/junit', 'third_party/junit',
'third_party/libevent',
'third_party/libxml', 'third_party/libxml',
'third_party/mockito', 'third_party/mockito',
'third_party/modp_b64', 'third_party/modp_b64',
'third_party/ow2_asm',
'third_party/protobuf',
'third_party/requests', 'third_party/requests',
'third_party/robolectric', 'third_party/robolectric',
'third_party/sqlite4java',
'third_party/zlib',
'tools/android', 'tools/android',
'tools/grit', 'tools/grit',
'tools/relocation_packer',
'tools/telemetry',
] ]
if 'ios' in target_os: if 'ios' in target_os:
DIRECTORIES.append('third_party/class-dump') DIRECTORIES.append('third_party/class-dump')
FILES = { FILES = {
'tools/find_depot_tools.py': None,
'tools/isolate_driver.py': None, 'tools/isolate_driver.py': None,
'third_party/BUILD.gn': None, 'third_party/BUILD.gn': None,
} }
@ -201,7 +189,7 @@ class Rmtree(Action):
def doit(self, _): def doit(self, _):
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
# shutil.rmtree() doesn't work on Windows if any of the directories are # shutil.rmtree() doesn't work on Windows if any of the directories are
# read-only, which svn repositories are. # read-only.
subprocess.check_call(['rd', '/q', '/s', self._path], shell=True) subprocess.check_call(['rd', '/q', '/s', self._path], shell=True)
else: else:
shutil.rmtree(self._path) shutil.rmtree(self._path)
@ -257,15 +245,16 @@ class LinkError(IOError):
pass pass
# Handles symlink creation on the different platforms. # Use junctions instead of symlinks on the Windows platform.
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
def symlink(source_path, link_path): def symlink(source_path, link_path):
flag = 1 if os.path.isdir(source_path) else 0 if os.path.isdir(source_path):
if not ctypes.windll.kernel32.CreateSymbolicLinkW( subprocess.check_call(['cmd.exe', '/c', 'mklink', '/J', link_path,
unicode(link_path), unicode(source_path), flag): source_path])
raise OSError('Failed to create symlink to %s. Notice that only NTFS ' else:
'version 5.0 and up has all the needed APIs for ' # Don't create symlinks to files on Windows, just copy the file instead
'creating symlinks.' % source_path) # (there's no way to create a link without administrator's privileges).
shutil.copy(source_path, link_path)
os.symlink = symlink os.symlink = symlink
@ -317,18 +306,10 @@ class WebRTCLinkSetup(object):
A C T I O N R E Q I R E D A C T I O N R E Q I R E D
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Because chromium/src is transitioning to Git (from SVN), we needed to Setting up the checkout requires creating symlinks to directories in the
change the way that the WebRTC standalone checkout works. Instead of Chromium checkout inside chromium/src.
individually syncing subdirectories of Chromium in SVN, we're now To avoid disrupting developers, we've chosen to not delete directories
syncing Chromium (and all of its DEPS, as defined by its own DEPS file), forcibly, in case you have some work in progress in one of them :)
into the `chromium/src` directory.
As such, all Chromium directories which are currently pulled by DEPS are
now replaced with a symlink into the full Chromium checkout.
To avoid disrupting developers, we've chosen to not delete your
directories forcibly, in case you have some work in progress in one of
them :).
ACTION REQUIRED: ACTION REQUIRED:
Before running `gclient sync|runhooks` again, you must run: Before running `gclient sync|runhooks` again, you must run:
@ -336,7 +317,7 @@ class WebRTCLinkSetup(object):
Which will replace all directories which now must be symlinks, after Which will replace all directories which now must be symlinks, after
prompting with a summary of the work-to-be-done. prompting with a summary of the work-to-be-done.
"""), 'python ' if sys.platform.startswith('win') else '', sys.argv[0]) """), 'python ' if sys.platform.startswith('win') else '', __file__)
sys.exit(1) sys.exit(1)
elif self._prompt: elif self._prompt:
if not query_yes_no('Would you like to perform the above plan?'): if not query_yes_no('Would you like to perform the above plan?'):
@ -374,8 +355,9 @@ class WebRTCLinkSetup(object):
check_msg=None): check_msg=None):
"""Create zero or more Actions to link to a file or directory. """Create zero or more Actions to link to a file or directory.
This will be a symlink on POSIX platforms. On Windows this requires This will be a symlink on POSIX platforms. On Windows it will result in:
that NTFS is version 5.0 or higher (Vista or newer). * a junction for directories
* a copied file for single files.
Args: Args:
source_path: Path relative to the Chromium checkout root. source_path: Path relative to the Chromium checkout root.
@ -405,8 +387,8 @@ class WebRTCLinkSetup(object):
source_path = fix_separators(source_path) source_path = fix_separators(source_path)
source_path = os.path.join(CHROMIUM_CHECKOUT, source_path) source_path = os.path.join(CHROMIUM_CHECKOUT, source_path)
if os.path.exists(source_path) and not check_fn: if os.path.exists(source_path) and not check_fn:
raise LinkError('_LinkChromiumPath can only be used to link to %s: ' raise LinkError('Can only to link to %s: tried to link to: %s' %
'Tried to link to: %s' % (check_msg, source_path)) (check_msg, source_path))
if not os.path.exists(source_path): if not os.path.exists(source_path):
logging.debug('Silently ignoring missing source: %s. This is to avoid ' logging.debug('Silently ignoring missing source: %s. This is to avoid '
@ -489,12 +471,9 @@ def main():
return os.getuid() == 0 return os.getuid() == 0
except AttributeError: except AttributeError:
return ctypes.windll.shell32.IsUserAnAdmin() != 0 return ctypes.windll.shell32.IsUserAnAdmin() != 0
if not is_admin(): if is_admin():
logging.error('On Windows, you now need to have administrator ' logging.warning('WARNING: On Windows, you no longer need run as '
'privileges for the shell running %s (or ' 'administrator. Please run with user account privileges.')
'`gclient sync|runhooks`).\nPlease start another command '
'prompt as Administrator and try again.', sys.argv[0])
return 1
if not os.path.exists(CHROMIUM_CHECKOUT): if not os.path.exists(CHROMIUM_CHECKOUT):
logging.error('Cannot find a Chromium checkout at %s. Did you run "gclient ' logging.error('Cannot find a Chromium checkout at %s. Did you run "gclient '

View File

@ -40,13 +40,14 @@ static int I4xxToI420(const uint8* src_y, int src_stride_y,
const int dst_y_height = Abs(src_y_height); const int dst_y_height = Abs(src_y_height);
const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1);
const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1);
if (src_y_width == 0 || src_y_height == 0 || if (src_uv_width == 0 || src_uv_height == 0) {
src_uv_width == 0 || src_uv_height == 0) {
return -1; return -1;
} }
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, if (dst_y) {
dst_y, dst_stride_y, dst_y_width, dst_y_height, ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
kFilterBilinear); dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
}
ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height,
dst_u, dst_stride_u, dst_uv_width, dst_uv_height, dst_u, dst_stride_u, dst_uv_width, dst_uv_height,
kFilterBilinear); kFilterBilinear);
@ -69,8 +70,8 @@ int I420Copy(const uint8* src_y, int src_stride_y,
int width, int height) { int width, int height) {
int halfwidth = (width + 1) >> 1; int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1; int halfheight = (height + 1) >> 1;
if (!src_y || !src_u || !src_v || if (!src_u || !src_v ||
!dst_y || !dst_u || !dst_v || !dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
@ -166,7 +167,7 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
int width, int height) { int width, int height) {
int halfwidth = (width + 1) >> 1; int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1; int halfheight = (height + 1) >> 1;
if (!src_y || !dst_y || !dst_u || !dst_v || if (!dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
@ -177,7 +178,9 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
src_y = src_y + (height - 1) * src_stride_y; src_y = src_y + (height - 1) * src_stride_y;
src_stride_y = -src_stride_y; src_stride_y = -src_stride_y;
} }
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128); SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128);
SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128); SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128);
return 0; return 0;
@ -242,13 +245,9 @@ static int X420ToI420(const uint8* src_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
int y;
int halfwidth = (width + 1) >> 1; int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1; int halfheight = (height + 1) >> 1;
void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, if (!src_uv || !dst_u || !dst_v ||
int width) = SplitUVRow_C;
if (!src_y || !src_uv ||
!dst_y || !dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
@ -256,7 +255,9 @@ static int X420ToI420(const uint8* src_y,
if (height < 0) { if (height < 0) {
height = -height; height = -height;
halfheight = (height + 1) >> 1; halfheight = (height + 1) >> 1;
dst_y = dst_y + (height - 1) * dst_stride_y; if (dst_y) {
dst_y = dst_y + (height - 1) * dst_stride_y;
}
dst_u = dst_u + (halfheight - 1) * dst_stride_u; dst_u = dst_u + (halfheight - 1) * dst_stride_u;
dst_v = dst_v + (halfheight - 1) * dst_stride_v; dst_v = dst_v + (halfheight - 1) * dst_stride_v;
dst_stride_y = -dst_stride_y; dst_stride_y = -dst_stride_y;
@ -279,41 +280,6 @@ static int X420ToI420(const uint8* src_y,
halfheight = 1; halfheight = 1;
src_stride_uv = dst_stride_u = dst_stride_v = 0; src_stride_uv = dst_stride_u = dst_stride_v = 0;
} }
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_SSE2;
}
}
#endif
#if defined(HAS_SPLITUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
SplitUVRow = SplitUVRow_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
SplitUVRow = SplitUVRow_AVX2;
}
}
#endif
#if defined(HAS_SPLITUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SplitUVRow = SplitUVRow_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_NEON;
}
}
#endif
#if defined(HAS_SPLITUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(src_uv, 4) && IS_ALIGNED(src_stride_uv, 4) &&
IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) &&
IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) {
SplitUVRow = SplitUVRow_Any_DSPR2;
if (IS_ALIGNED(halfwidth, 16)) {
SplitUVRow = SplitUVRow_DSPR2;
}
}
#endif
if (dst_y) { if (dst_y) {
if (src_stride_y0 == src_stride_y1) { if (src_stride_y0 == src_stride_y1) {
@ -324,13 +290,10 @@ static int X420ToI420(const uint8* src_y,
} }
} }
for (y = 0; y < halfheight; ++y) { // Split UV plane - NV12 / NV21
// Copy a row of UV. SplitUVPlane(src_uv, src_stride_uv, dst_u, dst_stride_u, dst_v, dst_stride_v,
SplitUVRow(src_uv, dst_u, dst_v, halfwidth); halfwidth, halfheight);
dst_u += dst_stride_u;
dst_v += dst_stride_v;
src_uv += src_stride_uv;
}
return 0; return 0;
} }
@ -1383,6 +1346,81 @@ int ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444,
return 0; return 0;
} }
static void SplitPixels(const uint8* src_u, int src_pixel_stride_uv,
uint8* dst_u, int width) {
int i;
for (i = 0; i < width; ++i) {
*dst_u = *src_u;
++dst_u;
src_u += src_pixel_stride_uv;
}
}
// Convert Android420 to I420.
LIBYUV_API
int Android420ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
int src_pixel_stride_uv,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
const int vu_off = src_v - src_u;
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_u || !src_v ||
!dst_u || !dst_v ||
width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
halfheight = (height + 1) >> 1;
src_y = src_y + (height - 1) * src_stride_y;
src_u = src_u + (halfheight - 1) * src_stride_u;
src_v = src_v + (halfheight - 1) * src_stride_v;
src_stride_y = -src_stride_y;
src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v;
}
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
// Copy UV planes as is - I420
if (src_pixel_stride_uv == 1) {
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight);
return 0;
// Split UV planes - NV21
} else if (src_pixel_stride_uv == 2 && vu_off == -1 &&
src_stride_u == src_stride_v) {
SplitUVPlane(src_v, src_stride_v, dst_v, dst_stride_v, dst_u, dst_stride_u,
halfwidth, halfheight);
return 0;
// Split UV planes - NV12
} else if (src_pixel_stride_uv == 2 && vu_off == 1 &&
src_stride_u == src_stride_v) {
SplitUVPlane(src_u, src_stride_u, dst_u, dst_stride_u, dst_v, dst_stride_v,
halfwidth, halfheight);
return 0;
}
for (y = 0; y < halfheight; ++y) {
SplitPixels(src_u, src_pixel_stride_uv, dst_u, halfwidth);
SplitPixels(src_v, src_pixel_stride_uv, dst_v, halfwidth);
src_u += src_stride_u;
src_v += src_stride_v;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
return 0;
}
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
} // namespace libyuv } // namespace libyuv

View File

@ -14,6 +14,7 @@
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
#include "libyuv/mjpeg_decoder.h" #include "libyuv/mjpeg_decoder.h"
#endif #endif
#include "libyuv/planar_functions.h" // For CopyPlane and ARGBShuffle.
#include "libyuv/rotate_argb.h" #include "libyuv/rotate_argb.h"
#include "libyuv/row.h" #include "libyuv/row.h"
#include "libyuv/video_common.h" #include "libyuv/video_common.h"

View File

@ -46,9 +46,11 @@ static int I420ToI4xx(const uint8* src_y, int src_stride_y,
dst_uv_width <= 0 || dst_uv_height <= 0) { dst_uv_width <= 0 || dst_uv_height <= 0) {
return -1; return -1;
} }
ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, if (dst_y) {
dst_y, dst_stride_y, dst_y_width, dst_y_height, ScalePlane(src_y, src_stride_y, src_y_width, src_y_height,
kFilterBilinear); dst_y, dst_stride_y, dst_y_width, dst_y_height,
kFilterBilinear);
}
ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height,
dst_u, dst_stride_u, dst_uv_width, dst_uv_height, dst_u, dst_stride_u, dst_uv_width, dst_uv_height,
kFilterBilinear); kFilterBilinear);
@ -359,6 +361,7 @@ int I420ToUYVY(const uint8* src_y, int src_stride_y,
return 0; return 0;
} }
// TODO(fbarchard): test negative height for invert.
LIBYUV_API LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y, int I420ToNV12(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u, const uint8* src_u, int src_stride_u,
@ -366,72 +369,19 @@ int I420ToNV12(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
uint8* dst_uv, int dst_stride_uv, uint8* dst_uv, int dst_stride_uv,
int width, int height) { int width, int height) {
int y;
void (*MergeUVRow_)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) = MergeUVRow_C;
// Coalesce rows.
int halfwidth = (width + 1) >> 1;
int halfheight = (height + 1) >> 1;
if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || if (!src_y || !src_u || !src_v || !dst_y || !dst_uv ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
// Negative height means invert the image. int halfwidth = (width + 1) / 2;
if (height < 0) { int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2;
height = -height; if (dst_y) {
halfheight = (height + 1) >> 1; CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_uv = dst_uv + (halfheight - 1) * dst_stride_uv;
dst_stride_y = -dst_stride_y;
dst_stride_uv = -dst_stride_uv;
}
if (src_stride_y == width &&
dst_stride_y == width) {
width *= height;
height = 1;
src_stride_y = dst_stride_y = 0;
}
// Coalesce rows.
if (src_stride_u == halfwidth &&
src_stride_v == halfwidth &&
dst_stride_uv == halfwidth * 2) {
halfwidth *= halfheight;
halfheight = 1;
src_stride_u = src_stride_v = dst_stride_uv = 0;
}
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow_ = MergeUVRow_Any_SSE2;
if (IS_ALIGNED(halfwidth, 16)) {
MergeUVRow_ = MergeUVRow_SSE2;
}
}
#endif
#if defined(HAS_MERGEUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
MergeUVRow_ = MergeUVRow_Any_AVX2;
if (IS_ALIGNED(halfwidth, 32)) {
MergeUVRow_ = MergeUVRow_AVX2;
}
}
#endif
#if defined(HAS_MERGEUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
MergeUVRow_ = MergeUVRow_Any_NEON;
if (IS_ALIGNED(halfwidth, 16)) {
MergeUVRow_ = MergeUVRow_NEON;
}
}
#endif
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
for (y = 0; y < halfheight; ++y) {
// Merge a row of U and V into a row of UV.
MergeUVRow_(src_u, src_v, dst_uv, halfwidth);
src_u += src_stride_u;
src_v += src_stride_v;
dst_uv += dst_stride_uv;
} }
MergeUVPlane(src_u, src_stride_u,
src_v, src_stride_v,
dst_uv, dst_stride_uv,
halfwidth, halfheight);
return 0; return 0;
} }
@ -1077,7 +1027,6 @@ int ConvertFromI420(const uint8* y, int y_stride,
// Triplanar formats // Triplanar formats
// TODO(fbarchard): halfstride instead of halfwidth // TODO(fbarchard): halfstride instead of halfwidth
case FOURCC_I420: case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: { case FOURCC_YV12: {
int halfwidth = (width + 1) / 2; int halfwidth = (width + 1) / 2;
int halfheight = (height + 1) / 2; int halfheight = (height + 1) / 2;

View File

@ -9,6 +9,7 @@
*/ */
#include "libyuv/convert.h" #include "libyuv/convert.h"
#include "libyuv/convert_argb.h"
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
#include "libyuv/mjpeg_decoder.h" #include "libyuv/mjpeg_decoder.h"

View File

@ -176,7 +176,6 @@ int ConvertToARGB(const uint8* sample, size_t sample_size,
break; break;
// Triplanar formats // Triplanar formats
case FOURCC_I420: case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: { case FOURCC_YV12: {
const uint8* src_y = sample + (src_width * crop_y + crop_x); const uint8* src_y = sample + (src_width * crop_y + crop_x);
const uint8* src_u; const uint8* src_u;

View File

@ -39,12 +39,13 @@ int ConvertToI420(const uint8* sample,
int aligned_src_width = (src_width + 1) & ~1; int aligned_src_width = (src_width + 1) & ~1;
const uint8* src; const uint8* src;
const uint8* src_uv; const uint8* src_uv;
int abs_src_height = (src_height < 0) ? -src_height : src_height; const int abs_src_height = (src_height < 0) ? -src_height : src_height;
int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; // TODO(nisse): Why allow crop_height < 0?
const int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height;
int r = 0; int r = 0;
LIBYUV_BOOL need_buf = (rotation && format != FOURCC_I420 && LIBYUV_BOOL need_buf = (rotation && format != FOURCC_I420 &&
format != FOURCC_NV12 && format != FOURCC_NV21 && format != FOURCC_NV12 && format != FOURCC_NV21 &&
format != FOURCC_YU12 && format != FOURCC_YV12) || y == sample; format != FOURCC_YV12) || y == sample;
uint8* tmp_y = y; uint8* tmp_y = y;
uint8* tmp_u = u; uint8* tmp_u = u;
uint8* tmp_v = v; uint8* tmp_v = v;
@ -52,16 +53,14 @@ int ConvertToI420(const uint8* sample,
int tmp_u_stride = u_stride; int tmp_u_stride = u_stride;
int tmp_v_stride = v_stride; int tmp_v_stride = v_stride;
uint8* rotate_buffer = NULL; uint8* rotate_buffer = NULL;
int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; const int inv_crop_height =
(src_height < 0) ? -abs_crop_height : abs_crop_height;
if (!y || !u || !v || !sample || if (!y || !u || !v || !sample ||
src_width <= 0 || crop_width <= 0 || src_width <= 0 || crop_width <= 0 ||
src_height == 0 || crop_height == 0) { src_height == 0 || crop_height == 0) {
return -1; return -1;
} }
if (src_height < 0) {
inv_crop_height = -inv_crop_height;
}
// One pass rotation is available for some formats. For the rest, convert // One pass rotation is available for some formats. For the rest, convert
// to I420 (with optional vertical flipping) into a temporary I420 buffer, // to I420 (with optional vertical flipping) into a temporary I420 buffer,
@ -214,7 +213,6 @@ int ConvertToI420(const uint8* sample,
break; break;
// Triplanar formats // Triplanar formats
case FOURCC_I420: case FOURCC_I420:
case FOURCC_YU12:
case FOURCC_YV12: { case FOURCC_YV12: {
const uint8* src_y = sample + (src_width * crop_y + crop_x); const uint8* src_y = sample + (src_width * crop_y + crop_x);
const uint8* src_u; const uint8* src_u;

View File

@ -161,6 +161,38 @@ int ArmCpuCaps(const char* cpuinfo_name) {
return 0; return 0;
} }
LIBYUV_API SAFEBUFFERS
int MipsCpuCaps(const char* cpuinfo_name, const char ase[]) {
char cpuinfo_line[512];
int len = (int)strlen(ase);
FILE* f = fopen(cpuinfo_name, "r");
if (!f) {
// ase enabled if /proc/cpuinfo is unavailable.
if (strcmp(ase, " msa") == 0) {
return kCpuHasMSA;
}
if (strcmp(ase, " dspr2") == 0) {
return kCpuHasDSPR2;
}
}
while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) {
if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) {
char* p = strstr(cpuinfo_line, ase);
if (p && (p[len] == ' ' || p[len] == '\n')) {
fclose(f);
if (strcmp(ase, " msa") == 0) {
return kCpuHasMSA;
}
if (strcmp(ase, " dspr2") == 0) {
return kCpuHasDSPR2;
}
}
}
}
fclose(f);
return 0;
}
// CPU detect function for SIMD instruction sets. // CPU detect function for SIMD instruction sets.
LIBYUV_API LIBYUV_API
int cpu_info_ = 0; // cpu_info is not initialized yet. int cpu_info_ = 0; // cpu_info is not initialized yet.
@ -253,11 +285,17 @@ int InitCpuFlags(void) {
#if defined(__mips__) && defined(__linux__) #if defined(__mips__) && defined(__linux__)
#if defined(__mips_dspr2) #if defined(__mips_dspr2)
cpu_info |= kCpuHasDSPR2; cpu_info |= kCpuHasDSPR2;
#endif
#if defined(__mips_msa)
cpu_info = MipsCpuCaps("/proc/cpuinfo", " msa");
#endif #endif
cpu_info |= kCpuHasMIPS; cpu_info |= kCpuHasMIPS;
if (getenv("LIBYUV_DISABLE_DSPR2")) { if (getenv("LIBYUV_DISABLE_DSPR2")) {
cpu_info &= ~kCpuHasDSPR2; cpu_info &= ~kCpuHasDSPR2;
} }
if (getenv("LIBYUV_DISABLE_MSA")) {
cpu_info &= ~kCpuHasMSA;
}
#endif #endif
#if defined(__arm__) || defined(__aarch64__) #if defined(__arm__) || defined(__aarch64__)
// gcc -mfpu=neon defines __ARM_NEON__ // gcc -mfpu=neon defines __ARM_NEON__

View File

@ -62,6 +62,7 @@ void init_source(jpeg_decompress_struct* cinfo);
void skip_input_data(jpeg_decompress_struct* cinfo, long num_bytes); // NOLINT void skip_input_data(jpeg_decompress_struct* cinfo, long num_bytes); // NOLINT
void term_source(jpeg_decompress_struct* cinfo); void term_source(jpeg_decompress_struct* cinfo);
void ErrorHandler(jpeg_common_struct* cinfo); void ErrorHandler(jpeg_common_struct* cinfo);
void OutputHandler(jpeg_common_struct* cinfo);
MJpegDecoder::MJpegDecoder() MJpegDecoder::MJpegDecoder()
: has_scanline_padding_(LIBYUV_FALSE), : has_scanline_padding_(LIBYUV_FALSE),
@ -77,6 +78,7 @@ MJpegDecoder::MJpegDecoder()
decompress_struct_->err = jpeg_std_error(&error_mgr_->base); decompress_struct_->err = jpeg_std_error(&error_mgr_->base);
// Override standard exit()-based error handler. // Override standard exit()-based error handler.
error_mgr_->base.error_exit = &ErrorHandler; error_mgr_->base.error_exit = &ErrorHandler;
error_mgr_->base.output_message = &OutputHandler;
#endif #endif
decompress_struct_->client_data = NULL; decompress_struct_->client_data = NULL;
source_mgr_->init_source = &init_source; source_mgr_->init_source = &init_source;
@ -456,7 +458,12 @@ void ErrorHandler(j_common_ptr cinfo) {
// and causes it to return (for a second time) with value 1. // and causes it to return (for a second time) with value 1.
longjmp(mgr->setjmp_buffer, 1); longjmp(mgr->setjmp_buffer, 1);
} }
#endif
void OutputHandler(j_common_ptr cinfo) {
// Suppress fprintf warnings.
}
#endif // HAVE_SETJMP
void MJpegDecoder::AllocOutputBuffers(int num_outbufs) { void MJpegDecoder::AllocOutputBuffers(int num_outbufs) {
if (num_outbufs != num_outbufs_) { if (num_outbufs != num_outbufs_) {

View File

@ -31,6 +31,12 @@ void CopyPlane(const uint8* src_y, int src_stride_y,
int width, int height) { int width, int height) {
int y; int y;
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_y = dst_y + (height - 1) * dst_stride_y;
dst_stride_y = -dst_stride_y;
}
// Coalesce rows. // Coalesce rows.
if (src_stride_y == width && if (src_stride_y == width &&
dst_stride_y == width) { dst_stride_y == width) {
@ -76,6 +82,7 @@ void CopyPlane(const uint8* src_y, int src_stride_y,
} }
} }
// TODO(fbarchard): Consider support for negative height.
LIBYUV_API LIBYUV_API
void CopyPlane_16(const uint16* src_y, int src_stride_y, void CopyPlane_16(const uint16* src_y, int src_stride_y,
uint16* dst_y, int dst_stride_y, uint16* dst_y, int dst_stride_y,
@ -128,8 +135,8 @@ int I422Copy(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
int halfwidth = (width + 1) >> 1; int halfwidth = (width + 1) >> 1;
if (!src_y || !src_u || !src_v || if (!src_u || !src_v ||
!dst_y || !dst_u || !dst_v || !dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
@ -143,7 +150,10 @@ int I422Copy(const uint8* src_y, int src_stride_y,
src_stride_u = -src_stride_u; src_stride_u = -src_stride_u;
src_stride_v = -src_stride_v; src_stride_v = -src_stride_v;
} }
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height); CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height); CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height);
return 0; return 0;
@ -158,8 +168,8 @@ int I444Copy(const uint8* src_y, int src_stride_y,
uint8* dst_u, int dst_stride_u, uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v, uint8* dst_v, int dst_stride_v,
int width, int height) { int width, int height) {
if (!src_y || !src_u || !src_v || if (!src_u || !src_v ||
!dst_y || !dst_u || !dst_v || !dst_u || !dst_v ||
width <= 0 || height == 0) { width <= 0 || height == 0) {
return -1; return -1;
} }
@ -174,7 +184,9 @@ int I444Copy(const uint8* src_y, int src_stride_y,
src_stride_v = -src_stride_v; src_stride_v = -src_stride_v;
} }
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); if (dst_y) {
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
}
CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height); CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height);
CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height); CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height);
return 0; return 0;
@ -214,10 +226,138 @@ int I420ToI400(const uint8* src_y, int src_stride_y,
src_y = src_y + (height - 1) * src_stride_y; src_y = src_y + (height - 1) * src_stride_y;
src_stride_y = -src_stride_y; src_stride_y = -src_stride_y;
} }
CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
return 0; return 0;
} }
// Support function for NV12 etc UV channels.
// Width and height are plane sizes (typically half pixel width).
LIBYUV_API
void SplitUVPlane(const uint8* src_uv, int src_stride_uv,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) = SplitUVRow_C;
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_u = dst_u + (height - 1) * dst_stride_u;
dst_v = dst_v + (height - 1) * dst_stride_v;
dst_stride_u = -dst_stride_u;
dst_stride_v = -dst_stride_v;
}
// Coalesce rows.
if (src_stride_uv == width * 2 &&
dst_stride_u == width &&
dst_stride_v == width) {
width *= height;
height = 1;
src_stride_uv = dst_stride_u = dst_stride_v = 0;
}
#if defined(HAS_SPLITUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SplitUVRow = SplitUVRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_SSE2;
}
}
#endif
#if defined(HAS_SPLITUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
SplitUVRow = SplitUVRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
SplitUVRow = SplitUVRow_AVX2;
}
}
#endif
#if defined(HAS_SPLITUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SplitUVRow = SplitUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_NEON;
}
}
#endif
#if defined(HAS_SPLITUVROW_DSPR2)
if (TestCpuFlag(kCpuHasDSPR2) &&
IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) &&
IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) {
SplitUVRow = SplitUVRow_Any_DSPR2;
if (IS_ALIGNED(width, 16)) {
SplitUVRow = SplitUVRow_DSPR2;
}
}
#endif
for (y = 0; y < height; ++y) {
// Copy a row of UV.
SplitUVRow(src_uv, dst_u, dst_v, width);
dst_u += dst_stride_u;
dst_v += dst_stride_v;
src_uv += src_stride_uv;
}
}
LIBYUV_API
void MergeUVPlane(const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
uint8* dst_uv, int dst_stride_uv,
int width, int height) {
int y;
void (*MergeUVRow)(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) = MergeUVRow_C;
// Coalesce rows.
// Negative height means invert the image.
if (height < 0) {
height = -height;
dst_uv = dst_uv + (height - 1) * dst_stride_uv;
dst_stride_uv = -dst_stride_uv;
}
// Coalesce rows.
if (src_stride_u == width &&
src_stride_v == width &&
dst_stride_uv == width * 2) {
width *= height;
height = 1;
src_stride_u = src_stride_v = dst_stride_uv = 0;
}
#if defined(HAS_MERGEUVROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
MergeUVRow = MergeUVRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
MergeUVRow = MergeUVRow_SSE2;
}
}
#endif
#if defined(HAS_MERGEUVROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
MergeUVRow = MergeUVRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
MergeUVRow = MergeUVRow_AVX2;
}
}
#endif
#if defined(HAS_MERGEUVROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
MergeUVRow = MergeUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
MergeUVRow = MergeUVRow_NEON;
}
}
#endif
for (y = 0; y < height; ++y) {
// Merge a row of U and V into a row of UV.
MergeUVRow(src_u, src_v, dst_uv, width);
src_u += src_stride_u;
src_v += src_stride_v;
dst_uv += dst_stride_uv;
}
}
// Mirror a plane of data. // Mirror a plane of data.
void MirrorPlane(const uint8* src_y, int src_stride_y, void MirrorPlane(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y, uint8* dst_y, int dst_stride_y,
@ -261,6 +401,14 @@ void MirrorPlane(const uint8* src_y, int src_stride_y,
IS_ALIGNED(dst_y, 4) && IS_ALIGNED(dst_stride_y, 4)) { IS_ALIGNED(dst_y, 4) && IS_ALIGNED(dst_stride_y, 4)) {
MirrorRow = MirrorRow_DSPR2; MirrorRow = MirrorRow_DSPR2;
} }
#endif
#if defined(HAS_MIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
MirrorRow = MirrorRow_Any_MSA;
if (IS_ALIGNED(width, 64)) {
MirrorRow = MirrorRow_MSA;
}
}
#endif #endif
// Mirror plane // Mirror plane
@ -511,6 +659,14 @@ int ARGBMirror(const uint8* src_argb, int src_stride_argb,
} }
} }
#endif #endif
#if defined(HAS_ARGBMIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBMirrorRow = ARGBMirrorRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBMirrorRow = ARGBMirrorRow_MSA;
}
}
#endif
// Mirror plane // Mirror plane
for (y = 0; y < height; ++y) { for (y = 0; y < height; ++y) {
@ -2374,6 +2530,49 @@ int ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb,
return 0; return 0;
} }
// Extract just the alpha channel from ARGB.
LIBYUV_API
int ARGBExtractAlpha(const uint8* src_argb, int src_stride,
uint8* dst_a, int dst_stride,
int width, int height) {
if (!src_argb || !dst_a || width <= 0 || height == 0) {
return -1;
}
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_argb += (height - 1) * src_stride;
src_stride = -src_stride;
}
// Coalesce rows.
if (src_stride == width * 4 && dst_stride == width) {
width *= height;
height = 1;
src_stride = dst_stride = 0;
}
void (*ARGBExtractAlphaRow)(const uint8 *src_argb, uint8 *dst_a, int width) =
ARGBExtractAlphaRow_C;
#if defined(HAS_ARGBEXTRACTALPHAROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2
: ARGBExtractAlphaRow_Any_SSE2;
}
#endif
#if defined(HAS_ARGBEXTRACTALPHAROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON
: ARGBExtractAlphaRow_Any_NEON;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBExtractAlphaRow(src_argb, dst_a, width);
src_argb += src_stride;
dst_a += dst_stride;
}
return 0;
}
// Copy a planar Y channel to the alpha channel of a destination ARGB image. // Copy a planar Y channel to the alpha channel of a destination ARGB image.
LIBYUV_API LIBYUV_API
int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y, int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,

View File

@ -141,6 +141,14 @@ void RotatePlane180(const uint8* src, int src_stride,
MirrorRow = MirrorRow_DSPR2; MirrorRow = MirrorRow_DSPR2;
} }
#endif #endif
#if defined(HAS_MIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
MirrorRow = MirrorRow_Any_MSA;
if (IS_ALIGNED(width, 64)) {
MirrorRow = MirrorRow_MSA;
}
}
#endif
#if defined(HAS_COPYROW_SSE2) #if defined(HAS_COPYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2)) {
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;

View File

@ -118,6 +118,14 @@ void ARGBRotate180(const uint8* src, int src_stride,
} }
} }
#endif #endif
#if defined(HAS_ARGBMIRRORROW_MSA)
if (TestCpuFlag(kCpuHasMSA)) {
ARGBMirrorRow = ARGBMirrorRow_Any_MSA;
if (IS_ALIGNED(width, 16)) {
ARGBMirrorRow = ARGBMirrorRow_MSA;
}
}
#endif
#if defined(HAS_COPYROW_SSE2) #if defined(HAS_COPYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) { if (TestCpuFlag(kCpuHasSSE2)) {
CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; CopyRow = IS_ALIGNED(width * 4, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;

View File

@ -23,7 +23,7 @@ extern "C" {
(_MIPS_SIM == _MIPS_SIM_ABI32) (_MIPS_SIM == _MIPS_SIM_ABI32)
void TransposeWx8_DSPR2(const uint8* src, int src_stride, void TransposeWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) { uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ ( __asm__ __volatile__ (
".set push \n" ".set push \n"
".set noreorder \n" ".set noreorder \n"
@ -107,7 +107,7 @@ void TransposeWx8_DSPR2(const uint8* src, int src_stride,
} }
void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride, void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width) { uint8* dst, int dst_stride, int width) {
__asm__ __volatile__ ( __asm__ __volatile__ (
".set noat \n" ".set noat \n"
".set push \n" ".set push \n"
@ -309,9 +309,9 @@ void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
} }
void TransposeUVWx8_DSPR2(const uint8* src, int src_stride, void TransposeUVWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a, uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, uint8* dst_b, int dst_stride_b,
int width) { int width) {
__asm__ __volatile__ ( __asm__ __volatile__ (
".set push \n" ".set push \n"
".set noreorder \n" ".set noreorder \n"

View File

@ -466,38 +466,15 @@ ANY11(ARGBUnattenuateRow_Any_AVX2, ARGBUnattenuateRow_AVX2, 0, 4, 4, 7)
#ifdef HAS_ARGBATTENUATEROW_NEON #ifdef HAS_ARGBATTENUATEROW_NEON
ANY11(ARGBAttenuateRow_Any_NEON, ARGBAttenuateRow_NEON, 0, 4, 4, 7) ANY11(ARGBAttenuateRow_Any_NEON, ARGBAttenuateRow_NEON, 0, 4, 4, 7)
#endif #endif
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
ANY11(ARGBExtractAlphaRow_Any_SSE2, ARGBExtractAlphaRow_SSE2, 0, 4, 1, 7)
#endif
#ifdef HAS_ARGBEXTRACTALPHAROW_NEON
ANY11(ARGBExtractAlphaRow_Any_NEON, ARGBExtractAlphaRow_NEON, 0, 4, 1, 15)
#endif
#undef ANY11 #undef ANY11
// Any 1 to 1 with yuvconstants // Any 1 to 1 blended. Destination is read, modify, write.
#define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, \
const struct YuvConstants* yuvconstants, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \
memset(temp, 0, 128); /* for YUY2 and msan */ \
int r = width & MASK; \
int n = width & ~MASK; \
if (n > 0) { \
ANY_SIMD(src_ptr, dst_ptr, yuvconstants, n); \
} \
memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \
ANY_SIMD(temp, temp + 128, yuvconstants, MASK + 1); \
memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \
}
#if defined(HAS_YUY2TOARGBROW_SSSE3)
ANY11C(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, 1, 4, 4, 15)
ANY11C(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, 1, 4, 4, 15)
#endif
#if defined(HAS_YUY2TOARGBROW_AVX2)
ANY11C(YUY2ToARGBRow_Any_AVX2, YUY2ToARGBRow_AVX2, 1, 4, 4, 31)
ANY11C(UYVYToARGBRow_Any_AVX2, UYVYToARGBRow_AVX2, 1, 4, 4, 31)
#endif
#if defined(HAS_YUY2TOARGBROW_NEON)
ANY11C(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, 1, 4, 4, 7)
ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#endif
#undef ANY11C
// Any 1 to 1 blended.
#define ANY11B(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \ #define ANY11B(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \ void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \ SIMD_ALIGNED(uint8 temp[128 * 2]); \
@ -516,7 +493,7 @@ ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#ifdef HAS_ARGBCOPYALPHAROW_AVX2 #ifdef HAS_ARGBCOPYALPHAROW_AVX2
ANY11B(ARGBCopyAlphaRow_Any_AVX2, ARGBCopyAlphaRow_AVX2, 0, 4, 4, 15) ANY11B(ARGBCopyAlphaRow_Any_AVX2, ARGBCopyAlphaRow_AVX2, 0, 4, 4, 15)
#endif #endif
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 #ifdef HAS_ARGBCOPYALPHAROW_SSE2
ANY11B(ARGBCopyAlphaRow_Any_SSE2, ARGBCopyAlphaRow_SSE2, 0, 4, 4, 7) ANY11B(ARGBCopyAlphaRow_Any_SSE2, ARGBCopyAlphaRow_SSE2, 0, 4, 4, 7)
#endif #endif
#ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2 #ifdef HAS_ARGBCOPYYTOALPHAROW_AVX2
@ -569,6 +546,35 @@ ANY11P(ARGBShuffleRow_Any_NEON, ARGBShuffleRow_NEON, const uint8*, 4, 4, 3)
#endif #endif
#undef ANY11P #undef ANY11P
// Any 1 to 1 with yuvconstants
#define ANY11C(NAMEANY, ANY_SIMD, UVSHIFT, SBPP, BPP, MASK) \
void NAMEANY(const uint8* src_ptr, uint8* dst_ptr, \
const struct YuvConstants* yuvconstants, int width) { \
SIMD_ALIGNED(uint8 temp[128 * 2]); \
memset(temp, 0, 128); /* for YUY2 and msan */ \
int r = width & MASK; \
int n = width & ~MASK; \
if (n > 0) { \
ANY_SIMD(src_ptr, dst_ptr, yuvconstants, n); \
} \
memcpy(temp, src_ptr + (n >> UVSHIFT) * SBPP, SS(r, UVSHIFT) * SBPP); \
ANY_SIMD(temp, temp + 128, yuvconstants, MASK + 1); \
memcpy(dst_ptr + n * BPP, temp + 128, r * BPP); \
}
#if defined(HAS_YUY2TOARGBROW_SSSE3)
ANY11C(YUY2ToARGBRow_Any_SSSE3, YUY2ToARGBRow_SSSE3, 1, 4, 4, 15)
ANY11C(UYVYToARGBRow_Any_SSSE3, UYVYToARGBRow_SSSE3, 1, 4, 4, 15)
#endif
#if defined(HAS_YUY2TOARGBROW_AVX2)
ANY11C(YUY2ToARGBRow_Any_AVX2, YUY2ToARGBRow_AVX2, 1, 4, 4, 31)
ANY11C(UYVYToARGBRow_Any_AVX2, UYVYToARGBRow_AVX2, 1, 4, 4, 31)
#endif
#if defined(HAS_YUY2TOARGBROW_NEON)
ANY11C(YUY2ToARGBRow_Any_NEON, YUY2ToARGBRow_NEON, 1, 4, 4, 7)
ANY11C(UYVYToARGBRow_Any_NEON, UYVYToARGBRow_NEON, 1, 4, 4, 7)
#endif
#undef ANY11C
// Any 1 to 1 interpolate. Takes 2 rows of source via stride. // Any 1 to 1 interpolate. Takes 2 rows of source via stride.
#define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \ #define ANY11T(NAMEANY, ANY_SIMD, SBPP, BPP, MASK) \
void NAMEANY(uint8* dst_ptr, const uint8* src_ptr, \ void NAMEANY(uint8* dst_ptr, const uint8* src_ptr, \
@ -625,6 +631,9 @@ ANY11M(MirrorRow_Any_SSSE3, MirrorRow_SSSE3, 1, 15)
#ifdef HAS_MIRRORROW_NEON #ifdef HAS_MIRRORROW_NEON
ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 15) ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 15)
#endif #endif
#ifdef HAS_MIRRORROW_MSA
ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63)
#endif
#ifdef HAS_ARGBMIRRORROW_AVX2 #ifdef HAS_ARGBMIRRORROW_AVX2
ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7) ANY11M(ARGBMirrorRow_Any_AVX2, ARGBMirrorRow_AVX2, 4, 7)
#endif #endif
@ -634,6 +643,9 @@ ANY11M(ARGBMirrorRow_Any_SSE2, ARGBMirrorRow_SSE2, 4, 3)
#ifdef HAS_ARGBMIRRORROW_NEON #ifdef HAS_ARGBMIRRORROW_NEON
ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 3) ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 3)
#endif #endif
#ifdef HAS_ARGBMIRRORROW_MSA
ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15)
#endif
#undef ANY11M #undef ANY11M
// Any 1 plane. (memset) // Any 1 plane. (memset)

View File

@ -988,8 +988,8 @@ void J400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
#define BG (UG * 128 + VG * 128 + YGB) #define BG (UG * 128 + VG * 128 + YGB)
#define BR (VR * 128 + YGB) #define BR (VR * 128 + YGB)
#if defined(__aarch64__) #if defined(__aarch64__) // 64 bit arm
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG }, { UG, VG, UG, VG, UG, VG, UG, VG },
@ -997,7 +997,7 @@ const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG }, { VG, UG, VG, UG, VG, UG, VG, UG },
@ -1005,21 +1005,21 @@ const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ BR, BG, BB, 0, 0, 0, 0, 0 }, { BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#elif defined(__arm__) #elif defined(__arm__) // 32 bit arm
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 }, { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 }, { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 }, { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 }, { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 }, { BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#else #else
const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 }, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1031,7 +1031,7 @@ const YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR }, { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG } { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
}; };
const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 }, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1076,7 +1076,7 @@ const YuvConstants SIMD_ALIGNED(kYvuI601Constants) = {
#define BR (VR * 128 + YGB) #define BR (VR * 128 + YGB)
#if defined(__aarch64__) #if defined(__aarch64__)
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG }, { UG, VG, UG, VG, UG, VG, UG, VG },
@ -1084,7 +1084,7 @@ const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG }, { VG, UG, VG, UG, VG, UG, VG, UG },
@ -1093,20 +1093,20 @@ const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#elif defined(__arm__) #elif defined(__arm__)
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 }, { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 }, { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 }, { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 }, { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 }, { BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#else #else
const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 }, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1118,7 +1118,7 @@ const YuvConstants SIMD_ALIGNED(kYuvJPEGConstants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR }, { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG } { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
}; };
const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = { const struct YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 }, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1164,7 +1164,7 @@ const YuvConstants SIMD_ALIGNED(kYvuJPEGConstants) = {
#define BR (VR * 128 + YGB) #define BR (VR * 128 + YGB)
#if defined(__aarch64__) #if defined(__aarch64__)
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR }, { -UB, -VR, -UB, -VR, -UB, -VR, -UB, -VR },
{ UG, VG, UG, VG, UG, VG, UG, VG }, { UG, VG, UG, VG, UG, VG, UG, VG },
@ -1172,7 +1172,7 @@ const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB }, { -VR, -UB, -VR, -UB, -VR, -UB, -VR, -UB },
{ VG, UG, VG, UG, VG, UG, VG, UG }, { VG, UG, VG, UG, VG, UG, VG, UG },
@ -1181,20 +1181,20 @@ const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#elif defined(__arm__) #elif defined(__arm__)
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 }, { -UB, -UB, -UB, -UB, -VR, -VR, -VR, -VR, 0, 0, 0, 0, 0, 0, 0, 0 },
{ UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 }, { UG, UG, UG, UG, VG, VG, VG, VG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BB, BG, BR, 0, 0, 0, 0, 0 }, { BB, BG, BR, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 }, { -VR, -VR, -VR, -VR, -UB, -UB, -UB, -UB, 0, 0, 0, 0, 0, 0, 0, 0 },
{ VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 }, { VG, VG, VG, VG, UG, UG, UG, UG, 0, 0, 0, 0, 0, 0, 0, 0 },
{ BR, BG, BB, 0, 0, 0, 0, 0 }, { BR, BG, BB, 0, 0, 0, 0, 0 },
{ 0x0101 * YG, 0, 0, 0 } { 0x0101 * YG, 0, 0, 0 }
}; };
#else #else
const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 }, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
{ UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
@ -1206,7 +1206,7 @@ const YuvConstants SIMD_ALIGNED(kYuvH709Constants) = {
{ BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR }, { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
{ YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG } { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG }
}; };
const YuvConstants SIMD_ALIGNED(kYvuH709Constants) = { const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
{ VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, { VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0,
VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 }, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0 },
{ VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, { VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG,
@ -1264,9 +1264,9 @@ static __inline void YuvPixel(uint8 y, uint8 u, uint8 v,
#endif #endif
uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16; uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16;
*b = Clamp((int32)(-(u * ub ) + y1 + bb) >> 6); *b = Clamp((int32)(-(u * ub) + y1 + bb) >> 6);
*g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6); *g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6);
*r = Clamp((int32)(-( v * vr) + y1 + br) >> 6); *r = Clamp((int32) (-(v * vr) + y1 + br) >> 6);
} }
// Y contribution to R,G,B. Scale and bias. // Y contribution to R,G,B. Scale and bias.
@ -2167,7 +2167,7 @@ static void HalfRow_16_C(const uint16* src_uv, ptrdiff_t src_uv_stride,
void InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr, void InterpolateRow_C(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride, ptrdiff_t src_stride,
int width, int source_y_fraction) { int width, int source_y_fraction) {
int y1_fraction = source_y_fraction ; int y1_fraction = source_y_fraction;
int y0_fraction = 256 - y1_fraction; int y0_fraction = 256 - y1_fraction;
const uint8* src_ptr1 = src_ptr + src_stride; const uint8* src_ptr1 = src_ptr + src_stride;
int x; int x;
@ -2381,6 +2381,19 @@ void ARGBCopyAlphaRow_C(const uint8* src, uint8* dst, int width) {
} }
} }
void ARGBExtractAlphaRow_C(const uint8* src_argb, uint8* dst_a, int width) {
int i;
for (i = 0; i < width - 1; i += 2) {
dst_a[0] = src_argb[3];
dst_a[1] = src_argb[7];
dst_a += 2;
src_argb += 8;
}
if (width & 1) {
dst_a[0] = src_argb[3];
}
}
void ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) { void ARGBCopyYToAlphaRow_C(const uint8* src, uint8* dst, int width) {
int i; int i;
for (i = 0; i < width - 1; i += 2) { for (i = 0; i < width - 1; i += 2) {
@ -2491,7 +2504,7 @@ void I422ToRGB565Row_AVX2(const uint8* src_y,
uint8* dst_rgb565, uint8* dst_rgb565,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) { while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2517,7 +2530,7 @@ void I422ToARGB1555Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
// Row buffer for intermediate ARGB pixels. // Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) { while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2543,7 +2556,7 @@ void I422ToARGB4444Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
// Row buffer for intermediate ARGB pixels. // Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) { while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2569,7 +2582,7 @@ void I422ToRGB24Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
// Row buffer for intermediate ARGB pixels. // Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) { while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth); I422ToARGBRow_AVX2(src_y, src_u, src_v, row, yuvconstants, twidth);
@ -2591,7 +2604,7 @@ void NV12ToRGB565Row_AVX2(const uint8* src_y,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
// Row buffer for intermediate ARGB pixels. // Row buffer for intermediate ARGB pixels.
SIMD_ALIGNED32(uint8 row[MAXTWIDTH * 4]); SIMD_ALIGNED(uint8 row[MAXTWIDTH * 4]);
while (width > 0) { while (width > 0) {
int twidth = width > MAXTWIDTH ? MAXTWIDTH : width; int twidth = width > MAXTWIDTH ? MAXTWIDTH : width;
NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth); NV12ToARGBRow_AVX2(src_y, src_uv, row, yuvconstants, twidth);

View File

@ -2936,6 +2936,33 @@ void ARGBCopyAlphaRow_AVX2(const uint8* src, uint8* dst, int width) {
} }
#endif // HAS_ARGBCOPYALPHAROW_AVX2 #endif // HAS_ARGBCOPYALPHAROW_AVX2
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
// width in pixels
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
LABELALIGN
"1: \n"
"movdqu " MEMACCESS(0) ", %%xmm0 \n"
"movdqu " MEMACCESS2(0x10, 0) ", %%xmm1 \n"
"lea " MEMLEA(0x20, 0) ", %0 \n"
"psrld $0x18, %%xmm0 \n"
"psrld $0x18, %%xmm1 \n"
"packssdw %%xmm1, %%xmm0 \n"
"packuswb %%xmm0, %%xmm0 \n"
"movq %%xmm0," MEMACCESS(1) " \n"
"lea " MEMLEA(0x8, 1) ", %1 \n"
"sub $0x8, %2 \n"
"jg 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+rm"(width) // %2
:
: "memory", "cc"
, "xmm0", "xmm1"
);
}
#endif // HAS_ARGBEXTRACTALPHAROW_SSE2
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 #ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2
// width in pixels // width in pixels
void ARGBCopyYToAlphaRow_SSE2(const uint8* src, uint8* dst, int width) { void ARGBCopyYToAlphaRow_SSE2(const uint8* src, uint8* dst, int width) {
@ -3569,7 +3596,7 @@ void BlendPlaneRow_SSSE3(const uint8* src0, const uint8* src1,
"+r"(src1), // %1 "+r"(src1), // %1
"+r"(alpha), // %2 "+r"(alpha), // %2
"+r"(dst), // %3 "+r"(dst), // %3
"+r"(width) // %4 "+rm"(width) // %4
:: "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7" :: "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7"
); );
} }
@ -3626,7 +3653,7 @@ void BlendPlaneRow_AVX2(const uint8* src0, const uint8* src1,
"+r"(src1), // %1 "+r"(src1), // %1
"+r"(alpha), // %2 "+r"(alpha), // %2
"+r"(dst), // %3 "+r"(dst), // %3
"+r"(width) // %4 "+rm"(width) // %4
:: "memory", "cc", "eax", :: "memory", "cc", "eax",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
); );
@ -4909,9 +4936,9 @@ void InterpolateRow_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"jg 100b \n" "jg 100b \n"
"99: \n" "99: \n"
: "+r"(dst_ptr), // %0 : "+r"(dst_ptr), // %0
"+r"(src_ptr), // %1 "+r"(src_ptr), // %1
"+r"(dst_width), // %2 "+rm"(dst_width), // %2
"+r"(source_y_fraction) // %3 "+r"(source_y_fraction) // %3
: "r"((intptr_t)(src_stride)) // %4 : "r"((intptr_t)(src_stride)) // %4
: "memory", "cc", "eax", NACL_R14 : "memory", "cc", "eax", NACL_R14
@ -4987,7 +5014,7 @@ void InterpolateRow_AVX2(uint8* dst_ptr, const uint8* src_ptr,
"999: \n" "999: \n"
: "+D"(dst_ptr), // %0 : "+D"(dst_ptr), // %0
"+S"(src_ptr), // %1 "+S"(src_ptr), // %1
"+c"(dst_width), // %2 "+cm"(dst_width), // %2
"+r"(source_y_fraction) // %3 "+r"(source_y_fraction) // %3
: "r"((intptr_t)(src_stride)) // %4 : "r"((intptr_t)(src_stride)) // %4
: "memory", "cc", "eax", NACL_R14 : "memory", "cc", "eax", NACL_R14

View File

@ -381,7 +381,7 @@ void CopyRow_MIPS(const uint8* src, uint8* dst, int count) {
(_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6) (_MIPS_SIM == _MIPS_SIM_ABI32) && (__mips_isa_rev < 6)
void SplitUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void SplitUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) { int width) {
__asm__ __volatile__ ( __asm__ __volatile__ (
".set push \n" ".set push \n"
".set noreorder \n" ".set noreorder \n"
@ -497,7 +497,7 @@ void MirrorRow_DSPR2(const uint8* src, uint8* dst, int width) {
} }
void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) { int width) {
int x; int x;
int y; int y;
__asm__ __volatile__ ( __asm__ __volatile__ (
@ -654,11 +654,11 @@ void MirrorUVRow_DSPR2(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
// TODO(fbarchard): accept yuv conversion constants. // TODO(fbarchard): accept yuv conversion constants.
void I422ToARGBRow_DSPR2(const uint8* y_buf, void I422ToARGBRow_DSPR2(const uint8* y_buf,
const uint8* u_buf, const uint8* u_buf,
const uint8* v_buf, const uint8* v_buf,
uint8* rgb_buf, uint8* rgb_buf,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
__asm__ __volatile__ ( __asm__ __volatile__ (
".set push \n" ".set push \n"
".set noreorder \n" ".set noreorder \n"
@ -717,8 +717,8 @@ void I422ToARGBRow_DSPR2(const uint8* y_buf,
// Bilinear filter 8x2 -> 8x1 // Bilinear filter 8x2 -> 8x1
void InterpolateRow_DSPR2(uint8* dst_ptr, const uint8* src_ptr, void InterpolateRow_DSPR2(uint8* dst_ptr, const uint8* src_ptr,
ptrdiff_t src_stride, int dst_width, ptrdiff_t src_stride, int dst_width,
int source_y_fraction) { int source_y_fraction) {
int y0_fraction = 256 - source_y_fraction; int y0_fraction = 256 - source_y_fraction;
const uint8* src_ptr1 = src_ptr + src_stride; const uint8* src_ptr1 = src_ptr + src_stride;

View File

@ -0,0 +1,61 @@
/*
* Copyright 2016 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.
*/
#include "libyuv/row.h"
// This module is for GCC MSA
#if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)
#include "libyuv/macros_msa.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
void MirrorRow_MSA(const uint8* src, uint8* dst, int width) {
int x;
v16u8 src0, src1, src2, src3;
v16u8 dst0, dst1, dst2, dst3;
v16i8 shuffler = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
src += width - 64;
for (x = 0; x < width; x += 64) {
LD_UB4(src, 16, src3, src2, src1, src0);
VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2);
VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0);
ST_UB4(dst0, dst1, dst2, dst3, dst, 16);
dst += 64;
src -= 64;
}
}
void ARGBMirrorRow_MSA(const uint8* src, uint8* dst, int width) {
int x;
v16u8 src0, src1, src2, src3;
v16u8 dst0, dst1, dst2, dst3;
v16i8 shuffler = { 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 };
src += width * 4 - 64;
for (x = 0; x < width; x += 16) {
LD_UB4(src, 16, src3, src2, src1, src0);
VSHF_B2_UB(src3, src3, src2, src2, shuffler, shuffler, dst3, dst2);
VSHF_B2_UB(src1, src1, src0, src0, shuffler, shuffler, dst1, dst0);
ST_UB4(dst0, dst1, dst2, dst3, dst, 16);
dst += 64;
src -= 64;
}
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa)

View File

@ -1298,6 +1298,24 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
); );
} }
void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
"1: \n"
MEMACCESS(0)
"vld4.8 {d0, d2, d4, d6}, [%0]! \n" // load 8 ARGB pixels
"vld4.8 {d1, d3, d5, d7}, [%0]! \n" // load next 8 ARGB pixels
"subs %2, %2, #16 \n" // 16 processed per loop
MEMACCESS(1)
"vst1.8 {q3}, [%1]! \n" // store 16 A's.
"bgt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+r"(width) // %2
:
: "cc", "memory", "q0", "q1", "q2", "q3" // Clobber List
);
}
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"vmov.u8 d24, #15 \n" // B * 0.11400 coefficient "vmov.u8 d24, #15 \n" // B * 0.11400 coefficient
@ -2565,8 +2583,6 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
); );
} }
// TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable.
#ifdef HAS_ARGBMULTIPLYROW_NEON
// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. // Multiply 2 rows of ARGB pixels together, 8 pixels at a time.
void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
@ -2598,7 +2614,6 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "q0", "q1", "q2", "q3" : "cc", "memory", "q0", "q1", "q2", "q3"
); );
} }
#endif // HAS_ARGBMULTIPLYROW_NEON
// Add 2 rows of ARGB pixels together, 8 pixels at a time. // Add 2 rows of ARGB pixels together, 8 pixels at a time.
void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,

View File

@ -127,7 +127,6 @@ extern "C" {
"sqshrun " #vG ".8b, " #vG ".8h, #6 \n" /* G */ \ "sqshrun " #vG ".8b, " #vG ".8h, #6 \n" /* G */ \
"sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ \ "sqshrun " #vR ".8b, " #vR ".8h, #6 \n" /* R */ \
#ifdef HAS_I444TOARGBROW_NEON
void I444ToARGBRow_NEON(const uint8* src_y, void I444ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -157,9 +156,7 @@ void I444ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I444TOARGBROW_NEON
#ifdef HAS_I422TOARGBROW_NEON
void I422ToARGBRow_NEON(const uint8* src_y, void I422ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -189,9 +186,7 @@ void I422ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TOARGBROW_NEON
#ifdef HAS_I422ALPHATOARGBROW_NEON
void I422AlphaToARGBRow_NEON(const uint8* src_y, void I422AlphaToARGBRow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -224,9 +219,7 @@ void I422AlphaToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422ALPHATOARGBROW_NEON
#ifdef HAS_I411TOARGBROW_NEON
void I411ToARGBRow_NEON(const uint8* src_y, void I411ToARGBRow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -256,9 +249,7 @@ void I411ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I411TOARGBROW_NEON
#ifdef HAS_I422TORGBAROW_NEON
void I422ToRGBARow_NEON(const uint8* src_y, void I422ToRGBARow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -288,9 +279,7 @@ void I422ToRGBARow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TORGBAROW_NEON
#ifdef HAS_I422TORGB24ROW_NEON
void I422ToRGB24Row_NEON(const uint8* src_y, void I422ToRGB24Row_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -319,7 +308,6 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TORGB24ROW_NEON
#define ARGBTORGB565 \ #define ARGBTORGB565 \
"shll v0.8h, v22.8b, #8 \n" /* R */ \ "shll v0.8h, v22.8b, #8 \n" /* R */ \
@ -328,7 +316,6 @@ void I422ToRGB24Row_NEON(const uint8* src_y,
"sri v0.8h, v21.8h, #5 \n" /* RG */ \ "sri v0.8h, v21.8h, #5 \n" /* RG */ \
"sri v0.8h, v20.8h, #11 \n" /* RGB */ "sri v0.8h, v20.8h, #11 \n" /* RGB */
#ifdef HAS_I422TORGB565ROW_NEON
void I422ToRGB565Row_NEON(const uint8* src_y, void I422ToRGB565Row_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -358,7 +345,6 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TORGB565ROW_NEON
#define ARGBTOARGB1555 \ #define ARGBTOARGB1555 \
"shll v0.8h, v23.8b, #8 \n" /* A */ \ "shll v0.8h, v23.8b, #8 \n" /* A */ \
@ -369,7 +355,6 @@ void I422ToRGB565Row_NEON(const uint8* src_y,
"sri v0.8h, v21.8h, #6 \n" /* ARG */ \ "sri v0.8h, v21.8h, #6 \n" /* ARG */ \
"sri v0.8h, v20.8h, #11 \n" /* ARGB */ "sri v0.8h, v20.8h, #11 \n" /* ARGB */
#ifdef HAS_I422TOARGB1555ROW_NEON
void I422ToARGB1555Row_NEON(const uint8* src_y, void I422ToARGB1555Row_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -400,7 +385,6 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TOARGB1555ROW_NEON
#define ARGBTOARGB4444 \ #define ARGBTOARGB4444 \
/* Input v20.8b<=B, v21.8b<=G, v22.8b<=R, v23.8b<=A, v4.8b<=0x0f */ \ /* Input v20.8b<=B, v21.8b<=G, v22.8b<=R, v23.8b<=A, v4.8b<=0x0f */ \
@ -412,7 +396,6 @@ void I422ToARGB1555Row_NEON(const uint8* src_y,
"orr v1.8b, v22.8b, v23.8b \n" /* RA */ \ "orr v1.8b, v22.8b, v23.8b \n" /* RA */ \
"zip1 v0.16b, v0.16b, v1.16b \n" /* BGRA */ "zip1 v0.16b, v0.16b, v1.16b \n" /* BGRA */
#ifdef HAS_I422TOARGB4444ROW_NEON
void I422ToARGB4444Row_NEON(const uint8* src_y, void I422ToARGB4444Row_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -444,13 +427,10 @@ void I422ToARGB4444Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I422TOARGB4444ROW_NEON
#ifdef HAS_I400TOARGBROW_NEON
void I400ToARGBRow_NEON(const uint8* src_y, void I400ToARGBRow_NEON(const uint8* src_y,
uint8* dst_argb, uint8* dst_argb,
int width) { int width) {
int64 width64 = (int64)(width);
asm volatile ( asm volatile (
YUVTORGB_SETUP YUVTORGB_SETUP
"movi v23.8b, #255 \n" "movi v23.8b, #255 \n"
@ -463,7 +443,7 @@ void I400ToARGBRow_NEON(const uint8* src_y,
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src_y), // %0 : "+r"(src_y), // %0
"+r"(dst_argb), // %1 "+r"(dst_argb), // %1
"+r"(width64) // %2 "+r"(width) // %2
: [kUVToRB]"r"(&kYuvI601Constants.kUVToRB), : [kUVToRB]"r"(&kYuvI601Constants.kUVToRB),
[kUVToG]"r"(&kYuvI601Constants.kUVToG), [kUVToG]"r"(&kYuvI601Constants.kUVToG),
[kUVBiasBGR]"r"(&kYuvI601Constants.kUVBiasBGR), [kUVBiasBGR]"r"(&kYuvI601Constants.kUVBiasBGR),
@ -472,9 +452,7 @@ void I400ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_I400TOARGBROW_NEON
#ifdef HAS_J400TOARGBROW_NEON
void J400ToARGBRow_NEON(const uint8* src_y, void J400ToARGBRow_NEON(const uint8* src_y,
uint8* dst_argb, uint8* dst_argb,
int width) { int width) {
@ -496,9 +474,7 @@ void J400ToARGBRow_NEON(const uint8* src_y,
: "cc", "memory", "v20", "v21", "v22", "v23" : "cc", "memory", "v20", "v21", "v22", "v23"
); );
} }
#endif // HAS_J400TOARGBROW_NEON
#ifdef HAS_NV12TOARGBROW_NEON
void NV12ToARGBRow_NEON(const uint8* src_y, void NV12ToARGBRow_NEON(const uint8* src_y,
const uint8* src_uv, const uint8* src_uv,
uint8* dst_argb, uint8* dst_argb,
@ -526,9 +502,7 @@ void NV12ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_NV12TOARGBROW_NEON
#ifdef HAS_NV12TOARGBROW_NEON
void NV21ToARGBRow_NEON(const uint8* src_y, void NV21ToARGBRow_NEON(const uint8* src_y,
const uint8* src_vu, const uint8* src_vu,
uint8* dst_argb, uint8* dst_argb,
@ -556,9 +530,7 @@ void NV21ToARGBRow_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_NV12TOARGBROW_NEON
#ifdef HAS_NV12TORGB565ROW_NEON
void NV12ToRGB565Row_NEON(const uint8* src_y, void NV12ToRGB565Row_NEON(const uint8* src_y,
const uint8* src_uv, const uint8* src_uv,
uint8* dst_rgb565, uint8* dst_rgb565,
@ -586,14 +558,11 @@ void NV12ToRGB565Row_NEON(const uint8* src_y,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_NV12TORGB565ROW_NEON
#ifdef HAS_YUY2TOARGBROW_NEON
void YUY2ToARGBRow_NEON(const uint8* src_yuy2, void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
uint8* dst_argb, uint8* dst_argb,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
int64 width64 = (int64)(width);
asm volatile ( asm volatile (
YUVTORGB_SETUP YUVTORGB_SETUP
"movi v23.8b, #255 \n" "movi v23.8b, #255 \n"
@ -606,7 +575,7 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src_yuy2), // %0 : "+r"(src_yuy2), // %0
"+r"(dst_argb), // %1 "+r"(dst_argb), // %1
"+r"(width64) // %2 "+r"(width) // %2
: [kUVToRB]"r"(&yuvconstants->kUVToRB), : [kUVToRB]"r"(&yuvconstants->kUVToRB),
[kUVToG]"r"(&yuvconstants->kUVToG), [kUVToG]"r"(&yuvconstants->kUVToG),
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
@ -615,14 +584,11 @@ void YUY2ToARGBRow_NEON(const uint8* src_yuy2,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_YUY2TOARGBROW_NEON
#ifdef HAS_UYVYTOARGBROW_NEON
void UYVYToARGBRow_NEON(const uint8* src_uyvy, void UYVYToARGBRow_NEON(const uint8* src_uyvy,
uint8* dst_argb, uint8* dst_argb,
const struct YuvConstants* yuvconstants, const struct YuvConstants* yuvconstants,
int width) { int width) {
int64 width64 = (int64)(width);
asm volatile ( asm volatile (
YUVTORGB_SETUP YUVTORGB_SETUP
"movi v23.8b, #255 \n" "movi v23.8b, #255 \n"
@ -635,7 +601,7 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src_uyvy), // %0 : "+r"(src_uyvy), // %0
"+r"(dst_argb), // %1 "+r"(dst_argb), // %1
"+r"(width64) // %2 "+r"(width) // %2
: [kUVToRB]"r"(&yuvconstants->kUVToRB), : [kUVToRB]"r"(&yuvconstants->kUVToRB),
[kUVToG]"r"(&yuvconstants->kUVToG), [kUVToG]"r"(&yuvconstants->kUVToG),
[kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR), [kUVBiasBGR]"r"(&yuvconstants->kUVBiasBGR),
@ -644,10 +610,8 @@ void UYVYToARGBRow_NEON(const uint8* src_uyvy,
"v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30" "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30"
); );
} }
#endif // HAS_UYVYTOARGBROW_NEON
// Reads 16 pairs of UV and write even values to dst_u and odd to dst_v. // Reads 16 pairs of UV and write even values to dst_u and odd to dst_v.
#ifdef HAS_SPLITUVROW_NEON
void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) { int width) {
asm volatile ( asm volatile (
@ -668,10 +632,8 @@ void SplitUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1" // Clobber List : "cc", "memory", "v0", "v1" // Clobber List
); );
} }
#endif // HAS_SPLITUVROW_NEON
// Reads 16 U's and V's and writes out 16 pairs of UV. // Reads 16 U's and V's and writes out 16 pairs of UV.
#ifdef HAS_MERGEUVROW_NEON
void MergeUVRow_NEON(const uint8* src_u, const uint8* src_v, uint8* dst_uv, void MergeUVRow_NEON(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
int width) { int width) {
asm volatile ( asm volatile (
@ -693,10 +655,8 @@ void MergeUVRow_NEON(const uint8* src_u, const uint8* src_v, uint8* dst_uv,
: "cc", "memory", "v0", "v1" // Clobber List : "cc", "memory", "v0", "v1" // Clobber List
); );
} }
#endif // HAS_MERGEUVROW_NEON
// Copy multiple of 32. vld4.8 allow unaligned and is fastest on a15. // Copy multiple of 32. vld4.8 allow unaligned and is fastest on a15.
#ifdef HAS_COPYROW_NEON
void CopyRow_NEON(const uint8* src, uint8* dst, int count) { void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -713,17 +673,16 @@ void CopyRow_NEON(const uint8* src, uint8* dst, int count) {
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_COPYROW_NEON
// SetRow writes 'count' bytes using an 8 bit value repeated. // SetRow writes 'count' bytes using an 8 bit value repeated.
void SetRow_NEON(uint8* dst, uint8 v8, int count) { void SetRow_NEON(uint8* dst, uint8 v8, int count) {
asm volatile ( asm volatile (
"dup v0.16b, %w2 \n" // duplicate 16 bytes "dup v0.16b, %w2 \n" // duplicate 16 bytes
"1: \n" "1: \n"
"subs %w1, %w1, #16 \n" // 16 bytes per loop "subs %w1, %w1, #16 \n" // 16 bytes per loop
MEMACCESS(0) MEMACCESS(0)
"st1 {v0.16b}, [%0], #16 \n" // store "st1 {v0.16b}, [%0], #16 \n" // store
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(dst), // %0 : "+r"(dst), // %0
"+r"(count) // %1 "+r"(count) // %1
: "r"(v8) // %2 : "r"(v8) // %2
@ -735,10 +694,10 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) {
asm volatile ( asm volatile (
"dup v0.4s, %w2 \n" // duplicate 4 ints "dup v0.4s, %w2 \n" // duplicate 4 ints
"1: \n" "1: \n"
"subs %w1, %w1, #4 \n" // 4 ints per loop "subs %w1, %w1, #4 \n" // 4 ints per loop
MEMACCESS(0) MEMACCESS(0)
"st1 {v0.16b}, [%0], #16 \n" // store "st1 {v0.16b}, [%0], #16 \n" // store
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(dst), // %0 : "+r"(dst), // %0
"+r"(count) // %1 "+r"(count) // %1
: "r"(v32) // %2 : "r"(v32) // %2
@ -746,18 +705,15 @@ void ARGBSetRow_NEON(uint8* dst, uint32 v32, int count) {
); );
} }
#ifdef HAS_MIRRORROW_NEON
void MirrorRow_NEON(const uint8* src, uint8* dst, int width) { void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
int64 width64 = (int64) width;
asm volatile ( asm volatile (
// Start at end of source row. // Start at end of source row.
"add %0, %0, %2 \n" "add %0, %0, %w2, sxtw \n"
"sub %0, %0, #16 \n" "sub %0, %0, #16 \n"
"1: \n" "1: \n"
MEMACCESS(0) MEMACCESS(0)
"ld1 {v0.16b}, [%0], %3 \n" // src -= 16 "ld1 {v0.16b}, [%0], %3 \n" // src -= 16
"subs %2, %2, #16 \n" // 16 pixels per loop. "subs %w2, %w2, #16 \n" // 16 pixels per loop.
"rev64 v0.16b, v0.16b \n" "rev64 v0.16b, v0.16b \n"
MEMACCESS(1) MEMACCESS(1)
"st1 {v0.D}[1], [%1], #8 \n" // dst += 16 "st1 {v0.D}[1], [%1], #8 \n" // dst += 16
@ -766,26 +722,22 @@ void MirrorRow_NEON(const uint8* src, uint8* dst, int width) {
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src), // %0 : "+r"(src), // %0
"+r"(dst), // %1 "+r"(dst), // %1
"+r"(width64) // %2 "+r"(width) // %2
: "r"((ptrdiff_t)-16) // %3 : "r"((ptrdiff_t)-16) // %3
: "cc", "memory", "v0" : "cc", "memory", "v0"
); );
} }
#endif // HAS_MIRRORROW_NEON
#ifdef HAS_MIRRORUVROW_NEON
void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v, void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
int width) { int width) {
int64 width64 = (int64) width;
asm volatile ( asm volatile (
// Start at end of source row. // Start at end of source row.
"add %0, %0, %3, lsl #1 \n" "add %0, %0, %w3, sxtw #1 \n"
"sub %0, %0, #16 \n" "sub %0, %0, #16 \n"
"1: \n" "1: \n"
MEMACCESS(0) MEMACCESS(0)
"ld2 {v0.8b, v1.8b}, [%0], %4 \n" // src -= 16 "ld2 {v0.8b, v1.8b}, [%0], %4 \n" // src -= 16
"subs %3, %3, #8 \n" // 8 pixels per loop. "subs %w3, %w3, #8 \n" // 8 pixels per loop.
"rev64 v0.8b, v0.8b \n" "rev64 v0.8b, v0.8b \n"
"rev64 v1.8b, v1.8b \n" "rev64 v1.8b, v1.8b \n"
MEMACCESS(1) MEMACCESS(1)
@ -796,25 +748,21 @@ void MirrorUVRow_NEON(const uint8* src_uv, uint8* dst_u, uint8* dst_v,
: "+r"(src_uv), // %0 : "+r"(src_uv), // %0
"+r"(dst_u), // %1 "+r"(dst_u), // %1
"+r"(dst_v), // %2 "+r"(dst_v), // %2
"+r"(width64) // %3 "+r"(width) // %3
: "r"((ptrdiff_t)-16) // %4 : "r"((ptrdiff_t)-16) // %4
: "cc", "memory", "v0", "v1" : "cc", "memory", "v0", "v1"
); );
} }
#endif // HAS_MIRRORUVROW_NEON
#ifdef HAS_ARGBMIRRORROW_NEON
void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) { void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) {
int64 width64 = (int64) width;
asm volatile ( asm volatile (
// Start at end of source row. // Start at end of source row.
"add %0, %0, %2, lsl #2 \n" "add %0, %0, %w2, sxtw #2 \n"
"sub %0, %0, #16 \n" "sub %0, %0, #16 \n"
"1: \n" "1: \n"
MEMACCESS(0) MEMACCESS(0)
"ld1 {v0.16b}, [%0], %3 \n" // src -= 16 "ld1 {v0.16b}, [%0], %3 \n" // src -= 16
"subs %2, %2, #4 \n" // 4 pixels per loop. "subs %w2, %w2, #4 \n" // 4 pixels per loop.
"rev64 v0.4s, v0.4s \n" "rev64 v0.4s, v0.4s \n"
MEMACCESS(1) MEMACCESS(1)
"st1 {v0.D}[1], [%1], #8 \n" // dst += 16 "st1 {v0.D}[1], [%1], #8 \n" // dst += 16
@ -823,14 +771,12 @@ void ARGBMirrorRow_NEON(const uint8* src, uint8* dst, int width) {
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src), // %0 : "+r"(src), // %0
"+r"(dst), // %1 "+r"(dst), // %1
"+r"(width64) // %2 "+r"(width) // %2
: "r"((ptrdiff_t)-16) // %3 : "r"((ptrdiff_t)-16) // %3
: "cc", "memory", "v0" : "cc", "memory", "v0"
); );
} }
#endif // HAS_ARGBMIRRORROW_NEON
#ifdef HAS_RGB24TOARGBROW_NEON
void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) { void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #255 \n" // Alpha "movi v4.8b, #255 \n" // Alpha
@ -843,14 +789,12 @@ void RGB24ToARGBRow_NEON(const uint8* src_rgb24, uint8* dst_argb, int width) {
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src_rgb24), // %0 : "+r"(src_rgb24), // %0
"+r"(dst_argb), // %1 "+r"(dst_argb), // %1
"+r"(width) // %2 "+r"(width) // %2
: :
: "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List : "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List
); );
} }
#endif // HAS_RGB24TOARGBROW_NEON
#ifdef HAS_RAWTOARGBROW_NEON
void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) { void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) {
asm volatile ( asm volatile (
"movi v5.8b, #255 \n" // Alpha "movi v5.8b, #255 \n" // Alpha
@ -865,12 +809,11 @@ void RAWToARGBRow_NEON(const uint8* src_raw, uint8* dst_argb, int width) {
"b.gt 1b \n" "b.gt 1b \n"
: "+r"(src_raw), // %0 : "+r"(src_raw), // %0
"+r"(dst_argb), // %1 "+r"(dst_argb), // %1
"+r"(width) // %2 "+r"(width) // %2
: :
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5" // Clobber List
); );
} }
#endif // HAS_RAWTOARGBROW_NEON
void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) { void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) {
asm volatile ( asm volatile (
@ -904,7 +847,6 @@ void RAWToRGB24Row_NEON(const uint8* src_raw, uint8* dst_rgb24, int width) {
"orr v0.16b, v0.16b, v2.16b \n" /* R,B */ \ "orr v0.16b, v0.16b, v2.16b \n" /* R,B */ \
"dup v2.2D, v0.D[1] \n" /* R */ "dup v2.2D, v0.D[1] \n" /* R */
#ifdef HAS_RGB565TOARGBROW_NEON
void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) { void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
asm volatile ( asm volatile (
"movi v3.8b, #255 \n" // Alpha "movi v3.8b, #255 \n" // Alpha
@ -923,7 +865,6 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v6" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v6" // Clobber List
); );
} }
#endif // HAS_RGB565TOARGBROW_NEON
#define ARGB1555TOARGB \ #define ARGB1555TOARGB \
"ushr v2.8h, v0.8h, #10 \n" /* R xxxRRRRR */ \ "ushr v2.8h, v0.8h, #10 \n" /* R xxxRRRRR */ \
@ -962,7 +903,6 @@ void RGB565ToARGBRow_NEON(const uint8* src_rgb565, uint8* dst_argb, int width) {
"orr v2.16b, v1.16b, v3.16b \n" /* R */ \ "orr v2.16b, v1.16b, v3.16b \n" /* R */ \
"dup v1.2D, v0.D[1] \n" /* G */ \ "dup v1.2D, v0.D[1] \n" /* G */ \
#ifdef HAS_ARGB1555TOARGBROW_NEON
void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb, void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
int width) { int width) {
asm volatile ( asm volatile (
@ -982,7 +922,6 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_ARGB1555TOARGBROW_NEON
#define ARGB4444TOARGB \ #define ARGB4444TOARGB \
"shrn v1.8b, v0.8h, #8 \n" /* v1(l) AR */ \ "shrn v1.8b, v0.8h, #8 \n" /* v1(l) AR */ \
@ -996,7 +935,6 @@ void ARGB1555ToARGBRow_NEON(const uint8* src_argb1555, uint8* dst_argb,
"dup v0.2D, v2.D[1] \n" \ "dup v0.2D, v2.D[1] \n" \
"dup v1.2D, v3.D[1] \n" "dup v1.2D, v3.D[1] \n"
#ifdef HAS_ARGB4444TOARGBROW_NEON
void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb, void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb,
int width) { int width) {
asm volatile ( asm volatile (
@ -1015,9 +953,7 @@ void ARGB4444ToARGBRow_NEON(const uint8* src_argb4444, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3", "v4" // Clobber List
); );
} }
#endif // HAS_ARGB4444TOARGBROW_NEON
#ifdef HAS_ARGBTORGB24ROW_NEON
void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) { void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -1034,9 +970,7 @@ void ARGBToRGB24Row_NEON(const uint8* src_argb, uint8* dst_rgb24, int width) {
: "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List : "cc", "memory", "v1", "v2", "v3", "v4" // Clobber List
); );
} }
#endif // HAS_ARGBTORGB24ROW_NEON
#ifdef HAS_ARGBTORAWROW_NEON
void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) { void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -1055,9 +989,7 @@ void ARGBToRAWRow_NEON(const uint8* src_argb, uint8* dst_raw, int width) {
: "cc", "memory", "v1", "v2", "v3", "v4", "v5" // Clobber List : "cc", "memory", "v1", "v2", "v3", "v4", "v5" // Clobber List
); );
} }
#endif // HAS_ARGBTORAWROW_NEON
#ifdef HAS_YUY2TOYROW_NEON
void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) { void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -1074,9 +1006,7 @@ void YUY2ToYRow_NEON(const uint8* src_yuy2, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1" // Clobber List : "cc", "memory", "v0", "v1" // Clobber List
); );
} }
#endif // HAS_YUY2TOYROW_NEON
#ifdef HAS_UYVYTOYROW_NEON
void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) { void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -1093,9 +1023,7 @@ void UYVYToYRow_NEON(const uint8* src_uyvy, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1" // Clobber List : "cc", "memory", "v0", "v1" // Clobber List
); );
} }
#endif // HAS_UYVYTOYROW_NEON
#ifdef HAS_YUY2TOUV422ROW_NEON
void YUY2ToUV422Row_NEON(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, void YUY2ToUV422Row_NEON(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v,
int width) { int width) {
asm volatile ( asm volatile (
@ -1116,9 +1044,7 @@ void YUY2ToUV422Row_NEON(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_YUY2TOUV422ROW_NEON
#ifdef HAS_UYVYTOUV422ROW_NEON
void UYVYToUV422Row_NEON(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v, void UYVYToUV422Row_NEON(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v,
int width) { int width) {
asm volatile ( asm volatile (
@ -1139,9 +1065,7 @@ void UYVYToUV422Row_NEON(const uint8* src_uyvy, uint8* dst_u, uint8* dst_v,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_UYVYTOUV422ROW_NEON
#ifdef HAS_YUY2TOUVROW_NEON
void YUY2ToUVRow_NEON(const uint8* src_yuy2, int stride_yuy2, void YUY2ToUVRow_NEON(const uint8* src_yuy2, int stride_yuy2,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_yuy2b = src_yuy2 + stride_yuy2; const uint8* src_yuy2b = src_yuy2 + stride_yuy2;
@ -1169,9 +1093,7 @@ void YUY2ToUVRow_NEON(const uint8* src_yuy2, int stride_yuy2,
"v5", "v6", "v7" // Clobber List "v5", "v6", "v7" // Clobber List
); );
} }
#endif // HAS_YUY2TOUVROW_NEON
#ifdef HAS_UYVYTOUVROW_NEON
void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy, void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_uyvyb = src_uyvy + stride_uyvy; const uint8* src_uyvyb = src_uyvy + stride_uyvy;
@ -1199,10 +1121,8 @@ void UYVYToUVRow_NEON(const uint8* src_uyvy, int stride_uyvy,
"v5", "v6", "v7" // Clobber List "v5", "v6", "v7" // Clobber List
); );
} }
#endif // HAS_UYVYTOUVROW_NEON
// For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA. // For BGRAToARGB, ABGRToARGB, RGBAToARGB, and ARGBToRGBA.
#ifdef HAS_ARGBSHUFFLEROW_NEON
void ARGBShuffleRow_NEON(const uint8* src_argb, uint8* dst_argb, void ARGBShuffleRow_NEON(const uint8* src_argb, uint8* dst_argb,
const uint8* shuffler, int width) { const uint8* shuffler, int width) {
asm volatile ( asm volatile (
@ -1223,9 +1143,7 @@ void ARGBShuffleRow_NEON(const uint8* src_argb, uint8* dst_argb,
: "cc", "memory", "v0", "v1", "v2" // Clobber List : "cc", "memory", "v0", "v1", "v2" // Clobber List
); );
} }
#endif // HAS_ARGBSHUFFLEROW_NEON
#ifdef HAS_I422TOYUY2ROW_NEON
void I422ToYUY2Row_NEON(const uint8* src_y, void I422ToYUY2Row_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -1252,9 +1170,7 @@ void I422ToYUY2Row_NEON(const uint8* src_y,
: "cc", "memory", "v0", "v1", "v2", "v3" : "cc", "memory", "v0", "v1", "v2", "v3"
); );
} }
#endif // HAS_I422TOYUY2ROW_NEON
#ifdef HAS_I422TOUYVYROW_NEON
void I422ToUYVYRow_NEON(const uint8* src_y, void I422ToUYVYRow_NEON(const uint8* src_y,
const uint8* src_u, const uint8* src_u,
const uint8* src_v, const uint8* src_v,
@ -1281,9 +1197,7 @@ void I422ToUYVYRow_NEON(const uint8* src_y,
: "cc", "memory", "v0", "v1", "v2", "v3" : "cc", "memory", "v0", "v1", "v2", "v3"
); );
} }
#endif // HAS_I422TOUYVYROW_NEON
#ifdef HAS_ARGBTORGB565ROW_NEON
void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) { void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) {
asm volatile ( asm volatile (
"1: \n" "1: \n"
@ -1301,9 +1215,7 @@ void ARGBToRGB565Row_NEON(const uint8* src_argb, uint8* dst_rgb565, int width) {
: "cc", "memory", "v0", "v20", "v21", "v22", "v23" : "cc", "memory", "v0", "v20", "v21", "v22", "v23"
); );
} }
#endif // HAS_ARGBTORGB565ROW_NEON
#ifdef HAS_ARGBTORGB565DITHERROW_NEON
void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, uint8* dst_rgb, void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, uint8* dst_rgb,
const uint32 dither4, int width) { const uint32 dither4, int width) {
asm volatile ( asm volatile (
@ -1326,9 +1238,7 @@ void ARGBToRGB565DitherRow_NEON(const uint8* src_argb, uint8* dst_rgb,
: "cc", "memory", "v0", "v1", "v20", "v21", "v22", "v23" : "cc", "memory", "v0", "v1", "v20", "v21", "v22", "v23"
); );
} }
#endif // HAS_ARGBTORGB565ROW_NEON
#ifdef HAS_ARGBTOARGB1555ROW_NEON
void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_argb1555, void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_argb1555,
int width) { int width) {
asm volatile ( asm volatile (
@ -1347,9 +1257,7 @@ void ARGBToARGB1555Row_NEON(const uint8* src_argb, uint8* dst_argb1555,
: "cc", "memory", "v0", "v20", "v21", "v22", "v23" : "cc", "memory", "v0", "v20", "v21", "v22", "v23"
); );
} }
#endif // HAS_ARGBTOARGB1555ROW_NEON
#ifdef HAS_ARGBTOARGB4444ROW_NEON
void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_argb4444, void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_argb4444,
int width) { int width) {
asm volatile ( asm volatile (
@ -1369,9 +1277,7 @@ void ARGBToARGB4444Row_NEON(const uint8* src_argb, uint8* dst_argb4444,
: "cc", "memory", "v0", "v1", "v4", "v20", "v21", "v22", "v23" : "cc", "memory", "v0", "v1", "v4", "v20", "v21", "v22", "v23"
); );
} }
#endif // HAS_ARGBTOARGB4444ROW_NEON
#ifdef HAS_ARGBTOYROW_NEON
void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient "movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -1397,9 +1303,24 @@ void ARGBToYRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGBTOYROW_NEON
#ifdef HAS_ARGBTOYJROW_NEON void ARGBExtractAlphaRow_NEON(const uint8* src_argb, uint8* dst_a, int width) {
asm volatile (
"1: \n"
MEMACCESS(0)
"ld4 {v0.16b,v1.16b,v2.16b,v3.16b}, [%0], #64 \n" // load row 16 pixels
"subs %w2, %w2, #16 \n" // 16 processed per loop
MEMACCESS(1)
"st1 {v3.16b}, [%1], #16 \n" // store 16 A's.
"b.gt 1b \n"
: "+r"(src_argb), // %0
"+r"(dst_a), // %1
"+r"(width) // %2
:
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
);
}
void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) { void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #15 \n" // B * 0.11400 coefficient "movi v4.8b, #15 \n" // B * 0.11400 coefficient
@ -1423,10 +1344,8 @@ void ARGBToYJRow_NEON(const uint8* src_argb, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
); );
} }
#endif // HAS_ARGBTOYJROW_NEON
// 8x1 pixels. // 8x1 pixels.
#ifdef HAS_ARGBTOUV444ROW_NEON
void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v, void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) { int width) {
asm volatile ( asm volatile (
@ -1467,7 +1386,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"v24", "v25", "v26", "v27", "v28", "v29" "v24", "v25", "v26", "v27", "v28", "v29"
); );
} }
#endif // HAS_ARGBTOUV444ROW_NEON
#define RGBTOUV_SETUP_REG \ #define RGBTOUV_SETUP_REG \
"movi v20.8h, #56, lsl #0 \n" /* UB/VR coefficient (0.875) / 2 */ \ "movi v20.8h, #56, lsl #0 \n" /* UB/VR coefficient (0.875) / 2 */ \
@ -1478,7 +1396,6 @@ void ARGBToUV444Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"movi v25.16b, #0x80 \n" /* 128.5 (0x8080 in 16-bit) */ "movi v25.16b, #0x80 \n" /* 128.5 (0x8080 in 16-bit) */
// 32x1 pixels -> 8x1. width is number of argb pixels. e.g. 32. // 32x1 pixels -> 8x1. width is number of argb pixels. e.g. 32.
#ifdef HAS_ARGBTOUV411ROW_NEON
void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v, void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
int width) { int width) {
asm volatile ( asm volatile (
@ -1528,7 +1445,6 @@ void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_ARGBTOUV411ROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#define RGBTOUV(QB, QG, QR) \ #define RGBTOUV(QB, QG, QR) \
@ -1546,7 +1462,6 @@ void ARGBToUV411Row_NEON(const uint8* src_argb, uint8* dst_u, uint8* dst_v,
// TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr. // TODO(fbarchard): Consider vhadd vertical, then vpaddl horizontal, avoid shr.
// TODO(fbarchard): consider ptrdiff_t for all strides. // TODO(fbarchard): consider ptrdiff_t for all strides.
#ifdef HAS_ARGBTOUVROW_NEON
void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb, void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb_1 = src_argb + src_stride_argb; const uint8* src_argb_1 = src_argb + src_stride_argb;
@ -1586,10 +1501,8 @@ void ARGBToUVRow_NEON(const uint8* src_argb, int src_stride_argb,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_ARGBTOUVROW_NEON
// TODO(fbarchard): Subsample match C code. // TODO(fbarchard): Subsample match C code.
#ifdef HAS_ARGBTOUVJROW_NEON
void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb, void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb_1 = src_argb + src_stride_argb; const uint8* src_argb_1 = src_argb + src_stride_argb;
@ -1633,9 +1546,7 @@ void ARGBToUVJRow_NEON(const uint8* src_argb, int src_stride_argb,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_ARGBTOUVJROW_NEON
#ifdef HAS_BGRATOUVROW_NEON
void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra, void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_bgra_1 = src_bgra + src_stride_bgra; const uint8* src_bgra_1 = src_bgra + src_stride_bgra;
@ -1674,9 +1585,7 @@ void BGRAToUVRow_NEON(const uint8* src_bgra, int src_stride_bgra,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_BGRATOUVROW_NEON
#ifdef HAS_ABGRTOUVROW_NEON
void ABGRToUVRow_NEON(const uint8* src_abgr, int src_stride_abgr, void ABGRToUVRow_NEON(const uint8* src_abgr, int src_stride_abgr,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_abgr_1 = src_abgr + src_stride_abgr; const uint8* src_abgr_1 = src_abgr + src_stride_abgr;
@ -1715,9 +1624,7 @@ void ABGRToUVRow_NEON(const uint8* src_abgr, int src_stride_abgr,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_ABGRTOUVROW_NEON
#ifdef HAS_RGBATOUVROW_NEON
void RGBAToUVRow_NEON(const uint8* src_rgba, int src_stride_rgba, void RGBAToUVRow_NEON(const uint8* src_rgba, int src_stride_rgba,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgba_1 = src_rgba + src_stride_rgba; const uint8* src_rgba_1 = src_rgba + src_stride_rgba;
@ -1756,9 +1663,7 @@ void RGBAToUVRow_NEON(const uint8* src_rgba, int src_stride_rgba,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_RGBATOUVROW_NEON
#ifdef HAS_RGB24TOUVROW_NEON
void RGB24ToUVRow_NEON(const uint8* src_rgb24, int src_stride_rgb24, void RGB24ToUVRow_NEON(const uint8* src_rgb24, int src_stride_rgb24,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgb24_1 = src_rgb24 + src_stride_rgb24; const uint8* src_rgb24_1 = src_rgb24 + src_stride_rgb24;
@ -1797,9 +1702,7 @@ void RGB24ToUVRow_NEON(const uint8* src_rgb24, int src_stride_rgb24,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_RGB24TOUVROW_NEON
#ifdef HAS_RAWTOUVROW_NEON
void RAWToUVRow_NEON(const uint8* src_raw, int src_stride_raw, void RAWToUVRow_NEON(const uint8* src_raw, int src_stride_raw,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_raw_1 = src_raw + src_stride_raw; const uint8* src_raw_1 = src_raw + src_stride_raw;
@ -1838,10 +1741,8 @@ void RAWToUVRow_NEON(const uint8* src_raw, int src_stride_raw,
"v20", "v21", "v22", "v23", "v24", "v25" "v20", "v21", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_RAWTOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_RGB565TOUVROW_NEON
void RGB565ToUVRow_NEON(const uint8* src_rgb565, int src_stride_rgb565, void RGB565ToUVRow_NEON(const uint8* src_rgb565, int src_stride_rgb565,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_rgb565_1 = src_rgb565 + src_stride_rgb565; const uint8* src_rgb565_1 = src_rgb565 + src_stride_rgb565;
@ -1914,10 +1815,8 @@ void RGB565ToUVRow_NEON(const uint8* src_rgb565, int src_stride_rgb565,
"v25", "v26", "v27" "v25", "v26", "v27"
); );
} }
#endif // HAS_RGB565TOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_ARGB1555TOUVROW_NEON
void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, int src_stride_argb1555, void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, int src_stride_argb1555,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb1555_1 = src_argb1555 + src_stride_argb1555; const uint8* src_argb1555_1 = src_argb1555 + src_stride_argb1555;
@ -1985,10 +1884,8 @@ void ARGB1555ToUVRow_NEON(const uint8* src_argb1555, int src_stride_argb1555,
"v26", "v27", "v28" "v26", "v27", "v28"
); );
} }
#endif // HAS_ARGB1555TOUVROW_NEON
// 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16. // 16x2 pixels -> 8x1. width is number of argb pixels. e.g. 16.
#ifdef HAS_ARGB4444TOUVROW_NEON
void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, int src_stride_argb4444, void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, int src_stride_argb4444,
uint8* dst_u, uint8* dst_v, int width) { uint8* dst_u, uint8* dst_v, int width) {
const uint8* src_argb4444_1 = src_argb4444 + src_stride_argb4444; const uint8* src_argb4444_1 = src_argb4444 + src_stride_argb4444;
@ -2057,9 +1954,7 @@ void ARGB4444ToUVRow_NEON(const uint8* src_argb4444, int src_stride_argb4444,
); );
} }
#endif // HAS_ARGB4444TOUVROW_NEON
#ifdef HAS_RGB565TOYROW_NEON
void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) { void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v24.8b, #13 \n" // B * 0.1016 coefficient "movi v24.8b, #13 \n" // B * 0.1016 coefficient
@ -2087,9 +1982,7 @@ void RGB565ToYRow_NEON(const uint8* src_rgb565, uint8* dst_y, int width) {
"v24", "v25", "v26", "v27" "v24", "v25", "v26", "v27"
); );
} }
#endif // HAS_RGB565TOYROW_NEON
#ifdef HAS_ARGB1555TOYROW_NEON
void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) { void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient "movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2116,9 +2009,7 @@ void ARGB1555ToYRow_NEON(const uint8* src_argb1555, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGB1555TOYROW_NEON
#ifdef HAS_ARGB4444TOYROW_NEON
void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) { void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v24.8b, #13 \n" // B * 0.1016 coefficient "movi v24.8b, #13 \n" // B * 0.1016 coefficient
@ -2145,9 +2036,7 @@ void ARGB4444ToYRow_NEON(const uint8* src_argb4444, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v24", "v25", "v26", "v27" : "cc", "memory", "v0", "v1", "v2", "v3", "v24", "v25", "v26", "v27"
); );
} }
#endif // HAS_ARGB4444TOYROW_NEON
#ifdef HAS_BGRATOYROW_NEON
void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) { void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient "movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2173,9 +2062,7 @@ void BGRAToYRow_NEON(const uint8* src_bgra, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
); );
} }
#endif // HAS_BGRATOYROW_NEON
#ifdef HAS_ABGRTOYROW_NEON
void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) { void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient "movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2201,9 +2088,7 @@ void ABGRToYRow_NEON(const uint8* src_abgr, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
); );
} }
#endif // HAS_ABGRTOYROW_NEON
#ifdef HAS_RGBATOYROW_NEON
void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) { void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient "movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2229,9 +2114,7 @@ void RGBAToYRow_NEON(const uint8* src_rgba, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
); );
} }
#endif // HAS_RGBATOYROW_NEON
#ifdef HAS_RGB24TOYROW_NEON
void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) { void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #13 \n" // B * 0.1016 coefficient "movi v4.8b, #13 \n" // B * 0.1016 coefficient
@ -2257,9 +2140,7 @@ void RGB24ToYRow_NEON(const uint8* src_rgb24, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
); );
} }
#endif // HAS_RGB24TOYROW_NEON
#ifdef HAS_RAWTOYROW_NEON
void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) { void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) {
asm volatile ( asm volatile (
"movi v4.8b, #33 \n" // R * 0.2578 coefficient "movi v4.8b, #33 \n" // R * 0.2578 coefficient
@ -2285,10 +2166,8 @@ void RAWToYRow_NEON(const uint8* src_raw, uint8* dst_y, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v16"
); );
} }
#endif // HAS_RAWTOYROW_NEON
// Bilinear filter 16x2 -> 16x1 // Bilinear filter 16x2 -> 16x1
#ifdef HAS_INTERPOLATEROW_NEON
void InterpolateRow_NEON(uint8* dst_ptr, void InterpolateRow_NEON(uint8* dst_ptr,
const uint8* src_ptr, ptrdiff_t src_stride, const uint8* src_ptr, ptrdiff_t src_stride,
int dst_width, int source_y_fraction) { int dst_width, int source_y_fraction) {
@ -2354,10 +2233,8 @@ void InterpolateRow_NEON(uint8* dst_ptr,
: "cc", "memory", "v0", "v1", "v3", "v4", "v5" : "cc", "memory", "v0", "v1", "v3", "v4", "v5"
); );
} }
#endif // HAS_INTERPOLATEROW_NEON
// dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr // dr * (256 - sa) / 256 + sr = dr - dr * sa / 256 + sr
#ifdef HAS_ARGBBLENDROW_NEON
void ARGBBlendRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBBlendRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2426,10 +2303,8 @@ void ARGBBlendRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
"v16", "v17", "v18" "v16", "v17", "v18"
); );
} }
#endif // HAS_ARGBBLENDROW_NEON
// Attenuate 8 pixels at a time. // Attenuate 8 pixels at a time.
#ifdef HAS_ARGBATTENUATEROW_NEON
void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
asm volatile ( asm volatile (
// Attenuate 8 pixels. // Attenuate 8 pixels.
@ -2453,11 +2328,9 @@ void ARGBAttenuateRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
); );
} }
#endif // HAS_ARGBATTENUATEROW_NEON
// Quantize 8 ARGB pixels (32 bytes). // Quantize 8 ARGB pixels (32 bytes).
// dst = (dst * scale >> 16) * interval_size + interval_offset; // dst = (dst * scale >> 16) * interval_size + interval_offset;
#ifdef HAS_ARGBQUANTIZEROW_NEON
void ARGBQuantizeRow_NEON(uint8* dst_argb, int scale, int interval_size, void ARGBQuantizeRow_NEON(uint8* dst_argb, int scale, int interval_size,
int interval_offset, int width) { int interval_offset, int width) {
asm volatile ( asm volatile (
@ -2497,12 +2370,10 @@ void ARGBQuantizeRow_NEON(uint8* dst_argb, int scale, int interval_size,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6"
); );
} }
#endif // HAS_ARGBQUANTIZEROW_NEON
// Shade 8 pixels at a time by specified value. // Shade 8 pixels at a time by specified value.
// NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8. // NOTE vqrdmulh.s16 q10, q10, d0[0] must use a scaler register from 0 to 8.
// Rounding in vqrdmulh does +1 to high if high bit of low s16 is set. // Rounding in vqrdmulh does +1 to high if high bit of low s16 is set.
#ifdef HAS_ARGBSHADEROW_NEON
void ARGBShadeRow_NEON(const uint8* src_argb, uint8* dst_argb, int width, void ARGBShadeRow_NEON(const uint8* src_argb, uint8* dst_argb, int width,
uint32 value) { uint32 value) {
asm volatile ( asm volatile (
@ -2537,12 +2408,10 @@ void ARGBShadeRow_NEON(const uint8* src_argb, uint8* dst_argb, int width,
: "cc", "memory", "v0", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGBSHADEROW_NEON
// Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels // Convert 8 ARGB pixels (64 bytes) to 8 Gray ARGB pixels
// Similar to ARGBToYJ but stores ARGB. // Similar to ARGBToYJ but stores ARGB.
// C code is (15 * b + 75 * g + 38 * r + 64) >> 7; // C code is (15 * b + 75 * g + 38 * r + 64) >> 7;
#ifdef HAS_ARGBGRAYROW_NEON
void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) { void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
asm volatile ( asm volatile (
"movi v24.8b, #15 \n" // B * 0.11400 coefficient "movi v24.8b, #15 \n" // B * 0.11400 coefficient
@ -2568,14 +2437,12 @@ void ARGBGrayRow_NEON(const uint8* src_argb, uint8* dst_argb, int width) {
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v24", "v25", "v26" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v24", "v25", "v26"
); );
} }
#endif // HAS_ARGBGRAYROW_NEON
// Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels. // Convert 8 ARGB pixels (32 bytes) to 8 Sepia ARGB pixels.
// b = (r * 35 + g * 68 + b * 17) >> 7 // b = (r * 35 + g * 68 + b * 17) >> 7
// g = (r * 45 + g * 88 + b * 22) >> 7 // g = (r * 45 + g * 88 + b * 22) >> 7
// r = (r * 50 + g * 98 + b * 24) >> 7 // r = (r * 50 + g * 98 + b * 24) >> 7
#ifdef HAS_ARGBSEPIAROW_NEON
void ARGBSepiaRow_NEON(uint8* dst_argb, int width) { void ARGBSepiaRow_NEON(uint8* dst_argb, int width) {
asm volatile ( asm volatile (
"movi v20.8b, #17 \n" // BB coefficient "movi v20.8b, #17 \n" // BB coefficient
@ -2613,12 +2480,10 @@ void ARGBSepiaRow_NEON(uint8* dst_argb, int width) {
"v20", "v21", "v22", "v24", "v25", "v26", "v28", "v29", "v30" "v20", "v21", "v22", "v24", "v25", "v26", "v28", "v29", "v30"
); );
} }
#endif // HAS_ARGBSEPIAROW_NEON
// Tranform 8 ARGB pixels (32 bytes) with color matrix. // Tranform 8 ARGB pixels (32 bytes) with color matrix.
// TODO(fbarchard): Was same as Sepia except matrix is provided. This function // TODO(fbarchard): Was same as Sepia except matrix is provided. This function
// needs to saturate. Consider doing a non-saturating version. // needs to saturate. Consider doing a non-saturating version.
#ifdef HAS_ARGBCOLORMATRIXROW_NEON
void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb, void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
const int8* matrix_argb, int width) { const int8* matrix_argb, int width) {
asm volatile ( asm volatile (
@ -2678,11 +2543,9 @@ void ARGBColorMatrixRow_NEON(const uint8* src_argb, uint8* dst_argb,
"v18", "v19", "v22", "v23", "v24", "v25" "v18", "v19", "v22", "v23", "v24", "v25"
); );
} }
#endif // HAS_ARGBCOLORMATRIXROW_NEON
// TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable. // TODO(fbarchard): fix vqshrun in ARGBMultiplyRow_NEON and reenable.
// Multiply 2 rows of ARGB pixels together, 8 pixels at a time. // Multiply 2 rows of ARGB pixels together, 8 pixels at a time.
#ifdef HAS_ARGBMULTIPLYROW_NEON
void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2713,10 +2576,8 @@ void ARGBMultiplyRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGBMULTIPLYROW_NEON
// Add 2 rows of ARGB pixels together, 8 pixels at a time. // Add 2 rows of ARGB pixels together, 8 pixels at a time.
#ifdef HAS_ARGBADDROW_NEON
void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2743,10 +2604,8 @@ void ARGBAddRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGBADDROW_NEON
// Subtract 2 rows of ARGB pixels, 8 pixels at a time. // Subtract 2 rows of ARGB pixels, 8 pixels at a time.
#ifdef HAS_ARGBSUBTRACTROW_NEON
void ARGBSubtractRow_NEON(const uint8* src_argb0, const uint8* src_argb1, void ARGBSubtractRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2773,14 +2632,12 @@ void ARGBSubtractRow_NEON(const uint8* src_argb0, const uint8* src_argb1,
: "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7" : "cc", "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7"
); );
} }
#endif // HAS_ARGBSUBTRACTROW_NEON
// Adds Sobel X and Sobel Y and stores Sobel into ARGB. // Adds Sobel X and Sobel Y and stores Sobel into ARGB.
// A = 255 // A = 255
// R = Sobel // R = Sobel
// G = Sobel // G = Sobel
// B = Sobel // B = Sobel
#ifdef HAS_SOBELROW_NEON
void SobelRow_NEON(const uint8* src_sobelx, const uint8* src_sobely, void SobelRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2806,10 +2663,8 @@ void SobelRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1", "v2", "v3" : "cc", "memory", "v0", "v1", "v2", "v3"
); );
} }
#endif // HAS_SOBELROW_NEON
// Adds Sobel X and Sobel Y and stores Sobel into plane. // Adds Sobel X and Sobel Y and stores Sobel into plane.
#ifdef HAS_SOBELTOPLANEROW_NEON
void SobelToPlaneRow_NEON(const uint8* src_sobelx, const uint8* src_sobely, void SobelToPlaneRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_y, int width) { uint8* dst_y, int width) {
asm volatile ( asm volatile (
@ -2832,14 +2687,12 @@ void SobelToPlaneRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1" : "cc", "memory", "v0", "v1"
); );
} }
#endif // HAS_SOBELTOPLANEROW_NEON
// Mixes Sobel X, Sobel Y and Sobel into ARGB. // Mixes Sobel X, Sobel Y and Sobel into ARGB.
// A = 255 // A = 255
// R = Sobel X // R = Sobel X
// G = Sobel // G = Sobel
// B = Sobel Y // B = Sobel Y
#ifdef HAS_SOBELXYROW_NEON
void SobelXYRow_NEON(const uint8* src_sobelx, const uint8* src_sobely, void SobelXYRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) { uint8* dst_argb, int width) {
asm volatile ( asm volatile (
@ -2863,13 +2716,11 @@ void SobelXYRow_NEON(const uint8* src_sobelx, const uint8* src_sobely,
: "cc", "memory", "v0", "v1", "v2", "v3" : "cc", "memory", "v0", "v1", "v2", "v3"
); );
} }
#endif // HAS_SOBELXYROW_NEON
// SobelX as a matrix is // SobelX as a matrix is
// -1 0 1 // -1 0 1
// -2 0 2 // -2 0 2
// -1 0 1 // -1 0 1
#ifdef HAS_SOBELXROW_NEON
void SobelXRow_NEON(const uint8* src_y0, const uint8* src_y1, void SobelXRow_NEON(const uint8* src_y0, const uint8* src_y1,
const uint8* src_y2, uint8* dst_sobelx, int width) { const uint8* src_y2, uint8* dst_sobelx, int width) {
asm volatile ( asm volatile (
@ -2908,13 +2759,11 @@ void SobelXRow_NEON(const uint8* src_y0, const uint8* src_y1,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_SOBELXROW_NEON
// SobelY as a matrix is // SobelY as a matrix is
// -1 -2 -1 // -1 -2 -1
// 0 0 0 // 0 0 0
// 1 2 1 // 1 2 1
#ifdef HAS_SOBELYROW_NEON
void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1, void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1,
uint8* dst_sobely, int width) { uint8* dst_sobely, int width) {
asm volatile ( asm volatile (
@ -2952,7 +2801,6 @@ void SobelYRow_NEON(const uint8* src_y0, const uint8* src_y1,
: "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List : "cc", "memory", "v0", "v1", "v2", "v3" // Clobber List
); );
} }
#endif // HAS_SOBELYROW_NEON
#endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__) #endif // !defined(LIBYUV_DISABLE_NEON) && defined(__aarch64__)
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -10,8 +10,11 @@
#include "libyuv/row.h" #include "libyuv/row.h"
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_X64) && \ // This module is for Visual C 32/64 bit and clangcl 32 bit
defined(_MSC_VER) && !defined(__clang__) #if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && \
(defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__)))
#if defined(_M_X64)
#include <emmintrin.h> #include <emmintrin.h>
#include <tmmintrin.h> // For _mm_maddubs_epi16 #include <tmmintrin.h> // For _mm_maddubs_epi16
#endif #endif
@ -21,10 +24,6 @@ namespace libyuv {
extern "C" { extern "C" {
#endif #endif
// This module is for Visual C 32/64 bit and clangcl 32 bit
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(_M_IX86) || (defined(_M_X64) && !defined(__clang__)))
// 64 bit // 64 bit
#if defined(_M_X64) #if defined(_M_X64)
@ -3532,6 +3531,33 @@ void ARGBCopyAlphaRow_AVX2(const uint8* src, uint8* dst, int width) {
} }
#endif // HAS_ARGBCOPYALPHAROW_AVX2 #endif // HAS_ARGBCOPYALPHAROW_AVX2
#ifdef HAS_ARGBEXTRACTALPHAROW_SSE2
// width in pixels
__declspec(naked)
void ARGBExtractAlphaRow_SSE2(const uint8* src_argb, uint8* dst_a, int width) {
__asm {
mov eax, [esp + 4] // src_argb
mov edx, [esp + 8] // dst_a
mov ecx, [esp + 12] // width
extractloop:
movdqu xmm0, [eax]
movdqu xmm1, [eax + 16]
lea eax, [eax + 32]
psrld xmm0, 24
psrld xmm1, 24
packssdw xmm0, xmm1
packuswb xmm0, xmm0
movq qword ptr [edx], xmm0
lea edx, [edx + 8]
sub ecx, 8
jg extractloop
ret
}
}
#endif // HAS_ARGBEXTRACTALPHAROW_SSE2
#ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2 #ifdef HAS_ARGBCOPYYTOALPHAROW_SSE2
// width in pixels // width in pixels
__declspec(naked) __declspec(naked)
@ -5248,6 +5274,7 @@ void SobelXYRow_SSE2(const uint8* src_sobelx, const uint8* src_sobely,
// dst points to pixel to store result to. // dst points to pixel to store result to.
// count is number of averaged pixels to produce. // count is number of averaged pixels to produce.
// Does 4 pixels at a time. // Does 4 pixels at a time.
// This function requires alignment on accumulation buffer pointers.
void CumulativeSumToAverageRow_SSE2(const int32* topleft, const int32* botleft, void CumulativeSumToAverageRow_SSE2(const int32* topleft, const int32* botleft,
int width, int area, uint8* dst, int width, int area, uint8* dst,
int count) { int count) {
@ -6233,9 +6260,10 @@ void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb, uint8* dst_argb,
#endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3 #endif // HAS_ARGBLUMACOLORTABLEROW_SSSE3
#endif // defined(_M_X64) #endif // defined(_M_X64)
#endif // !defined(LIBYUV_DISABLE_X86) && (defined(_M_IX86) || defined(_M_X64))
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
} // namespace libyuv } // namespace libyuv
#endif #endif
#endif // !defined(LIBYUV_DISABLE_X86) && (defined(_M_IX86) || defined(_M_X64))

View File

@ -1411,8 +1411,7 @@ void ScalePlane(const uint8* src, int src_stride,
} }
if (dst_width <= Abs(src_width) && dst_height <= src_height) { if (dst_width <= Abs(src_width) && dst_height <= src_height) {
// Scale down. // Scale down.
if (4 * dst_width == 3 * src_width && if (4 * dst_width == 3 * src_width && 4 * dst_height == 3 * src_height) {
4 * dst_height == 3 * src_height) {
// optimized, 3/4 // optimized, 3/4
ScalePlaneDown34(src_width, src_height, dst_width, dst_height, ScalePlaneDown34(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering); src_stride, dst_stride, src, dst, filtering);
@ -1425,8 +1424,7 @@ void ScalePlane(const uint8* src, int src_stride,
return; return;
} }
// 3/8 rounded up for odd sized chroma height. // 3/8 rounded up for odd sized chroma height.
if (8 * dst_width == 3 * src_width && if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) {
dst_height == ((src_height * 3 + 7) / 8)) {
// optimized, 3/8 // optimized, 3/8
ScalePlaneDown38(src_width, src_height, dst_width, dst_height, ScalePlaneDown38(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering); src_stride, dst_stride, src, dst, filtering);
@ -1508,8 +1506,7 @@ void ScalePlane_16(const uint16* src, int src_stride,
return; return;
} }
// 3/8 rounded up for odd sized chroma height. // 3/8 rounded up for odd sized chroma height.
if (8 * dst_width == 3 * src_width && if (8 * dst_width == 3 * src_width && 8 * dst_height == 3 * src_height) {
dst_height == ((src_height * 3 + 7) / 8)) {
// optimized, 3/8 // optimized, 3/8
ScalePlaneDown38_16(src_width, src_height, dst_width, dst_height, ScalePlaneDown38_16(src_width, src_height, dst_width, dst_height,
src_stride, dst_stride, src, dst, filtering); src_stride, dst_stride, src, dst, filtering);

View File

@ -417,8 +417,14 @@ void ScaleColsUp2_16_C(uint16* dst_ptr, const uint16* src_ptr,
} }
// (1-f)a + fb can be replaced with a + f(b-a) // (1-f)a + fb can be replaced with a + f(b-a)
#if defined(__arm__) || defined(__aarch64__)
#define BLENDER(a, b, f) (uint8)((int)(a) + \ #define BLENDER(a, b, f) (uint8)((int)(a) + \
((int)(f) * ((int)(b) - (int)(a)) >> 16)) ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
#else
// Intel uses 7 bit math with rounding.
#define BLENDER(a, b, f) (uint8)((int)(a) + \
(((int)((f) >> 9) * ((int)(b) - (int)(a)) + 0x40) >> 7))
#endif
void ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr, void ScaleFilterCols_C(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) { int dst_width, int x, int dx) {
@ -470,8 +476,9 @@ void ScaleFilterCols64_C(uint8* dst_ptr, const uint8* src_ptr,
} }
#undef BLENDER #undef BLENDER
// Same as 8 bit arm blender but return is cast to uint16
#define BLENDER(a, b, f) (uint16)((int)(a) + \ #define BLENDER(a, b, f) (uint16)((int)(a) + \
((int)(f) * ((int)(b) - (int)(a)) >> 16)) ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr, void ScaleFilterCols_16_C(uint16* dst_ptr, const uint16* src_ptr,
int dst_width, int x, int dx) { int dst_width, int x, int dx) {
@ -809,6 +816,7 @@ void ScaleARGBColsUp2_C(uint8* dst_argb, const uint8* src_argb,
} }
} }
// TODO(fbarchard): Replace 0x7f ^ f with 128-f. bug=607.
// Mimics SSSE3 blender // Mimics SSSE3 blender
#define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7 #define BLENDER1(a, b, f) ((a) * (0x7f ^ f) + (b) * f) >> 7
#define BLENDERC(a, b, f, s) (uint32)( \ #define BLENDERC(a, b, f, s) (uint32)( \

View File

@ -821,6 +821,16 @@ void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
} }
#endif // HAS_SCALEADDROW_AVX2 #endif // HAS_SCALEADDROW_AVX2
// Constant for making pixels signed to avoid pmaddubsw
// saturation.
static uvec8 kFsub80 =
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
// Constant for making pixels unsigned and adding .5 for rounding.
static uvec16 kFadd40 =
{ 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040 };
// Bilinear column filtering. SSSE3 version. // Bilinear column filtering. SSSE3 version.
void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr, void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) { int dst_width, int x, int dx) {
@ -831,7 +841,10 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movl $0x04040000,%k2 \n" "movl $0x04040000,%k2 \n"
"movd %k2,%%xmm5 \n" "movd %k2,%%xmm5 \n"
"pcmpeqb %%xmm6,%%xmm6 \n" "pcmpeqb %%xmm6,%%xmm6 \n"
"psrlw $0x9,%%xmm6 \n" "psrlw $0x9,%%xmm6 \n" // 0x007f007f
"pcmpeqb %%xmm7,%%xmm7 \n"
"psrlw $15,%%xmm7 \n" // 0x00010001
"pextrw $0x1,%%xmm2,%k3 \n" "pextrw $0x1,%%xmm2,%k3 \n"
"subl $0x2,%5 \n" "subl $0x2,%5 \n"
"jl 29f \n" "jl 29f \n"
@ -853,16 +866,19 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movd %k2,%%xmm4 \n" "movd %k2,%%xmm4 \n"
"pshufb %%xmm5,%%xmm1 \n" "pshufb %%xmm5,%%xmm1 \n"
"punpcklwd %%xmm4,%%xmm0 \n" "punpcklwd %%xmm4,%%xmm0 \n"
"pxor %%xmm6,%%xmm1 \n" "psubb %8,%%xmm0 \n" // make pixels signed.
"pmaddubsw %%xmm1,%%xmm0 \n" "pxor %%xmm6,%%xmm1 \n" // 128 - f = (f ^ 127 ) + 1
"paddusb %%xmm7,%%xmm1 \n"
"pmaddubsw %%xmm0,%%xmm1 \n"
"pextrw $0x1,%%xmm2,%k3 \n" "pextrw $0x1,%%xmm2,%k3 \n"
"pextrw $0x3,%%xmm2,%k4 \n" "pextrw $0x3,%%xmm2,%k4 \n"
"psrlw $0x7,%%xmm0 \n" "paddw %9,%%xmm1 \n" // make pixels unsigned.
"packuswb %%xmm0,%%xmm0 \n" "psrlw $0x7,%%xmm1 \n"
"movd %%xmm0,%k2 \n" "packuswb %%xmm1,%%xmm1 \n"
"movd %%xmm1,%k2 \n"
"mov %w2," MEMACCESS(0) " \n" "mov %w2," MEMACCESS(0) " \n"
"lea " MEMLEA(0x2,0) ",%0 \n" "lea " MEMLEA(0x2,0) ",%0 \n"
"sub $0x2,%5 \n" "subl $0x2,%5 \n"
"jge 2b \n" "jge 2b \n"
LABELALIGN LABELALIGN
@ -873,11 +889,14 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"movd %k2,%%xmm0 \n" "movd %k2,%%xmm0 \n"
"psrlw $0x9,%%xmm2 \n" "psrlw $0x9,%%xmm2 \n"
"pshufb %%xmm5,%%xmm2 \n" "pshufb %%xmm5,%%xmm2 \n"
"psubb %8,%%xmm0 \n" // make pixels signed.
"pxor %%xmm6,%%xmm2 \n" "pxor %%xmm6,%%xmm2 \n"
"pmaddubsw %%xmm2,%%xmm0 \n" "paddusb %%xmm7,%%xmm2 \n"
"psrlw $0x7,%%xmm0 \n" "pmaddubsw %%xmm0,%%xmm2 \n"
"packuswb %%xmm0,%%xmm0 \n" "paddw %9,%%xmm2 \n" // make pixels unsigned.
"movd %%xmm0,%k2 \n" "psrlw $0x7,%%xmm2 \n"
"packuswb %%xmm2,%%xmm2 \n"
"movd %%xmm2,%k2 \n"
"mov %b2," MEMACCESS(0) " \n" "mov %b2," MEMACCESS(0) " \n"
"99: \n" "99: \n"
: "+r"(dst_ptr), // %0 : "+r"(dst_ptr), // %0
@ -885,11 +904,22 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
"=&a"(temp_pixel), // %2 "=&a"(temp_pixel), // %2
"=&r"(x0), // %3 "=&r"(x0), // %3
"=&r"(x1), // %4 "=&r"(x1), // %4
#if defined(__x86_64__)
"+rm"(dst_width) // %5 "+rm"(dst_width) // %5
#else
"+m"(dst_width) // %5
#endif
: "rm"(x), // %6 : "rm"(x), // %6
"rm"(dx) // %7 "rm"(dx), // %7
#if defined(__x86_64__)
"x"(kFsub80), // %8
"x"(kFadd40) // %9
#else
"m"(kFsub80), // %8
"m"(kFadd40) // %9
#endif
: "memory", "cc", NACL_R14 : "memory", "cc", NACL_R14
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6" "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
); );
} }

View File

@ -572,6 +572,10 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
MEMACCESS(6) \ MEMACCESS(6) \
"vld2.8 {d6["#n"], d7["#n"]}, [%6] \n" "vld2.8 {d6["#n"], d7["#n"]}, [%6] \n"
// The NEON version mimics this formula (from row_common.cc):
// #define BLENDER(a, b, f) (uint8)((int)(a) +
// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr, void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) { int dst_width, int x, int dx) {
int dx_offset[4] = {0, 1, 2, 3}; int dx_offset[4] = {0, 1, 2, 3};
@ -608,8 +612,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
"vmovl.u16 q10, d21 \n" "vmovl.u16 q10, d21 \n"
"vmul.s32 q11, q11, q13 \n" "vmul.s32 q11, q11, q13 \n"
"vmul.s32 q12, q12, q10 \n" "vmul.s32 q12, q12, q10 \n"
"vshrn.s32 d18, q11, #16 \n" "vrshrn.s32 d18, q11, #16 \n"
"vshrn.s32 d19, q12, #16 \n" "vrshrn.s32 d19, q12, #16 \n"
"vadd.s16 q8, q8, q9 \n" "vadd.s16 q8, q8, q9 \n"
"vmovn.s16 d6, q8 \n" "vmovn.s16 d6, q8 \n"

View File

@ -587,6 +587,10 @@ void ScaleAddRows_NEON(const uint8* src_ptr, ptrdiff_t src_stride,
MEMACCESS(6) \ MEMACCESS(6) \
"ld2 {v4.b, v5.b}["#n"], [%6] \n" "ld2 {v4.b, v5.b}["#n"], [%6] \n"
// The NEON version mimics this formula (from row_common.cc):
// #define BLENDER(a, b, f) (uint8)((int)(a) +
// ((((int)((f)) * ((int)(b) - (int)(a))) + 0x8000) >> 16))
void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr, void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
int dst_width, int x, int dx) { int dst_width, int x, int dx) {
int dx_offset[4] = {0, 1, 2, 3}; int dx_offset[4] = {0, 1, 2, 3};
@ -626,8 +630,8 @@ void ScaleFilterCols_NEON(uint8* dst_ptr, const uint8* src_ptr,
"ushll2 v6.4s, v6.8h, #0 \n" "ushll2 v6.4s, v6.8h, #0 \n"
"mul v16.4s, v16.4s, v7.4s \n" "mul v16.4s, v16.4s, v7.4s \n"
"mul v17.4s, v17.4s, v6.4s \n" "mul v17.4s, v17.4s, v6.4s \n"
"shrn v6.4h, v16.4s, #16 \n" "rshrn v6.4h, v16.4s, #16 \n"
"shrn2 v6.8h, v17.4s, #16 \n" "rshrn2 v6.8h, v17.4s, #16 \n"
"add v4.8h, v4.8h, v6.8h \n" "add v4.8h, v4.8h, v6.8h \n"
"xtn v4.8b, v4.8h \n" "xtn v4.8b, v4.8h \n"

View File

@ -860,6 +860,16 @@ void ScaleAddRow_AVX2(const uint8* src_ptr, uint16* dst_ptr, int src_width) {
} }
#endif // HAS_SCALEADDROW_AVX2 #endif // HAS_SCALEADDROW_AVX2
// Constant for making pixels signed to avoid pmaddubsw
// saturation.
static uvec8 kFsub80 =
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
// Constant for making pixels unsigned and adding .5 for rounding.
static uvec16 kFadd40 =
{ 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040 };
// Bilinear column filtering. SSSE3 version. // Bilinear column filtering. SSSE3 version.
__declspec(naked) __declspec(naked)
void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr, void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
@ -877,6 +887,8 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm5, eax movd xmm5, eax
pcmpeqb xmm6, xmm6 // generate 0x007f for inverting fraction. pcmpeqb xmm6, xmm6 // generate 0x007f for inverting fraction.
psrlw xmm6, 9 psrlw xmm6, 9
pcmpeqb xmm7, xmm7 // generate 0x0001
psrlw xmm7, 15
pextrw eax, xmm2, 1 // get x0 integer. preroll pextrw eax, xmm2, 1 // get x0 integer. preroll
sub ecx, 2 sub ecx, 2
jl xloop29 jl xloop29
@ -899,20 +911,22 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm4, ebx movd xmm4, ebx
pshufb xmm1, xmm5 // 0011 pshufb xmm1, xmm5 // 0011
punpcklwd xmm0, xmm4 punpcklwd xmm0, xmm4
psubb xmm0, xmmword ptr kFsub80 // make pixels signed.
pxor xmm1, xmm6 // 0..7f and 7f..0 pxor xmm1, xmm6 // 0..7f and 7f..0
pmaddubsw xmm0, xmm1 // 16 bit, 2 pixels. paddusb xmm1, xmm7 // +1 so 0..7f and 80..1
pmaddubsw xmm1, xmm0 // 16 bit, 2 pixels.
pextrw eax, xmm2, 1 // get x0 integer. next iteration. pextrw eax, xmm2, 1 // get x0 integer. next iteration.
pextrw edx, xmm2, 3 // get x1 integer. next iteration. pextrw edx, xmm2, 3 // get x1 integer. next iteration.
psrlw xmm0, 7 // 8.7 fixed point to low 8 bits. paddw xmm1, xmmword ptr kFadd40 // make pixels unsigned and round.
packuswb xmm0, xmm0 // 8 bits, 2 pixels. psrlw xmm1, 7 // 8.7 fixed point to low 8 bits.
movd ebx, xmm0 packuswb xmm1, xmm1 // 8 bits, 2 pixels.
movd ebx, xmm1
mov [edi], bx mov [edi], bx
lea edi, [edi + 2] lea edi, [edi + 2]
sub ecx, 2 // 2 pixels sub ecx, 2 // 2 pixels
jge xloop2 jge xloop2
xloop29: xloop29:
add ecx, 2 - 1 add ecx, 2 - 1
jl xloop99 jl xloop99
@ -921,11 +935,14 @@ void ScaleFilterCols_SSSE3(uint8* dst_ptr, const uint8* src_ptr,
movd xmm0, ebx movd xmm0, ebx
psrlw xmm2, 9 // 7 bit fractions. psrlw xmm2, 9 // 7 bit fractions.
pshufb xmm2, xmm5 // 0011 pshufb xmm2, xmm5 // 0011
psubb xmm0, xmmword ptr kFsub80 // make pixels signed.
pxor xmm2, xmm6 // 0..7f and 7f..0 pxor xmm2, xmm6 // 0..7f and 7f..0
pmaddubsw xmm0, xmm2 // 16 bit paddusb xmm2, xmm7 // +1 so 0..7f and 80..1
psrlw xmm0, 7 // 8.7 fixed point to low 8 bits. pmaddubsw xmm2, xmm0 // 16 bit
packuswb xmm0, xmm0 // 8 bits paddw xmm2, xmmword ptr kFadd40 // make pixels unsigned and round.
movd ebx, xmm0 psrlw xmm2, 7 // 8.7 fixed point to low 8 bits.
packuswb xmm2, xmm2 // 8 bits
movd ebx, xmm2
mov [edi], bl mov [edi], bl
xloop99: xloop99:

View File

@ -25,6 +25,7 @@ struct FourCCAliasEntry {
static const struct FourCCAliasEntry kFourCCAliases[] = { static const struct FourCCAliasEntry kFourCCAliases[] = {
{FOURCC_IYUV, FOURCC_I420}, {FOURCC_IYUV, FOURCC_I420},
{FOURCC_YU12, FOURCC_I420},
{FOURCC_YU16, FOURCC_I422}, {FOURCC_YU16, FOURCC_I422},
{FOURCC_YU24, FOURCC_I444}, {FOURCC_YU24, FOURCC_I444},
{FOURCC_YUYV, FOURCC_YUY2}, {FOURCC_YUYV, FOURCC_YUY2},

View File

@ -18,7 +18,7 @@ if (is_win) {
config("gflags_config") { config("gflags_config") {
include_dirs = [ include_dirs = [
"$gflags_gen_arch_root/include", # For configured files. "$gflags_gen_arch_root/include", # For configured files.
"src", # For everything else. "src/src", # For everything else.
] ]
defines = [ defines = [
@ -38,31 +38,39 @@ config("gflags_config") {
} }
source_set("gflags") { source_set("gflags") {
cflags = []
sources = [ sources = [
"src/gflags.cc", "src/src/gflags.cc",
"src/gflags_completions.cc", "src/src/gflags_completions.cc",
"src/gflags_reporting.cc", "src/src/gflags_reporting.cc",
] ]
if (is_win) { if (is_win) {
sources += [ "src/windows/port.cc" ] sources += [ "src/src/windows_port.cc" ]
cflags = [ cflags += [
"/wd4005", # WIN32_LEAN_AND_MEAN. "/wd4005", # WIN32_LEAN_AND_MEAN.
"/wd4267", # Conversion from size_t to "type". "/wd4267", # Conversion from size_t to "type".
] ]
} }
include_dirs = [ "$gflags_gen_arch_root/include/private" ] # For config.h include_dirs = [
"$gflags_gen_arch_root/include/gflags", # For configured files.
"$gflags_gen_arch_root/include/private", # For config.h
]
public_configs = [ ":gflags_config" ] public_configs = [ ":gflags_config" ]
configs -= [ "//build/config/compiler:chromium_code" ] configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ]
if (is_win) {
configs -= [ "//build/config/win:unicode" ]
}
if (is_clang) { if (is_clang) {
# TODO(andrew): Look into fixing this warning upstream: # TODO(andrew): Look into fixing this warning upstream:
# http://code.google.com/p/webrtc/issues/detail?id=760 # http://code.google.com/p/webrtc/issues/detail?id=760
configs -= [ "//build/config/clang:extra_warnings" ] configs -= [ "//build/config/clang:extra_warnings" ]
cflags += [ "-Wno-microsoft-include" ]
} }
} }

View File

@ -1,5 +1,5 @@
URL: http://code.google.com/p/gflags/ URL: https://github.com/gflags/gflags
Version: 2.0 Version: 2.1.2
License: New BSD License: New BSD
License File: LICENSE License File: LICENSE

View File

@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Ray Sidney
// Revamped and reorganized by Craig Silverstein // Revamped and reorganized by Craig Silverstein
// //
// This is the file that should be included by any file which declares // This is the file that should be included by any file which declares
@ -52,8 +51,8 @@
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); // if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// } // }
// //
// Then, at the command-line: // Then, at the command-line:
// ./foo --noverbose --start=5 --end=100 // ./foo --noverbose --start=5 --end=100
// //
// For more details, see // For more details, see
// doc/gflags.html // doc/gflags.html
@ -76,53 +75,27 @@
// other thread is writing to the variable or calling non-const // other thread is writing to the variable or calling non-const
// methods of this class. // methods of this class.
#ifndef GOOGLE_GFLAGS_H_ #ifndef GFLAGS_GFLAGS_H_
#define GOOGLE_GFLAGS_H_ #define GFLAGS_GFLAGS_H_
#include <string> #include <string>
#include <vector> #include <vector>
// We care a lot about number of bits things take up. Unfortunately, #include "gflags_declare.h" // IWYU pragma: export
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but // We always want to export variables defined in user code
// that's because they were constructed that way at ./configure time. #ifndef GFLAGS_DLL_DEFINE_FLAG
// Look at gflags.h.in to see how they're calculated (based on your config). # ifdef _MSC_VER
#if 1 # define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
#include <stdint.h> // the normal place uint16_t is defined # else
#endif # define GFLAGS_DLL_DEFINE_FLAG
#if 1 # endif
#include <sys/types.h> // the normal place u_int16_t is defined
#endif
#if 1
#include <inttypes.h> // a third place for uint16_t or u_int16_t
#endif #endif
namespace google {
#if 1 // the C99 format namespace GFLAGS_NAMESPACE {
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 1 // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
// TODO(kjellander): update generated .h's for new gflags.
// https://code.google.com/p/webrtc/issues/detail?id=2251
extern const char* VersionString();
extern void SetVersionString(const std::string& version);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool, // To actually define a flag in a file, use DEFINE_bool,
@ -153,18 +126,17 @@ extern void SetVersionString(const std::string& version);
// Returns true if successfully registered, false if not (because the // Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a // first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag). // validator is already registered for this flag).
bool RegisterFlagValidator(const bool* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
bool (*validate_fn)(const char*, bool)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
bool RegisterFlagValidator(const int32* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
bool (*validate_fn)(const char*, int32)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
bool RegisterFlagValidator(const int64* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
bool (*validate_fn)(const char*, int64)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
bool RegisterFlagValidator(const uint64* flag,
bool (*validate_fn)(const char*, uint64)); // Convenience macro for the registration of a flag validator
bool RegisterFlagValidator(const double* flag, #define DEFINE_validator(name, validator) \
bool (*validate_fn)(const char*, double)); static const bool name##_validator_registered = \
bool RegisterFlagValidator(const std::string* flag, GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
bool (*validate_fn)(const char*, const std::string&));
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -177,49 +149,56 @@ bool RegisterFlagValidator(const std::string* flag,
// In addition to accessing flags, you can also access argv[0] (the program // In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of. // name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once. // These variables are static, so you should only set them once.
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo { struct CommandLineFlagInfo {
std::string name; // the name of the flag std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on flag bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline // has not been set explicitly from the cmdline
// or via SetCommandLineOption // or via SetCommandLineOption
const void* flag_ptr; const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
}; };
// Using this inside of a validator is a recipe for a deadlock. // Using this inside of a validator is a recipe for a deadlock.
// TODO(wojtekm) Fix locking when validators are running, to make it safe to // TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags. // call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in // Also make sure then to uncomment the corresponding unit test in
// commandlineflags_unittest.sh // gflags_unittest.sh
extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT); extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in commandlineflags_reporting.cc. // These two are actually defined in gflags_reporting.cc.
extern void ShowUsageWithFlags(const char *argv0); // what --help does extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag. // Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks. // Goes to some trouble to make pretty line breaks.
extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag); extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned. // Thread-hostile; meant to be called before any threads are spawned.
extern void SetArgv(int argc, const char** argv); extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is // The following functions are thread-safe as long as SetArgv() is
// only called before any threads start. // only called before any threads start.
extern const std::vector<std::string>& GetArgvs(); // all of argv as a vector extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern const char* GetArgv(); // all of argv as a string extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern const char* GetArgv0(); // only argv0 extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern uint32 GetArgvSum(); // simple checksum of argv extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern const char* ProgramInvocationShortName(); // basename(argv0) extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only // ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start. // called before any threads start.
extern const char* ProgramUsage(); // string set by SetUsageMessage() extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -232,19 +211,18 @@ extern const char* ProgramUsage(); // string set by SetUsageMessage()
// Return true iff the flagname was found. // Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false. // OUTPUT is set to the flag's value, or unchanged if we return false.
extern bool GetCommandLineOption(const char* name, std::string* OUTPUT); extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's // Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false. // CommandLineFlagInfo or unchanged if we return false.
extern bool GetCommandLineFlagInfo(const char* name, extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found. // Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value: // Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ... // if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum FlagSettingMode { enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times). // update the flag's value (can call this multiple times).
SET_FLAGS_VALUE, SET_FLAGS_VALUE,
// update the flag's value, but *only if* it has not yet been updated // update the flag's value, but *only if* it has not yet been updated
@ -264,9 +242,8 @@ enum FlagSettingMode {
// non-empty else. // non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) // SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern std::string SetCommandLineOption(const char* name, const char* value); extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern std::string SetCommandLineOptionWithMode(const char* name, const char* value, extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
FlagSettingMode set_mode);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -287,14 +264,17 @@ extern std::string SetCommandLineOptionWithMode(const char* name, const char* va
// // without worrying about restoring the FLAG values. // // without worrying about restoring the FLAG values.
// } // }
// //
// Note: This class is marked with __attribute__((unused)) because all the // Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// work is done in the constructor and destructor, so in the standard // the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an // usage example above, the compiler would complain that it's an
// unused variable. // unused variable.
// //
// This class is thread-safe. // This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class FlagSaver { class GFLAGS_DLL_DECL FlagSaver {
public: public:
FlagSaver(); FlagSaver();
~FlagSaver(); ~FlagSaver();
@ -304,24 +284,23 @@ class FlagSaver {
FlagSaver(const FlagSaver&); // no copying! FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&); void operator=(const FlagSaver&);
} __attribute__ ((unused)); }__attribute((unused));
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions. // Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way // This is often used for logging. TODO(csilvers): figure out a better way
extern std::string CommandlineFlagsIntoString(); extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead. // Usually where this is used, a FlagSaver should be used instead.
extern bool ReadFlagsFromString(const std::string& flagfilecontents, extern GFLAGS_DLL_DECL
const char* prog_name, bool ReadFlagsFromString(const std::string& flagfilecontents,
bool errors_are_fatal); // uses SET_FLAGS_VALUE const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality. // These let you manually implement --flagfile functionality.
// DEPRECATED. // DEPRECATED.
extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern bool SaveCommandFlags(); // actually defined in google.cc ! extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -332,16 +311,16 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name
// Otherwise, return the value. NOTE: for booleans, for true use // Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. // 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
extern bool BoolFromEnv(const char *varname, bool defval); extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
extern int32 Int32FromEnv(const char *varname, int32 defval); extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
extern int64 Int64FromEnv(const char *varname, int64 defval); extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
extern uint64 Uint64FromEnv(const char *varname, uint64 defval); extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern double DoubleFromEnv(const char *varname, double defval); extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
extern const char *StringFromEnv(const char *varname, const char *defval); extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// The next two functions parse commandlineflags from main(): // The next two functions parse gflags from main():
// Set the "usage" message for this program. For example: // Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n"); // string usage("This program does nothing. Sample usage:\n");
@ -349,7 +328,13 @@ extern const char *StringFromEnv(const char *varname, const char *defval);
// SetUsageMessage(usage); // SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you! // Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned. // Thread-hostile; meant to be called before any threads are spawned.
extern void SetUsageMessage(const std::string& usage); extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put // Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true. // flags first, or removes them entirely if remove_flags is true.
@ -358,8 +343,7 @@ extern void SetUsageMessage(const std::string& usage);
// of the first non-flag argument. // of the first non-flag argument.
// See top-of-file for more details on this function. // See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. #ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern uint32 ParseCommandLineFlags(int *argc, char*** argv, extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
bool remove_flags);
#endif #endif
@ -373,18 +357,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
// defined more than once in the command line or flag file, the last // defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first // definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.) // non-flag argument. (If remove_flags is true, will always return 1.)
extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
bool remove_flags);
// This is actually defined in commandlineflags_reporting.cc. // This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but // This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-( // it's too late to change that now. :-(
extern void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally // Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a // generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads // later parse. Thread-hostile; meant to be called before any threads
// are spawned. // are spawned.
extern void AllowCommandLineReparsing(); extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags // Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value // registered since the last parse will be recognized. Any flag value
@ -392,19 +376,18 @@ extern void AllowCommandLineReparsing();
// separate command line argument that follows the flag argument. // separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries, // Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded. // since their flags are not registered until they are loaded.
// Returns the index (into the original argv) of the first non-flag extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// argument. (If remove_flags is true, will always return 1.)
extern void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce // Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory // the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal // debugging tools such as valgrind. It is not required for normal
// operation, or for the perftools heap-checker. It must only be called // operation, or for the google perftools heap-checker. It must only
// when the process is about to exit, and all threads that might // be called when the process is about to exit, and all threads that
// access flags are quiescent. Referencing flags after this is called // might access flags are quiescent. Referencing flags after this is
// will have unexpected consequences. This is not safe to run when // called will have unexpected consequences. This is not safe to run
// multiple threads might be running: the function is thread-hostile. // when multiple threads might be running: the function is
extern void ShutDownCommandLineFlags(); // thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -435,7 +418,7 @@ extern void ShutDownCommandLineFlags();
// directly. The idea is that DEFINE puts the flag in the weird // directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current // namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get // namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern bool FLAGS_whatever;" // access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra // or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and // functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere. // make sure it is picked up everywhere.
@ -444,29 +427,30 @@ extern void ShutDownCommandLineFlags();
// people can't DECLARE_int32 something that they DEFINE_bool'd // people can't DECLARE_int32 something that they DEFINE_bool'd
// elsewhere. // elsewhere.
class FlagRegisterer { class GFLAGS_DLL_DECL FlagRegisterer {
public: public:
FlagRegisterer(const char* name, const char* type, FlagRegisterer(const char* name, const char* type,
const char* help, const char* filename, const char* help, const char* filename,
void* current_storage, void* defvalue_storage); void* current_storage, void* defvalue_storage);
}; };
extern bool FlagsTypeWarn(const char *name);
// If your application #defines STRIP_FLAG_HELP to a non-zero value // If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the // before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary // binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons. // somewhat, and may also be useful for security reasons.
extern const char kStrippedFlagHelp[]; extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
}
#ifndef SWIG // In swig, ignore the main flag declarations #ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 #if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning. // Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : ::google::kStrippedFlagHelp) #define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else #else
#define MAYBE_STRIPPED_HELP(txt) txt #define MAYBE_STRIPPED_HELP(txt) txt
#endif #endif
@ -482,21 +466,16 @@ extern const char kStrippedFlagHelp[];
// FLAGS_no<name>. This serves the second purpose of assuring a // FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name> // compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag). // which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ #define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \ namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \ static const type FLAGS_nono##name = value; \
type FLAGS_##name = FLAGS_nono##name; \ /* We always want to export defined variables, dll or no */ \
type FLAGS_no##name = FLAGS_nono##name; \ GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
static ::google::FlagRegisterer o_##name( \ type FLAGS_no##name = FLAGS_nono##name; \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
&FLAGS_##name, &FLAGS_no##name); \ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
} \ &FLAGS_##name, &FLAGS_no##name); \
using fL##shorttype::FLAGS_##name } \
#define DECLARE_VARIABLE(type, shorttype, name) \
namespace fL##shorttype { \
extern type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in // For DEFINE_bool, we want to do the extra check that the passed-in
@ -506,34 +485,39 @@ extern const char kStrippedFlagHelp[];
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires // We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since // that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a // this is not guaranteed by the standard, we check it with a
// compile-time assert (msg[-1] will give a compile-time error). // COMPILE_ASSERT.
namespace fLB { namespace fLB {
struct CompileAssert {}; struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1]; (sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> double IsBoolFlag(const From& from); template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
bool IsBoolFlag(bool from); GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB } // namespace fLB
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name) // Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
#define DEFINE_bool(name, val, txt) \ // are in a separate include, gflags_declare.h, for reducing
namespace fLB { \ // the physical transitive size for DECLARE use.
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \ #define DEFINE_bool(name, val, txt) \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \ namespace fLB { \
} \ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt) DEFINE_VARIABLE(bool, B, name, val, txt)
#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name) #define DEFINE_int32(name, val, txt) \
#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name) #define DEFINE_int64(name, val, txt) \
#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name) #define DEFINE_uint64(name,val, txt) \
#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name) #define DEFINE_double(name, val, txt) \
#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't // Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get // construct them at static-initialization time (instead they get
@ -543,11 +527,6 @@ bool IsBoolFlag(bool from);
// into it later. It's not perfect, but the best we can do. // into it later. It's not perfect, but the best we can do.
namespace fLS { namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
inline clstring* dont_pass0toDEFINE_string(char *stringspot, inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) { const char *value) {
@ -561,9 +540,6 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value); int value);
} // namespace fLS } // namespace fLS
#define DECLARE_string(name) namespace fLS { extern ::fLS::clstring& FLAGS_##name; } \
using fLS::FLAGS_##name
// We need to define a var named FLAGS_no##name so people don't define // We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val // --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go // so we don't have to evaluate it twice. Two great needs that go
@ -578,10 +554,10 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \ clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \ dont_pass0toDEFINE_string(s_##name[0].s, \
val); \ val); \
static ::google::FlagRegisterer o_##name( \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
extern clstring& FLAGS_##name; \ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \ using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \ clstring& FLAGS_##name = *FLAGS_no##name; \
} \ } \
@ -589,4 +565,9 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
#endif // SWIG #endif // SWIG
#endif // GOOGLE_GFLAGS_H_
// Import gflags library symbols into alternative/deprecated namespace(s)
#include "gflags_gflags.h"
#endif // GFLAGS_GFLAGS_H_

View File

@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Dave Nicponski
// //
// Implement helpful bash-style command line flag completions // Implement helpful bash-style command line flag completions
// //
@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ): // file would be (your path to gflags_completions.sh file may differ):
/* /*
$ complete -o bashdefault -o default -o nospace -C \ $ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...] time env binary_name another_binary [...]
*/ */
@ -109,13 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output. // produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ #ifndef GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_ #define GFLAGS_COMPLETIONS_H_
namespace google { namespace google {
void HandleCommandLineCompletions(void); extern void HandleCommandLineCompletions(void);
} }
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ #endif // GFLAGS_COMPLETIONS_H_

View File

@ -0,0 +1,141 @@
// Copyright (c) 1999, Google Inc.
// 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 Inc. 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
// OWNER 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.
// ---
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE google
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// We always want to import the symbols of the gflags library
#ifndef GFLAGS_DLL_DECL
# if 0 && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code
#ifndef GFLAGS_DLL_DECLARE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 1
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 1 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
using ::fLS::clstring; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,101 @@
// Copyright (c) 2014, Andreas Schuh
// 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 Inc. 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
// OWNER 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.
// -----------------------------------------------------------------------------
// Imports the gflags library symbols into an alternative/deprecated namespace.
#ifndef GFLAGS_GFLAGS_H_
# error The internal header gflags_gflags.h may only be included by gflags.h
#endif
#ifndef GFLAGS_NS_GFLAGS_H_
#define GFLAGS_NS_GFLAGS_H_
namespace gflags {
using GFLAGS_NAMESPACE::int32;
using GFLAGS_NAMESPACE::uint32;
using GFLAGS_NAMESPACE::int64;
using GFLAGS_NAMESPACE::uint64;
using GFLAGS_NAMESPACE::RegisterFlagValidator;
using GFLAGS_NAMESPACE::CommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetAllFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict;
using GFLAGS_NAMESPACE::DescribeOneFlag;
using GFLAGS_NAMESPACE::SetArgv;
using GFLAGS_NAMESPACE::GetArgvs;
using GFLAGS_NAMESPACE::GetArgv;
using GFLAGS_NAMESPACE::GetArgv0;
using GFLAGS_NAMESPACE::GetArgvSum;
using GFLAGS_NAMESPACE::ProgramInvocationName;
using GFLAGS_NAMESPACE::ProgramInvocationShortName;
using GFLAGS_NAMESPACE::ProgramUsage;
using GFLAGS_NAMESPACE::VersionString;
using GFLAGS_NAMESPACE::GetCommandLineOption;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie;
using GFLAGS_NAMESPACE::FlagSettingMode;
using GFLAGS_NAMESPACE::SET_FLAGS_VALUE;
using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT;
using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT;
using GFLAGS_NAMESPACE::SetCommandLineOption;
using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode;
using GFLAGS_NAMESPACE::FlagSaver;
using GFLAGS_NAMESPACE::CommandlineFlagsIntoString;
using GFLAGS_NAMESPACE::ReadFlagsFromString;
using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
using GFLAGS_NAMESPACE::ReadFromFlagsFile;
using GFLAGS_NAMESPACE::BoolFromEnv;
using GFLAGS_NAMESPACE::Int32FromEnv;
using GFLAGS_NAMESPACE::Int64FromEnv;
using GFLAGS_NAMESPACE::Uint64FromEnv;
using GFLAGS_NAMESPACE::DoubleFromEnv;
using GFLAGS_NAMESPACE::StringFromEnv;
using GFLAGS_NAMESPACE::SetUsageMessage;
using GFLAGS_NAMESPACE::SetVersionString;
using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags;
using GFLAGS_NAMESPACE::AllowCommandLineReparsing;
using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::ShutDownCommandLineFlags;
using GFLAGS_NAMESPACE::FlagRegisterer;
#ifndef SWIG
using GFLAGS_NAMESPACE::ParseCommandLineFlags;
#endif
} // namespace gflags
#endif // GFLAGS_NS_GFLAGS_H_

View File

@ -1,110 +1,112 @@
/* src/config.h. Generated from config.h.in by configure. */ /* Generated from config.h.in during build configuration using CMake. */
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Always the empty-string on non-windows systems. On windows, should be // Note: This header file is only used internally. It is not part of public interface!
"__declspec(dllexport)". This way, when we compile the dll, we export our
functions/classes. It's safe to define this here because config.h is only
used internally, to compile the DLL, and every DLL source file #includes
"config.h" before anything else. */
#define GFLAGS_DLL_DECL /**/
/* Namespace for Google classes */ // ---------------------------------------------------------------------------
#define GOOGLE_NAMESPACE ::google // System checks
/* Define to 1 if you have the <dlfcn.h> header file. */ // Define if you build this library for a MS Windows OS.
#define HAVE_DLFCN_H 1 /* #undef OS_WINDOWS */
/* Define to 1 if you have the <fnmatch.h> header file. */ // Define if you have the <stdint.h> header file.
#define HAVE_FNMATCH_H 1 #define HAVE_STDINT_H
/* Define to 1 if you have the <inttypes.h> header file. */ // Define if you have the <sys/types.h> header file.
#define HAVE_INTTYPES_H 1 #define HAVE_SYS_TYPES_H
/* Define to 1 if you have the <memory.h> header file. */ // Define if you have the <inttypes.h> header file.
#define HAVE_MEMORY_H 1 #define HAVE_INTTYPES_H
/* define if the compiler implements namespaces */ // Define if you have the <sys/stat.h> header file.
#define HAVE_NAMESPACES 1 #define HAVE_SYS_STAT_H
/* Define if you have POSIX threads libraries and header files. */ // Define if you have the <unistd.h> header file.
#define HAVE_PTHREAD 1 #define HAVE_UNISTD_H
/* Define to 1 if you have the `putenv' function. */ // Define if you have the <fnmatch.h> header file.
#define HAVE_PUTENV 1 #define HAVE_FNMATCH_H
/* Define to 1 if you have the `setenv' function. */ // Define if you have the <shlwapi.h> header file (Windows 2000/XP).
#define HAVE_SETENV 1 /* #undef HAVE_SHLWAPI_H */
/* Define to 1 if you have the <stdint.h> header file. */ // Define if you have the strtoll function.
#define HAVE_STDINT_H 1 #define HAVE_STRTOLL
/* Define to 1 if you have the <stdlib.h> header file. */ // Define if you have the strtoq function.
#define HAVE_STDLIB_H 1 /* #undef HAVE_STRTOQ */
/* Define to 1 if you have the <strings.h> header file. */ // Define if you have the <pthread.h> header file.
#define HAVE_STRINGS_H 1 #define HAVE_PTHREAD
/* Define to 1 if you have the <string.h> header file. */ // Define if your pthread library defines the type pthread_rwlock_t
#define HAVE_STRING_H 1 #define HAVE_RWLOCK
/* Define to 1 if you have the `strtoll' function. */ // gcc requires this to get PRId64, etc.
#define HAVE_STRTOLL 1 #if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif
/* Define to 1 if you have the `strtoq' function. */ // ---------------------------------------------------------------------------
#define HAVE_STRTOQ 1 // Package information
/* Define to 1 if you have the <sys/stat.h> header file. */ // Name of package.
#define HAVE_SYS_STAT_H 1 #define PACKAGE gflags
/* Define to 1 if you have the <sys/types.h> header file. */ // Define to the full name of this package.
#define HAVE_SYS_TYPES_H 1 #define PACKAGE_NAME gflags
/* Define to 1 if you have the <unistd.h> header file. */ // Define to the full name and version of this package.
#define HAVE_UNISTD_H 1 #define PACKAGE_STRING gflags 2.2.0
/* define if your compiler has __attribute__ */ // Define to the one symbol short name of this package.
#define HAVE___ATTRIBUTE__ 1 #define PACKAGE_TARNAME gflags-2.2.0
/* Define to the sub-directory in which libtool stores uninstalled libraries. // Define to the version of this package.
*/ #define PACKAGE_VERSION 2.2.0
#define LT_OBJDIR ".libs/"
/* Name of package */ // Version number of package.
#define PACKAGE "gflags" #define VERSION PACKAGE_VERSION
/* Define to the address where bug reports for this package should be sent. */ // Define to the address where bug reports for this package should be sent.
#define PACKAGE_BUGREPORT "opensource@google.com" #define PACKAGE_BUGREPORT https://github.com/schuhschuh/gflags/issues
/* Define to the full name of this package. */ // ---------------------------------------------------------------------------
#define PACKAGE_NAME "gflags" // Path separator
#ifndef PATH_SEPARATOR
# ifdef OS_WINDOWS
# define PATH_SEPARATOR '\\'
# else
# define PATH_SEPARATOR '/'
# endif
#endif
/* Define to the full name and version of this package. */ // ---------------------------------------------------------------------------
#define PACKAGE_STRING "gflags 1.5" // Windows
/* Define to the one symbol short name of this package. */ // Whether gflags library is a DLL.
#define PACKAGE_TARNAME "gflags" #ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
/* Define to the home page for this package. */ // Always export symbols when compiling a shared library as this file is only
#define PACKAGE_URL "" // included by internal modules when building the gflags library itself.
// The gflags_declare.h header file will set it to import these symbols otherwise.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllexport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// Flags defined by the gflags library itself must be exported
#ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
#endif
/* Define to the version of this package. */ #ifdef OS_WINDOWS
#define PACKAGE_VERSION "1.5" // The unittests import the symbols of the shared gflags library
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
/* Define to necessary symbol if this constant uses a non-standard name on # define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
your system. */ # endif
/* #undef PTHREAD_CREATE_JOINABLE */ # include "windows_port.h"
#endif
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#define VERSION "1.5"
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {

View File

@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Ray Sidney
// Revamped and reorganized by Craig Silverstein // Revamped and reorganized by Craig Silverstein
// //
// This is the file that should be included by any file which declares // This is the file that should be included by any file which declares
@ -52,8 +51,8 @@
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); // if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// } // }
// //
// Then, at the command-line: // Then, at the command-line:
// ./foo --noverbose --start=5 --end=100 // ./foo --noverbose --start=5 --end=100
// //
// For more details, see // For more details, see
// doc/gflags.html // doc/gflags.html
@ -76,76 +75,27 @@
// other thread is writing to the variable or calling non-const // other thread is writing to the variable or calling non-const
// methods of this class. // methods of this class.
#ifndef GOOGLE_GFLAGS_H_ #ifndef GFLAGS_GFLAGS_H_
#define GOOGLE_GFLAGS_H_ #define GFLAGS_GFLAGS_H_
#include <string> #include <string>
#include <vector> #include <vector>
// We care a lot about number of bits things take up. Unfortunately, #include "gflags_declare.h" // IWYU pragma: export
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but // We always want to export variables defined in user code
// that's because they were constructed that way at ./configure time. #ifndef GFLAGS_DLL_DEFINE_FLAG
// Look at gflags.h.in to see how they're calculated (based on your config). # ifdef _MSC_VER
#if 0 # define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
#include <stdint.h> // the normal place uint16_t is defined # else
#endif # define GFLAGS_DLL_DEFINE_FLAG
#if 1 # endif
#include <sys/types.h> // the normal place u_int16_t is defined
#endif
#if 0
#include <inttypes.h> // a third place for uint16_t or u_int16_t
#endif #endif
// Annoying stuff for windows -- makes sure clients can import these functions
#if defined(_WIN32)
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# endif
#else
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace google { namespace GFLAGS_NAMESPACE {
#if 0 // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
// TODO(kjellander): update generated .h's for new gflags.
// https://code.google.com/p/webrtc/issues/detail?id=2251
extern const char* VersionString();
extern void SetVersionString(const std::string& version);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool, // To actually define a flag in a file, use DEFINE_bool,
@ -176,18 +126,17 @@ extern void SetVersionString(const std::string& version);
// Returns true if successfully registered, false if not (because the // Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a // first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag). // validator is already registered for this flag).
GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
bool (*validate_fn)(const char*, bool)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
bool (*validate_fn)(const char*, int32)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
bool (*validate_fn)(const char*, int64)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag,
bool (*validate_fn)(const char*, uint64)); // Convenience macro for the registration of a flag validator
GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, #define DEFINE_validator(name, validator) \
bool (*validate_fn)(const char*, double)); static const bool name##_validator_registered = \
GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
bool (*validate_fn)(const char*, const std::string&));
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -200,28 +149,29 @@ GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag,
// In addition to accessing flags, you can also access argv[0] (the program // In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of. // name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once. // These variables are static, so you should only set them once.
//
struct GFLAGS_DLL_DECL CommandLineFlagInfo { // No need to export this data only structure from DLL, avoiding VS warning 4251.
std::string name; // the name of the flag struct CommandLineFlagInfo {
std::string type; // the type of the flag: int32, etc std::string name; // the name of the flag
std::string description; // the "help text" associated with the flag std::string type; // the type of the flag: int32, etc
std::string current_value; // the current value, as a string std::string description; // the "help text" associated with the flag
std::string default_value; // the default value, as a string std::string current_value; // the current value, as a string
std::string filename; // 'cleaned' version of filename holding the flag std::string default_value; // the default value, as a string
bool has_validator_fn; // true if RegisterFlagValidator called on flag std::string filename; // 'cleaned' version of filename holding the flag
bool is_default; // true if the flag has the default value and bool has_validator_fn; // true if RegisterFlagValidator called on this flag
// has not been set explicitly from the cmdline bool is_default; // true if the flag has the default value and
// or via SetCommandLineOption // has not been set explicitly from the cmdline
const void* flag_ptr; // or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
}; };
// Using this inside of a validator is a recipe for a deadlock. // Using this inside of a validator is a recipe for a deadlock.
// TODO(wojtekm) Fix locking when validators are running, to make it safe to // TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags. // call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in // Also make sure then to uncomment the corresponding unit test in
// commandlineflags_unittest.sh // gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT); extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in commandlineflags_reporting.cc. // These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
@ -231,17 +181,24 @@ extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& fl
// Thread-hostile; meant to be called before any threads are spawned. // Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv); extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is // The following functions are thread-safe as long as SetArgv() is
// only called before any threads start. // only called before any threads start.
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs(); // all of argv as a vector extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0 extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0) extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only // ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start. // called before any threads start.
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage() extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -258,8 +215,7 @@ extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string*
// Return true iff the flagname was found. OUTPUT is set to the flag's // Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false. // CommandLineFlagInfo or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found. // Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value: // Example usage, to check if a flag's value is currently the default value:
@ -286,9 +242,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode {
// non-empty else. // non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) // SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern GFLAGS_DLL_DECL std::string SetCommandLineOption(const char* name, const char* value); extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
FlagSettingMode set_mode);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -309,12 +264,15 @@ extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name
// // without worrying about restoring the FLAG values. // // without worrying about restoring the FLAG values.
// } // }
// //
// Note: This class is marked with __attribute__((unused)) because all the // Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// work is done in the constructor and destructor, so in the standard // the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an // usage example above, the compiler would complain that it's an
// unused variable. // unused variable.
// //
// This class is thread-safe. // This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class GFLAGS_DLL_DECL FlagSaver { class GFLAGS_DLL_DECL FlagSaver {
public: public:
@ -326,7 +284,7 @@ class GFLAGS_DLL_DECL FlagSaver {
FlagSaver(const FlagSaver&); // no copying! FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&); void operator=(const FlagSaver&);
} ; };
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions. // Some deprecated or hopefully-soon-to-be-deprecated functions.
@ -334,16 +292,15 @@ class GFLAGS_DLL_DECL FlagSaver {
// This is often used for logging. TODO(csilvers): figure out a better way // This is often used for logging. TODO(csilvers): figure out a better way
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString(); extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead. // Usually where this is used, a FlagSaver should be used instead.
extern GFLAGS_DLL_DECL bool ReadFlagsFromString(const std::string& flagfilecontents, extern GFLAGS_DLL_DECL
const char* prog_name, bool ReadFlagsFromString(const std::string& flagfilecontents,
bool errors_are_fatal); // uses SET_FLAGS_VALUE const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality. // These let you manually implement --flagfile functionality.
// DEPRECATED. // DEPRECATED.
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool SaveCommandFlags(); // actually defined in google.cc ! extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -363,7 +320,7 @@ extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// The next two functions parse commandlineflags from main(): // The next two functions parse gflags from main():
// Set the "usage" message for this program. For example: // Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n"); // string usage("This program does nothing. Sample usage:\n");
@ -373,14 +330,20 @@ extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char
// Thread-hostile; meant to be called before any threads are spawned. // Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage); extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put // Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true. // flags first, or removes them entirely if remove_flags is true.
// If a flag is defined more than once in the command line or flag // If a flag is defined more than once in the command line or flag
// file, the last definition is used. // file, the last definition is used. Returns the index (into argv)
// of the first non-flag argument.
// See top-of-file for more details on this function. // See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. #ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
bool remove_flags);
#endif #endif
@ -390,15 +353,16 @@ extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv,
// changing default values for some FLAGS (via // changing default values for some FLAGS (via
// e.g. SetCommandLineOptionWithMode calls) between the time of // e.g. SetCommandLineOptionWithMode calls) between the time of
// command line parsing and the time of dumping help information for // command line parsing and the time of dumping help information for
// the flags as a result of command line parsing. // the flags as a result of command line parsing. If a flag is
// If a flag is defined more than once in the command line or flag // defined more than once in the command line or flag file, the last
// file, the last definition is used. // definition is used. Returns the index (into argv) of the first
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, // non-flag argument. (If remove_flags is true, will always return 1.)
bool remove_flags); extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in commandlineflags_reporting.cc.
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but // This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-( // it's too late to change that now. :-(
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally // Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a // generated when an unknown flag is found, since it may be found in a
@ -406,10 +370,10 @@ extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in commandlinefla
// are spawned. // are spawned.
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing(); extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. // Reparse the flags that have not yet been recognized. Only flags
// Only flags registered since the last parse will be recognized. // registered since the last parse will be recognized. Any flag value
// Any flag value must be provided as part of the argument using "=", // must be provided as part of the argument using "=", not as a
// not as a separate command line argument that follows the flag argument. // separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries, // Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded. // since their flags are not registered until they are loaded.
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags(); extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
@ -417,11 +381,12 @@ extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce // Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory // the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal // debugging tools such as valgrind. It is not required for normal
// operation, or for the perftools heap-checker. It must only be called // operation, or for the google perftools heap-checker. It must only
// when the process is about to exit, and all threads that might // be called when the process is about to exit, and all threads that
// access flags are quiescent. Referencing flags after this is called // might access flags are quiescent. Referencing flags after this is
// will have unexpected consequences. This is not safe to run when // called will have unexpected consequences. This is not safe to run
// multiple threads might be running: the function is thread-hostile. // when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags(); extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
@ -453,7 +418,7 @@ extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// directly. The idea is that DEFINE puts the flag in the weird // directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current // namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get // namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern bool FLAGS_whatever;" // access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra // or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and // functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere. // make sure it is picked up everywhere.
@ -469,22 +434,23 @@ class GFLAGS_DLL_DECL FlagRegisterer {
void* current_storage, void* defvalue_storage); void* current_storage, void* defvalue_storage);
}; };
extern bool FlagsTypeWarn(const char *name);
// If your application #defines STRIP_FLAG_HELP to a non-zero value // If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the // before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary // binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons. // somewhat, and may also be useful for security reasons.
extern const char kStrippedFlagHelp[]; extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
}
#ifndef SWIG // In swig, ignore the main flag declarations #ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 #if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning. // Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp) #define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else #else
#define MAYBE_STRIPPED_HELP(txt) txt #define MAYBE_STRIPPED_HELP(txt) txt
#endif #endif
@ -500,23 +466,16 @@ extern const char kStrippedFlagHelp[];
// FLAGS_no<name>. This serves the second purpose of assuring a // FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name> // compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag). // which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ #define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \ namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \ static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \ /* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \ GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \ type FLAGS_no##name = FLAGS_nono##name; \
static ::google::FlagRegisterer o_##name( \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \ #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \ &FLAGS_##name, &FLAGS_no##name); \
} \ } \
using fL##shorttype::FLAGS_##name
#define DECLARE_VARIABLE(type, shorttype, name) \
namespace fL##shorttype { \
/* We always want to import declared variables, dll or no */ \
extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; \
} \
using fL##shorttype::FLAGS_##name using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in // For DEFINE_bool, we want to do the extra check that the passed-in
@ -526,34 +485,39 @@ extern const char kStrippedFlagHelp[];
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires // We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since // that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a // this is not guaranteed by the standard, we check it with a
// compile-time assert (msg[-1] will give a compile-time error). // COMPILE_ASSERT.
namespace fLB { namespace fLB {
struct CompileAssert {}; struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1]; (sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> GFLAGS_DLL_DECL double IsBoolFlag(const From& from); template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from); GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB } // namespace fLB
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name) // Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
#define DEFINE_bool(name, val, txt) \ // are in a separate include, gflags_declare.h, for reducing
namespace fLB { \ // the physical transitive size for DECLARE use.
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \ #define DEFINE_bool(name, val, txt) \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \ namespace fLB { \
} \ typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt) DEFINE_VARIABLE(bool, B, name, val, txt)
#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name) #define DEFINE_int32(name, val, txt) \
#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name) #define DEFINE_int64(name, val, txt) \
#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name) #define DEFINE_uint64(name,val, txt) \
#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt) DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name) #define DEFINE_double(name, val, txt) \
#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't // Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get // construct them at static-initialization time (instead they get
@ -563,11 +527,6 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
// into it later. It's not perfect, but the best we can do. // into it later. It's not perfect, but the best we can do.
namespace fLS { namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
inline clstring* dont_pass0toDEFINE_string(char *stringspot, inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) { const char *value) {
@ -581,13 +540,13 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value); int value);
} // namespace fLS } // namespace fLS
#define DECLARE_string(name) namespace fLS { extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; } \
using fLS::FLAGS_##name
// We need to define a var named FLAGS_no##name so people don't define // We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val // --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go // so we don't have to evaluate it twice. Two great needs that go
// great together! // great together!
// The weird 'using' + 'extern' inside the fLS namespace is to work around
// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
// http://code.google.com/p/google-gflags/issues/detail?id=20
#define DEFINE_string(name, val, txt) \ #define DEFINE_string(name, val, txt) \
namespace fLS { \ namespace fLS { \
using ::fLS::clstring; \ using ::fLS::clstring; \
@ -595,13 +554,20 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \ clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \ dont_pass0toDEFINE_string(s_##name[0].s, \
val); \ val); \
static ::google::FlagRegisterer o_##name( \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name = *FLAGS_no##name; \ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \ } \
using fLS::FLAGS_##name using fLS::FLAGS_##name
#endif // SWIG #endif // SWIG
#endif // GOOGLE_GFLAGS_H_
// Import gflags library symbols into alternative/deprecated namespace(s)
#include "gflags_gflags.h"
#endif // GFLAGS_GFLAGS_H_

View File

@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Dave Nicponski
// //
// Implement helpful bash-style command line flag completions // Implement helpful bash-style command line flag completions
// //
@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ): // file would be (your path to gflags_completions.sh file may differ):
/* /*
$ complete -o bashdefault -o default -o nospace -C \ $ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...] time env binary_name another_binary [...]
*/ */
@ -109,22 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output. // produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ #ifndef GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_ #define GFLAGS_COMPLETIONS_H_
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GFLAGS_DLL_DECL
# ifdef _WIN32
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
namespace google { namespace google {
GFLAGS_DLL_DECL void HandleCommandLineCompletions(void); extern void HandleCommandLineCompletions(void);
} }
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ #endif // GFLAGS_COMPLETIONS_H_

View File

@ -0,0 +1,141 @@
// Copyright (c) 1999, Google Inc.
// 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 Inc. 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
// OWNER 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.
// ---
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE google
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// We always want to import the symbols of the gflags library
#ifndef GFLAGS_DLL_DECL
# if 0 && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code
#ifndef GFLAGS_DLL_DECLARE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 0
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 0 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
using ::fLS::clstring; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,101 @@
// Copyright (c) 2014, Andreas Schuh
// 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 Inc. 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
// OWNER 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.
// -----------------------------------------------------------------------------
// Imports the gflags library symbols into an alternative/deprecated namespace.
#ifndef GFLAGS_GFLAGS_H_
# error The internal header gflags_gflags.h may only be included by gflags.h
#endif
#ifndef GFLAGS_NS_GFLAGS_H_
#define GFLAGS_NS_GFLAGS_H_
namespace gflags {
using GFLAGS_NAMESPACE::int32;
using GFLAGS_NAMESPACE::uint32;
using GFLAGS_NAMESPACE::int64;
using GFLAGS_NAMESPACE::uint64;
using GFLAGS_NAMESPACE::RegisterFlagValidator;
using GFLAGS_NAMESPACE::CommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetAllFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlags;
using GFLAGS_NAMESPACE::ShowUsageWithFlagsRestrict;
using GFLAGS_NAMESPACE::DescribeOneFlag;
using GFLAGS_NAMESPACE::SetArgv;
using GFLAGS_NAMESPACE::GetArgvs;
using GFLAGS_NAMESPACE::GetArgv;
using GFLAGS_NAMESPACE::GetArgv0;
using GFLAGS_NAMESPACE::GetArgvSum;
using GFLAGS_NAMESPACE::ProgramInvocationName;
using GFLAGS_NAMESPACE::ProgramInvocationShortName;
using GFLAGS_NAMESPACE::ProgramUsage;
using GFLAGS_NAMESPACE::VersionString;
using GFLAGS_NAMESPACE::GetCommandLineOption;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfo;
using GFLAGS_NAMESPACE::GetCommandLineFlagInfoOrDie;
using GFLAGS_NAMESPACE::FlagSettingMode;
using GFLAGS_NAMESPACE::SET_FLAGS_VALUE;
using GFLAGS_NAMESPACE::SET_FLAG_IF_DEFAULT;
using GFLAGS_NAMESPACE::SET_FLAGS_DEFAULT;
using GFLAGS_NAMESPACE::SetCommandLineOption;
using GFLAGS_NAMESPACE::SetCommandLineOptionWithMode;
using GFLAGS_NAMESPACE::FlagSaver;
using GFLAGS_NAMESPACE::CommandlineFlagsIntoString;
using GFLAGS_NAMESPACE::ReadFlagsFromString;
using GFLAGS_NAMESPACE::AppendFlagsIntoFile;
using GFLAGS_NAMESPACE::ReadFromFlagsFile;
using GFLAGS_NAMESPACE::BoolFromEnv;
using GFLAGS_NAMESPACE::Int32FromEnv;
using GFLAGS_NAMESPACE::Int64FromEnv;
using GFLAGS_NAMESPACE::Uint64FromEnv;
using GFLAGS_NAMESPACE::DoubleFromEnv;
using GFLAGS_NAMESPACE::StringFromEnv;
using GFLAGS_NAMESPACE::SetUsageMessage;
using GFLAGS_NAMESPACE::SetVersionString;
using GFLAGS_NAMESPACE::ParseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::HandleCommandLineHelpFlags;
using GFLAGS_NAMESPACE::AllowCommandLineReparsing;
using GFLAGS_NAMESPACE::ReparseCommandLineNonHelpFlags;
using GFLAGS_NAMESPACE::ShutDownCommandLineFlags;
using GFLAGS_NAMESPACE::FlagRegisterer;
#ifndef SWIG
using GFLAGS_NAMESPACE::ParseCommandLineFlags;
#endif
} // namespace gflags
#endif // GFLAGS_NS_GFLAGS_H_

View File

@ -1,139 +1,112 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */ /* Generated from config.h.in during build configuration using CMake. */
/* Sometimes we accidentally #include this config.h instead of the one // Note: This header file is only used internally. It is not part of public interface!
in .. -- this is particularly true for msys/mingw, which uses the
unix config.h but also runs code in the windows directory. // ---------------------------------------------------------------------------
*/ // System checks
#ifdef __MINGW32__
#include "../config.h" // Define if you build this library for a MS Windows OS.
#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ #define OS_WINDOWS
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
/* #undef HAVE_INTTYPES_H */
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
/* #undef HAVE_UNISTD_H */
// Define if you have the <fnmatch.h> header file.
/* #undef HAVE_FNMATCH_H */
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
#define HAVE_SHLWAPI_H
// Define if you have the strtoll function.
/* #undef HAVE_STRTOLL */
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
// Define if you have the <pthread.h> header file.
/* #undef HAVE_PTHREAD */
// Define if your pthread library defines the type pthread_rwlock_t
/* #undef HAVE_RWLOCK */
// gcc requires this to get PRId64, etc.
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif #endif
#ifndef GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ // ---------------------------------------------------------------------------
#define GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ // Package information
/* Always the empty-string on non-windows systems. On windows, should be // Name of package.
"__declspec(dllexport)". This way, when we compile the dll, we export our #define PACKAGE gflags
functions/classes. It's safe to define this here because config.h is only
used internally, to compile the DLL, and every DLL source file #includes // Define to the full name of this package.
"config.h" before anything else. */ #define PACKAGE_NAME gflags
// Define to the full name and version of this package.
#define PACKAGE_STRING gflags 2.2.0
// Define to the one symbol short name of this package.
#define PACKAGE_TARNAME gflags-2.2.0
// Define to the version of this package.
#define PACKAGE_VERSION 2.2.0
// Version number of package.
#define VERSION PACKAGE_VERSION
// Define to the address where bug reports for this package should be sent.
#define PACKAGE_BUGREPORT https://github.com/schuhschuh/gflags/issues
// ---------------------------------------------------------------------------
// Path separator
#ifndef PATH_SEPARATOR
# ifdef OS_WINDOWS
# define PATH_SEPARATOR '\\'
# else
# define PATH_SEPARATOR '/'
# endif
#endif
// ---------------------------------------------------------------------------
// Windows
// Whether gflags library is a DLL.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
// Always export symbols when compiling a shared library as this file is only
// included by internal modules when building the gflags library itself.
// The gflags_declare.h header file will set it to import these symbols otherwise.
#ifndef GFLAGS_DLL_DECL #ifndef GFLAGS_DLL_DECL
# define GFLAGS_IS_A_DLL 1 /* not set if you're statically linking */ # if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllexport) # define GFLAGS_DLL_DECL __declspec(dllexport)
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) # else
# define GFLAGS_DLL_DECL
# endif
#endif
// Flags defined by the gflags library itself must be exported
#ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
#endif #endif
/* Namespace for Google classes */ #ifdef OS_WINDOWS
#define GOOGLE_NAMESPACE ::google // The unittests import the symbols of the shared gflags library
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
/* Define to 1 if you have the <dlfcn.h> header file. */ # define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
#undef HAVE_DLFCN_H # endif
# include "windows_port.h"
/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES 1
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the `putenv' function. */
#define HAVE_PUTENV 1
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `strtoq' function. */
#define HAVE_STRTOQ 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* Version number of package */
#undef VERSION
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
// ---------------------------------------------------------------------
// Extra stuff not found in config.h.in
// This must be defined before the windows.h is included. It's needed
// for mutex.h, to give access to the TryLock method.
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#endif #endif
// TODO(csilvers): include windows/port.h in every relevant source file instead?
#include "windows/port.h"
#endif /* GOOGLE_GFLAGS_WINDOWS_CONFIG_H_ */

View File

@ -25,9 +25,9 @@
'target_name': 'gflags', 'target_name': 'gflags',
'type': 'static_library', 'type': 'static_library',
'include_dirs': [ 'include_dirs': [
'<(gflags_gen_arch_root)/include/gflags', # For configured files.
'<(gflags_gen_arch_root)/include/private', # For config.h '<(gflags_gen_arch_root)/include/private', # For config.h
'<(gflags_gen_arch_root)/include', # For configured files. '<(gflags_root)/src/src', # For everything else.
'<(gflags_root)/src', # For everything else.
], ],
'defines': [ 'defines': [
# These macros exist so flags and symbols are properly # These macros exist so flags and symbols are properly
@ -40,7 +40,7 @@
'direct_dependent_settings': { 'direct_dependent_settings': {
'include_dirs': [ 'include_dirs': [
'<(gflags_gen_arch_root)/include', # For configured files. '<(gflags_gen_arch_root)/include', # For configured files.
'<(gflags_root)/src', # For everything else. '<(gflags_root)/src/src', # For everything else.
], ],
'defines': [ 'defines': [
'GFLAGS_DLL_DECL=', 'GFLAGS_DLL_DECL=',
@ -49,42 +49,44 @@
], ],
}, },
'sources': [ 'sources': [
'src/gflags.cc', 'src/src/gflags.cc',
'src/gflags_completions.cc', 'src/src/gflags_completions.cc',
'src/gflags_reporting.cc', 'src/src/gflags_reporting.cc',
], ],
'conditions': [ 'conditions': [
['OS=="win"', { ['OS=="win"', {
'sources': [ 'sources': [
'src/windows/port.cc', 'src/src/windows_port.cc',
], ],
# Suppress warnings about WIN32_LEAN_AND_MEAN and size_t truncation. 'msvs_disabled_warnings': [
'msvs_disabled_warnings': [4005, 4267], 4005, # WIN32_LEAN_AND_MEAN redefinition.
4267, # Conversion from size_t to "type".
],
'configurations': {
'Common_Base': {
'msvs_configuration_attributes': {
'CharacterSet': '2', # Use Multi-byte Character Set.
},
},
},
}], }],
# TODO(andrew): Look into fixing this warning upstream: # TODO(andrew): Look into fixing this warning upstream:
# http://code.google.com/p/webrtc/issues/detail?id=760 # http://code.google.com/p/webrtc/issues/detail?id=760
['OS=="win" and clang==1', { ['OS=="win" and clang==1', {
'msvs_settings': { 'msvs_settings': {
'VCCLCompilerTool': { 'VCCLCompilerTool': {
'AdditionalOptions!': [
'-Wheader-hygiene', # Suppress warning about using namespace.
],
'AdditionalOptions': [ 'AdditionalOptions': [
'-Wno-unused-local-typedef', # Suppress unused private typedef. '-Wno-microsoft-include',
], ],
}, },
}, },
}], }],
['clang==1', { ['clang==1', {
'cflags': ['-Wno-unused-local-typedef',], 'cflags': [
'cflags!': ['-Wheader-hygiene',], '-Wno-microsoft-include',
'xcode_settings': { ],
'WARNING_CFLAGS': ['-Wno-unused-local-typedef',],
'WARNING_CFLAGS!': ['-Wheader-hygiene',],
},
}], }],
], ],
}, },
], ],
} }

View File

@ -10,12 +10,12 @@
#include <stdlib.h> #include <stdlib.h>
#include "libyuv/basic_types.h"
#include "libyuv/convert.h" #include "libyuv/convert.h"
#include "libyuv/convert_argb.h" #include "libyuv/convert_argb.h"
#include "libyuv/convert_from.h" #include "libyuv/convert_from.h"
#include "libyuv/convert_from_argb.h" #include "libyuv/convert_from_argb.h"
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/row.h" // For Sobel
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
namespace libyuv { namespace libyuv {
@ -41,15 +41,15 @@ namespace libyuv {
const int kPixels = benchmark_width_ * benchmark_height_; \ const int kPixels = benchmark_width_ * benchmark_height_; \
const int kHalfPixels = ((benchmark_width_ + 1) / 2) * \ const int kHalfPixels = ((benchmark_width_ + 1) / 2) * \
((benchmark_height_ + HS1) / HS); \ ((benchmark_height_ + HS1) / HS); \
align_buffer_64(orig_y, kPixels); \ align_buffer_page_end(orig_y, kPixels); \
align_buffer_64(orig_u, kHalfPixels); \ align_buffer_page_end(orig_u, kHalfPixels); \
align_buffer_64(orig_v, kHalfPixels); \ align_buffer_page_end(orig_v, kHalfPixels); \
align_buffer_64(orig_pixels, kPixels * 4); \ align_buffer_page_end(orig_pixels, kPixels * 4); \
align_buffer_64(temp_y, kPixels); \ align_buffer_page_end(temp_y, kPixels); \
align_buffer_64(temp_u, kHalfPixels); \ align_buffer_page_end(temp_u, kHalfPixels); \
align_buffer_64(temp_v, kHalfPixels); \ align_buffer_page_end(temp_v, kHalfPixels); \
align_buffer_64(dst_pixels_opt, kPixels * 4); \ align_buffer_page_end(dst_pixels_opt, kPixels * 4); \
align_buffer_64(dst_pixels_c, kPixels * 4); \ align_buffer_page_end(dst_pixels_c, kPixels * 4); \
\ \
MemRandomize(orig_pixels, kPixels * 4); \ MemRandomize(orig_pixels, kPixels * 4); \
MemRandomize(orig_y, kPixels); \ MemRandomize(orig_y, kPixels); \
@ -132,21 +132,21 @@ namespace libyuv {
static_cast<int>(dst_pixels_opt[i]), DIFF); \ static_cast<int>(dst_pixels_opt[i]), DIFF); \
} \ } \
\ \
free_aligned_buffer_64(orig_pixels); \ free_aligned_buffer_page_end(orig_pixels); \
free_aligned_buffer_64(orig_y); \ free_aligned_buffer_page_end(orig_y); \
free_aligned_buffer_64(orig_u); \ free_aligned_buffer_page_end(orig_u); \
free_aligned_buffer_64(orig_v); \ free_aligned_buffer_page_end(orig_v); \
free_aligned_buffer_64(temp_y); \ free_aligned_buffer_page_end(temp_y); \
free_aligned_buffer_64(temp_u); \ free_aligned_buffer_page_end(temp_u); \
free_aligned_buffer_64(temp_v); \ free_aligned_buffer_page_end(temp_v); \
free_aligned_buffer_64(dst_pixels_opt); \ free_aligned_buffer_page_end(dst_pixels_opt); \
free_aligned_buffer_64(dst_pixels_c); \ free_aligned_buffer_page_end(dst_pixels_c); \
} \ } \
TESTCS(TestI420, I420ToARGB, ARGBToI420, 1, 2, benchmark_width_, ERROR_FULL) TESTCS(TestI420, I420ToARGB, ARGBToI420, 1, 2, benchmark_width_, ERROR_FULL)
TESTCS(TestI422, I422ToARGB, ARGBToI422, 0, 1, 0, ERROR_FULL) TESTCS(TestI422, I422ToARGB, ARGBToI422, 0, 1, 0, ERROR_FULL)
TESTCS(TestJ420, J420ToARGB, ARGBToJ420, 1, 2, benchmark_width_, ERROR_J420) TESTCS(TestJ420, J420ToARGB, ARGBToJ420, 1, 2, benchmark_width_, ERROR_J420)
TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, 3) TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, ERROR_J420)
static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) { static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) {
const int kWidth = 16; const int kWidth = 16;

View File

@ -16,7 +16,6 @@
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
#include "libyuv/compare.h" #include "libyuv/compare.h"
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/row.h"
#include "libyuv/video_common.h" #include "libyuv/video_common.h"
namespace libyuv { namespace libyuv {
@ -34,8 +33,8 @@ static uint32 ReferenceHashDjb2(const uint8* src, uint64 count, uint32 seed) {
TEST_F(LibYUVBaseTest, Djb2_Test) { TEST_F(LibYUVBaseTest, Djb2_Test) {
const int kMaxTest = benchmark_width_ * benchmark_height_; const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest); align_buffer_page_end(src_a, kMaxTest);
align_buffer_64(src_b, kMaxTest); align_buffer_page_end(src_b, kMaxTest);
const char* fox = "The quick brown fox jumps over the lazy dog" const char* fox = "The quick brown fox jumps over the lazy dog"
" and feels as if he were in the seventh heaven of typography" " and feels as if he were in the seventh heaven of typography"
@ -112,13 +111,13 @@ TEST_F(LibYUVBaseTest, Djb2_Test) {
h2 = HashDjb2(src_a, kMaxTest / 2, 0); h2 = HashDjb2(src_a, kMaxTest / 2, 0);
EXPECT_EQ(h1, h2); EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, BenchmarkDjb2_Opt) { TEST_F(LibYUVBaseTest, BenchmarkDjb2_Opt) {
const int kMaxTest = benchmark_width_ * benchmark_height_; const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest); align_buffer_page_end(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) { for (int i = 0; i < kMaxTest; ++i) {
src_a[i] = i; src_a[i] = i;
@ -129,12 +128,12 @@ TEST_F(LibYUVBaseTest, BenchmarkDjb2_Opt) {
h1 = HashDjb2(src_a, kMaxTest, 5381); h1 = HashDjb2(src_a, kMaxTest, 5381);
} }
EXPECT_EQ(h1, h2); EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
} }
TEST_F(LibYUVBaseTest, BenchmarkDjb2_Unaligned) { TEST_F(LibYUVBaseTest, BenchmarkDjb2_Unaligned) {
const int kMaxTest = benchmark_width_ * benchmark_height_; const int kMaxTest = benchmark_width_ * benchmark_height_;
align_buffer_64(src_a, kMaxTest + 1); align_buffer_page_end(src_a, kMaxTest + 1);
for (int i = 0; i < kMaxTest; ++i) { for (int i = 0; i < kMaxTest; ++i) {
src_a[i + 1] = i; src_a[i + 1] = i;
} }
@ -144,13 +143,13 @@ TEST_F(LibYUVBaseTest, BenchmarkDjb2_Unaligned) {
h1 = HashDjb2(src_a + 1, kMaxTest, 5381); h1 = HashDjb2(src_a + 1, kMaxTest, 5381);
} }
EXPECT_EQ(h1, h2); EXPECT_EQ(h1, h2);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
} }
TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Opt) { TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Opt) {
uint32 fourcc; uint32 fourcc;
const int kMaxTest = benchmark_width_ * benchmark_height_ * 4; const int kMaxTest = benchmark_width_ * benchmark_height_ * 4;
align_buffer_64(src_a, kMaxTest); align_buffer_page_end(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) { for (int i = 0; i < kMaxTest; ++i) {
src_a[i] = 255; src_a[i] = 255;
} }
@ -172,15 +171,15 @@ TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Opt) {
} }
EXPECT_EQ(0, fourcc); EXPECT_EQ(0, fourcc);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
} }
TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Unaligned) { TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Unaligned) {
uint32 fourcc; uint32 fourcc;
const int kMaxTest = benchmark_width_ * benchmark_height_ * 4 + 1; const int kMaxTest = benchmark_width_ * benchmark_height_ * 4 + 1;
align_buffer_64(src_a, kMaxTest); align_buffer_page_end(src_a, kMaxTest);
for (int i = 0; i < kMaxTest; ++i) { for (int i = 1; i < kMaxTest; ++i) {
src_a[i + 1] = 255; src_a[i] = 255;
} }
src_a[0 + 1] = 0; src_a[0 + 1] = 0;
@ -200,12 +199,12 @@ TEST_F(LibYUVBaseTest, BenchmarkARGBDetect_Unaligned) {
} }
EXPECT_EQ(0, fourcc); EXPECT_EQ(0, fourcc);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
} }
TEST_F(LibYUVBaseTest, BenchmarkSumSquareError_Opt) { TEST_F(LibYUVBaseTest, BenchmarkSumSquareError_Opt) {
const int kMaxWidth = 4096 * 3; const int kMaxWidth = 4096 * 3;
align_buffer_64(src_a, kMaxWidth); align_buffer_page_end(src_a, kMaxWidth);
align_buffer_64(src_b, kMaxWidth); align_buffer_page_end(src_b, kMaxWidth);
memset(src_a, 0, kMaxWidth); memset(src_a, 0, kMaxWidth);
memset(src_b, 0, kMaxWidth); memset(src_b, 0, kMaxWidth);
@ -229,14 +228,14 @@ TEST_F(LibYUVBaseTest, BenchmarkSumSquareError_Opt) {
EXPECT_EQ(0, h1); EXPECT_EQ(0, h1);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, SumSquareError) { TEST_F(LibYUVBaseTest, SumSquareError) {
const int kMaxWidth = 4096 * 3; const int kMaxWidth = 4096 * 3;
align_buffer_64(src_a, kMaxWidth); align_buffer_page_end(src_a, kMaxWidth);
align_buffer_64(src_b, kMaxWidth); align_buffer_page_end(src_b, kMaxWidth);
memset(src_a, 0, kMaxWidth); memset(src_a, 0, kMaxWidth);
memset(src_b, 0, kMaxWidth); memset(src_b, 0, kMaxWidth);
@ -269,13 +268,13 @@ TEST_F(LibYUVBaseTest, SumSquareError) {
EXPECT_EQ(c_err, opt_err); EXPECT_EQ(c_err, opt_err);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, BenchmarkPsnr_Opt) { TEST_F(LibYUVBaseTest, BenchmarkPsnr_Opt) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_); align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_); align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) { for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i] = i; src_a[i] = i;
src_b[i] = i; src_b[i] = i;
@ -294,13 +293,13 @@ TEST_F(LibYUVBaseTest, BenchmarkPsnr_Opt) {
EXPECT_EQ(0, 0); EXPECT_EQ(0, 0);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, BenchmarkPsnr_Unaligned) { TEST_F(LibYUVBaseTest, BenchmarkPsnr_Unaligned) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_ + 1); align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_ + 1);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_); align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) { for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i + 1] = i; src_a[i + 1] = i;
src_b[i] = i; src_b[i] = i;
@ -319,8 +318,8 @@ TEST_F(LibYUVBaseTest, BenchmarkPsnr_Unaligned) {
EXPECT_EQ(0, 0); EXPECT_EQ(0, 0);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, Psnr) { TEST_F(LibYUVBaseTest, Psnr) {
@ -329,8 +328,8 @@ TEST_F(LibYUVBaseTest, Psnr) {
const int b = 128; const int b = 128;
const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2); const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
const int kSrcStride = 2 * b + kSrcWidth; const int kSrcStride = 2 * b + kSrcWidth;
align_buffer_64(src_a, kSrcPlaneSize); align_buffer_page_end(src_a, kSrcPlaneSize);
align_buffer_64(src_b, kSrcPlaneSize); align_buffer_page_end(src_b, kSrcPlaneSize);
memset(src_a, 0, kSrcPlaneSize); memset(src_a, 0, kSrcPlaneSize);
memset(src_b, 0, kSrcPlaneSize); memset(src_b, 0, kSrcPlaneSize);
@ -396,13 +395,13 @@ TEST_F(LibYUVBaseTest, Psnr) {
EXPECT_EQ(opt_err, c_err); EXPECT_EQ(opt_err, c_err);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, DISABLED_BenchmarkSsim_Opt) { TEST_F(LibYUVBaseTest, DISABLED_BenchmarkSsim_Opt) {
align_buffer_64(src_a, benchmark_width_ * benchmark_height_); align_buffer_page_end(src_a, benchmark_width_ * benchmark_height_);
align_buffer_64(src_b, benchmark_width_ * benchmark_height_); align_buffer_page_end(src_b, benchmark_width_ * benchmark_height_);
for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) { for (int i = 0; i < benchmark_width_ * benchmark_height_; ++i) {
src_a[i] = i; src_a[i] = i;
src_b[i] = i; src_b[i] = i;
@ -421,8 +420,8 @@ TEST_F(LibYUVBaseTest, DISABLED_BenchmarkSsim_Opt) {
EXPECT_EQ(0, 0); // Pass if we get this far. EXPECT_EQ(0, 0); // Pass if we get this far.
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
TEST_F(LibYUVBaseTest, Ssim) { TEST_F(LibYUVBaseTest, Ssim) {
@ -431,8 +430,8 @@ TEST_F(LibYUVBaseTest, Ssim) {
const int b = 128; const int b = 128;
const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2); const int kSrcPlaneSize = (kSrcWidth + b * 2) * (kSrcHeight + b * 2);
const int kSrcStride = 2 * b + kSrcWidth; const int kSrcStride = 2 * b + kSrcWidth;
align_buffer_64(src_a, kSrcPlaneSize); align_buffer_page_end(src_a, kSrcPlaneSize);
align_buffer_64(src_b, kSrcPlaneSize); align_buffer_page_end(src_b, kSrcPlaneSize);
memset(src_a, 0, kSrcPlaneSize); memset(src_a, 0, kSrcPlaneSize);
memset(src_b, 0, kSrcPlaneSize); memset(src_b, 0, kSrcPlaneSize);
@ -507,8 +506,8 @@ TEST_F(LibYUVBaseTest, Ssim) {
EXPECT_EQ(opt_err, c_err); EXPECT_EQ(opt_err, c_err);
} }
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(src_b); free_aligned_buffer_page_end(src_b);
} }
} // namespace libyuv } // namespace libyuv

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,6 @@
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/row.h" // For HAS_ARGBSHUFFLEROW_AVX2.
#include "libyuv/version.h" #include "libyuv/version.h"
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
@ -68,16 +67,9 @@ printf("_MSC_VER %d\n", _MSC_VER);
#if !defined(LIBYUV_DISABLE_X86) && (defined(GCC_HAS_AVX2) || \ #if !defined(LIBYUV_DISABLE_X86) && (defined(GCC_HAS_AVX2) || \
defined(CLANG_HAS_AVX2) || defined(VISUALC_HAS_AVX2)) defined(CLANG_HAS_AVX2) || defined(VISUALC_HAS_AVX2))
printf("Has AVX2 1\n"); printf("Has AVX2 1\n");
// If compiler supports AVX2, the following function is expected to exist:
#if !defined(HAS_ARGBSHUFFLEROW_AVX2)
EXPECT_TRUE(0); // HAS_ARGBSHUFFLEROW_AVX2 was expected.
#endif
#else #else
printf("Has AVX2 0\n"); printf("Has AVX2 0\n");
// If compiler does not support AVX2, the following function not expected: // If compiler does not support AVX2, the following function not expected:
#if defined(HAS_ARGBSHUFFLEROW_AVX2)
EXPECT_TRUE(0); // HAS_ARGBSHUFFLEROW_AVX2 was not expected.
#endif
#endif #endif
} }

View File

@ -14,7 +14,6 @@
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/row.h"
#include "libyuv/scale.h" #include "libyuv/scale.h"
#include "libyuv/scale_row.h" #include "libyuv/scale_row.h"
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"

View File

@ -19,17 +19,16 @@
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/planar_functions.h" #include "libyuv/planar_functions.h"
#include "libyuv/rotate.h" #include "libyuv/rotate.h"
#include "libyuv/row.h" // For Sobel
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
namespace libyuv { namespace libyuv {
TEST_F(LibYUVPlanarTest, TestAttenuate) { TEST_F(LibYUVPlanarTest, TestAttenuate) {
const int kSize = 1280 * 4; const int kSize = 1280 * 4;
align_buffer_64(orig_pixels, kSize); align_buffer_page_end(orig_pixels, kSize);
align_buffer_64(atten_pixels, kSize); align_buffer_page_end(atten_pixels, kSize);
align_buffer_64(unatten_pixels, kSize); align_buffer_page_end(unatten_pixels, kSize);
align_buffer_64(atten2_pixels, kSize); align_buffer_page_end(atten2_pixels, kSize);
// Test unattenuation clamps // Test unattenuation clamps
orig_pixels[0 * 4 + 0] = 200u; orig_pixels[0 * 4 + 0] = 200u;
@ -98,10 +97,10 @@ TEST_F(LibYUVPlanarTest, TestAttenuate) {
EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1); EXPECT_NEAR(85, atten_pixels[255 * 4 + 2], 1);
EXPECT_EQ(255, atten_pixels[255 * 4 + 3]); EXPECT_EQ(255, atten_pixels[255 * 4 + 3]);
free_aligned_buffer_64(atten2_pixels); free_aligned_buffer_page_end(atten2_pixels);
free_aligned_buffer_64(unatten_pixels); free_aligned_buffer_page_end(unatten_pixels);
free_aligned_buffer_64(atten_pixels); free_aligned_buffer_page_end(atten_pixels);
free_aligned_buffer_64(orig_pixels); free_aligned_buffer_page_end(orig_pixels);
} }
static int TestAttenuateI(int width, int height, int benchmark_iterations, static int TestAttenuateI(int width, int height, int benchmark_iterations,
@ -112,9 +111,9 @@ static int TestAttenuateI(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb, kStride * height + off); align_buffer_page_end(src_argb, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb[i + off] = (fastrand() & 0xff); src_argb[i + off] = (fastrand() & 0xff);
} }
@ -140,9 +139,9 @@ static int TestAttenuateI(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb); free_aligned_buffer_page_end(src_argb);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -186,9 +185,9 @@ static int TestUnattenuateI(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb, kStride * height + off); align_buffer_page_end(src_argb, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb[i + off] = (fastrand() & 0xff); src_argb[i + off] = (fastrand() & 0xff);
} }
@ -217,9 +216,9 @@ static int TestUnattenuateI(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb); free_aligned_buffer_page_end(src_argb);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1023,16 +1022,16 @@ TEST_F(LibYUVPlanarTest, TestInterpolatePlane) {
#define TESTTERP(FMT_A, BPP_A, STRIDE_A, \ #define TESTTERP(FMT_A, BPP_A, STRIDE_A, \
FMT_B, BPP_B, STRIDE_B, \ FMT_B, BPP_B, STRIDE_B, \
W1280, TERP, N, NEG, OFF) \ W1280, TERP, N, NEG, OFF) \
TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) { \ TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) { \
const int kWidth = ((W1280) > 0) ? (W1280) : 1; \ const int kWidth = ((W1280) > 0) ? (W1280) : 1; \
const int kHeight = benchmark_height_; \ const int kHeight = benchmark_height_; \
const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \ const int kStrideA = (kWidth * BPP_A + STRIDE_A - 1) / STRIDE_A * STRIDE_A; \
const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \ const int kStrideB = (kWidth * BPP_B + STRIDE_B - 1) / STRIDE_B * STRIDE_B; \
align_buffer_64(src_argb_a, kStrideA * kHeight + OFF); \ align_buffer_page_end(src_argb_a, kStrideA * kHeight + OFF); \
align_buffer_64(src_argb_b, kStrideA * kHeight + OFF); \ align_buffer_page_end(src_argb_b, kStrideA * kHeight + OFF); \
align_buffer_64(dst_argb_c, kStrideB * kHeight); \ align_buffer_page_end(dst_argb_c, kStrideB * kHeight); \
align_buffer_64(dst_argb_opt, kStrideB * kHeight); \ align_buffer_page_end(dst_argb_opt, kStrideB * kHeight); \
for (int i = 0; i < kStrideA * kHeight; ++i) { \ for (int i = 0; i < kStrideA * kHeight; ++i) { \
src_argb_a[i + OFF] = (fastrand() & 0xff); \ src_argb_a[i + OFF] = (fastrand() & 0xff); \
src_argb_b[i + OFF] = (fastrand() & 0xff); \ src_argb_b[i + OFF] = (fastrand() & 0xff); \
@ -1052,10 +1051,10 @@ TEST_F(LibYUVPlanarTest, ARGBInterpolate##TERP##N) { \
for (int i = 0; i < kStrideB * kHeight; ++i) { \ for (int i = 0; i < kStrideB * kHeight; ++i) { \
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \ EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); \
} \ } \
free_aligned_buffer_64(src_argb_a); \ free_aligned_buffer_page_end(src_argb_a); \
free_aligned_buffer_64(src_argb_b); \ free_aligned_buffer_page_end(src_argb_b); \
free_aligned_buffer_64(dst_argb_c); \ free_aligned_buffer_page_end(dst_argb_c); \
free_aligned_buffer_64(dst_argb_opt); \ free_aligned_buffer_page_end(dst_argb_opt); \
} }
#define TESTINTERPOLATE(TERP) \ #define TESTINTERPOLATE(TERP) \
@ -1078,10 +1077,10 @@ static int TestBlend(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off); align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff); src_argb_b[i + off] = (fastrand() & 0xff);
@ -1114,10 +1113,10 @@ static int TestBlend(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(src_argb_b); free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1157,11 +1156,11 @@ static void TestBlendPlane(int width, int height, int benchmark_iterations,
} }
const int kBpp = 1; const int kBpp = 1;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off); align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_64(src_argb_alpha, kStride * height + off); align_buffer_page_end(src_argb_alpha, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height + off); align_buffer_page_end(dst_argb_c, kStride * height + off);
align_buffer_64(dst_argb_opt, kStride * height + off); align_buffer_page_end(dst_argb_opt, kStride * height + off);
memset(dst_argb_c, 255, kStride * height + off); memset(dst_argb_c, 255, kStride * height + off);
memset(dst_argb_opt, 255, kStride * height + off); memset(dst_argb_opt, 255, kStride * height + off);
@ -1212,11 +1211,11 @@ static void TestBlendPlane(int width, int height, int benchmark_iterations,
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
EXPECT_EQ(dst_argb_c[i + off], dst_argb_opt[i + off]); EXPECT_EQ(dst_argb_c[i + off], dst_argb_opt[i + off]);
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(src_argb_b); free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_64(src_argb_alpha); free_aligned_buffer_page_end(src_argb_alpha);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return; return;
} }
@ -1245,19 +1244,19 @@ static void TestI420Blend(int width, int height, int benchmark_iterations,
width = ((width) > 0) ? (width) : 1; width = ((width) > 0) ? (width) : 1;
const int kStrideUV = SUBSAMPLE(width, 2); const int kStrideUV = SUBSAMPLE(width, 2);
const int kSizeUV = kStrideUV * SUBSAMPLE(height, 2); const int kSizeUV = kStrideUV * SUBSAMPLE(height, 2);
align_buffer_64(src_y0, width * height + off); align_buffer_page_end(src_y0, width * height + off);
align_buffer_64(src_u0, kSizeUV + off); align_buffer_page_end(src_u0, kSizeUV + off);
align_buffer_64(src_v0, kSizeUV + off); align_buffer_page_end(src_v0, kSizeUV + off);
align_buffer_64(src_y1, width * height + off); align_buffer_page_end(src_y1, width * height + off);
align_buffer_64(src_u1, kSizeUV + off); align_buffer_page_end(src_u1, kSizeUV + off);
align_buffer_64(src_v1, kSizeUV + off); align_buffer_page_end(src_v1, kSizeUV + off);
align_buffer_64(src_a, width * height + off); align_buffer_page_end(src_a, width * height + off);
align_buffer_64(dst_y_c, width * height + off); align_buffer_page_end(dst_y_c, width * height + off);
align_buffer_64(dst_u_c, kSizeUV + off); align_buffer_page_end(dst_u_c, kSizeUV + off);
align_buffer_64(dst_v_c, kSizeUV + off); align_buffer_page_end(dst_v_c, kSizeUV + off);
align_buffer_64(dst_y_opt, width * height + off); align_buffer_page_end(dst_y_opt, width * height + off);
align_buffer_64(dst_u_opt, kSizeUV + off); align_buffer_page_end(dst_u_opt, kSizeUV + off);
align_buffer_64(dst_v_opt, kSizeUV + off); align_buffer_page_end(dst_v_opt, kSizeUV + off);
MemRandomize(src_y0, width * height + off); MemRandomize(src_y0, width * height + off);
MemRandomize(src_u0, kSizeUV + off); MemRandomize(src_u0, kSizeUV + off);
@ -1306,19 +1305,19 @@ static void TestI420Blend(int width, int height, int benchmark_iterations,
EXPECT_EQ(dst_u_c[i + off], dst_u_opt[i + off]); EXPECT_EQ(dst_u_c[i + off], dst_u_opt[i + off]);
EXPECT_EQ(dst_v_c[i + off], dst_v_opt[i + off]); EXPECT_EQ(dst_v_c[i + off], dst_v_opt[i + off]);
} }
free_aligned_buffer_64(src_y0); free_aligned_buffer_page_end(src_y0);
free_aligned_buffer_64(src_u0); free_aligned_buffer_page_end(src_u0);
free_aligned_buffer_64(src_v0); free_aligned_buffer_page_end(src_v0);
free_aligned_buffer_64(src_y1); free_aligned_buffer_page_end(src_y1);
free_aligned_buffer_64(src_u1); free_aligned_buffer_page_end(src_u1);
free_aligned_buffer_64(src_v1); free_aligned_buffer_page_end(src_v1);
free_aligned_buffer_64(src_a); free_aligned_buffer_page_end(src_a);
free_aligned_buffer_64(dst_y_c); free_aligned_buffer_page_end(dst_y_c);
free_aligned_buffer_64(dst_u_c); free_aligned_buffer_page_end(dst_u_c);
free_aligned_buffer_64(dst_v_c); free_aligned_buffer_page_end(dst_v_c);
free_aligned_buffer_64(dst_y_opt); free_aligned_buffer_page_end(dst_y_opt);
free_aligned_buffer_64(dst_u_opt); free_aligned_buffer_page_end(dst_u_opt);
free_aligned_buffer_64(dst_v_opt); free_aligned_buffer_page_end(dst_v_opt);
return; return;
} }
@ -1375,206 +1374,6 @@ TEST_F(LibYUVPlanarTest, TestAffine) {
#endif #endif
} }
TEST_F(LibYUVPlanarTest, TestSobelX) {
SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_2[1280 + 2]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280 + 2; ++i) {
orig_pixels_0[i] = i;
orig_pixels_1[i] = i * 2;
orig_pixels_2[i] = i * 3;
}
SobelXRow_C(orig_pixels_0, orig_pixels_1, orig_pixels_2,
sobel_pixels_c, 1280);
EXPECT_EQ(16u, sobel_pixels_c[0]);
EXPECT_EQ(16u, sobel_pixels_c[100]);
EXPECT_EQ(255u, sobel_pixels_c[255]);
void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1,
const uint8* src_y2, uint8* dst_sobely, int width) =
SobelXRow_C;
#if defined(HAS_SOBELXROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelXRow = SobelXRow_SSE2;
}
#endif
#if defined(HAS_SOBELXROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelXRow = SobelXRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelXRow(orig_pixels_0, orig_pixels_1, orig_pixels_2,
sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelY) {
SIMD_ALIGNED(uint8 orig_pixels_0[1280 + 2]);
SIMD_ALIGNED(uint8 orig_pixels_1[1280 + 2]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280 + 2; ++i) {
orig_pixels_0[i] = i;
orig_pixels_1[i] = i * 2;
}
SobelYRow_C(orig_pixels_0, orig_pixels_1, sobel_pixels_c, 1280);
EXPECT_EQ(4u, sobel_pixels_c[0]);
EXPECT_EQ(255u, sobel_pixels_c[100]);
EXPECT_EQ(0u, sobel_pixels_c[255]);
void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1,
uint8* dst_sobely, int width) = SobelYRow_C;
#if defined(HAS_SOBELYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelYRow = SobelYRow_SSE2;
}
#endif
#if defined(HAS_SOBELYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelYRow = SobelYRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelYRow(orig_pixels_0, orig_pixels_1, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobel) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(3u, sobel_pixels_c[4]);
EXPECT_EQ(3u, sobel_pixels_c[5]);
EXPECT_EQ(3u, sobel_pixels_c[6]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(6u, sobel_pixels_c[8]);
EXPECT_EQ(6u, sobel_pixels_c[9]);
EXPECT_EQ(6u, sobel_pixels_c[10]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]);
EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]);
void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) = SobelRow_C;
#if defined(HAS_SOBELROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelRow = SobelRow_SSE2;
}
#endif
#if defined(HAS_SOBELROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelRow = SobelRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280 * 4; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelToPlane) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelToPlaneRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(3u, sobel_pixels_c[1]);
EXPECT_EQ(6u, sobel_pixels_c[2]);
EXPECT_EQ(99u, sobel_pixels_c[33]);
EXPECT_EQ(255u, sobel_pixels_c[100]);
void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_y, int width) = SobelToPlaneRow_C;
#if defined(HAS_SOBELTOPLANEROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelToPlaneRow = SobelToPlaneRow_SSE2;
}
#endif
#if defined(HAS_SOBELTOPLANEROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelToPlaneRow = SobelToPlaneRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelToPlaneRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestSobelXY) {
SIMD_ALIGNED(uint8 orig_sobelx[1280]);
SIMD_ALIGNED(uint8 orig_sobely[1280]);
SIMD_ALIGNED(uint8 sobel_pixels_c[1280 * 4]);
SIMD_ALIGNED(uint8 sobel_pixels_opt[1280 * 4]);
for (int i = 0; i < 1280; ++i) {
orig_sobelx[i] = i;
orig_sobely[i] = i * 2;
}
SobelXYRow_C(orig_sobelx, orig_sobely, sobel_pixels_c, 1280);
EXPECT_EQ(0u, sobel_pixels_c[0]);
EXPECT_EQ(2u, sobel_pixels_c[4]);
EXPECT_EQ(3u, sobel_pixels_c[5]);
EXPECT_EQ(1u, sobel_pixels_c[6]);
EXPECT_EQ(255u, sobel_pixels_c[7]);
EXPECT_EQ(255u, sobel_pixels_c[100 * 4 + 1]);
EXPECT_EQ(255u, sobel_pixels_c[255 * 4 + 1]);
void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely,
uint8* dst_argb, int width) = SobelXYRow_C;
#if defined(HAS_SOBELXYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
SobelXYRow = SobelXYRow_SSE2;
}
#endif
#if defined(HAS_SOBELXYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
SobelXYRow = SobelXYRow_NEON;
}
#endif
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
SobelXYRow(orig_sobelx, orig_sobely, sobel_pixels_opt, 1280);
}
for (int i = 0; i < 1280 * 4; ++i) {
EXPECT_EQ(sobel_pixels_c[i], sobel_pixels_opt[i]);
}
}
TEST_F(LibYUVPlanarTest, TestCopyPlane) { TEST_F(LibYUVPlanarTest, TestCopyPlane) {
int err = 0; int err = 0;
int yw = benchmark_width_; int yw = benchmark_width_;
@ -1583,9 +1382,9 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) {
int i, j; int i, j;
int y_plane_size = (yw + b * 2) * (yh + b * 2); int y_plane_size = (yw + b * 2) * (yh + b * 2);
align_buffer_64(orig_y, y_plane_size); align_buffer_page_end(orig_y, y_plane_size);
align_buffer_64(dst_c, y_plane_size); align_buffer_page_end(dst_c, y_plane_size);
align_buffer_64(dst_opt, y_plane_size); align_buffer_page_end(dst_opt, y_plane_size);
memset(orig_y, 0, y_plane_size); memset(orig_y, 0, y_plane_size);
memset(dst_c, 0, y_plane_size); memset(dst_c, 0, y_plane_size);
@ -1631,9 +1430,9 @@ TEST_F(LibYUVPlanarTest, TestCopyPlane) {
++err; ++err;
} }
free_aligned_buffer_64(orig_y); free_aligned_buffer_page_end(orig_y);
free_aligned_buffer_64(dst_c); free_aligned_buffer_page_end(dst_c);
free_aligned_buffer_64(dst_opt); free_aligned_buffer_page_end(dst_opt);
EXPECT_EQ(0, err); EXPECT_EQ(0, err);
} }
@ -1646,10 +1445,10 @@ static int TestMultiply(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off); align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff); src_argb_b[i + off] = (fastrand() & 0xff);
@ -1678,10 +1477,10 @@ static int TestMultiply(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(src_argb_b); free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1721,10 +1520,10 @@ static int TestAdd(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off); align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff); src_argb_b[i + off] = (fastrand() & 0xff);
@ -1753,10 +1552,10 @@ static int TestAdd(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(src_argb_b); free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1796,10 +1595,10 @@ static int TestSubtract(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(src_argb_b, kStride * height + off); align_buffer_page_end(src_argb_b, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
src_argb_b[i + off] = (fastrand() & 0xff); src_argb_b[i + off] = (fastrand() & 0xff);
@ -1828,10 +1627,10 @@ static int TestSubtract(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(src_argb_b); free_aligned_buffer_page_end(src_argb_b);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1871,9 +1670,9 @@ static int TestSobel(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
memset(src_argb_a, 0, kStride * height + off); memset(src_argb_a, 0, kStride * height + off);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
@ -1900,9 +1699,9 @@ static int TestSobel(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -1944,9 +1743,9 @@ static int TestSobelToPlane(int width, int height, int benchmark_iterations,
const int kDstBpp = 1; const int kDstBpp = 1;
const int kSrcStride = (width * kSrcBpp + 15) & ~15; const int kSrcStride = (width * kSrcBpp + 15) & ~15;
const int kDstStride = (width * kDstBpp + 15) & ~15; const int kDstStride = (width * kDstBpp + 15) & ~15;
align_buffer_64(src_argb_a, kSrcStride * height + off); align_buffer_page_end(src_argb_a, kSrcStride * height + off);
align_buffer_64(dst_argb_c, kDstStride * height); align_buffer_page_end(dst_argb_c, kDstStride * height);
align_buffer_64(dst_argb_opt, kDstStride * height); align_buffer_page_end(dst_argb_opt, kDstStride * height);
memset(src_argb_a, 0, kSrcStride * height + off); memset(src_argb_a, 0, kSrcStride * height + off);
for (int i = 0; i < kSrcStride * height; ++i) { for (int i = 0; i < kSrcStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
@ -1973,9 +1772,9 @@ static int TestSobelToPlane(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -2019,9 +1818,9 @@ static int TestSobelXY(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
memset(src_argb_a, 0, kStride * height + off); memset(src_argb_a, 0, kStride * height + off);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
@ -2048,9 +1847,9 @@ static int TestSobelXY(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -2090,10 +1889,10 @@ static int TestBlur(int width, int height, int benchmark_iterations,
} }
const int kBpp = 4; const int kBpp = 4;
const int kStride = width * kBpp; const int kStride = width * kBpp;
align_buffer_64(src_argb_a, kStride * height + off); align_buffer_page_end(src_argb_a, kStride * height + off);
align_buffer_64(dst_cumsum, width * height * 16); align_buffer_page_end(dst_cumsum, width * height * 16);
align_buffer_64(dst_argb_c, kStride * height); align_buffer_page_end(dst_argb_c, kStride * height);
align_buffer_64(dst_argb_opt, kStride * height); align_buffer_page_end(dst_argb_opt, kStride * height);
for (int i = 0; i < kStride * height; ++i) { for (int i = 0; i < kStride * height; ++i) {
src_argb_a[i + off] = (fastrand() & 0xff); src_argb_a[i + off] = (fastrand() & 0xff);
} }
@ -2122,10 +1921,10 @@ static int TestBlur(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(src_argb_a); free_aligned_buffer_page_end(src_argb_a);
free_aligned_buffer_64(dst_cumsum); free_aligned_buffer_page_end(dst_cumsum);
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -2288,7 +2087,7 @@ TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) {
SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]); SIMD_ALIGNED(uint8 dst_pixels_c[1280][4]);
memset(orig_pixels, 0, sizeof(orig_pixels)); memset(orig_pixels, 0, sizeof(orig_pixels));
align_buffer_64(lumacolortable, 32768); align_buffer_page_end(lumacolortable, 32768);
int v = 0; int v = 0;
for (int i = 0; i < 32768; ++i) { for (int i = 0; i < 32768; ++i) {
lumacolortable[i] = v; lumacolortable[i] = v;
@ -2357,14 +2156,14 @@ TEST_F(LibYUVPlanarTest, TestARGBLumaColorTable) {
EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]); EXPECT_EQ(dst_pixels_c[i][3], dst_pixels_opt[i][3]);
} }
free_aligned_buffer_64(lumacolortable); free_aligned_buffer_page_end(lumacolortable);
} }
TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) { TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) {
const int kSize = benchmark_width_ * benchmark_height_ * 4; const int kSize = benchmark_width_ * benchmark_height_ * 4;
align_buffer_64(orig_pixels, kSize); align_buffer_page_end(orig_pixels, kSize);
align_buffer_64(dst_pixels_opt, kSize); align_buffer_page_end(dst_pixels_opt, kSize);
align_buffer_64(dst_pixels_c, kSize); align_buffer_page_end(dst_pixels_c, kSize);
MemRandomize(orig_pixels, kSize); MemRandomize(orig_pixels, kSize);
MemRandomize(dst_pixels_opt, kSize); MemRandomize(dst_pixels_opt, kSize);
@ -2385,16 +2184,46 @@ TEST_F(LibYUVPlanarTest, TestARGBCopyAlpha) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
} }
free_aligned_buffer_64(dst_pixels_c); free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_64(dst_pixels_opt); free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_64(orig_pixels); free_aligned_buffer_page_end(orig_pixels);
}
TEST_F(LibYUVPlanarTest, TestARGBExtractAlpha) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 4);
align_buffer_page_end(dst_pixels_opt, kPixels);
align_buffer_page_end(dst_pixels_c, kPixels);
MemRandomize(src_pixels, kPixels * 4);
MemRandomize(dst_pixels_opt, kPixels);
memcpy(dst_pixels_c, dst_pixels_opt, kPixels);
MaskCpuFlags(disable_cpu_flags_);
ARGBExtractAlpha(src_pixels, benchmark_width_ * 4,
dst_pixels_c, benchmark_width_,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
for (int i = 0; i < benchmark_iterations_; ++i) {
ARGBExtractAlpha(src_pixels, benchmark_width_ * 4,
dst_pixels_opt, benchmark_width_,
benchmark_width_, benchmark_height_);
}
for (int i = 0; i < kPixels; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(src_pixels);
} }
TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) { TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) {
const int kPixels = benchmark_width_ * benchmark_height_; const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_64(orig_pixels, kPixels); align_buffer_page_end(orig_pixels, kPixels);
align_buffer_64(dst_pixels_opt, kPixels * 4); align_buffer_page_end(dst_pixels_opt, kPixels * 4);
align_buffer_64(dst_pixels_c, kPixels * 4); align_buffer_page_end(dst_pixels_c, kPixels * 4);
MemRandomize(orig_pixels, kPixels); MemRandomize(orig_pixels, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 4); MemRandomize(dst_pixels_opt, kPixels * 4);
@ -2415,9 +2244,9 @@ TEST_F(LibYUVPlanarTest, TestARGBCopyYToAlpha) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]); EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
} }
free_aligned_buffer_64(dst_pixels_c); free_aligned_buffer_page_end(dst_pixels_c);
free_aligned_buffer_64(dst_pixels_opt); free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_64(orig_pixels); free_aligned_buffer_page_end(orig_pixels);
} }
static int TestARGBRect(int width, int height, int benchmark_iterations, static int TestARGBRect(int width, int height, int benchmark_iterations,
@ -2430,8 +2259,8 @@ static int TestARGBRect(int width, int height, int benchmark_iterations,
const int kSize = kStride * height; const int kSize = kStride * height;
const uint32 v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff); const uint32 v32 = fastrand() & (bpp == 4 ? 0xffffffff : 0xff);
align_buffer_64(dst_argb_c, kSize + off); align_buffer_page_end(dst_argb_c, kSize + off);
align_buffer_64(dst_argb_opt, kSize + off); align_buffer_page_end(dst_argb_opt, kSize + off);
MemRandomize(dst_argb_c + off, kSize); MemRandomize(dst_argb_c + off, kSize);
memcpy(dst_argb_opt + off, dst_argb_c + off, kSize); memcpy(dst_argb_opt + off, dst_argb_c + off, kSize);
@ -2460,8 +2289,8 @@ static int TestARGBRect(int width, int height, int benchmark_iterations,
max_diff = abs_diff; max_diff = abs_diff;
} }
} }
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
return max_diff; return max_diff;
} }
@ -2529,4 +2358,99 @@ TEST_F(LibYUVPlanarTest, SetPlane_Opt) {
EXPECT_EQ(0, max_diff); EXPECT_EQ(0, max_diff);
} }
TEST_F(LibYUVPlanarTest, MergeUVPlane_Opt) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 2);
align_buffer_page_end(tmp_pixels_u, kPixels);
align_buffer_page_end(tmp_pixels_v, kPixels);
align_buffer_page_end(dst_pixels_opt, kPixels * 2);
align_buffer_page_end(dst_pixels_c, kPixels * 2);
MemRandomize(src_pixels, kPixels * 2);
MemRandomize(tmp_pixels_u, kPixels);
MemRandomize(tmp_pixels_v, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 2);
MemRandomize(dst_pixels_c, kPixels * 2);
MaskCpuFlags(disable_cpu_flags_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_c, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
for (int i = 0; i < benchmark_iterations_; ++i) {
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_opt, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
}
for (int i = 0; i < kPixels * 2; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(src_pixels);
free_aligned_buffer_page_end(tmp_pixels_u);
free_aligned_buffer_page_end(tmp_pixels_v);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(dst_pixels_c);
}
TEST_F(LibYUVPlanarTest, SplitUVPlane_Opt) {
const int kPixels = benchmark_width_ * benchmark_height_;
align_buffer_page_end(src_pixels, kPixels * 2);
align_buffer_page_end(tmp_pixels_u, kPixels);
align_buffer_page_end(tmp_pixels_v, kPixels);
align_buffer_page_end(dst_pixels_opt, kPixels * 2);
align_buffer_page_end(dst_pixels_c, kPixels * 2);
MemRandomize(src_pixels, kPixels * 2);
MemRandomize(tmp_pixels_u, kPixels);
MemRandomize(tmp_pixels_v, kPixels);
MemRandomize(dst_pixels_opt, kPixels * 2);
MemRandomize(dst_pixels_c, kPixels * 2);
MaskCpuFlags(disable_cpu_flags_);
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_c, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
MaskCpuFlags(benchmark_cpu_info_);
for (int i = 0; i < benchmark_iterations_; ++i) {
SplitUVPlane(src_pixels, benchmark_width_ * 2,
tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
benchmark_width_, benchmark_height_);
}
MergeUVPlane(tmp_pixels_u, benchmark_width_,
tmp_pixels_v, benchmark_width_,
dst_pixels_opt, benchmark_width_ * 2,
benchmark_width_, benchmark_height_);
for (int i = 0; i < kPixels * 2; ++i) {
EXPECT_EQ(dst_pixels_c[i], dst_pixels_opt[i]);
}
free_aligned_buffer_page_end(src_pixels);
free_aligned_buffer_page_end(tmp_pixels_u);
free_aligned_buffer_page_end(tmp_pixels_v);
free_aligned_buffer_page_end(dst_pixels_opt);
free_aligned_buffer_page_end(dst_pixels_c);
}
} // namespace libyuv } // namespace libyuv

View File

@ -12,7 +12,6 @@
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/rotate_argb.h" #include "libyuv/rotate_argb.h"
#include "libyuv/row.h"
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
namespace libyuv { namespace libyuv {
@ -38,15 +37,15 @@ void TestRotateBpp(int src_width, int src_height,
} }
int src_stride_argb = src_width * kBpp; int src_stride_argb = src_width * kBpp;
int src_argb_plane_size = src_stride_argb * abs(src_height); int src_argb_plane_size = src_stride_argb * abs(src_height);
align_buffer_64(src_argb, src_argb_plane_size); align_buffer_page_end(src_argb, src_argb_plane_size);
for (int i = 0; i < src_argb_plane_size; ++i) { for (int i = 0; i < src_argb_plane_size; ++i) {
src_argb[i] = fastrand() & 0xff; src_argb[i] = fastrand() & 0xff;
} }
int dst_stride_argb = dst_width * kBpp; int dst_stride_argb = dst_width * kBpp;
int dst_argb_plane_size = dst_stride_argb * dst_height; int dst_argb_plane_size = dst_stride_argb * dst_height;
align_buffer_64(dst_argb_c, dst_argb_plane_size); align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
align_buffer_64(dst_argb_opt, dst_argb_plane_size); align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
memset(dst_argb_c, 2, dst_argb_plane_size); memset(dst_argb_c, 2, dst_argb_plane_size);
memset(dst_argb_opt, 3, dst_argb_plane_size); memset(dst_argb_opt, 3, dst_argb_plane_size);
@ -81,9 +80,9 @@ void TestRotateBpp(int src_width, int src_height,
EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]); EXPECT_EQ(dst_argb_c[i], dst_argb_opt[i]);
} }
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
free_aligned_buffer_64(src_argb); free_aligned_buffer_page_end(src_argb);
} }
static void ARGBTestRotate(int src_width, int src_height, static void ARGBTestRotate(int src_width, int src_height,

View File

@ -12,7 +12,6 @@
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/rotate.h" #include "libyuv/rotate.h"
#include "libyuv/row.h"
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
namespace libyuv { namespace libyuv {
@ -37,7 +36,7 @@ static void I420TestRotate(int src_width, int src_height,
int src_i420_y_size = src_width * Abs(src_height); int src_i420_y_size = src_width * Abs(src_height);
int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2); int src_i420_uv_size = ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2);
int src_i420_size = src_i420_y_size + src_i420_uv_size * 2; int src_i420_size = src_i420_y_size + src_i420_uv_size * 2;
align_buffer_64(src_i420, src_i420_size); align_buffer_page_end(src_i420, src_i420_size);
for (int i = 0; i < src_i420_size; ++i) { for (int i = 0; i < src_i420_size; ++i) {
src_i420[i] = fastrand() & 0xff; src_i420[i] = fastrand() & 0xff;
} }
@ -45,8 +44,8 @@ static void I420TestRotate(int src_width, int src_height,
int dst_i420_y_size = dst_width * dst_height; int dst_i420_y_size = dst_width * dst_height;
int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2); int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2; int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
align_buffer_64(dst_i420_c, dst_i420_size); align_buffer_page_end(dst_i420_c, dst_i420_size);
align_buffer_64(dst_i420_opt, dst_i420_size); align_buffer_page_end(dst_i420_opt, dst_i420_size);
memset(dst_i420_c, 2, dst_i420_size); memset(dst_i420_c, 2, dst_i420_size);
memset(dst_i420_opt, 3, dst_i420_size); memset(dst_i420_opt, 3, dst_i420_size);
@ -78,9 +77,9 @@ static void I420TestRotate(int src_width, int src_height,
EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]); EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
} }
free_aligned_buffer_64(dst_i420_c); free_aligned_buffer_page_end(dst_i420_c);
free_aligned_buffer_64(dst_i420_opt); free_aligned_buffer_page_end(dst_i420_opt);
free_aligned_buffer_64(src_i420); free_aligned_buffer_page_end(src_i420);
} }
TEST_F(LibYUVRotateTest, I420Rotate0_Opt) { TEST_F(LibYUVRotateTest, I420Rotate0_Opt) {
@ -163,7 +162,7 @@ static void NV12TestRotate(int src_width, int src_height,
int src_nv12_uv_size = int src_nv12_uv_size =
((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2; ((src_width + 1) / 2) * ((Abs(src_height) + 1) / 2) * 2;
int src_nv12_size = src_nv12_y_size + src_nv12_uv_size; int src_nv12_size = src_nv12_y_size + src_nv12_uv_size;
align_buffer_64(src_nv12, src_nv12_size); align_buffer_page_end(src_nv12, src_nv12_size);
for (int i = 0; i < src_nv12_size; ++i) { for (int i = 0; i < src_nv12_size; ++i) {
src_nv12[i] = fastrand() & 0xff; src_nv12[i] = fastrand() & 0xff;
} }
@ -171,8 +170,8 @@ static void NV12TestRotate(int src_width, int src_height,
int dst_i420_y_size = dst_width * dst_height; int dst_i420_y_size = dst_width * dst_height;
int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2); int dst_i420_uv_size = ((dst_width + 1) / 2) * ((dst_height + 1) / 2);
int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2; int dst_i420_size = dst_i420_y_size + dst_i420_uv_size * 2;
align_buffer_64(dst_i420_c, dst_i420_size); align_buffer_page_end(dst_i420_c, dst_i420_size);
align_buffer_64(dst_i420_opt, dst_i420_size); align_buffer_page_end(dst_i420_opt, dst_i420_size);
memset(dst_i420_c, 2, dst_i420_size); memset(dst_i420_c, 2, dst_i420_size);
memset(dst_i420_opt, 3, dst_i420_size); memset(dst_i420_opt, 3, dst_i420_size);
@ -201,9 +200,9 @@ static void NV12TestRotate(int src_width, int src_height,
EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]); EXPECT_EQ(dst_i420_c[i], dst_i420_opt[i]);
} }
free_aligned_buffer_64(dst_i420_c); free_aligned_buffer_page_end(dst_i420_c);
free_aligned_buffer_64(dst_i420_opt); free_aligned_buffer_page_end(dst_i420_opt);
free_aligned_buffer_64(src_nv12); free_aligned_buffer_page_end(src_nv12);
} }
TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) { TEST_F(LibYUVRotateTest, NV12Rotate0_Opt) {

View File

@ -11,10 +11,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include "libyuv/convert_argb.h"
#include "libyuv/cpu_id.h" #include "libyuv/cpu_id.h"
#include "libyuv/convert.h"
#include "libyuv/scale_argb.h" #include "libyuv/scale_argb.h"
#include "libyuv/row.h"
#include "libyuv/video_common.h" #include "libyuv/video_common.h"
#include "../unit_test/unit_test.h" #include "../unit_test/unit_test.h"
@ -28,6 +27,10 @@ static int ARGBTestFilter(int src_width, int src_height,
int dst_width, int dst_height, int dst_width, int dst_height,
FilterMode f, int benchmark_iterations, FilterMode f, int benchmark_iterations,
int disable_cpu_flags, int benchmark_cpu_info) { int disable_cpu_flags, int benchmark_cpu_info) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j; int i, j;
const int b = 0; // 128 to test for padding/stride. const int b = 0; // 128 to test for padding/stride.
int64 src_argb_plane_size = (Abs(src_width) + b * 2) * int64 src_argb_plane_size = (Abs(src_width) + b * 2) *
@ -143,12 +146,16 @@ static int TileARGBScale(const uint8* src_argb, int src_stride_argb,
static int ARGBClipTestFilter(int src_width, int src_height, static int ARGBClipTestFilter(int src_width, int src_height,
int dst_width, int dst_height, int dst_width, int dst_height,
FilterMode f, int benchmark_iterations) { FilterMode f, int benchmark_iterations) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
const int b = 128; const int b = 128;
int64 src_argb_plane_size = (Abs(src_width) + b * 2) * int64 src_argb_plane_size = (Abs(src_width) + b * 2) *
(Abs(src_height) + b * 2) * 4; (Abs(src_height) + b * 2) * 4;
int src_stride_argb = (b * 2 + Abs(src_width)) * 4; int src_stride_argb = (b * 2 + Abs(src_width)) * 4;
align_buffer_64(src_argb, src_argb_plane_size); align_buffer_page_end(src_argb, src_argb_plane_size);
if (!src_argb) { if (!src_argb) {
printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
return 0; return 0;
@ -165,8 +172,8 @@ static int ARGBClipTestFilter(int src_width, int src_height,
} }
} }
align_buffer_64(dst_argb_c, dst_argb_plane_size); align_buffer_page_end(dst_argb_c, dst_argb_plane_size);
align_buffer_64(dst_argb_opt, dst_argb_plane_size); align_buffer_page_end(dst_argb_opt, dst_argb_plane_size);
if (!dst_argb_c || !dst_argb_opt) { if (!dst_argb_c || !dst_argb_opt) {
printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n"); printf("Skipped. Alloc failed " FILELINESTR(__FILE__, __LINE__) "\n");
return 0; return 0;
@ -208,9 +215,9 @@ static int ARGBClipTestFilter(int src_width, int src_height,
} }
} }
free_aligned_buffer_64(dst_argb_c); free_aligned_buffer_page_end(dst_argb_c);
free_aligned_buffer_64(dst_argb_opt); free_aligned_buffer_page_end(dst_argb_opt);
free_aligned_buffer_64(src_argb); free_aligned_buffer_page_end(src_argb);
return max_diff; return max_diff;
} }
@ -314,8 +321,7 @@ int YUVToARGBScaleReference2(const uint8* src_y, int src_stride_y,
int clip_x, int clip_y, int clip_x, int clip_y,
int clip_width, int clip_height, int clip_width, int clip_height,
enum FilterMode filtering) { enum FilterMode filtering) {
uint8* argb_buffer = static_cast<uint8*>(malloc(src_width * src_height * 4));
uint8* argb_buffer = (uint8*)malloc(src_width * src_height * 4);
int r; int r;
I420ToARGB(src_y, src_stride_y, I420ToARGB(src_y, src_stride_y,
src_u, src_stride_u, src_u, src_stride_u,

View File

@ -25,6 +25,10 @@ static int TestFilter(int src_width, int src_height,
int dst_width, int dst_height, int dst_width, int dst_height,
FilterMode f, int benchmark_iterations, FilterMode f, int benchmark_iterations,
int disable_cpu_flags, int benchmark_cpu_info) { int disable_cpu_flags, int benchmark_cpu_info) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j; int i, j;
const int b = 0; // 128 to test for padding/stride. const int b = 0; // 128 to test for padding/stride.
int src_width_uv = (Abs(src_width) + 1) >> 1; int src_width_uv = (Abs(src_width) + 1) >> 1;
@ -148,6 +152,10 @@ static int TestFilter(int src_width, int src_height,
static int TestFilter_16(int src_width, int src_height, static int TestFilter_16(int src_width, int src_height,
int dst_width, int dst_height, int dst_width, int dst_height,
FilterMode f, int benchmark_iterations) { FilterMode f, int benchmark_iterations) {
if (!SizeValid(src_width, src_height, dst_width, dst_height)) {
return 0;
}
int i, j; int i, j;
const int b = 0; // 128 to test for padding/stride. const int b = 0; // 128 to test for padding/stride.
int src_width_uv = (Abs(src_width) + 1) >> 1; int src_width_uv = (Abs(src_width) + 1) >> 1;
@ -274,8 +282,8 @@ static int TestFilter_16(int src_width, int src_height,
// The following adjustments in dimensions ensure the scale factor will be // The following adjustments in dimensions ensure the scale factor will be
// exactly achieved. // exactly achieved.
// 2 is chroma subsample // 2 is chroma subsample
#define DX(x, nom, denom) static_cast<int>((Abs(x) / nom / 2) * nom * 2) #define DX(x, nom, denom) static_cast<int>(((Abs(x) / nom + 1) / 2) * nom * 2)
#define SX(x, nom, denom) static_cast<int>((x / nom / 2) * denom * 2) #define SX(x, nom, denom) static_cast<int>(((x / nom + 1) / 2) * denom * 2)
#define TEST_FACTOR1(name, filter, nom, denom, max_diff) \ #define TEST_FACTOR1(name, filter, nom, denom, max_diff) \
TEST_F(LibYUVScaleTest, ScaleDownBy##name##_##filter) { \ TEST_F(LibYUVScaleTest, ScaleDownBy##name##_##filter) { \
@ -306,10 +314,10 @@ static int TestFilter_16(int src_width, int src_height,
TEST_FACTOR(2, 1, 2, 0) TEST_FACTOR(2, 1, 2, 0)
TEST_FACTOR(4, 1, 4, 0) TEST_FACTOR(4, 1, 4, 0)
TEST_FACTOR(8, 1, 8, 3) TEST_FACTOR(8, 1, 8, 0)
TEST_FACTOR(3by4, 3, 4, 1) TEST_FACTOR(3by4, 3, 4, 1)
TEST_FACTOR(3by8, 3, 8, 1) TEST_FACTOR(3by8, 3, 8, 1)
TEST_FACTOR(3, 1, 3, 3) TEST_FACTOR(3, 1, 3, 0)
#undef TEST_FACTOR1 #undef TEST_FACTOR1
#undef TEST_FACTOR #undef TEST_FACTOR
#undef SX #undef SX
@ -348,9 +356,9 @@ TEST_FACTOR(3, 1, 3, 3)
// Test scale to a specified size with all 4 filters. // Test scale to a specified size with all 4 filters.
#define TEST_SCALETO(name, width, height) \ #define TEST_SCALETO(name, width, height) \
TEST_SCALETO1(name, width, height, None, 0) \ TEST_SCALETO1(name, width, height, None, 0) \
TEST_SCALETO1(name, width, height, Linear, 3) \ TEST_SCALETO1(name, width, height, Linear, 0) \
TEST_SCALETO1(name, width, height, Bilinear, 3) \ TEST_SCALETO1(name, width, height, Bilinear, 0) \
TEST_SCALETO1(name, width, height, Box, 3) TEST_SCALETO1(name, width, height, Box, 0)
TEST_SCALETO(Scale, 1, 1) TEST_SCALETO(Scale, 1, 1)
TEST_SCALETO(Scale, 320, 240) TEST_SCALETO(Scale, 320, 240)

View File

@ -25,16 +25,17 @@ unsigned int fastrand_seed = 0xfb;
DEFINE_int32(libyuv_width, 0, "width of test image."); DEFINE_int32(libyuv_width, 0, "width of test image.");
DEFINE_int32(libyuv_height, 0, "height of test image."); DEFINE_int32(libyuv_height, 0, "height of test image.");
DEFINE_int32(libyuv_repeat, 0, "number of times to repeat test."); DEFINE_int32(libyuv_repeat, 0, "number of times to repeat test.");
DEFINE_int32(libyuv_flags, 0, "cpu flags for reference code. 0 = C -1 = asm"); DEFINE_int32(libyuv_flags, 0,
DEFINE_int32(libyuv_cpu_info, -1, "cpu flags for reference code. 1 = C, -1 = SIMD");
"cpu flags for benchmark code. -1 = SIMD, 1 = C"); DEFINE_int32(libyuv_cpu_info, 0,
"cpu flags for benchmark code. 1 = C, -1 = SIMD");
// For quicker unittests, default is 128 x 72. But when benchmarking, // For quicker unittests, default is 128 x 72. But when benchmarking,
// default to 720p. Allow size to specify. // default to 720p. Allow size to specify.
// Set flags to -1 for benchmarking to avoid slower C code. // Set flags to -1 for benchmarking to avoid slower C code.
LibYUVConvertTest::LibYUVConvertTest() : LibYUVConvertTest::LibYUVConvertTest() :
benchmark_iterations_(BENCHMARK_ITERATIONS), benchmark_width_(130), benchmark_iterations_(BENCHMARK_ITERATIONS), benchmark_width_(128),
benchmark_height_(72), disable_cpu_flags_(1), benchmark_cpu_info_(-1) { benchmark_height_(72), disable_cpu_flags_(1), benchmark_cpu_info_(-1) {
const char* repeat = getenv("LIBYUV_REPEAT"); const char* repeat = getenv("LIBYUV_REPEAT");
if (repeat) { if (repeat) {

View File

@ -22,18 +22,54 @@
#include "libyuv/basic_types.h" #include "libyuv/basic_types.h"
#ifndef SIMD_ALIGNED
#if defined(_MSC_VER) && !defined(__CLR_VER)
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#elif defined(__GNUC__) && !defined(__pnacl__)
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#else
#define SIMD_ALIGNED(var) var
#endif
#endif
static __inline int Abs(int v) { static __inline int Abs(int v) {
return v >= 0 ? v : -v; return v >= 0 ? v : -v;
} }
#define OFFBY 0 #define OFFBY 0
// Scaling uses 16.16 fixed point to step thru the source image, so a
// maximum size of 32767.999 can be expressed. 32768 is valid because
// the step is 1 beyond the image but not used.
// Destination size is mainly constrained by valid scale step not the
// absolute size, so it may be possible to relax the destination size
// constraint.
// Source size is unconstrained for most specialized scalers. e.g.
// An image of 65536 scaled to half size would be valid. The test
// could be relaxed for special scale factors.
// If this test is removed, the scaling function should gracefully
// fail with a return code. The test could be changed to know that
// libyuv failed in a controlled way.
static const int kMaxWidth = 32768;
static const int kMaxHeight = 32768;
static inline bool SizeValid(int src_width, int src_height,
int dst_width, int dst_height) {
if (src_width > kMaxWidth || src_height > kMaxHeight ||
dst_width > kMaxWidth || dst_height > kMaxHeight) {
printf("Warning - size too large to test. Skipping\n");
return false;
}
return true;
}
#define align_buffer_page_end(var, size) \ #define align_buffer_page_end(var, size) \
uint8* var; \ uint8* var; \
uint8* var##_mem; \ uint8* var##_mem; \
var##_mem = reinterpret_cast<uint8*>(malloc((((size) + 4095) & ~4095) + \ var##_mem = reinterpret_cast<uint8*>(malloc(((size) + 4095 + 63) & ~4095)); \
OFFBY)); \ var = (uint8*)((intptr_t)(var##_mem + (((size) + 4095 + 63) & ~4095) - \
var = var##_mem + (-(size) & 4095) + OFFBY; (size)) & ~63);
#define free_aligned_buffer_page_end(var) \ #define free_aligned_buffer_page_end(var) \
free(var##_mem); \ free(var##_mem); \
@ -55,6 +91,16 @@ static inline double get_time() {
} }
#endif #endif
#ifndef SIMD_ALIGNED
#if defined(_MSC_VER) && !defined(__CLR_VER)
#define SIMD_ALIGNED(var) __declspec(align(16)) var
#elif defined(__GNUC__) && !defined(__pnacl__)
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
#else
#define SIMD_ALIGNED(var) var
#endif
#endif
extern unsigned int fastrand_seed; extern unsigned int fastrand_seed;
inline int fastrand() { inline int fastrand() {
fastrand_seed = fastrand_seed * 214013u + 2531011u; fastrand_seed = fastrand_seed * 214013u + 2531011u;

View File

@ -43,6 +43,7 @@ static bool TestValidFourCC(uint32 fourcc, int bpp) {
TEST_F(LibYUVBaseTest, TestCanonicalFourCC) { TEST_F(LibYUVBaseTest, TestCanonicalFourCC) {
EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_IYUV)); EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_IYUV));
EXPECT_EQ(FOURCC_I420, CanonicalFourCC(FOURCC_YU12));
EXPECT_EQ(FOURCC_I422, CanonicalFourCC(FOURCC_YU16)); EXPECT_EQ(FOURCC_I422, CanonicalFourCC(FOURCC_YU16));
EXPECT_EQ(FOURCC_I444, CanonicalFourCC(FOURCC_YU24)); EXPECT_EQ(FOURCC_I444, CanonicalFourCC(FOURCC_YU24));
EXPECT_EQ(FOURCC_YUY2, CanonicalFourCC(FOURCC_YUYV)); EXPECT_EQ(FOURCC_YUY2, CanonicalFourCC(FOURCC_YUYV));

View File

@ -10,7 +10,7 @@
// Get SSIM for video sequence. Assuming RAW 4:2:0 Y:Cb:Cr format // Get SSIM for video sequence. Assuming RAW 4:2:0 Y:Cb:Cr format
#ifndef UTIL_SSIM_H_ // NOLINT #ifndef UTIL_SSIM_H_
#define UTIL_SSIM_H_ #define UTIL_SSIM_H_
#include <math.h> // For log10() #include <math.h> // For log10()
@ -33,4 +33,4 @@ double CalcLSSIM(double ssim);
} // extern "C" } // extern "C"
#endif #endif
#endif // UTIL_SSIM_H_ // NOLINT #endif // UTIL_SSIM_H_