Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 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 | |
Hal Canary | 6b20a55 | 2017-02-07 14:09:38 -0500 | [diff] [blame] | 8 | #ifndef SkImageInfoPriv_DEFINED |
| 9 | #define SkImageInfoPriv_DEFINED |
| 10 | |
| 11 | #include "SkImageInfo.h" |
| 12 | |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 13 | /** |
Matt Sarett | 26b44df | 2017-05-02 16:04:56 -0400 | [diff] [blame] | 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. |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 16 | */ |
Matt Sarett | 26b44df | 2017-05-02 16:04:56 -0400 | [diff] [blame] | 17 | static inline bool SkImageInfoIsValidCommon(const SkImageInfo& info) { |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 18 | if (info.width() <= 0 || info.height() <= 0) { |
| 19 | return false; |
| 20 | } |
| 21 | |
Matt Sarett | 8572d85 | 2017-02-14 11:21:02 -0500 | [diff] [blame] | 22 | const int kMaxDimension = SK_MaxS32 >> 2; |
| 23 | if (info.width() > kMaxDimension || info.height() > kMaxDimension) { |
| 24 | return false; |
| 25 | } |
| 26 | |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 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() && |
Stan Iliev | 4ed9ae4 | 2017-07-25 11:59:12 -0400 | [diff] [blame] | 37 | (info.colorSpace() && (!info.colorSpace()->gammaIsLinear()))) { |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 38 | return false; |
| 39 | } |
| 40 | |
Matt Sarett | 26b44df | 2017-05-02 16:04:56 -0400 | [diff] [blame] | 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 | |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 70 | if (info.colorSpace() && |
| 71 | (!info.colorSpace()->gammaCloseToSRGB() && !info.colorSpace()->gammaIsLinear())) { |
| 72 | return false; |
| 73 | } |
| 74 | |
| 75 | return true; |
| 76 | } |
| 77 | |
| 78 | /** |
Matt Sarett | dedac85 | 2017-05-12 10:56:49 -0400 | [diff] [blame] | 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 | /** |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 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: |
Matt Sarett | 8572d85 | 2017-02-14 11:21:02 -0500 | [diff] [blame] | 94 | * We will not convert to kIndex8 unless it exactly matches the src, since color tables |
| 95 | * are immutable. |
Matt Sarett | 5101448 | 2017-02-09 13:50:45 -0500 | [diff] [blame] | 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. |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 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. |
Matt Sarett | f575993 | 2017-02-07 21:52:07 +0000 | [diff] [blame] | 106 | * We will not convert to a particular color space if |src| is nullptr. The color space |
| 107 | * conversion is not well-defined. |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 108 | */ |
| 109 | static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkImageInfo& src) { |
Matt Sarett | 733340a | 2017-05-02 16:19:51 -0400 | [diff] [blame] | 110 | if (!SkImageInfoIsValidAllowNumericalCS(dst) || !SkImageInfoIsValidAllowNumericalCS(src)) { |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 111 | return false; |
| 112 | } |
| 113 | |
Matt Sarett | 8572d85 | 2017-02-14 11:21:02 -0500 | [diff] [blame] | 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 | } |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | if (kAlpha_8_SkColorType != dst.colorType() && kAlpha_8_SkColorType == src.colorType()) { |
| 125 | return false; |
| 126 | } |
| 127 | |
Matt Sarett | a8f4139 | 2017-02-06 18:28:49 +0000 | [diff] [blame] | 128 | if (kOpaque_SkAlphaType == dst.alphaType() && kOpaque_SkAlphaType != src.alphaType()) { |
| 129 | return false; |
| 130 | } |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 131 | |
Matt Sarett | f575993 | 2017-02-07 21:52:07 +0000 | [diff] [blame] | 132 | if (dst.colorSpace() && !src.colorSpace()) { |
| 133 | return false; |
| 134 | } |
| 135 | |
Matt Sarett | cb6266b | 2017-01-17 10:48:53 -0500 | [diff] [blame] | 136 | return true; |
| 137 | } |
Hal Canary | 6b20a55 | 2017-02-07 14:09:38 -0500 | [diff] [blame] | 138 | #endif // SkImageInfoPriv_DEFINED |