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>
diff --git a/src/codec/SkCodecImageGenerator.cpp b/src/codec/SkCodecImageGenerator.cpp
index ba02233..7a23c07 100644
--- a/src/codec/SkCodecImageGenerator.cpp
+++ b/src/codec/SkCodecImageGenerator.cpp
@@ -46,12 +46,11 @@
return fData;
}
-bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
- size_t requestRowBytes, const Options&) {
- SkPixmap dst(requestInfo, requestPixels, requestRowBytes);
+bool SkCodecImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options) {
+ SkPixmap dst(info, pixels, rowBytes);
- auto decode = [this](const SkPixmap& pm) {
- SkCodec::Result result = fCodec->getPixels(pm);
+ auto decode = [this, options](const SkPixmap& pm) {
+ SkCodec::Result result = fCodec->getPixels(pm, options);
switch (result) {
case SkCodec::kSuccess:
case SkCodec::kIncompleteInput:
@@ -65,6 +64,11 @@
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,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* colorSpace) const {
diff --git a/src/codec/SkCodecImageGenerator.h b/src/codec/SkCodecImageGenerator.h
index c27e77f..11664ba 100644
--- a/src/codec/SkCodecImageGenerator.h
+++ b/src/codec/SkCodecImageGenerator.h
@@ -32,16 +32,78 @@
*/
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:
sk_sp<SkData> onRefEncodedData() override;
- bool onGetPixels(
- const SkImageInfo& info, void* pixels, size_t rowBytes, const Options& opts) override;
+ bool onGetPixels(const SkImageInfo& info,
+ void* pixels,
+ size_t rowBytes,
+ const Options& opts) override;
- bool onQueryYUVA8(
- SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount], SkYUVColorSpace*) const override;
+ bool onQueryYUVA8(SkYUVASizeInfo*,
+ 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;
private: