blob: 846c380851dbc199a93e5b3b657acdacae5c5f36 [file] [log] [blame]
halcanary@google.comad04eb42013-11-21 15:32:08 +00001/*
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
reed4b3d3be2015-09-17 13:35:19 -070011#include "SkBitmap.h"
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000012#include "SkColor.h"
Matt Sarette94255d2017-01-09 12:38:59 -050013#include "SkImage.h"
rileyaabaef862014-09-12 17:45:58 -070014#include "SkImageInfo.h"
msarett4984c3c2016-03-10 05:44:43 -080015#include "SkYUVSizeInfo.h"
halcanary@google.comad04eb42013-11-21 15:32:08 +000016
reed8f343722015-08-13 13:32:39 -070017class GrContext;
Mike Reed34a2ca12016-10-20 15:37:41 -040018class GrContextThreadSafeProxy;
Robert Phillips4447b642017-03-03 11:10:18 -050019class GrTextureProxy;
Brian Salomon514baff2016-11-17 15:17:07 -050020class GrSamplerParams;
halcanary@google.comedd370f2013-12-10 21:11:12 +000021class SkBitmap;
halcanary@google.comad04eb42013-11-21 15:32:08 +000022class SkData;
fmalita1dedc3d2015-08-04 13:53:14 -070023class SkMatrix;
24class SkPaint;
25class SkPicture;
halcanary@google.comedd370f2013-12-10 21:11:12 +000026
scroggo08649082015-02-13 11:13:34 -080027class SK_API SkImageGenerator : public SkNoncopyable {
halcanary@google.comad04eb42013-11-21 15:32:08 +000028public:
29 /**
30 * The PixelRef which takes ownership of this SkImageGenerator
31 * will call the image generator's destructor.
32 */
33 virtual ~SkImageGenerator() { }
34
reed8f343722015-08-13 13:32:39 -070035 uint32_t uniqueID() const { return fUniqueID; }
36
halcanary@google.comad04eb42013-11-21 15:32:08 +000037 /**
38 * Return a ref to the encoded (i.e. compressed) representation,
reed05dd2512016-01-05 09:16:19 -080039 * of this data. If the GrContext is non-null, then the caller is only interested in
40 * gpu-specific formats, so the impl may return null even if they have encoded data,
41 * assuming they know it is not suitable for the gpu.
halcanary@google.comad04eb42013-11-21 15:32:08 +000042 *
43 * If non-NULL is returned, the caller is responsible for calling
44 * unref() on the data when it is finished.
45 */
reed05dd2512016-01-05 09:16:19 -080046 SkData* refEncodedData(GrContext* ctx = nullptr) {
reed05dd2512016-01-05 09:16:19 -080047 return this->onRefEncodedData(ctx);
reed05dd2512016-01-05 09:16:19 -080048 }
halcanary@google.comad04eb42013-11-21 15:32:08 +000049
50 /**
reed3ef71e32015-03-19 08:31:14 -070051 * Return the ImageInfo associated with this generator.
halcanary@google.comad04eb42013-11-21 15:32:08 +000052 */
reed3ef71e32015-03-19 08:31:14 -070053 const SkImageInfo& getInfo() const { return fInfo; }
halcanary@google.comad04eb42013-11-21 15:32:08 +000054
scroggo95526622015-03-17 05:02:17 -070055 /**
halcanary@google.comad04eb42013-11-21 15:32:08 +000056 * Decode into the given pixels, a block of memory of size at
57 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
58 * bytesPerPixel)
59 *
commit-bot@chromium.orgdd597992013-12-02 22:32:54 +000060 * Repeated calls to this function should give the same results,
61 * allowing the PixelRef to be immutable.
62 *
halcanary@google.comad04eb42013-11-21 15:32:08 +000063 * @param info A description of the format (config, size)
64 * expected by the caller. This can simply be identical
65 * to the info returned by getInfo().
66 *
67 * This contract also allows the caller to specify
68 * different output-configs, which the implementation can
69 * decide to support or not.
70 *
scroggo08649082015-02-13 11:13:34 -080071 * A size that does not match getInfo() implies a request
72 * to scale. If the generator cannot perform this scale,
73 * it will return kInvalidScale.
74 *
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000075 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
76 * SkPMColor values in ctable. On success the generator must copy N colors into that storage,
77 * (where N is the logical number of table entries) and set ctableCount to N.
78 *
79 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
80 * is not null, it will be set to 0.
81 *
scroggo5315fd42015-07-09 09:08:00 -070082 * @return true on success.
halcanary@google.comad04eb42013-11-21 15:32:08 +000083 */
scroggo5315fd42015-07-09 09:08:00 -070084 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
85 SkPMColor ctable[], int* ctableCount);
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000086
87 /**
scroggo95526622015-03-17 05:02:17 -070088 * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
89 * uses the default Options.
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000090 */
scroggo5315fd42015-07-09 09:08:00 -070091 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000092
sugoi518d83d2014-07-21 11:37:39 -070093 /**
msarett4984c3c2016-03-10 05:44:43 -080094 * If decoding to YUV is supported, this returns true. Otherwise, this
95 * returns false and does not modify any of the parameters.
sugoi518d83d2014-07-21 11:37:39 -070096 *
msarett4984c3c2016-03-10 05:44:43 -080097 * @param sizeInfo Output parameter indicating the sizes and required
98 * allocation widths of the Y, U, and V planes.
99 * @param colorSpace Output parameter.
sugoi518d83d2014-07-21 11:37:39 -0700100 */
msarett4984c3c2016-03-10 05:44:43 -0800101 bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const;
102
103 /**
104 * Returns true on success and false on failure.
105 * This always attempts to perform a full decode. If the client only
106 * wants size, it should call queryYUV8().
107 *
108 * @param sizeInfo Needs to exactly match the values returned by the
109 * query, except the WidthBytes may be larger than the
110 * recommendation (but not smaller).
111 * @param planes Memory for each of the Y, U, and V planes.
112 */
113 bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]);
sugoi518d83d2014-07-21 11:37:39 -0700114
Robert Phillips4447b642017-03-03 11:10:18 -0500115#if SK_SUPPORT_GPU
reedb5d818a2015-01-06 11:30:45 -0800116 /**
reed8f343722015-08-13 13:32:39 -0700117 * If the generator can natively/efficiently return its pixels as a GPU image (backed by a
118 * texture) this will return that image. If not, this will return NULL.
119 *
Brian Osman222e9ad2016-12-14 15:42:36 -0500120 * This routine also supports retrieving only a subset of the pixels. That subset is specified
121 * by the following rectangle:
122 *
123 * subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
124 *
125 * If subset is not contained inside the generator's bounds, this returns false.
126 *
127 * whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
128 * if (!whole.contains(subset)) {
129 * return false;
130 * }
131 *
reed8f343722015-08-13 13:32:39 -0700132 * Regarding the GrContext parameter:
133 *
Robert Phillips4447b642017-03-03 11:10:18 -0500134 * It must be non-NULL. The generator should only succeed if:
reed8f343722015-08-13 13:32:39 -0700135 * - its internal context is the same
136 * - it can somehow convert its texture into one that is valid for the provided context.
reed8f343722015-08-13 13:32:39 -0700137 */
Robert Phillips4447b642017-03-03 11:10:18 -0500138 sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
139 const SkIPoint& origin);
140#endif
reed8f343722015-08-13 13:32:39 -0700141
Florin Malitaca795352016-11-16 14:45:34 -0500142 /**
reedb5d818a2015-01-06 11:30:45 -0800143 * If the default image decoder system can interpret the specified (encoded) data, then
144 * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
145 * the caller is still responsible for managing their ownership of the data.
146 */
Mike Reed185130c2017-02-15 15:14:16 -0500147 static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
reedb5d818a2015-01-06 11:30:45 -0800148
fmalita1dedc3d2015-08-04 13:53:14 -0700149 /** Return a new image generator backed by the specified picture. If the size is empty or
150 * the picture is NULL, this returns NULL.
151 * The optional matrix and paint arguments are passed to drawPicture() at rasterization
152 * time.
153 */
Mike Reed185130c2017-02-15 15:14:16 -0500154 static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
155 const SkMatrix*, const SkPaint*,
156 SkImage::BitDepth,
157 sk_sp<SkColorSpace>);
fmalita1dedc3d2015-08-04 13:53:14 -0700158
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +0000159protected:
aleksandar.stojiljkovic95167752016-05-02 01:43:38 -0700160 enum {
161 kNeedNewImageUniqueID = 0
162 };
163
164 SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
reed3ef71e32015-03-19 08:31:14 -0700165
Mike Reeddf8599a2016-12-08 13:41:10 -0500166 virtual SkData* onRefEncodedData(GrContext* ctx);
reed3ef71e32015-03-19 08:31:14 -0700167
scroggo5315fd42015-07-09 09:08:00 -0700168 virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
169 SkPMColor ctable[], int* ctableCount);
msarett4984c3c2016-03-10 05:44:43 -0800170
171 virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
172 return false;
173 }
174 virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
175 return false;
176 }
reed3ef71e32015-03-19 08:31:14 -0700177
Matt Sarettd531ca02017-03-24 16:31:19 -0400178 struct Options {
179 Options()
180 : fColorTable(nullptr)
181 , fColorTableCount(nullptr)
182 , fBehavior(SkTransferFunctionBehavior::kRespect)
183 {}
184
185 SkPMColor* fColorTable;
186 int* fColorTableCount;
187 SkTransferFunctionBehavior fBehavior;
188 };
189 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts);
190 virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
191 const Options& opts) {
192 return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount);
193 }
194
Robert Phillips4447b642017-03-03 11:10:18 -0500195#if SK_SUPPORT_GPU
196 virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
197 const SkIPoint&);
198#endif
reed8f343722015-08-13 13:32:39 -0700199
reed3ef71e32015-03-19 08:31:14 -0700200private:
201 const SkImageInfo fInfo;
reed8f343722015-08-13 13:32:39 -0700202 const uint32_t fUniqueID;
reed1c846342015-07-09 11:47:36 -0700203
Matt Sarettd531ca02017-03-24 16:31:19 -0400204 friend class SkImageCacherator;
205
reedd7c05bf2015-07-09 14:08:49 -0700206 // This is our default impl, which may be different on different platforms.
207 // It is called from NewFromEncoded() after it has checked for any runtime factory.
208 // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
Mike Reed185130c2017-02-15 15:14:16 -0500209 static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
halcanary@google.comad04eb42013-11-21 15:32:08 +0000210};
211
212#endif // SkImageGenerator_DEFINED