merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-07-26 16:59:46 +02:00
commit 8b58b75b4e
238 changed files with 31622 additions and 17903 deletions

View File

@ -9,6 +9,7 @@ support-files =
worker.js
[browser_aboutURLs.js]
[browser_eme.js]
[browser_favicon.js]
[browser_forgetaboutsite.js]
[browser_usercontext.js]

View File

@ -0,0 +1,185 @@
/*
* Bug 1283325 - A test case to test the EME is originAttributes aware or not.
*/
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
const TEST_HOST = "example.com";
const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
const TESTKEY = {
initDataType: 'keyids',
initData: '{"kids":["LwVHf8JLtPrv2GUXFW2v_A"], "type":"persistent-license"}',
kid: "LwVHf8JLtPrv2GUXFW2v_A",
key: "97b9ddc459c8d5ff23c1f2754c95abe8",
sessionType: 'persistent-license',
};
const USER_ID_DEFAULT = 0;
const USER_ID_PERSONAL = 1;
function* openTabInUserContext(uri, userContextId) {
// Open the tab in the correct userContextId.
let tab = gBrowser.addTab(uri, {userContextId});
// Select tab and make sure its browser is focused.
gBrowser.selectedTab = tab;
tab.ownerDocument.defaultView.focus();
let browser = gBrowser.getBrowserForTab(tab);
yield BrowserTestUtils.browserLoaded(browser);
return {tab, browser};
}
function HexToBase64(hex)
{
var bin = "";
for (var i = 0; i < hex.length; i += 2) {
bin += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
}
return window.btoa(bin).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
}
function Base64ToHex(str)
{
var bin = window.atob(str.replace(/-/g, "+").replace(/_/g, "/"));
var res = "";
for (var i = 0; i < bin.length; i++) {
res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
}
return res;
}
function ByteArrayToHex(array) {
let bin = String.fromCharCode.apply(null, new Uint8Array(array));
let res = "";
for (let i = 0; i < bin.length; i++) {
res += ("0" + bin.charCodeAt(i).toString(16)).substr(-2);
}
return res;
}
function generateKeyObject(aKid, aKey) {
let keyObj = {
kty: 'oct',
kid: aKid,
k: HexToBase64(aKey),
};
return new TextEncoder().encode(JSON.stringify({
keys: [keyObj]
}));
}
function generateKeyInfo(aData) {
let keyInfo = {
initDataType: aData.initDataType,
initData: new TextEncoder().encode(aData.initData),
sessionType: aData.sessionType,
keyObj: generateKeyObject(aData.kid, aData.key),
};
return keyInfo;
}
add_task(function* setup() {
// Make sure userContext is enabled.
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
[ "privacy.userContext.enabled", true ],
[ "media.mediasource.enabled", true ],
[ "media.eme.apiVisible", true ],
[ "media.mediasource.webm.enabled", true ],
]}, resolve);
});
});
add_task(function* test() {
// Open a tab with the default container.
let defaultContainer = yield openTabInUserContext(TEST_URL + "empty_file.html", USER_ID_DEFAULT);
// Generate the key info for the default container.
let keyInfo = generateKeyInfo(TESTKEY);
// Update the media key for the default container.
let result = yield ContentTask.spawn(defaultContainer.browser, keyInfo, function* (aKeyInfo) {
let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
[{
initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm'}],
sessionTypes: ['persistent-license'],
persistentState: 'required',
}]);
let mediaKeys = yield access.createMediaKeys();
let session = mediaKeys.createSession(aKeyInfo.sessionType);
let res = {};
// Insert the media key.
let result = yield new Promise(resolve => {
session.addEventListener("message", function(event) {
session.update(aKeyInfo.keyObj).then(
() => { resolve(); }
).catch(
() => {
ok(false, "Update the media key fail.");
resolve();
}
);
});
session.generateRequest(aKeyInfo.initDataType, aKeyInfo.initData);
});
let map = session.keyStatuses;
is(map.size, 1, "One media key has been added.");
if (map.size === 1) {
res.keyId = map.keys().next().value;
res.sessionId = session.sessionId;
}
// Close the session.
session.close();
yield session.closed;
return res;
});
// Check the media key ID.
is(ByteArrayToHex(result.keyId), Base64ToHex(TESTKEY.kid), "The key Id of the default container is correct.");
// Store the sessionId for the further checking.
keyInfo.sessionId = result.sessionId;
// Open a tab with personal container.
let personalContainer = yield openTabInUserContext(TEST_URL + "empty_file.html", USER_ID_PERSONAL);
yield ContentTask.spawn(personalContainer.browser, keyInfo, function* (aKeyInfo) {
let access = yield content.navigator.requestMediaKeySystemAccess('org.w3.clearkey',
[{
initDataTypes: [aKeyInfo.initDataType],
videoCapabilities: [{contentType: 'video/webm'}],
sessionTypes: ['persistent-license'],
persistentState: 'required',
}]);
let mediaKeys = yield access.createMediaKeys();
let session = mediaKeys.createSession(aKeyInfo.sessionType);
// First, load the session to check that mediakeys do not share with
// default container.
yield session.load(aKeyInfo.sessionId);
let map = session.keyStatuses;
// Check that there is no media key here.
is(map.size, 0, "No media key should be here for the personal container.");
});
// Close default container tab.
yield BrowserTestUtils.removeTab(defaultContainer.tab);
// Close personal container tab.
yield BrowserTestUtils.removeTab(personalContainer.tab);
});

View File

@ -67,6 +67,9 @@ elif test -z "$CCACHE_DIR" -a -z "$SCCACHE_DISABLE" -a -z "$no_sccache" -a -z "$
# set a dummy master
case "${region}" in
eu-central-1)
master=dummy.euc1.mozilla.com
;;
us-east-1)
master=dummy.use1.mozilla.com
;;
@ -102,7 +105,7 @@ else
fi
mk_add_options "export SCCACHE_BUCKET=$bucket"
case "$master" in
*us[ew][12].mozilla.com*)
*us[ew][12].mozilla.com*|*euc1.mozilla.com*)
mk_add_options "export SCCACHE_NAMESERVER=169.254.169.253"
;;
esac

View File

@ -592,8 +592,8 @@ protected:
explicit Arr(const arrT& arr) {
arr.ComputeLengthAndData();
dataCount = arr.Length();
data = arr.Data();
dataCount = arr.LengthAllowShared();
data = arr.DataAllowShared();
}
explicit Arr(const dom::Sequence<elemT>& arr) {
@ -950,7 +950,7 @@ public:
void VertexAttrib1fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
VertexAttrib1fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib1fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
@ -958,7 +958,7 @@ public:
void VertexAttrib2fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
VertexAttrib2fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib2fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
@ -966,7 +966,7 @@ public:
void VertexAttrib3fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
VertexAttrib3fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib3fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
@ -974,7 +974,7 @@ public:
void VertexAttrib4fv(GLuint idx, const dom::Float32Array& arr) {
arr.ComputeLengthAndData();
VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
VertexAttrib4fv_base(idx, arr.LengthAllowShared(), arr.DataAllowShared());
}
void VertexAttrib4fv(GLuint idx, const dom::Sequence<GLfloat>& arr) {
VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());

View File

@ -123,7 +123,7 @@ function testColorConversions() {
testColorConversion("RGBA32", "GRAY8"),
testColorConversion("RGBA32", "YUV444P"),
testColorConversion("RGBA32", "YUV422P"),
testColorConversion("RGBA32", "YUV420P"),
testColorConversion("RGBA32", "YUV420P", 2),
testColorConversion("RGBA32", "YUV420SP_NV12"),
testColorConversion("RGBA32", "YUV420SP_NV21"),
testColorConversion("RGBA32", "HSV", 0.01),
@ -136,10 +136,10 @@ function testColorConversions() {
testColorConversion("BGRA32", "BGR24"),
testColorConversion("BGRA32", "GRAY8"),
testColorConversion("BGRA32", "YUV444P", 3),
testColorConversion("BGRA32", "YUV422P"),
testColorConversion("BGRA32", "YUV420P"),
testColorConversion("BGRA32", "YUV420SP_NV12"),
testColorConversion("BGRA32", "YUV420SP_NV21"),
testColorConversion("BGRA32", "YUV422P", 2),
testColorConversion("BGRA32", "YUV420P", 2),
testColorConversion("BGRA32", "YUV420SP_NV12", 2),
testColorConversion("BGRA32", "YUV420SP_NV21", 2),
testColorConversion("BGRA32", "HSV", 0.01),
testColorConversion("BGRA32", "Lab", 0.5),
@ -178,7 +178,7 @@ function testColorConversions() {
testColorConversion("YUV444P", "BGR24"),
testColorConversion("YUV444P", "GRAY8"),
testColorConversion("YUV444P", "YUV444P"),
testColorConversion("YUV444P", "YUV422P", 3),
testColorConversion("YUV444P", "YUV422P", 4),
testColorConversion("YUV444P", "YUV420P", 3),
testColorConversion("YUV444P", "YUV420SP_NV12", 3),
testColorConversion("YUV444P", "YUV420SP_NV21", 3),
@ -187,7 +187,7 @@ function testColorConversions() {
// From YUV422P
testColorConversion("YUV422P", "RGBA32"),
testColorConversion("YUV422P", "BGRA32"),
testColorConversion("YUV422P", "BGRA32", 2),
testColorConversion("YUV422P", "RGB24"),
testColorConversion("YUV422P", "BGR24"),
testColorConversion("YUV422P", "GRAY8"),
@ -200,13 +200,13 @@ function testColorConversions() {
testColorConversion("YUV422P", "Lab", 0.01),
// From YUV420P
testColorConversion("YUV420P", "RGBA32"),
testColorConversion("YUV420P", "BGRA32"),
testColorConversion("YUV420P", "RGBA32", 2),
testColorConversion("YUV420P", "BGRA32", 2),
testColorConversion("YUV420P", "RGB24"),
testColorConversion("YUV420P", "BGR24"),
testColorConversion("YUV420P", "GRAY8"),
testColorConversion("YUV420P", "YUV444P", 3),
testColorConversion("YUV420P", "YUV422P"),
testColorConversion("YUV420P", "YUV422P", 1),
testColorConversion("YUV420P", "YUV420P"),
testColorConversion("YUV420P", "YUV420SP_NV12"),
testColorConversion("YUV420P", "YUV420SP_NV21"),
@ -215,12 +215,12 @@ function testColorConversions() {
// From NV12
testColorConversion("YUV420SP_NV12", "RGBA32"),
testColorConversion("YUV420SP_NV12", "BGRA32"),
testColorConversion("YUV420SP_NV12", "BGRA32", 2),
testColorConversion("YUV420SP_NV12", "RGB24"),
testColorConversion("YUV420SP_NV12", "BGR24"),
testColorConversion("YUV420SP_NV12", "GRAY8"),
testColorConversion("YUV420SP_NV12", "YUV444P", 3),
testColorConversion("YUV420SP_NV12", "YUV422P"),
testColorConversion("YUV420SP_NV12", "YUV422P", 1),
testColorConversion("YUV420SP_NV12", "YUV420P"),
testColorConversion("YUV420SP_NV12", "YUV420SP_NV12"),
testColorConversion("YUV420SP_NV12", "YUV420SP_NV21"),
@ -229,12 +229,12 @@ function testColorConversions() {
// From NV21
testColorConversion("YUV420SP_NV21", "RGBA32"),
testColorConversion("YUV420SP_NV21", "BGRA32"),
testColorConversion("YUV420SP_NV21", "BGRA32", 2),
testColorConversion("YUV420SP_NV21", "RGB24"),
testColorConversion("YUV420SP_NV21", "BGR24"),
testColorConversion("YUV420SP_NV21", "GRAY8"),
testColorConversion("YUV420SP_NV21", "YUV444P", 3),
testColorConversion("YUV420SP_NV21", "YUV422P"),
testColorConversion("YUV420SP_NV21", "YUV422P", 1),
testColorConversion("YUV420SP_NV21", "YUV420P"),
testColorConversion("YUV420SP_NV21", "YUV420SP_NV12"),
testColorConversion("YUV420SP_NV21", "YUV420SP_NV21"),

View File

@ -69,6 +69,27 @@ CompositionEvent::InitCompositionEvent(const nsAString& aType,
mLocale = aLocale;
}
void
CompositionEvent::GetRanges(TextClauseArray& aRanges)
{
// If the mRanges is not empty, we return the cached value.
if (!mRanges.IsEmpty()) {
aRanges = mRanges;
return;
}
RefPtr<TextRangeArray> textRangeArray = mEvent->AsCompositionEvent()->mRanges;
if (!textRangeArray) {
return;
}
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mOwner);
const TextRange* targetRange = textRangeArray->GetTargetClause();
for (size_t i = 0; i < textRangeArray->Length(); i++) {
const TextRange& range = textRangeArray->ElementAt(i);
mRanges.AppendElement(new TextClause(window, range, targetRange));
}
aRanges = mRanges;
}
} // namespace dom
} // namespace mozilla

View File

@ -8,12 +8,16 @@
#define mozilla_dom_CompositionEvent_h_
#include "mozilla/dom/CompositionEventBinding.h"
#include "mozilla/dom/TextClause.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/UIEvent.h"
#include "mozilla/EventForwards.h"
namespace mozilla {
namespace dom {
typedef nsTArray<RefPtr<TextClause>> TextClauseArray;
class CompositionEvent : public UIEvent
{
public:
@ -37,12 +41,14 @@ public:
const nsAString& aLocale);
void GetData(nsAString&) const;
void GetLocale(nsAString&) const;
void GetRanges(TextClauseArray& aRanges);
protected:
~CompositionEvent() {}
nsString mData;
nsString mLocale;
TextClauseArray mRanges;
};
} // namespace dom

50
dom/events/TextClause.cpp Normal file
View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TextClause.h"
#include "mozilla/dom/TextClauseBinding.h"
#include "mozilla/TextEvents.h"
namespace mozilla {
namespace dom {
// Only needed for refcounted objects.
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(TextClause)
NS_IMPL_CYCLE_COLLECTING_ADDREF(TextClause)
NS_IMPL_CYCLE_COLLECTING_RELEASE(TextClause)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextClause)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
TextClause::TextClause(nsPIDOMWindowInner* aOwner, const TextRange& aRange,
const TextRange* aTargetRange)
: mOwner(aOwner)
, mIsTargetClause(false)
{
MOZ_ASSERT(aOwner);
mStartOffset = aRange.mStartOffset;
mEndOffset = aRange.mEndOffset;
if (aRange.IsClause()) {
mIsCaret = false;
if (aTargetRange && aTargetRange->mStartOffset == mStartOffset) {
mIsTargetClause = true;
}
} else {
mIsCaret = true;
}
}
JSObject*
TextClause::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return TextClauseBinding::Wrap(aCx, this, aGivenProto);
}
TextClause::~TextClause() {}
} // namespace dom
} // namespace mozilla

57
dom/events/TextClause.h Normal file
View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TextClause_h
#define mozilla_dom_TextClause_h
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class TextClause final : public nsISupports
, public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextClause)
nsPIDOMWindowInner* GetParentObject() const { return mOwner; }
TextClause(nsPIDOMWindowInner* aWindow, const TextRange& aRange,
const TextRange* targetRange);
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
inline uint32_t StartOffset() const { return mStartOffset; }
inline uint32_t EndOffset() const { return mEndOffset; }
inline bool IsCaret() const { return mIsCaret; }
inline bool IsTargetClause() const { return mIsTargetClause; }
private:
~TextClause();
nsCOMPtr<nsPIDOMWindowInner> mOwner;
// Following members, please take look at widget/TextRange.h.
uint32_t mStartOffset;
uint32_t mEndOffset;
bool mIsCaret;
bool mIsTargetClause;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TextClause_h

View File

@ -64,6 +64,7 @@ EXPORTS.mozilla.dom += [
'ScrollAreaEvent.h',
'SimpleGestureEvent.h',
'StorageEvent.h',
'TextClause.h',
'Touch.h',
'TouchEvent.h',
'TransitionEvent.h',
@ -112,6 +113,7 @@ UNIFIED_SOURCES += [
'ScrollAreaEvent.cpp',
'SimpleGestureEvent.cpp',
'StorageEvent.cpp',
'TextClause.cpp',
'TextComposition.cpp',
'Touch.cpp',
'TouchEvent.cpp',

View File

@ -1356,9 +1356,14 @@ GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
return true;
}
static void
static bool
StartMacOSContentSandbox()
{
int sandboxLevel = Preferences::GetInt("security.sandbox.content.level");
if (sandboxLevel < 1) {
return false;
}
nsAutoCString appPath, appBinaryPath, appDir;
if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
MOZ_CRASH("Error resolving child process path");
@ -1382,7 +1387,7 @@ StartMacOSContentSandbox()
MacSandboxInfo info;
info.type = MacSandboxType_Content;
info.level = Preferences::GetInt("security.sandbox.content.level");
info.level = info.level = sandboxLevel;
info.appPath.assign(appPath.get());
info.appBinaryPath.assign(appBinaryPath.get());
info.appDir.assign(appDir.get());
@ -1393,6 +1398,8 @@ StartMacOSContentSandbox()
NS_WARNING(err.c_str());
MOZ_CRASH("sandbox_init() failed");
}
return true;
}
#endif
@ -1402,6 +1409,7 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
// We may want to move the sandbox initialization somewhere else
// at some point; see bug 880808.
#if defined(MOZ_CONTENT_SANDBOX)
bool sandboxEnabled = true;
#if defined(XP_LINUX)
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 19
// For B2G >= KitKat, sandboxing is mandatory; this has already
@ -1410,32 +1418,45 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
#else
// Otherwise, sandboxing is best-effort.
if (!SandboxInfo::Get().CanSandboxContent()) {
return true;
sandboxEnabled = false;
} else {
// This triggers the initialization of cubeb, which needs to happen
// before seccomp is enabled (Bug 1259508). It also increases the startup
// time of the content process, because cubeb is usually initialized
// when it is actually needed. This call here is no longer required
// once Bug 1104619 (remoting audio) is resolved.
Unused << CubebUtils::GetCubebContext();
}
// This triggers the initialization of cubeb, which needs to happen
// before seccomp is enabled (Bug 1259508). It also increases the startup
// time of the content process, because cubeb is usually initialized
// when it is actually needed. This call here is no longer required
// once Bug 1104619 (remoting audio) is resolved.
Unused << CubebUtils::GetCubebContext();
#endif
int brokerFd = -1;
if (aBroker.type() == MaybeFileDesc::TFileDescriptor) {
#endif /* MOZ_WIDGET_GONK && ANDROID_VERSION >= 19 */
if (sandboxEnabled) {
int brokerFd = -1;
if (aBroker.type() == MaybeFileDesc::TFileDescriptor) {
auto fd = aBroker.get_FileDescriptor().ClonePlatformHandle();
brokerFd = fd.release();
// brokerFd < 0 means to allow direct filesystem access, so
// make absolutely sure that doesn't happen if the parent
// didn't intend it.
MOZ_RELEASE_ASSERT(brokerFd >= 0);
}
sandboxEnabled = SetContentProcessSandbox(brokerFd);
}
SetContentProcessSandbox(brokerFd);
#elif defined(XP_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#elif defined(XP_MACOSX)
StartMacOSContentSandbox();
#endif
sandboxEnabled = StartMacOSContentSandbox();
#endif
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AnnotateCrashReport(
NS_LITERAL_CSTRING("ContentSandboxEnabled"),
sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
#if defined(XP_LINUX) && !defined(OS_ANDROID)
SandboxInfo::Get().AnnotateCrashReport();
#endif /* XP_LINUX && !OS_ANDROID */
#endif /* MOZ_CRASHREPORTER */
#endif /* MOZ_CONTENT_SANDBOX */
return true;
}

View File

@ -356,15 +356,15 @@ MediaKeys::Init(ErrorResult& aRv)
return promise.forget();
}
nsAutoString origin;
nsresult rv = nsContentUtils::GetUTFOrigin(mPrincipal, origin);
nsAutoCString origin;
nsresult rv = mPrincipal->GetOrigin(origin);
if (NS_FAILED(rv)) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get principal origin string in MediaKeys::Init"));
return promise.forget();
}
nsAutoString topLevelOrigin;
rv = nsContentUtils::GetUTFOrigin(mTopLevelPrincipal, topLevelOrigin);
nsAutoCString topLevelOrigin;
rv = mTopLevelPrincipal->GetOrigin(topLevelOrigin);
if (NS_FAILED(rv)) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("Couldn't get top-level principal origin string in MediaKeys::Init"));
@ -376,8 +376,8 @@ MediaKeys::Init(ErrorResult& aRv)
EME_LOG("MediaKeys[%p]::Create() (%s, %s), %s",
this,
NS_ConvertUTF16toUTF8(origin).get(),
NS_ConvertUTF16toUTF8(topLevelOrigin).get(),
origin.get(),
topLevelOrigin.get(),
(inPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"));
// The CDMProxy's initialization is asynchronous. The MediaKeys is
@ -392,8 +392,8 @@ MediaKeys::Init(ErrorResult& aRv)
mCreatePromiseId = StorePromise(promise);
AddRef();
mProxy->Init(mCreatePromiseId,
origin,
topLevelOrigin,
NS_ConvertUTF8toUTF16(origin),
NS_ConvertUTF8toUTF16(topLevelOrigin),
KeySystemToGMPName(mKeySystem),
inPrivateBrowsing);

View File

@ -2461,6 +2461,7 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
tag.isJavaPlugin(),
tag.isFlashPlugin(),
tag.supportsAsyncInit(),
tag.supportsAsyncRender(),
tag.lastModifiedTime(),
tag.isFromExtension(),
tag.sandboxLevel());
@ -2701,6 +2702,7 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
tag->mIsJavaPlugin,
tag->mIsFlashPlugin,
tag->mSupportsAsyncInit,
tag->mSupportsAsyncRender,
tag->FileName(),
tag->Version(),
tag->mLastModifiedTime,

View File

@ -236,6 +236,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo,
mIsJavaPlugin(false),
mIsFlashPlugin(false),
mSupportsAsyncInit(false),
mSupportsAsyncRender(false),
mFullPath(aPluginInfo->fFullPath),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(0),
@ -271,6 +272,7 @@ nsPluginTag::nsPluginTag(const char* aName,
mIsJavaPlugin(false),
mIsFlashPlugin(false),
mSupportsAsyncInit(false),
mSupportsAsyncRender(false),
mFullPath(aFullPath),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(0),
@ -298,6 +300,7 @@ nsPluginTag::nsPluginTag(uint32_t aId,
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
bool aSupportsAsyncRender,
int64_t aLastModifiedTime,
bool aFromExtension,
int32_t aSandboxLevel)
@ -309,6 +312,7 @@ nsPluginTag::nsPluginTag(uint32_t aId,
mIsJavaPlugin(aIsJavaPlugin),
mIsFlashPlugin(aIsFlashPlugin),
mSupportsAsyncInit(aSupportsAsyncInit),
mSupportsAsyncRender(aSupportsAsyncRender),
mLastModifiedTime(aLastModifiedTime),
mSandboxLevel(aSandboxLevel),
mNiceFileName(),

View File

@ -133,6 +133,7 @@ public:
bool aIsJavaPlugin,
bool aIsFlashPlugin,
bool aSupportsAsyncInit,
bool aSupportsAsyncRender,
int64_t aLastModifiedTime,
bool aFromExtension,
int32_t aSandboxLevel);
@ -172,6 +173,7 @@ public:
bool mIsJavaPlugin;
bool mIsFlashPlugin;
bool mSupportsAsyncInit;
bool mSupportsAsyncRender;
nsCString mFullPath; // UTF-8
int64_t mLastModifiedTime;
nsCOMPtr<nsITimer> mUnloadTimer;

View File

@ -34,6 +34,7 @@ struct nsPluginInfo {
char* fFileName;
char* fFullPath;
char* fVersion;
bool fSupportsAsyncRender;
};
/**

View File

@ -109,6 +109,20 @@ static char* GetVersion(void* verbuf)
return nullptr;
}
// Returns a boolean indicating if the key's value contains a string
// entry equal to "1" or "0". No entry for the key returns false.
static bool GetBooleanFlag(void* verbuf, const WCHAR* key,
UINT language, UINT codepage)
{
char* flagStr = GetKeyValue(verbuf, key, language, codepage);
if (!flagStr) {
return false;
}
bool result = (PL_strncmp("1", flagStr, 1) == 0);
PL_strfree(flagStr);
return result;
}
static uint32_t CalculateVariantCount(char* mimeTypes)
{
uint32_t variants = 1;
@ -356,11 +370,12 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
if (::GetFileVersionInfoW(lpFilepath, 0, versionsize, verbuf))
{
// TODO: get appropriately-localized info from plugin file
UINT lang = 1033; // language = English
UINT cp = 1252; // codepage = Western
UINT lang = 1033; // language = English, 0x409
UINT cp = 1252; // codepage = Western, 0x4E4
info.fName = GetKeyValue(verbuf, L"ProductName", lang, cp);
info.fDescription = GetKeyValue(verbuf, L"FileDescription", lang, cp);
info.fSupportsAsyncRender = GetBooleanFlag(verbuf, L"AsyncDrawingSupport", lang, cp);
char *mimeType = GetKeyValue(verbuf, L"MIMEType", lang, cp);
char *mimeDescription = GetKeyValue(verbuf, L"FileOpenName", lang, cp);
char *extensions = GetKeyValue(verbuf, L"FileExtents", lang, cp);

View File

@ -48,6 +48,11 @@ both:
child:
async DisableFlashProtectedMode();
// Sync query to check if a Flash library indicates it
// supports async rendering mode.
intr ModuleSupportsAsyncRender()
returns (bool result);
// Forces the child process to update its plugin function table.
intr NP_GetEntryPoints()
returns (NPError rv);

View File

@ -123,6 +123,7 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
#ifdef OS_WIN
, mNestedEventHook(nullptr)
, mGlobalCallWndProcHook(nullptr)
, mAsyncRenderSupport(false)
#endif
{
memset(&mFunctions, 0, sizeof(mFunctions));
@ -243,26 +244,29 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
nsPluginFile pluginFile(localFile);
#if defined(MOZ_X11) || defined(XP_MACOSX)
nsPluginInfo info = nsPluginInfo();
if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary))) {
return false;
}
#if defined(XP_WIN)
// XXX quirks isn't initialized yet
mAsyncRenderSupport = info.fSupportsAsyncRender;
#endif
#if defined(MOZ_X11)
NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10.");
if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) {
AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION);
}
#else // defined(XP_MACOSX)
#endif
#if defined(XP_MACOSX)
const char* namePrefix = "Plugin Content";
char nameBuffer[80];
snprintf(nameBuffer, sizeof(nameBuffer), "%s (%s)", namePrefix, info.fName);
mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer);
#endif
pluginFile.FreePluginInfo(info);
#if defined(MOZ_X11) || defined(XP_MACOSX)
if (!mLibrary)
#endif
{
@ -2104,6 +2108,18 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
mQuirks = GetQuirksFromMimeTypeAndFilename(aMimeType, mPluginFilename);
}
bool
PluginModuleChild::AnswerModuleSupportsAsyncRender(bool* aResult)
{
#if defined(XP_WIN)
*aResult = gChromeInstance->mAsyncRenderSupport;
return true;
#else
NS_NOTREACHED("Shouldn't get here!");
return false;
#endif
}
bool
PluginModuleChild::RecvPPluginInstanceConstructor(PPluginInstanceChild* aActor,
const nsCString& aMimeType,

View File

@ -144,6 +144,8 @@ protected:
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;
virtual bool
AnswerModuleSupportsAsyncRender(bool* aResult) override;
public:
explicit PluginModuleChild(bool aIsChrome);
virtual ~PluginModuleChild();
@ -362,6 +364,8 @@ private:
void ResetEventHooks();
HHOOK mNestedEventHook;
HHOOK mGlobalCallWndProcHook;
public:
bool mAsyncRenderSupport;
#endif
};

View File

@ -2714,11 +2714,16 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance,
if (mIsFlashPlugin) {
parentInstance->InitMetadata(strPluginType, srcAttribute);
#ifdef XP_WIN
// Force windowless mode (bug 1201904) when sandbox level >= 2 or Win64
bool supportsAsyncRender = false;
CallModuleSupportsAsyncRender(&supportsAsyncRender);
#ifdef _WIN64
{
// For 64-bit builds force windowless if the flash library doesn't support
// async rendering regardless of sandbox level.
if (!supportsAsyncRender) {
#else
if (mSandboxLevel >= 2) {
// For 32-bit builds force windowless if the flash library doesn't support
// async rendering and the sandbox level is 2 or greater.
if (!supportsAsyncRender && mSandboxLevel >= 2) {
#endif
NS_NAMED_LITERAL_CSTRING(wmodeAttributeName, "wmode");
NS_NAMED_LITERAL_CSTRING(opaqueAttributeValue, "opaque");

View File

@ -17,6 +17,7 @@ struct PluginTag
bool isJavaPlugin;
bool isFlashPlugin;
bool supportsAsyncInit;
bool supportsAsyncRender; // flash specific
nsCString filename;
nsCString version;
int64_t lastModifiedTime;

View File

@ -13,6 +13,13 @@ interface CompositionEvent : UIEvent
{
readonly attribute DOMString? data;
readonly attribute DOMString locale;
/**
* ranges is trying to expose TextRangeArray in Gecko so a
* js-plugin couble be able to know the clauses information
*/
[ChromeOnly,Cached,Pure]
readonly attribute sequence<TextClause> ranges;
};
partial interface CompositionEvent

View File

@ -0,0 +1,21 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[ChromeOnly]
interface TextClause
{
// The start offset of TextClause
readonly attribute long startOffset;
// The end offset of TextClause
readonly attribute long endOffset;
// If the TextClause is Caret or not
readonly attribute boolean isCaret;
// If the TextClause is TargetClause or not
readonly attribute boolean isTargetClause;
};

View File

@ -545,6 +545,7 @@ WEBIDL_FILES = [
'TelephonyCallGroup.webidl',
'TelephonyCallId.webidl',
'Text.webidl',
'TextClause.webidl',
'TextDecoder.webidl',
'TextEncoder.webidl',
'TextTrack.webidl',

View File

@ -3067,6 +3067,7 @@ GetBytesPerTexel(GLenum format, GLenum type)
case LOCAL_GL_RGB:
return 3 * multiplier;
case LOCAL_GL_RGBA:
case LOCAL_GL_BGRA_EXT:
return 4 * multiplier;
default:
break;
@ -3079,7 +3080,6 @@ GetBytesPerTexel(GLenum format, GLenum type)
}
gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
MOZ_CRASH();
return 0;
}

View File

@ -100,11 +100,12 @@ OpenParent(RefPtr<CompositorBridgeParent> aParent,
bool
GPUParent::RecvNewWidgetCompositor(Endpoint<layers::PCompositorBridgeParent>&& aEndpoint,
const CSSToLayoutDeviceScale& aScale,
const TimeDuration& aVsyncRate,
const bool& aUseExternalSurfaceSize,
const IntSize& aSurfaceSize)
{
RefPtr<CompositorBridgeParent> cbp =
new CompositorBridgeParent(aScale, aUseExternalSurfaceSize, aSurfaceSize);
new CompositorBridgeParent(aScale, aVsyncRate, aUseExternalSurfaceSize, aSurfaceSize);
MessageLoop* loop = CompositorThreadHolder::Loop();
loop->PostTask(NewRunnableFunction(OpenParent, cbp, Move(aEndpoint)));

View File

@ -32,6 +32,7 @@ public:
bool RecvNewWidgetCompositor(
Endpoint<PCompositorBridgeParent>&& aEndpoint,
const CSSToLayoutDeviceScale& aScale,
const TimeDuration& aVsyncRate,
const bool& aUseExternalSurface,
const IntSize& aSurfaceSize) override;
bool RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aEndpoint) override;

View File

@ -21,6 +21,7 @@
#include "VRManagerParent.h"
#include "VsyncBridgeChild.h"
#include "VsyncIOThreadHolder.h"
#include "VsyncSource.h"
namespace mozilla {
namespace gfx {
@ -352,9 +353,13 @@ GPUProcessManager::CreateRemoteSession(nsBaseWidget* aWidget,
CompositorWidgetInitData initData;
aWidget->GetCompositorWidgetInitData(&initData);
TimeDuration vsyncRate =
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
bool ok = mGPUChild->SendNewWidgetCompositor(
Move(parentPipe),
aScale,
vsyncRate,
aUseExternalSurfaceSize,
aSurfaceSize);
if (!ok) {

View File

@ -8,6 +8,7 @@ include protocol PImageBridge;
include protocol PVRManager;
include protocol PVsyncBridge;
using mozilla::TimeDuration from "mozilla/TimeStamp.h";
using mozilla::CSSToLayoutDeviceScale from "Units.h";
using mozilla::gfx::IntSize from "mozilla/gfx/2D.h";
@ -42,6 +43,7 @@ parent:
// Create a new top-level compositor.
async NewWidgetCompositor(Endpoint<PCompositorBridgeParent> endpoint,
CSSToLayoutDeviceScale scale,
TimeDuration vsyncRate,
bool useExternalSurface,
IntSize surfaceSize);

View File

@ -1465,6 +1465,7 @@ AsyncCompositionManager::GetFrameUniformity(FrameUniformityData* aOutData)
bool
AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
TimeDuration aVsyncRate,
TransformsToSkip aSkip)
{
PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree",
@ -1529,10 +1530,12 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
// Advance APZ animations to the next expected vsync timestamp, if we can
// get it.
TimeStamp nextFrame = aCurrentFrame;
TimeDuration vsyncrate = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
if (vsyncrate != TimeDuration::Forever()) {
nextFrame += vsyncrate;
MOZ_ASSERT(aVsyncRate != TimeDuration::Forever());
if (aVsyncRate != TimeDuration::Forever()) {
nextFrame += aVsyncRate;
}
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), nextFrame);
}

View File

@ -85,7 +85,8 @@ public:
// another animation frame.
enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 };
bool TransformShadowTree(TimeStamp aCurrentFrame,
TransformsToSkip aSkip = TransformsToSkip::NoneOfThem);
TimeDuration aVsyncRate,
TransformsToSkip aSkip = TransformsToSkip::NoneOfThem);
// Calculates the correct rotation and applies the transform to
// our layer manager

View File

@ -36,6 +36,7 @@
#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
# include "mozilla/widget/CompositorWidgetChild.h"
#endif
#include "VsyncSource.h"
using mozilla::layers::LayerTransactionChild;
using mozilla::dom::TabChildBase;
@ -197,8 +198,11 @@ CompositorBridgeChild::InitSameProcess(widget::CompositorWidget* aWidget,
bool aUseExternalSurface,
const gfx::IntSize& aSurfaceSize)
{
TimeDuration vsyncRate =
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
mCompositorBridgeParent =
new CompositorBridgeParent(aScale, aUseExternalSurface, aSurfaceSize);
new CompositorBridgeParent(aScale, vsyncRate, aUseExternalSurface, aSurfaceSize);
mCanSend = Open(mCompositorBridgeParent->GetIPCChannel(),
CompositorThreadHolder::Loop(),

View File

@ -597,10 +597,12 @@ CompositorLoop()
}
CompositorBridgeParent::CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
const TimeDuration& aVsyncRate,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize)
: mWidget(nullptr)
, mScale(aScale)
, mVsyncRate(aVsyncRate)
, mIsTesting(false)
, mPendingTransaction(0)
, mPaused(false)
@ -1242,7 +1244,7 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
mCompositionManager->ComputeRotation();
TimeStamp time = mIsTesting ? mTestTime : mCompositorScheduler->GetLastComposeTime();
bool requestNextFrame = mCompositionManager->TransformShadowTree(time);
bool requestNextFrame = mCompositionManager->TransformShadowTree(time, mVsyncRate);
if (requestNextFrame) {
ScheduleComposition();
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
@ -1437,7 +1439,7 @@ CompositorBridgeParent::SetTestSampleTime(LayerTransactionParent* aLayerTree,
// Update but only if we were already scheduled to animate
if (testComposite) {
AutoResolveRefLayers resolve(mCompositionManager);
bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime);
bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime, mVsyncRate);
if (!requestNextFrame) {
CancelCurrentCompositeTask();
// Pretend we composited in case someone is wating for this event.
@ -1469,7 +1471,7 @@ CompositorBridgeParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
TimeStamp time = mIsTesting ? mTestTime : mCompositorScheduler->GetLastComposeTime();
bool requestNextFrame =
mCompositionManager->TransformShadowTree(time,
mCompositionManager->TransformShadowTree(time, mVsyncRate,
AsyncCompositionManager::TransformsToSkip::APZ);
if (!requestNextFrame) {
CancelCurrentCompositeTask();

View File

@ -213,6 +213,7 @@ class CompositorBridgeParent final : public PCompositorBridgeParent,
public:
explicit CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
const TimeDuration& aVsyncRate,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize);
@ -604,6 +605,7 @@ protected:
widget::CompositorWidget* mWidget;
TimeStamp mTestTime;
CSSToLayoutDeviceScale mScale;
TimeDuration mVsyncRate;
bool mIsTesting;
uint64_t mPendingTransaction;

View File

@ -1117,9 +1117,10 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
base::LaunchApp(cmdLine, false, false, &process);
#ifdef MOZ_SANDBOX
// We need to be able to duplicate handles to non-sandboxed content
// We need to be able to duplicate handles to non-sandboxed content and GMP
// processes, so add it as a target peer.
if (mProcessType == GeckoProcessType_Content) {
if (mProcessType == GeckoProcessType_Content ||
mProcessType == GeckoProcessType_GMPlugin) {
if (!mSandboxBroker.AddTargetPeer(process)) {
NS_WARNING("Failed to add content process as target peer.");
}

View File

@ -378,11 +378,11 @@ ProcLoaderLoadRunner::ShuffleFds()
for (i = 0; i < mFdsRemap.Length(); i++) {
const FDRemap *map = &mFdsRemap[i];
int fd = map->fd().PlatformHandle();
auto rawFD = map->fd().ClonePlatformHandle();
int tofd = map->mapto();
// The FD that is dup2()'d from needs to be closed after shuffling.
fd_shuffle.push_back(InjectionArc(fd, tofd, /*in_close=*/true));
fd_shuffle.push_back(InjectionArc(rawFD.get(), tofd, /*in_close=*/true));
// Erase from sReservedFds we will use.
for (int* toErase = sReservedFds->begin();

View File

@ -3372,8 +3372,8 @@ ComputeDrawnSizeForBackground(const CSSSizeOrRatio& aIntrinsicSize,
/* ComputeSpacedRepeatSize
* aImageDimension: the image width/height
* aAvailableSpace: the background positioning area width/height
* aRepeatSize: the image size plus gap size of app units for use as spacing
* aRepeat: determine whether the image is repeated
* Returns the image size plus gap size of app units for use as spacing
*/
static nscoord
ComputeSpacedRepeatSize(nscoord aImageDimension,
@ -3390,6 +3390,22 @@ ComputeSpacedRepeatSize(nscoord aImageDimension,
}
}
/* ComputeBorderSpacedRepeatSize
* aImageDimension: the image width/height
* aAvailableSpace: the background positioning area width/height
* aSpace: the space between each image
* Returns the image size plus gap size of app units for use as spacing
*/
static nscoord
ComputeBorderSpacedRepeatSize(nscoord aImageDimension,
nscoord aAvailableSpace,
nscoord& aSpace)
{
int32_t count = aAvailableSpace / aImageDimension;
aSpace = (aAvailableSpace - aImageDimension * count) / (count + 1);
return aSpace + aImageDimension;
}
nsBackgroundLayerState
nsCSSRendering::PrepareImageLayer(nsPresContext* aPresContext,
nsIFrame* aForFrame,
@ -3921,7 +3937,6 @@ DrawBorderImage(nsPresContext* aPresContext,
// default sizing algorithm) to renderer as the viewport size.
Maybe<nsSize> svgViewportSize = intrinsicSize.CanComputeConcreteSize() ?
Nothing() : Some(imageSize);
result &=
renderer.DrawBorderImageComponent(aPresContext,
aRenderingContext, aDirtyRect,
@ -5455,24 +5470,39 @@ nsImageRenderer::DrawBackground(nsPresContext* aPresContext,
* aUnitSize The size of the source rect in dest coords.
*/
static nsRect
ComputeTile(const nsRect& aFill,
ComputeTile(nsRect& aFill,
uint8_t aHFill,
uint8_t aVFill,
const nsSize& aUnitSize)
const nsSize& aUnitSize,
nsSize& aRepeatSize)
{
nsRect tile;
switch (aHFill) {
case NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH:
tile.x = aFill.x;
tile.width = aFill.width;
aRepeatSize.width = tile.width;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT:
tile.x = aFill.x + aFill.width/2 - aUnitSize.width/2;
tile.width = aUnitSize.width;
aRepeatSize.width = tile.width;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_ROUND:
tile.x = aFill.x;
tile.width = ComputeRoundedSize(aUnitSize.width, aFill.width);
aRepeatSize.width = tile.width;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_SPACE:
{
nscoord space;
aRepeatSize.width =
ComputeBorderSpacedRepeatSize(aUnitSize.width, aFill.width, space);
tile.x = aFill.x + space;
tile.width = aUnitSize.width;
aFill.x = tile.x;
aFill.width = aFill.width - space * 2;
}
break;
default:
NS_NOTREACHED("unrecognized border-image fill style");
@ -5482,14 +5512,28 @@ ComputeTile(const nsRect& aFill,
case NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH:
tile.y = aFill.y;
tile.height = aFill.height;
aRepeatSize.height = tile.height;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT:
tile.y = aFill.y + aFill.height/2 - aUnitSize.height/2;
tile.height = aUnitSize.height;
aRepeatSize.height = tile.height;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_ROUND:
tile.y = aFill.y;
tile.height = ComputeRoundedSize(aUnitSize.height, aFill.height);
aRepeatSize.height = tile.height;
break;
case NS_STYLE_BORDER_IMAGE_REPEAT_SPACE:
{
nscoord space;
aRepeatSize.height =
ComputeBorderSpacedRepeatSize(aUnitSize.height, aFill.height, space);
tile.y = aFill.y + space;
tile.height = aUnitSize.height;
aFill.y = tile.y;
aFill.height = aFill.height - space * 2;
}
break;
default:
NS_NOTREACHED("unrecognized border-image fill style");
@ -5596,21 +5640,27 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
drawFlags);
}
nsRect tile = ComputeTile(aFill, aHFill, aVFill, aUnitSize);
return nsLayoutUtils::DrawImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage,
samplingFilter,
tile, aFill, tile.TopLeft(), aDirtyRect,
drawFlags);
nsSize repeatSize;
nsRect fillRect(aFill);
nsRect tile = ComputeTile(fillRect, aHFill, aVFill, aUnitSize, repeatSize);
CSSIntSize imageSize(nsPresContext::AppUnitsToIntCSSPixels(srcRect.width),
nsPresContext::AppUnitsToIntCSSPixels(srcRect.height));
return nsLayoutUtils::DrawBackgroundImage(*aRenderingContext.ThebesContext(),
aPresContext,
subImage, imageSize, samplingFilter,
tile, fillRect, repeatSize,
tile.TopLeft(), aDirtyRect,
drawFlags,
ExtendMode::CLAMP);
}
nsRect destTile = RequiresScaling(aFill, aHFill, aVFill, aUnitSize)
? ComputeTile(aFill, aHFill, aVFill, aUnitSize)
: aFill;
nsSize repeatSize(aFill.Size());
nsRect fillRect(aFill);
nsRect destTile = RequiresScaling(fillRect, aHFill, aVFill, aUnitSize)
? ComputeTile(fillRect, aHFill, aVFill, aUnitSize, repeatSize)
: fillRect;
return Draw(aPresContext, aRenderingContext, aDirtyRect, destTile,
aFill, destTile.TopLeft(), destTile.Size(), aSrc);
fillRect, destTile.TopLeft(), repeatSize, aSrc);
}
bool

View File

@ -121,7 +121,7 @@ function do_test() {
"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "physical", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "repeat", "rgb", "rgba", "ridge", "rosybrown", "round", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey",
"snow", "solid", "springgreen", "steelblue", "stretch", "tan", "teal", "thick", "thin", "thistle", "tomato",
"snow", "solid", "space", "springgreen", "steelblue", "stretch", "tan", "teal", "thick", "thin", "thistle", "tomato",
"transparent", "turquoise", "-moz-element", "-moz-image-rect", "url", "violet", "wheat", "white", "whitesmoke",
"yellow", "yellowgreen", "linear-gradient", "radial-gradient", "repeating-linear-gradient",
"repeating-radial-gradient", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient",

View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
width: 81px;
height: 81px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner2 {
position: absolute;
top: 0px;
left: 31px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner3 {
position: absolute;
top: 0px;
left: 62px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner4 {
position: absolute;
top: 31px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner5 {
position: absolute;
top: 31px;
left: 62px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner6 {
position: absolute;
top: 62px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner7 {
position: absolute;
top: 62px;
left: 31px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner8 {
position: absolute;
top: 62px;
left: 62px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2"></div>
<div class="inner3"></div>
<div class="inner4"></div>
<div class="inner5"></div>
<div class="inner6"></div>
<div class="inner7"></div>
<div class="inner8"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-1-ref.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' uses the correct formula when a single image fits.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: space space;
width: 35px;
height: 35px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: round</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
width: 67px;
height: 67px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner2 {
position: absolute;
top: 0px;
left: 40px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner3 {
position: absolute;
top: 40px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner4 {
position: absolute;
top: 40px;
left: 40px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2"></div>
<div class="inner3"></div>
<div class="inner4"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-2-ref.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' uses the correct formula when no images fit.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: space space;
width: 13px;
height: 13px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
width: 114px;
height: 114px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner2_1 {
position: absolute;
top: 0px;
left: 29px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner2_2 {
position: absolute;
top: 0px;
left: 58px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner3 {
position: absolute;
top: 0px;
left: 87px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner4_1 {
position: absolute;
top: 29px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner4_2 {
position: absolute;
top: 58px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner5_1 {
position: absolute;
top: 29px;
left: 87px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner5_2 {
position: absolute;
top: 58px;
left: 87px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner6 {
position: absolute;
top: 87px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner7_1 {
position: absolute;
top: 87px;
left: 29px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner7_2 {
position: absolute;
top: 87px;
left: 58px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner8 {
position: absolute;
top: 87px;
left: 87px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2_1"></div>
<div class="inner2_2"></div>
<div class="inner3"></div>
<div class="inner4_1"></div>
<div class="inner4_2"></div>
<div class="inner5_1"></div>
<div class="inner5_2"></div>
<div class="inner6"></div>
<div class="inner7_1"></div>
<div class="inner7_2"></div>
<div class="inner8"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-3-ref.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' uses the correct formula when multiple images fit.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: space space;
width: 60px;
height: 60px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="match" href="border-image-repeat-space-4-ref-2.html">
<style type="text/css">
.outer {
width: 81px;
height: 81px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner2 {
position: absolute;
top: 0px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner3 {
position: absolute;
top: 0px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner4 {
position: absolute;
top: 27px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner5 {
position: absolute;
top: 27px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner6 {
position: absolute;
top: 54px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner7 {
position: absolute;
top: 54px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner8 {
position: absolute;
top: 54px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2"></div>
<div class="inner3"></div>
<div class="inner4"></div>
<div class="inner5"></div>
<div class="inner6"></div>
<div class="inner7"></div>
<div class="inner8"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: stretch stretch;
width: 27px;
height: 27px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-4-ref-1.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' uses the correct formula when a single image fits exactly.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: space space;
width: 27px;
height: 27px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="match" href="border-image-repeat-space-5-ref-2.html">
<style type="text/css">
.outer {
width: 135px;
height: 135px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner2_1 {
position: absolute;
top: 0px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner2_2 {
position: absolute;
top: 0px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner2_3 {
position: absolute;
top: 0px;
left: 81px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px 0px;
}
.inner3 {
position: absolute;
top: 0px;
left: 108px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner4_1 {
position: absolute;
top: 27px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner4_2 {
position: absolute;
top: 54px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner4_3 {
position: absolute;
top: 81px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: 0px -27px;
}
.inner5_1 {
position: absolute;
top: 27px;
left: 108px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner5_2 {
position: absolute;
top: 54px;
left: 108px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner5_3 {
position: absolute;
top: 81px;
left: 108px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -54px -27px;
}
.inner6 {
position: absolute;
top: 108px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
.inner7_1 {
position: absolute;
top: 108px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner7_2 {
position: absolute;
top: 108px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner7_3 {
position: absolute;
top: 108px;
left: 81px;
width: 27px;
height: 27px;
background-image: url("border.png");
background-position: -27px -54px;
}
.inner8 {
position: absolute;
top: 108px;
left: 108px;
width: 27px;
height: 27px;
background-image: url("border.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2_1"></div>
<div class="inner2_2"></div>
<div class="inner2_3"></div>
<div class="inner3"></div>
<div class="inner4_1"></div>
<div class="inner4_2"></div>
<div class="inner4_3"></div>
<div class="inner5_1"></div>
<div class="inner5_2"></div>
<div class="inner5_3"></div>
<div class="inner6"></div>
<div class="inner7_1"></div>
<div class="inner7_2"></div>
<div class="inner7_3"></div>
<div class="inner8"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: repeat repeat;
width: 81px;
height: 81px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-5-ref-1.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' uses the correct formula when multiple images fit exactly.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border: 27px solid transparent;
border-image: url("border.png") 27;
border-image-repeat: space space;
width: 81px;
height: 81px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
width: 81px;
height: 81px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-tl.png");
}
.inner2 {
position: absolute;
top: 0px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("reticule-to.png");
}
.inner3 {
position: absolute;
top: 0px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("reticule-tr.png");
}
.inner4 {
position: absolute;
top: 27px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-le.png");
}
.inner5 {
position: absolute;
top: 27px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("reticule-ct.png");
}
.inner6 {
position: absolute;
top: 27px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("reticule-ri.png");
}
.inner7 {
position: absolute;
top: 54px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-bl.png");
}
.inner8 {
position: absolute;
top: 54px;
left: 27px;
width: 27px;
height: 27px;
background-image: url("reticule-bo.png");
}
.inner9 {
position: absolute;
top: 54px;
left: 54px;
width: 27px;
height: 27px;
background-image: url("reticule-br.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2"></div>
<div class="inner3"></div>
<div class="inner4"></div>
<div class="inner5"></div>
<div class="inner6"></div>
<div class="inner7"></div>
<div class="inner8"></div>
<div class="inner9"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-6-ref.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' with 'fill' uses the correct formula when a single image fits exactly.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border-width: 27px;
border-style: solid;
border-image: url("reticule.png") 27 fill space;
width: 27px;
height: 27px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -0,0 +1,164 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<style type="text/css">
.outer {
width: 132px;
height: 132px;
}
.inner1 {
position: absolute;
top: 0px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-tl.png");
}
.inner2_1 {
position: absolute;
top: 0px;
left: 35px;
width: 27px;
height: 27px;
background-image: url("reticule-to.png");
}
.inner2_2 {
position: absolute;
top: 0px;
left: 70px;
width: 27px;
height: 27px;
background-image: url("reticule-to.png");
}
.inner3 {
position: absolute;
top: 0px;
left: 105px;
width: 27px;
height: 27px;
background-image: url("reticule-tr.png");
}
.inner4_1 {
position: absolute;
top: 35px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-le.png");
}
.inner4_2 {
position: absolute;
top: 70px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-le.png");
}
.inner5_1 {
position: absolute;
top: 35px;
left: 35px;
width: 27px;
height: 27px;
background-image: url("reticule-ct.png");
}
.inner5_2 {
position: absolute;
top: 35px;
left: 70px;
width: 27px;
height: 27px;
background-image: url("reticule-ct.png");
}
.inner5_3 {
position: absolute;
top: 70px;
left: 35px;
width: 27px;
height: 27px;
background-image: url("reticule-ct.png");
}
.inner5_4 {
position: absolute;
top: 70px;
left: 70px;
width: 27px;
height: 27px;
background-image: url("reticule-ct.png");
}
.inner6_1 {
position: absolute;
top: 35px;
left: 105px;
width: 27px;
height: 27px;
background-image: url("reticule-ri.png");
}
.inner6_2 {
position: absolute;
top: 70px;
left: 105px;
width: 27px;
height: 27px;
background-image: url("reticule-ri.png");
}
.inner7 {
position: absolute;
top: 105px;
left: 0px;
width: 27px;
height: 27px;
background-image: url("reticule-bl.png");
}
.inner8_1 {
position: absolute;
top: 105px;
left: 35px;
width: 27px;
height: 27px;
background-image: url("reticule-bo.png");
}
.inner8_2 {
position: absolute;
top: 105px;
left: 70px;
width: 27px;
height: 27px;
background-image: url("reticule-bo.png");
}
.inner9 {
position: absolute;
top: 105px;
left: 105px;
width: 27px;
height: 27px;
background-image: url("reticule-br.png");
}
</style>
</head>
<body>
<div class="outer">
<div class="inner1"></div>
<div class="inner2_1"></div>
<div class="inner2_2"></div>
<div class="inner3"></div>
<div class="inner4_1"></div>
<div class="inner4_2"></div>
<div class="inner5_1"></div>
<div class="inner5_2"></div>
<div class="inner5_3"></div>
<div class="inner5_4"></div>
<div class="inner6_1"></div>
<div class="inner6_2"></div>
<div class="inner7"></div>
<div class="inner8_1"></div>
<div class="inner8_2"></div>
<div class="inner9"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Border Image: border-image-repeat: space</title>
<link rel="author" title="Ethan Lin" href="mailto:ethlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css3-background/#the-border-image-repeat">
<link rel="match" href="border-image-repeat-space-7-ref.html">
<meta name="assert" content="The test checks whether border-image-repeat: 'space' with 'fill' uses the correct formula when multiple image fit.">
<style type="text/css">
.outer {
position: absolute;
left: 0px;
top: 0px;
border-width: 27px;
border-style: solid;
border-image: url("reticule.png") 27 fill space;
width: 78px;
height: 78px;
}
</style>
</head>
<body>
<div class="outer"></div>
</body>
</html>

View File

@ -23,3 +23,12 @@
#border-image test cases
== border-image-repeat-round-1.html border-image-repeat-round-1-ref.html
== border-image-repeat-round-2.html border-image-repeat-round-2-ref.html
== border-image-repeat-space-1.html border-image-repeat-space-1-ref.html
== border-image-repeat-space-2.html border-image-repeat-space-2-ref.html
== border-image-repeat-space-3.html border-image-repeat-space-3-ref.html
== border-image-repeat-space-4.html border-image-repeat-space-4-ref-1.html
== border-image-repeat-space-4.html border-image-repeat-space-4-ref-2.html
== border-image-repeat-space-5.html border-image-repeat-space-5-ref-1.html
== border-image-repeat-space-5.html border-image-repeat-space-5-ref-2.html
== border-image-repeat-space-6.html border-image-repeat-space-6-ref.html
== border-image-repeat-space-7.html border-image-repeat-space-7-ref.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@ -1004,6 +1004,7 @@ const KTableEntry nsCSSProps::kBorderImageRepeatKTable[] = {
{ eCSSKeyword_stretch, NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH },
{ eCSSKeyword_repeat, NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT },
{ eCSSKeyword_round, NS_STYLE_BORDER_IMAGE_REPEAT_ROUND },
{ eCSSKeyword_space, NS_STYLE_BORDER_IMAGE_REPEAT_SPACE },
{ eCSSKeyword_UNKNOWN, -1 }
};

View File

@ -362,6 +362,7 @@ enum class FillMode : uint32_t;
#define NS_STYLE_BORDER_IMAGE_REPEAT_STRETCH 0
#define NS_STYLE_BORDER_IMAGE_REPEAT_REPEAT 1
#define NS_STYLE_BORDER_IMAGE_REPEAT_ROUND 2
#define NS_STYLE_BORDER_IMAGE_REPEAT_SPACE 3
#define NS_STYLE_BORDER_IMAGE_SLICE_NOFILL 0
#define NS_STYLE_BORDER_IMAGE_SLICE_FILL 1

View File

@ -1063,6 +1063,7 @@ var gCSSProperties = {
"repeat url('border.png') 27 27 27 27",
"url('border.png') repeat 27 27 27 27",
"url('border.png') fill 27 27 27 27 repeat",
"url('border.png') fill 27 27 27 27 repeat space",
"url('border.png') 27 27 27 27 / 1em",
"27 27 27 27 / 1em url('border.png') ",
"url('border.png') 27 27 27 27 / 10 10 10 / 10 10 repeat",
@ -1130,7 +1131,8 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "stretch", "stretch stretch" ],
other_values: [ "round", "repeat", "stretch round", "repeat round", "stretch repeat", "round round", "repeat repeat" ],
other_values: [ "round", "repeat", "stretch round", "repeat round", "stretch repeat", "round round", "repeat repeat",
"space", "stretch space", "repeat space", "round space", "space space" ],
invalid_values: [ "none", "stretch stretch stretch", "0", "10", "0%", "0px" ]
},
"-moz-border-left-colors": {

View File

@ -8,7 +8,8 @@ LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := \
source/compare.cc \
source/compare_common.cc \
source/compare_posix.cc \
source/compare_neon64.cc \
source/compare_gcc.cc \
source/convert.cc \
source/convert_argb.cc \
source/convert_from.cc \
@ -16,20 +17,26 @@ LOCAL_SRC_FILES := \
source/convert_to_argb.cc \
source/convert_to_i420.cc \
source/cpu_id.cc \
source/format_conversion.cc \
source/planar_functions.cc \
source/rotate.cc \
source/rotate_any.cc \
source/rotate_argb.cc \
source/rotate_common.cc \
source/rotate_mips.cc \
source/rotate_neon64.cc \
source/rotate_gcc.cc \
source/row_any.cc \
source/row_common.cc \
source/row_mips.cc \
source/row_posix.cc \
source/row_neon64.cc \
source/row_gcc.cc \
source/scale.cc \
source/scale_any.cc \
source/scale_argb.cc \
source/scale_common.cc \
source/scale_mips.cc \
source/scale_posix.cc \
source/scale_neon64.cc \
source/scale_gcc.cc \
source/video_common.cc
# TODO(fbarchard): Enable mjpeg encoder.

135
media/libyuv/BUILD.gn Normal file
View File

@ -0,0 +1,135 @@
# Copyright 2014 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/config/arm.gni")
import("//build/config/sanitizers/sanitizers.gni")
config("libyuv_config") {
include_dirs = [
".",
"include",
]
}
use_neon = current_cpu == "arm64" || (current_cpu == "arm" && (arm_use_neon || arm_optionally_use_neon))
source_set("libyuv") {
sources = [
# Headers
"include/libyuv.h",
"include/libyuv/basic_types.h",
"include/libyuv/compare.h",
"include/libyuv/convert.h",
"include/libyuv/convert_argb.h",
"include/libyuv/convert_from.h",
"include/libyuv/convert_from_argb.h",
"include/libyuv/cpu_id.h",
"include/libyuv/mjpeg_decoder.h",
"include/libyuv/planar_functions.h",
"include/libyuv/rotate.h",
"include/libyuv/rotate_argb.h",
"include/libyuv/rotate_row.h",
"include/libyuv/row.h",
"include/libyuv/scale.h",
"include/libyuv/scale_argb.h",
"include/libyuv/scale_row.h",
"include/libyuv/version.h",
"include/libyuv/video_common.h",
# Source Files
"source/compare.cc",
"source/compare_common.cc",
"source/compare_gcc.cc",
"source/compare_win.cc",
"source/convert.cc",
"source/convert_argb.cc",
"source/convert_from.cc",
"source/convert_from_argb.cc",
"source/convert_jpeg.cc",
"source/convert_to_argb.cc",
"source/convert_to_i420.cc",
"source/cpu_id.cc",
"source/mjpeg_decoder.cc",
"source/mjpeg_validate.cc",
"source/planar_functions.cc",
"source/rotate.cc",
"source/rotate_any.cc",
"source/rotate_argb.cc",
"source/rotate_common.cc",
"source/rotate_mips.cc",
"source/rotate_gcc.cc",
"source/rotate_win.cc",
"source/row_any.cc",
"source/row_common.cc",
"source/row_mips.cc",
"source/row_gcc.cc",
"source/row_win.cc",
"source/scale.cc",
"source/scale_any.cc",
"source/scale_argb.cc",
"source/scale_common.cc",
"source/scale_mips.cc",
"source/scale_gcc.cc",
"source/scale_win.cc",
"source/video_common.cc",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
public_configs = [ ":libyuv_config" ]
defines = []
if (!is_ios) {
defines += [ "HAVE_JPEG" ]
}
if (is_msan) {
# 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" ]
}
if (is_nacl) {
# Always enable optimization under NaCl to workaround crbug.com/538243 .
configs -= [ "//build/config/compiler:default_optimization" ]
configs += [ "//build/config/compiler:optimize_max" ]
}
}
if (use_neon) {
static_library("libyuv_neon") {
sources = [
# ARM Source Files
"source/compare_neon.cc",
"source/compare_neon64.cc",
"source/rotate_neon.cc",
"source/rotate_neon64.cc",
"source/row_neon.cc",
"source/row_neon64.cc",
"source/scale_neon.cc",
"source/scale_neon64.cc",
]
public_configs = [ ":libyuv_config" ]
if (current_cpu != "arm64") {
configs -= [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
}
}

142
media/libyuv/CMakeLists.txt Normal file
View File

@ -0,0 +1,142 @@
cmake_minimum_required(VERSION 2.8)
# CMakeLists for libyuv
# Originally created for "roxlu build system" to compile libyuv on windows
# Run with -DTEST=ON to build unit tests
option(TEST "Built unit tests" OFF)
set(ly_base_dir ${CMAKE_CURRENT_LIST_DIR})
set(ly_src_dir ${ly_base_dir}/source/)
set(ly_inc_dir ${ly_base_dir}/include)
set(ly_lib_name "yuv")
set(ly_source_files
${ly_src_dir}/compare.cc
${ly_src_dir}/compare_common.cc
${ly_src_dir}/compare_neon.cc
${ly_src_dir}/compare_neon64.cc
${ly_src_dir}/compare_gcc.cc
${ly_src_dir}/compare_win.cc
${ly_src_dir}/convert.cc
${ly_src_dir}/convert_argb.cc
${ly_src_dir}/convert_from.cc
${ly_src_dir}/convert_from_argb.cc
${ly_src_dir}/convert_jpeg.cc
${ly_src_dir}/convert_to_argb.cc
${ly_src_dir}/convert_to_i420.cc
${ly_src_dir}/cpu_id.cc
${ly_src_dir}/mjpeg_decoder.cc
${ly_src_dir}/mjpeg_validate.cc
${ly_src_dir}/planar_functions.cc
${ly_src_dir}/rotate.cc
${ly_src_dir}/rotate_any.cc
${ly_src_dir}/rotate_argb.cc
${ly_src_dir}/rotate_common.cc
${ly_src_dir}/rotate_mips.cc
${ly_src_dir}/rotate_neon.cc
${ly_src_dir}/rotate_neon64.cc
${ly_src_dir}/rotate_gcc.cc
${ly_src_dir}/rotate_win.cc
${ly_src_dir}/row_any.cc
${ly_src_dir}/row_common.cc
${ly_src_dir}/row_mips.cc
${ly_src_dir}/row_neon.cc
${ly_src_dir}/row_neon64.cc
${ly_src_dir}/row_gcc.cc
${ly_src_dir}/row_win.cc
${ly_src_dir}/scale.cc
${ly_src_dir}/scale_any.cc
${ly_src_dir}/scale_argb.cc
${ly_src_dir}/scale_common.cc
${ly_src_dir}/scale_mips.cc
${ly_src_dir}/scale_neon.cc
${ly_src_dir}/scale_neon64.cc
${ly_src_dir}/scale_gcc.cc
${ly_src_dir}/scale_win.cc
${ly_src_dir}/video_common.cc
)
set(ly_unittest_sources
${ly_base_dir}/unit_test/basictypes_test.cc
${ly_base_dir}/unit_test/color_test.cc
${ly_base_dir}/unit_test/compare_test.cc
${ly_base_dir}/unit_test/convert_test.cc
${ly_base_dir}/unit_test/cpu_test.cc
${ly_base_dir}/unit_test/math_test.cc
${ly_base_dir}/unit_test/planar_test.cc
${ly_base_dir}/unit_test/rotate_argb_test.cc
${ly_base_dir}/unit_test/rotate_test.cc
${ly_base_dir}/unit_test/scale_argb_test.cc
${ly_base_dir}/unit_test/scale_test.cc
${ly_base_dir}/unit_test/unit_test.cc
${ly_base_dir}/unit_test/video_common_test.cc
)
set(ly_header_files
${ly_inc_dir}/libyuv/basic_types.h
${ly_inc_dir}/libyuv/compare.h
${ly_inc_dir}/libyuv/convert.h
${ly_inc_dir}/libyuv/convert_argb.h
${ly_inc_dir}/libyuv/convert_from.h
${ly_inc_dir}/libyuv/convert_from_argb.h
${ly_inc_dir}/libyuv/cpu_id.h
${ly_inc_dir}/libyuv/planar_functions.h
${ly_inc_dir}/libyuv/rotate.h
${ly_inc_dir}/libyuv/rotate_argb.h
${ly_inc_dir}/libyuv/rotate_row.h
${ly_inc_dir}/libyuv/row.h
${ly_inc_dir}/libyuv/scale.h
${ly_inc_dir}/libyuv/scale_argb.h
${ly_inc_dir}/libyuv/scale_row.h
${ly_inc_dir}/libyuv/version.h
${ly_inc_dir}/libyuv/video_common.h
${ly_inc_dir}/libyuv/mjpeg_decoder.h
)
include_directories(${ly_inc_dir})
add_library(${ly_lib_name} STATIC ${ly_source_files})
add_executable(convert ${ly_base_dir}/util/convert.cc)
target_link_libraries(convert ${ly_lib_name})
include(FindJPEG)
if (JPEG_FOUND)
include_directories(${JPEG_INCLUDE_DIR})
target_link_libraries(convert ${JPEG_LIBRARY})
add_definitions(-DHAVE_JPEG)
endif()
if(TEST)
find_library(GTEST_LIBRARY gtest)
if(GTEST_LIBRARY STREQUAL "GTEST_LIBRARY-NOTFOUND")
set(GTEST_SRC_DIR /usr/src/gtest CACHE STRING "Location of gtest sources")
if(EXISTS ${GTEST_SRC_DIR}/src/gtest-all.cc)
message(STATUS "building gtest from sources in ${GTEST_SRC_DIR}")
set(gtest_sources ${GTEST_SRC_DIR}/src/gtest-all.cc)
add_library(gtest STATIC ${gtest_sources})
include_directories(${GTEST_SRC_DIR})
include_directories(${GTEST_SRC_DIR}/include)
set(GTEST_LIBRARY gtest)
else()
message(FATAL_ERROR "TEST is set but unable to find gtest library")
endif()
endif()
add_executable(libyuv_unittest ${ly_unittest_sources})
target_link_libraries(libyuv_unittest ${ly_lib_name} ${GTEST_LIBRARY} pthread)
if (JPEG_FOUND)
target_link_libraries(libyuv_unittest ${JPEG_LIBRARY})
endif()
if(NACL AND NACL_LIBC STREQUAL "newlib")
target_link_libraries(libyuv_unittest glibc-compat)
endif()
target_link_libraries(libyuv_unittest gflags)
endif()
install(TARGETS ${ly_lib_name} DESTINATION lib)
install(FILES ${ly_header_files} DESTINATION include/libyuv)
install(FILES ${ly_inc_dir}/libyuv.h DESTINATION include/)

View File

@ -1,130 +1,42 @@
use_relative_paths = True
vars = {
"libyuv_trunk" : "https://libyuv.googlecode.com/svn/trunk",
# Override root_dir in your .gclient's custom_vars to specify a custom root
# folder name.
"root_dir": "trunk",
"extra_gyp_flag": "-Dextra_gyp_flag=0",
'root_dir': 'libyuv',
'extra_gyp_flag': '-Dextra_gyp_flag=0',
'chromium_git': 'https://chromium.googlesource.com',
# Use this googlecode_url variable only if there is an internal mirror for it.
# If you do not know, use the full path while defining your new deps entry.
"googlecode_url": "http://%s.googlecode.com/svn",
"chromium_trunk" : "http://src.chromium.org/svn/trunk",
# chrome://version/ for revision of canary Chrome.
"chromium_revision": "232627",
# Roll the Chromium Git hash to pick up newer versions of all the
# dependencies and tools linked to in setup_links.py.
'chromium_revision': '2a818f54130d8c93f81490adce5a1e87307bf5f0',
}
# NOTE: Prefer revision numbers to tags for svn deps. Use http rather than
# https; the latter can cause problems for users behind proxies.
deps = {
"../chromium_deps":
File(Var("chromium_trunk") + "/src/DEPS@" + Var("chromium_revision")),
"build":
Var("chromium_trunk") + "/src/build@" + Var("chromium_revision"),
# Needed by common.gypi.
"google_apis/build":
Var("chromium_trunk") + "/src/google_apis/build@" + Var("chromium_revision"),
"testing":
Var("chromium_trunk") + "/src/testing@" + Var("chromium_revision"),
"testing/gtest":
From("chromium_deps", "src/testing/gtest"),
"tools/clang":
Var("chromium_trunk") + "/src/tools/clang@" + Var("chromium_revision"),
"tools/gyp":
From("chromium_deps", "src/tools/gyp"),
"tools/python":
Var("chromium_trunk") + "/src/tools/python@" + Var("chromium_revision"),
"tools/valgrind":
Var("chromium_trunk") + "/src/tools/valgrind@" + Var("chromium_revision"),
# Needed by build/common.gypi.
"tools/win/supalink":
Var("chromium_trunk") + "/src/tools/win/supalink@" + Var("chromium_revision"),
"third_party/libjpeg_turbo":
From("chromium_deps", "src/third_party/libjpeg_turbo"),
# Yasm assember required for libjpeg_turbo
"third_party/yasm":
Var("chromium_trunk") + "/src/third_party/yasm@" + Var("chromium_revision"),
"third_party/yasm/source/patched-yasm":
Var("chromium_trunk") + "/deps/third_party/yasm/patched-yasm@" + Var("chromium_revision"),
Var('root_dir') + '/third_party/gflags/src':
Var('chromium_git') + '/external/github.com/gflags/gflags@03bebcb065c83beff83d50ae025a55a4bf94dfca',
}
deps_os = {
"win": {
# Use WebRTC's, stripped down, version of Cygwin (required by GYP).
"third_party/cygwin":
(Var("googlecode_url") % "webrtc") + "/deps/third_party/cygwin@2672",
# Used by libjpeg-turbo.
# TODO(fbarchard): Remove binaries and run yasm from build folder.
"third_party/yasm/binaries":
Var("chromium_trunk") + "/deps/third_party/yasm/binaries@" + Var("chromium_revision"),
"third_party/yasm": None,
},
"unix": {
"third_party/gold":
From("chromium_deps", "src/third_party/gold"),
},
"android": {
"third_party/android_tools":
From("chromium_deps", "src/third_party/android_tools"),
"third_party/libjpeg":
From("chromium_deps", "src/third_party/libjpeg"),
},
"ios": {
# NSS, for SSLClientSocketNSS.
"third_party/nss":
From("chromium_deps", "src/third_party/nss"),
"net/third_party/nss":
Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"),
# class-dump utility to generate header files for undocumented SDKs.
"testing/iossim/third_party/class-dump":
From("chromium_deps", "src/testing/iossim/third_party/class-dump"),
# Helper for running under the simulator.
"testing/iossim":
Var("chromium_trunk") + "/src/testing/iossim@" + Var("chromium_revision"),
},
}
# Define rules for which include paths are allowed in our source.
include_rules = [ '+gflags' ]
hooks = [
{
# Pull clang on mac. If nothing changed, or on non-mac platforms, this takes
# zero seconds to run. If something changed, it downloads a prebuilt clang.
"pattern": ".",
"action": ["python", Var("root_dir") + "/tools/clang/scripts/update.py",
"--mac-only"],
# Clone chromium and its deps.
'name': 'sync chromium',
'pattern': '.',
'action': ['python', '-u', Var('root_dir') + '/sync_chromium.py',
'--target-revision', Var('chromium_revision')],
},
{
# Create links to shared dependencies in Chromium.
'name': 'setup_links',
'pattern': '.',
'action': ['python', Var('root_dir') + '/setup_links.py'],
},
{
# A change to a .gyp, .gypi, or to GYP itself should run the generator.
"pattern": ".",
"action": ["python", Var("root_dir") + "/build/gyp_chromium",
"--depth=" + Var("root_dir"), Var("root_dir") + "/all.gyp",
Var("extra_gyp_flag")],
},
{
# Update the cygwin mount on Windows.
# This is necessary to get the correct mapping between e.g. /bin and the
# cygwin path on Windows. Without it we can't run bash scripts in actions.
# Ideally this should be solved in "pylib/gyp/msvs_emulation.py".
"pattern": ".",
"action": ["python", Var("root_dir") + "/build/win/setup_cygwin_mount.py",
"--win-only"],
'pattern': '.',
'action': ['python', Var('root_dir') + '/gyp_libyuv'],
},
]

View File

@ -1,2 +1,13 @@
fbarchard@chromium.org
mflodman@chromium.org
fbarchard@chromium.org
magjed@chromium.org
torbjorng@chromium.org
per-file *.gyp=kjellander@chromium.org
per-file *.gn=kjellander@chromium.org
per-file .gitignore=*
per-file AUTHORS=*
per-file DEPS=*
per-file PRESUBMIT.py=kjellander@chromium.org
per-file gyp_libyuv.py=kjellander@chromium.org
per-file setup_links.py=*
per-file sync_chromium.py=kjellander@chromium.org

65
media/libyuv/PRESUBMIT.py Normal file
View File

@ -0,0 +1,65 @@
# Copyright 2014 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 re
import sys
def GetDefaultTryConfigs(bots=None):
"""Returns a list of ('bot', set(['tests']), optionally filtered by [bots].
For WebRTC purposes, we always return an empty list of tests, since we want
to run all tests by default on all our trybots.
"""
return { 'tryserver.libyuv': dict((bot, []) for bot in bots)}
# pylint: disable=W0613
def GetPreferredTryMasters(project, change):
files = change.LocalPaths()
bots = [
'win',
'win_rel',
'win_x64_rel',
'win_x64_gn',
'win_x64_gn_rel',
'win_clang',
'win_clang_rel',
'win_x64_clang_rel',
'mac',
'mac_rel',
'mac_gn',
'mac_gn_rel',
'mac_asan',
'ios',
'ios_rel',
'ios_arm64',
'ios_arm64_rel',
'linux',
'linux_rel',
'linux_gn',
'linux_gn_rel',
'linux_memcheck',
'linux_tsan2',
'linux_asan',
'linux_msan',
'linux_ubsan',
'linux_ubsan_vptr',
'android',
'android_rel',
'android_clang',
'android_arm64',
'android_mips',
'android_x64',
'android_x86',
'android_gn',
'android_gn_rel',
]
if not files or all(re.search(r'[\\/]OWNERS$', f) for f in files):
return {}
return GetDefaultTryConfigs(bots)

View File

@ -1,9 +1,8 @@
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 971
Version: 1602
License: BSD
License File: LICENSE
Description:
libyuv is an open source project that includes
YUV conversion and scaling functionality.
libyuv is an open source project that includes YUV conversion and scaling functionality.

18
media/libyuv/README.md Normal file
View File

@ -0,0 +1,18 @@
**libyuv** is an open source project that includes YUV scaling and conversion functionality.
* Scale YUV to prepare content for compression, with point, bilinear or box filter.
* Convert to YUV from webcam formats.
* Convert from YUV to formats for rendering/effects.
* Rotate by 90/180/270 degrees to adjust for mobile devices in portrait mode.
* Optimized for SSE2/SSSE3/AVX2 on x86/x64.
* Optimized for Neon on Arm.
* Optimized for DSP R2 on Mips.
### Development
See [Getting started] [1] for instructions on how to get started developing.
You can also browse the [docs directory] [2] for more documentation.
[1]: https://chromium.googlesource.com/libyuv/libyuv/+/master/docs/getting_started.md
[2]: https://chromium.googlesource.com/libyuv/libyuv/+/master/docs/

View File

@ -0,0 +1,15 @@
# 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.
# Using same overrides as WebRTC
# See https://bugs.chromium.org/p/webrtc/issues/detail?id=5453.
# Some WebRTC targets require the 10.7 deployment version of the Mac SDK and a
# 10.11 min SDK but those targets are only used in non-Chromium builds. We can
# remove this when Chromium drops 10.6 support and also requires 10.7.
mac_sdk_min_build_override = "10.11"
mac_deployment_target_build_override = "10.7"

View File

@ -0,0 +1,5 @@
This .gclient file is used to do download a copy of Chromium.
Libyuv uses the Chromium build toolchain and a number of shared
dependencies by creating symlinks to folders in this checkout,
using the ../setup_links.py script.

View File

@ -1,9 +1,10 @@
# This file is used by gcl to get repository specific information.
# The LibYuv code review is via WebRtc's code review
CODE_REVIEW_SERVER: webrtc-codereview.appspot.com
CODE_REVIEW_SERVER: codereview.chromium.org
#CC_LIST:
VIEW_VC: https://code.google.com/p/libyuv/source/detail?r=
VIEW_VC: https://chromium.googlesource.com/libyuv/libyuv/+/
#STATUS:
FORCE_HTTPS_COMMIT_URL: True
PROJECT: libyuv
TRY_ON_UPLOAD: False
TRYSERVER_ROOT: src
TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-libyuv

View File

@ -0,0 +1,32 @@
# Introduction
For test purposes, environment variables can be set to control libyuv behavior. These should only be used for testing, to narrow down bugs or to test performance.
# CPU
By default the cpu is detected and the most advanced form of SIMD is used. But you can disable instruction sets selectively, or completely, falling back on C code. Set the variable to 1 to disable the specified instruction set.
LIBYUV_DISABLE_ASM
LIBYUV_DISABLE_X86
LIBYUV_DISABLE_SSE2
LIBYUV_DISABLE_SSSE3
LIBYUV_DISABLE_SSE41
LIBYUV_DISABLE_SSE42
LIBYUV_DISABLE_AVX
LIBYUV_DISABLE_AVX2
LIBYUV_DISABLE_AVX3
LIBYUV_DISABLE_ERMS
LIBYUV_DISABLE_FMA3
LIBYUV_DISABLE_DSPR2
LIBYUV_DISABLE_NEON
# Test Width/Height/Repeat
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.
set LIBYUV_WIDTH=1280
set LIBYUV_HEIGHT=720
set LIBYUV_REPEAT=999
set LIBYUV_FLAGS=-1
set LIBYUV_CPU_INFO=-1

View File

@ -0,0 +1,196 @@
# Introduction
This document discusses the current state of filtering in libyuv. An emphasis on maximum performance while avoiding memory exceptions, and minimal amount of code/complexity. See future work at end.
# LibYuv Filter Subsampling
There are 2 challenges with subsampling
1. centering of samples, which involves clamping on edges
2. clipping a source region
Centering depends on scale factor and filter mode.
# Down Sampling
If scaling down, the stepping rate is always src_width / dst_width.
dx = src_width / dst_width;
e.g. If scaling from 1280x720 to 640x360, the step thru the source will be 2.0, stepping over 2 pixels of source for each pixel of destination.
Centering, depends on filter mode.
*Point* downsampling takes the middle pixel.
x = dx >> 1;
For odd scale factors (e.g. 3x down) this is exactly the middle. For even scale factors, this rounds up and takes the pixel to the right of center. e.g. scale of 4x down will take pixel 2.
**Bilinear** filter, uses the 2x2 pixels in the middle.
x = dx / 2 - 0.5;
For odd scale factors (e.g. 3x down) this is exactly the middle, and point sampling is used.
For even scale factors, this evenly filters the middle 2x2 pixels. e.g. 4x down will filter pixels 1,2 at 50% in both directions.
**Box** filter averages the entire box so sampling starts at 0.
x = 0;
For a scale factor of 2x down, this is equivalent to bilinear.
# Up Sampling
**Point** upsampling use stepping rate of src_width / dst_width and a starting coordinate of 0.
x = 0;
dx = src_width / dst_width;
e.g. If scaling from 640x360 to 1280x720 the step thru the source will be 0.0, stepping half a pixel of source for each pixel of destination. Each pixel is replicated by the scale factor.
**Bilinear** filter stretches such that the first pixel of source maps to the first pixel of destination, and the last pixel of source maps to the last pixel of destination.
x = 0;
dx = (src_width - 1) / (dst_width - 1);
This method is not technically correct, and will likely change in the future.
* It is inconsistent with the bilinear down sampler. The same method could be used for down sampling, and then it would be more reversible, but that would prevent specialized 2x down sampling.
* Although centered, the image is slightly magnified.
* The filtering was changed in early 2013 - previously it used:
x = 0;
dx = (src_width - 1) / (dst_width - 1);
Which is the correct scale factor, but shifted the image left, and extruded the last pixel. The reason for the change was to remove the extruding code from the low level row functions, allowing 3 functions to sshare the same row functions - ARGBScale, I420Scale, and ARGBInterpolate. Then the one function was ported to many cpu variations: SSE2, SSSE3, AVX2, Neon and 'Any' version for any number of pixels and alignment. The function is also specialized for 0,25,50,75%.
The above goes still has the potential to read the last pixel 100% and last pixel + 1 0%, which may cause a memory exception. So the left pixel goes to a fraction less than the last pixel, but filters in the minimum amount of it, and the maximum of the last pixel.
dx = FixedDiv((src_width << 16) - 0x00010001, (dst << 16) - 0x00010000);
**Box** filter for upsampling switches over to Bilinear.
# Scale snippet:
#define CENTERSTART(dx, s) (dx < 0) ? -((-dx >> 1) + s) : ((dx >> 1) + s)
#define FIXEDDIV1(src, dst) FixedDiv((src << 16) - 0x00010001, \
(dst << 16) - 0x00010000);
// Compute slope values for stepping.
void ScaleSlope(int src_width, int src_height,
int dst_width, int dst_height,
FilterMode filtering,
int* x, int* y, int* dx, int* dy) {
assert(x != NULL);
assert(y != NULL);
assert(dx != NULL);
assert(dy != NULL);
assert(src_width != 0);
assert(src_height != 0);
assert(dst_width > 0);
assert(dst_height > 0);
if (filtering == kFilterBox) {
// Scale step for point sampling duplicates all pixels equally.
*dx = FixedDiv(Abs(src_width), dst_width);
*dy = FixedDiv(src_height, dst_height);
*x = 0;
*y = 0;
} else if (filtering == kFilterBilinear) {
// Scale step for bilinear sampling renders last pixel once for upsample.
if (dst_width <= Abs(src_width)) {
*dx = FixedDiv(Abs(src_width), dst_width);
*x = CENTERSTART(*dx, -32768);
} else if (dst_width > 1) {
*dx = FIXEDDIV1(Abs(src_width), dst_width);
*x = 0;
}
if (dst_height <= src_height) {
*dy = FixedDiv(src_height, dst_height);
*y = CENTERSTART(*dy, -32768); // 32768 = -0.5 to center bilinear.
} else if (dst_height > 1) {
*dy = FIXEDDIV1(src_height, dst_height);
*y = 0;
}
} else if (filtering == kFilterLinear) {
// Scale step for bilinear sampling renders last pixel once for upsample.
if (dst_width <= Abs(src_width)) {
*dx = FixedDiv(Abs(src_width), dst_width);
*x = CENTERSTART(*dx, -32768);
} else if (dst_width > 1) {
*dx = FIXEDDIV1(Abs(src_width), dst_width);
*x = 0;
}
*dy = FixedDiv(src_height, dst_height);
*y = *dy >> 1;
} else {
// Scale step for point sampling duplicates all pixels equally.
*dx = FixedDiv(Abs(src_width), dst_width);
*dy = FixedDiv(src_height, dst_height);
*x = CENTERSTART(*dx, 0);
*y = CENTERSTART(*dy, 0);
}
// Negative src_width means horizontally mirror.
if (src_width < 0) {
*x += (dst_width - 1) * *dx;
*dx = -*dx;
src_width = -src_width;
}
}
# Future Work
Point sampling should ideally be the same as bilinear, but pixel by pixel, round to nearest neighbor. But as is, it is reversible and exactly matches ffmpeg at all scale factors, both up and down. The scale factor is
dx = src_width / dst_width;
The step value is centered for down sample:
x = dx / 2;
Or starts at 0 for upsample.
x = 0;
Bilinear filtering is currently correct for down sampling, but not for upsampling.
Upsampling is stretching the first and last pixel of source, to the first and last pixel of destination.
dx = (src_width - 1) / (dst_width - 1);<br>
x = 0;
It should be stretching such that the first pixel is centered in the middle of the scale factor, to match the pixel that would be sampled for down sampling by the same amount. And same on last pixel.
dx = src_width / dst_width;<br>
x = dx / 2 - 0.5;
This would start at -0.5 and go to last pixel + 0.5, sampling 50% from last pixel + 1.
Then clamping would be needed. On GPUs there are numerous ways to clamp.
1. Clamp the coordinate to the edge of the texture, duplicating the first and last pixel.
2. Blend with a constant color, such as transparent black. Typically best for fonts.
3. Mirror the UV coordinate, which is similar to clamping. Good for continuous tone images.
4. Wrap the coordinate, for texture tiling.
5. Allow the coordinate to index beyond the image, which may be the correct data if sampling a subimage.
6. Extrapolate the edge based on the previous pixel. pixel -0.5 is computed from slope of pixel 0 and 1.
Some of these are computational, even for a GPU, which is one reason textures are sometimes limited to power of 2 sizes.
We do care about the clipping case, where allowing coordinates to become negative and index pixels before the image is the correct data. But normally for simple scaling, we want to clamp to the edge pixel. For example, if bilinear scaling from 3x3 to 30x30, wed essentially want 10 pixels of each of the original 3 pixels. But we want the original pixels to land in the middle of each 10 pixels, at offsets 5, 15 and 25. There would be filtering between 5 and 15 between the original pixels 0 and 1. And filtering between 15 and 25 from original pixels 1 and 2. The first 5 pixels are clamped to pixel 0 and the last 5 pixels are clamped to pixel 2.
The easiest way to implement this is copy the original 3 pixels to a buffer, and duplicate the first and last pixels. 0,1,2 becomes 0, 0,1,2, 2. Then implement a filtering without clamping. We call this source extruding. Its only necessary on up sampling, since down sampler will always have valid surrounding pixels.
Extruding is practical when the image is already copied to a temporary buffer. It could be done to the original image, as long as the original memory is restored, but valgrind and/or memory protection would disallow this, so it requires a memcpy to a temporary buffer, which may hurt performance. The memcpy has a performance advantage, from a cache point of view, that can actually make this technique faster, depending on hardware characteristics.
Vertical extrusion can be done with a memcpy of the first/last row, or clamping a pointer.
The other way to implement clamping is handle the edges with a memset. e.g. Read first source pixel and memset the first 5 pixels. Filter pixels 0,1,2 to 5 to 25. Read last pixel and memset the last 5 pixels. Blur is implemented with this method like this, which has 3 loops per row - left, middle and right.
Box filter is only used for 2x down sample or more. Its based on integer sized boxes. Technically it should be filtered edges, but thats substantially slower (roughly 100x), and at that point you may as well do a cubic filter which is more correct.
Box filter currently sums rows into a row buffer. It does this with
Mirroring will use the same slope as normal, but with a negative.
The starting coordinate needs to consider the scale factor and filter. e.g. box filter of 30x30 to 3x3 with mirroring would use -10 for step, but x = 20. width (30) - dx.
Step needs to be accurate, so it uses an integer divide. This is as much as 5% of the profile. An approximated divide is substantially faster, but the inaccuracy causes stepping beyond the original image boundaries. 3 general solutions:
1. copy image to buffer with padding. allows for small errors in stepping.
2. hash the divide, so common values are quickly found.
3. change api so caller provides the slope.

View File

@ -0,0 +1,133 @@
# Introduction
Formats (FOURCC) supported by libyuv are detailed here.
# Core Formats
There are 2 core formats supported by libyuv - I420 and ARGB. All YUV formats can be converted to/from I420. All RGB formats can be converted to/from ARGB.
Filtering functions such as scaling and planar functions work on I420 and/or ARGB.
# OSX Core Media Pixel Formats
This is how OSX formats map to libyuv
enum {
kCMPixelFormat_32ARGB = 32, FOURCC_BGRA
kCMPixelFormat_32BGRA = 'BGRA', FOURCC_ARGB
kCMPixelFormat_24RGB = 24, FOURCC_RAW
kCMPixelFormat_16BE555 = 16, Not supported.
kCMPixelFormat_16BE565 = 'B565', Not supported.
kCMPixelFormat_16LE555 = 'L555', FOURCC_RGBO
kCMPixelFormat_16LE565 = 'L565', FOURCC_RGBP
kCMPixelFormat_16LE5551 = '5551', FOURCC_RGBO
kCMPixelFormat_422YpCbCr8 = '2vuy', FOURCC_UYVY
kCMPixelFormat_422YpCbCr8_yuvs = 'yuvs', FOURCC_YUY2
kCMPixelFormat_444YpCbCr8 = 'v308', FOURCC_I444 ?
kCMPixelFormat_4444YpCbCrA8 = 'v408', Not supported.
kCMPixelFormat_422YpCbCr16 = 'v216', Not supported.
kCMPixelFormat_422YpCbCr10 = 'v210', FOURCC_V210 previously. Removed now.
kCMPixelFormat_444YpCbCr10 = 'v410', Not supported.
kCMPixelFormat_8IndexedGray_WhiteIsZero = 0x00000028, Not supported.
};
# FOURCC (Four Charactacter Code) List
The following is extracted from video_common.h as a complete list of formats supported by libyuv.
enum FourCC {
// 9 Primary YUV formats: 5 planar, 2 biplanar, 2 packed.
FOURCC_I420 = FOURCC('I', '4', '2', '0'),
FOURCC_I422 = FOURCC('I', '4', '2', '2'),
FOURCC_I444 = FOURCC('I', '4', '4', '4'),
FOURCC_I411 = FOURCC('I', '4', '1', '1'),
FOURCC_I400 = FOURCC('I', '4', '0', '0'),
FOURCC_NV21 = FOURCC('N', 'V', '2', '1'),
FOURCC_NV12 = FOURCC('N', 'V', '1', '2'),
FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'),
FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'),
// 2 Secondary YUV formats: row biplanar.
FOURCC_M420 = FOURCC('M', '4', '2', '0'),
FOURCC_Q420 = FOURCC('Q', '4', '2', '0'),
// 9 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp.
FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'),
FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'),
FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'),
FOURCC_24BG = FOURCC('2', '4', 'B', 'G'),
FOURCC_RAW = FOURCC('r', 'a', 'w', ' '),
FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'),
FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // rgb565 LE.
FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE.
FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE.
// 4 Secondary RGB formats: 4 Bayer Patterns.
FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'),
FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'),
FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'),
FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'),
// 1 Primary Compressed YUV format.
FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
// 5 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'),
FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420.
FOURCC_J420 = FOURCC('J', '4', '2', '0'),
FOURCC_J400 = FOURCC('J', '4', '0', '0'),
// 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc.
FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420.
FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'), // Alias for I422.
FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'), // Alias for I444.
FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2.
FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2 on Mac.
FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY.
FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY on Mac.
FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG.
FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac.
FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR.
FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW.
FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG.
FOURCC_CM32 = FOURCC(0, 0, 0, 32), // Alias for BGRA kCMPixelFormat_32ARGB
FOURCC_CM24 = FOURCC(0, 0, 0, 24), // Alias for RAW kCMPixelFormat_24RGB
FOURCC_L555 = FOURCC('L', '5', '5', '5'), // Alias for RGBO.
FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP.
FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO.
// 1 Auxiliary compressed YUV format set aside for capturer.
FOURCC_H264 = FOURCC('H', '2', '6', '4'),
# 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.
The fourcc describes the order of channels in a ***register***.
A fourcc provided by capturer, can be thought of string, e.g. "ARGB".
On little endian machines, as an int, this would have 'A' in the lowest byte. The FOURCC macro reverses the order:
#define FOURCC(a, b, c, d) (((uint32)(a)) | ((uint32)(b) << 8) | ((uint32)(c) << 16) | ((uint32)(d) << 24))
So the "ARGB" string, read as an uint32, is
FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B')
If you were to read ARGB pixels as uint32's, the alpha would be in the high byte, and the blue in the lowest byte. In memory, these are stored little endian, so 'B' is first, then 'G', 'R' and 'A' last.
When calling conversion functions, the names match the FOURCC, so in this case it would be I420ToARGB().
All formats can be converted to/from ARGB.
Most 'planar_functions' work on ARGB (e.g. ARGBBlend).
Some are channel order agnostic (e.g. ARGBScale).
Some functions are symmetric (e.g. ARGBToBGRA is the same as BGRAToARGB, so its a macro).
ARGBBlend expects preattenuated ARGB. The R,G,B are premultiplied by alpha. Other functions don't care.

View File

@ -0,0 +1,429 @@
# Getting Started
How to get and build the libyuv code.
## Pre-requisites
You'll need to have depot tools installed: https://www.chromium.org/developers/how-tos/install-depot-tools
Refer to chromium instructions for each platform for other prerequisites.
## Getting the Code
Create a working directory, enter it, and run:
gclient config https://chromium.googlesource.com/libyuv/libyuv
gclient sync
Then you'll get a .gclient file like:
solutions = [
{ "name" : "libyuv",
"url" : "https://chromium.googlesource.com/libyuv/libyuv",
"deps_file" : "DEPS",
"managed" : True,
"custom_deps" : {
},
"safesync_url": "",
},
];
For iOS add `;target_os=['ios'];` to your OSX .gclient and run `GYP_DEFINES="OS=ios" gclient sync.`
Browse the Git reprository: https://chromium.googlesource.com/libyuv/libyuv/+/master
### Android
For Android add `;target_os=['android'];` to your Linux .gclient
solutions = [
{ "name" : "libyuv",
"url" : "https://chromium.googlesource.com/libyuv/libyuv",
"deps_file" : "DEPS",
"managed" : True,
"custom_deps" : {
},
"safesync_url": "",
},
];
target_os = ["android", "unix"];
Then run:
export GYP_DEFINES="OS=android"
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:
cd chromium/src
./build/android/play_services/update.py download
cd ../..
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`
To get just the source (not buildable):
git clone https://chromium.googlesource.com/libyuv/libyuv
## Building the Library and Unittests
### Windows
set GYP_DEFINES=target_arch=ia32
call python gyp_libyuv -fninja -G msvs_version=2013
ninja -j7 -C out\Release
ninja -j7 -C out\Debug
set GYP_DEFINES=target_arch=x64
call python gyp_libyuv -fninja -G msvs_version=2013
ninja -C out\Debug_x64
ninja -C out\Release_x64
#### Building with clangcl
set GYP_DEFINES=clang=1 target_arch=ia32 libyuv_enable_svn=1
set LLVM_REPO_URL=svn://svn.chromium.org/llvm-project
call python tools\clang\scripts\update.py
call python gyp_libyuv -fninja libyuv_test.gyp
ninja -C out\Debug
ninja -C out\Release
### OSX
Clang 64 bit shown. Remove `clang=1` for GCC and change x64 to ia32 for 32 bit.
GYP_DEFINES="clang=1 target_arch=x64" ./gyp_libyuv
ninja -j7 -C out/Debug
ninja -j7 -C out/Release
GYP_DEFINES="clang=1 target_arch=ia32" ./gyp_libyuv
ninja -j7 -C out/Debug
ninja -j7 -C out/Release
### iOS
http://www.chromium.org/developers/how-tos/build-instructions-ios
Add to .gclient last line: `target_os=['ios'];`
armv7
GYP_DEFINES="OS=ios target_arch=armv7 target_subarch=arm32" GYP_CROSSCOMPILE=1 GYP_GENERATOR_FLAGS="output_dir=out_ios" ./gyp_libyuv
ninja -j7 -C out_ios/Debug-iphoneos libyuv_unittest
ninja -j7 -C out_ios/Release-iphoneos libyuv_unittest
arm64
GYP_DEFINES="OS=ios target_arch=arm64 target_subarch=arm64" GYP_CROSSCOMPILE=1 GYP_GENERATOR_FLAGS="output_dir=out_ios" ./gyp_libyuv
ninja -j7 -C out_ios/Debug-iphoneos libyuv_unittest
ninja -j7 -C out_ios/Release-iphoneos libyuv_unittest
both armv7 and arm64 (fat)
GYP_DEFINES="OS=ios target_arch=armv7 target_subarch=both" GYP_CROSSCOMPILE=1 GYP_GENERATOR_FLAGS="output_dir=out_ios" ./gyp_libyuv
ninja -j7 -C out_ios/Debug-iphoneos libyuv_unittest
ninja -j7 -C out_ios/Release-iphoneos libyuv_unittest
simulator
GYP_DEFINES="OS=ios target_arch=ia32 target_subarch=arm32" GYP_CROSSCOMPILE=1 GYP_GENERATOR_FLAGS="output_dir=out_sim" ./gyp_libyuv
ninja -j7 -C out_sim/Debug-iphonesimulator libyuv_unittest
ninja -j7 -C out_sim/Release-iphonesimulator libyuv_unittest
### Android
https://code.google.com/p/chromium/wiki/AndroidBuildInstructions
Add to .gclient last line: `target_os=['android'];`
armv7
GYP_DEFINES="OS=android" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
arm64
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/Release libyuv_unittest_apk
ia32
GYP_DEFINES="OS=android target_arch=ia32" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
GYP_DEFINES="OS=android target_arch=ia32 android_full_debug=1" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
mipsel
GYP_DEFINES="OS=android target_arch=mipsel" GYP_CROSSCOMPILE=1 ./gyp_libyuv
ninja -j7 -C out/Debug libyuv_unittest_apk
ninja -j7 -C out/Release libyuv_unittest_apk
arm32 disassembly:
third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump -d out/Release/obj/source/libyuv.row_neon.o
arm64 disassembly:
third_party/android_tools/ndk/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump -d out/Release/obj/source/libyuv.row_neon64.o
Running tests:
util/android/test_runner.py gtest -s libyuv_unittest -t 7200 --verbose --release --gtest_filter=*
Running test as benchmark:
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"
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=1 --libyuv_cpu_info=1"
#### Building with GN
gn gen out/Release "--args=is_debug=false target_cpu=\"x86\""
gn gen out/Debug "--args=is_debug=true target_cpu=\"x86\""
ninja -C out/Release
ninja -C out/Debug
### Building Offical with GN
gn gen out/Official "--args=is_debug=false is_official_build=true is_chrome_branded=true"
ninja -C out/Official
### Linux
GYP_DEFINES="target_arch=x64" ./gyp_libyuv
ninja -j7 -C out/Debug
ninja -j7 -C out/Release
GYP_DEFINES="target_arch=ia32" ./gyp_libyuv
ninja -j7 -C out/Debug
ninja -j7 -C out/Release
#### CentOS
On CentOS 32 bit the following work around allows a sync:
export GYP_DEFINES="host_arch=ia32"
gclient sync
### Windows Shared Library
Modify libyuv.gyp from 'static_library' to 'shared_library', and add 'LIBYUV_BUILDING_SHARED_LIBRARY' to 'defines'.
gclient runhooks
After this command follow the building the library instructions above.
If you get a compile error for atlthunk.lib on Windows, read http://www.chromium.org/developers/how-tos/build-instructions-windows
### Build targets
ninja -C out/Debug libyuv
ninja -C out/Debug libyuv_unittest
ninja -C out/Debug compare
ninja -C out/Debug convert
ninja -C out/Debug psnr
ninja -C out/Debug cpuid
## Building the Library with make
### Linux
make -j7 V=1 -f linux.mk
make -j7 V=1 -f linux.mk clean
make -j7 V=1 -f linux.mk CXX=clang++
## Building the Library with cmake
Install cmake: http://www.cmake.org/
Default debug build:
mkdir out
cd out
cmake ..
cmake --build .
Release build/install
mkdir out
cd out
cmake -DCMAKE_INSTALL_PREFIX="/usr/lib" -DCMAKE_BUILD_TYPE="Release" ..
cmake --build . --config Release
sudo cmake --build . --target install --config Release
### Windows 8 Phone
Pre-requisite:
* Install Visual Studio 2012 and Arm to your environment.<br>
Then:
call "c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\x86_arm\vcvarsx86_arm.bat"
or with Visual Studio 2013:
call "c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_arm\vcvarsx86_arm.bat"
nmake /f winarm.mk clean
nmake /f winarm.mk
### Windows Shared Library
Modify libyuv.gyp from 'static_library' to 'shared_library', and add 'LIBYUV_BUILDING_SHARED_LIBRARY' to 'defines'. Then run this.
gclient runhooks
After this command follow the building the library instructions above.
If you get a compile error for atlthunk.lib on Windows, read http://www.chromium.org/developers/how-tos/build-instructions-windows
### 64 bit Windows
set GYP_DEFINES=target_arch=x64
gclient runhooks V=1
### ARM Linux
export GYP_DEFINES="target_arch=arm"
export CROSSTOOL=`<path>`/arm-none-linux-gnueabi
export CXX=$CROSSTOOL-g++
export CC=$CROSSTOOL-gcc
export AR=$CROSSTOOL-ar
export AS=$CROSSTOOL-as
export RANLIB=$CROSSTOOL-ranlib
gclient runhooks
## Running Unittests
### Windows
out\Release\libyuv_unittest.exe --gtest_catch_exceptions=0 --gtest_filter="*"
### OSX
out/Release/libyuv_unittest --gtest_filter="*"
### Linux
out/Release/libyuv_unittest --gtest_filter="*"
Replace --gtest_filter="*" with specific unittest to run. May include wildcards. e.g.
out/Release/libyuv_unittest --gtest_filter=libyuvTest.I420ToARGB_Opt
## CPU Emulator tools
### Intel SDE (Software Development Emulator)
Pre-requisite: Install IntelSDE for Windows: http://software.intel.com/en-us/articles/intel-software-development-emulator
Then run:
c:\intelsde\sde -hsw -- out\release\libyuv_unittest.exe --gtest_filter=*
## Memory tools
### Running Dr Memory memcheck for Windows
Pre-requisite: Install Dr Memory for Windows and add it to your path: http://www.drmemory.org/docs/page_install_windows.html
set GYP_DEFINES=build_for_tool=drmemory target_arch=ia32
call python gyp_libyuv -fninja -G msvs_version=2013
ninja -C out\Debug
drmemory out\Debug\libyuv_unittest.exe --gtest_catch_exceptions=0 --gtest_filter=*
### Running UBSan
See Chromium instructions for sanitizers: https://www.chromium.org/developers/testing/undefinedbehaviorsanitizer
Sanitizers available: TSan, MSan, ASan, UBSan, LSan
GYP_DEFINES='ubsan=1' gclient runhooks
ninja -C out/Release
### Running Valgrind memcheck
Memory errors and race conditions can be found by running tests under special memory tools. [Valgrind] [1] is an instrumentation framework for building dynamic analysis tools. Various tests and profilers are built upon it to find memory handling errors and memory leaks, for instance.
[1]: http://valgrind.org
solutions = [
{ "name" : "libyuv",
"url" : "https://chromium.googlesource.com/libyuv/libyuv",
"deps_file" : "DEPS",
"managed" : True,
"custom_deps" : {
"libyuv/chromium/src/third_party/valgrind": "https://chromium.googlesource.com/chromium/deps/valgrind/binaries",
},
"safesync_url": "",
},
]
Then run:
GYP_DEFINES="clang=0 target_arch=x64 build_for_tool=memcheck" python gyp_libyuv
ninja -C out/Debug
valgrind out/Debug/libyuv_unittest
For more information, see http://www.chromium.org/developers/how-tos/using-valgrind
### Running Thread Sanitizer (TSan)
GYP_DEFINES="clang=0 target_arch=x64 build_for_tool=tsan" python gyp_libyuv
ninja -C out/Debug
valgrind out/Debug/libyuv_unittest
For more info, see http://www.chromium.org/developers/how-tos/using-valgrind/threadsanitizer
### Running Address Sanitizer (ASan)
GYP_DEFINES="clang=0 target_arch=x64 build_for_tool=asan" python gyp_libyuv
ninja -C out/Debug
valgrind out/Debug/libyuv_unittest
For more info, see http://dev.chromium.org/developers/testing/addresssanitizer
## Benchmarking
The unittests can be used to benchmark.
### Windows
set LIBYUV_WIDTH=1280
set LIBYUV_HEIGHT=720
set LIBYUV_REPEAT=999
set LIBYUV_FLAGS=-1
out\Release\libyuv_unittest.exe --gtest_filter=*I420ToARGB_Opt
### Linux and Mac
LIBYUV_WIDTH=1280 LIBYUV_HEIGHT=720 LIBYUV_REPEAT=1000 out/Release/libyuv_unittest --gtest_filter=*I420ToARGB_Opt
libyuvTest.I420ToARGB_Opt (547 ms)
Indicates 0.547 ms/frame for 1280 x 720.
## Making a change
gclient sync
git checkout -b mycl -t origin/master
git pull
<edit files>
git add -u
git commit -m "my change"
git cl lint
git cl try
git cl upload -r a-reviewer@chomium.org -s
<once approved..>
git cl land

View File

@ -0,0 +1,103 @@
# Introduction
Rotation by multiplies of 90 degrees allows mobile devices to rotate webcams from landscape to portrait. The higher level functions ConvertToI420 and ConvertToARGB allow rotation of any format. Optimized functionality is supported for I420, ARGB, NV12 and NV21.
# ConvertToI420
int ConvertToI420(const uint8* src_frame, size_t src_size,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int crop_x, int crop_y,
int src_width, int src_height,
int crop_width, int crop_height,
enum RotationMode rotation,
uint32 format);
This function crops, converts, and rotates. You should think of it in that order.
* Crops the original image, which is src_width x src_height, to crop_width x crop_height. At this point the image is still not rotated.
* Converts the cropped region to I420. Supports inverted source for src_height negative.
* Rotates by 90, 180 or 270 degrees.
The buffer the caller provides should account for rotation. Be especially important to get stride of the destination correct.
e.g.
640 x 480 NV12 captured<br>
Crop to 640 x 360<br>
Rotate by 90 degrees to 360 x 640.<br>
Caller passes stride of 360 for Y and 360 / 2 for U and V.<br>
Caller passes crop_width of 640, crop_height of 360.<br>
# ConvertToARGB
int ConvertToARGB(const uint8* src_frame, size_t src_size,
uint8* dst_argb, int dst_stride_argb,
int crop_x, int crop_y,
int src_width, int src_height,
int crop_width, int crop_height,
enum RotationMode rotation,
uint32 format);
Same as I420, but implementation is less optimized - reads columns and writes rows, 16 bytes at a time.
# I420Rotate
int I420Rotate(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_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int src_width, int src_height, enum RotationMode mode);
Destination is rotated, so pass dst_stride_y etc that consider rotation.<br>
Rotate by 180 can be done in place, but 90 and 270 can not.
Implementation (Neon/SSE2) uses 8 x 8 block transpose, so best efficiency is with sizes and pointers that are aligned to 8.
Cropping can be achieved by adjusting the src_y/u/v pointers and src_width, src_height.
Lower level plane functions are provided, allowing other planar formats to be rotated. (e.g. I444)
For other planar YUV formats (I444, I422, I411, I400, NV16, NV24), the planar functions are exposed and can be called directly
// Rotate a plane by 0, 90, 180, or 270.
int RotatePlane(const uint8* src, int src_stride,
uint8* dst, int dst_stride,
int src_width, int src_height, enum RotationMode mode);
# ARGBRotate
LIBYUV_API
int ARGBRotate(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int src_width, int src_height, enum RotationMode mode);
Same as I420, but implementation is less optimized - reads columns and writes rows.
Rotate by 90, or any angle, can be achieved using ARGBAffine.
# Mirror - Horizontal Flip
Mirror functions for horizontally flipping an image, which can be useful for 'self view' of a webcam.
int I420Mirror(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_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
int ARGBMirror(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
Mirror functionality can also be achieved with the I420Scale and ARGBScale functions by passing negative width and/or height.
# Invert - Vertical Flip
Inverting can be achieved with almost any libyuv function by passing a negative source height.
I420Mirror and ARGBMirror can also be used to rotate by 180 degrees by passing a negative height.

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
#
# Copyright 2014 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.
# This script is used to run the vs_toolchain.py script to download the
# Visual Studio toolchain. It's just a temporary measure while waiting for the
# Chrome team to move find_depot_tools into src/build to get rid of these
# workarounds (similar one in gyp_libyuv).
import os
import sys
checkout_root = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(checkout_root, 'build'))
sys.path.insert(0, os.path.join(checkout_root, 'tools', 'find_depot_tools'))
import vs_toolchain
if __name__ == '__main__':
sys.exit(vs_toolchain.main())

101
media/libyuv/gyp_libyuv Normal file
View File

@ -0,0 +1,101 @@
#!/usr/bin/env python
#
# Copyright 2014 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.
# This script is used to run GYP for libyuv. It contains selected parts of the
# main function from the src/build/gyp_chromium file.
import glob
import os
import shlex
import sys
checkout_root = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.join(checkout_root, 'build'))
import gyp_chromium
import gyp_helper
import vs_toolchain
sys.path.insert(0, os.path.join(checkout_root, 'tools', 'gyp', 'pylib'))
import gyp
def GetSupplementalFiles():
"""Returns a list of the supplemental files that are included in all GYP
sources."""
# Can't use the one in gyp_chromium since the directory location of the root
# is different.
return glob.glob(os.path.join(checkout_root, '*', 'supplement.gypi'))
if __name__ == '__main__':
args = sys.argv[1:]
if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)):
print 'Skipping gyp_libyuv due to GYP_CHROMIUM_NO_ACTION env var.'
sys.exit(0)
# This could give false positives since it doesn't actually do real option
# parsing. Oh well.
gyp_file_specified = False
for arg in args:
if arg.endswith('.gyp'):
gyp_file_specified = True
break
# If we didn't get a file, assume 'all.gyp' in the root of the checkout.
if not gyp_file_specified:
# Because of a bug in gyp, simply adding the abspath to all.gyp doesn't
# work, but chdir'ing and adding the relative path does. Spooky :/
os.chdir(checkout_root)
args.append('all.gyp')
# There shouldn't be a circular dependency relationship between .gyp files,
args.append('--no-circular-check')
# Default to ninja unless GYP_GENERATORS is set.
if not os.environ.get('GYP_GENERATORS'):
os.environ['GYP_GENERATORS'] = 'ninja'
vs2013_runtime_dll_dirs = None
if int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')):
vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
# Enforce gyp syntax checking. This adds about 20% execution time.
args.append('--check')
supplemental_includes = gyp_chromium.GetSupplementalFiles()
gyp_vars_dict = gyp_chromium.GetGypVars(supplemental_includes)
# Automatically turn on crosscompile support for platforms that need it.
if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
gyp_vars_dict.get('OS') in ['android', 'ios'],
'GYP_CROSSCOMPILE' not in os.environ)):
os.environ['GYP_CROSSCOMPILE'] = '1'
args.extend(['-I' + i for i in
gyp_chromium.additional_include_files(supplemental_includes,
args)])
# Set the gyp depth variable to the root of the checkout.
args.append('--depth=' + os.path.relpath(checkout_root))
print 'Updating projects from gyp files...'
sys.stdout.flush()
# Off we go...
gyp_rc = gyp.main(args)
if vs2013_runtime_dll_dirs:
x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
vs_toolchain.CopyVsRuntimeDlls(
os.path.join(checkout_root, gyp_chromium.GetOutputDirectory()),
(x86_runtime, x64_runtime))
sys.exit(gyp_rc)

View File

@ -0,0 +1,28 @@
#!/usr/bin/env python
#
# Copyright 2014 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.
# This script is a modified copy of the src/build/gyp_chromium.py file.
# It is needed for parallel processing.
# This file is (possibly, depending on python version) imported by
# gyp_libyuv when GYP_PARALLEL=1 and it creates sub-processes
# through the multiprocessing library.
# Importing in Python 2.6 (fixed in 2.7) on Windows doesn't search for
# imports that don't end in .py (and aren't directories with an
# __init__.py). This wrapper makes "import gyp_libyuv" work with
# those old versions and makes it possible to execute gyp_libyuv.py
# directly on Windows where the extension is useful.
import os
path = os.path.abspath(os.path.split(__file__)[0])
execfile(os.path.join(path, 'gyp_libyuv'))

View File

@ -18,7 +18,6 @@
#include "libyuv/convert_from.h"
#include "libyuv/convert_from_argb.h"
#include "libyuv/cpu_id.h"
#include "libyuv/format_conversion.h"
#include "libyuv/mjpeg_decoder.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"

View File

@ -22,6 +22,11 @@ extern "C" {
LIBYUV_API
uint32 HashDjb2(const uint8* src, uint64 count, uint32 seed);
// Scan an opaque argb image and return fourcc based on alpha offset.
// Returns FOURCC_ARGB, FOURCC_BGRA, or 0 if unknown.
LIBYUV_API
uint32 ARGBDetect(const uint8* argb, int stride_argb, int width, int height);
// Sum Square Error - used to compute Mean Square Error or PSNR.
LIBYUV_API
uint64 ComputeSumSquareError(const uint8* src_a,

View File

@ -0,0 +1,84 @@
/*
* Copyright 2013 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_COMPARE_ROW_H_ // NOLINT
#define INCLUDE_LIBYUV_COMPARE_ROW_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if defined(__pnacl__) || defined(__CLR_VER) || \
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// Visual C 2012 required for AVX2.
#if defined(_M_IX86) && !defined(__clang__) && \
defined(_MSC_VER) && _MSC_VER >= 1700
#define VISUALC_HAS_AVX2 1
#endif // VisualStudio >= 2012
// clang >= 3.4.0 required for AVX2.
#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
#if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4))
#define CLANG_HAS_AVX2 1
#endif // clang >= 3.4
#endif // __clang__
#if !defined(LIBYUV_DISABLE_X86) && \
defined(_M_IX86) && (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
#define HAS_HASHDJB2_AVX2
#endif
// The following are available for Visual C and GCC:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(__x86_64__) || (defined(__i386__) || defined(_M_IX86)))
#define HAS_HASHDJB2_SSE41
#define HAS_SUMSQUAREERROR_SSE2
#endif
// The following are available for Visual C and clangcl 32 bit:
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && \
(defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2))
#define HAS_HASHDJB2_AVX2
#define HAS_SUMSQUAREERROR_AVX2
#endif
// The following are available for Neon:
#if !defined(LIBYUV_DISABLE_NEON) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#define HAS_SUMSQUAREERROR_NEON
#endif
uint32 SumSquareError_C(const uint8* src_a, const uint8* src_b, int count);
uint32 SumSquareError_SSE2(const uint8* src_a, const uint8* src_b, int count);
uint32 SumSquareError_AVX2(const uint8* src_a, const uint8* src_b, int count);
uint32 SumSquareError_NEON(const uint8* src_a, const uint8* src_b, int count);
uint32 HashDjb2_C(const uint8* src, int count, uint32 seed);
uint32 HashDjb2_SSE41(const uint8* src, int count, uint32 seed);
uint32 HashDjb2_AVX2(const uint8* src, int count, uint32 seed);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_COMPARE_ROW_H_ NOLINT

View File

@ -12,10 +12,8 @@
#define INCLUDE_LIBYUV_CONVERT_H_
#include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes.
#include "libyuv/convert_from.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/rotate.h" // For enum RotationMode.
#ifdef __cplusplus
namespace libyuv {
@ -71,6 +69,8 @@ int I400ToI420(const uint8* src_y, int src_stride_y,
uint8* dst_v, int dst_stride_v,
int width, int height);
#define J400ToJ420 I400ToI420
// Convert NV12 to I420.
LIBYUV_API
int NV12ToI420(const uint8* src_y, int src_stride_y,
@ -113,15 +113,6 @@ int M420ToI420(const uint8* src_m420, int src_stride_m420,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert Q420 to I420.
LIBYUV_API
int Q420ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_yuy2, int src_stride_yuy2,
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.
LIBYUV_API
int ARGBToI420(const uint8* src_frame, int src_stride_frame,
@ -211,8 +202,6 @@ int MJPGSize(const uint8* sample, size_t sample_size,
int* width, int* height);
#endif
// Note Bayer formats (BGGR) To I420 are in format_conversion.h
// Convert camera sample to I420 with cropping, rotation and vertical flip.
// "src_size" is needed to parse MJPG.
// "dst_stride_y" number of bytes in a row of the dst_y plane.

View File

@ -12,13 +12,10 @@
#define INCLUDE_LIBYUV_CONVERT_ARGB_H_
#include "libyuv/basic_types.h"
// TODO(fbarchard): Remove the following headers includes
#include "libyuv/convert_from.h"
#include "libyuv/planar_functions.h"
#include "libyuv/rotate.h"
#include "libyuv/rotate.h" // For enum RotationMode.
// TODO(fbarchard): This set of functions should exactly match convert.h
// Add missing Q420.
// TODO(fbarchard): Add tests. Create random content of right size and convert
// with C vs Opt and or to I420 and compare.
// TODO(fbarchard): Some of these functions lack parameter setting.
@ -61,6 +58,22 @@ int I444ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert J444 to ARGB.
LIBYUV_API
int J444ToARGB(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 I444 to ABGR.
LIBYUV_API
int I444ToABGR(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_abgr, int dst_stride_abgr,
int width, int height);
// Convert I411 to ARGB.
LIBYUV_API
int I411ToARGB(const uint8* src_y, int src_stride_y,
@ -69,20 +82,38 @@ int I411ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert I400 (grey) to ARGB.
// Convert I420 with Alpha to preattenuated ARGB.
LIBYUV_API
int I420AlphaToARGB(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
const uint8* src_a, int src_stride_a,
uint8* dst_argb, int dst_stride_argb,
int width, int height, int attenuate);
// Convert I420 with Alpha to preattenuated ABGR.
LIBYUV_API
int I420AlphaToABGR(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
const uint8* src_v, int src_stride_v,
const uint8* src_a, int src_stride_a,
uint8* dst_abgr, int dst_stride_abgr,
int width, int height, int attenuate);
// Convert I400 (grey) to ARGB. Reverse of ARGBToI400.
LIBYUV_API
int I400ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Alias.
#define YToARGB I400ToARGB_Reference
// Convert I400 to ARGB. Reverse of ARGBToI400.
// Convert J400 (jpeg grey) to ARGB.
LIBYUV_API
int I400ToARGB_Reference(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
int J400ToARGB(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Alias.
#define YToARGB I400ToARGB
// Convert NV12 to ARGB.
LIBYUV_API
@ -104,13 +135,6 @@ int M420ToARGB(const uint8* src_m420, int src_stride_m420,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// TODO(fbarchard): Convert Q420 to ARGB.
// LIBYUV_API
// int Q420ToARGB(const uint8* src_y, int src_stride_y,
// const uint8* src_yuy2, int src_stride_yuy2,
// uint8* dst_argb, int dst_stride_argb,
// int width, int height);
// Convert YUY2 to ARGB.
LIBYUV_API
int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
@ -123,6 +147,70 @@ int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert J420 to ARGB.
LIBYUV_API
int J420ToARGB(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 J422 to ARGB.
LIBYUV_API
int J422ToARGB(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 J420 to ABGR.
LIBYUV_API
int J420ToABGR(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_abgr, int dst_stride_abgr,
int width, int height);
// Convert J422 to ABGR.
LIBYUV_API
int J422ToABGR(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_abgr, int dst_stride_abgr,
int width, int height);
// Convert H420 to ARGB.
LIBYUV_API
int H420ToARGB(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 H422 to ARGB.
LIBYUV_API
int H422ToARGB(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 H420 to ABGR.
LIBYUV_API
int H420ToABGR(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_abgr, int dst_stride_abgr,
int width, int height);
// Convert H422 to ABGR.
LIBYUV_API
int H422ToABGR(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_abgr, int dst_stride_abgr,
int width, int height);
// BGRA little endian (argb in memory) to ARGB.
LIBYUV_API
int BGRAToARGB(const uint8* src_frame, int src_stride_frame,
@ -184,8 +272,6 @@ int MJPGToARGB(const uint8* sample, size_t sample_size,
int dst_width, int dst_height);
#endif
// Note Bayer formats (BGGR) to ARGB are in format_conversion.h.
// Convert camera sample to ARGB with cropping, rotation and vertical flip.
// "src_size" is needed to parse MJPG.
// "dst_stride_argb" number of bytes in a row of the dst_argb plane.

View File

@ -56,9 +56,6 @@ int I400Copy(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height);
// TODO(fbarchard): I420ToM420
// TODO(fbarchard): I420ToQ420
LIBYUV_API
int I420ToNV12(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
@ -138,6 +135,17 @@ int I420ToRGB565(const uint8* src_y, int src_stride_y,
uint8* dst_frame, int dst_stride_frame,
int width, int height);
// Convert I420 To RGB565 with 4x4 dither matrix (16 bytes).
// Values in dither matrix from 0 to 7 recommended.
// The order of the dither matrix is first byte is upper left.
LIBYUV_API
int I420ToRGB565Dither(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_frame, int dst_stride_frame,
const uint8* dither4x4, int width, int height);
LIBYUV_API
int I420ToARGB1555(const uint8* src_y, int src_stride_y,
const uint8* src_u, int src_stride_u,
@ -152,8 +160,6 @@ int I420ToARGB4444(const uint8* src_y, int src_stride_y,
uint8* dst_frame, int dst_stride_frame,
int width, int height);
// Note Bayer formats (BGGR) To I420 are in format_conversion.h.
// Convert I420 to specified format.
// "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the
// buffer has contiguous rows. Can be negative. A multiple of 16 is optimal.

View File

@ -25,24 +25,22 @@ int ARGBCopy(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert ARGB To BGRA. (alias)
#define ARGBToBGRA BGRAToARGB
// Convert ARGB To BGRA.
LIBYUV_API
int BGRAToARGB(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int ARGBToBGRA(const uint8* src_argb, int src_stride_argb,
uint8* dst_bgra, int dst_stride_bgra,
int width, int height);
// Convert ARGB To ABGR. (alias)
#define ARGBToABGR ABGRToARGB
// Convert ARGB To ABGR.
LIBYUV_API
int ABGRToARGB(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int ARGBToABGR(const uint8* src_argb, int src_stride_argb,
uint8* dst_abgr, int dst_stride_abgr,
int width, int height);
// Convert ARGB To RGBA.
LIBYUV_API
int ARGBToRGBA(const uint8* src_frame, int src_stride_frame,
uint8* dst_argb, int dst_stride_argb,
int ARGBToRGBA(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgba, int dst_stride_rgba,
int width, int height);
// Convert ARGB To RGB24.
@ -63,6 +61,16 @@ int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes).
// Values in dither matrix from 0 to 7 recommended.
// The order of the dither matrix is first byte is upper left.
// TODO(fbarchard): Consider pointer to 2d array for dither4x4.
// const uint8(*dither)[4][4];
LIBYUV_API
int ARGBToRGB565Dither(const uint8* src_argb, int src_stride_argb,
uint8* dst_rgb565, int dst_stride_rgb565,
const uint8* dither4x4, int width, int height);
// Convert ARGB To ARGB1555.
LIBYUV_API
int ARGBToARGB1555(const uint8* src_argb, int src_stride_argb,
@ -107,6 +115,14 @@ int ARGBToJ420(const uint8* src_argb, int src_stride_argb,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert ARGB to J422.
LIBYUV_API
int ARGBToJ422(const uint8* src_argb, int src_stride_argb,
uint8* dst_yj, int dst_stride_yj,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert ARGB To I411.
LIBYUV_API
int ARGBToI411(const uint8* src_argb, int src_stride_argb,
@ -127,6 +143,12 @@ int ARGBToI400(const uint8* src_argb, int src_stride_argb,
uint8* dst_y, int dst_stride_y,
int width, int height);
// Convert ARGB to G. (Reverse of J400toARGB, which replicates G back to ARGB)
LIBYUV_API
int ARGBToG(const uint8* src_argb, int src_stride_argb,
uint8* dst_g, int dst_stride_g,
int width, int height);
// Convert ARGB To NV12.
LIBYUV_API
int ARGBToNV12(const uint8* src_argb, int src_stride_argb,

View File

@ -18,9 +18,8 @@ namespace libyuv {
extern "C" {
#endif
// TODO(fbarchard): Consider overlapping bits for different architectures.
// Internal flag to indicate cpuid requires initialization.
#define kCpuInit 0x1
static const int kCpuInitialized = 0x1;
// These flags are only valid on ARM processors.
static const int kCpuHasARM = 0x2;
@ -37,12 +36,12 @@ static const int kCpuHasAVX = 0x200;
static const int kCpuHasAVX2 = 0x400;
static const int kCpuHasERMS = 0x800;
static const int kCpuHasFMA3 = 0x1000;
static const int kCpuHasAVX3 = 0x2000;
// 0x2000, 0x4000, 0x8000 reserved for future X86 flags.
// These flags are only valid on MIPS processors.
static const int kCpuHasMIPS = 0x10000;
static const int kCpuHasMIPS_DSP = 0x20000;
static const int kCpuHasMIPS_DSPR2 = 0x40000;
static const int kCpuHasDSPR2 = 0x20000;
// Internal function used to auto-init.
LIBYUV_API
@ -57,13 +56,13 @@ int ArmCpuCaps(const char* cpuinfo_name);
// returns non-zero if instruction set is detected
static __inline int TestCpuFlag(int test_flag) {
LIBYUV_API extern int cpu_info_;
return (cpu_info_ == kCpuInit ? InitCpuFlags() : cpu_info_) & test_flag;
return (!cpu_info_ ? InitCpuFlags() : cpu_info_) & test_flag;
}
// For testing, allow CPU flags to be disabled.
// ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3.
// 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
void MaskCpuFlags(int enable_flags);

View File

@ -1,168 +0,0 @@
/*
* Copyright 2011 The LibYuv Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef INCLUDE_LIBYUV_FORMATCONVERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_FORMATCONVERSION_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
// Convert Bayer RGB formats to I420.
LIBYUV_API
int BayerBGGRToI420(const uint8* src_bayer, int src_stride_bayer,
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);
LIBYUV_API
int BayerGBRGToI420(const uint8* src_bayer, int src_stride_bayer,
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);
LIBYUV_API
int BayerGRBGToI420(const uint8* src_bayer, int src_stride_bayer,
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);
LIBYUV_API
int BayerRGGBToI420(const uint8* src_bayer, int src_stride_bayer,
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);
// Temporary API mapper.
#define BayerRGBToI420(b, bs, f, y, ys, u, us, v, vs, w, h) \
BayerToI420(b, bs, y, ys, u, us, v, vs, w, h, f)
LIBYUV_API
int BayerToI420(const uint8* src_bayer, int src_stride_bayer,
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,
uint32 src_fourcc_bayer);
// Convert I420 to Bayer RGB formats.
LIBYUV_API
int I420ToBayerBGGR(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_frame, int dst_stride_frame,
int width, int height);
LIBYUV_API
int I420ToBayerGBRG(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_frame, int dst_stride_frame,
int width, int height);
LIBYUV_API
int I420ToBayerGRBG(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_frame, int dst_stride_frame,
int width, int height);
LIBYUV_API
int I420ToBayerRGGB(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_frame, int dst_stride_frame,
int width, int height);
// Temporary API mapper.
#define I420ToBayerRGB(y, ys, u, us, v, vs, b, bs, f, w, h) \
I420ToBayer(y, ys, u, us, v, vs, b, bs, w, h, f)
LIBYUV_API
int I420ToBayer(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_frame, int dst_stride_frame,
int width, int height,
uint32 dst_fourcc_bayer);
// Convert Bayer RGB formats to ARGB.
LIBYUV_API
int BayerBGGRToARGB(const uint8* src_bayer, int src_stride_bayer,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
LIBYUV_API
int BayerGBRGToARGB(const uint8* src_bayer, int src_stride_bayer,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
LIBYUV_API
int BayerGRBGToARGB(const uint8* src_bayer, int src_stride_bayer,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
LIBYUV_API
int BayerRGGBToARGB(const uint8* src_bayer, int src_stride_bayer,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Temporary API mapper.
#define BayerRGBToARGB(b, bs, f, a, as, w, h) BayerToARGB(b, bs, a, as, w, h, f)
LIBYUV_API
int BayerToARGB(const uint8* src_bayer, int src_stride_bayer,
uint8* dst_argb, int dst_stride_argb,
int width, int height,
uint32 src_fourcc_bayer);
// Converts ARGB to Bayer RGB formats.
LIBYUV_API
int ARGBToBayerBGGR(const uint8* src_argb, int src_stride_argb,
uint8* dst_bayer, int dst_stride_bayer,
int width, int height);
LIBYUV_API
int ARGBToBayerGBRG(const uint8* src_argb, int src_stride_argb,
uint8* dst_bayer, int dst_stride_bayer,
int width, int height);
LIBYUV_API
int ARGBToBayerGRBG(const uint8* src_argb, int src_stride_argb,
uint8* dst_bayer, int dst_stride_bayer,
int width, int height);
LIBYUV_API
int ARGBToBayerRGGB(const uint8* src_argb, int src_stride_argb,
uint8* dst_bayer, int dst_stride_bayer,
int width, int height);
// Temporary API mapper.
#define ARGBToBayerRGB(a, as, b, bs, f, w, h) ARGBToBayer(b, bs, a, as, w, h, f)
LIBYUV_API
int ARGBToBayer(const uint8* src_argb, int src_stride_argb,
uint8* dst_bayer, int dst_stride_bayer,
int width, int height,
uint32 dst_fourcc_bayer);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_FORMATCONVERSION_H_ NOLINT

View File

@ -43,6 +43,17 @@ enum JpegSubsamplingType {
kJpegUnknown
};
struct Buffer {
const uint8* data;
int len;
};
struct BufferVector {
Buffer* buffers;
int len;
int pos;
};
struct SetJmpErrorMgr;
// MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are
@ -142,27 +153,6 @@ class LIBYUV_API MJpegDecoder {
int* subsample_x, int* subsample_y, int number_of_components);
private:
struct Buffer {
const uint8* data;
int len;
};
struct BufferVector {
Buffer* buffers;
int len;
int pos;
};
// Methods that are passed to jpeglib.
static int fill_input_buffer(jpeg_decompress_struct* cinfo);
static void init_source(jpeg_decompress_struct* cinfo);
static void skip_input_data(jpeg_decompress_struct* cinfo,
long num_bytes); // NOLINT
static void term_source(jpeg_decompress_struct* cinfo);
static void ErrorHandler(jpeg_common_struct* cinfo);
static void OutputHandler(jpeg_common_struct* cinfo);
void AllocOutputBuffers(int num_outbufs);
void DestroyOutputBuffers();

View File

@ -28,6 +28,11 @@ void CopyPlane(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height);
LIBYUV_API
void CopyPlane_16(const uint16* src_y, int src_stride_y,
uint16* dst_y, int dst_stride_y,
int width, int height);
// Set a plane of data to a 32 bit value.
LIBYUV_API
void SetPlane(uint8* dst_y, int dst_stride_y,
@ -40,6 +45,7 @@ int I400ToI400(const uint8* src_y, int src_stride_y,
uint8* dst_y, int dst_stride_y,
int width, int height);
#define J400ToJ400 I400ToI400
// Copy I422 to I422.
#define I422ToI422 I422Copy
@ -79,6 +85,18 @@ int UYVYToI422(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_v, int dst_stride_v,
int width, int height);
LIBYUV_API
int YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2,
uint8* dst_y, int dst_stride_y,
uint8* dst_uv, int dst_stride_uv,
int width, int height);
LIBYUV_API
int UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_y, int dst_stride_y,
uint8* dst_uv, int dst_stride_uv,
int width, int height);
// Convert I420 to I400. (calls CopyPlane ignoring u/v).
LIBYUV_API
int I420ToI400(const uint8* src_y, int src_stride_y,
@ -88,6 +106,7 @@ int I420ToI400(const uint8* src_y, int src_stride_y,
int width, int height);
// Alias
#define J420ToJ400 I420ToI400
#define I420ToI420Mirror I420Mirror
// I420 mirror.
@ -126,13 +145,6 @@ int NV12ToRGB565(const uint8* src_y, int src_stride_y,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// Convert NV21 to RGB565.
LIBYUV_API
int NV21ToRGB565(const uint8* src_y, int src_stride_y,
const uint8* src_uv, int src_stride_uv,
uint8* dst_rgb565, int dst_stride_rgb565,
int width, int height);
// I422ToARGB is in convert_argb.h
// Convert I422 to BGRA.
LIBYUV_API
@ -158,6 +170,14 @@ int I422ToRGBA(const uint8* src_y, int src_stride_y,
uint8* dst_rgba, int dst_stride_rgba,
int width, int height);
// Alias
#define RGB24ToRAW RAWToRGB24
LIBYUV_API
int RAWToRGB24(const uint8* src_raw, int src_stride_raw,
uint8* dst_rgb24, int dst_stride_rgb24,
int width, int height);
// Draw a rectangle into I420.
LIBYUV_API
int I420Rect(uint8* dst_y, int dst_stride_y,
@ -262,13 +282,19 @@ int ARGBCopy(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Copy ARGB to ARGB.
// Copy Alpha channel of ARGB to alpha of ARGB.
LIBYUV_API
int ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Copy ARGB to ARGB.
// 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.
LIBYUV_API
int ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y,
uint8* dst_argb, int dst_stride_argb,
@ -282,6 +308,7 @@ LIBYUV_API
ARGBBlendRow GetARGBBlend();
// Alpha Blend ARGB images and store to destination.
// Source is pre-multiplied by alpha using ARGBAttenuate.
// Alpha of destination is set to 255.
LIBYUV_API
int ARGBBlend(const uint8* src_argb0, int src_stride_argb0,
@ -289,6 +316,31 @@ int ARGBBlend(const uint8* src_argb0, int src_stride_argb0,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Alpha Blend plane and store to destination.
// Source is not pre-multiplied by alpha.
LIBYUV_API
int BlendPlane(const uint8* src_y0, int src_stride_y0,
const uint8* src_y1, int src_stride_y1,
const uint8* alpha, int alpha_stride,
uint8* dst_y, int dst_stride_y,
int width, int height);
// Alpha Blend YUV images and store to destination.
// Source is not pre-multiplied by alpha.
// Alpha is full width x height and subsampled to half size to apply to UV.
LIBYUV_API
int I420Blend(const uint8* src_y0, int src_stride_y0,
const uint8* src_u0, int src_stride_u0,
const uint8* src_v0, int src_stride_v0,
const uint8* src_y1, int src_stride_y1,
const uint8* src_u1, int src_stride_u1,
const uint8* src_v1, int src_stride_v1,
const uint8* alpha, int alpha_stride,
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);
// Multiply ARGB image by ARGB image. Shifted down by 8. Saturates to 255.
LIBYUV_API
int ARGBMultiply(const uint8* src_argb0, int src_stride_argb0,
@ -338,12 +390,6 @@ int ARGBUnattenuate(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height);
// Convert MJPG to ARGB.
LIBYUV_API
int MJPGToARGB(const uint8* sample, size_t sample_size,
uint8* argb, int argb_stride,
int w, int h, int dw, int dh);
// Internal function - do not call directly.
// Computes table of cumulative sum for image where the value is the sum
// of all values above and to the left of the entry. Used by ARGBBlur.
@ -370,36 +416,63 @@ int ARGBShade(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
int width, int height, uint32 value);
// Interpolate between two ARGB images using specified amount of interpolation
// Interpolate between two images using specified amount of interpolation
// (0 to 255) and store to destination.
// 'interpolation' is specified as 8 bit fraction where 0 means 100% src_argb0
// and 255 means 1% src_argb0 and 99% src_argb1.
// Internally uses ARGBScale bilinear filtering.
// Caveat: This function will write up to 16 bytes beyond the end of dst_argb.
// 'interpolation' is specified as 8 bit fraction where 0 means 100% src0
// and 255 means 1% src0 and 99% src1.
LIBYUV_API
int InterpolatePlane(const uint8* src0, int src_stride0,
const uint8* src1, int src_stride1,
uint8* dst, int dst_stride,
int width, int height, int interpolation);
// Interpolate between two ARGB images using specified amount of interpolation
// Internally calls InterpolatePlane with width * 4 (bpp).
LIBYUV_API
int ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0,
const uint8* src_argb1, int src_stride_argb1,
uint8* dst_argb, int dst_stride_argb,
int width, int height, int interpolation);
#if defined(__pnacl__) || defined(__CLR_VER) || defined(COVERAGE_ENABLED) || \
defined(TARGET_IPHONE_SIMULATOR)
// Interpolate between two YUV images using specified amount of interpolation
// Internally calls InterpolatePlane on each plane where the U and V planes
// are half width and half height.
LIBYUV_API
int I420Interpolate(const uint8* src0_y, int src0_stride_y,
const uint8* src0_u, int src0_stride_u,
const uint8* src0_v, int src0_stride_v,
const uint8* src1_y, int src1_stride_y,
const uint8* src1_u, int src1_stride_u,
const uint8* src1_v, int src1_stride_v,
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 interpolation);
#if defined(__pnacl__) || defined(__CLR_VER) || \
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// The following are available on all x86 platforms:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
#define HAS_ARGBAFFINEROW_SSE2
#endif
// Row functions for copying a pixels from a source with a slope to a row
// Row function for copying pixels from a source with a slope to a row
// of destination. Useful for scaling, rotation, mirror, texture mapping.
LIBYUV_API
void ARGBAffineRow_C(const uint8* src_argb, int src_argb_stride,
uint8* dst_argb, const float* uv_dudv, int width);
// The following are available on all x86 platforms:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
LIBYUV_API
void ARGBAffineRow_SSE2(const uint8* src_argb, int src_argb_stride,
uint8* dst_argb, const float* uv_dudv, int width);
#define HAS_ARGBAFFINEROW_SSE2
#endif // LIBYUV_DISABLE_X86
// Shuffle ARGB channel order. e.g. BGRA to ARGB.
// shuffler is 16 bytes and must be aligned.

View File

@ -0,0 +1,121 @@
/*
* Copyright 2013 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_ROTATE_ROW_H_ // NOLINT
#define INCLUDE_LIBYUV_ROTATE_ROW_H_
#include "libyuv/basic_types.h"
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if defined(__pnacl__) || defined(__CLR_VER) || \
(defined(__i386__) && !defined(__SSE2__))
#define LIBYUV_DISABLE_X86
#endif
// MemorySanitizer does not support assembly code yet. http://crbug.com/344505
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define LIBYUV_DISABLE_X86
#endif
#endif
// The following are available for Visual C and clangcl 32 bit:
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86)
#define HAS_TRANSPOSEWX8_SSSE3
#define HAS_TRANSPOSEUVWX8_SSE2
#endif
// The following are available for GCC 32 or 64 bit but not NaCL for 64 bit:
#if !defined(LIBYUV_DISABLE_X86) && \
(defined(__i386__) || (defined(__x86_64__) && !defined(__native_client__)))
#define HAS_TRANSPOSEWX8_SSSE3
#endif
// The following are available for 64 bit GCC but not NaCL:
#if !defined(LIBYUV_DISABLE_X86) && !defined(__native_client__) && \
defined(__x86_64__)
#define HAS_TRANSPOSEWX8_FAST_SSSE3
#define HAS_TRANSPOSEUVWX8_SSE2
#endif
#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \
(defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__))
#define HAS_TRANSPOSEWX8_NEON
#define HAS_TRANSPOSEUVWX8_NEON
#endif
#if !defined(LIBYUV_DISABLE_MIPS) && !defined(__native_client__) && \
defined(__mips__) && \
defined(__mips_dsp) && (__mips_dsp_rev >= 2)
#define HAS_TRANSPOSEWX8_DSPR2
#define HAS_TRANSPOSEUVWX8_DSPR2
#endif // defined(__mips__)
void TransposeWxH_C(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width, int height);
void TransposeWx8_C(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_NEON(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Fast_Any_SSSE3(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeWx8_Any_DSPR2(const uint8* src, int src_stride,
uint8* dst, int dst_stride, int width);
void TransposeUVWxH_C(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b,
int width, int height);
void TransposeUVWx8_C(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_SSE2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_SSE2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_NEON(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
void TransposeUVWx8_Any_DSPR2(const uint8* src, int src_stride,
uint8* dst_a, int dst_stride_a,
uint8* dst_b, int dst_stride_b, int width);
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
#endif
#endif // INCLUDE_LIBYUV_ROTATE_ROW_H_ NOLINT

Some files were not shown because too many files have changed in this diff Show More