1 /* 2 * Copyright 2016 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 SkEncodedInfo_DEFINED 9 #define SkEncodedInfo_DEFINED 10 11 #include "SkImageInfo.h" 12 13 class SkColorSpace; 14 15 struct SkEncodedInfo { 16 public: 17 18 enum Alpha { 19 kOpaque_Alpha, 20 kUnpremul_Alpha, 21 22 // Each pixel is either fully opaque or fully transparent. 23 // There is no difference between requesting kPremul or kUnpremul. 24 kBinary_Alpha, 25 }; 26 27 /* 28 * We strive to make the number of components per pixel obvious through 29 * our naming conventions. 30 * Ex: kRGB has 3 components. kRGBA has 4 components. 31 * 32 * This sometimes results in redundant Alpha and Color information. 33 * Ex: kRGB images must also be kOpaque. 34 */ 35 enum Color { 36 // PNG, WBMP 37 kGray_Color, 38 39 // PNG 40 kGrayAlpha_Color, 41 42 // PNG, GIF, BMP 43 kPalette_Color, 44 45 // PNG, RAW 46 kRGB_Color, 47 kRGBA_Color, 48 49 // BMP 50 kBGR_Color, 51 kBGRX_Color, 52 kBGRA_Color, 53 54 // JPEG, WEBP 55 kYUV_Color, 56 57 // WEBP 58 kYUVA_Color, 59 60 // JPEG 61 // Photoshop actually writes inverted CMYK data into JPEGs, where zero 62 // represents 100% ink coverage. For this reason, we treat CMYK JPEGs 63 // as having inverted CMYK. libjpeg-turbo warns that this may break 64 // other applications, but the CMYK JPEGs we see on the web expect to 65 // be treated as inverted CMYK. 66 kInvertedCMYK_Color, 67 kYCCK_Color, 68 }; 69 MakeSkEncodedInfo70 static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) { 71 SkASSERT(1 == bitsPerComponent || 72 2 == bitsPerComponent || 73 4 == bitsPerComponent || 74 8 == bitsPerComponent || 75 16 == bitsPerComponent); 76 77 switch (color) { 78 case kGray_Color: 79 SkASSERT(kOpaque_Alpha == alpha); 80 break; 81 case kGrayAlpha_Color: 82 SkASSERT(kOpaque_Alpha != alpha); 83 break; 84 case kPalette_Color: 85 SkASSERT(16 != bitsPerComponent); 86 break; 87 case kRGB_Color: 88 case kBGR_Color: 89 case kBGRX_Color: 90 SkASSERT(kOpaque_Alpha == alpha); 91 SkASSERT(bitsPerComponent >= 8); 92 break; 93 case kYUV_Color: 94 case kInvertedCMYK_Color: 95 case kYCCK_Color: 96 SkASSERT(kOpaque_Alpha == alpha); 97 SkASSERT(8 == bitsPerComponent); 98 break; 99 case kRGBA_Color: 100 SkASSERT(kOpaque_Alpha != alpha); 101 SkASSERT(bitsPerComponent >= 8); 102 break; 103 case kBGRA_Color: 104 case kYUVA_Color: 105 SkASSERT(kOpaque_Alpha != alpha); 106 SkASSERT(8 == bitsPerComponent); 107 break; 108 default: 109 SkASSERT(false); 110 break; 111 } 112 113 return SkEncodedInfo(color, alpha, bitsPerComponent); 114 } 115 116 /* 117 * Returns an SkImageInfo with Skia color and alpha types that are the 118 * closest possible match to the encoded info. 119 */ makeImageInfoSkEncodedInfo120 SkImageInfo makeImageInfo(int width, int height, sk_sp<SkColorSpace> colorSpace) const { 121 switch (fColor) { 122 case kGray_Color: 123 SkASSERT(kOpaque_Alpha == fAlpha); 124 return SkImageInfo::Make(width, height, kGray_8_SkColorType, 125 kOpaque_SkAlphaType, colorSpace); 126 case kGrayAlpha_Color: 127 SkASSERT(kOpaque_Alpha != fAlpha); 128 return SkImageInfo::Make(width, height, kN32_SkColorType, 129 kUnpremul_SkAlphaType, colorSpace); 130 case kPalette_Color: { 131 SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType : 132 kUnpremul_SkAlphaType; 133 return SkImageInfo::Make(width, height, kN32_SkColorType, 134 alphaType, colorSpace); 135 } 136 case kRGB_Color: 137 case kBGR_Color: 138 case kBGRX_Color: 139 case kYUV_Color: 140 case kInvertedCMYK_Color: 141 case kYCCK_Color: 142 SkASSERT(kOpaque_Alpha == fAlpha); 143 return SkImageInfo::Make(width, height, kN32_SkColorType, 144 kOpaque_SkAlphaType, colorSpace); 145 case kRGBA_Color: 146 case kBGRA_Color: 147 case kYUVA_Color: 148 SkASSERT(kOpaque_Alpha != fAlpha); 149 return SkImageInfo::Make(width, height, kN32_SkColorType, 150 kUnpremul_SkAlphaType, std::move(colorSpace)); 151 default: 152 SkASSERT(false); 153 return SkImageInfo::MakeUnknown(); 154 } 155 } 156 colorSkEncodedInfo157 Color color() const { return fColor; } alphaSkEncodedInfo158 Alpha alpha() const { return fAlpha; } bitsPerComponentSkEncodedInfo159 uint8_t bitsPerComponent() const { return fBitsPerComponent; } 160 bitsPerPixelSkEncodedInfo161 uint8_t bitsPerPixel() const { 162 switch (fColor) { 163 case kGray_Color: 164 return fBitsPerComponent; 165 case kGrayAlpha_Color: 166 return 2 * fBitsPerComponent; 167 case kPalette_Color: 168 return fBitsPerComponent; 169 case kRGB_Color: 170 case kBGR_Color: 171 case kYUV_Color: 172 return 3 * fBitsPerComponent; 173 case kRGBA_Color: 174 case kBGRA_Color: 175 case kBGRX_Color: 176 case kYUVA_Color: 177 case kInvertedCMYK_Color: 178 case kYCCK_Color: 179 return 4 * fBitsPerComponent; 180 default: 181 SkASSERT(false); 182 return 0; 183 } 184 } 185 186 private: 187 SkEncodedInfoSkEncodedInfo188 SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent) 189 : fColor(color) 190 , fAlpha(alpha) 191 , fBitsPerComponent(bitsPerComponent) 192 {} 193 194 Color fColor; 195 Alpha fAlpha; 196 uint8_t fBitsPerComponent; 197 }; 198 199 #endif 200