1 /*
2  * Copyright 2021 Google LLC
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 SkYUVAInfoLocation_DEFINED
9 #define SkYUVAInfoLocation_DEFINED
10 
11 #include "include/core/SkColor.h"
12 #include "include/core/SkYUVAInfo.h"
13 
14 /**
15  * The location of Y, U, V, or A values within the planes described by SkYUVAInfo. Computed from a
16  * SkYUVAInfo and the set of channels present in a set of pixmaps/textures.
17  */
18 struct SkYUVAInfo::YUVALocation {
19     /** The index of the plane where the Y, U, V, or A value is to be found. */
20     int fPlane = -1;
21     /** The channel in the plane that contains the Y, U, V, or A value. */
22     SkColorChannel fChannel = SkColorChannel::kA;
23 
24     bool operator==(const YUVALocation& that) const {
25         return fPlane == that.fPlane && fChannel == that.fChannel;
26     }
27     bool operator!=(const YUVALocation& that) const { return !(*this == that); }
28 
29     static bool AreValidLocations(const SkYUVAInfo::YUVALocations& locations,
30                                   int* numPlanes = nullptr) {
31         int maxSlotUsed = -1;
32         bool used[SkYUVAInfo::kMaxPlanes] = {};
33         bool valid = true;
34         for (int i = 0; i < SkYUVAInfo::kYUVAChannelCount; ++i) {
35             if (locations[i].fPlane < 0) {
36                 if (i != SkYUVAInfo::YUVAChannels::kA) {
37                     valid = false;  // only the 'A' plane can be omitted
38                 }
39             } else if (locations[i].fPlane >= SkYUVAInfo::kMaxPlanes) {
40                 valid = false;  // A maximum of four input textures is allowed
41             } else {
42                 maxSlotUsed = std::max(locations[i].fPlane, maxSlotUsed);
43                 used[i] = true;
44             }
45         }
46 
47         // All the used slots should be packed starting at 0 with no gaps
48         for (int i = 0; i <= maxSlotUsed; ++i) {
49             if (!used[i]) {
50                 valid = false;
51             }
52         }
53 
54         if (numPlanes) {
55             *numPlanes = valid ? maxSlotUsed + 1 : 0;
56         }
57         return valid;
58     }
59 };
60 
61 #endif
62