xref: /aosp_15_r20/external/skia/gm/encode_srgb.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/codec/SkEncodedImageFormat.h"
11 #include "include/core/SkBitmap.h"
12 #include "include/core/SkCanvas.h"
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkData.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             SK_ABORT("Unsupported format %d", (int)format);
84             break;
85     }
86     return buf.detachAsData();
87 }
88 
89 class EncodeSRGBGM : public GM {
90 public:
EncodeSRGBGM(SkEncodedImageFormat format)91     EncodeSRGBGM(SkEncodedImageFormat format)
92         : fEncodedFormat(format)
93     {}
94 
95 protected:
getName() const96     SkString getName() const override {
97         const char* format = nullptr;
98         switch (fEncodedFormat) {
99             case SkEncodedImageFormat::kPNG:
100                 format = "png";
101                 break;
102             case SkEncodedImageFormat::kWEBP:
103                 format = "webp";
104                 break;
105             case SkEncodedImageFormat::kJPEG:
106                 format = "jpg";
107                 break;
108             default:
109                 break;
110         }
111         return SkStringPrintf("encode-srgb-%s", format);
112     }
113 
getISize()114     SkISize getISize() override { return SkISize::Make(imageWidth * 2, imageHeight * 15); }
115 
onDraw(SkCanvas * canvas)116     void onDraw(SkCanvas* canvas) override {
117         const SkColorType colorTypes[] = {
118             kN32_SkColorType, kRGBA_F16_SkColorType,
119 #if !defined(SK_ENABLE_NDK_IMAGES)
120             // These fail with the NDK encoders because there is a mismatch between
121             // Gray_8 and Alpha_8
122             kGray_8_SkColorType,
123 #endif
124             kRGB_565_SkColorType,
125         };
126         const SkAlphaType alphaTypes[] = {
127             kUnpremul_SkAlphaType, kPremul_SkAlphaType, kOpaque_SkAlphaType,
128         };
129         const sk_sp<SkColorSpace> colorSpaces[] = {
130             nullptr, SkColorSpace::MakeSRGB(),
131         };
132 
133         SkBitmap bitmap;
134         for (SkColorType colorType : colorTypes) {
135             for (SkAlphaType alphaType : alphaTypes) {
136                 canvas->save();
137                 for (const sk_sp<SkColorSpace>& colorSpace : colorSpaces) {
138                     make(&bitmap, colorType, alphaType, colorSpace);
139                     auto data = encode_data(bitmap, fEncodedFormat);
140                     auto image = SkImages::DeferredFromEncodedData(data);
141                     canvas->drawImage(image.get(), 0.0f, 0.0f);
142                     canvas->translate((float) imageWidth, 0.0f);
143                 }
144                 canvas->restore();
145                 canvas->translate(0.0f, (float) imageHeight);
146             }
147         }
148     }
149 
150 private:
151     SkEncodedImageFormat fEncodedFormat;
152 
153     using INHERITED = GM;
154 };
155 
156 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kPNG); )
157 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kWEBP); )
158 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kJPEG); )
159 }  // namespace skiagm
160