diff options
author | bsalomon <bsalomon@google.com> | 2016-02-01 13:16:14 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-01 13:16:14 -0800 |
commit | f267c1efe7de7a8e71404afde6cbf93c3808d267 (patch) | |
tree | 3ca07e8c6e5526ccfe4166953631006dd8b71845 /src/utils/SkRGBAToYUV.cpp | |
parent | 9d02b264b72be64702e43cb797b7899a8a6926ca (diff) |
Add ability to extract YUV planes from SkImage
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1513393002
Review URL: https://codereview.chromium.org/1513393002
Diffstat (limited to 'src/utils/SkRGBAToYUV.cpp')
-rw-r--r-- | src/utils/SkRGBAToYUV.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/utils/SkRGBAToYUV.cpp b/src/utils/SkRGBAToYUV.cpp new file mode 100644 index 0000000000..b7f78bac14 --- /dev/null +++ b/src/utils/SkRGBAToYUV.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkRGBAToYUV.h" +#include "SkCanvas.h" +#include "SkColorMatrixFilterRowMajor255.h" +#include "SkImage.h" +#include "SkPaint.h" +#include "SkSurface.h" + +bool SkRGBAToYUV(const SkImage* image, const SkISize sizes[3], void* const planes[3], + const size_t rowBytes[3], SkYUVColorSpace colorSpace) { + // Matrices that go from RGBA to YUV. + static const SkScalar kYUVColorSpaceInvMatrices[][15] = { + // kJPEG_SkYUVColorSpace + { 0.299001f, 0.586998f, 0.114001f, 0.f, 0.0000821798f * 255.f, + -0.168736f, -0.331263f, 0.499999f, 0.f, 0.499954f * 255.f, + 0.499999f, -0.418686f, -0.0813131f, 0.f, 0.499941f * 255.f}, + + // kRec601_SkYUVColorSpace + { 0.256951f, 0.504421f, 0.0977346f, 0.f, 0.0625f * 255.f, + -0.148212f, -0.290954f, 0.439166f, 0.f, 0.5f * 255.f, + 0.439166f, -0.367886f, -0.0712802f, 0.f, 0.5f * 255.f}, + + // kRec709_SkYUVColorSpace + { 0.182663f, 0.614473f, 0.061971f, 0.f, 0.0625f * 255.f, + -0.100672f, -0.338658f, 0.43933f, 0.f, 0.5f * 255.f, + 0.439142f, -0.39891f, -0.040231f, 0.f, 0.5f * 255.f}, + }; + static_assert(kLastEnum_SkYUVColorSpace == 2, "yuv color matrix array problem"); + static_assert(kJPEG_SkYUVColorSpace == 0, "yuv color matrix array problem"); + static_assert(kRec601_SkYUVColorSpace == 1, "yuv color matrix array problem"); + static_assert(kRec709_SkYUVColorSpace == 2, "yuv color matrix array problem"); + + for (int i = 0; i < 3; ++i) { + size_t rb = rowBytes[i] ? rowBytes[i] : sizes[i].fWidth; + SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterDirect( + SkImageInfo::MakeA8(sizes[i].fWidth, sizes[i].fHeight), planes[i], rb)); + if (!surface) { + return false; + } + SkPaint paint; + paint.setFilterQuality(kLow_SkFilterQuality); + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + int rowStartIdx = 5 * i; + const SkScalar* row = kYUVColorSpaceInvMatrices[colorSpace] + rowStartIdx; + paint.setColorFilter( + SkColorMatrixFilterRowMajor255::CreateSingleChannelOutput(row))->unref(); + surface->getCanvas()->drawImageRect(image, SkIRect::MakeWH(image->width(), image->height()), + SkRect::MakeIWH(surface->width(), surface->height()), + &paint); + } + return true; +} |