1 /* 2 * Copyright 2018 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 SkYUVAIndex_DEFINED 9 #define SkYUVAIndex_DEFINED 10 11 #include "SkTypes.h" 12 13 /** \enum SkColorChannel 14 Describes different color channels one can manipulate 15 */ 16 enum class SkColorChannel { 17 kR, // the red channel 18 kG, // the green channel 19 kB, // the blue channel 20 kA, // the alpha channel 21 22 kLastEnum = kA, 23 }; 24 25 /** \struct SkYUVAIndex 26 Describes from which image source and which channel to read each individual YUVA plane. 27 28 SkYUVAIndex contains a index for which image source to read from and a enum for which channel 29 to read from. 30 */ 31 struct SK_API SkYUVAIndex { 32 bool operator==(const SkYUVAIndex& that) const { 33 return this->fIndex == that.fIndex && this->fChannel == that.fChannel; 34 } 35 36 bool operator!=(const SkYUVAIndex& that) const { 37 return !(*this == that); 38 } 39 40 // Index in the array of SkYUVAIndex 41 // TODO: rename as Component 42 enum Index { 43 kY_Index = 0, 44 kU_Index = 1, 45 kV_Index = 2, 46 kA_Index = 3, 47 48 kLast_Index = kA_Index 49 }; 50 static constexpr int kIndexCount = kLast_Index + 1; 51 52 /** The index is a number between -1..3 which definies which image source to read from, where -1 53 * means the image source doesn't exist. The assumption is we will always have image sources for 54 * each of YUV planes, but optionally have image source for A plane. */ 55 int fIndex; 56 /** The channel describes from which channel to read the info from. Currently we only deal with 57 * YUV and NV12 and channel info is ignored. */ 58 SkColorChannel fChannel; 59 AreValidIndicesSkYUVAIndex60 static bool AreValidIndices(const SkYUVAIndex yuvaIndices[4], int* numPlanes) { 61 // Note that 'numPlanes' is always filled in even if the indices are not valid. 62 // This means it can always be used to process the backing resources (but be careful 63 // of empty intervening slots). 64 int maxSlotUsed = -1; 65 bool used[4] = { false, false, false, false }; 66 bool valid = true; 67 for (int i = 0; i < 4; ++i) { 68 if (yuvaIndices[i].fIndex < 0) { 69 if (SkYUVAIndex::kA_Index != i) { 70 valid = false; // only the 'A' plane can be omitted 71 } 72 } else if (yuvaIndices[i].fIndex > 3) { 73 valid = false; // A maximum of four input textures is allowed 74 } else { 75 maxSlotUsed = SkTMax(yuvaIndices[i].fIndex, maxSlotUsed); 76 used[i] = true; 77 } 78 } 79 80 // All the used slots should be packed starting at 0 with no gaps 81 for (int i = 0; i <= maxSlotUsed; ++i) { 82 if (!used[i]) { 83 valid = false; 84 } 85 } 86 87 *numPlanes = maxSlotUsed + 1; 88 return valid; 89 } 90 }; 91 92 #endif 93