1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #ifndef SkCodecImageGenerator_DEFINED 8 #define SkCodecImageGenerator_DEFINED 9 10 #include "include/codec/SkCodec.h" 11 #include "include/core/SkData.h" 12 #include "include/core/SkImageGenerator.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/core/SkSize.h" 15 #include "include/core/SkYUVAPixmaps.h" 16 17 #include <cstddef> 18 #include <memory> 19 #include <optional> 20 21 enum SkAlphaType : int; 22 struct SkImageInfo; 23 24 class SkCodecImageGenerator : public SkImageGenerator { 25 public: 26 /* 27 * If this data represents an encoded image that we know how to decode, 28 * return an SkCodecImageGenerator. Otherwise return nullptr. 29 */ 30 static std::unique_ptr<SkImageGenerator> MakeFromEncodedCodec( 31 sk_sp<SkData>, std::optional<SkAlphaType> = std::nullopt); 32 33 static std::unique_ptr<SkImageGenerator> MakeFromCodec( 34 std::unique_ptr<SkCodec>, std::optional<SkAlphaType> = std::nullopt); 35 36 /** 37 * Return a size that approximately supports the desired scale factor. The codec may not be able 38 * to scale efficiently to the exact scale factor requested, so return a size that approximates 39 * that scale. The returned value is the codec's suggestion for the closest valid scale that it 40 * can natively support. 41 * 42 * This is similar to SkCodec::getScaledDimensions, but adjusts the returned dimensions based 43 * on the image's EXIF orientation. 44 */ 45 SkISize getScaledDimensions(float desiredScale) const; 46 47 /** 48 * Decode into the given pixels, a block of memory of size at 49 * least (info.fHeight - 1) * rowBytes + (info.fWidth * 50 * bytesPerPixel) 51 * 52 * Repeated calls to this function should give the same results, 53 * allowing the PixelRef to be immutable. 54 * 55 * @param info A description of the format 56 * expected by the caller. This can simply be identical 57 * to the info returned by getInfo(). 58 * 59 * This contract also allows the caller to specify 60 * different output-configs, which the implementation can 61 * decide to support or not. 62 * 63 * A size that does not match getInfo() implies a request 64 * to scale. If the generator cannot perform this scale, 65 * it will return false. 66 * 67 * @return true on success. 68 */ 69 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options = nullptr); 70 71 /** 72 * Return the number of frames in the image. 73 * 74 * May require reading through the stream. 75 */ getFrameCount()76 int getFrameCount() { return fCodec->getFrameCount(); } 77 78 /** 79 * Return info about a single frame. 80 * 81 * Only supported by multi-frame images. Does not read through the stream, 82 * so it should be called after getFrameCount() to parse any frames that 83 * have not already been parsed. 84 */ getFrameInfo(int index,SkCodec::FrameInfo * info)85 bool getFrameInfo(int index, SkCodec::FrameInfo* info) const { 86 return fCodec->getFrameInfo(index, info); 87 } 88 89 /** 90 * Return the number of times to repeat, if this image is animated. This number does not 91 * include the first play through of each frame. For example, a repetition count of 4 means 92 * that each frame is played 5 times and then the animation stops. 93 * 94 * It can return kRepetitionCountInfinite, a negative number, meaning that the animation 95 * should loop forever. 96 * 97 * May require reading the stream to find the repetition count. 98 * 99 * As such, future decoding calls may require a rewind. 100 * 101 * For still (non-animated) image codecs, this will return 0. 102 */ getRepetitionCount()103 int getRepetitionCount() { return fCodec->getRepetitionCount(); } 104 105 protected: 106 sk_sp<SkData> onRefEncodedData() override; 107 108 bool onGetPixels(const SkImageInfo& info, 109 void* pixels, 110 size_t rowBytes, 111 const Options& opts) override; 112 113 bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&, 114 SkYUVAPixmapInfo*) const override; 115 116 bool onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) override; 117 118 private: 119 /* 120 * Takes ownership of codec 121 */ 122 SkCodecImageGenerator(std::unique_ptr<SkCodec>, std::optional<SkAlphaType>); 123 124 std::unique_ptr<SkCodec> fCodec; 125 sk_sp<SkData> fCachedData = nullptr; 126 }; 127 #endif // SkCodecImageGenerator_DEFINED 128