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 "SkImageInfo.h" 12 13 /** 14 * This contains shared checks on SkImageInfo. Depending on the desired color space behavior, 15 * the caller should choose one of the two versions below. 16 */ 17 static inline bool SkImageInfoIsValidCommon(const SkImageInfo& info) { 18 if (info.width() <= 0 || info.height() <= 0) { 19 return false; 20 } 21 22 const int kMaxDimension = SK_MaxS32 >> 2; 23 if (info.width() > kMaxDimension || info.height() > kMaxDimension) { 24 return false; 25 } 26 27 if (kUnknown_SkColorType == info.colorType() || kUnknown_SkAlphaType == info.alphaType()) { 28 return false; 29 } 30 31 if (kOpaque_SkAlphaType != info.alphaType() && 32 (kRGB_565_SkColorType == info.colorType() || kGray_8_SkColorType == info.colorType())) { 33 return false; 34 } 35 36 if (kRGBA_F16_SkColorType == info.colorType() && 37 (info.colorSpace() && (!info.colorSpace()->gammaIsLinear()))) { 38 return false; 39 } 40 41 return true; 42 } 43 44 /** 45 * Returns true if |info| contains a valid combination of width, height, colorType, alphaType, 46 * colorSpace. Allows numerical color spaces. Returns false otherwise. 47 */ 48 static inline bool SkImageInfoIsValidAllowNumericalCS(const SkImageInfo& info) { 49 if (!SkImageInfoIsValidCommon(info)) { 50 return false; 51 } 52 53 SkColorSpaceTransferFn fn; 54 if (info.colorSpace() && !info.colorSpace()->isNumericalTransferFn(&fn)) { 55 return false; 56 } 57 58 return true; 59 } 60 61 /** 62 * Returns true if |info| contains a valid combination of width, height, colorType, alphaType, 63 * colorSpace. Only supports rendering color spaces. Returns false otherwise. 64 */ 65 static inline bool SkImageInfoIsValidRenderingCS(const SkImageInfo& info) { 66 if (!SkImageInfoIsValidCommon(info)) { 67 return false; 68 } 69 70 if (info.colorSpace() && 71 (!info.colorSpace()->gammaCloseToSRGB() && !info.colorSpace()->gammaIsLinear())) { 72 return false; 73 } 74 75 return true; 76 } 77 78 /** 79 * Returns true if |info| contains a valid combination of width, height, colorType, alphaType, 80 * colorSpace. Uses |colorMode| to decide how to treat color spaces. 81 */ 82 static inline bool SkImageInfoIsValid(const SkImageInfo& info, 83 SkDestinationSurfaceColorMode colorMode) { 84 if (SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware == colorMode) { 85 return SkImageInfoIsValidRenderingCS(info); 86 } 87 88 return SkImageInfoIsValidAllowNumericalCS(info); 89 } 90 91 /** 92 * Returns true if Skia has defined a pixel conversion from the |src| to the |dst|. 93 * Returns false otherwise. Some discussion of false cases: 94 * We will not convert to kIndex8 unless it exactly matches the src, since color tables 95 * are immutable. 96 * We do not convert to kGray8 when the |src| is not kGray8 in the same color space. 97 * We may add this feature - it just requires some work to convert to luminance while 98 * handling color spaces correctly. Currently no one is asking for this. 99 * We will not convert from kAlpha8 when the |dst| is not kAlpha8. This would require 100 * inventing color information. 101 * We will not convert to kOpaque when the |src| is not kOpaque. This could be 102 * implemented to set all the alpha values to 1, but there is still some ambiguity - 103 * should we use kPremul or kUnpremul color values with the opaque alphas? Or should 104 * we just use whatever the |src| alpha is? In the future, we could choose to clearly 105 * define this, but currently no one is asking for this feature. 106 * We will not convert to a particular color space if |src| is nullptr. The color space 107 * conversion is not well-defined. 108 */ 109 static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkImageInfo& src) { 110 if (!SkImageInfoIsValidAllowNumericalCS(dst) || !SkImageInfoIsValidAllowNumericalCS(src)) { 111 return false; 112 } 113 114 if (kGray_8_SkColorType == dst.colorType()) { 115 if (kGray_8_SkColorType != src.colorType()) { 116 return false; 117 } 118 119 if (dst.colorSpace() && !SkColorSpace::Equals(dst.colorSpace(), src.colorSpace())) { 120 return false; 121 } 122 } 123 124 if (kAlpha_8_SkColorType != dst.colorType() && kAlpha_8_SkColorType == src.colorType()) { 125 return false; 126 } 127 128 if (kOpaque_SkAlphaType == dst.alphaType() && kOpaque_SkAlphaType != src.alphaType()) { 129 return false; 130 } 131 132 if (dst.colorSpace() && !src.colorSpace()) { 133 return false; 134 } 135 136 return true; 137 } 138 #endif // SkImageInfoPriv_DEFINED 139