xref: /aosp_15_r20/external/skia/src/codec/SkCodecImageGenerator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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