Expose multi-frame methods for SkCodecImageGenerator

This will allow Flutter to avoid some usages of SkCodec
and have consistent EXIF handling for multi-frame formats
that support EXIF.

Change-Id: I80daee9b00777d88d0a960cc0f0d76da6680e257
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302270
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Dan Field <dnfield@google.com>
This commit is contained in:
Dan Field 2020-07-13 10:18:15 -07:00 committed by Skia Commit-Bot
parent 3b5a4fac1e
commit 439709a97d
2 changed files with 76 additions and 10 deletions

View File

@ -46,12 +46,11 @@ sk_sp<SkData> SkCodecImageGenerator::onRefEncodedData() {
return fData; return fData;
} }
bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels, bool SkCodecImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options) {
size_t requestRowBytes, const Options&) { SkPixmap dst(info, pixels, rowBytes);
SkPixmap dst(requestInfo, requestPixels, requestRowBytes);
auto decode = [this](const SkPixmap& pm) { auto decode = [this, options](const SkPixmap& pm) {
SkCodec::Result result = fCodec->getPixels(pm); SkCodec::Result result = fCodec->getPixels(pm, options);
switch (result) { switch (result) {
case SkCodec::kSuccess: case SkCodec::kSuccess:
case SkCodec::kIncompleteInput: case SkCodec::kIncompleteInput:
@ -65,6 +64,11 @@ bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* re
return SkPixmapPriv::Orient(dst, fCodec->getOrigin(), decode); return SkPixmapPriv::Orient(dst, fCodec->getOrigin(), decode);
} }
bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
size_t requestRowBytes, const Options& options) {
return this->getPixels(requestInfo, requestPixels, requestRowBytes, nullptr);
}
bool SkCodecImageGenerator::onQueryYUVA8(SkYUVASizeInfo* sizeInfo, bool SkCodecImageGenerator::onQueryYUVA8(SkYUVASizeInfo* sizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount], SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* colorSpace) const { SkYUVColorSpace* colorSpace) const {

View File

@ -32,16 +32,78 @@ public:
*/ */
SkISize getScaledDimensions(float desiredScale) const; SkISize getScaledDimensions(float desiredScale) const;
/**
* Decode into the given pixels, a block of memory of size at
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
* bytesPerPixel)
*
* Repeated calls to this function should give the same results,
* allowing the PixelRef to be immutable.
*
* @param info A description of the format
* expected by the caller. This can simply be identical
* to the info returned by getInfo().
*
* This contract also allows the caller to specify
* different output-configs, which the implementation can
* decide to support or not.
*
* A size that does not match getInfo() implies a request
* to scale. If the generator cannot perform this scale,
* it will return false.
*
* @return true on success.
*/
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options = nullptr);
/**
* Return the number of frames in the image.
*
* May require reading through the stream.
*/
int getFrameCount() { return fCodec->getFrameCount(); }
/**
* Return info about a single frame.
*
* Only supported by multi-frame images. Does not read through the stream,
* so it should be called after getFrameCount() to parse any frames that
* have not already been parsed.
*/
bool getFrameInfo(int index, SkCodec::FrameInfo* info) const {
return fCodec->getFrameInfo(index, info);
}
/**
* Return the number of times to repeat, if this image is animated. This number does not
* include the first play through of each frame. For example, a repetition count of 4 means
* that each frame is played 5 times and then the animation stops.
*
* It can return kRepetitionCountInfinite, a negative number, meaning that the animation
* should loop forever.
*
* May require reading the stream to find the repetition count.
*
* As such, future decoding calls may require a rewind.
*
* For still (non-animated) image codecs, this will return 0.
*/
int getRepetitionCount() { return fCodec->getRepetitionCount(); }
protected: protected:
sk_sp<SkData> onRefEncodedData() override; sk_sp<SkData> onRefEncodedData() override;
bool onGetPixels( bool onGetPixels(const SkImageInfo& info,
const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts) override; void* pixels,
size_t rowBytes,
const Options& opts) override;
bool onQueryYUVA8( bool onQueryYUVA8(SkYUVASizeInfo*,
SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount], SkYUVColorSpace*) const override; SkYUVAIndex[SkYUVAIndex::kIndexCount],
SkYUVColorSpace*) const override;
bool onGetYUVA8Planes(const SkYUVASizeInfo&, const SkYUVAIndex[SkYUVAIndex::kIndexCount], bool onGetYUVA8Planes(const SkYUVASizeInfo&,
const SkYUVAIndex[SkYUVAIndex::kIndexCount],
void* planes[]) override; void* planes[]) override;
private: private: