blob: 015713dcd453d454d591991de70442cb0e27af4c [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/lib/ui/painting/image_generator.h"
#include "flutter/fml/logging.h"
namespace flutter {
ImageGenerator::~ImageGenerator() = default;
sk_sp<SkImage> ImageGenerator::GetImage() {
SkImageInfo info = GetInfo();
SkBitmap bitmap;
if (!bitmap.tryAllocPixels(info)) {
FML_DLOG(ERROR) << "Failed to allocate memory for bitmap of size "
<< info.computeMinByteSize() << "B";
return nullptr;
}
const auto& pixmap = bitmap.pixmap();
if (!GetPixels(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes())) {
FML_DLOG(ERROR) << "Failed to get pixels for image.";
return nullptr;
}
bitmap.setImmutable();
return SkImage::MakeFromBitmap(bitmap);
}
BuiltinSkiaImageGenerator::~BuiltinSkiaImageGenerator() = default;
BuiltinSkiaImageGenerator::BuiltinSkiaImageGenerator(
std::unique_ptr<SkImageGenerator> generator)
: generator_(std::move(generator)) {}
const SkImageInfo& BuiltinSkiaImageGenerator::GetInfo() {
return generator_->getInfo();
}
unsigned int BuiltinSkiaImageGenerator::GetFrameCount() const {
return 1;
}
unsigned int BuiltinSkiaImageGenerator::GetPlayCount() const {
return 1;
}
const ImageGenerator::FrameInfo BuiltinSkiaImageGenerator::GetFrameInfo(
unsigned int frame_index) const {
return {.required_frame = std::nullopt,
.duration = 0,
.disposal_method = SkCodecAnimation::DisposalMethod::kKeep};
}
SkISize BuiltinSkiaImageGenerator::GetScaledDimensions(float desired_scale) {
return generator_->getInfo().dimensions();
}
bool BuiltinSkiaImageGenerator::GetPixels(
const SkImageInfo& info,
void* pixels,
size_t row_bytes,
unsigned int frame_index,
std::optional<unsigned int> prior_frame) {
return generator_->getPixels(info, pixels, row_bytes);
}
std::unique_ptr<ImageGenerator> BuiltinSkiaImageGenerator::MakeFromGenerator(
std::unique_ptr<SkImageGenerator> generator) {
if (!generator) {
return nullptr;
}
return std::make_unique<BuiltinSkiaImageGenerator>(std::move(generator));
}
BuiltinSkiaCodecImageGenerator::~BuiltinSkiaCodecImageGenerator() = default;
BuiltinSkiaCodecImageGenerator::BuiltinSkiaCodecImageGenerator(
std::unique_ptr<SkCodec> codec)
: codec_generator_(static_cast<SkCodecImageGenerator*>(
SkCodecImageGenerator::MakeFromCodec(std::move(codec)).release())) {}
BuiltinSkiaCodecImageGenerator::BuiltinSkiaCodecImageGenerator(
sk_sp<SkData> buffer)
: codec_generator_(static_cast<SkCodecImageGenerator*>(
SkCodecImageGenerator::MakeFromEncodedCodec(buffer).release())) {}
const SkImageInfo& BuiltinSkiaCodecImageGenerator::GetInfo() {
return codec_generator_->getInfo();
}
unsigned int BuiltinSkiaCodecImageGenerator::GetFrameCount() const {
return codec_generator_->getFrameCount();
}
unsigned int BuiltinSkiaCodecImageGenerator::GetPlayCount() const {
auto repetition_count = codec_generator_->getRepetitionCount();
return repetition_count < 0 ? kInfinitePlayCount : repetition_count + 1;
}
const ImageGenerator::FrameInfo BuiltinSkiaCodecImageGenerator::GetFrameInfo(
unsigned int frame_index) const {
SkCodec::FrameInfo info;
codec_generator_->getFrameInfo(frame_index, &info);
return {
.required_frame = info.fRequiredFrame == SkCodec::kNoFrame
? std::nullopt
: std::optional<unsigned int>(info.fRequiredFrame),
.duration = static_cast<unsigned int>(info.fDuration),
.disposal_method = info.fDisposalMethod};
}
SkISize BuiltinSkiaCodecImageGenerator::GetScaledDimensions(
float desired_scale) {
return codec_generator_->getScaledDimensions(desired_scale);
}
bool BuiltinSkiaCodecImageGenerator::GetPixels(
const SkImageInfo& info,
void* pixels,
size_t row_bytes,
unsigned int frame_index,
std::optional<unsigned int> prior_frame) {
SkCodec::Options options;
options.fFrameIndex = frame_index;
if (prior_frame.has_value()) {
options.fPriorFrame = prior_frame.value();
}
return codec_generator_->getPixels(info, pixels, row_bytes, &options);
}
std::unique_ptr<ImageGenerator> BuiltinSkiaCodecImageGenerator::MakeFromData(
sk_sp<SkData> data) {
auto codec = SkCodec::MakeFromData(data);
if (!codec) {
return nullptr;
}
return std::make_unique<BuiltinSkiaCodecImageGenerator>(std::move(codec));
}
} // namespace flutter