blob: 0218a7431094048107d9817270124ce7a16fb83b [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
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000011#include "SkMath.h"
halcanaryf622a6c2014-10-24 12:54:53 -070012#include "SkRect.h"
commit-bot@chromium.org32678d92014-01-15 02:38:22 +000013#include "SkSize.h"
reed@google.com3443fd82013-11-13 19:09:13 +000014
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000015class SkReadBuffer;
halcanaryf622a6c2014-10-24 12:54:53 -070016class SkWriteBuffer;
reed@google.com9230ea22013-12-09 22:01:03 +000017
reed@google.com3443fd82013-11-13 19:09:13 +000018/**
reed8f343722015-08-13 13:32:39 -070019 * This enum provides information about "how" an image will be used. For older GPUs that do not
20 * support non-power-of-2 tiling, some routines need to know this information before they create
21 * a texture.
22 */
23enum SkImageUsageType {
24 /* Image will not be tiled (regardless of filtering) */
25 kUntiled_SkImageUsageType,
26
27 /* Image will be tiled, but not filtered */
28 kTiled_Unfiltered_SkImageUsageType,
29
30 /* Image will be tiled and filtered */
31 kTiled_Filtered_SkImageUsageType,
32};
33
34/**
reed@google.com3443fd82013-11-13 19:09:13 +000035 * Describes how to interpret the alpha compoent of a pixel.
36 */
37enum SkAlphaType {
reed44977482015-02-27 10:23:00 -080038 kUnknown_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000039
reed@google.com3443fd82013-11-13 19:09:13 +000040 /**
41 * All pixels are stored as opaque. This differs slightly from kIgnore in
42 * that kOpaque has correct "opaque" values stored in the pixels, while
43 * kIgnore may not, but in both cases the caller should treat the pixels
44 * as opaque.
45 */
46 kOpaque_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000047
reed@google.com3443fd82013-11-13 19:09:13 +000048 /**
49 * All pixels have their alpha premultiplied in their color components.
50 * This is the natural format for the rendering target pixels.
51 */
52 kPremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000053
reed@google.com3443fd82013-11-13 19:09:13 +000054 /**
55 * All pixels have their color components stored without any regard to the
56 * alpha. e.g. this is the default configuration for PNG images.
57 *
58 * This alpha-type is ONLY supported for input images. Rendering cannot
59 * generate this on output.
60 */
61 kUnpremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000062
reed@google.com3443fd82013-11-13 19:09:13 +000063 kLastEnum_SkAlphaType = kUnpremul_SkAlphaType
64};
65
66static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
reed44977482015-02-27 10:23:00 -080067 return kOpaque_SkAlphaType == at;
reed@google.com3443fd82013-11-13 19:09:13 +000068}
69
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000070static inline bool SkAlphaTypeIsValid(unsigned value) {
71 return value <= kLastEnum_SkAlphaType;
72}
73
reed@google.com3443fd82013-11-13 19:09:13 +000074///////////////////////////////////////////////////////////////////////////////
75
76/**
77 * Describes how to interpret the components of a pixel.
reed6c6ddb82014-06-30 12:44:03 -070078 *
79 * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
80 * form for skia's blitters. Use this if you don't have a swizzle preference
81 * for 32bit pixels.
reed@google.com3443fd82013-11-13 19:09:13 +000082 */
83enum SkColorType {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000084 kUnknown_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000085 kAlpha_8_SkColorType,
86 kRGB_565_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000087 kARGB_4444_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000088 kRGBA_8888_SkColorType,
89 kBGRA_8888_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000090 kIndex_8_SkColorType,
reed0c9b1a82015-03-17 17:44:06 -070091 kGray_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000092
reed0c9b1a82015-03-17 17:44:06 -070093 kLastEnum_SkColorType = kGray_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000094
95#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000096 kN32_SkColorType = kBGRA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000097#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000098 kN32_SkColorType = kRGBA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000099#else
reed3b40ee62014-12-21 14:29:04 -0800100 #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +0000101#endif
reed@google.com3443fd82013-11-13 19:09:13 +0000102};
103
104static int SkColorTypeBytesPerPixel(SkColorType ct) {
105 static const uint8_t gSize[] = {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000106 0, // Unknown
reed@google.com3443fd82013-11-13 19:09:13 +0000107 1, // Alpha_8
108 2, // RGB_565
reed@google.com9230ea22013-12-09 22:01:03 +0000109 2, // ARGB_4444
reed@google.com3443fd82013-11-13 19:09:13 +0000110 4, // RGBA_8888
111 4, // BGRA_8888
112 1, // kIndex_8
reed0c9b1a82015-03-17 17:44:06 -0700113 1, // kGray_8
reed@google.com3443fd82013-11-13 19:09:13 +0000114 };
bungeman99fe8222015-08-20 07:57:51 -0700115 static_assert(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1),
116 "size_mismatch_with_SkColorType_enum");
reed@google.com3443fd82013-11-13 19:09:13 +0000117
118 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize));
119 return gSize[ct];
120}
121
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000122static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
123 return width * SkColorTypeBytesPerPixel(ct);
124}
125
126static inline bool SkColorTypeIsValid(unsigned value) {
127 return value <= kLastEnum_SkColorType;
128}
129
reed92fc2ae2015-05-22 08:06:21 -0700130static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) {
131 int shift = 0;
132 switch (SkColorTypeBytesPerPixel(ct)) {
133 case 4: shift = 2; break;
134 case 2: shift = 1; break;
135 case 1: shift = 0; break;
136 default: return 0;
137 }
138 return y * rowBytes + (x << shift);
139}
140
reed@google.com3443fd82013-11-13 19:09:13 +0000141///////////////////////////////////////////////////////////////////////////////
142
143/**
scroggo2fd0d142014-07-01 07:08:19 -0700144 * Return true if alphaType is supported by colorType. If there is a canonical
145 * alphaType for this colorType, return it in canonical.
146 */
147bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
148 SkAlphaType* canonical = NULL);
149
150///////////////////////////////////////////////////////////////////////////////
151
152/**
rileyaabaef862014-09-12 17:45:58 -0700153 * Describes the color space a YUV pixel.
154 */
155enum SkYUVColorSpace {
156 /** Standard JPEG color space. */
157 kJPEG_SkYUVColorSpace,
158 /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color
159 range. See http://en.wikipedia.org/wiki/Rec._601 for details. */
160 kRec601_SkYUVColorSpace,
rileya13400392015-07-20 15:00:03 -0700161 /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color
162 range. See http://en.wikipedia.org/wiki/Rec._709 for details. */
163 kRec709_SkYUVColorSpace,
rileyaabaef862014-09-12 17:45:58 -0700164
rileya13400392015-07-20 15:00:03 -0700165 kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace
rileyaabaef862014-09-12 17:45:58 -0700166};
167
168///////////////////////////////////////////////////////////////////////////////
169
reed7c748852014-11-10 08:57:21 -0800170enum SkColorProfileType {
171 kLinear_SkColorProfileType,
172 kSRGB_SkColorProfileType,
173
174 kLastEnum_SkColorProfileType = kSRGB_SkColorProfileType
175};
176
rileyaabaef862014-09-12 17:45:58 -0700177/**
reed@google.com3443fd82013-11-13 19:09:13 +0000178 * Describe an image's dimensions and pixel type.
reed7c748852014-11-10 08:57:21 -0800179 * Used for both src images and render-targets (surfaces).
reed@google.com3443fd82013-11-13 19:09:13 +0000180 */
reed41814922015-01-30 14:54:38 -0800181struct SK_API SkImageInfo {
reede5ea5002014-09-03 11:54:58 -0700182public:
183 SkImageInfo()
184 : fWidth(0)
185 , fHeight(0)
186 , fColorType(kUnknown_SkColorType)
reed44977482015-02-27 10:23:00 -0800187 , fAlphaType(kUnknown_SkAlphaType)
reed7c748852014-11-10 08:57:21 -0800188 , fProfileType(kLinear_SkColorProfileType)
reede5ea5002014-09-03 11:54:58 -0700189 {}
reed@google.com3443fd82013-11-13 19:09:13 +0000190
reed7c748852014-11-10 08:57:21 -0800191 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
192 SkColorProfileType pt = kLinear_SkColorProfileType) {
193 return SkImageInfo(width, height, ct, at, pt);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000194 }
195
196 /**
197 * Sets colortype to the native ARGB32 type.
198 */
reed7c748852014-11-10 08:57:21 -0800199 static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
200 SkColorProfileType pt = kLinear_SkColorProfileType) {
201 return SkImageInfo(width, height, kN32_SkColorType, at, pt);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000202 }
203
204 /**
205 * Sets colortype to the native ARGB32 type, and the alphatype to premul.
206 */
reed7c748852014-11-10 08:57:21 -0800207 static SkImageInfo MakeN32Premul(int width, int height,
208 SkColorProfileType pt = kLinear_SkColorProfileType) {
209 return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType, pt);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000210 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000211
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000212 /**
213 * Sets colortype to the native ARGB32 type, and the alphatype to premul.
214 */
reed7c748852014-11-10 08:57:21 -0800215 static SkImageInfo MakeN32Premul(const SkISize& size,
216 SkColorProfileType pt = kLinear_SkColorProfileType) {
217 return MakeN32Premul(size.width(), size.height(), pt);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000218 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000219
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000220 static SkImageInfo MakeA8(int width, int height) {
reed7c748852014-11-10 08:57:21 -0800221 return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType,
222 kLinear_SkColorProfileType);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000223 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000224
reed@google.com900ecf22014-02-20 20:55:37 +0000225 static SkImageInfo MakeUnknown(int width, int height) {
reed44977482015-02-27 10:23:00 -0800226 return SkImageInfo(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType,
reed7c748852014-11-10 08:57:21 -0800227 kLinear_SkColorProfileType);
reed@google.com900ecf22014-02-20 20:55:37 +0000228 }
229
reedf252f642014-06-14 04:24:56 -0700230 static SkImageInfo MakeUnknown() {
reede5ea5002014-09-03 11:54:58 -0700231 return SkImageInfo();
reedf252f642014-06-14 04:24:56 -0700232 }
233
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000234 int width() const { return fWidth; }
235 int height() const { return fHeight; }
236 SkColorType colorType() const { return fColorType; }
237 SkAlphaType alphaType() const { return fAlphaType; }
reed7c748852014-11-10 08:57:21 -0800238 SkColorProfileType profileType() const { return fProfileType; }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000239
240 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
241
reed@google.com3443fd82013-11-13 19:09:13 +0000242 bool isOpaque() const {
243 return SkAlphaTypeIsOpaque(fAlphaType);
244 }
245
reed7c748852014-11-10 08:57:21 -0800246 bool isLinear() const { return kLinear_SkColorProfileType == fProfileType; }
247 bool isSRGB() const { return kSRGB_SkColorProfileType == fProfileType; }
248
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000249 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
reed7c748852014-11-10 08:57:21 -0800250 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000251
reedc77392e2014-06-02 13:07:26 -0700252 /**
253 * Return a new ImageInfo with the same colortype and alphatype as this info,
254 * but with the specified width and height.
255 */
256 SkImageInfo makeWH(int newWidth, int newHeight) const {
reed7c748852014-11-10 08:57:21 -0800257 return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType, fProfileType);
reedc77392e2014-06-02 13:07:26 -0700258 }
259
reede5ea5002014-09-03 11:54:58 -0700260 SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
reed7c748852014-11-10 08:57:21 -0800261 return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType, fProfileType);
reede5ea5002014-09-03 11:54:58 -0700262 }
263
264 SkImageInfo makeColorType(SkColorType newColorType) const {
reed7c748852014-11-10 08:57:21 -0800265 return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType, fProfileType);
reede5ea5002014-09-03 11:54:58 -0700266 }
reed7c748852014-11-10 08:57:21 -0800267
reed@google.com3443fd82013-11-13 19:09:13 +0000268 int bytesPerPixel() const {
269 return SkColorTypeBytesPerPixel(fColorType);
270 }
271
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000272 uint64_t minRowBytes64() const {
273 return sk_64_mul(fWidth, this->bytesPerPixel());
274 }
275
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000276 size_t minRowBytes() const {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000277 return (size_t)this->minRowBytes64();
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000278 }
skia.committer@gmail.com8ed64432014-02-11 03:02:13 +0000279
reed92fc2ae2015-05-22 08:06:21 -0700280 size_t computeOffset(int x, int y, size_t rowBytes) const {
281 SkASSERT((unsigned)x < (unsigned)fWidth);
282 SkASSERT((unsigned)y < (unsigned)fHeight);
283 return SkColorTypeComputeOffset(fColorType, x, y, rowBytes);
284 }
285
reed@google.com3443fd82013-11-13 19:09:13 +0000286 bool operator==(const SkImageInfo& other) const {
287 return 0 == memcmp(this, &other, sizeof(other));
288 }
289 bool operator!=(const SkImageInfo& other) const {
290 return 0 != memcmp(this, &other, sizeof(other));
291 }
reed@google.com9230ea22013-12-09 22:01:03 +0000292
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000293 void unflatten(SkReadBuffer&);
294 void flatten(SkWriteBuffer&) const;
reed@google.com9230ea22013-12-09 22:01:03 +0000295
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000296 int64_t getSafeSize64(size_t rowBytes) const {
reed@google.com9230ea22013-12-09 22:01:03 +0000297 if (0 == fHeight) {
298 return 0;
299 }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000300 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
reed@google.com9230ea22013-12-09 22:01:03 +0000301 }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000302
303 size_t getSafeSize(size_t rowBytes) const {
reedde499882015-06-18 13:41:40 -0700304 int64_t size = this->getSafeSize64(rowBytes);
305 if (!sk_64_isS32(size)) {
306 return 0;
307 }
308 return sk_64_asS32(size);
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000309 }
310
311 bool validRowBytes(size_t rowBytes) const {
312 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
313 return rowBytes >= rb;
314 }
315
316 SkDEBUGCODE(void validate() const;)
reede5ea5002014-09-03 11:54:58 -0700317
reede5ea5002014-09-03 11:54:58 -0700318private:
reed7c748852014-11-10 08:57:21 -0800319 int fWidth;
320 int fHeight;
321 SkColorType fColorType;
322 SkAlphaType fAlphaType;
reedc2e68272015-08-01 07:03:20 -0700323 SkColorProfileType fProfileType;
reede5ea5002014-09-03 11:54:58 -0700324
reed7c748852014-11-10 08:57:21 -0800325 SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, SkColorProfileType pt)
reede5ea5002014-09-03 11:54:58 -0700326 : fWidth(width)
327 , fHeight(height)
328 , fColorType(ct)
329 , fAlphaType(at)
reed7c748852014-11-10 08:57:21 -0800330 , fProfileType(pt)
reede5ea5002014-09-03 11:54:58 -0700331 {}
reed@google.com3443fd82013-11-13 19:09:13 +0000332};
333
334#endif