diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp')
-rw-r--r-- | gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp b/gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp new file mode 100644 index 0000000000..dc827e5f6f --- /dev/null +++ b/gfx/skia/skia/src/utils/SkAnimCodecPlayer.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/codec/SkCodec.h" +#include "include/core/SkData.h" +#include "include/core/SkImage.h" +#include "include/utils/SkAnimCodecPlayer.h" +#include "src/codec/SkCodecImageGenerator.h" +#include <algorithm> + +SkAnimCodecPlayer::SkAnimCodecPlayer(std::unique_ptr<SkCodec> codec) : fCodec(std::move(codec)) { + fImageInfo = fCodec->getInfo(); + fFrameInfos = fCodec->getFrameInfo(); + fImages.resize(fFrameInfos.size()); + + // change the interpretation of fDuration to a end-time for that frame + size_t dur = 0; + for (auto& f : fFrameInfos) { + dur += f.fDuration; + f.fDuration = dur; + } + fTotalDuration = dur; + + if (!fTotalDuration) { + // Static image -- may or may not have returned a single frame info. + fFrameInfos.clear(); + fImages.clear(); + fImages.push_back(SkImage::MakeFromGenerator( + SkCodecImageGenerator::MakeFromCodec(std::move(fCodec)))); + } +} + +SkAnimCodecPlayer::~SkAnimCodecPlayer() {} + +SkISize SkAnimCodecPlayer::dimensions() { + return { fImageInfo.width(), fImageInfo.height() }; +} + +sk_sp<SkImage> SkAnimCodecPlayer::getFrameAt(int index) { + SkASSERT((unsigned)index < fFrameInfos.size()); + + if (fImages[index]) { + return fImages[index]; + } + + size_t rb = fImageInfo.minRowBytes(); + size_t size = fImageInfo.computeByteSize(rb); + auto data = SkData::MakeUninitialized(size); + + SkCodec::Options opts; + opts.fFrameIndex = index; + + const int requiredFrame = fFrameInfos[index].fRequiredFrame; + if (requiredFrame != SkCodec::kNoFrame) { + auto requiredImage = fImages[requiredFrame]; + SkPixmap requiredPM; + if (requiredImage && requiredImage->peekPixels(&requiredPM)) { + sk_careful_memcpy(data->writable_data(), requiredPM.addr(), size); + opts.fPriorFrame = requiredFrame; + } + } + if (SkCodec::kSuccess == fCodec->getPixels(fImageInfo, data->writable_data(), rb, &opts)) { + return fImages[index] = SkImage::MakeRasterData(fImageInfo, std::move(data), rb); + } + return nullptr; +} + +sk_sp<SkImage> SkAnimCodecPlayer::getFrame() { + SkASSERT(fTotalDuration > 0 || fImages.size() == 1); + + return fTotalDuration > 0 + ? this->getFrameAt(fCurrIndex) + : fImages.front(); +} + +bool SkAnimCodecPlayer::seek(uint32_t msec) { + if (!fTotalDuration) { + return false; + } + + msec %= fTotalDuration; + + auto lower = std::lower_bound(fFrameInfos.begin(), fFrameInfos.end(), msec, + [](const SkCodec::FrameInfo& info, uint32_t msec) { + return (uint32_t)info.fDuration < msec; + }); + int prevIndex = fCurrIndex; + fCurrIndex = lower - fFrameInfos.begin(); + return fCurrIndex != prevIndex; +} + + |