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