Flutter Engine
The Flutter Engine
SkEncodedInfo.h
Go to the documentation of this file.
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#ifndef SkEncodedInfo_DEFINED
9#define SkEncodedInfo_DEFINED
10
14#include "include/core/SkData.h"
19#include "modules/skcms/skcms.h"
20
21#include <cstdint>
22#include <memory>
23#include <utility>
24
26public:
27 class ICCProfile {
28 public:
29 static std::unique_ptr<ICCProfile> Make(sk_sp<SkData>);
30 static std::unique_ptr<ICCProfile> Make(const skcms_ICCProfile&);
31
32 const skcms_ICCProfile* profile() const { return &fProfile; }
33 sk_sp<SkData> data() const { return fData; }
34 private:
35 ICCProfile(const skcms_ICCProfile&, sk_sp<SkData> = nullptr);
36
37 skcms_ICCProfile fProfile;
38 sk_sp<SkData> fData;
39 };
40
41 enum Alpha {
44
45 // Each pixel is either fully opaque or fully transparent.
46 // There is no difference between requesting kPremul or kUnpremul.
48 };
49
50 /*
51 * We strive to make the number of components per pixel obvious through
52 * our naming conventions.
53 * Ex: kRGB has 3 components. kRGBA has 4 components.
54 *
55 * This sometimes results in redundant Alpha and Color information.
56 * Ex: kRGB images must also be kOpaque.
57 */
58 enum Color {
59 // PNG, WBMP
61
62 // PNG
64
65 // PNG with Skia-specific sBIT
66 // Like kGrayAlpha, except this expects to be treated as
67 // kAlpha_8_SkColorType, which ignores the gray component. If
68 // decoded to full color (e.g. kN32), the gray component is respected
69 // (so it can share code with kGrayAlpha).
71
72 // PNG
73 // 565 images may be encoded to PNG by specifying the number of
74 // significant bits for each channel. This is a strange 565
75 // representation because the image is still encoded with 8 bits per
76 // component.
78
79 // PNG, GIF, BMP
81
82 // PNG, RAW
85
86 // BMP
90
91 // JPEG, WEBP
93
94 // WEBP
96
97 // JPEG
98 // Photoshop actually writes inverted CMYK data into JPEGs, where zero
99 // represents 100% ink coverage. For this reason, we treat CMYK JPEGs
100 // as having inverted CMYK. libjpeg-turbo warns that this may break
101 // other applications, but the CMYK JPEGs we see on the web expect to
102 // be treated as inverted CMYK.
105 };
106
108 int bitsPerComponent) {
109 return Make(width, height, color, alpha, bitsPerComponent, nullptr);
110 }
111
113 Alpha alpha, int bitsPerComponent, std::unique_ptr<ICCProfile> profile) {
114 return Make(width, height, color, alpha, /*bitsPerComponent*/ bitsPerComponent,
115 std::move(profile), /*colorDepth*/ bitsPerComponent);
116 }
117
119 Alpha alpha, int bitsPerComponent, std::unique_ptr<ICCProfile> profile,
120 int colorDepth) {
122 2 == bitsPerComponent ||
123 4 == bitsPerComponent ||
124 8 == bitsPerComponent ||
125 16 == bitsPerComponent);
126
127 switch (color) {
128 case kGray_Color:
130 break;
131 case kGrayAlpha_Color:
133 break;
134 case kPalette_Color:
136 break;
137 case kRGB_Color:
138 case kBGR_Color:
139 case kBGRX_Color:
142 break;
143 case kYUV_Color:
145 case kYCCK_Color:
148 break;
149 case kRGBA_Color:
151 break;
152 case kBGRA_Color:
153 case kYUVA_Color:
155 break;
156 case kXAlpha_Color:
159 break;
160 case k565_Color:
163 break;
164 default:
165 SkASSERT(false);
166 break;
167 }
168
169 return SkEncodedInfo(width,
170 height,
171 color,
172 alpha,
174 SkToU8(colorDepth),
175 std::move(profile));
176 }
177
178 /*
179 * Returns a recommended SkImageInfo.
180 *
181 * TODO: Leave this up to the client.
182 */
184 auto ct = kGray_Color == fColor ? kGray_8_SkColorType :
186 k565_Color == fColor ? kRGB_565_SkColorType :
187 kN32_SkColorType ;
188 auto alpha = kOpaque_Alpha == fAlpha ? kOpaque_SkAlphaType
190 sk_sp<SkColorSpace> cs = fProfile ? SkColorSpace::Make(*fProfile->profile())
191 : nullptr;
192 if (!cs) {
194 }
195 return SkImageInfo::Make(fWidth, fHeight, ct, alpha, std::move(cs));
196 }
197
198 int width() const { return fWidth; }
199 int height() const { return fHeight; }
200 Color color() const { return fColor; }
201 Alpha alpha() const { return fAlpha; }
202 bool opaque() const { return fAlpha == kOpaque_Alpha; }
203 const skcms_ICCProfile* profile() const {
204 if (!fProfile) return nullptr;
205 return fProfile->profile();
206 }
208 if (!fProfile) return nullptr;
209 return fProfile->data();
210 }
211
212 uint8_t bitsPerComponent() const { return fBitsPerComponent; }
213
214 uint8_t bitsPerPixel() const {
215 switch (fColor) {
216 case kGray_Color:
217 return fBitsPerComponent;
218 case kXAlpha_Color:
219 case kGrayAlpha_Color:
220 return 2 * fBitsPerComponent;
221 case kPalette_Color:
222 return fBitsPerComponent;
223 case kRGB_Color:
224 case kBGR_Color:
225 case kYUV_Color:
226 case k565_Color:
227 return 3 * fBitsPerComponent;
228 case kRGBA_Color:
229 case kBGRA_Color:
230 case kBGRX_Color:
231 case kYUVA_Color:
233 case kYCCK_Color:
234 return 4 * fBitsPerComponent;
235 default:
236 SkASSERT(false);
237 return 0;
238 }
239 }
240
241 SkEncodedInfo(const SkEncodedInfo& orig) = delete;
243
244 SkEncodedInfo(SkEncodedInfo&& orig) = default;
246
247 // Explicit copy method, to avoid accidental copying.
250 fWidth, fHeight, fColor, fAlpha, fBitsPerComponent, nullptr, fColorDepth);
251 if (fProfile) {
252 copy.fProfile = std::make_unique<ICCProfile>(*fProfile);
253 }
254 return copy;
255 }
256
257 // Return number of bits of R/G/B channel
258 uint8_t getColorDepth() const {
259 return fColorDepth;
260 }
261
262private:
264 uint8_t bitsPerComponent, uint8_t colorDepth, std::unique_ptr<ICCProfile> profile)
265 : fWidth(width)
266 , fHeight(height)
267 , fColor(color)
268 , fAlpha(alpha)
269 , fBitsPerComponent(bitsPerComponent)
270 , fColorDepth(colorDepth)
271 , fProfile(std::move(profile))
272 {}
273
274 int fWidth;
275 int fHeight;
276 Color fColor;
277 Alpha fAlpha;
278 uint8_t fBitsPerComponent;
279 uint8_t fColorDepth;
280 std::unique_ptr<ICCProfile> fProfile;
281};
282
283#endif
kUnpremul_SkAlphaType
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > Make(const skcms_ICCProfile &)
const skcms_ICCProfile * profile() const
Definition: SkEncodedInfo.h:32
sk_sp< SkData > data() const
Definition: SkEncodedInfo.h:33
static std::unique_ptr< ICCProfile > Make(sk_sp< SkData >)
Definition: copy.py:1
Definition: ref_ptr.h:256
sk_sp< SkData > profileData() const
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent, std::unique_ptr< ICCProfile > profile)
SkEncodedInfo & operator=(SkEncodedInfo &&)=default
Color color() const
SkImageInfo makeImageInfo() const
SkEncodedInfo & operator=(const SkEncodedInfo &)=delete
uint8_t bitsPerPixel() const
SkEncodedInfo copy() const
SkEncodedInfo(const SkEncodedInfo &orig)=delete
const skcms_ICCProfile * profile() const
int width() const
int height() const
bool opaque() const
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent, std::unique_ptr< ICCProfile > profile, int colorDepth)
uint8_t getColorDepth() const
Alpha alpha() const
uint8_t bitsPerComponent() const
SkEncodedInfo(SkEncodedInfo &&orig)=default
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)