OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkCodec_DEFINED | 8 #ifndef SkCodec_DEFINED |
9 #define SkCodec_DEFINED | 9 #define SkCodec_DEFINED |
10 | 10 |
| 11 #include "SkColor.h" |
11 #include "SkEncodedFormat.h" | 12 #include "SkEncodedFormat.h" |
12 #include "SkImageGenerator.h" | |
13 #include "SkImageInfo.h" | 13 #include "SkImageInfo.h" |
14 #include "SkScanlineDecoder.h" | |
15 #include "SkSize.h" | 14 #include "SkSize.h" |
16 #include "SkStream.h" | 15 #include "SkStream.h" |
17 #include "SkTemplates.h" | 16 #include "SkTemplates.h" |
18 #include "SkTypes.h" | 17 #include "SkTypes.h" |
19 | 18 |
20 class SkData; | 19 class SkData; |
| 20 class SkScanlineDecoder; |
21 | 21 |
22 /** | 22 /** |
23 * Abstraction layer directly on top of an image codec. | 23 * Abstraction layer directly on top of an image codec. |
24 */ | 24 */ |
25 class SkCodec : public SkImageGenerator { | 25 class SkCodec : SkNoncopyable { |
26 public: | 26 public: |
27 /** | 27 /** |
28 * If this stream represents an encoded image that we know how to decode, | 28 * If this stream represents an encoded image that we know how to decode, |
29 * return an SkCodec that can decode it. Otherwise return NULL. | 29 * return an SkCodec that can decode it. Otherwise return NULL. |
30 * | 30 * |
31 * If NULL is returned, the stream is deleted immediately. Otherwise, the | 31 * If NULL is returned, the stream is deleted immediately. Otherwise, the |
32 * SkCodec takes ownership of it, and will delete it when done with it. | 32 * SkCodec takes ownership of it, and will delete it when done with it. |
33 */ | 33 */ |
34 static SkCodec* NewFromStream(SkStream*); | 34 static SkCodec* NewFromStream(SkStream*); |
35 | 35 |
36 /** | 36 /** |
37 * If this data represents an encoded image that we know how to decode, | 37 * If this data represents an encoded image that we know how to decode, |
38 * return an SkCodec that can decode it. Otherwise return NULL. | 38 * return an SkCodec that can decode it. Otherwise return NULL. |
39 * | 39 * |
40 * Will take a ref if it returns a codec, else will not affect the data. | 40 * Will take a ref if it returns a codec, else will not affect the data. |
41 */ | 41 */ |
42 static SkCodec* NewFromData(SkData*); | 42 static SkCodec* NewFromData(SkData*); |
43 | 43 |
| 44 virtual ~SkCodec(); |
| 45 |
| 46 /** |
| 47 * Return the ImageInfo associated with this codec. |
| 48 */ |
| 49 const SkImageInfo& getInfo() const { return fInfo; } |
| 50 |
44 /** | 51 /** |
45 * Return a size that approximately supports the desired scale factor. | 52 * Return a size that approximately supports the desired scale factor. |
46 * The codec may not be able to scale efficiently to the exact scale | 53 * The codec may not be able to scale efficiently to the exact scale |
47 * factor requested, so return a size that approximates that scale. | 54 * factor requested, so return a size that approximates that scale. |
48 * | |
49 * FIXME: Move to SkImageGenerator? | |
50 */ | 55 */ |
51 SkISize getScaledDimensions(float desiredScale) const { | 56 SkISize getScaledDimensions(float desiredScale) const { |
52 return this->onGetScaledDimensions(desiredScale); | 57 return this->onGetScaledDimensions(desiredScale); |
53 } | 58 } |
54 | 59 |
55 /** | 60 /** |
56 * Format of the encoded data. | 61 * Format of the encoded data. |
57 */ | 62 */ |
58 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat()
; } | 63 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat()
; } |
59 | 64 |
60 /** | 65 /** |
| 66 * Used to describe the result of a call to getPixels(). |
| 67 * |
| 68 * Result is the union of possible results from subclasses. |
| 69 */ |
| 70 enum Result { |
| 71 /** |
| 72 * General return value for success. |
| 73 */ |
| 74 kSuccess, |
| 75 /** |
| 76 * The input is incomplete. A partial image was generated. |
| 77 */ |
| 78 kIncompleteInput, |
| 79 /** |
| 80 * The generator cannot convert to match the request, ignoring |
| 81 * dimensions. |
| 82 */ |
| 83 kInvalidConversion, |
| 84 /** |
| 85 * The generator cannot scale to requested size. |
| 86 */ |
| 87 kInvalidScale, |
| 88 /** |
| 89 * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes |
| 90 * too small, etc. |
| 91 */ |
| 92 kInvalidParameters, |
| 93 /** |
| 94 * The input did not contain a valid image. |
| 95 */ |
| 96 kInvalidInput, |
| 97 /** |
| 98 * Fulfilling this request requires rewinding the input, which is not |
| 99 * supported for this input. |
| 100 */ |
| 101 kCouldNotRewind, |
| 102 /** |
| 103 * This method is not implemented by this generator. |
| 104 */ |
| 105 kUnimplemented, |
| 106 }; |
| 107 |
| 108 /** |
| 109 * Whether or not the memory passed to getPixels is zero initialized. |
| 110 */ |
| 111 enum ZeroInitialized { |
| 112 /** |
| 113 * The memory passed to getPixels is zero initialized. The SkCodec |
| 114 * may take advantage of this by skipping writing zeroes. |
| 115 */ |
| 116 kYes_ZeroInitialized, |
| 117 /** |
| 118 * The memory passed to getPixels has not been initialized to zero, |
| 119 * so the SkCodec must write all zeroes to memory. |
| 120 * |
| 121 * This is the default. It will be used if no Options struct is used. |
| 122 */ |
| 123 kNo_ZeroInitialized, |
| 124 }; |
| 125 |
| 126 /** |
| 127 * Additional options to pass to getPixels. |
| 128 */ |
| 129 struct Options { |
| 130 Options() |
| 131 : fZeroInitialized(kNo_ZeroInitialized) {} |
| 132 |
| 133 ZeroInitialized fZeroInitialized; |
| 134 }; |
| 135 |
| 136 /** |
| 137 * Decode into the given pixels, a block of memory of size at |
| 138 * least (info.fHeight - 1) * rowBytes + (info.fWidth * |
| 139 * bytesPerPixel) |
| 140 * |
| 141 * Repeated calls to this function should give the same results, |
| 142 * allowing the PixelRef to be immutable. |
| 143 * |
| 144 * @param info A description of the format (config, size) |
| 145 * expected by the caller. This can simply be identical |
| 146 * to the info returned by getInfo(). |
| 147 * |
| 148 * This contract also allows the caller to specify |
| 149 * different output-configs, which the implementation can |
| 150 * decide to support or not. |
| 151 * |
| 152 * A size that does not match getInfo() implies a request |
| 153 * to scale. If the generator cannot perform this scale, |
| 154 * it will return kInvalidScale. |
| 155 * |
| 156 * If info is kIndex8_SkColorType, then the caller must provide storage for
up to 256 |
| 157 * SkPMColor values in ctable. On success the generator must copy N colors
into that storage, |
| 158 * (where N is the logical number of table entries) and set ctableCount to
N. |
| 159 * |
| 160 * If info is not kIndex8_SkColorType, then the last two parameters may be
NULL. If ctableCount |
| 161 * is not null, it will be set to 0. |
| 162 * |
| 163 * @return Result kSuccess, or another value explaining the type of failure
. |
| 164 */ |
| 165 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con
st Options*, |
| 166 SkPMColor ctable[], int* ctableCount); |
| 167 |
| 168 /** |
| 169 * Simplified version of getPixels() that asserts that info is NOT kIndex8_
SkColorType and |
| 170 * uses the default Options. |
| 171 */ |
| 172 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); |
| 173 |
| 174 /** |
61 * Return an object which can be used to decode individual scanlines. | 175 * Return an object which can be used to decode individual scanlines. |
62 * | 176 * |
63 * This object is owned by the SkCodec, which will handle its lifetime. The | 177 * This object is owned by the SkCodec, which will handle its lifetime. The |
64 * returned object is only valid until the SkCodec is deleted or the next | 178 * returned object is only valid until the SkCodec is deleted or the next |
65 * call to getScanlineDecoder, whichever comes first. | 179 * call to getScanlineDecoder, whichever comes first. |
66 * | 180 * |
67 * Calling a second time will rewind and replace the existing one with a | 181 * Calling a second time will rewind and replace the existing one with a |
68 * new one. If the stream cannot be rewound, this will delete the existing | 182 * new one. If the stream cannot be rewound, this will delete the existing |
69 * one and return NULL. | 183 * one and return NULL. |
70 * | 184 * |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 protected: | 225 protected: |
112 SkCodec(const SkImageInfo&, SkStream*); | 226 SkCodec(const SkImageInfo&, SkStream*); |
113 | 227 |
114 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { | 228 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { |
115 // By default, scaling is not supported. | 229 // By default, scaling is not supported. |
116 return this->getInfo().dimensions(); | 230 return this->getInfo().dimensions(); |
117 } | 231 } |
118 | 232 |
119 virtual SkEncodedFormat onGetEncodedFormat() const = 0; | 233 virtual SkEncodedFormat onGetEncodedFormat() const = 0; |
120 | 234 |
| 235 virtual Result onGetPixels(const SkImageInfo& info, |
| 236 void* pixels, size_t rowBytes, const Options&, |
| 237 SkPMColor ctable[], int* ctableCount) = 0; |
| 238 |
121 /** | 239 /** |
122 * Override if your codec supports scanline decoding. | 240 * Override if your codec supports scanline decoding. |
123 * | 241 * |
124 * As in onGetPixels(), the implementation must call rewindIfNeeded() and | 242 * As in onGetPixels(), the implementation must call rewindIfNeeded() and |
125 * handle as appropriate. | 243 * handle as appropriate. |
126 * | 244 * |
127 * @param dstInfo Info of the destination. If the dimensions do not match | 245 * @param dstInfo Info of the destination. If the dimensions do not match |
128 * those of getInfo, this implies a scale. | 246 * those of getInfo, this implies a scale. |
129 * @param options Contains decoding options, including if memory is zero | 247 * @param options Contains decoding options, including if memory is zero |
130 * initialized. | 248 * initialized. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 return fStream.get(); | 293 return fStream.get(); |
176 } | 294 } |
177 | 295 |
178 /** | 296 /** |
179 * If the codec has a scanline decoder, return it (no ownership change occur
s) | 297 * If the codec has a scanline decoder, return it (no ownership change occur
s) |
180 * else return NULL. | 298 * else return NULL. |
181 * The returned decoder is valid while the codec exists and the client has n
ot | 299 * The returned decoder is valid while the codec exists and the client has n
ot |
182 * created a new scanline decoder. | 300 * created a new scanline decoder. |
183 */ | 301 */ |
184 SkScanlineDecoder* scanlineDecoder() { | 302 SkScanlineDecoder* scanlineDecoder() { |
185 return fScanlineDecoder.get(); | 303 return fScanlineDecoder; |
186 } | 304 } |
187 | 305 |
188 /** | 306 /** |
189 * Allow the codec subclass to detach and take ownership of the scanline dec
oder. | 307 * Allow the codec subclass to detach and take ownership of the scanline dec
oder. |
190 * This will likely be used when the scanline decoder needs to be destroyed | 308 * This will likely be used when the scanline decoder needs to be destroyed |
191 * in the destructor of the subclass. | 309 * in the destructor of the subclass. |
192 */ | 310 */ |
193 SkScanlineDecoder* detachScanlineDecoder() { | 311 SkScanlineDecoder* detachScanlineDecoder() { |
194 return fScanlineDecoder.detach(); | 312 SkScanlineDecoder* scanlineDecoder = fScanlineDecoder; |
| 313 fScanlineDecoder = NULL; |
| 314 return scanlineDecoder; |
195 } | 315 } |
196 | 316 |
197 private: | 317 private: |
198 SkAutoTDelete<SkStream> fStream; | 318 const SkImageInfo fInfo; |
199 bool fNeedsRewind; | 319 SkAutoTDelete<SkStream> fStream; |
200 SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder; | 320 bool fNeedsRewind; |
201 | 321 SkScanlineDecoder* fScanlineDecoder; |
202 typedef SkImageGenerator INHERITED; | |
203 }; | 322 }; |
204 #endif // SkCodec_DEFINED | 323 #endif // SkCodec_DEFINED |
OLD | NEW |