Index: src/image/SkImage.cpp |
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp |
index 25370bcff15e09ad2e7276ec3a98f23e4a79cf35..f6033a2b06b161aebc3931c1d1746fb322bf6173 100644 |
--- a/src/image/SkImage.cpp |
+++ b/src/image/SkImage.cpp |
@@ -258,6 +258,83 @@ bool SkImage::readPixels(const SkPixmap& pmap, int srcX, int srcY, CachingHint c |
return this->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), srcX, srcY, chint); |
} |
+#if SK_SUPPORT_GPU |
+#include "GrTextureToYUVPlanes.h" |
+#endif |
+ |
+#define HACKY_RASTER_IMPL 1 |
+ |
+#if HACKY_RASTER_IMPL |
+ // Shouldn't really include from effects here. |
+#include "../effects/SkColorMatrixFilter.h" |
+ |
+static const float kYUVColorSpaceInvMatrices[][20] = { |
+ {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, |
+ 0.f, 0.f, 0.f, 1.f, 0.f * 255.f}, |
+ |
+ {0.256951f, 0.504421f, 0.0977346f, 0.f, 0.0625f * 255.f, |
reed1
2016/01/28 22:12:45
// I'm this colorspace
|
+ -0.148212f, -0.290954f, 0.439166f, 0.f, 0.5f * 255.f, |
+ 0.439166f, -0.367886f, -0.0712802f, 0.f, 0.5f * 255.f, |
+ 0.f, 0.f, 0.f, 1.f, 0.f * 255.f}, |
+ |
+ {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, |
+ 0.f, 0.f, 0.f, 1.f, 0.f * 255.f}, |
+}; |
+#endif |
+ |
+bool SkImage::asYUV8Planes(const SkISize sizes[3], void* const planes[3], const size_t rowBytes[3], |
+ SkYUVColorSpace colorSpace) { |
+#if SK_SUPPORT_GPU |
+ if (GrTexture* texture = as_IB(this)->peekTexture()) { |
+ if (GrTextureToYUVPlanes(texture, sizes, planes, rowBytes, colorSpace)) { |
+ return true; |
+ } |
+ } |
+#endif |
+#if !HACKY_RASTER_IMPL |
+ return false; |
+#else // This seems to work for Y but not U and V |
+ SkPixmap pixmap; |
+ SkAutoTDeleteArray<uint32_t> pixels(0); |
+ if (!this->peekPixels(&pixmap)) { |
+ // Should this be premul? |
+ SkImageInfo info = SkImageInfo::MakeN32Premul(this->width(), this->height()); |
+ pixels.reset(new uint32_t[this->width() * this->height()]); |
+ pixmap.reset(info, pixels.get(), 0); |
reed1
2016/01/28 22:12:45
pass the explicit rowBYtes (width() * 4)
|
+ if (!this->readPixels(pixmap, 0, 0, kDisallow_CachingHint)) { |
+ return false; |
+ } |
+ } |
+ 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)); |
+ SkPaint paint; |
+ paint.setFilterQuality(kLow_SkFilterQuality); |
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
+ SkColorMatrix replicateChannel; |
+ for (int j = 0; j < 20; ++j) { |
+ replicateChannel.fMat[j] = 0.f; |
+ } |
+ replicateChannel.fMat[0+i] = 1.f; |
+ replicateChannel.fMat[5+i] = 1.f; |
+ replicateChannel.fMat[10+i] = 1.f; |
+ replicateChannel.fMat[15+i] = 1.f; |
+ SkColorMatrix::SetConcat(replicateChannel.fMat, replicateChannel.fMat, |
+ kYUVColorSpaceInvMatrices[colorSpace]); |
+ paint.setColorFilter(SkColorMatrixFilter::Create(replicateChannel))->unref(); |
+ surface->getCanvas()->drawImageRect(this, SkIRect::MakeWH(this->width(), this->height()), |
+ SkRect::MakeIWH(surface->width(), surface->height()), |
+ &paint); |
+ } |
+ return true; |
+#endif |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
SkImage* SkImage::NewFromBitmap(const SkBitmap& bm) { |