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>
This commit is contained in:
parent
70eba23828
commit
e4387382c2
@ -7,6 +7,10 @@ This file includes a list of high level updates for each milestone release.
|
|||||||
Milestone 88
|
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"
|
* Simplified SkDeferredDisplayListRecorder promise image API. Removed "release"
|
||||||
callback and renamed "done" callback to "release". The new "release" proc can
|
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
|
be null. Added a new SkYUVAInfo-based factory for YUVA promise texture images
|
||||||
|
@ -166,7 +166,10 @@ static sk_sp<SkImage> make_yuv_420(GrRecordingContext* rContext,
|
|||||||
int const strides[],
|
int const strides[],
|
||||||
SkYUVColorSpace yuvSpace,
|
SkYUVColorSpace yuvSpace,
|
||||||
sk_sp<SkColorSpace> cs) {
|
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];
|
SkPixmap pixmaps[3];
|
||||||
pixmaps[0].reset(SkImageInfo::MakeA8(w, h), data[0], strides[0]);
|
pixmaps[0].reset(SkImageInfo::MakeA8(w, h), data[0], strides[0]);
|
||||||
w = (w + 1)/2;
|
w = (w + 1)/2;
|
||||||
|
@ -94,7 +94,10 @@ static sk_sp<SkImage> do_read_and_scale_yuv(Src* src,
|
|||||||
if (!asyncContext.fResult) {
|
if (!asyncContext.fResult) {
|
||||||
return nullptr;
|
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[] = {
|
SkPixmap yuvPMs[] = {
|
||||||
{yII, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0)},
|
{yII, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0)},
|
||||||
{uvII, asyncContext.fResult->data(1), asyncContext.fResult->rowBytes(1)},
|
{uvII, asyncContext.fResult->data(1), asyncContext.fResult->rowBytes(1)},
|
||||||
|
@ -61,7 +61,8 @@ protected:
|
|||||||
bmp = copy;
|
bmp = copy;
|
||||||
}
|
}
|
||||||
SkYUVAPixmapInfo pixmapInfo({bmp.dimensions(),
|
SkYUVAPixmapInfo pixmapInfo({bmp.dimensions(),
|
||||||
SkYUVAInfo::PlanarConfig::kY_U_V_A_4204,
|
SkYUVAInfo::PlaneConfig::kY_U_V_A,
|
||||||
|
SkYUVAInfo::Subsampling::k420,
|
||||||
kJPEG_Full_SkYUVColorSpace},
|
kJPEG_Full_SkYUVColorSpace},
|
||||||
SkYUVAPixmapInfo::DataType::kUnorm8,
|
SkYUVAPixmapInfo::DataType::kUnorm8,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
@ -123,51 +123,63 @@ public:
|
|||||||
case kP016F_YUVFormat:
|
case kP016F_YUVFormat:
|
||||||
case kNV12_YUVFormat:
|
case kNV12_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_UV_420;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_UV;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_UV_A_4204;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_UV_A;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kY416_YUVFormat:
|
case kY416_YUVFormat:
|
||||||
case kY410_YUVFormat:
|
case kY410_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kUYV_444;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kUYV;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k444;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kUYVA_4444;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kUYVA;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k444;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kAYUV_YUVFormat:
|
case kAYUV_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kYUV_444;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kYUV;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k444;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kYUVA_4444;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kYUVA;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k444;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kNV21_YUVFormat:
|
case kNV21_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_VU_420;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_VU;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_VU_A_4204;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_VU_A;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kI420_YUVFormat:
|
case kI420_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_420;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_U_V;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_A_4204;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_U_V_A;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kYV12_YUVFormat:
|
case kYV12_YUVFormat:
|
||||||
if (opaque) {
|
if (opaque) {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_V_U_420;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_V_U;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
} else {
|
} else {
|
||||||
fPlanarConfig = SkYUVAInfo::PlanarConfig::kY_V_U_A_4204;
|
fPlaneConfig = SkYUVAInfo::PlaneConfig::kY_V_U_A;
|
||||||
|
fSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numPlanes() const { return SkYUVAInfo::NumPlanes(fPlanarConfig); }
|
int numPlanes() const { return SkYUVAInfo::NumPlanes(fPlaneConfig); }
|
||||||
|
|
||||||
SkYUVAPixmaps makeYUVAPixmaps(SkISize dimensions,
|
SkYUVAPixmaps makeYUVAPixmaps(SkISize dimensions,
|
||||||
SkYUVColorSpace yuvColorSpace,
|
SkYUVColorSpace yuvColorSpace,
|
||||||
@ -175,14 +187,15 @@ public:
|
|||||||
int numBitmaps) const;
|
int numBitmaps) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkYUVAInfo::PlanarConfig fPlanarConfig;
|
SkYUVAInfo::PlaneConfig fPlaneConfig;
|
||||||
|
SkYUVAInfo::Subsampling fSubsampling;
|
||||||
};
|
};
|
||||||
|
|
||||||
SkYUVAPixmaps YUVAPlanarConfig::makeYUVAPixmaps(SkISize dimensions,
|
SkYUVAPixmaps YUVAPlanarConfig::makeYUVAPixmaps(SkISize dimensions,
|
||||||
SkYUVColorSpace yuvColorSpace,
|
SkYUVColorSpace yuvColorSpace,
|
||||||
const SkBitmap bitmaps[],
|
const SkBitmap bitmaps[],
|
||||||
int numBitmaps) const {
|
int numBitmaps) const {
|
||||||
SkYUVAInfo info(dimensions, fPlanarConfig, yuvColorSpace);
|
SkYUVAInfo info(dimensions, fPlaneConfig, fSubsampling, yuvColorSpace);
|
||||||
SkPixmap pmaps[SkYUVAInfo::kMaxPlanes];
|
SkPixmap pmaps[SkYUVAInfo::kMaxPlanes];
|
||||||
int n = info.numPlanes();
|
int n = info.numPlanes();
|
||||||
if (numBitmaps < n) {
|
if (numBitmaps < n) {
|
||||||
@ -1198,7 +1211,10 @@ protected:
|
|||||||
for (auto cs : {kRec709_SkYUVColorSpace, kRec601_SkYUVColorSpace, kJPEG_SkYUVColorSpace,
|
for (auto cs : {kRec709_SkYUVColorSpace, kRec601_SkYUVColorSpace, kJPEG_SkYUVColorSpace,
|
||||||
kBT2020_SkYUVColorSpace}) {
|
kBT2020_SkYUVColorSpace}) {
|
||||||
split_into_yuv(fOrig.get(), cs, fPM);
|
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 yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, fPM);
|
||||||
auto img = SkImage::MakeFromYUVAPixmaps(canvas->recordingContext(),
|
auto img = SkImage::MakeFromYUVAPixmaps(canvas->recordingContext(),
|
||||||
yuvaPixmaps,
|
yuvaPixmaps,
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include "include/core/SkSize.h"
|
#include "include/core/SkSize.h"
|
||||||
#include "include/core/SkYUVAIndex.h"
|
#include "include/core/SkYUVAIndex.h"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the structure of planes for a YUV image with optional alpha. The actual planar data
|
* 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.
|
* is not part of this structure and depending on usage is in external textures or pixmaps.
|
||||||
@ -20,6 +22,59 @@
|
|||||||
class SK_API SkYUVAInfo {
|
class SK_API SkYUVAInfo {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
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
|
* 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
|
* 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
|
* mapped to the YUVA channels in the order specified, e.g. for kY_UV Y is in channel 0 of plane
|
||||||
@ -34,9 +89,6 @@ public:
|
|||||||
* UV subsampling is also specified in the enum value names using J:a:b notation (e.g. 4:2:0 is
|
* 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
|
* 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).
|
* 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 {
|
enum class PlanarConfig {
|
||||||
kUnknown,
|
kUnknown,
|
||||||
@ -65,6 +117,9 @@ public:
|
|||||||
kUYVA_4444, ///< Plane 0: UYVA
|
kUYVA_4444, ///< Plane 0: UYVA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr std::tuple<PlaneConfig, Subsampling>
|
||||||
|
PlanarConfigToPlaneConfigAndSubsampling(PlanarConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes how subsampled chroma values are sited relative to luma values.
|
* Describes how subsampled chroma values are sited relative to luma values.
|
||||||
*
|
*
|
||||||
@ -80,37 +135,39 @@ public:
|
|||||||
static constexpr int kMaxPlanes = 4;
|
static constexpr int kMaxPlanes = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given image dimensions, a planar configuration, and origin, determine the expected size of
|
* Given image dimensions, a planer configuration, subsampling, and origin, determine the
|
||||||
* each plane. Returns the number of expected planes. planeDimensions[0] through
|
* expected size of each plane. Returns the number of expected planes. planeDimensions[0]
|
||||||
* planeDimensons[<ret>] are written. The input image dimensions are as displayed (after the
|
* through planeDimensions[<ret>] are written. The input image dimensions are as displayed
|
||||||
* planes have been transformed to the intended display orientation). The plane dimensions
|
* (after the planes have been transformed to the intended display orientation). The plane
|
||||||
* are output as stored in memory.
|
* dimensions are output as the planes are stored in memory (may be rotated from image
|
||||||
|
* dimensions).
|
||||||
*/
|
*/
|
||||||
static int PlaneDimensions(SkISize imageDimensions,
|
static int PlaneDimensions(SkISize imageDimensions,
|
||||||
PlanarConfig,
|
PlaneConfig,
|
||||||
|
Subsampling ,
|
||||||
SkEncodedOrigin,
|
SkEncodedOrigin,
|
||||||
SkISize planeDimensions[kMaxPlanes]);
|
SkISize planeDimensions[kMaxPlanes]);
|
||||||
|
|
||||||
/** Number of planes for a given PlanarConfig. */
|
/** Number of planes for a given PlaneConfig. */
|
||||||
static constexpr int NumPlanes(PlanarConfig);
|
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).
|
* 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
|
* 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 PlanarConfig (i.e. don't have
|
* representation. Fails if channel flags aren't valid for the PlaneConfig (i.e. don't have
|
||||||
* enough channels in a plane).
|
* enough channels in a plane).
|
||||||
*/
|
*/
|
||||||
static bool GetYUVAIndices(PlanarConfig,
|
static bool GetYUVAIndices(PlaneConfig,
|
||||||
const uint32_t planeChannelFlags[kMaxPlanes],
|
const uint32_t planeChannelFlags[kMaxPlanes],
|
||||||
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]);
|
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]);
|
||||||
|
|
||||||
/** Does the PlanarConfig have alpha values? */
|
/** Does the PlaneConfig have alpha values? */
|
||||||
static bool HasAlpha(PlanarConfig);
|
static bool HasAlpha(PlaneConfig);
|
||||||
|
|
||||||
SkYUVAInfo() = default;
|
SkYUVAInfo() = default;
|
||||||
SkYUVAInfo(const SkYUVAInfo&) = default;
|
SkYUVAInfo(const SkYUVAInfo&) = default;
|
||||||
@ -119,6 +176,20 @@ public:
|
|||||||
* 'dimensions' should specify the size of the full resolution image (after planes have been
|
* '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').
|
* 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,
|
SkYUVAInfo(SkISize dimensions,
|
||||||
PlanarConfig,
|
PlanarConfig,
|
||||||
SkYUVColorSpace,
|
SkYUVColorSpace,
|
||||||
@ -128,7 +199,14 @@ public:
|
|||||||
|
|
||||||
SkYUVAInfo& operator=(const SkYUVAInfo& that) = default;
|
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
|
* Dimensions of the full resolution image (after planes have been oriented to how the image
|
||||||
@ -144,7 +222,7 @@ public:
|
|||||||
|
|
||||||
SkEncodedOrigin origin() const { return fOrigin; }
|
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
|
* Returns the number of planes and initializes planeDimensions[0]..planeDimensions[<ret>] to
|
||||||
@ -152,7 +230,7 @@ public:
|
|||||||
* transformation to image display space as indicated by origin().
|
* transformation to image display space as indicated by origin().
|
||||||
*/
|
*/
|
||||||
int planeDimensions(SkISize planeDimensions[kMaxPlanes]) const {
|
int planeDimensions(SkISize planeDimensions[kMaxPlanes]) const {
|
||||||
return PlaneDimensions(fDimensions, fPlanarConfig, fOrigin, planeDimensions);
|
return PlaneDimensions(fDimensions, fPlaneConfig, fSubsampling, fOrigin, planeDimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,28 +241,29 @@ public:
|
|||||||
size_t computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
size_t computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
||||||
size_t planeSizes[kMaxPlanes] = nullptr) const;
|
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
|
* 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).
|
* enough channels in a plane).
|
||||||
*/
|
*/
|
||||||
bool toYUVAIndices(const uint32_t channelFlags[4], SkYUVAIndex indices[4]) const {
|
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;
|
||||||
bool operator!=(const SkYUVAInfo& that) const { return !(*this == that); }
|
bool operator!=(const SkYUVAInfo& that) const { return !(*this == that); }
|
||||||
|
|
||||||
bool isValid() const { return fPlanarConfig != PlanarConfig::kUnknown; }
|
bool isValid() const { return fPlaneConfig != PlaneConfig::kUnknown; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkISize fDimensions = {0, 0};
|
SkISize fDimensions = {0, 0};
|
||||||
|
|
||||||
PlanarConfig fPlanarConfig = PlanarConfig::kUnknown;
|
PlaneConfig fPlaneConfig = PlaneConfig::kUnknown;
|
||||||
|
Subsampling fSubsampling = Subsampling::kUnknown;
|
||||||
|
|
||||||
SkYUVColorSpace fYUVColorSpace = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
|
SkYUVColorSpace fYUVColorSpace = SkYUVColorSpace::kIdentity_SkYUVColorSpace;
|
||||||
|
|
||||||
@ -198,74 +277,87 @@ private:
|
|||||||
Siting fSitingY = Siting::kCentered;
|
Siting fSitingY = Siting::kCentered;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int SkYUVAInfo::NumPlanes(PlanarConfig planarConfig) {
|
constexpr int SkYUVAInfo::NumPlanes(PlaneConfig planeConfig) {
|
||||||
switch (planarConfig) {
|
switch (planeConfig) {
|
||||||
case PlanarConfig::kUnknown: return 0;
|
case PlaneConfig::kUnknown: return 0;
|
||||||
|
case PlaneConfig::kY_U_V: return 3;
|
||||||
case PlanarConfig::kY_U_V_444: return 3;
|
case PlaneConfig::kY_V_U: return 3;
|
||||||
case PlanarConfig::kY_U_V_422: return 3;
|
case PlaneConfig::kY_UV: return 2;
|
||||||
case PlanarConfig::kY_U_V_420: return 3;
|
case PlaneConfig::kY_VU: return 2;
|
||||||
case PlanarConfig::kY_V_U_420: return 3;
|
case PlaneConfig::kYUV: return 1;
|
||||||
case PlanarConfig::kY_U_V_440: return 3;
|
case PlaneConfig::kUYV: return 1;
|
||||||
case PlanarConfig::kY_U_V_411: return 3;
|
case PlaneConfig::kY_U_V_A: return 4;
|
||||||
case PlanarConfig::kY_U_V_410: return 3;
|
case PlaneConfig::kY_V_U_A: return 4;
|
||||||
|
case PlaneConfig::kY_UV_A: return 3;
|
||||||
case PlanarConfig::kY_U_V_A_4204: return 4;
|
case PlaneConfig::kY_VU_A: return 3;
|
||||||
case PlanarConfig::kY_V_U_A_4204: return 4;
|
case PlaneConfig::kYUVA: return 1;
|
||||||
|
case PlaneConfig::kUYVA: return 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
SkUNREACHABLE;
|
SkUNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int SkYUVAInfo::NumChannelsInPlane(PlanarConfig config, int i) {
|
constexpr int SkYUVAInfo::NumChannelsInPlane(PlaneConfig config, int i) {
|
||||||
switch (config) {
|
switch (config) {
|
||||||
case PlanarConfig::kUnknown:
|
case PlaneConfig::kUnknown:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SkYUVAInfo::PlanarConfig::kY_U_V_444:
|
case SkYUVAInfo::PlaneConfig::kY_U_V:
|
||||||
case SkYUVAInfo::PlanarConfig::kY_U_V_422:
|
case SkYUVAInfo::PlaneConfig::kY_V_U:
|
||||||
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:
|
|
||||||
return i >= 0 && i < 3 ? 1 : 0;
|
return i >= 0 && i < 3 ? 1 : 0;
|
||||||
case SkYUVAInfo::PlanarConfig::kY_U_V_A_4204:
|
case SkYUVAInfo::PlaneConfig::kY_UV:
|
||||||
case SkYUVAInfo::PlanarConfig::kY_V_U_A_4204:
|
case SkYUVAInfo::PlaneConfig::kY_VU:
|
||||||
return i >= 0 && i < 4 ? 1 : 0;
|
|
||||||
case SkYUVAInfo::PlanarConfig::kY_UV_420:
|
|
||||||
case SkYUVAInfo::PlanarConfig::kY_VU_420:
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0: return 1;
|
case 0: return 1;
|
||||||
case 1: return 2;
|
case 1: return 2;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
case SkYUVAInfo::PlanarConfig::kY_UV_A_4204:
|
case SkYUVAInfo::PlaneConfig::kYUV:
|
||||||
case SkYUVAInfo::PlanarConfig::kY_VU_A_4204:
|
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) {
|
switch (i) {
|
||||||
case 0: return 1;
|
case 0: return 1;
|
||||||
case 1: return 2;
|
case 1: return 2;
|
||||||
case 2: return 1;
|
case 2: return 1;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
case SkYUVAInfo::PlanarConfig::kYUV_444:
|
case SkYUVAInfo::PlaneConfig::kYUVA:
|
||||||
case SkYUVAInfo::PlanarConfig::kUYV_444:
|
case SkYUVAInfo::PlaneConfig::kUYVA:
|
||||||
return i == 0 ? 3 : 0;
|
|
||||||
case SkYUVAInfo::PlanarConfig::kYUVA_4444:
|
|
||||||
case SkYUVAInfo::PlanarConfig::kUYVA_4444:
|
|
||||||
return i == 0 ? 4 : 0;
|
return i == 0 ? 4 : 0;
|
||||||
}
|
}
|
||||||
return 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
|
#endif
|
||||||
|
@ -29,6 +29,8 @@ class SK_API SkYUVAPixmapInfo {
|
|||||||
public:
|
public:
|
||||||
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
|
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
|
||||||
|
|
||||||
|
using PlaneConfig = SkYUVAInfo::PlaneConfig;
|
||||||
|
using Subsampling = SkYUVAInfo::Subsampling;
|
||||||
using PlanarConfig = SkYUVAInfo::PlanarConfig;
|
using PlanarConfig = SkYUVAInfo::PlanarConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,13 +55,16 @@ public:
|
|||||||
/** Init based on texture formats supported by the context. */
|
/** Init based on texture formats supported by the context. */
|
||||||
SupportedDataTypes(const GrImageContext&);
|
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();
|
static constexpr SupportedDataTypes All();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether there is a supported combination of color types for planes structured
|
* 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;
|
constexpr bool supported(PlanarConfig, DataType) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,7 +157,7 @@ public:
|
|||||||
* Returns true if this has been configured with a non-empty dimensioned SkYUVAInfo with
|
* Returns true if this has been configured with a non-empty dimensioned SkYUVAInfo with
|
||||||
* compatible color types and row bytes.
|
* 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? */
|
/** Is this valid and does it use color types allowed by the passed SupportedDataTypes? */
|
||||||
bool isSupported(const SupportedDataTypes&) const;
|
bool isSupported(const SupportedDataTypes&) const;
|
||||||
@ -281,7 +286,7 @@ constexpr SkYUVAPixmapInfo::SupportedDataTypes SkYUVAPixmapInfo::SupportedDataTy
|
|||||||
return combinations;
|
return combinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlanarConfig config,
|
constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlaneConfig config,
|
||||||
DataType type) const {
|
DataType type) const {
|
||||||
int n = SkYUVAInfo::NumPlanes(config);
|
int n = SkYUVAInfo::NumPlanes(config);
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
@ -295,6 +300,12 @@ constexpr bool SkYUVAPixmapInfo::SupportedDataTypes::supported(PlanarConfig conf
|
|||||||
return true;
|
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,
|
constexpr SkColorType SkYUVAPixmapInfo::DefaultColorTypeForDataType(DataType dataType,
|
||||||
int numChannels) {
|
int numChannels) {
|
||||||
switch (numChannels) {
|
switch (numChannels) {
|
||||||
|
@ -23,8 +23,6 @@ class SK_API GrYUVABackendTextureInfo {
|
|||||||
public:
|
public:
|
||||||
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
|
static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
|
||||||
|
|
||||||
using PlanarConfig = SkYUVAInfo::PlanarConfig;
|
|
||||||
|
|
||||||
/** Default GrYUVABackendTextureInfo is invalid. */
|
/** Default GrYUVABackendTextureInfo is invalid. */
|
||||||
GrYUVABackendTextureInfo() = default;
|
GrYUVABackendTextureInfo() = default;
|
||||||
|
|
||||||
|
@ -796,24 +796,25 @@ static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
|
|||||||
SkASSERT(hSampY == dinfo->max_h_samp_factor);
|
SkASSERT(hSampY == dinfo->max_h_samp_factor);
|
||||||
SkASSERT(vSampY == dinfo->max_v_samp_factor);
|
SkASSERT(vSampY == dinfo->max_v_samp_factor);
|
||||||
|
|
||||||
SkYUVAInfo::PlanarConfig tempPlanarConfig;
|
SkYUVAInfo::Subsampling tempSubsampling;
|
||||||
if (1 == hSampY && 1 == vSampY) {
|
if (1 == hSampY && 1 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_444;
|
tempSubsampling = SkYUVAInfo::Subsampling::k444;
|
||||||
} else if (2 == hSampY && 1 == vSampY) {
|
} else if (2 == hSampY && 1 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_422;
|
tempSubsampling = SkYUVAInfo::Subsampling::k422;
|
||||||
} else if (2 == hSampY && 2 == vSampY) {
|
} else if (2 == hSampY && 2 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_420;
|
tempSubsampling = SkYUVAInfo::Subsampling::k420;
|
||||||
} else if (1 == hSampY && 2 == vSampY) {
|
} else if (1 == hSampY && 2 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_440;
|
tempSubsampling = SkYUVAInfo::Subsampling::k440;
|
||||||
} else if (4 == hSampY && 1 == vSampY) {
|
} else if (4 == hSampY && 1 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_411;
|
tempSubsampling = SkYUVAInfo::Subsampling::k411;
|
||||||
} else if (4 == hSampY && 2 == vSampY) {
|
} else if (4 == hSampY && 2 == vSampY) {
|
||||||
tempPlanarConfig = SkYUVAInfo::PlanarConfig::kY_U_V_410;
|
tempSubsampling = SkYUVAInfo::Subsampling::k410;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (supportedDataTypes &&
|
if (supportedDataTypes &&
|
||||||
!supportedDataTypes->supported(tempPlanarConfig, SkYUVAPixmapInfo::DataType::kUnorm8)) {
|
!supportedDataTypes->supported(SkYUVAInfo::PlaneConfig::kY_U_V,
|
||||||
|
SkYUVAPixmapInfo::DataType::kUnorm8)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (yuvaPixmapInfo) {
|
if (yuvaPixmapInfo) {
|
||||||
@ -824,7 +825,8 @@ static bool is_yuv_supported(const jpeg_decompress_struct* dinfo,
|
|||||||
rowBytes[i] = dinfo->comp_info[i].width_in_blocks * DCTSIZE;
|
rowBytes[i] = dinfo->comp_info[i].width_in_blocks * DCTSIZE;
|
||||||
}
|
}
|
||||||
SkYUVAInfo yuvaInfo(codec.dimensions(),
|
SkYUVAInfo yuvaInfo(codec.dimensions(),
|
||||||
tempPlanarConfig,
|
SkYUVAInfo::PlaneConfig::kY_U_V,
|
||||||
|
tempSubsampling,
|
||||||
kJPEG_Full_SkYUVColorSpace,
|
kJPEG_Full_SkYUVColorSpace,
|
||||||
codec.getOrigin(),
|
codec.getOrigin(),
|
||||||
SkYUVAInfo::Siting::kCentered,
|
SkYUVAInfo::Siting::kCentered,
|
||||||
|
@ -8,10 +8,31 @@
|
|||||||
#include "include/core/SkYUVAInfo.h"
|
#include "include/core/SkYUVAInfo.h"
|
||||||
#include "src/core/SkSafeMath.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,
|
int SkYUVAInfo::PlaneDimensions(SkISize imageDimensions,
|
||||||
PlanarConfig planarConfig,
|
PlaneConfig planeConfig,
|
||||||
|
Subsampling subsampling,
|
||||||
SkEncodedOrigin origin,
|
SkEncodedOrigin origin,
|
||||||
SkISize planeDimensions[SkYUVAInfo::kMaxPlanes]) {
|
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 w = imageDimensions.width();
|
||||||
int h = imageDimensions.height();
|
int h = imageDimensions.height();
|
||||||
if (origin >= kLeftTop_SkEncodedOrigin) {
|
if (origin >= kLeftTop_SkEncodedOrigin) {
|
||||||
@ -20,66 +41,50 @@ int SkYUVAInfo::PlaneDimensions(SkISize imageDimensions,
|
|||||||
}
|
}
|
||||||
auto down2 = [](int x) { return (x + 1)/2; };
|
auto down2 = [](int x) { return (x + 1)/2; };
|
||||||
auto down4 = [](int x) { return (x + 3)/4; };
|
auto down4 = [](int x) { return (x + 3)/4; };
|
||||||
switch (planarConfig) {
|
SkISize uvSize;
|
||||||
case PlanarConfig::kUnknown:
|
switch (subsampling) {
|
||||||
planeDimensions[0] =
|
case Subsampling::kUnknown: SkUNREACHABLE;
|
||||||
planeDimensions[1] =
|
|
||||||
planeDimensions[2] =
|
case Subsampling::k444: uvSize = { w , h }; break;
|
||||||
planeDimensions[3] = {0, 0};
|
case Subsampling::k422: uvSize = {down2(w), h }; break;
|
||||||
return 0;
|
case Subsampling::k420: uvSize = {down2(w), down2(h)}; break;
|
||||||
case PlanarConfig::kY_U_V_444:
|
case Subsampling::k440: uvSize = { w , down2(h)}; break;
|
||||||
planeDimensions[0] = planeDimensions[1] = planeDimensions[2] = {w, h};
|
case Subsampling::k411: uvSize = {down4(w), h }; break;
|
||||||
planeDimensions[3] = {0, 0};
|
case Subsampling::k410: uvSize = {down4(w), down2(h)}; break;
|
||||||
return 3;
|
}
|
||||||
case PlanarConfig::kY_U_V_422:
|
switch (planeConfig) {
|
||||||
|
case PlaneConfig::kUnknown: SkUNREACHABLE;
|
||||||
|
|
||||||
|
case PlaneConfig::kY_U_V:
|
||||||
|
case PlaneConfig::kY_V_U:
|
||||||
planeDimensions[0] = {w, h};
|
planeDimensions[0] = {w, h};
|
||||||
planeDimensions[1] = planeDimensions[2] = {down2(w), h};
|
planeDimensions[1] = planeDimensions[2] = uvSize;
|
||||||
planeDimensions[3] = {0, 0};
|
|
||||||
return 3;
|
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[0] = {w, h};
|
||||||
planeDimensions[1] = planeDimensions[2] = {down2(w), down2(h)};
|
planeDimensions[1] = uvSize;
|
||||||
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};
|
|
||||||
return 2;
|
return 2;
|
||||||
case PlanarConfig::kYUV_444:
|
|
||||||
case PlanarConfig::kUYV_444:
|
case PlaneConfig::kY_U_V_A:
|
||||||
case PlanarConfig::kYUVA_4444:
|
case PlaneConfig::kY_V_U_A:
|
||||||
case PlanarConfig::kUYVA_4444:
|
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[0] = {w, h};
|
||||||
planeDimensions[1] = planeDimensions[2] = planeDimensions[3] = {0, 0};
|
SkASSERT(planeDimensions[0] == uvSize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SkUNREACHABLE;
|
SkUNREACHABLE;
|
||||||
@ -125,76 +130,71 @@ static bool channel_index_to_channel(uint32_t channelFlags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkYUVAInfo::GetYUVAIndices(PlanarConfig config,
|
bool SkYUVAInfo::GetYUVAIndices(PlaneConfig config,
|
||||||
const uint32_t planeChannelFlags[kMaxPlanes],
|
const uint32_t planeChannelFlags[kMaxPlanes],
|
||||||
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) {
|
SkYUVAIndex indices[SkYUVAIndex::kIndexCount]) {
|
||||||
struct Location {int plane, chanIdx;};
|
struct Location {int plane, chanIdx;};
|
||||||
const Location* locations = nullptr;
|
const Location* locations = nullptr;
|
||||||
switch (config) {
|
switch (config) {
|
||||||
case PlanarConfig::kUnknown:
|
case PlaneConfig::kUnknown:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case PlanarConfig::kY_U_V_444:
|
case PlaneConfig::kY_U_V: {
|
||||||
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: {
|
|
||||||
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {2, 0}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {2, 0}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kY_V_U_420: {
|
case PlaneConfig::kY_V_U: {
|
||||||
static constexpr Location kLocations[] = {{0, 0}, {2, 0}, {1, 0}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 0}, {2, 0}, {1, 0}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kY_U_V_A_4204: {
|
case PlaneConfig::kY_UV: {
|
||||||
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: {
|
|
||||||
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {1, 1}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 0}, {1, 0}, {1, 1}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kY_VU_420: {
|
case PlaneConfig::kY_VU: {
|
||||||
static constexpr Location kLocations[] = {{0, 0}, {1, 1}, {1, 0}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 0}, {1, 1}, {1, 0}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kY_UV_A_4204: {
|
case PlaneConfig::kYUV: {
|
||||||
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: {
|
|
||||||
static constexpr Location kLocations[] = {{0, 0}, {0, 1}, {0, 2}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 0}, {0, 1}, {0, 2}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kUYV_444: {
|
case PlaneConfig::kUYV: {
|
||||||
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {-1, -1}};
|
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {-1, -1}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
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}};
|
static constexpr Location kLocations[] = {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PlanarConfig::kUYVA_4444: {
|
case PlaneConfig::kUYVA: {
|
||||||
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {0, 3}};
|
static constexpr Location kLocations[] = {{0, 1}, {0, 0}, {0, 2}, {0, 3}};
|
||||||
locations = kLocations;
|
locations = kLocations;
|
||||||
break;
|
break;
|
||||||
@ -217,56 +217,58 @@ bool SkYUVAInfo::GetYUVAIndices(PlanarConfig config,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkYUVAInfo::HasAlpha(PlanarConfig planarConfig) {
|
bool SkYUVAInfo::HasAlpha(PlaneConfig planeConfig) {
|
||||||
switch (planarConfig) {
|
switch (planeConfig) {
|
||||||
case PlanarConfig::kUnknown: return false;
|
case PlaneConfig::kUnknown: return false;
|
||||||
|
|
||||||
case PlanarConfig::kY_U_V_444: return false;
|
case PlaneConfig::kY_U_V: return false;
|
||||||
case PlanarConfig::kY_U_V_422: return false;
|
case PlaneConfig::kY_V_U: return false;
|
||||||
case PlanarConfig::kY_U_V_420: return false;
|
case PlaneConfig::kY_UV: return false;
|
||||||
case PlanarConfig::kY_V_U_420: return false;
|
case PlaneConfig::kY_VU: return false;
|
||||||
case PlanarConfig::kY_U_V_440: return false;
|
case PlaneConfig::kYUV: return false;
|
||||||
case PlanarConfig::kY_U_V_411: return false;
|
case PlaneConfig::kUYV: return false;
|
||||||
case PlanarConfig::kY_U_V_410: return false;
|
|
||||||
|
|
||||||
case PlanarConfig::kY_U_V_A_4204: return true;
|
case PlaneConfig::kY_U_V_A: return true;
|
||||||
case PlanarConfig::kY_V_U_A_4204: return true;
|
case PlaneConfig::kY_V_U_A: return true;
|
||||||
|
case PlaneConfig::kY_UV_A: return true;
|
||||||
case PlanarConfig::kY_UV_420: return false;
|
case PlaneConfig::kY_VU_A: return true;
|
||||||
case PlanarConfig::kY_VU_420: return false;
|
case PlaneConfig::kYUVA: return true;
|
||||||
|
case PlaneConfig::kUYVA: return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
SkUNREACHABLE;
|
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,
|
SkYUVAInfo::SkYUVAInfo(SkISize dimensions,
|
||||||
PlanarConfig planarConfig,
|
PlanarConfig planarConfig,
|
||||||
SkYUVColorSpace yuvColorSpace,
|
SkYUVColorSpace yuvColorSpace,
|
||||||
SkEncodedOrigin origin,
|
SkEncodedOrigin origin,
|
||||||
Siting sitingX,
|
Siting sitingX,
|
||||||
Siting sitingY)
|
Siting sitingY) {
|
||||||
: fDimensions(dimensions)
|
auto [c, s] = PlanarConfigToPlaneConfigAndSubsampling(planarConfig);
|
||||||
, fPlanarConfig(planarConfig)
|
*this = SkYUVAInfo(dimensions, c, s, yuvColorSpace, origin, sitingX, sitingY);
|
||||||
, 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SkYUVAInfo::computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
size_t SkYUVAInfo::computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
||||||
@ -302,8 +304,75 @@ size_t SkYUVAInfo::computeTotalBytes(const size_t rowBytes[kMaxPlanes],
|
|||||||
return safe.ok() ? totalBytes : SIZE_MAX;
|
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 {
|
bool SkYUVAInfo::operator==(const SkYUVAInfo& that) const {
|
||||||
return fPlanarConfig == that.fPlanarConfig &&
|
return fPlaneConfig == that.fPlaneConfig &&
|
||||||
|
fSubsampling == that.fSubsampling &&
|
||||||
fYUVColorSpace == that.fYUVColorSpace &&
|
fYUVColorSpace == that.fYUVColorSpace &&
|
||||||
fDimensions == that.fDimensions &&
|
fDimensions == that.fDimensions &&
|
||||||
fSitingX == that.fSitingX &&
|
fSitingX == that.fSitingX &&
|
||||||
|
@ -172,7 +172,7 @@ bool SkYUVAPixmapInfo::isSupported(const SupportedDataTypes& supportedDataTypes)
|
|||||||
if (!this->isValid()) {
|
if (!this->isValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return supportedDataTypes.supported(fYUVAInfo.planarConfig(), fDataType);
|
return supportedDataTypes.supported(fYUVAInfo.planeConfig(), fDataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -67,7 +67,8 @@ DEF_TEST(ImageGenerator, reporter) {
|
|||||||
// Check that the YUV decoding API does not cause any crashes
|
// Check that the YUV decoding API does not cause any crashes
|
||||||
ig.queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo);
|
ig.queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo);
|
||||||
SkYUVAInfo yuvaInfo({250, 250},
|
SkYUVAInfo yuvaInfo({250, 250},
|
||||||
SkYUVAInfo::PlanarConfig::kY_UV_420,
|
SkYUVAInfo::PlaneConfig::kY_UV,
|
||||||
|
SkYUVAInfo::Subsampling::k420,
|
||||||
kJPEG_Full_SkYUVColorSpace);
|
kJPEG_Full_SkYUVColorSpace);
|
||||||
yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo,
|
yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo,
|
||||||
SkYUVAPixmapInfo::DataType::kUnorm8,
|
SkYUVAPixmapInfo::DataType::kUnorm8,
|
||||||
|
@ -1372,7 +1372,10 @@ DEF_TEST(Image_nonfinite_dst, reporter) {
|
|||||||
static sk_sp<SkImage> make_yuva_image(GrDirectContext* dContext) {
|
static sk_sp<SkImage> make_yuva_image(GrDirectContext* dContext) {
|
||||||
SkAutoPixmapStorage pm;
|
SkAutoPixmapStorage pm;
|
||||||
pm.alloc(SkImageInfo::Make(1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType));
|
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};
|
const SkPixmap pmaps[] = {pm, pm, pm};
|
||||||
auto yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, pmaps);
|
auto yuvaPixmaps = SkYUVAPixmaps::FromExternalPixmaps(yuvaInfo, pmaps);
|
||||||
|
|
||||||
|
@ -34,7 +34,8 @@ DEF_TEST(YUVPlanesCache, reporter) {
|
|||||||
SkResourceCache cache(1024);
|
SkResourceCache cache(1024);
|
||||||
|
|
||||||
SkYUVAInfo yuvaInfo({5, 5},
|
SkYUVAInfo yuvaInfo({5, 5},
|
||||||
SkYUVAInfo::PlanarConfig::kY_U_V_420,
|
SkYUVAInfo::PlaneConfig::kY_U_V,
|
||||||
|
SkYUVAInfo::Subsampling::k420,
|
||||||
kRec601_Limited_SkYUVColorSpace);
|
kRec601_Limited_SkYUVColorSpace);
|
||||||
SkYUVAPixmapInfo yuvaPixmapInfo(yuvaInfo,
|
SkYUVAPixmapInfo yuvaPixmapInfo(yuvaInfo,
|
||||||
SkYUVAPixmapInfo::DataType::kUnorm8,
|
SkYUVAPixmapInfo::DataType::kUnorm8,
|
||||||
|
@ -82,39 +82,40 @@ static void codec_yuv(skiatest::Reporter* reporter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEF_TEST(Jpeg_YUV_Codec, r) {
|
DEF_TEST(Jpeg_YUV_Codec, r) {
|
||||||
auto setExpectations = [](SkISize dims, SkYUVAInfo::PlanarConfig planarConfig) {
|
auto setExpectations = [](SkISize dims, SkYUVAInfo::Subsampling subsampling) {
|
||||||
return SkYUVAInfo(dims,
|
return SkYUVAInfo(dims,
|
||||||
planarConfig,
|
SkYUVAInfo::PlaneConfig::kY_U_V,
|
||||||
|
subsampling,
|
||||||
kJPEG_Full_SkYUVColorSpace,
|
kJPEG_Full_SkYUVColorSpace,
|
||||||
kTopLeft_SkEncodedOrigin,
|
kTopLeft_SkEncodedOrigin,
|
||||||
SkYUVAInfo::Siting::kCentered,
|
SkYUVAInfo::Siting::kCentered,
|
||||||
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);
|
codec_yuv(r, "images/color_wheel.jpg", &expectations);
|
||||||
|
|
||||||
// H2V2
|
// 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);
|
codec_yuv(r, "images/mandrill_512_q075.jpg", &expectations);
|
||||||
|
|
||||||
// H1V1
|
// 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);
|
codec_yuv(r, "images/mandrill_h1v1.jpg", &expectations);
|
||||||
|
|
||||||
// H2V1
|
// 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);
|
codec_yuv(r, "images/mandrill_h2v1.jpg", &expectations);
|
||||||
|
|
||||||
// Non-power of two dimensions
|
// 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);
|
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);
|
codec_yuv(r, "images/randPixels.jpg", &expectations);
|
||||||
|
|
||||||
// Progressive images
|
// 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-texture.jpg", &expectations);
|
||||||
codec_yuv(r, "images/brickwork_normal-map.jpg", &expectations);
|
codec_yuv(r, "images/brickwork_normal-map.jpg", &expectations);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user