blob: c21c3df8c990fba06fdae6459a5629e9dd31462d [file] [log] [blame]
reed@google.com3443fd82013-11-13 19:09:13 +00001/*
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
msarett23c51102016-05-27 07:39:02 -070011#include "SkColorSpace.h"
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000012#include "SkMath.h"
halcanaryf622a6c2014-10-24 12:54:53 -070013#include "SkRect.h"
commit-bot@chromium.org32678d92014-01-15 02:38:22 +000014#include "SkSize.h"
reed@google.com3443fd82013-11-13 19:09:13 +000015
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000016class SkReadBuffer;
halcanaryf622a6c2014-10-24 12:54:53 -070017class SkWriteBuffer;
reed@google.com9230ea22013-12-09 22:01:03 +000018
reed@google.com3443fd82013-11-13 19:09:13 +000019/**
bsalomonafa95e22015-10-12 10:39:46 -070020 * Describes how to interpret the alpha component of a pixel.
reed@google.com3443fd82013-11-13 19:09:13 +000021 */
22enum SkAlphaType {
reed44977482015-02-27 10:23:00 -080023 kUnknown_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000024
reed@google.com3443fd82013-11-13 19:09:13 +000025 /**
26 * All pixels are stored as opaque. This differs slightly from kIgnore in
27 * that kOpaque has correct "opaque" values stored in the pixels, while
28 * kIgnore may not, but in both cases the caller should treat the pixels
29 * as opaque.
30 */
31 kOpaque_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000032
reed@google.com3443fd82013-11-13 19:09:13 +000033 /**
34 * All pixels have their alpha premultiplied in their color components.
35 * This is the natural format for the rendering target pixels.
36 */
37 kPremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000038
reed@google.com3443fd82013-11-13 19:09:13 +000039 /**
40 * All pixels have their color components stored without any regard to the
41 * alpha. e.g. this is the default configuration for PNG images.
42 *
Joe Gregorioc4859072017-01-20 14:21:27 +000043 * This alpha-type is ONLY supported for input images. Rendering cannot
44 * generate this on output.
reed@google.com3443fd82013-11-13 19:09:13 +000045 */
46 kUnpremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000047
Cary Clark745c3982018-01-24 15:37:13 -050048 kLastEnum_SkAlphaType = kUnpremul_SkAlphaType,
reed@google.com3443fd82013-11-13 19:09:13 +000049};
50
51static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
reed44977482015-02-27 10:23:00 -080052 return kOpaque_SkAlphaType == at;
reed@google.com3443fd82013-11-13 19:09:13 +000053}
54
55///////////////////////////////////////////////////////////////////////////////
56
Brian Salomone41e1762018-01-25 14:07:47 -050057/** Temporary macro that allows us to add new color types without breaking Chrome compile. */
58#define SK_EXTENDED_COLOR_TYPES
59
reed@google.com3443fd82013-11-13 19:09:13 +000060/**
61 * Describes how to interpret the components of a pixel.
reed6c6ddb82014-06-30 12:44:03 -070062 *
63 * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
64 * form for skia's blitters. Use this if you don't have a swizzle preference
65 * for 32bit pixels.
reed@google.com3443fd82013-11-13 19:09:13 +000066 */
67enum SkColorType {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000068 kUnknown_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000069 kAlpha_8_SkColorType,
70 kRGB_565_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000071 kARGB_4444_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000072 kRGBA_8888_SkColorType,
Brian Salomone41e1762018-01-25 14:07:47 -050073 kRGB_888x_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000074 kBGRA_8888_SkColorType,
Brian Salomone41e1762018-01-25 14:07:47 -050075 kRGBA_1010102_SkColorType,
76 kRGB_101010x_SkColorType,
reed0c9b1a82015-03-17 17:44:06 -070077 kGray_8_SkColorType,
reed3601f282016-02-05 11:18:39 -080078 kRGBA_F16_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000079
reed3601f282016-02-05 11:18:39 -080080 kLastEnum_SkColorType = kRGBA_F16_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000081
82#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000083 kN32_SkColorType = kBGRA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000084#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000085 kN32_SkColorType = kRGBA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000086#else
Cary Clark745c3982018-01-24 15:37:13 -050087 #error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order"
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000088#endif
reed@google.com3443fd82013-11-13 19:09:13 +000089};
90
Mike Reed7fcfb622018-02-09 13:26:46 -050091/**
92 * Returns the number of bytes-per-pixel for the specified colortype, or 0 if invalid.
93 */
94SK_API int SkColorTypeBytesPerPixel(SkColorType ct);
reed@google.com3443fd82013-11-13 19:09:13 +000095
96/**
Mike Reed7fcfb622018-02-09 13:26:46 -050097 * Tries to validate the colortype, alphatype pair. In all cases if it returns true, it
98 * will set canonical to the "canonical" answer if it is non-null, and ignore the parameter if
99 * it is set to null.
100 *
101 * If the specified colortype has only 1 valid alphatype (e.g. 565 must always be opaque) then
102 * canonical will be set to that valid alphatype.
103 *
104 * If the specified colortype treats more than one alphatype the same (e.g. Alpha_8 colortype
105 * treates Premul and Unpremul the same) and the specified alphatype is one of those,
106 * then canonical will be set to the "canonical" answer (Premul in the case of Alpha_8 colortype).
107 *
108 * If the colortype supports multiple alphatypes, and the specified alphatype is one of them,
109 * then canonical will be set to the specified alphatype. If the specified alphatype is not
110 * one of them (e.g. kUnknown_SkAlphaType is not valid for any colortype except
111 * kUnknown_SkColorType), then the function returns false, and canonical's value is undefined.
scroggo2fd0d142014-07-01 07:08:19 -0700112 */
113bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
Ben Wagnera93a14a2017-08-28 10:34:05 -0400114 SkAlphaType* canonical = nullptr);
scroggo2fd0d142014-07-01 07:08:19 -0700115
Mike Reed7fcfb622018-02-09 13:26:46 -0500116
scroggo2fd0d142014-07-01 07:08:19 -0700117///////////////////////////////////////////////////////////////////////////////
118
119/**
rileyaabaef862014-09-12 17:45:58 -0700120 * Describes the color space a YUV pixel.
121 */
122enum SkYUVColorSpace {
123 /** Standard JPEG color space. */
124 kJPEG_SkYUVColorSpace,
125 /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color
126 range. See http://en.wikipedia.org/wiki/Rec._601 for details. */
127 kRec601_SkYUVColorSpace,
rileya13400392015-07-20 15:00:03 -0700128 /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color
129 range. See http://en.wikipedia.org/wiki/Rec._709 for details. */
130 kRec709_SkYUVColorSpace,
rileyaabaef862014-09-12 17:45:58 -0700131
Cary Clark745c3982018-01-24 15:37:13 -0500132 kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace,
rileyaabaef862014-09-12 17:45:58 -0700133};
134
135///////////////////////////////////////////////////////////////////////////////
136
Brian Osman7b8400d2016-11-08 17:08:54 -0500137enum class SkDestinationSurfaceColorMode {
138 kLegacy,
139 kGammaAndColorSpaceAware,
brianosman982eb7f2016-06-06 13:10:58 -0700140};
141
rileyaabaef862014-09-12 17:45:58 -0700142/**
reed@google.com3443fd82013-11-13 19:09:13 +0000143 * Describe an image's dimensions and pixel type.
reed7c748852014-11-10 08:57:21 -0800144 * Used for both src images and render-targets (surfaces).
reed@google.com3443fd82013-11-13 19:09:13 +0000145 */
reed41814922015-01-30 14:54:38 -0800146struct SK_API SkImageInfo {
reede5ea5002014-09-03 11:54:58 -0700147public:
148 SkImageInfo()
msarett23c51102016-05-27 07:39:02 -0700149 : fColorSpace(nullptr)
150 , fWidth(0)
reede5ea5002014-09-03 11:54:58 -0700151 , fHeight(0)
152 , fColorType(kUnknown_SkColorType)
reed44977482015-02-27 10:23:00 -0800153 , fAlphaType(kUnknown_SkAlphaType)
reede5ea5002014-09-03 11:54:58 -0700154 {}
reed@google.com3443fd82013-11-13 19:09:13 +0000155
reed7c748852014-11-10 08:57:21 -0800156 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
reed960b2d62016-06-17 09:26:41 -0700157 sk_sp<SkColorSpace> cs = nullptr) {
158 return SkImageInfo(width, height, ct, at, std::move(cs));
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000159 }
160
161 /**
162 * Sets colortype to the native ARGB32 type.
163 */
reed7c748852014-11-10 08:57:21 -0800164 static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
reed960b2d62016-06-17 09:26:41 -0700165 sk_sp<SkColorSpace> cs = nullptr) {
166 return Make(width, height, kN32_SkColorType, at, cs);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000167 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000168
reedfbce71f2016-06-02 12:40:22 -0700169 /**
170 * Create an ImageInfo marked as SRGB with N32 swizzle.
171 */
172 static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
173
reed960b2d62016-06-17 09:26:41 -0700174 /**
175 * Sets colortype to the native ARGB32 type, and the alphatype to premul.
176 */
reeddabe5d32016-06-21 10:28:14 -0700177 static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
178 return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, cs);
reed960b2d62016-06-17 09:26:41 -0700179 }
180
181 static SkImageInfo MakeN32Premul(const SkISize& size) {
182 return MakeN32Premul(size.width(), size.height());
183 }
184
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000185 static SkImageInfo MakeA8(int width, int height) {
reed960b2d62016-06-17 09:26:41 -0700186 return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000187 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000188
reed@google.com900ecf22014-02-20 20:55:37 +0000189 static SkImageInfo MakeUnknown(int width, int height) {
reed960b2d62016-06-17 09:26:41 -0700190 return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
reed@google.com900ecf22014-02-20 20:55:37 +0000191 }
192
reedf252f642014-06-14 04:24:56 -0700193 static SkImageInfo MakeUnknown() {
reed960b2d62016-06-17 09:26:41 -0700194 return MakeUnknown(0, 0);
reedf252f642014-06-14 04:24:56 -0700195 }
Ben Wagner63fd7602017-10-09 15:45:33 -0400196
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000197 int width() const { return fWidth; }
198 int height() const { return fHeight; }
199 SkColorType colorType() const { return fColorType; }
200 SkAlphaType alphaType() const { return fAlphaType; }
msarett23c51102016-05-27 07:39:02 -0700201 SkColorSpace* colorSpace() const { return fColorSpace.get(); }
Mike Reed693fdbd2017-01-12 10:13:40 -0500202 sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
msarett23c51102016-05-27 07:39:02 -0700203
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000204 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
205
reed@google.com3443fd82013-11-13 19:09:13 +0000206 bool isOpaque() const {
207 return SkAlphaTypeIsOpaque(fAlphaType);
208 }
209
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000210 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
reed7c748852014-11-10 08:57:21 -0800211 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000212
reed960b2d62016-06-17 09:26:41 -0700213 bool gammaCloseToSRGB() const {
214 return fColorSpace && fColorSpace->gammaCloseToSRGB();
215 }
216
reedc77392e2014-06-02 13:07:26 -0700217 /**
218 * Return a new ImageInfo with the same colortype and alphatype as this info,
219 * but with the specified width and height.
220 */
221 SkImageInfo makeWH(int newWidth, int newHeight) const {
reed960b2d62016-06-17 09:26:41 -0700222 return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace);
reedc77392e2014-06-02 13:07:26 -0700223 }
224
reede5ea5002014-09-03 11:54:58 -0700225 SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
reed960b2d62016-06-17 09:26:41 -0700226 return Make(fWidth, fHeight, fColorType, newAlphaType, fColorSpace);
reede5ea5002014-09-03 11:54:58 -0700227 }
Ben Wagner63fd7602017-10-09 15:45:33 -0400228
reede5ea5002014-09-03 11:54:58 -0700229 SkImageInfo makeColorType(SkColorType newColorType) const {
reed960b2d62016-06-17 09:26:41 -0700230 return Make(fWidth, fHeight, newColorType, fAlphaType, fColorSpace);
reede5ea5002014-09-03 11:54:58 -0700231 }
reed7c748852014-11-10 08:57:21 -0800232
msarett804b4612016-06-09 11:03:45 -0700233 SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
reed960b2d62016-06-17 09:26:41 -0700234 return Make(fWidth, fHeight, fColorType, fAlphaType, std::move(cs));
msarett804b4612016-06-09 11:03:45 -0700235 }
236
Mike Reed7fcfb622018-02-09 13:26:46 -0500237 int bytesPerPixel() const;
238 int shiftPerPixel() const;
reed@google.com3443fd82013-11-13 19:09:13 +0000239
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000240 uint64_t minRowBytes64() const {
241 return sk_64_mul(fWidth, this->bytesPerPixel());
242 }
243
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000244 size_t minRowBytes() const {
Matt Sarett29121eb2016-10-17 14:32:46 -0400245 uint64_t minRowBytes = this->minRowBytes64();
246 if (!sk_64_isS32(minRowBytes)) {
247 return 0;
248 }
249 return sk_64_asS32(minRowBytes);
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000250 }
skia.committer@gmail.com8ed64432014-02-11 03:02:13 +0000251
Mike Reed7fcfb622018-02-09 13:26:46 -0500252 size_t computeOffset(int x, int y, size_t rowBytes) const;
reed92fc2ae2015-05-22 08:06:21 -0700253
reed@google.com3443fd82013-11-13 19:09:13 +0000254 bool operator==(const SkImageInfo& other) const {
msarett23c51102016-05-27 07:39:02 -0700255 return fWidth == other.fWidth && fHeight == other.fHeight &&
256 fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
msarettabbd6d52016-08-01 09:43:08 -0700257 SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
reed@google.com3443fd82013-11-13 19:09:13 +0000258 }
259 bool operator!=(const SkImageInfo& other) const {
msarettabbd6d52016-08-01 09:43:08 -0700260 return !(*this == other);
reed@google.com3443fd82013-11-13 19:09:13 +0000261 }
reed@google.com9230ea22013-12-09 22:01:03 +0000262
Cary Clark745c3982018-01-24 15:37:13 -0500263 void unflatten(SkReadBuffer& buffer);
264 void flatten(SkWriteBuffer& buffer) const;
reed@google.com9230ea22013-12-09 22:01:03 +0000265
Mike Reede74dafc2017-09-29 13:41:58 -0400266 /**
267 * Returns the size (in bytes) of the image buffer that this info needs, given the specified
268 * rowBytes. The rowBytes must be >= this->minRowBytes().
Mike Reed3758c752017-10-11 11:30:31 -0400269 *
270 * if (height == 0) {
271 * return 0;
272 * } else {
273 * return (height - 1) * rowBytes + width * bytes_per_pixel;
274 * }
275 *
Mike Reed72818012017-10-09 11:37:44 -0400276 * If the calculation overflows this returns SK_MaxSizeT
277 */
Mike Reede74dafc2017-09-29 13:41:58 -0400278 size_t computeByteSize(size_t rowBytes) const;
279
280 /**
281 * Returns the minimum size (in bytes) of the image buffer that this info needs.
282 * If the calculation overflows, or if the height is 0, this returns 0.
283 */
284 size_t computeMinByteSize() const {
285 return this->computeByteSize(this->minRowBytes());
286 }
287
Mike Reedc5eb97d2017-10-09 10:42:51 -0400288 // Returns true if the result of computeByteSize (or computeMinByteSize) overflowed
289 static bool ByteSizeOverflowed(size_t byteSize) {
Mike Reed72818012017-10-09 11:37:44 -0400290 return SK_MaxSizeT == byteSize;
Mike Reedc5eb97d2017-10-09 10:42:51 -0400291 }
292
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000293 bool validRowBytes(size_t rowBytes) const {
Mike Reedf0ffb892017-10-03 14:47:21 -0400294 uint64_t minRB = sk_64_mul(fWidth, this->bytesPerPixel());
295 return rowBytes >= minRB;
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000296 }
297
msarett23c51102016-05-27 07:39:02 -0700298 void reset() {
reed960b2d62016-06-17 09:26:41 -0700299 fColorSpace = nullptr;
msarett23c51102016-05-27 07:39:02 -0700300 fWidth = 0;
301 fHeight = 0;
302 fColorType = kUnknown_SkColorType;
303 fAlphaType = kUnknown_SkAlphaType;
msarett23c51102016-05-27 07:39:02 -0700304 }
305
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000306 SkDEBUGCODE(void validate() const;)
reede5ea5002014-09-03 11:54:58 -0700307
reede5ea5002014-09-03 11:54:58 -0700308private:
msarett23c51102016-05-27 07:39:02 -0700309 sk_sp<SkColorSpace> fColorSpace;
reed7c748852014-11-10 08:57:21 -0800310 int fWidth;
311 int fHeight;
312 SkColorType fColorType;
313 SkAlphaType fAlphaType;
reede5ea5002014-09-03 11:54:58 -0700314
reed960b2d62016-06-17 09:26:41 -0700315 SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
msarett23c51102016-05-27 07:39:02 -0700316 : fColorSpace(std::move(cs))
317 , fWidth(width)
reede5ea5002014-09-03 11:54:58 -0700318 , fHeight(height)
319 , fColorType(ct)
320 , fAlphaType(at)
321 {}
reed@google.com3443fd82013-11-13 19:09:13 +0000322};
323
reed@google.com3443fd82013-11-13 19:09:13 +0000324#endif