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*/
20struct 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