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