1/*
2 * Copyright 2017 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 SkImageInfoPriv_DEFINED
9#define SkImageInfoPriv_DEFINED
10
11#include "include/core/SkColor.h"
12#include "include/core/SkImageInfo.h"
13
14static inline uint32_t SkColorTypeChannelFlags(SkColorType ct) {
15    switch (ct) {
16        case kUnknown_SkColorType:            return 0;
17        case kAlpha_8_SkColorType:            return kAlpha_SkColorChannelFlag;
18        case kRGB_565_SkColorType:            return kRGB_SkColorChannelFlags;
19        case kARGB_4444_SkColorType:          return kRGBA_SkColorChannelFlags;
20        case kRGBA_8888_SkColorType:          return kRGBA_SkColorChannelFlags;
21        case kRGB_888x_SkColorType:           return kRGB_SkColorChannelFlags;
22        case kBGRA_8888_SkColorType:          return kRGBA_SkColorChannelFlags;
23        case kRGBA_1010102_SkColorType:       return kRGBA_SkColorChannelFlags;
24        case kRGB_101010x_SkColorType:        return kRGB_SkColorChannelFlags;
25        case kBGRA_1010102_SkColorType:       return kRGBA_SkColorChannelFlags;
26        case kBGR_101010x_SkColorType:        return kRGB_SkColorChannelFlags;
27        case kGray_8_SkColorType:             return kGray_SkColorChannelFlag;
28        case kRGBA_F16Norm_SkColorType:       return kRGBA_SkColorChannelFlags;
29        case kRGBA_F16_SkColorType:           return kRGBA_SkColorChannelFlags;
30        case kRGBA_F32_SkColorType:           return kRGBA_SkColorChannelFlags;
31        case kR8G8_unorm_SkColorType:         return kRG_SkColorChannelFlags;
32        case kA16_unorm_SkColorType:          return kAlpha_SkColorChannelFlag;
33        case kR16G16_unorm_SkColorType:       return kRG_SkColorChannelFlags;
34        case kA16_float_SkColorType:          return kAlpha_SkColorChannelFlag;
35        case kR16G16_float_SkColorType:       return kRG_SkColorChannelFlags;
36        case kR16G16B16A16_unorm_SkColorType: return kRGBA_SkColorChannelFlags;
37        case kSRGBA_8888_SkColorType:         return kRGBA_SkColorChannelFlags;
38    }
39    SkUNREACHABLE;
40}
41
42static inline bool SkColorTypeIsAlphaOnly(SkColorType ct) {
43    return SkColorTypeChannelFlags(ct) == kAlpha_SkColorChannelFlag;
44}
45
46static inline bool SkAlphaTypeIsValid(unsigned value) {
47    return value <= kLastEnum_SkAlphaType;
48}
49
50static int SkColorTypeShiftPerPixel(SkColorType ct) {
51    switch (ct) {
52        case kUnknown_SkColorType:            return 0;
53        case kAlpha_8_SkColorType:            return 0;
54        case kRGB_565_SkColorType:            return 1;
55        case kARGB_4444_SkColorType:          return 1;
56        case kRGBA_8888_SkColorType:          return 2;
57        case kRGB_888x_SkColorType:           return 2;
58        case kBGRA_8888_SkColorType:          return 2;
59        case kRGBA_1010102_SkColorType:       return 2;
60        case kRGB_101010x_SkColorType:        return 2;
61        case kBGRA_1010102_SkColorType:       return 2;
62        case kBGR_101010x_SkColorType:        return 2;
63        case kGray_8_SkColorType:             return 0;
64        case kRGBA_F16Norm_SkColorType:       return 3;
65        case kRGBA_F16_SkColorType:           return 3;
66        case kRGBA_F32_SkColorType:           return 4;
67        case kR8G8_unorm_SkColorType:         return 1;
68        case kA16_unorm_SkColorType:          return 1;
69        case kR16G16_unorm_SkColorType:       return 2;
70        case kA16_float_SkColorType:          return 1;
71        case kR16G16_float_SkColorType:       return 2;
72        case kR16G16B16A16_unorm_SkColorType: return 3;
73        case kSRGBA_8888_SkColorType:         return 2;
74    }
75    SkUNREACHABLE;
76}
77
78static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
79    return (size_t)(width * SkColorTypeBytesPerPixel(ct));
80}
81
82static inline bool SkColorTypeIsValid(unsigned value) {
83    return value <= kLastEnum_SkColorType;
84}
85
86static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) {
87    if (kUnknown_SkColorType == ct) {
88        return 0;
89    }
90    return (size_t)y * rowBytes + ((size_t)x << SkColorTypeShiftPerPixel(ct));
91}
92
93static inline bool SkColorTypeIsNormalized(SkColorType ct) {
94    switch (ct) {
95        case kUnknown_SkColorType:
96        case kAlpha_8_SkColorType:
97        case kRGB_565_SkColorType:
98        case kARGB_4444_SkColorType:
99        case kRGBA_8888_SkColorType:
100        case kRGB_888x_SkColorType:
101        case kBGRA_8888_SkColorType:
102        case kRGBA_1010102_SkColorType:
103        case kRGB_101010x_SkColorType:
104        case kBGRA_1010102_SkColorType:
105        case kBGR_101010x_SkColorType:
106        case kGray_8_SkColorType:
107        case kRGBA_F16Norm_SkColorType:
108        case kR8G8_unorm_SkColorType:
109        case kA16_unorm_SkColorType:
110        case kA16_float_SkColorType:          /*subtle... alpha is always [0,1]*/
111        case kR16G16_unorm_SkColorType:
112        case kR16G16B16A16_unorm_SkColorType:
113        case kSRGBA_8888_SkColorType: return true;
114
115        case kRGBA_F16_SkColorType:
116        case kRGBA_F32_SkColorType:
117        case kR16G16_float_SkColorType:       return false;
118    }
119    SkUNREACHABLE;
120}
121
122static inline int SkColorTypeMaxBitsPerChannel(SkColorType ct) {
123    switch (ct) {
124        case kUnknown_SkColorType:
125            return 0;
126
127        case kARGB_4444_SkColorType:
128            return 4;
129
130        case kRGB_565_SkColorType:
131            return 6;
132
133        case kAlpha_8_SkColorType:
134        case kRGBA_8888_SkColorType:
135        case kRGB_888x_SkColorType:
136        case kBGRA_8888_SkColorType:
137        case kGray_8_SkColorType:
138        case kR8G8_unorm_SkColorType:
139        case kSRGBA_8888_SkColorType:
140            return 8;
141
142        case kRGBA_1010102_SkColorType:
143        case kRGB_101010x_SkColorType:
144        case kBGRA_1010102_SkColorType:
145        case kBGR_101010x_SkColorType:
146            return 10;
147
148        case kRGBA_F16Norm_SkColorType:
149        case kA16_unorm_SkColorType:
150        case kA16_float_SkColorType:
151        case kR16G16_unorm_SkColorType:
152        case kR16G16B16A16_unorm_SkColorType:
153        case kRGBA_F16_SkColorType:
154        case kR16G16_float_SkColorType:
155            return 16;
156
157        case kRGBA_F32_SkColorType:
158            return 32;
159    }
160    SkUNREACHABLE;
161}
162
163/**
164 *  Returns true if |info| contains a valid colorType and alphaType.
165 */
166static inline bool SkColorInfoIsValid(const SkColorInfo& info) {
167    return info.colorType() != kUnknown_SkColorType && info.alphaType() != kUnknown_SkAlphaType;
168}
169
170/**
171 *  Returns true if |info| contains a valid combination of width, height and colorInfo.
172 */
173static inline bool SkImageInfoIsValid(const SkImageInfo& info) {
174    if (info.width() <= 0 || info.height() <= 0) {
175        return false;
176    }
177
178    const int kMaxDimension = SK_MaxS32 >> 2;
179    if (info.width() > kMaxDimension || info.height() > kMaxDimension) {
180        return false;
181    }
182
183    return SkColorInfoIsValid(info.colorInfo());
184}
185
186/**
187 *  Returns true if Skia has defined a pixel conversion from the |src| to the |dst|.
188 *  Returns false otherwise.
189 */
190static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkImageInfo& src) {
191    return SkImageInfoIsValid(dst) && SkImageInfoIsValid(src);
192}
193#endif  // SkImageInfoPriv_DEFINED
194