1 /*
2  * Copyright 2013 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 
8 #ifndef SkImageGenerator_DEFINED
9 #define SkImageGenerator_DEFINED
10 
11 #include "SkColor.h"
12 #include "SkImageInfo.h"
13 
14 class SkBitmap;
15 class SkData;
16 class SkImageGenerator;
17 
18 //#define SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
19 
20 /**
21  *  Takes ownership of SkImageGenerator.  If this method fails for
22  *  whatever reason, it will return false and immediatetely delete
23  *  the generator.  If it succeeds, it will modify destination
24  *  bitmap.
25  *
26  *  If generator is NULL, will safely return false.
27  *
28  *  If this fails or when the SkDiscardablePixelRef that is
29  *  installed into destination is destroyed, it will call
30  *  SkDELETE() on the generator.  Therefore, generator should be
31  *  allocated with SkNEW() or SkNEW_ARGS().
32  *
33  *  @param destination Upon success, this bitmap will be
34  *  configured and have a pixelref installed.
35  *
36  *  @return true iff successful.
37  */
38 SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
39 
40 /**
41  *  On success, installs a discardable pixelref into destination, based on encoded data.
42  *  Regardless of success or failure, the caller must still balance their ownership of encoded.
43  */
44 SK_API bool SkInstallDiscardablePixelRef(SkData* encoded, SkBitmap* destination);
45 
46 /**
47  *  An interface that allows a purgeable PixelRef (such as a
48  *  SkDiscardablePixelRef) to decode and re-decode an image as needed.
49  */
50 class SK_API SkImageGenerator : public SkNoncopyable {
51 public:
52     /**
53      *  The PixelRef which takes ownership of this SkImageGenerator
54      *  will call the image generator's destructor.
55      */
~SkImageGenerator()56     virtual ~SkImageGenerator() { }
57 
58     /**
59      *  Return a ref to the encoded (i.e. compressed) representation,
60      *  of this data.
61      *
62      *  If non-NULL is returned, the caller is responsible for calling
63      *  unref() on the data when it is finished.
64      */
refEncodedData()65     SkData* refEncodedData() { return this->onRefEncodedData(); }
66 
67     /**
68      *  Return the ImageInfo associated with this generator.
69      */
getInfo()70     const SkImageInfo& getInfo() const { return fInfo; }
71 
72     /**
73      *  Used to describe the result of a call to getPixels().
74      *
75      *  Result is the union of possible results from subclasses.
76      */
77     enum Result {
78         /**
79          *  General return value for success.
80          */
81         kSuccess,
82         /**
83          *  The input is incomplete. A partial image was generated.
84          */
85         kIncompleteInput,
86         /**
87          *  The generator cannot convert to match the request, ignoring
88          *  dimensions.
89          */
90         kInvalidConversion,
91         /**
92          *  The generator cannot scale to requested size.
93          */
94         kInvalidScale,
95         /**
96          *  Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
97          *  too small, etc.
98          */
99         kInvalidParameters,
100         /**
101          *  The input did not contain a valid image.
102          */
103         kInvalidInput,
104         /**
105          *  Fulfilling this request requires rewinding the input, which is not
106          *  supported for this input.
107          */
108         kCouldNotRewind,
109         /**
110          *  This method is not implemented by this generator.
111          */
112         kUnimplemented,
113     };
114 
115     /**
116      *  Whether or not the memory passed to getPixels is zero initialized.
117      */
118     enum ZeroInitialized {
119         /**
120          *  The memory passed to getPixels is zero initialized. The SkCodec
121          *  may take advantage of this by skipping writing zeroes.
122          */
123         kYes_ZeroInitialized,
124         /**
125          *  The memory passed to getPixels has not been initialized to zero,
126          *  so the SkCodec must write all zeroes to memory.
127          *
128          *  This is the default. It will be used if no Options struct is used.
129          */
130         kNo_ZeroInitialized,
131     };
132 
133     /**
134      *  Additional options to pass to getPixels.
135      */
136     struct Options {
OptionsOptions137         Options()
138             : fZeroInitialized(kNo_ZeroInitialized) {}
139 
140         ZeroInitialized fZeroInitialized;
141     };
142 
143     /**
144      *  Decode into the given pixels, a block of memory of size at
145      *  least (info.fHeight - 1) * rowBytes + (info.fWidth *
146      *  bytesPerPixel)
147      *
148      *  Repeated calls to this function should give the same results,
149      *  allowing the PixelRef to be immutable.
150      *
151      *  @param info A description of the format (config, size)
152      *         expected by the caller.  This can simply be identical
153      *         to the info returned by getInfo().
154      *
155      *         This contract also allows the caller to specify
156      *         different output-configs, which the implementation can
157      *         decide to support or not.
158      *
159      *         A size that does not match getInfo() implies a request
160      *         to scale. If the generator cannot perform this scale,
161      *         it will return kInvalidScale.
162      *
163      *  If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
164      *  SkPMColor values in ctable. On success the generator must copy N colors into that storage,
165      *  (where N is the logical number of table entries) and set ctableCount to N.
166      *
167      *  If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
168      *  is not null, it will be set to 0.
169      *
170      *  @return Result kSuccess, or another value explaining the type of failure.
171      */
172     Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*,
173                      SkPMColor ctable[], int* ctableCount);
174 
175     /**
176      *  Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
177      *  uses the default Options.
178      */
179     Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
180 
181     /**
182      *  If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
183      *  is 0, this imagegenerator should output the sizes and return true if it can efficiently
184      *  return YUV planar data. If it cannot, it should return false. Note that either planes and
185      *  rowBytes are both fully defined and non NULL/non 0 or they are both NULL or have NULL or 0
186      *  entries only. Having only partial planes/rowBytes information is not supported.
187      *
188      *  If all planes and rowBytes entries are non NULL or non 0, then it should copy the
189      *  associated YUV data into those planes of memory supplied by the caller. It should validate
190      *  that the sizes match what it expected. If the sizes do not match, it should return false.
191      */
192     bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
193                        SkYUVColorSpace* colorSpace);
194 
195     /**
196      *  If the default image decoder system can interpret the specified (encoded) data, then
197      *  this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
198      *  the caller is still responsible for managing their ownership of the data.
199      */
200     static SkImageGenerator* NewFromData(SkData*);
201 
202 protected:
SkImageGenerator(const SkImageInfo & info)203     SkImageGenerator(const SkImageInfo& info) : fInfo(info) {}
204 
205     virtual SkData* onRefEncodedData();
206 
207 #ifdef SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
208     virtual Result onGetPixels(const SkImageInfo& info,
209                                void* pixels, size_t rowBytes,
210                                SkPMColor ctable[], int* ctableCount);
211 #endif
212     virtual Result onGetPixels(const SkImageInfo& info,
213                                void* pixels, size_t rowBytes, const Options&,
214                                SkPMColor ctable[], int* ctableCount);
215     virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
216     virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
217                                  SkYUVColorSpace* colorSpace);
218 
219 private:
220     const SkImageInfo fInfo;
221 };
222 
223 #endif  // SkImageGenerator_DEFINED
224