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