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