bool SkAvifCodec::IsAvif(constvoid* buffer, size_t bytesRead) {
avifROData avifData = {static_cast<const uint8_t*>(buffer), bytesRead}; bool isAvif = avifPeekCompatibleFileType(&avifData) == AVIF_TRUE; if (isAvif) returntrue; // Peeking sometimes fails if the ftyp box is too large. Check the signature // just to be sure. constchar* bytes = static_cast<constchar*>(buffer);
isAvif = bytesRead >= 12 && !memcmp(&bytes[4], "ftyp", 4) &&
(!memcmp(&bytes[8], "avif", 4) || !memcmp(&bytes[8], "avis", 4)); return isAvif;
}
std::unique_ptr<SkCodec> SkAvifCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
Result* result) {
SkASSERT(result); if (!stream) {
*result = SkCodec::kInvalidInput; return nullptr;
}
AvifDecoder avifDecoder(avifDecoderCreate()); if (avifDecoder == nullptr) {
*result = SkCodec::kInternalError; return nullptr;
}
avifDecoder->ignoreXMP = AVIF_TRUE;
avifDecoder->ignoreExif = AVIF_TRUE;
avifDecoder->allowProgressive = AVIF_FALSE;
avifDecoder->allowIncremental = AVIF_FALSE;
avifDecoder->strictFlags = AVIF_STRICT_DISABLED; // TODO(vigneshv): Enable threading based on number of CPU cores available.
avifDecoder->maxThreads = 1;
// libavif needs a contiguous data buffer.
sk_sp<SkData> data = nullptr; if (stream->getMemoryBase()) { // It is safe to make without copy because we'll hold onto the stream.
data = SkData::MakeWithoutCopy(stream->getMemoryBase(), stream->getLength());
} else {
data = SkCopyStreamToData(stream.get()); // If we are forced to copy the stream to a data, we can go ahead and // delete the stream.
stream.reset(nullptr);
}
avifResult res = avifDecoderSetIOMemory(avifDecoder.get(), data->bytes(), data->size()); if (res != AVIF_RESULT_OK) {
*result = SkCodec::kInternalError; return nullptr;
}
res = avifDecoderParse(avifDecoder.get()); if (res != AVIF_RESULT_OK) {
*result = SkCodec::kInvalidInput; return nullptr;
}
std::unique_ptr<SkEncodedInfo::ICCProfile> profile = nullptr; // TODO(vigneshv): Get ICC Profile from the avif decoder.
const SkColorType dstColorType = dstInfo.colorType(); if (dstColorType != kRGBA_8888_SkColorType && dstColorType != kRGBA_F16_SkColorType) { // TODO(vigneshv): Check if more color types need to be supported. // Currently android supports at least RGB565 and BGRA8888 which is not // supported here. return kUnimplemented;
}
avifResult result = avifDecoderNthImage(fAvifDecoder.get(), options.fFrameIndex); if (result != AVIF_RESULT_OK) { return kInvalidInput;
}
if (this->dimensions() != dstInfo.dimensions()) {
result = avifImageScale(
fAvifDecoder->image, dstInfo.width(), dstInfo.height(), &fAvifDecoder->diag); if (result != AVIF_RESULT_OK) { return kInvalidInput;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.