• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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