blob: 82d24753aa3cf7993835de57c16f9c256e4a510a [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"
commit-bot@chromium.org32678d92014-01-15 02:38:22 +000012#include "SkSize.h"
reed@google.com3443fd82013-11-13 19:09:13 +000013
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000014class SkWriteBuffer;
15class SkReadBuffer;
reed@google.com9230ea22013-12-09 22:01:03 +000016
reed@google.com3443fd82013-11-13 19:09:13 +000017/**
18 * Describes how to interpret the alpha compoent of a pixel.
19 */
20enum SkAlphaType {
21 /**
22 * All pixels should be treated as opaque, regardless of the value stored
23 * in their alpha field. Used for legacy images that wrote 0 or garbarge
24 * in their alpha field, but intended the RGB to be treated as opaque.
25 */
26 kIgnore_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000027
reed@google.com3443fd82013-11-13 19:09:13 +000028 /**
29 * All pixels are stored as opaque. This differs slightly from kIgnore in
30 * that kOpaque has correct "opaque" values stored in the pixels, while
31 * kIgnore may not, but in both cases the caller should treat the pixels
32 * as opaque.
33 */
34 kOpaque_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000035
reed@google.com3443fd82013-11-13 19:09:13 +000036 /**
37 * All pixels have their alpha premultiplied in their color components.
38 * This is the natural format for the rendering target pixels.
39 */
40 kPremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000041
reed@google.com3443fd82013-11-13 19:09:13 +000042 /**
43 * All pixels have their color components stored without any regard to the
44 * alpha. e.g. this is the default configuration for PNG images.
45 *
46 * This alpha-type is ONLY supported for input images. Rendering cannot
47 * generate this on output.
48 */
49 kUnpremul_SkAlphaType,
skia.committer@gmail.com73a5d532013-11-14 07:02:31 +000050
reed@google.com3443fd82013-11-13 19:09:13 +000051 kLastEnum_SkAlphaType = kUnpremul_SkAlphaType
52};
53
54static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
55 SK_COMPILE_ASSERT(kIgnore_SkAlphaType < kOpaque_SkAlphaType, bad_alphatype_order);
56 SK_COMPILE_ASSERT(kPremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
57 SK_COMPILE_ASSERT(kUnpremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
58
59 return (unsigned)at <= kOpaque_SkAlphaType;
60}
61
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000062static inline bool SkAlphaTypeIsValid(unsigned value) {
63 return value <= kLastEnum_SkAlphaType;
64}
65
reed@google.com3443fd82013-11-13 19:09:13 +000066///////////////////////////////////////////////////////////////////////////////
67
68/**
69 * Describes how to interpret the components of a pixel.
reed6c6ddb82014-06-30 12:44:03 -070070 *
71 * kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
72 * form for skia's blitters. Use this if you don't have a swizzle preference
73 * for 32bit pixels.
reed@google.com3443fd82013-11-13 19:09:13 +000074 */
75enum SkColorType {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +000076 kUnknown_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000077 kAlpha_8_SkColorType,
78 kRGB_565_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000079 kARGB_4444_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000080 kRGBA_8888_SkColorType,
81 kBGRA_8888_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000082 kIndex_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000083
reed@google.com9230ea22013-12-09 22:01:03 +000084 kLastEnum_SkColorType = kIndex_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000085
86#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000087 kN32_SkColorType = kBGRA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000088#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000089 kN32_SkColorType = kRGBA_8888_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000090#else
91#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
92#endif
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000093
94#ifdef SK_SUPPORT_LEGACY_N32_NAME
95 kPMColor_SkColorType = kN32_SkColorType
96#endif
reed@google.com3443fd82013-11-13 19:09:13 +000097};
98
99static int SkColorTypeBytesPerPixel(SkColorType ct) {
100 static const uint8_t gSize[] = {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000101 0, // Unknown
reed@google.com3443fd82013-11-13 19:09:13 +0000102 1, // Alpha_8
103 2, // RGB_565
reed@google.com9230ea22013-12-09 22:01:03 +0000104 2, // ARGB_4444
reed@google.com3443fd82013-11-13 19:09:13 +0000105 4, // RGBA_8888
106 4, // BGRA_8888
107 1, // kIndex_8
108 };
109 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1),
110 size_mismatch_with_SkColorType_enum);
111
112 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize));
113 return gSize[ct];
114}
115
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000116static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
117 return width * SkColorTypeBytesPerPixel(ct);
118}
119
120static inline bool SkColorTypeIsValid(unsigned value) {
121 return value <= kLastEnum_SkColorType;
122}
123
reed@google.com3443fd82013-11-13 19:09:13 +0000124///////////////////////////////////////////////////////////////////////////////
125
126/**
scroggo2fd0d142014-07-01 07:08:19 -0700127 * Return true if alphaType is supported by colorType. If there is a canonical
128 * alphaType for this colorType, return it in canonical.
129 */
130bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
131 SkAlphaType* canonical = NULL);
132
133///////////////////////////////////////////////////////////////////////////////
134
135/**
reed@google.com3443fd82013-11-13 19:09:13 +0000136 * Describe an image's dimensions and pixel type.
137 */
138struct SkImageInfo {
reede759a262014-08-28 11:57:33 -0700139public:
140 SkImageInfo() {}
141
reed@google.com3443fd82013-11-13 19:09:13 +0000142 int fWidth;
143 int fHeight;
144 SkColorType fColorType;
145 SkAlphaType fAlphaType;
146
reede759a262014-08-28 11:57:33 -0700147private:
148 enum Profile {
149 kUnknown_Profile,
150 kSRGB_Profile,
151 kExponential_Profile,
152 };
153
154 uint32_t fProfile;
155 float fGamma;
156
157 SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, Profile p, float g)
158 : fWidth(width)
159 , fHeight(height)
160 , fColorType(ct)
161 , fAlphaType(at)
162 , fProfile(p)
163 , fGamma(g)
164 {}
165
166public:
167 /*
168 * Return an info with the specified attributes, tagged as sRGB. Note that if the requested
169 * color type does not make sense with sRGB (e.g. kAlpha_8) then the sRGB request is ignored.
170 *
171 * You can call isSRGB() on the returned info to determine if the request was fulfilled.
172 */
173 static SkImageInfo MakeSRGB(int width, int height, SkColorType ct, SkAlphaType at);
174
175 /*
176 * Return an info with the specified attributes, tagged with a specific gamma.
177 * Note that if the requested gamma is unsupported for the requested color type, then the gamma
178 * value will be set to 1.0 (the default).
179 *
180 * You can call gamma() to query the resulting gamma value.
181 */
182 static SkImageInfo MakeWithGamma(int width, int height, SkColorType ct, SkAlphaType at,
183 float gamma);
184
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000185 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) {
reede759a262014-08-28 11:57:33 -0700186 return MakeWithGamma(width, height, ct, at, 1);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000187 }
188
189 /**
190 * Sets colortype to the native ARGB32 type.
191 */
192 static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
reede759a262014-08-28 11:57:33 -0700193 return SkImageInfo(width, height, kN32_SkColorType, at, kExponential_Profile, 1);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000194 }
195
196 /**
197 * Sets colortype to the native ARGB32 type, and the alphatype to premul.
198 */
199 static SkImageInfo MakeN32Premul(int width, int height) {
reede759a262014-08-28 11:57:33 -0700200 return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType,
201 kExponential_Profile, 1);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000202 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000203
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000204 /**
205 * Sets colortype to the native ARGB32 type, and the alphatype to premul.
206 */
207 static SkImageInfo MakeN32Premul(const SkISize& size) {
208 return MakeN32Premul(size.width(), size.height());
209 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000210
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000211 static SkImageInfo MakeA8(int width, int height) {
reede759a262014-08-28 11:57:33 -0700212 return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType,
213 kUnknown_Profile, 0);
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000214 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000215
reed@google.com900ecf22014-02-20 20:55:37 +0000216 static SkImageInfo MakeUnknown(int width, int height) {
reede759a262014-08-28 11:57:33 -0700217 return SkImageInfo(width, height, kUnknown_SkColorType, kIgnore_SkAlphaType,
218 kUnknown_Profile, 0);
reed@google.com900ecf22014-02-20 20:55:37 +0000219 }
220
reedf252f642014-06-14 04:24:56 -0700221 static SkImageInfo MakeUnknown() {
reede759a262014-08-28 11:57:33 -0700222 return SkImageInfo(0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType, kUnknown_Profile, 0);
reedf252f642014-06-14 04:24:56 -0700223 }
224
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000225 int width() const { return fWidth; }
226 int height() const { return fHeight; }
227 SkColorType colorType() const { return fColorType; }
228 SkAlphaType alphaType() const { return fAlphaType; }
229
230 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
231
reed@google.com3443fd82013-11-13 19:09:13 +0000232 bool isOpaque() const {
233 return SkAlphaTypeIsOpaque(fAlphaType);
234 }
235
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000236 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
237
reedc77392e2014-06-02 13:07:26 -0700238 /**
239 * Return a new ImageInfo with the same colortype and alphatype as this info,
240 * but with the specified width and height.
241 */
242 SkImageInfo makeWH(int newWidth, int newHeight) const {
243 return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType);
244 }
245
reed@google.com3443fd82013-11-13 19:09:13 +0000246 int bytesPerPixel() const {
247 return SkColorTypeBytesPerPixel(fColorType);
248 }
249
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000250 uint64_t minRowBytes64() const {
251 return sk_64_mul(fWidth, this->bytesPerPixel());
252 }
253
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000254 size_t minRowBytes() const {
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000255 return (size_t)this->minRowBytes64();
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000256 }
skia.committer@gmail.com8ed64432014-02-11 03:02:13 +0000257
reed@google.com3443fd82013-11-13 19:09:13 +0000258 bool operator==(const SkImageInfo& other) const {
259 return 0 == memcmp(this, &other, sizeof(other));
260 }
261 bool operator!=(const SkImageInfo& other) const {
262 return 0 != memcmp(this, &other, sizeof(other));
263 }
reed@google.com9230ea22013-12-09 22:01:03 +0000264
reede759a262014-08-28 11:57:33 -0700265 // DEPRECATED : use the static Unflatten
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000266 void unflatten(SkReadBuffer&);
267 void flatten(SkWriteBuffer&) const;
reede759a262014-08-28 11:57:33 -0700268
269 static SkImageInfo Unflatten(SkReadBuffer&);
reed@google.com9230ea22013-12-09 22:01:03 +0000270
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000271 int64_t getSafeSize64(size_t rowBytes) const {
reed@google.com9230ea22013-12-09 22:01:03 +0000272 if (0 == fHeight) {
273 return 0;
274 }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000275 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
reed@google.com9230ea22013-12-09 22:01:03 +0000276 }
commit-bot@chromium.org61e96cd2014-02-11 18:21:45 +0000277
278 size_t getSafeSize(size_t rowBytes) const {
279 return (size_t)this->getSafeSize64(rowBytes);
280 }
281
282 bool validRowBytes(size_t rowBytes) const {
283 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
284 return rowBytes >= rb;
285 }
286
287 SkDEBUGCODE(void validate() const;)
reede759a262014-08-28 11:57:33 -0700288
289 /**
290 * If the Info was tagged to be sRGB, return true, else return false.
291 */
292 bool isSRGB() const { return kSRGB_Profile == fProfile; }
293
294 /**
295 * If this was tagged with an explicit gamma value, return that value, else return 0.
296 * If this was tagged as sRGB, return 0.
297 */
298 float gamma() const { return fGamma; }
reed@google.com3443fd82013-11-13 19:09:13 +0000299};
300
301#endif