void readPixelsCallback(SkImage::ReadPixelsContext context, std::unique_ptr<const SkImage::AsyncReadResult> result) {
auto* pixels = static_cast<std::vector<uint8_t>*>(context);
if (!result) {
assert(false);
return;
}
// the data in result is ordered Y, U, then V.
pixels->resize(result->rowBytes(0) + result->rowBytes(1) + result->rowBytes(2));
memcpy(pixels->data(), result->data(0), result->rowBytes(0));
auto* data = pixels->data() + result->rowBytes(0);
memcpy(data, result->data(1), result->rowBytes(1));
data += result->rowBytes(1);
memcpy(data, result->data(2), result->rowBytes(2));
}
std::vector<uint8_t> ContextSkia::readPixelsYUV(sk_sp<SkImage> image, int srcX, int srcY, int width, int height) {
assert(0 <= srcX && srcX < image->width());
assert(0 <= srcY && srcY < image->height());
assert(width <= image->width() - srcX);
assert(height <= image->height() - srcY);
int clampedWidth = (width > 0) ? width : image->width();
int clampedHeight = (height > 0) ? height : image->height();
int readWidth = srcX + clampedWidth;
int readHeight = srcY + clampedHeight;
std::vector<uint8_t> pixels(0);
image->asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace::kRec709_Limited_SkYUVColorSpace,
SkColorSpace::MakeSRGB(),
SkIRect::MakeXYWH(srcX, srcY, readWidth, readHeight),
SkISize::Make(clampedWidth, clampedHeight),
SkImage::RescaleGamma::kSrc,
SkImage::RescaleMode::kNearest,
readPixelsCallback,
&pixels);
return pixels;
}