1 /*
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/gm.h"
9 #include "include/codec/SkCodec.h"
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColorSpace.h"
13 #include "include/core/SkData.h"
14 #include "include/core/SkEncodedImageFormat.h"
15 #include "include/core/SkImage.h"
16 #include "include/core/SkImageInfo.h"
17 #include "include/core/SkPixmap.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkSize.h"
20 #include "include/core/SkStream.h"
21 #include "include/core/SkString.h"
22 #include "include/core/SkTypes.h"
23 #include "include/encode/SkJpegEncoder.h"
24 #include "include/encode/SkPngEncoder.h"
25 #include "include/encode/SkWebpEncoder.h"
26 #include "tools/Resources.h"
27
28 #include <memory>
29
30 namespace skiagm {
31
32 static const int imageWidth = 128;
33 static const int imageHeight = 128;
34
make(SkBitmap * bitmap,SkColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace)35 static void make(SkBitmap* bitmap, SkColorType colorType, SkAlphaType alphaType,
36 sk_sp<SkColorSpace> colorSpace) {
37 const char* resource;
38 switch (colorType) {
39 case kGray_8_SkColorType:
40 resource = "images/grayscale.jpg";
41 alphaType = kOpaque_SkAlphaType;
42 break;
43 case kRGB_565_SkColorType:
44 resource = "images/color_wheel.jpg";
45 alphaType = kOpaque_SkAlphaType;
46 break;
47 default:
48 resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg"
49 : "images/color_wheel.png";
50 break;
51 }
52
53 sk_sp<SkData> data = GetResourceAsData(resource);
54 if (!data) {
55 return;
56 }
57 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data);
58 SkImageInfo dstInfo = codec->getInfo().makeColorType(colorType)
59 .makeAlphaType(alphaType)
60 .makeColorSpace(colorSpace);
61 bitmap->allocPixels(dstInfo);
62 codec->getPixels(dstInfo, bitmap->getPixels(), bitmap->rowBytes());
63 }
64
encode_data(const SkBitmap & bitmap,SkEncodedImageFormat format)65 static sk_sp<SkData> encode_data(const SkBitmap& bitmap, SkEncodedImageFormat format) {
66 SkPixmap src;
67 if (!bitmap.peekPixels(&src)) {
68 return nullptr;
69 }
70 SkDynamicMemoryWStream buf;
71
72 switch (format) {
73 case SkEncodedImageFormat::kPNG:
74 SkAssertResult(SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options()));
75 break;
76 case SkEncodedImageFormat::kWEBP:
77 SkAssertResult(SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options()));
78 break;
79 case SkEncodedImageFormat::kJPEG:
80 SkAssertResult(SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options()));
81 break;
82 default:
83 break;
84 }
85 return buf.detachAsData();
86 }
87
88 class EncodeSRGBGM : public GM {
89 public:
EncodeSRGBGM(SkEncodedImageFormat format)90 EncodeSRGBGM(SkEncodedImageFormat format)
91 : fEncodedFormat(format)
92 {}
93
94 protected:
onShortName()95 SkString onShortName() override {
96 const char* format = nullptr;
97 switch (fEncodedFormat) {
98 case SkEncodedImageFormat::kPNG:
99 format = "png";
100 break;
101 case SkEncodedImageFormat::kWEBP:
102 format = "webp";
103 break;
104 case SkEncodedImageFormat::kJPEG:
105 format = "jpg";
106 break;
107 default:
108 break;
109 }
110 return SkStringPrintf("encode-srgb-%s", format);
111 }
112
onISize()113 SkISize onISize() override {
114 return SkISize::Make(imageWidth * 2, imageHeight * 15);
115 }
116
onDraw(SkCanvas * canvas)117 void onDraw(SkCanvas* canvas) override {
118 const SkColorType colorTypes[] = {
119 kN32_SkColorType, kRGBA_F16_SkColorType, kGray_8_SkColorType, kRGB_565_SkColorType,
120 };
121 const SkAlphaType alphaTypes[] = {
122 kUnpremul_SkAlphaType, kPremul_SkAlphaType, kOpaque_SkAlphaType,
123 };
124 const sk_sp<SkColorSpace> colorSpaces[] = {
125 nullptr, SkColorSpace::MakeSRGB(),
126 };
127
128 SkBitmap bitmap;
129 for (SkColorType colorType : colorTypes) {
130 for (SkAlphaType alphaType : alphaTypes) {
131 canvas->save();
132 for (const sk_sp<SkColorSpace>& colorSpace : colorSpaces) {
133 make(&bitmap, colorType, alphaType, colorSpace);
134 auto image = SkImage::MakeFromEncoded(encode_data(bitmap, fEncodedFormat));
135 canvas->drawImage(image.get(), 0.0f, 0.0f);
136 canvas->translate((float) imageWidth, 0.0f);
137 }
138 canvas->restore();
139 canvas->translate(0.0f, (float) imageHeight);
140 }
141 }
142 }
143
144 private:
145 SkEncodedImageFormat fEncodedFormat;
146
147 using INHERITED = GM;
148 };
149
150 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kPNG); )
151 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kWEBP); )
152 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kJPEG); )
153 } // namespace skiagm
154