blob: 3b9526b3c993b0f821e6cc544048a5278fe2bf69 [file] [log] [blame]
Matt Sarett84014f02017-01-10 11:28:54 -05001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9
10#include "Resources.h"
11#include "SkCanvas.h"
12#include "SkCodec.h"
13#include "SkData.h"
Florin Malitaab244f02017-05-03 19:16:58 +000014#include "SkImage.h"
Matt Sarett84014f02017-01-10 11:28:54 -050015#include "SkImageEncoderPriv.h"
Matt Sarett26b44df2017-05-02 16:04:56 -040016#include "SkJpegEncoder.h"
Matt Sarettc367d032017-05-05 11:13:26 -040017#include "SkPngEncoder.h"
Matt Sarett84014f02017-01-10 11:28:54 -050018#include "SkPM4f.h"
19#include "SkSRGB.h"
Matt Sarett04c37312017-05-05 14:02:13 -040020#include "SkWebpEncoder.h"
Matt Sarett84014f02017-01-10 11:28:54 -050021
22namespace skiagm {
23
24static const int imageWidth = 128;
25static const int imageHeight = 128;
26
Matt Sarett1da27ef2017-01-19 17:14:07 -050027sk_sp<SkColorSpace> fix_for_colortype(sk_sp<SkColorSpace> colorSpace, SkColorType colorType) {
28 if (kRGBA_F16_SkColorType == colorType) {
29 if (!colorSpace) {
Matt Sarett77a7a1b2017-02-07 13:56:11 -050030 return SkColorSpace::MakeSRGBLinear();
Matt Sarett1da27ef2017-01-19 17:14:07 -050031 }
32
Brian Osman36703d92017-12-12 14:09:31 -050033 return colorSpace->makeLinearGamma();
Matt Sarett1da27ef2017-01-19 17:14:07 -050034 }
35
36 return colorSpace;
37}
38
Matt Sarett84014f02017-01-10 11:28:54 -050039static void make(SkBitmap* bitmap, SkColorType colorType, SkAlphaType alphaType,
40 sk_sp<SkColorSpace> colorSpace) {
Matt Sarette95941f2017-01-27 18:16:40 -050041 const char* resource;
42 switch (colorType) {
Matt Sarette95941f2017-01-27 18:16:40 -050043 case kGray_8_SkColorType:
Hal Canaryc465d132017-12-08 10:21:31 -050044 resource = "images/grayscale.jpg";
Matt Sarette95941f2017-01-27 18:16:40 -050045 alphaType = kOpaque_SkAlphaType;
46 break;
47 case kRGB_565_SkColorType:
Hal Canaryc465d132017-12-08 10:21:31 -050048 resource = "images/color_wheel.jpg";
Matt Sarette95941f2017-01-27 18:16:40 -050049 alphaType = kOpaque_SkAlphaType;
50 break;
51 default:
Hal Canaryc465d132017-12-08 10:21:31 -050052 resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg"
53 : "images/color_wheel.png";
Matt Sarette95941f2017-01-27 18:16:40 -050054 break;
Matt Sarett62bb2802017-01-23 12:28:02 -050055 }
56
Matt Sarett1da27ef2017-01-19 17:14:07 -050057 sk_sp<SkData> data = GetResourceAsData(resource);
Mike Reedede7bac2017-07-23 15:30:02 -040058 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data);
Matt Sarett84014f02017-01-10 11:28:54 -050059 SkImageInfo dstInfo = codec->getInfo().makeColorType(colorType)
60 .makeAlphaType(alphaType)
Matt Sarett1da27ef2017-01-19 17:14:07 -050061 .makeColorSpace(fix_for_colortype(colorSpace, colorType));
Matt Sarett84014f02017-01-10 11:28:54 -050062 bitmap->allocPixels(dstInfo);
63 codec->getPixels(dstInfo, bitmap->getPixels(), bitmap->rowBytes());
64}
65
Matt Sarett62bb2802017-01-23 12:28:02 -050066static sk_sp<SkData> encode_data(const SkBitmap& bitmap, SkEncodedImageFormat format) {
Matt Sarett84014f02017-01-10 11:28:54 -050067 SkPixmap src;
68 if (!bitmap.peekPixels(&src)) {
69 return nullptr;
70 }
71 SkDynamicMemoryWStream buf;
Matt Sarett62bb2802017-01-23 12:28:02 -050072
Matt Sarettc367d032017-05-05 11:13:26 -040073 SkPngEncoder::Options pngOptions;
Matt Sarett04c37312017-05-05 14:02:13 -040074 SkWebpEncoder::Options webpOptions;
Brian Osman39ef5562017-07-11 11:59:48 -040075 SkTransferFunctionBehavior behavior = bitmap.colorSpace()
76 ? SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore;
77 pngOptions.fUnpremulBehavior = behavior;
78 webpOptions.fUnpremulBehavior = behavior;
Matt Sarett62bb2802017-01-23 12:28:02 -050079
80 switch (format) {
81 case SkEncodedImageFormat::kPNG:
Matt Sarettc367d032017-05-05 11:13:26 -040082 SkAssertResult(SkPngEncoder::Encode(&buf, src, pngOptions));
Matt Sarett62bb2802017-01-23 12:28:02 -050083 break;
84 case SkEncodedImageFormat::kWEBP:
Matt Sarett04c37312017-05-05 14:02:13 -040085 SkAssertResult(SkWebpEncoder::Encode(&buf, src, webpOptions));
Matt Sarette95941f2017-01-27 18:16:40 -050086 break;
87 case SkEncodedImageFormat::kJPEG:
Matt Sarett26b44df2017-05-02 16:04:56 -040088 SkAssertResult(SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options()));
Matt Sarett62bb2802017-01-23 12:28:02 -050089 break;
90 default:
91 break;
92 }
Matt Sarett84014f02017-01-10 11:28:54 -050093 return buf.detachAsData();
94}
95
96class EncodeSRGBGM : public GM {
97public:
Matt Sarett62bb2802017-01-23 12:28:02 -050098 EncodeSRGBGM(SkEncodedImageFormat format)
99 : fEncodedFormat(format)
100 {}
Matt Sarett84014f02017-01-10 11:28:54 -0500101
102protected:
103 SkString onShortName() override {
Matt Sarett62bb2802017-01-23 12:28:02 -0500104 const char* format = nullptr;
105 switch (fEncodedFormat) {
106 case SkEncodedImageFormat::kPNG:
Matt Sarette95941f2017-01-27 18:16:40 -0500107 format = "png";
Matt Sarett62bb2802017-01-23 12:28:02 -0500108 break;
109 case SkEncodedImageFormat::kWEBP:
Matt Sarette95941f2017-01-27 18:16:40 -0500110 format = "webp";
111 break;
112 case SkEncodedImageFormat::kJPEG:
113 format = "jpg";
Matt Sarett62bb2802017-01-23 12:28:02 -0500114 break;
115 default:
116 break;
117 }
Matt Sarette95941f2017-01-27 18:16:40 -0500118 return SkStringPrintf("encode-srgb-%s", format);
Matt Sarett84014f02017-01-10 11:28:54 -0500119 }
120
121 SkISize onISize() override {
Matt Sarette95941f2017-01-27 18:16:40 -0500122 return SkISize::Make(imageWidth * 2, imageHeight * 15);
Matt Sarett84014f02017-01-10 11:28:54 -0500123 }
124
125 void onDraw(SkCanvas* canvas) override {
Matt Sarett1da27ef2017-01-19 17:14:07 -0500126 const SkColorType colorTypes[] = {
Mike Reed304a07c2017-07-12 15:10:28 -0400127 kN32_SkColorType, kRGBA_F16_SkColorType, kGray_8_SkColorType, kRGB_565_SkColorType,
Matt Sarett1da27ef2017-01-19 17:14:07 -0500128 };
129 const SkAlphaType alphaTypes[] = {
Mike Reed304a07c2017-07-12 15:10:28 -0400130 kUnpremul_SkAlphaType, kPremul_SkAlphaType, kOpaque_SkAlphaType,
Matt Sarett1da27ef2017-01-19 17:14:07 -0500131 };
Matt Sarett84014f02017-01-10 11:28:54 -0500132 const sk_sp<SkColorSpace> colorSpaces[] = {
Mike Reed304a07c2017-07-12 15:10:28 -0400133 nullptr, SkColorSpace::MakeSRGB(),
Matt Sarett84014f02017-01-10 11:28:54 -0500134 };
135
136 SkBitmap bitmap;
137 for (SkColorType colorType : colorTypes) {
138 for (SkAlphaType alphaType : alphaTypes) {
139 canvas->save();
140 for (sk_sp<SkColorSpace> colorSpace : colorSpaces) {
141 make(&bitmap, colorType, alphaType, colorSpace);
Matt Sarett62bb2802017-01-23 12:28:02 -0500142 auto image = SkImage::MakeFromEncoded(encode_data(bitmap, fEncodedFormat));
Matt Sarett84014f02017-01-10 11:28:54 -0500143 canvas->drawImage(image.get(), 0.0f, 0.0f);
144 canvas->translate((float) imageWidth, 0.0f);
145 }
146 canvas->restore();
147 canvas->translate(0.0f, (float) imageHeight);
148 }
149 }
150 }
151
152private:
Matt Sarett62bb2802017-01-23 12:28:02 -0500153 SkEncodedImageFormat fEncodedFormat;
154
Matt Sarett84014f02017-01-10 11:28:54 -0500155 typedef GM INHERITED;
156};
157
Matt Sarett62bb2802017-01-23 12:28:02 -0500158DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kPNG); )
159DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kWEBP); )
Matt Sarette95941f2017-01-27 18:16:40 -0500160DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kJPEG); )
Matt Sarett84014f02017-01-10 11:28:54 -0500161}