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