2e61b182da
This instructs us on how to encode jpegs when the src image has alpha. The original behavior is to ignore the alpha channel. This CL adds the option to blend the pixels onto opaque black. Note that kBlendOnBlack and kIgnore are identical unless the input alpha type is kUnpremul. Bug: 713862 Bug: skia:1501 Change-Id: I4891c70bb0ccd83f7974c359bd40a2143b5c49ac Reviewed-on: https://skia-review.googlesource.com/15817 Reviewed-by: Leon Scroggins <scroggo@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
106 lines
3.9 KiB
C++
106 lines
3.9 KiB
C++
/*
|
|
* Copyright 2017 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "gm.h"
|
|
#include "SkImage.h"
|
|
#include "SkJpegEncoder.h"
|
|
|
|
#include "Resources.h"
|
|
|
|
namespace skiagm {
|
|
|
|
static inline void read_into_pixmap(SkPixmap* dst, SkImageInfo dstInfo, void* dstPixels,
|
|
sk_sp<SkImage> src) {
|
|
dst->reset(dstInfo, dstPixels, dstInfo.minRowBytes());
|
|
src->readPixels(*dst, 0, 0, SkImage::CachingHint::kDisallow_CachingHint);
|
|
}
|
|
|
|
static inline sk_sp<SkImage> encode_pixmap_and_make_image(const SkPixmap& src,
|
|
SkJpegEncoder::AlphaOption alphaOption, SkTransferFunctionBehavior blendBehavior) {
|
|
SkDynamicMemoryWStream dst;
|
|
SkJpegEncoder::Options options;
|
|
options.fAlphaOption = alphaOption;
|
|
options.fBlendBehavior = blendBehavior;
|
|
SkJpegEncoder::Encode(&dst, src, options);
|
|
return SkImage::MakeFromEncoded(dst.detachAsData());
|
|
}
|
|
|
|
class EncodeJpegAlphaOptsGM : public GM {
|
|
public:
|
|
EncodeJpegAlphaOptsGM() {}
|
|
|
|
protected:
|
|
SkString onShortName() override {
|
|
return SkString("encode-alpha-jpeg");
|
|
}
|
|
|
|
SkISize onISize() override {
|
|
return SkISize::Make(400, 200);
|
|
}
|
|
|
|
void onDraw(SkCanvas* canvas) override {
|
|
sk_sp<SkImage> srcImg = GetResourceAsImage("rainbow-gradient.png");
|
|
fStorage.reset(srcImg->width() * srcImg->height() *
|
|
SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType));
|
|
|
|
SkPixmap src;
|
|
SkImageInfo info = SkImageInfo::MakeN32Premul(srcImg->width(), srcImg->height(),
|
|
canvas->imageInfo().colorSpace() ? SkColorSpace::MakeSRGB() : nullptr);
|
|
read_into_pixmap(&src, info, fStorage.get(), srcImg);
|
|
|
|
SkTransferFunctionBehavior behavior = canvas->imageInfo().colorSpace() ?
|
|
SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore;
|
|
|
|
// Encode 8888 premul.
|
|
sk_sp<SkImage> img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore,
|
|
behavior);
|
|
sk_sp<SkImage> img1 = encode_pixmap_and_make_image(src,
|
|
SkJpegEncoder::AlphaOption::kBlendOnBlack, behavior);
|
|
canvas->drawImage(img0, 0.0f, 0.0f);
|
|
canvas->drawImage(img1, 0.0f, 100.0f);
|
|
|
|
// Encode 8888 unpremul
|
|
info = info.makeAlphaType(kUnpremul_SkAlphaType);
|
|
read_into_pixmap(&src, info, fStorage.get(), srcImg);
|
|
img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior);
|
|
img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack,
|
|
behavior);
|
|
canvas->drawImage(img0, 100.0f, 0.0f);
|
|
canvas->drawImage(img1, 100.0f, 100.0f);
|
|
|
|
if (canvas->imageInfo().colorSpace()) {
|
|
// Encode F16 premul
|
|
info = SkImageInfo::Make(srcImg->width(), srcImg->height(), kRGBA_F16_SkColorType,
|
|
kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear());
|
|
read_into_pixmap(&src, info, fStorage.get(), srcImg);
|
|
img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior);
|
|
img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack,
|
|
behavior);
|
|
canvas->drawImage(img0, 200.0f, 0.0f);
|
|
canvas->drawImage(img1, 200.0f, 100.0f);
|
|
|
|
// Encode F16 unpremul
|
|
info = info.makeAlphaType(kUnpremul_SkAlphaType);
|
|
read_into_pixmap(&src, info, fStorage.get(), srcImg);
|
|
img0 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kIgnore, behavior);
|
|
img1 = encode_pixmap_and_make_image(src, SkJpegEncoder::AlphaOption::kBlendOnBlack,
|
|
behavior);
|
|
canvas->drawImage(img0, 300.0f, 0.0f);
|
|
canvas->drawImage(img1, 300.0f, 100.0f);
|
|
}
|
|
}
|
|
|
|
private:
|
|
SkAutoTMalloc<uint8_t> fStorage;
|
|
|
|
typedef GM INHERITED;
|
|
};
|
|
|
|
DEF_GM( return new EncodeJpegAlphaOptsGM; )
|
|
|
|
};
|