Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: src/codec/SkWebpCodec.cpp

Issue 2294993002: Add color xform support to SkWebpCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Try v6 Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codec/SkPngCodec.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codec/SkWebpCodec.cpp
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index c12b1df5edf955d547aad34892d441544528f485..0c3aa402bd70bfd2659b01d8468d4cfa252be82a 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -6,6 +6,7 @@
*/
#include "SkCodecPriv.h"
+#include "SkColorSpaceXform.h"
#include "SkWebpCodec.h"
#include "SkStreamPriv.h"
#include "SkTemplates.h"
@@ -143,20 +144,20 @@ SkCodec* SkWebpCodec::NewFromStream(SkStream* stream) {
streamDeleter.release(), demux.release(), std::move(data));
}
-// This version is slightly different from SkCodecPriv's version of conversion_possible. It
-// supports both byte orders for 8888.
-static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) {
+static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src,
+ SkColorSpaceXform* colorXform) {
if (!valid_alpha(dst.alphaType(), src.alphaType())) {
return false;
}
switch (dst.colorType()) {
- // Both byte orders are supported.
+ case kRGBA_F16_SkColorType:
+ return nullptr != colorXform;
case kBGRA_8888_SkColorType:
case kRGBA_8888_SkColorType:
return true;
case kRGB_565_SkColorType:
- return src.alphaType() == kOpaque_SkAlphaType;
+ return nullptr == colorXform && src.alphaType() == kOpaque_SkAlphaType;
default:
return false;
}
@@ -210,8 +211,15 @@ bool SkWebpCodec::onGetValidSubset(SkIRect* desiredSubset) const {
SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
const Options& options, SkPMColor*, int*,
- int* rowsDecoded) {
- if (!webp_conversion_possible(dstInfo, this->getInfo())) {
+ int* rowsDecodedPtr) {
+
+ std::unique_ptr<SkColorSpaceXform> colorXform = nullptr;
+ if (needs_color_xform(dstInfo, this->getInfo())) {
+ colorXform = SkColorSpaceXform::New(sk_ref_sp(this->getInfo().colorSpace()),
+ sk_ref_sp(dstInfo.colorSpace()));
+ }
+
+ if (!webp_conversion_possible(dstInfo, this->getInfo(), colorXform.get())) {
return kInvalidConversion;
}
@@ -269,13 +277,28 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
config.options.scaled_height = dstDimensions.height();
}
- config.output.colorspace = webp_decode_mode(dstInfo.colorType(),
- dstInfo.alphaType() == kPremul_SkAlphaType);
- config.output.u.RGBA.rgba = (uint8_t*) dst;
- config.output.u.RGBA.stride = (int) rowBytes;
- config.output.u.RGBA.size = dstInfo.getSafeSize(rowBytes);
+ // FIXME (msarett):
+ // Lossless webp is encoded as BGRA. In that case, it would be more efficient to
+ // to decode BGRA and apply the color xform to a BGRA buffer.
+ config.output.colorspace = colorXform ? MODE_RGBA :
+ webp_decode_mode(dstInfo.colorType(), dstInfo.alphaType() == kPremul_SkAlphaType);
config.output.is_external_memory = 1;
+ // We will decode the entire image and then perform the color transform. libwebp
+ // does not provide a row-by-row API. This is a shame particularly in the F16 case,
+ // where we need to allocate an extra image-sized buffer.
+ SkAutoTMalloc<uint32_t> pixels;
+ if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
+ pixels.reset(dstDimensions.width() * dstDimensions.height());
+ config.output.u.RGBA.rgba = (uint8_t*) pixels.get();
+ config.output.u.RGBA.stride = (int) dstDimensions.width() * sizeof(uint32_t);
+ config.output.u.RGBA.size = config.output.u.RGBA.stride * dstDimensions.height();
+ } else {
+ config.output.u.RGBA.rgba = (uint8_t*) dst;
+ config.output.u.RGBA.stride = (int) rowBytes;
+ config.output.u.RGBA.size = dstInfo.getSafeSize(rowBytes);
+ }
+
WebPIterator frame;
SkAutoTCallVProc<WebPIterator, WebPDemuxReleaseIterator> autoFrame(&frame);
// If this succeeded in NewFromStream(), it should succeed again here.
@@ -286,15 +309,36 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
return kInvalidInput;
}
+ int rowsDecoded;
+ SkCodec::Result result;
switch (WebPIUpdate(idec, frame.fragment.bytes, frame.fragment.size)) {
case VP8_STATUS_OK:
- return kSuccess;
+ rowsDecoded = dstInfo.height();
+ result = kSuccess;
+ break;
case VP8_STATUS_SUSPENDED:
- WebPIDecGetRGB(idec, rowsDecoded, nullptr, nullptr, nullptr);
- return kIncompleteInput;
+ WebPIDecGetRGB(idec, rowsDecodedPtr, nullptr, nullptr, nullptr);
+ rowsDecoded = *rowsDecodedPtr;
+ result = kIncompleteInput;
+ break;
default:
return kInvalidInput;
}
+
+ if (colorXform) {
+ SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(),
+ this->getInfo().alphaType());
+
+ uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba;
+ size_t srcRowBytes = config.output.u.RGBA.stride;
+ for (int y = 0; y < rowsDecoded; y++) {
+ colorXform->apply(dst, src, dstInfo.width(), dstInfo.colorType(), xformAlphaType);
+ dst = SkTAddOffset<void>(dst, rowBytes);
+ src = SkTAddOffset<uint32_t>(src, srcRowBytes);
+ }
+ }
+
+ return result;
}
SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info,
« no previous file with comments | « src/codec/SkPngCodec.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698