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 |
(...skipping 27 matching lines...) Expand all Loading... |
38 * | 38 * |
39 * Will take a ref if it returns a codec, else will not affect the data. | 39 * Will take a ref if it returns a codec, else will not affect the data. |
40 */ | 40 */ |
41 static SkCodec* NewFromData(SkData*); | 41 static SkCodec* NewFromData(SkData*); |
42 | 42 |
43 virtual ~SkCodec(); | 43 virtual ~SkCodec(); |
44 | 44 |
45 /** | 45 /** |
46 * Return the ImageInfo associated with this codec. | 46 * Return the ImageInfo associated with this codec. |
47 */ | 47 */ |
48 const SkImageInfo& getInfo() const { return fInfo; } | 48 const SkImageInfo& getInfo() const { return fSrcInfo; } |
49 | 49 |
50 /** | 50 /** |
51 * Return a size that approximately supports the desired scale factor. | 51 * Return a size that approximately supports the desired scale factor. |
52 * The codec may not be able to scale efficiently to the exact scale | 52 * The codec may not be able to scale efficiently to the exact scale |
53 * factor requested, so return a size that approximates that scale. | 53 * factor requested, so return a size that approximates that scale. |
54 * The returned value is the codec's suggestion for the closest valid | 54 * The returned value is the codec's suggestion for the closest valid |
55 * scale that it can natively support | 55 * scale that it can natively support |
56 */ | 56 */ |
57 SkISize getScaledDimensions(float desiredScale) const { | 57 SkISize getScaledDimensions(float desiredScale) const { |
58 // Negative and zero scales are errors. | 58 // Negative and zero scales are errors. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 /** | 124 /** |
125 * The input did not contain a valid image. | 125 * The input did not contain a valid image. |
126 */ | 126 */ |
127 kInvalidInput, | 127 kInvalidInput, |
128 /** | 128 /** |
129 * Fulfilling this request requires rewinding the input, which is not | 129 * Fulfilling this request requires rewinding the input, which is not |
130 * supported for this input. | 130 * supported for this input. |
131 */ | 131 */ |
132 kCouldNotRewind, | 132 kCouldNotRewind, |
133 /** | 133 /** |
134 * This method is not implemented by this generator. | 134 * startScanlineDecode() was not called before calling getScanlines. |
| 135 */ |
| 136 kScanlineDecodingNotStarted, |
| 137 /** |
| 138 * This method is not implemented by this codec. |
| 139 * FIXME: Perhaps this should be kUnsupported? |
135 */ | 140 */ |
136 kUnimplemented, | 141 kUnimplemented, |
137 }; | 142 }; |
138 | 143 |
139 /** | 144 /** |
140 * Whether or not the memory passed to getPixels is zero initialized. | 145 * Whether or not the memory passed to getPixels is zero initialized. |
141 */ | 146 */ |
142 enum ZeroInitialized { | 147 enum ZeroInitialized { |
143 /** | 148 /** |
144 * The memory passed to getPixels is zero initialized. The SkCodec | 149 * The memory passed to getPixels is zero initialized. The SkCodec |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 * to scale. If the generator cannot perform this scale, | 200 * to scale. If the generator cannot perform this scale, |
196 * it will return kInvalidScale. | 201 * it will return kInvalidScale. |
197 * | 202 * |
198 * If info is kIndex8_SkColorType, then the caller must provide storage for
up to 256 | 203 * If info is kIndex8_SkColorType, then the caller must provide storage for
up to 256 |
199 * SkPMColor values in ctable. On success the generator must copy N colors
into that storage, | 204 * SkPMColor values in ctable. On success the generator must copy N colors
into that storage, |
200 * (where N is the logical number of table entries) and set ctableCount to
N. | 205 * (where N is the logical number of table entries) and set ctableCount to
N. |
201 * | 206 * |
202 * If info is not kIndex8_SkColorType, then the last two parameters may be
NULL. If ctableCount | 207 * If info is not kIndex8_SkColorType, then the last two parameters may be
NULL. If ctableCount |
203 * is not null, it will be set to 0. | 208 * is not null, it will be set to 0. |
204 * | 209 * |
| 210 * If a scanline decode is in progress, scanline mode will end, requiring t
he client to call |
| 211 * startScanlineDecode() in order to return to decoding scanlines. |
| 212 * |
205 * @return Result kSuccess, or another value explaining the type of failure
. | 213 * @return Result kSuccess, or another value explaining the type of failure
. |
206 */ | 214 */ |
207 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con
st Options*, | 215 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, con
st Options*, |
208 SkPMColor ctable[], int* ctableCount); | 216 SkPMColor ctable[], int* ctableCount); |
209 | 217 |
210 /** | 218 /** |
211 * Simplified version of getPixels() that asserts that info is NOT kIndex8_
SkColorType and | 219 * Simplified version of getPixels() that asserts that info is NOT kIndex8_
SkColorType and |
212 * uses the default Options. | 220 * uses the default Options. |
213 */ | 221 */ |
214 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); | 222 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); |
215 | 223 |
216 /** | 224 /** |
217 * Some images may initially report that they have alpha due to the format | 225 * Some images may initially report that they have alpha due to the format |
218 * of the encoded data, but then never use any colors which have alpha | 226 * of the encoded data, but then never use any colors which have alpha |
219 * less than 100%. This function can be called *after* decoding to | 227 * less than 100%. This function can be called *after* decoding to |
220 * determine if such an image truly had alpha. Calling it before decoding | 228 * determine if such an image truly had alpha. Calling it before decoding |
221 * is undefined. | 229 * is undefined. |
222 * FIXME: see skbug.com/3582. | 230 * FIXME: see skbug.com/3582. |
223 */ | 231 */ |
224 bool reallyHasAlpha() const { | 232 bool reallyHasAlpha() const { |
225 return this->onReallyHasAlpha(); | 233 return this->onReallyHasAlpha(); |
226 } | 234 } |
227 | 235 |
| 236 /** |
| 237 * The remaining functions revolve around decoding scanlines. |
| 238 */ |
| 239 |
| 240 /** |
| 241 * Prepare for a scanline decode with the specified options. |
| 242 * |
| 243 * After this call, this class will be ready to decode the first scanline. |
| 244 * |
| 245 * This must be called in order to call getScanlines or skipScanlines. |
| 246 * |
| 247 * This may require rewinding the stream. |
| 248 * |
| 249 * Not all SkCodecs support this. |
| 250 * |
| 251 * @param dstInfo Info of the destination. If the dimensions do not match |
| 252 * those of getInfo, this implies a scale. |
| 253 * @param options Contains decoding options, including if memory is zero |
| 254 * initialized. |
| 255 * @param ctable A pointer to a color table. When dstInfo.colorType() is |
| 256 * kIndex8, this should be non-NULL and have enough storage for 256 |
| 257 * colors. The color table will be populated after decoding the palett
e. |
| 258 * @param ctableCount A pointer to the size of the color table. When |
| 259 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will |
| 260 * be modified to the true size of the color table (<= 256) after |
| 261 * decoding the palette. |
| 262 * @return Enum representing success or reason for failure. |
| 263 */ |
| 264 Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Option
s* options, |
| 265 SkPMColor ctable[], int* ctableCount); |
| 266 |
| 267 /** |
| 268 * Simplified version of startScanlineDecode() that asserts that info is NO
T |
| 269 * kIndex8_SkColorType and uses the default Options. |
| 270 */ |
| 271 Result startScanlineDecode(const SkImageInfo& dstInfo); |
| 272 |
| 273 /** |
| 274 * Write the next countLines scanlines into dst. |
| 275 * |
| 276 * Not valid to call before calling startScanlineDecode(). |
| 277 * |
| 278 * @param dst Must be non-null, and large enough to hold countLines |
| 279 * scanlines of size rowBytes. |
| 280 * @param countLines Number of lines to write. |
| 281 * @param rowBytes Number of bytes per row. Must be large enough to hold |
| 282 * a scanline based on the SkImageInfo used to create this object. |
| 283 */ |
| 284 Result getScanlines(void* dst, int countLines, size_t rowBytes); |
| 285 |
| 286 /** |
| 287 * Skip count scanlines. |
| 288 * |
| 289 * Not valid to call before calling startScanlineDecode(). |
| 290 * |
| 291 * The default version just calls onGetScanlines and discards the dst. |
| 292 * NOTE: If skipped lines are the only lines with alpha, this default |
| 293 * will make reallyHasAlpha return true, when it could have returned |
| 294 * false. |
| 295 */ |
| 296 Result skipScanlines(int countLines); |
| 297 |
| 298 /** |
| 299 * The order in which rows are output from the scanline decoder is not the |
| 300 * same for all variations of all image types. This explains the possible |
| 301 * output row orderings. |
| 302 */ |
| 303 enum SkScanlineOrder { |
| 304 /* |
| 305 * By far the most common, this indicates that the image can be decoded |
| 306 * reliably using the scanline decoder, and that rows will be output in |
| 307 * the logical order. |
| 308 */ |
| 309 kTopDown_SkScanlineOrder, |
| 310 |
| 311 /* |
| 312 * This indicates that the scanline decoder reliably outputs rows, but |
| 313 * they will be returned in reverse order. If the scanline format is |
| 314 * kBottomUp, the nextScanline() API can be used to determine the actual |
| 315 * y-coordinate of the next output row, but the client is not forced |
| 316 * to take advantage of this, given that it's not too tough to keep |
| 317 * track independently. |
| 318 * |
| 319 * For full image decodes, it is safe to get all of the scanlines at |
| 320 * once, since the decoder will handle inverting the rows as it |
| 321 * decodes. |
| 322 * |
| 323 * For subset decodes and sampling, it is simplest to get and skip |
| 324 * scanlines one at a time, using the nextScanline() API. It is |
| 325 * possible to ask for larger chunks at a time, but this should be used |
| 326 * with caution. As with full image decodes, the decoder will handle |
| 327 * inverting the requested rows, but rows will still be delivered |
| 328 * starting from the bottom of the image. |
| 329 * |
| 330 * Upside down bmps are an example. |
| 331 */ |
| 332 kBottomUp_SkScanlineOrder, |
| 333 |
| 334 /* |
| 335 * This indicates that the scanline decoder reliably outputs rows, but |
| 336 * they will not be in logical order. If the scanline format is |
| 337 * kOutOfOrder, the nextScanline() API should be used to determine the |
| 338 * actual y-coordinate of the next output row. |
| 339 * |
| 340 * For this scanline ordering, it is advisable to get and skip |
| 341 * scanlines one at a time. |
| 342 * |
| 343 * Interlaced gifs are an example. |
| 344 */ |
| 345 kOutOfOrder_SkScanlineOrder, |
| 346 |
| 347 /* |
| 348 * Indicates that the entire image must be decoded in order to output |
| 349 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to |
| 350 * request scanlines 1-by-1 or in small chunks. The client should |
| 351 * determine which scanlines are needed and ask for all of them in |
| 352 * a single call to getScanlines(). |
| 353 * |
| 354 * Interlaced pngs are an example. |
| 355 */ |
| 356 kNone_SkScanlineOrder, |
| 357 }; |
| 358 |
| 359 /** |
| 360 * An enum representing the order in which scanlines will be returned by |
| 361 * the scanline decoder. |
| 362 */ |
| 363 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } |
| 364 |
| 365 /** |
| 366 * Returns the y-coordinate of the next row to be returned by the scanline |
| 367 * decoder. This will be overridden in the case of |
| 368 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of |
| 369 * kNone_SkScanlineOrder. |
| 370 * |
| 371 * Results are undefined when not in scanline decoding mode. |
| 372 */ |
| 373 int nextScanline() const { |
| 374 return this->onNextScanline(); |
| 375 } |
| 376 |
228 protected: | 377 protected: |
229 SkCodec(const SkImageInfo&, SkStream*); | 378 SkCodec(const SkImageInfo&, SkStream*); |
230 | 379 |
231 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { | 380 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { |
232 // By default, scaling is not supported. | 381 // By default, scaling is not supported. |
233 return this->getInfo().dimensions(); | 382 return this->getInfo().dimensions(); |
234 } | 383 } |
235 | 384 |
236 virtual SkEncodedFormat onGetEncodedFormat() const = 0; | 385 virtual SkEncodedFormat onGetEncodedFormat() const = 0; |
237 | 386 |
(...skipping 30 matching lines...) Expand all Loading... |
268 return true; | 417 return true; |
269 } | 418 } |
270 | 419 |
271 /** | 420 /** |
272 * Get method for the input stream | 421 * Get method for the input stream |
273 */ | 422 */ |
274 SkStream* stream() { | 423 SkStream* stream() { |
275 return fStream.get(); | 424 return fStream.get(); |
276 } | 425 } |
277 | 426 |
| 427 /** |
| 428 * The remaining functions revolve around decoding scanlines. |
| 429 */ |
| 430 |
| 431 /** |
| 432 * Most images types will be kTopDown and will not need to override this fu
nction. |
| 433 */ |
| 434 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl
ineOrder; } |
| 435 |
| 436 /** |
| 437 * Most images will be kTopDown and will not need to override this function
. |
| 438 */ |
| 439 virtual int onNextScanline() const { return fCurrScanline; } |
| 440 |
| 441 /** |
| 442 * Update the next scanline. Used by interlaced png. |
| 443 */ |
| 444 void updateNextScanline(int newY) { fCurrScanline = newY; } |
| 445 |
| 446 const SkImageInfo& dstInfo() const { return fDstInfo; } |
| 447 |
| 448 const SkCodec::Options& options() const { return fOptions; } |
| 449 |
278 private: | 450 private: |
279 const SkImageInfo fInfo; | 451 const SkImageInfo fSrcInfo; |
280 SkAutoTDelete<SkStream> fStream; | 452 SkAutoTDelete<SkStream> fStream; |
281 bool fNeedsRewind; | 453 bool fNeedsRewind; |
| 454 // These fields are only meaningful during scanline decodes. |
| 455 SkImageInfo fDstInfo; |
| 456 SkCodec::Options fOptions; |
| 457 int fCurrScanline; |
| 458 |
| 459 // Methods for scanline decoding. |
| 460 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, |
| 461 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun
t) { |
| 462 return kUnimplemented; |
| 463 } |
| 464 |
| 465 // Naive default version just calls onGetScanlines on temp memory. |
| 466 virtual SkCodec::Result onSkipScanlines(int countLines) { |
| 467 SkAutoMalloc storage(fDstInfo.minRowBytes()); |
| 468 // Note that we pass 0 to rowBytes so we continue to use the same memory
. |
| 469 // Also note that while getScanlines checks that rowBytes is big enough, |
| 470 // onGetScanlines bypasses that check. |
| 471 // Calling the virtual method also means we do not double count |
| 472 // countLines. |
| 473 return this->onGetScanlines(storage.get(), countLines, 0); |
| 474 } |
| 475 |
| 476 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, |
| 477 size_t rowBytes) { |
| 478 return kUnimplemented; |
| 479 } |
| 480 |
282 }; | 481 }; |
283 #endif // SkCodec_DEFINED | 482 #endif // SkCodec_DEFINED |
OLD | NEW |