SkImageInfo.h revision 61e96cd44624c9faceb625519c1b29775b161f45
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
14class SkWriteBuffer;
15class SkReadBuffer;
16
17/**
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,
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
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
62static 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 */
71enum 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
91static 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
108static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
109    return width * SkColorTypeBytesPerPixel(ct);
110}
111
112static 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 */
121struct 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        SkASSERT(width >= 0);
129        SkASSERT(height >= 0);
130        SkImageInfo info = {
131            width, height, ct, at
132        };
133        return info;
134    }
135
136    /**
137     *  Sets colortype to the native ARGB32 type.
138     */
139    static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
140        SkASSERT(width >= 0);
141        SkASSERT(height >= 0);
142        SkImageInfo info = {
143            width, height, kPMColor_SkColorType, at
144        };
145        return info;
146    }
147
148    /**
149     *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
150     */
151    static SkImageInfo MakeN32Premul(int width, int height) {
152        SkASSERT(width >= 0);
153        SkASSERT(height >= 0);
154        SkImageInfo info = {
155            width, height, kPMColor_SkColorType, kPremul_SkAlphaType
156        };
157        return info;
158    }
159
160    /**
161     *  Sets colortype to the native ARGB32 type, and the alphatype to premul.
162     */
163    static SkImageInfo MakeN32Premul(const SkISize& size) {
164        return MakeN32Premul(size.width(), size.height());
165    }
166
167    static SkImageInfo MakeA8(int width, int height) {
168        SkASSERT(width >= 0);
169        SkASSERT(height >= 0);
170        SkImageInfo info = {
171            width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType
172        };
173        return info;
174    }
175
176    int width() const { return fWidth; }
177    int height() const { return fHeight; }
178    SkColorType colorType() const { return fColorType; }
179    SkAlphaType alphaType() const { return fAlphaType; }
180
181    bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
182
183    bool isOpaque() const {
184        return SkAlphaTypeIsOpaque(fAlphaType);
185    }
186
187    SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
188
189    int bytesPerPixel() const {
190        return SkColorTypeBytesPerPixel(fColorType);
191    }
192
193    uint64_t minRowBytes64() const {
194        return sk_64_mul(fWidth, this->bytesPerPixel());
195    }
196
197    size_t minRowBytes() const {
198        return (size_t)this->minRowBytes64();
199    }
200
201    bool operator==(const SkImageInfo& other) const {
202        return 0 == memcmp(this, &other, sizeof(other));
203    }
204    bool operator!=(const SkImageInfo& other) const {
205        return 0 != memcmp(this, &other, sizeof(other));
206    }
207
208    void unflatten(SkReadBuffer&);
209    void flatten(SkWriteBuffer&) const;
210
211    int64_t getSafeSize64(size_t rowBytes) const {
212        if (0 == fHeight) {
213            return 0;
214        }
215        return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
216    }
217
218    size_t getSafeSize(size_t rowBytes) const {
219        return (size_t)this->getSafeSize64(rowBytes);
220    }
221
222    bool validRowBytes(size_t rowBytes) const {
223        uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel());
224        return rowBytes >= rb;
225    }
226
227    SkDEBUGCODE(void validate() const;)
228};
229
230#endif
231