Split SkYUVAInfo::PlanarConfig into PlaneConfig and Subsampling enums
Sometimes it's helpful to think about subsampling separately from
how the channels are spread across planes.
Bug: skia:10632
Change-Id: Ib03f71195f9706ef6def418b1f2125c29e0cf738
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/334102
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 59b06d5..848f86c 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -7,6 +7,10 @@
Milestone 88
------------
+ * SkYUVAInfo now has separate enums for division of channels among planes and
+ the subsampling. The previous combined enum, PlanarConfig, is deprecated.
+ https://review.skia.org/334102
+
* Simplified SkDeferredDisplayListRecorder promise image API. Removed "release"
callback and renamed "done" callback to "release". The new "release" proc can
be null. Added a new SkYUVAInfo-based factory for YUVA promise texture images
diff --git a/experimental/ffmpeg/SkVideoDecoder.cpp b/experimental/ffmpeg/SkVideoDecoder.cpp
index 2d46f66..f5b805a 100644
--- a/experimental/ffmpeg/SkVideoDecoder.cpp
+++ b/experimental/ffmpeg/SkVideoDecoder.cpp
@@ -166,7 +166,10 @@
int const strides[],
SkYUVColorSpace yuvSpace,
sk_sp<SkColorSpace> cs) {
- SkYUVAInfo yuvaInfo({w, h}, SkYUVAInfo::PlanarConfig::kY_U_V_420, yuvSpace);
+ SkYUVAInfo yuvaInfo({w, h},
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAInfo::Subsampling::k420,
+ yuvSpace);
SkPixmap pixmaps[3];
pixmaps[0].reset(SkImageInfo::MakeA8(w, h), data[0], strides[0]);
w = (w + 1)/2;
diff --git a/gm/asyncrescaleandread.cpp b/gm/asyncrescaleandread.cpp
index b4d55c9..32070e3 100644
--- a/gm/asyncrescaleandread.cpp
+++ b/gm/asyncrescaleandread.cpp
@@ -94,7 +94,10 @@
if (!asyncContext.fResult) {
return nullptr;
}
- SkYUVAInfo yuvaInfo(size, SkYUVAInfo::PlanarConfig::kY_U_V_420, yuvCS);
+ SkYUVAInfo yuvaInfo(size,
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAInfo::Subsampling::k420,
+ yuvCS);
SkPixmap yuvPMs[] = {
{yII, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0)},
{uvII, asyncContext.fResult->data(1), asyncContext.fResult->rowBytes(1)},
diff --git a/gm/imagefromyuvtextures.cpp b/gm/imagefromyuvtextures.cpp
index 2a50973..9eef57b 100644
--- a/gm/imagefromyuvtextures.cpp
+++ b/gm/imagefromyuvtextures.cpp
@@ -61,7 +61,8 @@
bmp = copy;
}
SkYUVAPixmapInfo pixmapInfo({bmp.dimensions(),
- SkYUVAInfo::PlanarConfig::kY_U_V_A_4204,
+ SkYUVAInfo::PlaneConfig::kY_U_V_A,
+ SkYUVAInfo::Subsampling::k420,
kJPEG_Full_SkYUVColorSpace},
SkYUVAPixmapInfo::DataType::kUnorm8,
nullptr);
diff --git a/gm/wacky_yuv_formats.cpp b/gm/wacky_yuv_formats.cpp
index 400378c..5993d5e 100644
--- a/gm/wacky_yuv_formats.cpp
+++ b/gm/wacky_yuv_formats.cpp
@@ -123,51 +123,63 @@
case kP016F_YUVFormat:
case kNV12_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_UV_420;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_UV;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_UV_A_4204;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_UV_A;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
}
break;
case kY416_YUVFormat:
case kY410_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kUYV_444;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kUYV;
+ fSubsampling = SkYUVAInfo::Subsampling::k444;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kUYVA_4444;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kUYVA;
+ fSubsampling = SkYUVAInfo::Subsampling::k444;
}
break;
case kAYUV_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kYUV_444;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kYUV;
+ fSubsampling = SkYUVAInfo::Subsampling::k444;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kYUVA_4444;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kYUVA;
+ fSubsampling = SkYUVAInfo::Subsampling::k444;
}
break;
case kNV21_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_VU_420;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_VU;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_VU_A_4204;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_VU_A;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
}
break;
case kI420_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_420;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_U_V;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_A_4204;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_U_V_A;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
}
break;
case kYV12_YUVFormat:
if (opaque) {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_V_U_420;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_V_U;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
} else {
- fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_V_U_A_4204;
+ fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_V_U_A;
+ fSubsampling = SkYUVAInfo::Subsampling::k420;
}
break;
}
}
- int numPlanes() const { return SkYUVAInfo::NumPlanes(fPlanarConfig); }
+ int numPlanes() const { return SkYUVAInfo::NumPlanes(fPlaneConfig); }
SkYUVAPixmaps makeYUVAPixmaps(SkISize dimensions,
SkYUVColorSpace yuvColorSpace,
@@ -175,14 +187,15 @@
int numBitmaps) const;
private:
- SkYUVAInfo::PlanarConfig fPlanarConfig;
+ SkYUVAInfo::PlaneConfig fPlaneConfig;
+ SkYUVAInfo::Subsampling fSubsampling;
};
SkYUVAPixmaps YUVAPlanarConfig::makeYUVAPixmaps(SkISize dimensions,
SkYUVColorSpace yuvColorSpace,
const SkBitmap bitmaps[],
int numBitmaps) const {
- SkYUVAInfo info(dimensions, fPlanarConfig, yuvColorSpace);
+ SkYUVAInfo info(dimensions, fPlaneConfig, fSubsampling, yuvColorSpace);
SkPixmap pmaps[SkYUVAInfo::kMaxPlanes];
int n = info.numPlanes();
if (numBitmaps < n) {
@@ -1198,7 +1211,10 @@
for (auto cs : {kRec709_SkYUVColorSpace, kRec601_SkYUVColorSpace, kJPEG_SkYUVColorSpace,
kBT2020_SkYUVColorSpace}) {
split_into_yuv(fOrig.get(), cs, fPM);
- SkYUVAInfo yuvaInfo(fOrig->dimensions(), SkYUVAInfo::PlanarConfig::kY_U_V_444, cs);
+ SkYUVAInfo yuvaInfo(fOrig->dimensions(),
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAInfo::Subsampling::k444,
+ cs);
auto yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, fPM);
auto img = SkImage::MakeFromYUVAPixmaps(canvas->recordingContext(),
yuvaPixmaps,
diff --git a/include/core/SkYUVAInfo.h b/include/core/SkYUVAInfo.h
index 0c0cb51..a87994b 100644
--- a/include/core/SkYUVAInfo.h
+++ b/include/core/SkYUVAInfo.h
@@ -13,6 +13,8 @@
#include "include/core/SkSize.h"
#include "include/core/SkYUVAIndex.h"
+#include <tuple>
+
/**
* Specifies the structure of planes for a YUV image with optional alpha. The actual planar data
* is not part of this structure and depending on usage is in external textures or pixmaps.
@@ -30,13 +32,63 @@
* RG 0:R, 1:G
* RGB 0:R, 1:G, 2:B
* RGBA 0:R, 1:G, 2:B, 3:A
+ */
+ enum class PlaneConfig {
+ kUnknown,
+
+ kY_U_V, ///< Plane 0: Y, Plane 1: U, Plane 2: V
+ kY_V_U, ///< Plane 0: Y, Plane 1: V, Plane 2: U
+ kY_UV, ///< Plane 0: Y, Plane 1: UV
+ kY_VU, ///< Plane 0: Y, Plane 1: VU
+ kYUV, ///< Plane 0: YUV
+ kUYV, ///< Plane 0: UYV
+
+ kY_U_V_A, ///< Plane 0: Y, Plane 1: U, Plane 2: V, Plane 3: A
+ kY_V_U_A, ///< Plane 0: Y, Plane 1: V, Plane 2: U, Plane 3: A
+ kY_UV_A, ///< Plane 0: Y, Plane 1: UV, Plane 2: A
+ kY_VU_A, ///< Plane 0: Y, Plane 1: VU, Plane 2: A
+ kYUVA, ///< Plane 0: YUVA
+ kUYVA, ///< Plane 0: UYVA
+
+ kLast = kUYVA
+ };
+
+ /**
+ * UV subsampling is also specified in the enum value names using J:a:b notation (e.g. 4:2:0 is
+ * 1/2 horizontal and 1/2 vertical resolution for U and V). If alpha is present it is not sub-
+ * sampled. Note that Subsampling values other than k444 are only valid with PlaneConfig values
+ * that have U and V in different planes than Y (and A, if present).
+ */
+ enum class Subsampling {
+ kUnknown,
+
+ k444, ///< No subsampling. UV values for each Y.
+ k422, ///< 1 set of UV values for each 2x1 block of Y values.
+ k420, ///< 1 set of UV values for each 2x2 block of Y values.
+ k440, ///< 1 set of UV values for each 1x2 block of Y values.
+ k411, ///< 1 set of UV values for each 4x1 block of Y values.
+ k410, ///< 1 set of UV values for each 4x2 block of Y values.
+
+ kLast = k410
+ };
+
+ /**
+ * Deprecated in favor of separate PlaneConfig and Subsampling enums.
+ *
+ * Specifies how YUV (and optionally A) are divided among planes. Planes are separated by
+ * underscores in the enum value names. Within each plane the pixmap/texture channels are
+ * mapped to the YUVA channels in the order specified, e.g. for kY_UV Y is in channel 0 of plane
+ * 0, U is in channel 0 of plane 1, and V is in channel 1 of plane 1. Channel ordering
+ * within a pixmap/texture given the channels it contains:
+ * A: 0:A
+ * Luminance/Gray: 0:Gray
+ * RG 0:R, 1:G
+ * RGB 0:R, 1:G, 2:B
+ * RGBA 0:R, 1:G, 2:B, 3:A
*
* UV subsampling is also specified in the enum value names using J:a:b notation (e.g. 4:2:0 is
* 1/2 horizontal and 1/2 vertical resolution for U and V). A fourth number is added if alpha
* is present (always 4 as only full resolution alpha is supported).
- *
- * Currently this only has three-plane formats but more will be added as usage and testing of
- * this expands.
*/
enum class PlanarConfig {
kUnknown,
@@ -65,6 +117,9 @@
kUYVA_4444, ///< Plane 0: UYVA
};
+ static constexpr std::tuple<PlaneConfig, Subsampling>
+ PlanarConfigToPlaneConfigAndSubsampling(PlanarConfig);
+
/**
* Describes how subsampled chroma values are sited relative to luma values.
*
@@ -80,37 +135,39 @@
static constexpr int kMaxPlanes = 4;
/**
- * Given image dimensions, a planar configuration, and origin, determine the expected size of
- * each plane. Returns the number of expected planes. planeDimensions[0] through
- * planeDimensons[<ret>] are written. The input image dimensions are as displayed (after the
- * planes have been transformed to the intended display orientation). The plane dimensions
- * are output as stored in memory.
+ * Given image dimensions, a planer configuration, subsampling, and origin, determine the
+ * expected size of each plane. Returns the number of expected planes. planeDimensions[0]
+ * through planeDimensions[<ret>] are written. The input image dimensions are as displayed
+ * (after the planes have been transformed to the intended display orientation). The plane
+ * dimensions are output as the planes are stored in memory (may be rotated from image
+ * dimensions).
*/
static int PlaneDimensions(SkISize imageDimensions,
- PlanarConfig,
+ PlaneConfig,
+ Subsampling ,
SkEncodedOrigin,
SkISize planeDimensions[kMaxPlanes]);
- /** Number of planes for a given PlanarConfig. */
- static constexpr int NumPlanes(PlanarConfig);
+ /** Number of planes for a given PlaneConfig. */
+ static constexpr int NumPlanes(PlaneConfig);
/**
- * Number of Y, U, V, A channels in the ith plane for a given PlanarConfig (or 0 if i is
+ * Number of Y, U, V, A channels in the ith plane for a given PlaneConfig (or 0 if i is
* invalid).
*/
- static constexpr int NumChannelsInPlane(PlanarConfig, int i);
+ static constexpr int NumChannelsInPlane(PlaneConfig, int i);
/**
- * Given a PlanarConfig and a set of channel flags for each plane, convert to SkYUVAIndex
- * representation. Fails if channel flags aren't valid for the PlanarConfig (i.e. don't have
+ * Given a PlaneConfig and a set of channel flags for each plane, convert to SkYUVAIndex
+ * representation. Fails if channel flags aren't valid for the PlaneConfig (i.e. don't have
* enough channels in a plane).
*/
- static bool GetYUVAIndices(PlanarConfig,
+ static bool GetYUVAIndices(PlaneConfig,
const uint32_t planeChannelFlags[kMaxPlanes],
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]);
- /** Does the PlanarConfig have alpha values? */
- static bool HasAlpha(PlanarConfig);
+ /** Does the PlaneConfig have alpha values? */
+ static bool HasAlpha(PlaneConfig);
SkYUVAInfo() = default;
SkYUVAInfo(const SkYUVAInfo&) = default;
@@ -120,6 +177,20 @@
* oriented to how the image is displayed as indicated by 'origin').
*/
SkYUVAInfo(SkISize dimensions,
+ PlaneConfig,
+ Subsampling,
+ SkYUVColorSpace,
+ SkEncodedOrigin origin = kTopLeft_SkEncodedOrigin,
+ Siting sitingX = Siting::kCentered,
+ Siting sitingY = Siting::kCentered);
+
+ /**
+ * Deprecated in favor of constructor that takes PlaneConfig and Subsampling.
+ *
+ * 'dimensions' should specify the size of the full resolution image (after planes have been
+ * oriented to how the image is displayed as indicated by 'origin').
+ */
+ SkYUVAInfo(SkISize dimensions,
PlanarConfig,
SkYUVColorSpace,
SkEncodedOrigin origin = kTopLeft_SkEncodedOrigin,
@@ -128,7 +199,14 @@
SkYUVAInfo& operator=(const SkYUVAInfo& that) = default;
- PlanarConfig planarConfig() const { return fPlanarConfig; }
+ PlaneConfig planeConfig() const { return fPlaneConfig; }
+ Subsampling subsampling() const { return fSubsampling; }
+
+ /**
+ * Deprecated. May return kUnknown even if this is valid because not all valid PlaneConfig/
+ * Subsampling pairs have am equivalent PlanarConfig value.
+ */
+ PlanarConfig planarConfig() const;
/**
* Dimensions of the full resolution image (after planes have been oriented to how the image
@@ -144,7 +222,7 @@
SkEncodedOrigin origin() const { return fOrigin; }
- bool hasAlpha() const { return HasAlpha(fPlanarConfig); }
+ bool hasAlpha() const { return HasAlpha(fPlaneConfig); }
/**
* Returns the number of planes and initializes planeDimensions[0]..planeDimensions[<ret>] to
@@ -152,7 +230,7 @@
* transformation to image display space as indicated by origin().
*/
int planeDimensions(SkISize planeDimensions[kMaxPlanes]) const {
- return PlaneDimensions(fDimensions, fPlanarConfig, fOrigin, planeDimensions);
+ return PlaneDimensions(fDimensions, fPlaneConfig, fSubsampling, fOrigin, planeDimensions);
}
/**
@@ -163,28 +241,29 @@
size_t computeTotalBytes(const size_t rowBytes[kMaxPlanes],
size_t planeSizes[kMaxPlanes] = nullptr) const;
- int numPlanes() const { return NumPlanes(fPlanarConfig); }
+ int numPlanes() const { return NumPlanes(fPlaneConfig); }
- int numChannelsInPlane(int i) const { return NumChannelsInPlane(fPlanarConfig, i); }
+ int numChannelsInPlane(int i) const { return NumChannelsInPlane(fPlaneConfig, i); }
/**
* Given a set of channel flags for each plane, converts this->planarConfig() to SkYUVAIndex
- * representation. Fails if the channel flags aren't valid for the PlanarConfig (i.e. don't have
+ * representation. Fails if the channel flags aren't valid for the PlaneConfig (i.e. don't have
* enough channels in a plane).
*/
bool toYUVAIndices(const uint32_t channelFlags[4], SkYUVAIndex indices[4]) const {
- return GetYUVAIndices(fPlanarConfig, channelFlags, indices);
+ return GetYUVAIndices(fPlaneConfig, channelFlags, indices);
}
bool operator==(const SkYUVAInfo& that) const;
bool operator!=(const SkYUVAInfo& that) const { return !(*this == that); }
- bool isValid() const { return fPlanarConfig != PlanarConfig::kUnknown; }
+ bool isValid() const { return fPlaneConfig != PlaneConfig::kUnknown; }
private:
SkISize fDimensions = {0, 0};
- PlanarConfig fPlanarConfig = PlanarConfig::kUnknown;
+ PlaneConfig fPlaneConfig = PlaneConfig::kUnknown;
+ Subsampling fSubsampling = Subsampling::kUnknown;
SkYUVColorSpace fYUVColorSpace = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
@@ -198,74 +277,87 @@
Siting fSitingY = Siting::kCentered;
};
-constexpr int SkYUVAInfo::NumPlanes(PlanarConfig planarConfig) {
- switch (planarConfig) {
- case PlanarConfig::kUnknown: return 0;
-
- case PlanarConfig::kY_U_V_444: return 3;
- case PlanarConfig::kY_U_V_422: return 3;
- case PlanarConfig::kY_U_V_420: return 3;
- case PlanarConfig::kY_V_U_420: return 3;
- case PlanarConfig::kY_U_V_440: return 3;
- case PlanarConfig::kY_U_V_411: return 3;
- case PlanarConfig::kY_U_V_410: return 3;
-
- case PlanarConfig::kY_U_V_A_4204: return 4;
- case PlanarConfig::kY_V_U_A_4204: return 4;
-
- case PlanarConfig::kY_UV_420: return 2;
- case PlanarConfig::kY_VU_420: return 2;
-
- case PlanarConfig::kY_UV_A_4204: return 3;
- case PlanarConfig::kY_VU_A_4204: return 3;
-
- case PlanarConfig::kYUV_444: return 1;
- case PlanarConfig::kUYV_444: return 1;
- case PlanarConfig::kYUVA_4444: return 1;
- case PlanarConfig::kUYVA_4444: return 1;
+constexpr int SkYUVAInfo::NumPlanes(PlaneConfig planeConfig) {
+ switch (planeConfig) {
+ case PlaneConfig::kUnknown: return 0;
+ case PlaneConfig::kY_U_V: return 3;
+ case PlaneConfig::kY_V_U: return 3;
+ case PlaneConfig::kY_UV: return 2;
+ case PlaneConfig::kY_VU: return 2;
+ case PlaneConfig::kYUV: return 1;
+ case PlaneConfig::kUYV: return 1;
+ case PlaneConfig::kY_U_V_A: return 4;
+ case PlaneConfig::kY_V_U_A: return 4;
+ case PlaneConfig::kY_UV_A: return 3;
+ case PlaneConfig::kY_VU_A: return 3;
+ case PlaneConfig::kYUVA: return 1;
+ case PlaneConfig::kUYVA: return 1;
}
SkUNREACHABLE;
}
-constexpr int SkYUVAInfo::NumChannelsInPlane(PlanarConfig config, int i) {
+constexpr int SkYUVAInfo::NumChannelsInPlane(PlaneConfig config, int i) {
switch (config) {
- case PlanarConfig::kUnknown:
+ case PlaneConfig::kUnknown:
return 0;
- case SkYUVAInfo::PlanarConfig::kY_U_V_444:
- case SkYUVAInfo::PlanarConfig::kY_U_V_422:
- case SkYUVAInfo::PlanarConfig::kY_U_V_420:
- case SkYUVAInfo::PlanarConfig::kY_V_U_420:
- case SkYUVAInfo::PlanarConfig::kY_U_V_440:
- case SkYUVAInfo::PlanarConfig::kY_U_V_411:
- case SkYUVAInfo::PlanarConfig::kY_U_V_410:
+ case SkYUVAInfo::PlaneConfig::kY_U_V:
+ case SkYUVAInfo::PlaneConfig::kY_V_U:
return i >= 0 && i < 3 ? 1 : 0;
- case SkYUVAInfo::PlanarConfig::kY_U_V_A_4204:
- case SkYUVAInfo::PlanarConfig::kY_V_U_A_4204:
- return i >= 0 && i < 4 ? 1 : 0;
- case SkYUVAInfo::PlanarConfig::kY_UV_420:
- case SkYUVAInfo::PlanarConfig::kY_VU_420:
+ case SkYUVAInfo::PlaneConfig::kY_UV:
+ case SkYUVAInfo::PlaneConfig::kY_VU:
switch (i) {
case 0: return 1;
case 1: return 2;
default: return 0;
}
- case SkYUVAInfo::PlanarConfig::kY_UV_A_4204:
- case SkYUVAInfo::PlanarConfig::kY_VU_A_4204:
+ case SkYUVAInfo::PlaneConfig::kYUV:
+ case SkYUVAInfo::PlaneConfig::kUYV:
+ return i == 0 ? 3 : 0;
+ case SkYUVAInfo::PlaneConfig::kY_U_V_A:
+ case SkYUVAInfo::PlaneConfig::kY_V_U_A:
+ return i >= 0 && i < 4 ? 1 : 0;
+ case SkYUVAInfo::PlaneConfig::kY_UV_A:
+ case SkYUVAInfo::PlaneConfig::kY_VU_A:
switch (i) {
case 0: return 1;
case 1: return 2;
case 2: return 1;
default: return 0;
}
- case SkYUVAInfo::PlanarConfig::kYUV_444:
- case SkYUVAInfo::PlanarConfig::kUYV_444:
- return i == 0 ? 3 : 0;
- case SkYUVAInfo::PlanarConfig::kYUVA_4444:
- case SkYUVAInfo::PlanarConfig::kUYVA_4444:
+ case SkYUVAInfo::PlaneConfig::kYUVA:
+ case SkYUVAInfo::PlaneConfig::kUYVA:
return i == 0 ? 4 : 0;
}
return 0;
}
+constexpr std::tuple<SkYUVAInfo::PlaneConfig, SkYUVAInfo::Subsampling>
+SkYUVAInfo::PlanarConfigToPlaneConfigAndSubsampling(PlanarConfig planarConfig) {
+ switch (planarConfig) {
+ case PlanarConfig::kUnknown:
+ return {PlaneConfig::kUnknown, Subsampling ::kUnknown};
+
+ case PlanarConfig::kY_U_V_444: return {PlaneConfig::kY_U_V, Subsampling::k444};
+ case PlanarConfig::kY_U_V_422: return {PlaneConfig::kY_U_V, Subsampling::k422};
+ case PlanarConfig::kY_U_V_420: return {PlaneConfig::kY_U_V, Subsampling::k420};
+ case PlanarConfig::kY_V_U_420: return {PlaneConfig::kY_V_U, Subsampling::k420};
+ case PlanarConfig::kY_U_V_440: return {PlaneConfig::kY_U_V, Subsampling::k440};
+ case PlanarConfig::kY_U_V_411: return {PlaneConfig::kY_U_V, Subsampling::k411};
+ case PlanarConfig::kY_U_V_410: return {PlaneConfig::kY_U_V, Subsampling::k410};
+ case PlanarConfig::kY_U_V_A_4204: return {PlaneConfig::kY_U_V_A, Subsampling::k420};
+ case PlanarConfig::kY_V_U_A_4204: return {PlaneConfig::kY_V_U_A, Subsampling::k420};
+ case PlanarConfig::kY_UV_420: return {PlaneConfig::kY_UV, Subsampling::k420};
+ case PlanarConfig::kY_VU_420: return {PlaneConfig::kY_VU, Subsampling::k420};
+ case PlanarConfig::kY_UV_A_4204: return {PlaneConfig::kY_UV_A, Subsampling::k420};
+ case PlanarConfig::kY_VU_A_4204: return {PlaneConfig::kY_VU_A, Subsampling::k420};
+ case PlanarConfig::kYUV_444: return {PlaneConfig::kYUV, Subsampling::k444};
+ case PlanarConfig::kUYV_444: return {PlaneConfig::kUYV, Subsampling::k444};
+ case PlanarConfig::kYUVA_4444: return {PlaneConfig::kYUVA, Subsampling::k444};
+ case PlanarConfig::kUYVA_4444: return {PlaneConfig::kUYVA, Subsampling::k444};
+ }
+ SkUNREACHABLE;
+}
+
+
#endif
diff --git a/include/core/SkYUVAPixmaps.h b/include/core/SkYUVAPixmaps.h
index bf0950b..b4d04ac 100644
--- a/include/core/SkYUVAPixmaps.h
+++ b/include/core/SkYUVAPixmaps.h
@@ -29,6 +29,8 @@
public:
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
+ using PlaneConfig = SkYUVAInfo::PlaneConfig;
+ using Subsampling = SkYUVAInfo::Subsampling;
using PlanarConfig = SkYUVAInfo::PlanarConfig;
/**
@@ -53,13 +55,16 @@
/** Init based on texture formats supported by the context. */
SupportedDataTypes(const GrImageContext&);
- /** All legal combinations of PlanarConfig and DataType are supported. */
+ /** All legal combinations of PlaneConfig and DataType are supported. */
static constexpr SupportedDataTypes All();
/**
* Checks whether there is a supported combination of color types for planes structured
- * as indicated by PlanarConfig with channel data types as indicated by DataType.
+ * as indicated by PlaneConfig with channel data types as indicated by DataType.
*/
+ constexpr bool supported(PlaneConfig, DataType) const;
+
+ /** Deprecated. Use PlaneConfig version. */
constexpr bool supported(PlanarConfig, DataType) const;
/**
@@ -152,7 +157,7 @@
* Returns true if this has been configured with a non-empty dimensioned SkYUVAInfo with
* compatible color types and row bytes.
*/
- bool isValid() const { return fPlaneInfos[0].colorType() != kUnknown_SkColorType; }
+ bool isValid() const { return fYUVAInfo.isValid(); }
/** Is this valid and does it use color types allowed by the passed SupportedDataTypes? */
bool isSupported(const SupportedDataTypes&) const;
@@ -281,7 +286,7 @@
return combinations;
}
-constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlanarConfig config,
+constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlaneConfig config,
DataType type) const {
int n = SkYUVAInfo::NumPlanes(config);
for (int i = 0; i < n; ++i) {
@@ -295,6 +300,12 @@
return true;
}
+constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlanarConfig planarConfig,
+ DataType type) const {
+ auto pc = std::get<0>(SkYUVAInfo::PlanarConfigToPlaneConfigAndSubsampling(planarConfig));
+ return this->supported(pc, type);
+}
+
constexpr SkColorType SkYUVAPixmapInfo::DefaultColorTypeForDataType(DataType dataType,
int numChannels) {
switch (numChannels) {
diff --git a/include/gpu/GrYUVABackendTextures.h b/include/gpu/GrYUVABackendTextures.h
index da230e7..2acf043 100644
--- a/include/gpu/GrYUVABackendTextures.h
+++ b/include/gpu/GrYUVABackendTextures.h
@@ -23,8 +23,6 @@
public:
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
- using PlanarConfig = SkYUVAInfo::PlanarConfig;
-
/** Default GrYUVABackendTextureInfo is invalid. */
GrYUVABackendTextureInfo() = default;
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index d7b3974..6c5a28c 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -796,24 +796,25 @@
SkASSERT(hSampY == dinfo->max_h_samp_factor);
SkASSERT(vSampY == dinfo->max_v_samp_factor);
- SkYUVAInfo::PlanarConfig tempPlanarConfig;
+ SkYUVAInfo::Subsampling tempSubsampling;
if (1 == hSampY && 1 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_444;
+ tempSubsampling = SkYUVAInfo::Subsampling::k444;
} else if (2 == hSampY && 1 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_422;
+ tempSubsampling = SkYUVAInfo::Subsampling::k422;
} else if (2 == hSampY && 2 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_420;
+ tempSubsampling = SkYUVAInfo::Subsampling::k420;
} else if (1 == hSampY && 2 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_440;
+ tempSubsampling = SkYUVAInfo::Subsampling::k440;
} else if (4 == hSampY && 1 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_411;
+ tempSubsampling = SkYUVAInfo::Subsampling::k411;
} else if (4 == hSampY && 2 == vSampY) {
- tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_410;
+ tempSubsampling = SkYUVAInfo::Subsampling::k410;
} else {
return false;
}
if (supportedDataTypes &&
- !supportedDataTypes->supported(tempPlanarConfig, SkYUVAPixmapInfo::DataType::kUnorm8)) {
+ !supportedDataTypes->supported(SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAPixmapInfo::DataType::kUnorm8)) {
return false;
}
if (yuvaPixmapInfo) {
@@ -824,7 +825,8 @@
rowBytes[i] = dinfo->comp_info[i].width_in_blocks * DCTSIZE;
}
SkYUVAInfo yuvaInfo(codec.dimensions(),
- tempPlanarConfig,
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ tempSubsampling,
kJPEG_Full_SkYUVColorSpace,
codec.getOrigin(),
SkYUVAInfo::Siting::kCentered,
diff --git a/src/core/SkYUVAInfo.cpp b/src/core/SkYUVAInfo.cpp
index c504f69..a7fb245 100644
--- a/src/core/SkYUVAInfo.cpp
+++ b/src/core/SkYUVAInfo.cpp
@@ -8,10 +8,31 @@
#include "include/core/SkYUVAInfo.h"
#include "src/core/SkSafeMath.h"
+#include <algorithm>
+
+static bool is_plane_config_compatible_with_subsampling(SkYUVAInfo::PlaneConfig config,
+ SkYUVAInfo::Subsampling subsampling) {
+ if (config == SkYUVAInfo::PlaneConfig::kUnknown ||
+ subsampling == SkYUVAInfo::Subsampling::kUnknown) {
+ return false;
+ }
+ return subsampling == SkYUVAInfo::Subsampling::k444 ||
+ (config != SkYUVAInfo::PlaneConfig::kYUV &&
+ config != SkYUVAInfo::PlaneConfig::kYUVA &&
+ config != SkYUVAInfo::PlaneConfig::kUYV &&
+ config != SkYUVAInfo::PlaneConfig::kUYVA);
+}
+
int SkYUVAInfo::PlaneDimensions(SkISize imageDimensions,
- PlanarConfig planarConfig,
+ PlaneConfig planeConfig,
+ Subsampling subsampling,
SkEncodedOrigin origin,
SkISize planeDimensions[SkYUVAInfo::kMaxPlanes]) {
+ std::fill_n(planeDimensions, SkYUVAInfo::kMaxPlanes, SkISize{0, 0});
+ if (!is_plane_config_compatible_with_subsampling(planeConfig, subsampling)) {
+ return 0;
+ }
+
int w = imageDimensions.width();
int h = imageDimensions.height();
if (origin >= kLeftTop_SkEncodedOrigin) {
@@ -20,66 +41,50 @@
}
auto down2 = [](int x) { return (x + 1)/2; };
auto down4 = [](int x) { return (x + 3)/4; };
- switch (planarConfig) {
- case PlanarConfig::kUnknown:
- planeDimensions[0] =
- planeDimensions[1] =
- planeDimensions[2] =
- planeDimensions[3] = {0, 0};
- return 0;
- case PlanarConfig::kY_U_V_444:
- planeDimensions[0] = planeDimensions[1] = planeDimensions[2] = {w, h};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_U_V_422:
+ SkISize uvSize;
+ switch (subsampling) {
+ case Subsampling::kUnknown: SkUNREACHABLE;
+
+ case Subsampling::k444: uvSize = { w , h }; break;
+ case Subsampling::k422: uvSize = {down2(w), h }; break;
+ case Subsampling::k420: uvSize = {down2(w), down2(h)}; break;
+ case Subsampling::k440: uvSize = { w , down2(h)}; break;
+ case Subsampling::k411: uvSize = {down4(w), h }; break;
+ case Subsampling::k410: uvSize = {down4(w), down2(h)}; break;
+ }
+ switch (planeConfig) {
+ case PlaneConfig::kUnknown: SkUNREACHABLE;
+
+ case PlaneConfig::kY_U_V:
+ case PlaneConfig::kY_V_U:
planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {down2(w), h};
- planeDimensions[3] = {0, 0};
+ planeDimensions[1] = planeDimensions[2] = uvSize;
return 3;
- case PlanarConfig::kY_U_V_420:
- case PlanarConfig::kY_V_U_420:
+
+ case PlaneConfig::kY_UV:
+ case PlaneConfig::kY_VU:
planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {down2(w), down2(h)};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_UV_A_4204:
- case PlanarConfig::kY_VU_A_4204:
- planeDimensions[0] = planeDimensions[2] = {w, h};
- planeDimensions[1] = {down2(w), down2(h)};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_U_V_440:
- planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {w, down2(h)};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_U_V_411:
- planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {down4(w), h};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_U_V_410:
- planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {down4(w), down2(h)};
- planeDimensions[3] = {0, 0};
- return 3;
- case PlanarConfig::kY_U_V_A_4204:
- case PlanarConfig::kY_V_U_A_4204:
- planeDimensions[0] = planeDimensions[3] = {w, h};
- planeDimensions[1] = planeDimensions[2] = {down2(w), down2(h)};
- return 4;
- case PlanarConfig::kY_UV_420:
- case PlanarConfig::kY_VU_420:
- planeDimensions[0] = {w, h};
- planeDimensions[1] = {down2(w), down2(h)};
- planeDimensions[2] = planeDimensions[3] = {0, 0};
+ planeDimensions[1] = uvSize;
return 2;
- case PlanarConfig::kYUV_444:
- case PlanarConfig::kUYV_444:
- case PlanarConfig::kYUVA_4444:
- case PlanarConfig::kUYVA_4444:
+
+ case PlaneConfig::kY_U_V_A:
+ case PlaneConfig::kY_V_U_A:
+ planeDimensions[0] = planeDimensions[3] = {w, h};
+ planeDimensions[1] = planeDimensions[2] = uvSize;
+ return 4;
+
+ case PlaneConfig::kY_UV_A:
+ case PlaneConfig::kY_VU_A:
+ planeDimensions[0] = planeDimensions[2] = {w, h};
+ planeDimensions[1] = uvSize;
+ return 3;
+
+ case PlaneConfig::kYUV:
+ case PlaneConfig::kUYV:
+ case PlaneConfig::kYUVA:
+ case PlaneConfig::kUYVA:
planeDimensions[0] = {w, h};
- planeDimensions[1] = planeDimensions[2] = planeDimensions[3] = {0, 0};
+ SkASSERT(planeDimensions[0] == uvSize);
return 1;
}
SkUNREACHABLE;
@@ -125,76 +130,71 @@
}
}
-bool SkYUVAInfo::GetYUVAIndices(PlanarConfig config,
+bool SkYUVAInfo::GetYUVAIndices(PlaneConfig config,
const uint32_t planeChannelFlags[kMaxPlanes],
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) {
struct Location {int plane, chanIdx;};
const Location* locations = nullptr;
switch (config) {
- case PlanarConfig::kUnknown:
+ case PlaneConfig::kUnknown:
return false;
- case PlanarConfig::kY_U_V_444:
- case PlanarConfig::kY_U_V_422:
- case PlanarConfig::kY_U_V_420:
- case PlanarConfig::kY_U_V_440:
- case PlanarConfig::kY_U_V_411:
- case PlanarConfig::kY_U_V_410: {
+ case PlaneConfig::kY_U_V: {
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {2, 0}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kY_V_U_420: {
+ case PlaneConfig::kY_V_U: {
static constexpr Location kLocations[] = {{0, 0}, {2, 0}, {1, 0}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kY_U_V_A_4204: {
- static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
- locations = kLocations;
- break;
- }
- case PlanarConfig::kY_V_U_A_4204: {
- static constexpr Location kLocations[] = {{0, 0}, {2, 0}, {1, 0}, {3, 0}};
- locations = kLocations;
- break;
- }
- case PlanarConfig::kY_UV_420: {
+ case PlaneConfig::kY_UV: {
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {1, 1}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kY_VU_420: {
+ case PlaneConfig::kY_VU: {
static constexpr Location kLocations[] = {{0, 0}, {1, 1}, {1, 0}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kY_UV_A_4204: {
- static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}};
- locations = kLocations;
- break;
- }
- case PlanarConfig::kY_VU_A_4204: {
- static constexpr Location kLocations[] = {{0, 0}, {1, 1}, {1, 0}, {2, 0}};
- locations = kLocations;
- break;
- }
- case PlanarConfig::kYUV_444: {
+ case PlaneConfig::kYUV: {
static constexpr Location kLocations[] = {{0, 0}, {0, 1}, {0, 2}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kUYV_444: {
+ case PlaneConfig::kUYV: {
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {-1, -1}};
locations = kLocations;
break;
}
- case PlanarConfig::kYUVA_4444: {
+ case PlaneConfig::kY_U_V_A: {
+ static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
+ locations = kLocations;
+ break;
+ }
+ case PlaneConfig::kY_V_U_A: {
+ static constexpr Location kLocations[] = {{0, 0}, {2, 0}, {1, 0}, {3, 0}};
+ locations = kLocations;
+ break;
+ }
+ case PlaneConfig::kY_UV_A: {
+ static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}};
+ locations = kLocations;
+ break;
+ }
+ case PlaneConfig::kY_VU_A: {
+ static constexpr Location kLocations[] = {{0, 0}, {1, 1}, {1, 0}, {2, 0}};
+ locations = kLocations;
+ break;
+ }
+ case PlaneConfig::kYUVA: {
static constexpr Location kLocations[] = {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
locations = kLocations;
break;
}
- case PlanarConfig::kUYVA_4444: {
+ case PlaneConfig::kUYVA: {
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {0, 3}};
locations = kLocations;
break;
@@ -217,56 +217,58 @@
return true;
}
-bool SkYUVAInfo::HasAlpha(PlanarConfig planarConfig) {
- switch (planarConfig) {
- case PlanarConfig::kUnknown: return false;
+bool SkYUVAInfo::HasAlpha(PlaneConfig planeConfig) {
+ switch (planeConfig) {
+ case PlaneConfig::kUnknown: return false;
- case PlanarConfig::kY_U_V_444: return false;
- case PlanarConfig::kY_U_V_422: return false;
- case PlanarConfig::kY_U_V_420: return false;
- case PlanarConfig::kY_V_U_420: return false;
- case PlanarConfig::kY_U_V_440: return false;
- case PlanarConfig::kY_U_V_411: return false;
- case PlanarConfig::kY_U_V_410: return false;
+ case PlaneConfig::kY_U_V: return false;
+ case PlaneConfig::kY_V_U: return false;
+ case PlaneConfig::kY_UV: return false;
+ case PlaneConfig::kY_VU: return false;
+ case PlaneConfig::kYUV: return false;
+ case PlaneConfig::kUYV: return false;
- case PlanarConfig::kY_U_V_A_4204: return true;
- case PlanarConfig::kY_V_U_A_4204: return true;
-
- case PlanarConfig::kY_UV_420: return false;
- case PlanarConfig::kY_VU_420: return false;
-
- case PlanarConfig::kY_UV_A_4204: return true;
- case PlanarConfig::kY_VU_A_4204: return true;
-
- case PlanarConfig::kYUV_444: return false;
- case PlanarConfig::kUYV_444: return false;
-
- case PlanarConfig::kYUVA_4444: return true;
- case PlanarConfig::kUYVA_4444: return true;
+ case PlaneConfig::kY_U_V_A: return true;
+ case PlaneConfig::kY_V_U_A: return true;
+ case PlaneConfig::kY_UV_A: return true;
+ case PlaneConfig::kY_VU_A: return true;
+ case PlaneConfig::kYUVA: return true;
+ case PlaneConfig::kUYVA: return true;
}
SkUNREACHABLE;
}
SkYUVAInfo::SkYUVAInfo(SkISize dimensions,
+ PlaneConfig planeConfig,
+ Subsampling subsampling,
+ SkYUVColorSpace yuvColorSpace,
+ SkEncodedOrigin origin,
+ Siting sitingX,
+ Siting sitingY)
+ : fDimensions(dimensions)
+ , fPlaneConfig(planeConfig)
+ , fSubsampling(subsampling)
+ , fYUVColorSpace(yuvColorSpace)
+ , fOrigin(origin)
+ , fSitingX(sitingX)
+ , fSitingY(sitingY) {
+ if (fDimensions.isEmpty() ||
+ !is_plane_config_compatible_with_subsampling(planeConfig, subsampling)) {
+ *this = {};
+ SkASSERT(!this->isValid());
+ return;
+ }
+ SkASSERT(this->isValid());
+}
+
+SkYUVAInfo::SkYUVAInfo(SkISize dimensions,
PlanarConfig planarConfig,
SkYUVColorSpace yuvColorSpace,
SkEncodedOrigin origin,
Siting sitingX,
- Siting sitingY)
- : fDimensions(dimensions)
- , fPlanarConfig(planarConfig)
- , fYUVColorSpace(yuvColorSpace)
- , fOrigin(origin)
- , fSitingX(sitingX)
- , fSitingY(sitingY) {
- if (fDimensions.width() <= 0 ||
- fDimensions.height() <= 0 ||
- planarConfig == PlanarConfig::kUnknown) {
- *this = {};
- SkASSERT(!this->isValid());
- return;
- }
- SkASSERT(this->isValid());
+ Siting sitingY) {
+ auto [c, s] = PlanarConfigToPlaneConfigAndSubsampling(planarConfig);
+ *this = SkYUVAInfo(dimensions, c, s, yuvColorSpace, origin, sitingX, sitingY);
}
size_t SkYUVAInfo::computeTotalBytes(const size_t rowBytes[kMaxPlanes],
@@ -302,8 +304,75 @@
return safe.ok() ? totalBytes : SIZE_MAX;
}
+SkYUVAInfo::PlanarConfig SkYUVAInfo::planarConfig() const {
+ SkASSERT(!this->isValid() || is_plane_config_compatible_with_subsampling(fPlaneConfig,
+ fSubsampling));
+ switch (fPlaneConfig) {
+ case PlaneConfig::kUnknown: return PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_U_V:
+ switch (fSubsampling) {
+ case Subsampling::kUnknown: SkUNREACHABLE;
+
+ case Subsampling::k444: return PlanarConfig::kY_U_V_444;
+ case Subsampling::k422: return PlanarConfig::kY_U_V_422;
+ case Subsampling::k420: return PlanarConfig::kY_U_V_420;
+ case Subsampling::k440: return PlanarConfig::kY_U_V_440;
+ case Subsampling::k411: return PlanarConfig::kY_U_V_411;
+ case Subsampling::k410: return PlanarConfig::kY_U_V_410;
+ }
+ SkUNREACHABLE;
+
+ case PlaneConfig::kY_V_U:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_V_U_420
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_UV:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_UV_420
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_VU:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_VU_420
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kYUV:
+ SkASSERT(fSubsampling == Subsampling::k444);
+ return PlanarConfig::kYUV_444;
+
+ case PlaneConfig::kUYV:
+ SkASSERT(fSubsampling == Subsampling::k444);
+ return PlanarConfig::kUYV_444;
+
+ case PlaneConfig::kY_U_V_A:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_U_V_A_4204
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_V_U_A:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_V_U_A_4204
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_UV_A:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_UV_A_4204
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kY_VU_A:
+ return fSubsampling == Subsampling::k420 ? PlanarConfig::kY_VU_A_4204
+ : PlanarConfig::kUnknown;
+
+ case PlaneConfig::kYUVA:
+ SkASSERT(fSubsampling == Subsampling::k444);
+ return PlanarConfig::kYUVA_4444;
+
+ case PlaneConfig::kUYVA:
+ SkASSERT(fSubsampling == Subsampling::k444);
+ return PlanarConfig::kUYVA_4444;
+ }
+ SkUNREACHABLE;
+}
+
bool SkYUVAInfo::operator==(const SkYUVAInfo& that) const {
- return fPlanarConfig == that.fPlanarConfig &&
+ return fPlaneConfig == that.fPlaneConfig &&
+ fSubsampling == that.fSubsampling &&
fYUVColorSpace == that.fYUVColorSpace &&
fDimensions == that.fDimensions &&
fSitingX == that.fSitingX &&
diff --git a/src/core/SkYUVAPixmaps.cpp b/src/core/SkYUVAPixmaps.cpp
index 36d1562..5ef1268 100644
--- a/src/core/SkYUVAPixmaps.cpp
+++ b/src/core/SkYUVAPixmaps.cpp
@@ -172,7 +172,7 @@
if (!this->isValid()) {
return false;
}
- return supportedDataTypes.supported(fYUVAInfo.planarConfig(), fDataType);
+ return supportedDataTypes.supported(fYUVAInfo.planeConfig(), fDataType);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/tests/ImageGeneratorTest.cpp b/tests/ImageGeneratorTest.cpp
index cd8526d..ddb0be2 100644
--- a/tests/ImageGeneratorTest.cpp
+++ b/tests/ImageGeneratorTest.cpp
@@ -67,7 +67,8 @@
// Check that the YUV decoding API does not cause any crashes
ig.queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo);
SkYUVAInfo yuvaInfo({250, 250},
- SkYUVAInfo::PlanarConfig::kY_UV_420,
+ SkYUVAInfo::PlaneConfig::kY_UV,
+ SkYUVAInfo::Subsampling::k420,
kJPEG_Full_SkYUVColorSpace);
yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo,
SkYUVAPixmapInfo::DataType::kUnorm8,
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index a77bd47..a42103f 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -1372,7 +1372,10 @@
static sk_sp<SkImage> make_yuva_image(GrDirectContext* dContext) {
SkAutoPixmapStorage pm;
pm.alloc(SkImageInfo::Make(1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType));
- SkYUVAInfo yuvaInfo({1, 1}, SkYUVAInfo::PlanarConfig::kY_U_V_444, kJPEG_Full_SkYUVColorSpace);
+ SkYUVAInfo yuvaInfo({1, 1},
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAInfo::Subsampling::k444,
+ kJPEG_Full_SkYUVColorSpace);
const SkPixmap pmaps[] = {pm, pm, pm};
auto yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, pmaps);
diff --git a/tests/YUVCacheTest.cpp b/tests/YUVCacheTest.cpp
index 95794f8..c8fb9dc 100644
--- a/tests/YUVCacheTest.cpp
+++ b/tests/YUVCacheTest.cpp
@@ -34,7 +34,8 @@
SkResourceCache cache(1024);
SkYUVAInfo yuvaInfo({5, 5},
- SkYUVAInfo::PlanarConfig::kY_U_V_420,
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ SkYUVAInfo::Subsampling::k420,
kRec601_Limited_SkYUVColorSpace);
SkYUVAPixmapInfo yuvaPixmapInfo(yuvaInfo,
SkYUVAPixmapInfo::DataType::kUnorm8,
diff --git a/tests/YUVTest.cpp b/tests/YUVTest.cpp
index 6c947d9..77203fd 100644
--- a/tests/YUVTest.cpp
+++ b/tests/YUVTest.cpp
@@ -82,39 +82,40 @@
}
DEF_TEST(Jpeg_YUV_Codec, r) {
- auto setExpectations = [](SkISize dims, SkYUVAInfo::PlanarConfig planarConfig) {
+ auto setExpectations = [](SkISize dims, SkYUVAInfo::Subsampling subsampling) {
return SkYUVAInfo(dims,
- planarConfig,
+ SkYUVAInfo::PlaneConfig::kY_U_V,
+ subsampling,
kJPEG_Full_SkYUVColorSpace,
kTopLeft_SkEncodedOrigin,
SkYUVAInfo::Siting::kCentered,
SkYUVAInfo::Siting::kCentered);
};
- SkYUVAInfo expectations = setExpectations({128, 128}, SkYUVAInfo::PlanarConfig::kY_U_V_420);
+ SkYUVAInfo expectations = setExpectations({128, 128}, SkYUVAInfo::Subsampling::k420);
codec_yuv(r, "images/color_wheel.jpg", &expectations);
// H2V2
- expectations = setExpectations({512, 512}, SkYUVAInfo::PlanarConfig::kY_U_V_420);
+ expectations = setExpectations({512, 512}, SkYUVAInfo::Subsampling::k420);
codec_yuv(r, "images/mandrill_512_q075.jpg", &expectations);
// H1V1
- expectations = setExpectations({512, 512}, SkYUVAInfo::PlanarConfig::kY_U_V_444);
+ expectations = setExpectations({512, 512}, SkYUVAInfo::Subsampling::k444);
codec_yuv(r, "images/mandrill_h1v1.jpg", &expectations);
// H2V1
- expectations = setExpectations({512, 512}, SkYUVAInfo::PlanarConfig::kY_U_V_422);
+ expectations = setExpectations({512, 512}, SkYUVAInfo::Subsampling::k422);
codec_yuv(r, "images/mandrill_h2v1.jpg", &expectations);
// Non-power of two dimensions
- expectations = setExpectations({439, 154}, SkYUVAInfo::PlanarConfig::kY_U_V_420);
+ expectations = setExpectations({439, 154}, SkYUVAInfo::Subsampling::k420);
codec_yuv(r, "images/cropped_mandrill.jpg", &expectations);
- expectations = setExpectations({8, 8}, SkYUVAInfo::PlanarConfig::kY_U_V_420);
+ expectations = setExpectations({8, 8}, SkYUVAInfo::Subsampling::k420);
codec_yuv(r, "images/randPixels.jpg", &expectations);
// Progressive images
- expectations = setExpectations({512, 512}, SkYUVAInfo::PlanarConfig::kY_U_V_444);
+ expectations = setExpectations({512, 512}, SkYUVAInfo::Subsampling::k444);
codec_yuv(r, "images/brickwork-texture.jpg", &expectations);
codec_yuv(r, "images/brickwork_normal-map.jpg", &expectations);