|
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 "SkMath.h" |
|
12 #include "SkSize.h" |
|
13 |
|
14 class SkWriteBuffer; |
|
15 class SkReadBuffer; |
|
16 |
|
17 /** |
|
18 * Describes how to interpret the alpha compoent of a pixel. |
|
19 */ |
|
20 enum 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, |
|
27 |
|
28 /** |
|
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, |
|
35 |
|
36 /** |
|
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, |
|
41 |
|
42 /** |
|
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, |
|
50 |
|
51 kLastEnum_SkAlphaType = kUnpremul_SkAlphaType |
|
52 }; |
|
53 |
|
54 static 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 |
|
62 static inline bool SkAlphaTypeIsValid(unsigned value) { |
|
63 return value <= kLastEnum_SkAlphaType; |
|
64 } |
|
65 |
|
66 /////////////////////////////////////////////////////////////////////////////// |
|
67 |
|
68 /** |
|
69 * Describes how to interpret the components of a pixel. |
|
70 */ |
|
71 enum SkColorType { |
|
72 kUnknown_SkColorType, |
|
73 kAlpha_8_SkColorType, |
|
74 kRGB_565_SkColorType, |
|
75 kARGB_4444_SkColorType, |
|
76 kRGBA_8888_SkColorType, |
|
77 kBGRA_8888_SkColorType, |
|
78 kIndex_8_SkColorType, |
|
79 |
|
80 kLastEnum_SkColorType = kIndex_8_SkColorType, |
|
81 |
|
82 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) |
|
83 kPMColor_SkColorType = kBGRA_8888_SkColorType |
|
84 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) |
|
85 kPMColor_SkColorType = kRGBA_8888_SkColorType |
|
86 #else |
|
87 #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" |
|
88 #endif |
|
89 }; |
|
90 |
|
91 static int SkColorTypeBytesPerPixel(SkColorType ct) { |
|
92 static const uint8_t gSize[] = { |
|
93 0, // Unknown |
|
94 1, // Alpha_8 |
|
95 2, // RGB_565 |
|
96 2, // ARGB_4444 |
|
97 4, // RGBA_8888 |
|
98 4, // BGRA_8888 |
|
99 1, // kIndex_8 |
|
100 }; |
|
101 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), |
|
102 size_mismatch_with_SkColorType_enum); |
|
103 |
|
104 SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize)); |
|
105 return gSize[ct]; |
|
106 } |
|
107 |
|
108 static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) { |
|
109 return width * SkColorTypeBytesPerPixel(ct); |
|
110 } |
|
111 |
|
112 static inline bool SkColorTypeIsValid(unsigned value) { |
|
113 return value <= kLastEnum_SkColorType; |
|
114 } |
|
115 |
|
116 /////////////////////////////////////////////////////////////////////////////// |
|
117 |
|
118 /** |
|
119 * Describe an image's dimensions and pixel type. |
|
120 */ |
|
121 struct SkImageInfo { |
|
122 int fWidth; |
|
123 int fHeight; |
|
124 SkColorType fColorType; |
|
125 SkAlphaType fAlphaType; |
|
126 |
|
127 static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) { |
|
128 SkImageInfo info = { |
|
129 width, height, ct, at |
|
130 }; |
|
131 return info; |
|
132 } |
|
133 |
|
134 /** |
|
135 * Sets colortype to the native ARGB32 type. |
|
136 */ |
|
137 static SkImageInfo MakeN32(int width, int height, SkAlphaType at) { |
|
138 SkImageInfo info = { |
|
139 width, height, kPMColor_SkColorType, at |
|
140 }; |
|
141 return info; |
|
142 } |
|
143 |
|
144 /** |
|
145 * Sets colortype to the native ARGB32 type, and the alphatype to premul. |
|
146 */ |
|
147 static SkImageInfo MakeN32Premul(int width, int height) { |
|
148 SkImageInfo info = { |
|
149 width, height, kPMColor_SkColorType, kPremul_SkAlphaType |
|
150 }; |
|
151 return info; |
|
152 } |
|
153 |
|
154 /** |
|
155 * Sets colortype to the native ARGB32 type, and the alphatype to premul. |
|
156 */ |
|
157 static SkImageInfo MakeN32Premul(const SkISize& size) { |
|
158 return MakeN32Premul(size.width(), size.height()); |
|
159 } |
|
160 |
|
161 static SkImageInfo MakeA8(int width, int height) { |
|
162 SkImageInfo info = { |
|
163 width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType |
|
164 }; |
|
165 return info; |
|
166 } |
|
167 |
|
168 static SkImageInfo MakeUnknown(int width, int height) { |
|
169 SkImageInfo info = { |
|
170 width, height, kUnknown_SkColorType, kIgnore_SkAlphaType |
|
171 }; |
|
172 return info; |
|
173 } |
|
174 |
|
175 int width() const { return fWidth; } |
|
176 int height() const { return fHeight; } |
|
177 SkColorType colorType() const { return fColorType; } |
|
178 SkAlphaType alphaType() const { return fAlphaType; } |
|
179 |
|
180 bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } |
|
181 |
|
182 bool isOpaque() const { |
|
183 return SkAlphaTypeIsOpaque(fAlphaType); |
|
184 } |
|
185 |
|
186 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } |
|
187 |
|
188 int bytesPerPixel() const { |
|
189 return SkColorTypeBytesPerPixel(fColorType); |
|
190 } |
|
191 |
|
192 uint64_t minRowBytes64() const { |
|
193 return sk_64_mul(fWidth, this->bytesPerPixel()); |
|
194 } |
|
195 |
|
196 size_t minRowBytes() const { |
|
197 return (size_t)this->minRowBytes64(); |
|
198 } |
|
199 |
|
200 bool operator==(const SkImageInfo& other) const { |
|
201 return 0 == memcmp(this, &other, sizeof(other)); |
|
202 } |
|
203 bool operator!=(const SkImageInfo& other) const { |
|
204 return 0 != memcmp(this, &other, sizeof(other)); |
|
205 } |
|
206 |
|
207 void unflatten(SkReadBuffer&); |
|
208 void flatten(SkWriteBuffer&) const; |
|
209 |
|
210 int64_t getSafeSize64(size_t rowBytes) const { |
|
211 if (0 == fHeight) { |
|
212 return 0; |
|
213 } |
|
214 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel(); |
|
215 } |
|
216 |
|
217 size_t getSafeSize(size_t rowBytes) const { |
|
218 return (size_t)this->getSafeSize64(rowBytes); |
|
219 } |
|
220 |
|
221 bool validRowBytes(size_t rowBytes) const { |
|
222 uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); |
|
223 return rowBytes >= rb; |
|
224 } |
|
225 |
|
226 SkDEBUGCODE(void validate() const;) |
|
227 }; |
|
228 |
|
229 #endif |