SkImageInfo.h revision 3b40ee60094b3b232847f782f8d878be98386ed9
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 "SkRect.h"
13#include "SkSize.h"
14
15class SkReadBuffer;
16class SkWriteBuffer;
17
18/**
19 *  Describes how to interpret the alpha compoent of a pixel.
20 */
21enum SkAlphaType {
22    /**
23     *  All pixels should be treated as opaque, regardless of the value stored
24     *  in their alpha field. Used for legacy images that wrote 0 or garbarge
25     *  in their alpha field, but intended the RGB to be treated as opaque.
26     */
27    kIgnore_SkAlphaType,
28
29    /**
30     *  All pixels are stored as opaque. This differs slightly from kIgnore in
31     *  that kOpaque has correct "opaque" values stored in the pixels, while
32     *  kIgnore may not, but in both cases the caller should treat the pixels
33     *  as opaque.
34     */
35    kOpaque_SkAlphaType,
36
37    /**
38     *  All pixels have their alpha premultiplied in their color components.
39     *  This is the natural format for the rendering target pixels.
40     */
41    kPremul_SkAlphaType,
42
43    /**
44     *  All pixels have their color components stored without any regard to the
45     *  alpha. e.g. this is the default configuration for PNG images.
46     *
47     *  This alpha-type is ONLY supported for input images. Rendering cannot
48     *  generate this on output.
49     */
50    kUnpremul_SkAlphaType,
51
52    kLastEnum_SkAlphaType = kUnpremul_SkAlphaType
53};
54
55static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
56    SK_COMPILE_ASSERT(kIgnore_SkAlphaType < kOpaque_SkAlphaType, bad_alphatype_order);
57    SK_COMPILE_ASSERT(kPremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
58    SK_COMPILE_ASSERT(kUnpremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order);
59
60    return (unsigned)at <= kOpaque_SkAlphaType;
61}
62
63static inline bool SkAlphaTypeIsValid(unsigned value) {
64    return value <= kLastEnum_SkAlphaType;
65}
66
67///////////////////////////////////////////////////////////////////////////////
68
69/**
70 *  Describes how to interpret the components of a pixel.
71 *
72 *  kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
73 *  form for skia's blitters. Use this if you don't have a swizzle preference
74 *  for 32bit pixels.
75 */
76enum SkColorType {
77    kUnknown_SkColorType,
78    kAlpha_8_SkColorType,
79    kRGB_565_SkColorType,
80    kARGB_4444_SkColorType,
81    kRGBA_8888_SkColorType,
82    kBGRA_8888_SkColorType,
83    kIndex_8_SkColorType,
84
85    kLastEnum_SkColorType = kIndex_8_SkColorType,
86
87#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
88    kN32_SkColorType = kBGRA_8888_SkColorType,
89#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
90    kN32_SkColorType = kRGBA_8888_SkColorType,
91#else
92    #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
93#endif
94};
95
96static int SkColorTypeBytesPerPixel(SkColorType ct) {
97    static const uint8_t gSize[] = {
98        0,  // Unknown
99        1,  // Alpha_8
100        2,  // RGB_565
101        2,  // ARGB_4444
102        4,  // RGBA_8888
103        4,  // BGRA_8888
104        1,  // kIndex_8
105    };
106    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1),
107                      size_mismatch_with_SkColorType_enum);
108
109    SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize));
110    return gSize[ct];
111}
112
113static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
114    return width * SkColorTypeBytesPerPixel(ct);
115}
116
117static inline bool SkColorTypeIsValid(unsigned value) {
118    return value <= kLastEnum_SkColorType;
119}
120
121///////////////////////////////////////////////////////////////////////////////
122
123/**
124 *  Return true if alphaType is supported by colorType. If there is a canonical
125 *  alphaType for this colorType, return it in canonical.
126 */
127bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
128                                  SkAlphaType* canonical = NULL);
129
130///////////////////////////////////////////////////////////////////////////////
131
132/**
133 *  Describes the color space a YUV pixel.
134 */
135enum SkYUVColorSpace {
136    /** Standard JPEG color space. */
137    kJPEG_SkYUVColorSpace,
138    /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color
139       range. See http://en.wikipedia.org/wiki/Rec._601 for details. */
140    kRec601_SkYUVColorSpace,
141
142    kLastEnum_SkYUVColorSpace = kRec601_SkYUVColorSpace
143};
144
145///////////////////////////////////////////////////////////////////////////////
146
147enum SkColorProfileType {
148    kLinear_SkColorProfileType,
149    kSRGB_SkColorProfileType,
150
151    kLastEnum_SkColorProfileType = kSRGB_SkColorProfileType
152};
153
154/**
155 *  Describe an image's dimensions and pixel type.
156 *  Used for both src images and render-targets (surfaces).
157 */
158struct SkImageInfo {
159public:
160    SkImageInfo()
161        : fWidth(0)
162        , fHeight(0)
163        , fColorType(kUnknown_SkColorType)
164        , fAlphaType(kIgnore_SkAlphaType)
165        , fProfileType(kLinear_SkColorProfileType)
166    {}
167
168    static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
169                            SkColorProfileType pt = kLinear_SkColorProfileType) {
170        return SkImageInfo(width, height, ct, at, pt);
171    }
172
173    /**
174     *  Sets colortype to the native ARGB32 type.
175     */
176    static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
177                               SkColorProfileType pt = kLinear_SkColorProfileType) {
178        return SkImageInfo(width, height, kN32_SkColorType, at, pt);
179    }
180
181    /**
182     *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
183     */
184    static SkImageInfo MakeN32Premul(int width, int height,
185                                     SkColorProfileType pt = kLinear_SkColorProfileType) {
186        return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType, pt);
187    }
188
189    /**
190     *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
191     */
192    static SkImageInfo MakeN32Premul(const SkISize& size,
193                                     SkColorProfileType pt = kLinear_SkColorProfileType) {
194        return MakeN32Premul(size.width(), size.height(), pt);
195    }
196
197    static SkImageInfo MakeA8(int width, int height) {
198        return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType,
199                           kLinear_SkColorProfileType);
200    }
201
202    static SkImageInfo MakeUnknown(int width, int height) {
203        return SkImageInfo(width, height, kUnknown_SkColorType, kIgnore_SkAlphaType,
204                           kLinear_SkColorProfileType);
205    }
206
207    static SkImageInfo MakeUnknown() {
208        return SkImageInfo();
209    }
210
211    int width() const { return fWidth; }
212    int height() const { return fHeight; }
213    SkColorType colorType() const { return fColorType; }
214    SkAlphaType alphaType() const { return fAlphaType; }
215    SkColorProfileType profileType() const { return fProfileType; }
216
217    bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
218
219    bool isOpaque() const {
220        return SkAlphaTypeIsOpaque(fAlphaType);
221    }
222
223    bool isLinear() const { return kLinear_SkColorProfileType == fProfileType; }
224    bool isSRGB() const { return kSRGB_SkColorProfileType == fProfileType; }
225
226    SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
227    SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
228
229    /**
230     *  Return a new ImageInfo with the same colortype and alphatype as this info,
231     *  but with the specified width and height.
232     */
233    SkImageInfo makeWH(int newWidth, int newHeight) const {
234        return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType, fProfileType);
235    }
236
237    SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
238        return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType, fProfileType);
239    }
240
241    SkImageInfo makeColorType(SkColorType newColorType) const {
242        return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType, fProfileType);
243    }
244
245    int bytesPerPixel() const {
246        return SkColorTypeBytesPerPixel(fColorType);
247    }
248
249    uint64_t minRowBytes64() const {
250        return sk_64_mul(fWidth, this->bytesPerPixel());
251    }
252
253    size_t minRowBytes() const {
254        return (size_t)this->minRowBytes64();
255    }
256
257    bool operator==(const SkImageInfo& other) const {
258        return 0 == memcmp(this, &other, sizeof(other));
259    }
260    bool operator!=(const SkImageInfo& other) const {
261        return 0 != memcmp(this, &other, sizeof(other));
262    }
263
264    void unflatten(SkReadBuffer&);
265    void flatten(SkWriteBuffer&) const;
266
267    int64_t getSafeSize64(size_t rowBytes) const {
268        if (0 == fHeight) {
269            return 0;
270        }
271        return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
272    }
273
274    size_t getSafeSize(size_t rowBytes) const {
275        return (size_t)this->getSafeSize64(rowBytes);
276    }
277
278    bool validRowBytes(size_t rowBytes) const {
279        uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
280        return rowBytes >= rb;
281    }
282
283    SkDEBUGCODE(void validate() const;)
284
285#ifdef SK_SUPPORT_LEGACY_PUBLIC_IMAGEINFO_FIELDS
286public:
287#else
288private:
289#endif
290    int                 fWidth;
291    int                 fHeight;
292    SkColorType         fColorType;
293    SkAlphaType         fAlphaType;
294
295private:
296    SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, SkColorProfileType pt)
297        : fWidth(width)
298        , fHeight(height)
299        , fColorType(ct)
300        , fAlphaType(at)
301        , fProfileType(pt)
302    {}
303
304    SkColorProfileType  fProfileType;
305};
306
307#endif
308