• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkAlphaTypeIsOpaque(SkAlphaType at)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 
SkAlphaTypeIsValid(unsigned value)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     kN32_SkColorType = kBGRA_8888_SkColorType,
84 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
85     kN32_SkColorType = kRGBA_8888_SkColorType,
86 #else
87 #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
88 #endif
89 
90 #ifdef SK_SUPPORT_LEGACY_N32_NAME
91     kPMColor_SkColorType = kN32_SkColorType
92 #endif
93 };
94 
SkColorTypeBytesPerPixel(SkColorType ct)95 static int SkColorTypeBytesPerPixel(SkColorType ct) {
96     static const uint8_t gSize[] = {
97         0,  // Unknown
98         1,  // Alpha_8
99         2,  // RGB_565
100         2,  // ARGB_4444
101         4,  // RGBA_8888
102         4,  // BGRA_8888
103         1,  // kIndex_8
104     };
105     SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1),
106                       size_mismatch_with_SkColorType_enum);
107 
108     SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize));
109     return gSize[ct];
110 }
111 
SkColorTypeMinRowBytes(SkColorType ct,int width)112 static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
113     return width * SkColorTypeBytesPerPixel(ct);
114 }
115 
SkColorTypeIsValid(unsigned value)116 static inline bool SkColorTypeIsValid(unsigned value) {
117     return value <= kLastEnum_SkColorType;
118 }
119 
120 ///////////////////////////////////////////////////////////////////////////////
121 
122 /**
123  *  Describe an image's dimensions and pixel type.
124  */
125 struct SkImageInfo {
126     int         fWidth;
127     int         fHeight;
128     SkColorType fColorType;
129     SkAlphaType fAlphaType;
130 
MakeSkImageInfo131     static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) {
132         SkImageInfo info = {
133             width, height, ct, at
134         };
135         return info;
136     }
137 
138     /**
139      *  Sets colortype to the native ARGB32 type.
140      */
MakeN32SkImageInfo141     static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
142         SkImageInfo info = {
143             width, height, kN32_SkColorType, at
144         };
145         return info;
146     }
147 
148     /**
149      *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
150      */
MakeN32PremulSkImageInfo151     static SkImageInfo MakeN32Premul(int width, int height) {
152         SkImageInfo info = {
153             width, height, kN32_SkColorType, kPremul_SkAlphaType
154         };
155         return info;
156     }
157 
158     /**
159      *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
160      */
MakeN32PremulSkImageInfo161     static SkImageInfo MakeN32Premul(const SkISize& size) {
162         return MakeN32Premul(size.width(), size.height());
163     }
164 
MakeA8SkImageInfo165     static SkImageInfo MakeA8(int width, int height) {
166         SkImageInfo info = {
167             width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType
168         };
169         return info;
170     }
171 
MakeUnknownSkImageInfo172     static SkImageInfo MakeUnknown(int width, int height) {
173         SkImageInfo info = {
174             width, height, kUnknown_SkColorType, kIgnore_SkAlphaType
175         };
176         return info;
177     }
178 
MakeUnknownSkImageInfo179     static SkImageInfo MakeUnknown() {
180         SkImageInfo info = {
181             0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType
182         };
183         return info;
184     }
185 
widthSkImageInfo186     int width() const { return fWidth; }
heightSkImageInfo187     int height() const { return fHeight; }
colorTypeSkImageInfo188     SkColorType colorType() const { return fColorType; }
alphaTypeSkImageInfo189     SkAlphaType alphaType() const { return fAlphaType; }
190 
isEmptySkImageInfo191     bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
192 
isOpaqueSkImageInfo193     bool isOpaque() const {
194         return SkAlphaTypeIsOpaque(fAlphaType);
195     }
196 
dimensionsSkImageInfo197     SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
198 
199     /**
200      *  Return a new ImageInfo with the same colortype and alphatype as this info,
201      *  but with the specified width and height.
202      */
makeWHSkImageInfo203     SkImageInfo makeWH(int newWidth, int newHeight) const {
204         return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType);
205     }
206 
bytesPerPixelSkImageInfo207     int bytesPerPixel() const {
208         return SkColorTypeBytesPerPixel(fColorType);
209     }
210 
minRowBytes64SkImageInfo211     uint64_t minRowBytes64() const {
212         return sk_64_mul(fWidth, this->bytesPerPixel());
213     }
214 
minRowBytesSkImageInfo215     size_t minRowBytes() const {
216         return (size_t)this->minRowBytes64();
217     }
218 
219     bool operator==(const SkImageInfo& other) const {
220         return 0 == memcmp(this, &other, sizeof(other));
221     }
222     bool operator!=(const SkImageInfo& other) const {
223         return 0 != memcmp(this, &other, sizeof(other));
224     }
225 
226     void unflatten(SkReadBuffer&);
227     void flatten(SkWriteBuffer&) const;
228 
getSafeSize64SkImageInfo229     int64_t getSafeSize64(size_t rowBytes) const {
230         if (0 == fHeight) {
231             return 0;
232         }
233         return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
234     }
235 
getSafeSizeSkImageInfo236     size_t getSafeSize(size_t rowBytes) const {
237         return (size_t)this->getSafeSize64(rowBytes);
238     }
239 
validRowBytesSkImageInfo240     bool validRowBytes(size_t rowBytes) const {
241         uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
242         return rowBytes >= rb;
243     }
244 
245     SkDEBUGCODE(void validate() const;)
246 };
247 
248 #endif
249