blob: 8ca87eba7a8ce4095067339f543fb2b64cf4e534 [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
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +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
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +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.
70 */
71enum SkColorType {
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +000072 kUnknown_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000073 kAlpha_8_SkColorType,
74 kRGB_565_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000075 kARGB_4444_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000076 kRGBA_8888_SkColorType,
77 kBGRA_8888_SkColorType,
reed@google.com9230ea22013-12-09 22:01:03 +000078 kIndex_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000079
reed@google.com9230ea22013-12-09 22:01:03 +000080 kLastEnum_SkColorType = kIndex_8_SkColorType,
reed@google.com3443fd82013-11-13 19:09:13 +000081
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[] = {
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +000093 0, // Unknown
reed@google.com3443fd82013-11-13 19:09:13 +000094 1, // Alpha_8
95 2, // RGB_565
reed@google.com9230ea22013-12-09 22:01:03 +000096 2, // ARGB_4444
reed@google.com3443fd82013-11-13 19:09:13 +000097 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
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000108static 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
reed@google.com3443fd82013-11-13 19:09:13 +0000116///////////////////////////////////////////////////////////////////////////////
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
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000127 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 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000159
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000160 /**
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 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000166
commit-bot@chromium.org32678d92014-01-15 02:38:22 +0000167 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 }
skia.committer@gmail.comd77b3ec2014-01-15 07:01:43 +0000175
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000176 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
reed@google.com3443fd82013-11-13 19:09:13 +0000183 bool isOpaque() const {
184 return SkAlphaTypeIsOpaque(fAlphaType);
185 }
186
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000187 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
188
reed@google.com3443fd82013-11-13 19:09:13 +0000189 int bytesPerPixel() const {
190 return SkColorTypeBytesPerPixel(fColorType);
191 }
192
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000193 uint64_t minRowBytes64() const {
194 return sk_64_mul(fWidth, this->bytesPerPixel());
reed@google.com9230ea22013-12-09 22:01:03 +0000195 }
skia.committer@gmail.com8ed64432014-02-11 03:02:13 +0000196
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000197 size_t minRowBytes() const {
198 return (size_t)this->minRowBytes64();
199 }
skia.committer@gmail.com8ed64432014-02-11 03:02:13 +0000200
reed@google.com3443fd82013-11-13 19:09:13 +0000201 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 }
reed@google.com9230ea22013-12-09 22:01:03 +0000207
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000208 void unflatten(SkReadBuffer&);
209 void flatten(SkWriteBuffer&) const;
reed@google.com9230ea22013-12-09 22:01:03 +0000210
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000211 int64_t getSafeSize64(size_t rowBytes) const {
reed@google.com9230ea22013-12-09 22:01:03 +0000212 if (0 == fHeight) {
213 return 0;
214 }
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000215 return sk_64_mul(fHeight - 1, rowBytes) + fWidth * this->bytesPerPixel();
reed@google.com9230ea22013-12-09 22:01:03 +0000216 }
mike@reedtribe.org169a0ed2014-02-11 02:20:17 +0000217
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;)
reed@google.com3443fd82013-11-13 19:09:13 +0000228};
229
230#endif