1 | /* |
2 | * Copyright 2013 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 SkImageInfo_DEFINED |
9 | #define SkImageInfo_DEFINED |
10 | |
11 | #include "include/core/SkColorSpace.h" |
12 | #include "include/core/SkMath.h" |
13 | #include "include/core/SkRect.h" |
14 | #include "include/core/SkSize.h" |
15 | |
16 | #include "include/private/SkTFitsIn.h" |
17 | #include "include/private/SkTo.h" |
18 | |
19 | class SkReadBuffer; |
20 | class SkWriteBuffer; |
21 | |
22 | /** \enum SkImageInfo::SkAlphaType |
23 | Describes how to interpret the alpha component of a pixel. A pixel may |
24 | be opaque, or alpha, describing multiple levels of transparency. |
25 | |
26 | In simple blending, alpha weights the draw color and the destination |
27 | color to create a new color. If alpha describes a weight from zero to one: |
28 | |
29 | new color = draw color * alpha + destination color * (1 - alpha) |
30 | |
31 | In practice alpha is encoded in two or more bits, where 1.0 equals all bits set. |
32 | |
33 | RGB may have alpha included in each component value; the stored |
34 | value is the original RGB multiplied by alpha. Premultiplied color |
35 | components improve performance. |
36 | */ |
37 | enum SkAlphaType { |
38 | kUnknown_SkAlphaType, //!< uninitialized |
39 | kOpaque_SkAlphaType, //!< pixel is opaque |
40 | kPremul_SkAlphaType, //!< pixel components are premultiplied by alpha |
41 | kUnpremul_SkAlphaType, //!< pixel components are independent of alpha |
42 | kLastEnum_SkAlphaType = kUnpremul_SkAlphaType, //!< last valid value |
43 | }; |
44 | |
45 | /** Returns true if SkAlphaType equals kOpaque_SkAlphaType. |
46 | |
47 | kOpaque_SkAlphaType is a hint that the SkColorType is opaque, or that all |
48 | alpha values are set to their 1.0 equivalent. If SkAlphaType is |
49 | kOpaque_SkAlphaType, and SkColorType is not opaque, then the result of |
50 | drawing any pixel with a alpha value less than 1.0 is undefined. |
51 | */ |
52 | static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) { |
53 | return kOpaque_SkAlphaType == at; |
54 | } |
55 | |
56 | /////////////////////////////////////////////////////////////////////////////// |
57 | |
58 | /** \enum SkImageInfo::SkColorType |
59 | Describes how pixel bits encode color. A pixel may be an alpha mask, a grayscale, RGB, or ARGB. |
60 | |
61 | kN32_SkColorType selects the native 32-bit ARGB format for the current configuration. This can |
62 | lead to inconsistent results across platforms, so use with caution. |
63 | */ |
64 | enum SkColorType { |
65 | kUnknown_SkColorType, //!< uninitialized |
66 | kAlpha_8_SkColorType, //!< pixel with alpha in 8-bit byte |
67 | kRGB_565_SkColorType, //!< pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word |
68 | kARGB_4444_SkColorType, //!< pixel with 4 bits for alpha, red, green, blue; in 16-bit word |
69 | kRGBA_8888_SkColorType, //!< pixel with 8 bits for red, green, blue, alpha; in 32-bit word |
70 | kRGB_888x_SkColorType, //!< pixel with 8 bits each for red, green, blue; in 32-bit word |
71 | kBGRA_8888_SkColorType, //!< pixel with 8 bits for blue, green, red, alpha; in 32-bit word |
72 | kRGBA_1010102_SkColorType, //!< 10 bits for red, green, blue; 2 bits for alpha; in 32-bit word |
73 | kBGRA_1010102_SkColorType, //!< 10 bits for blue, green, red; 2 bits for alpha; in 32-bit word |
74 | kRGB_101010x_SkColorType, //!< pixel with 10 bits each for red, green, blue; in 32-bit word |
75 | kBGR_101010x_SkColorType, //!< pixel with 10 bits each for blue, green, red; in 32-bit word |
76 | kGray_8_SkColorType, //!< pixel with grayscale level in 8-bit byte |
77 | kRGBA_F16Norm_SkColorType, //!< pixel with half floats in [0,1] for red, green, blue, alpha; |
78 | // in 64-bit word |
79 | kRGBA_F16_SkColorType, //!< pixel with half floats for red, green, blue, alpha; |
80 | // in 64-bit word |
81 | kRGBA_F32_SkColorType, //!< pixel using C float for red, green, blue, alpha; in 128-bit word |
82 | |
83 | // The following 6 colortypes are just for reading from - not for rendering to |
84 | kR8G8_unorm_SkColorType, //!< pixel with a uint8_t for red and green |
85 | |
86 | kA16_float_SkColorType, //!< pixel with a half float for alpha |
87 | kR16G16_float_SkColorType, //!< pixel with a half float for red and green |
88 | |
89 | kA16_unorm_SkColorType, //!< pixel with a little endian uint16_t for alpha |
90 | kR16G16_unorm_SkColorType, //!< pixel with a little endian uint16_t for red and green |
91 | kR16G16B16A16_unorm_SkColorType, //!< pixel with a little endian uint16_t for red, green, blue |
92 | // and alpha |
93 | |
94 | kLastEnum_SkColorType = kR16G16B16A16_unorm_SkColorType, //!< last valid value |
95 | |
96 | #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) |
97 | kN32_SkColorType = kBGRA_8888_SkColorType,//!< native 32-bit BGRA encoding |
98 | |
99 | #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) |
100 | kN32_SkColorType = kRGBA_8888_SkColorType,//!< native 32-bit RGBA encoding |
101 | |
102 | #else |
103 | #error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order" |
104 | #endif |
105 | }; |
106 | |
107 | /** Returns the number of bytes required to store a pixel, including unused padding. |
108 | Returns zero if ct is kUnknown_SkColorType or invalid. |
109 | |
110 | @return bytes per pixel |
111 | */ |
112 | SK_API int SkColorTypeBytesPerPixel(SkColorType ct); |
113 | |
114 | /** Returns true if SkColorType always decodes alpha to 1.0, making the pixel |
115 | fully opaque. If true, SkColorType does not reserve bits to encode alpha. |
116 | |
117 | @return true if alpha is always set to 1.0 |
118 | */ |
119 | SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct); |
120 | |
121 | /** Returns true if canonical can be set to a valid SkAlphaType for colorType. If |
122 | there is more than one valid canonical SkAlphaType, set to alphaType, if valid. |
123 | If true is returned and canonical is not nullptr, store valid SkAlphaType. |
124 | |
125 | Returns false only if alphaType is kUnknown_SkAlphaType, color type is not |
126 | kUnknown_SkColorType, and SkColorType is not always opaque. If false is returned, |
127 | canonical is ignored. |
128 | |
129 | @param canonical storage for SkAlphaType |
130 | @return true if valid SkAlphaType can be associated with colorType |
131 | */ |
132 | SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, |
133 | SkAlphaType* canonical = nullptr); |
134 | |
135 | /** \enum SkImageInfo::SkYUVColorSpace |
136 | Describes color range of YUV pixels. The color mapping from YUV to RGB varies |
137 | depending on the source. YUV pixels may be generated by JPEG images, standard |
138 | video streams, or high definition video streams. Each has its own mapping from |
139 | YUV to RGB. |
140 | |
141 | JPEG YUV values encode the full range of 0 to 255 for all three components. |
142 | Video YUV values often range from 16 to 235 for Y and from 16 to 240 for U and V (limited). |
143 | Details of encoding and conversion to RGB are described in YCbCr color space. |
144 | |
145 | The identity colorspace exists to provide a utility mapping from Y to R, U to G and V to B. |
146 | It can be used to visualize the YUV planes or to explicitly post process the YUV channels. |
147 | */ |
148 | enum SkYUVColorSpace { |
149 | kJPEG_Full_SkYUVColorSpace, //!< describes full range |
150 | kRec601_Limited_SkYUVColorSpace, //!< describes SDTV range |
151 | kRec709_Full_SkYUVColorSpace, //!< describes HDTV range |
152 | kRec709_Limited_SkYUVColorSpace, |
153 | kBT2020_8bit_Full_SkYUVColorSpace, //!< describes UHDTV range, non-constant-luminance |
154 | kBT2020_8bit_Limited_SkYUVColorSpace, |
155 | kBT2020_10bit_Full_SkYUVColorSpace, |
156 | kBT2020_10bit_Limited_SkYUVColorSpace, |
157 | kBT2020_12bit_Full_SkYUVColorSpace, |
158 | kBT2020_12bit_Limited_SkYUVColorSpace, |
159 | kIdentity_SkYUVColorSpace, //!< maps Y->R, U->G, V->B |
160 | |
161 | kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value |
162 | |
163 | // Legacy (deprecated) names: |
164 | kJPEG_SkYUVColorSpace = kJPEG_Full_SkYUVColorSpace, |
165 | kRec601_SkYUVColorSpace = kRec601_Limited_SkYUVColorSpace, |
166 | kRec709_SkYUVColorSpace = kRec709_Limited_SkYUVColorSpace, |
167 | kBT2020_SkYUVColorSpace = kBT2020_8bit_Limited_SkYUVColorSpace, |
168 | }; |
169 | |
170 | /** \struct SkColorInfo |
171 | Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by |
172 | providing dimensions. |
173 | |
174 | It encodes how pixel bits describe alpha, transparency; color components red, blue, |
175 | and green; and SkColorSpace, the range and linearity of colors. |
176 | */ |
177 | class SK_API SkColorInfo { |
178 | public: |
179 | /** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType, |
180 | and no SkColorSpace. |
181 | |
182 | @return empty SkImageInfo |
183 | */ |
184 | SkColorInfo() = default; |
185 | |
186 | /** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs. |
187 | |
188 | If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace |
189 | defaults to sRGB, mapping into SkSurface SkColorSpace. |
190 | |
191 | Parameters are not validated to see if their values are legal, or that the |
192 | combination is supported. |
193 | @return created SkColorInfo |
194 | */ |
195 | SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs) |
196 | : fColorSpace(std::move(cs)), fColorType(ct), fAlphaType(at) {} |
197 | |
198 | SkColorInfo(const SkColorInfo&) = default; |
199 | SkColorInfo(SkColorInfo&&) = default; |
200 | |
201 | SkColorInfo& operator=(const SkColorInfo&) = default; |
202 | SkColorInfo& operator=(SkColorInfo&&) = default; |
203 | |
204 | SkColorSpace* colorSpace() const { return fColorSpace.get(); } |
205 | sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; } |
206 | SkColorType colorType() const { return fColorType; } |
207 | SkAlphaType alphaType() const { return fAlphaType; } |
208 | |
209 | bool isOpaque() const { |
210 | return SkAlphaTypeIsOpaque(fAlphaType) |
211 | || SkColorTypeIsAlwaysOpaque(fColorType); |
212 | } |
213 | |
214 | bool gammaCloseToSRGB() const { return fColorSpace && fColorSpace->gammaCloseToSRGB(); } |
215 | |
216 | /** Does other represent the same color type, alpha type, and color space? */ |
217 | bool operator==(const SkColorInfo& other) const { |
218 | return fColorType == other.fColorType && fAlphaType == other.fAlphaType && |
219 | SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get()); |
220 | } |
221 | |
222 | /** Does other represent a different color type, alpha type, or color space? */ |
223 | bool operator!=(const SkColorInfo& other) const { return !(*this == other); } |
224 | |
225 | /** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set |
226 | to newAlphaType. |
227 | |
228 | Created SkColorInfo contains newAlphaType even if it is incompatible with |
229 | SkColorType, in which case SkAlphaType in SkColorInfo is ignored. |
230 | */ |
231 | SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const { |
232 | return SkColorInfo(this->colorType(), newAlphaType, this->refColorSpace()); |
233 | } |
234 | |
235 | /** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType |
236 | set to newColorType. |
237 | */ |
238 | SkColorInfo makeColorType(SkColorType newColorType) const { |
239 | return SkColorInfo(newColorType, this->alphaType(), this->refColorSpace()); |
240 | } |
241 | |
242 | /** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace |
243 | set to cs. cs may be nullptr. |
244 | */ |
245 | SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const { |
246 | return SkColorInfo(this->colorType(), this->alphaType(), std::move(cs)); |
247 | } |
248 | |
249 | /** Returns number of bytes per pixel required by SkColorType. |
250 | Returns zero if colorType() is kUnknown_SkColorType. |
251 | |
252 | @return bytes in pixel |
253 | |
254 | example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel |
255 | */ |
256 | int bytesPerPixel() const; |
257 | |
258 | /** Returns bit shift converting row bytes to row pixels. |
259 | Returns zero for kUnknown_SkColorType. |
260 | |
261 | @return one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes |
262 | |
263 | example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel |
264 | */ |
265 | int shiftPerPixel() const; |
266 | |
267 | private: |
268 | sk_sp<SkColorSpace> fColorSpace; |
269 | SkColorType fColorType = kUnknown_SkColorType; |
270 | SkAlphaType fAlphaType = kUnknown_SkAlphaType; |
271 | }; |
272 | |
273 | /** \struct SkImageInfo |
274 | Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface |
275 | can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and |
276 | SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface |
277 | implementations may defer pixel depth, so may not completely specify SkImageInfo. |
278 | |
279 | SkImageInfo contains dimensions, the pixel integral width and height. It encodes |
280 | how pixel bits describe alpha, transparency; color components red, blue, |
281 | and green; and SkColorSpace, the range and linearity of colors. |
282 | */ |
283 | struct SK_API SkImageInfo { |
284 | public: |
285 | |
286 | /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType, |
287 | a width and height of zero, and no SkColorSpace. |
288 | |
289 | @return empty SkImageInfo |
290 | */ |
291 | SkImageInfo() = default; |
292 | |
293 | /** Creates SkImageInfo from integral dimensions width and height, SkColorType ct, |
294 | SkAlphaType at, and optionally SkColorSpace cs. |
295 | |
296 | If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace |
297 | defaults to sRGB, mapping into SkSurface SkColorSpace. |
298 | |
299 | Parameters are not validated to see if their values are legal, or that the |
300 | combination is supported. |
301 | |
302 | @param width pixel column count; must be zero or greater |
303 | @param height pixel row count; must be zero or greater |
304 | @param cs range of colors; may be nullptr |
305 | @return created SkImageInfo |
306 | */ |
307 | static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at, |
308 | sk_sp<SkColorSpace> cs = nullptr) { |
309 | return SkImageInfo({width, height}, {ct, at, std::move(cs)}); |
310 | } |
311 | static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at, |
312 | sk_sp<SkColorSpace> cs = nullptr) { |
313 | return SkImageInfo(dimensions, {ct, at, std::move(cs)}); |
314 | } |
315 | |
316 | /** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo, |
317 | |
318 | Parameters are not validated to see if their values are legal, or that the |
319 | combination is supported. |
320 | |
321 | @param dimensions pixel column and row count; must be zeros or greater |
322 | @param SkColorInfo the pixel encoding consisting of SkColorType, SkAlphaType, and |
323 | SkColorSpace (which may be nullptr) |
324 | @return created SkImageInfo |
325 | */ |
326 | static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) { |
327 | return SkImageInfo(dimensions, colorInfo); |
328 | } |
329 | static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) { |
330 | return SkImageInfo(dimensions, std::move(colorInfo)); |
331 | } |
332 | |
333 | /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType, |
334 | SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either |
335 | kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal. |
336 | |
337 | If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace |
338 | defaults to sRGB, mapping into SkSurface SkColorSpace. |
339 | |
340 | Parameters are not validated to see if their values are legal, or that the |
341 | combination is supported. |
342 | |
343 | @param width pixel column count; must be zero or greater |
344 | @param height pixel row count; must be zero or greater |
345 | @param cs range of colors; may be nullptr |
346 | @return created SkImageInfo |
347 | */ |
348 | static SkImageInfo MakeN32(int width, int height, SkAlphaType at, |
349 | sk_sp<SkColorSpace> cs = nullptr) { |
350 | return Make({width, height}, kN32_SkColorType, at, std::move(cs)); |
351 | } |
352 | |
353 | /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType, |
354 | SkAlphaType at, with sRGB SkColorSpace. |
355 | |
356 | Parameters are not validated to see if their values are legal, or that the |
357 | combination is supported. |
358 | |
359 | @param width pixel column count; must be zero or greater |
360 | @param height pixel row count; must be zero or greater |
361 | @return created SkImageInfo |
362 | |
363 | example: https://fiddle.skia.org/c/@ImageInfo_MakeS32 |
364 | */ |
365 | static SkImageInfo MakeS32(int width, int height, SkAlphaType at); |
366 | |
367 | /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType, |
368 | kPremul_SkAlphaType, with optional SkColorSpace. |
369 | |
370 | If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace |
371 | defaults to sRGB, mapping into SkSurface SkColorSpace. |
372 | |
373 | Parameters are not validated to see if their values are legal, or that the |
374 | combination is supported. |
375 | |
376 | @param width pixel column count; must be zero or greater |
377 | @param height pixel row count; must be zero or greater |
378 | @param cs range of colors; may be nullptr |
379 | @return created SkImageInfo |
380 | */ |
381 | static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) { |
382 | return Make({width, height}, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs)); |
383 | } |
384 | |
385 | /** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType, |
386 | kPremul_SkAlphaType, with SkColorSpace set to nullptr. |
387 | |
388 | If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping |
389 | into SkSurface SkColorSpace. |
390 | |
391 | Parameters are not validated to see if their values are legal, or that the |
392 | combination is supported. |
393 | |
394 | @param dimensions width and height, each must be zero or greater |
395 | @param cs range of colors; may be nullptr |
396 | @return created SkImageInfo |
397 | */ |
398 | static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs = nullptr) { |
399 | return Make(dimensions, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs)); |
400 | } |
401 | |
402 | /** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType, |
403 | kPremul_SkAlphaType, with SkColorSpace set to nullptr. |
404 | |
405 | @param width pixel column count; must be zero or greater |
406 | @param height pixel row count; must be zero or greater |
407 | @return created SkImageInfo |
408 | */ |
409 | static SkImageInfo MakeA8(int width, int height) { |
410 | return Make({width, height}, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr); |
411 | } |
412 | /** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType, |
413 | kPremul_SkAlphaType, with SkColorSpace set to nullptr. |
414 | |
415 | @param dimensions pixel row and column count; must be zero or greater |
416 | @return created SkImageInfo |
417 | */ |
418 | static SkImageInfo MakeA8(SkISize dimensions) { |
419 | return Make(dimensions, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr); |
420 | } |
421 | |
422 | /** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType, |
423 | kUnknown_SkAlphaType, with SkColorSpace set to nullptr. |
424 | |
425 | Returned SkImageInfo as part of source does not draw, and as part of destination |
426 | can not be drawn to. |
427 | |
428 | @param width pixel column count; must be zero or greater |
429 | @param height pixel row count; must be zero or greater |
430 | @return created SkImageInfo |
431 | */ |
432 | static SkImageInfo MakeUnknown(int width, int height) { |
433 | return Make({width, height}, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr); |
434 | } |
435 | |
436 | /** Creates SkImageInfo from integral dimensions width and height set to zero, |
437 | kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr. |
438 | |
439 | Returned SkImageInfo as part of source does not draw, and as part of destination |
440 | can not be drawn to. |
441 | |
442 | @return created SkImageInfo |
443 | */ |
444 | static SkImageInfo MakeUnknown() { |
445 | return MakeUnknown(0, 0); |
446 | } |
447 | |
448 | /** Returns pixel count in each row. |
449 | |
450 | @return pixel width |
451 | */ |
452 | int width() const { return fDimensions.width(); } |
453 | |
454 | /** Returns pixel row count. |
455 | |
456 | @return pixel height |
457 | */ |
458 | int height() const { return fDimensions.height(); } |
459 | |
460 | SkColorType colorType() const { return fColorInfo.colorType(); } |
461 | |
462 | SkAlphaType alphaType() const { return fColorInfo.alphaType(); } |
463 | |
464 | /** Returns SkColorSpace, the range of colors. The reference count of |
465 | SkColorSpace is unchanged. The returned SkColorSpace is immutable. |
466 | |
467 | @return SkColorSpace, or nullptr |
468 | */ |
469 | SkColorSpace* colorSpace() const { return fColorInfo.colorSpace(); } |
470 | |
471 | /** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer |
472 | tracks the number of objects sharing this SkColorSpace reference so the memory |
473 | is released when the owners destruct. |
474 | |
475 | The returned SkColorSpace is immutable. |
476 | |
477 | @return SkColorSpace wrapped in a smart pointer |
478 | */ |
479 | sk_sp<SkColorSpace> refColorSpace() const { return fColorInfo.refColorSpace(); } |
480 | |
481 | /** Returns if SkImageInfo describes an empty area of pixels by checking if either |
482 | width or height is zero or smaller. |
483 | |
484 | @return true if either dimension is zero or smaller |
485 | */ |
486 | bool isEmpty() const { return fDimensions.isEmpty(); } |
487 | |
488 | /** Returns the dimensionless SkColorInfo that represents the same color type, |
489 | alpha type, and color space as this SkImageInfo. |
490 | */ |
491 | const SkColorInfo& colorInfo() const { return fColorInfo; } |
492 | |
493 | /** Returns true if SkAlphaType is set to hint that all pixels are opaque; their |
494 | alpha value is implicitly or explicitly 1.0. If true, and all pixels are |
495 | not opaque, Skia may draw incorrectly. |
496 | |
497 | Does not check if SkColorType allows alpha, or if any pixel value has |
498 | transparency. |
499 | |
500 | @return true if SkAlphaType is kOpaque_SkAlphaType |
501 | */ |
502 | bool isOpaque() const { return fColorInfo.isOpaque(); } |
503 | |
504 | /** Returns SkISize { width(), height() }. |
505 | |
506 | @return integral size of width() and height() |
507 | */ |
508 | SkISize dimensions() const { return fDimensions; } |
509 | |
510 | /** Returns SkIRect { 0, 0, width(), height() }. |
511 | |
512 | @return integral rectangle from origin to width() and height() |
513 | */ |
514 | SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); } |
515 | |
516 | /** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma |
517 | is approximately the same as sRGB. |
518 | This includes the |
519 | |
520 | @return true if SkColorSpace gamma is approximately the same as sRGB |
521 | */ |
522 | bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); } |
523 | |
524 | /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType, |
525 | with dimensions set to width and height. |
526 | |
527 | @param newWidth pixel column count; must be zero or greater |
528 | @param newHeight pixel row count; must be zero or greater |
529 | @return created SkImageInfo |
530 | */ |
531 | SkImageInfo makeWH(int newWidth, int newHeight) const { |
532 | return Make({newWidth, newHeight}, fColorInfo); |
533 | } |
534 | |
535 | /** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType, |
536 | with dimensions set to newDimensions. |
537 | |
538 | @param newSize pixel column and row count; must be zero or greater |
539 | @return created SkImageInfo |
540 | */ |
541 | SkImageInfo makeDimensions(SkISize newSize) const { |
542 | return Make(newSize, fColorInfo); |
543 | } |
544 | |
545 | /** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height, |
546 | with SkAlphaType set to newAlphaType. |
547 | |
548 | Created SkImageInfo contains newAlphaType even if it is incompatible with |
549 | SkColorType, in which case SkAlphaType in SkImageInfo is ignored. |
550 | |
551 | @return created SkImageInfo |
552 | */ |
553 | SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const { |
554 | return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType)); |
555 | } |
556 | |
557 | /** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height, |
558 | with SkColorType set to newColorType. |
559 | |
560 | @return created SkImageInfo |
561 | */ |
562 | SkImageInfo makeColorType(SkColorType newColorType) const { |
563 | return Make(fDimensions, fColorInfo.makeColorType(newColorType)); |
564 | } |
565 | |
566 | /** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height, |
567 | with SkColorSpace set to cs. |
568 | |
569 | @param cs range of colors; may be nullptr |
570 | @return created SkImageInfo |
571 | */ |
572 | SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const { |
573 | return Make(fDimensions, fColorInfo.makeColorSpace(std::move(cs))); |
574 | } |
575 | |
576 | /** Returns number of bytes per pixel required by SkColorType. |
577 | Returns zero if colorType( is kUnknown_SkColorType. |
578 | |
579 | @return bytes in pixel |
580 | */ |
581 | int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); } |
582 | |
583 | /** Returns bit shift converting row bytes to row pixels. |
584 | Returns zero for kUnknown_SkColorType. |
585 | |
586 | @return one of: 0, 1, 2, 3; left shift to convert pixels to bytes |
587 | */ |
588 | int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); } |
589 | |
590 | /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which |
591 | specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit |
592 | in 31 bits. |
593 | |
594 | @return width() times bytesPerPixel() as unsigned 64-bit integer |
595 | */ |
596 | uint64_t minRowBytes64() const { |
597 | return (uint64_t)sk_64_mul(this->width(), this->bytesPerPixel()); |
598 | } |
599 | |
600 | /** Returns minimum bytes per row, computed from pixel width() and SkColorType, which |
601 | specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit |
602 | in 31 bits. |
603 | |
604 | @return width() times bytesPerPixel() as size_t |
605 | */ |
606 | size_t minRowBytes() const { |
607 | uint64_t minRowBytes = this->minRowBytes64(); |
608 | if (!SkTFitsIn<int32_t>(minRowBytes)) { |
609 | return 0; |
610 | } |
611 | return (size_t)minRowBytes; |
612 | } |
613 | |
614 | /** Returns byte offset of pixel from pixel base address. |
615 | |
616 | Asserts in debug build if x or y is outside of bounds. Does not assert if |
617 | rowBytes is smaller than minRowBytes(), even though result may be incorrect. |
618 | |
619 | @param x column index, zero or greater, and less than width() |
620 | @param y row index, zero or greater, and less than height() |
621 | @param rowBytes size of pixel row or larger |
622 | @return offset within pixel array |
623 | |
624 | example: https://fiddle.skia.org/c/@ImageInfo_computeOffset |
625 | */ |
626 | size_t computeOffset(int x, int y, size_t rowBytes) const; |
627 | |
628 | /** Compares SkImageInfo with other, and returns true if width, height, SkColorType, |
629 | SkAlphaType, and SkColorSpace are equivalent. |
630 | |
631 | @param other SkImageInfo to compare |
632 | @return true if SkImageInfo equals other |
633 | */ |
634 | bool operator==(const SkImageInfo& other) const { |
635 | return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo; |
636 | } |
637 | |
638 | /** Compares SkImageInfo with other, and returns true if width, height, SkColorType, |
639 | SkAlphaType, and SkColorSpace are not equivalent. |
640 | |
641 | @param other SkImageInfo to compare |
642 | @return true if SkImageInfo is not equal to other |
643 | */ |
644 | bool operator!=(const SkImageInfo& other) const { |
645 | return !(*this == other); |
646 | } |
647 | |
648 | /** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType, |
649 | and rowBytes. rowBytes is assumed to be at least as large as minRowBytes(). |
650 | |
651 | Returns zero if height is zero. |
652 | Returns SIZE_MAX if answer exceeds the range of size_t. |
653 | |
654 | @param rowBytes size of pixel row or larger |
655 | @return memory required by pixel buffer |
656 | |
657 | example: https://fiddle.skia.org/c/@ImageInfo_computeByteSize |
658 | */ |
659 | size_t computeByteSize(size_t rowBytes) const; |
660 | |
661 | /** Returns storage required by pixel array, given SkImageInfo dimensions, and |
662 | SkColorType. Uses minRowBytes() to compute bytes for pixel row. |
663 | |
664 | Returns zero if height is zero. |
665 | Returns SIZE_MAX if answer exceeds the range of size_t. |
666 | |
667 | @return least memory required by pixel buffer |
668 | */ |
669 | size_t computeMinByteSize() const { |
670 | return this->computeByteSize(this->minRowBytes()); |
671 | } |
672 | |
673 | /** Returns true if byteSize equals SIZE_MAX. computeByteSize() and |
674 | computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size. |
675 | |
676 | @param byteSize result of computeByteSize() or computeMinByteSize() |
677 | @return true if computeByteSize() or computeMinByteSize() result exceeds size_t |
678 | */ |
679 | static bool ByteSizeOverflowed(size_t byteSize) { |
680 | return SIZE_MAX == byteSize; |
681 | } |
682 | |
683 | /** Returns true if rowBytes is valid for this SkImageInfo. |
684 | |
685 | @param rowBytes size of pixel row including padding |
686 | @return true if rowBytes is large enough to contain pixel row and is properly |
687 | aligned |
688 | */ |
689 | bool validRowBytes(size_t rowBytes) const { |
690 | if (rowBytes < this->minRowBytes64()) { |
691 | return false; |
692 | } |
693 | int shift = this->shiftPerPixel(); |
694 | size_t alignedRowBytes = rowBytes >> shift << shift; |
695 | return alignedRowBytes == rowBytes; |
696 | } |
697 | |
698 | /** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType, |
699 | a width and height of zero, and no SkColorSpace. |
700 | */ |
701 | void reset() { *this = {}; } |
702 | |
703 | /** Asserts if internal values are illegal or inconsistent. Only available if |
704 | SK_DEBUG is defined at compile time. |
705 | */ |
706 | SkDEBUGCODE(void validate() const;) |
707 | |
708 | private: |
709 | SkColorInfo fColorInfo; |
710 | SkISize fDimensions = {0, 0}; |
711 | |
712 | SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo) |
713 | : fColorInfo(colorInfo), fDimensions(dimensions) {} |
714 | |
715 | SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo) |
716 | : fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {} |
717 | }; |
718 | |
719 | #endif |
720 | |