Revert "heif: Add AVIF type and AVIF sniffing"

This reverts commit 3ab5b73649.

Reason for revert: <optional> header is C++17 only

Original change's description:
> heif: Add AVIF type and AVIF sniffing
>
> AVIF is the image format based on the AV1 video codec. The
> container for AVIF is very similar to that of HEIF. Add type
> definitions for AVIF and sniffing code for detecting AVIF images.
>
> The underlying android platform's HEIF decoder implementation will
> also support AVIF decoding.
>
> Bug: b/141654151
> Change-Id: I7e31f4cedf0bffb8920ddf880a26601e48d0e833
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330059
> Reviewed-by: Leon Scroggins <scroggo@google.com>
> Reviewed-by: Derek Sollenberger <djsollen@google.com>
> Reviewed-by: Chong Zhang <chz@google.com>
> Commit-Queue: Leon Scroggins <scroggo@google.com>

TBR=djsollen@google.com,scroggo@google.com,chz@google.com,vigneshv@google.com

Change-Id: I9c9cd00af1a41bffa37725f39afc9bc0e504d616
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: b/141654151
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/331336
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-11-02 16:07:54 +00:00 committed by Skia Commit-Bot
parent 3ab5b73649
commit ebb26e30f2
6 changed files with 21 additions and 50 deletions

View File

@ -9,8 +9,6 @@ Milestone 88
* <insert new release notes here>
* Add AVIF support to SkHeifCodec.
* Removed SkSurfaceProps::kLegacyFontHost_InitType, SkFontLCDConfig, and related code.
The default pixel geometry for SkSurfaceProps is now kUnknown instead of kRGB_H.
The removal was guarded by the SK_LEGACY_SURFACE_PROPS build flag which was later removed.

View File

@ -29,7 +29,6 @@ enum class SkEncodedImageFormat {
kASTC,
kDNG,
kHEIF,
kAVIF,
};
#endif // SkEncodedImageFormat_DEFINED

View File

@ -96,7 +96,6 @@ std::unique_ptr<SkAndroidCodec> SkAndroidCodec::MakeFromCodec(std::unique_ptr<Sk
case SkEncodedImageFormat::kBMP:
case SkEncodedImageFormat::kWBMP:
case SkEncodedImageFormat::kHEIF:
case SkEncodedImageFormat::kAVIF:
return std::make_unique<SkSampledCodec>(codec.release(), orientationBehavior);
#ifdef SK_HAS_WUFFS_LIBRARY
case SkEncodedImageFormat::kGIF:

View File

@ -125,9 +125,8 @@ std::unique_ptr<SkCodec> SkCodec::MakeFromStream(
}
#ifdef SK_HAS_HEIF_LIBRARY
if (auto format = SkHeifCodec::IsSupported(buffer, bytesRead)) {
return SkHeifCodec::MakeFromStream(std::move(stream), selectionPolicy,
format.value(), outResult);
if (SkHeifCodec::IsHeif(buffer, bytesRead)) {
return SkHeifCodec::MakeFromStream(std::move(stream), selectionPolicy, outResult);
}
#endif

View File

@ -18,11 +18,11 @@
#define FOURCC(c1, c2, c3, c4) \
((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
std::optional<SkEncodedImageFormat> SkHeifCodec::IsSupported(const void* buffer, size_t bytesRead) {
// Parse the ftyp box up to bytesRead to determine if this is HEIF or AVIF.
bool SkHeifCodec::IsHeif(const void* buffer, size_t bytesRead) {
// Parse the ftyp box up to bytesRead to determine if this is HEIF.
// Any valid ftyp box should have at least 8 bytes.
if (bytesRead < 8) {
return std::nullopt;
return false;
}
uint32_t* ptr = (uint32_t*)buffer;
@ -30,7 +30,7 @@ std::optional<SkEncodedImageFormat> SkHeifCodec::IsSupported(const void* buffer,
uint32_t chunkType = SkEndian_SwapBE32(ptr[1]);
if (chunkType != FOURCC('f', 't', 'y', 'p')) {
return std::nullopt;
return false;
}
int64_t offset = 8;
@ -38,18 +38,18 @@ std::optional<SkEncodedImageFormat> SkHeifCodec::IsSupported(const void* buffer,
// This indicates that the next 8 bytes represent the chunk size,
// and chunk data comes after that.
if (bytesRead < 16) {
return std::nullopt;
return false;
}
auto* chunkSizePtr = SkTAddOffset<const uint64_t>(buffer, offset);
chunkSize = SkEndian_SwapBE64(*chunkSizePtr);
if (chunkSize < 16) {
// The smallest valid chunk is 16 bytes long in this case.
return std::nullopt;
return false;
}
offset += 8;
} else if (chunkSize < 8) {
// The smallest valid chunk is 8 bytes long.
return std::nullopt;
return false;
}
if (chunkSize > bytesRead) {
@ -59,11 +59,10 @@ std::optional<SkEncodedImageFormat> SkHeifCodec::IsSupported(const void* buffer,
// It should at least have major brand (4-byte) and minor version (4-bytes).
// The rest of the chunk (if any) is a list of (4-byte) compatible brands.
if (chunkDataSize < 8) {
return std::nullopt;
return false;
}
uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
bool isHeif = false;
for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
if (i == 1) {
// Skip this index, it refers to the minorVersion,
@ -73,23 +72,11 @@ std::optional<SkEncodedImageFormat> SkHeifCodec::IsSupported(const void* buffer,
auto* brandPtr = SkTAddOffset<const uint32_t>(buffer, offset + 4 * i);
uint32_t brand = SkEndian_SwapBE32(*brandPtr);
if (brand == FOURCC('m', 'i', 'f', '1') || brand == FOURCC('h', 'e', 'i', 'c')
|| brand == FOURCC('m', 's', 'f', '1') || brand == FOURCC('h', 'e', 'v', 'c')
|| brand == FOURCC('a', 'v', 'i', 'f') || brand == FOURCC('a', 'v', 'i', 's')) {
// AVIF files could have "mif1" as the major brand. So we cannot
// distinguish whether the image is AVIF or HEIC just based on the
// "mif1" brand. So wait until we see a specific avif brand to
// determine whether it is AVIF or HEIC.
isHeif = true;
if (brand == FOURCC('a', 'v', 'i', 'f')
|| brand == FOURCC('a', 'v', 'i', 's')) {
return SkEncodedImageFormat::kAVIF;
}
|| brand == FOURCC('m', 's', 'f', '1') || brand == FOURCC('h', 'e', 'v', 'c')) {
return true;
}
}
if (isHeif) {
return SkEncodedImageFormat::kHEIF;
}
return std::nullopt;
return false;
}
static SkEncodedOrigin get_orientation(const HeifFrameInfo& frameInfo) {
@ -136,7 +123,7 @@ static void releaseProc(const void* ptr, void* context) {
}
std::unique_ptr<SkCodec> SkHeifCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
SkCodec::SelectionPolicy selectionPolicy, SkEncodedImageFormat format, Result* result) {
SkCodec::SelectionPolicy selectionPolicy, Result* result) {
std::unique_ptr<HeifDecoder> heifDecoder(createHeifDecoder());
if (heifDecoder == nullptr) {
*result = kInternalError;
@ -175,21 +162,19 @@ std::unique_ptr<SkCodec> SkHeifCodec::MakeFromStream(std::unique_ptr<SkStream> s
*result = kSuccess;
return std::unique_ptr<SkCodec>(new SkHeifCodec(
std::move(info), heifDecoder.release(), orientation, frameCount > 1, format));
std::move(info), heifDecoder.release(), orientation, frameCount > 1));
}
SkHeifCodec::SkHeifCodec(
SkEncodedInfo&& info,
HeifDecoder* heifDecoder,
SkEncodedOrigin origin,
bool useAnimation,
SkEncodedImageFormat format)
bool useAnimation)
: INHERITED(std::move(info), skcms_PixelFormat_RGBA_8888, nullptr, origin)
, fHeifDecoder(heifDecoder)
, fSwizzleSrcRow(nullptr)
, fColorXformSrcRow(nullptr)
, fUseAnimation(useAnimation)
, fFormat(format)
{}
bool SkHeifCodec::conversionSupported(const SkImageInfo& dstInfo, bool srcIsOpaque,

View File

@ -21,22 +21,15 @@
#include "src/codec/SkStubHeifDecoderAPI.h"
#endif
#include <optional>
class SkHeifCodec : public SkCodec {
public:
/*
* Returns kHEIF or kAVIF if one of those image types were detected.
* Returns nullopt otherwise
*/
static std::optional<SkEncodedImageFormat> IsSupported(const void*, size_t);
static bool IsHeif(const void*, size_t);
/*
* Assumes IsSupported was called and it returned a non-nullopt value.
* Assumes IsHeif was called and returned true.
*/
static std::unique_ptr<SkCodec> MakeFromStream(
std::unique_ptr<SkStream>, SkCodec::SelectionPolicy selectionPolicy,
SkEncodedImageFormat, Result*);
std::unique_ptr<SkStream>, SkCodec::SelectionPolicy selectionPolicy, Result*);
protected:
@ -47,7 +40,7 @@ protected:
int* rowsDecoded) override;
SkEncodedImageFormat onGetEncodedFormat() const override {
return fFormat;
return SkEncodedImageFormat::kHEIF;
}
int onGetFrameCount() override;
@ -66,8 +59,7 @@ private:
* Creates an instance of the decoder
* Called only by NewFromStream
*/
SkHeifCodec(SkEncodedInfo&&, HeifDecoder*, SkEncodedOrigin, bool animation,
SkEncodedImageFormat);
SkHeifCodec(SkEncodedInfo&&, HeifDecoder*, SkEncodedOrigin, bool animation);
void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
void allocateStorage(const SkImageInfo& dstInfo);
@ -91,7 +83,6 @@ private:
std::unique_ptr<SkSwizzler> fSwizzler;
bool fUseAnimation;
const SkEncodedImageFormat fFormat;
class Frame : public SkFrame {
public: