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