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 113 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 * startScanlineDecode() was not called before calling getScanlines. | |
135 */ | |
136 kScanlineDecodingNotStarted, | |
137 /** | |
138 * This method is not implemented by this codec. | 134 * This method is not implemented by this codec. |
139 * FIXME: Perhaps this should be kUnsupported? | 135 * FIXME: Perhaps this should be kUnsupported? |
140 */ | 136 */ |
141 kUnimplemented, | 137 kUnimplemented, |
142 }; | 138 }; |
143 | 139 |
144 /** | 140 /** |
145 * Whether or not the memory passed to getPixels is zero initialized. | 141 * Whether or not the memory passed to getPixels is zero initialized. |
146 */ | 142 */ |
147 enum ZeroInitialized { | 143 enum ZeroInitialized { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 /** | 269 /** |
274 * Write the next countLines scanlines into dst. | 270 * Write the next countLines scanlines into dst. |
275 * | 271 * |
276 * Not valid to call before calling startScanlineDecode(). | 272 * Not valid to call before calling startScanlineDecode(). |
277 * | 273 * |
278 * @param dst Must be non-null, and large enough to hold countLines | 274 * @param dst Must be non-null, and large enough to hold countLines |
279 * scanlines of size rowBytes. | 275 * scanlines of size rowBytes. |
280 * @param countLines Number of lines to write. | 276 * @param countLines Number of lines to write. |
281 * @param rowBytes Number of bytes per row. Must be large enough to hold | 277 * @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. | 278 * a scanline based on the SkImageInfo used to create this object. |
279 * @return the number of lines successfully decoded. If this value is | |
280 * less than countLines, this will fill the remaining lines with a | |
281 * default value. | |
283 */ | 282 */ |
284 Result getScanlines(void* dst, int countLines, size_t rowBytes); | 283 int getScanlines(void* dst, int countLines, size_t rowBytes); |
djsollen
2015/10/05 12:15:39
what do you expect the caller to do with this valu
scroggo
2015/10/05 13:12:24
This is something we discussed and were not very s
reed1
2015/10/06 18:40:02
What is the default value? Can it be provided by t
msarett
2015/10/06 18:47:40
/**
* kN32_SkColorType: Transparent or Black
* k
| |
285 | 284 |
286 /** | 285 /** |
287 * Skip count scanlines. | 286 * Skip count scanlines. |
288 * | 287 * |
289 * Not valid to call before calling startScanlineDecode(). | 288 * Not valid to call before calling startScanlineDecode(). |
290 * | 289 * |
291 * The default version just calls onGetScanlines and discards the dst. | 290 * The default version just calls onGetScanlines and discards the dst. |
292 * NOTE: If skipped lines are the only lines with alpha, this default | 291 * NOTE: If skipped lines are the only lines with alpha, this default |
293 * will make reallyHasAlpha return true, when it could have returned | 292 * will make reallyHasAlpha return true, when it could have returned |
294 * false. | 293 * false. |
294 * | |
295 * @return true if the scanlines were successfully skipped | |
296 * false on failure, possible reasons for failure include: | |
297 * An incomplete input image stream. | |
298 * Calling this function before calling startScanlineDecode(). | |
299 * If countLines is less than zero or so large that it moves | |
300 * the current scanline past the end of the image. | |
295 */ | 301 */ |
296 Result skipScanlines(int countLines); | 302 bool skipScanlines(int countLines); |
297 | 303 |
298 /** | 304 /** |
299 * The order in which rows are output from the scanline decoder is not the | 305 * 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 | 306 * same for all variations of all image types. This explains the possible |
301 * output row orderings. | 307 * output row orderings. |
302 */ | 308 */ |
303 enum SkScanlineOrder { | 309 enum SkScanlineOrder { |
304 /* | 310 /* |
305 * By far the most common, this indicates that the image can be decoded | 311 * 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 | 312 * reliably using the scanline decoder, and that rows will be output in |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 }; | 363 }; |
358 | 364 |
359 /** | 365 /** |
360 * An enum representing the order in which scanlines will be returned by | 366 * An enum representing the order in which scanlines will be returned by |
361 * the scanline decoder. | 367 * the scanline decoder. |
362 */ | 368 */ |
363 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; } | 369 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; } |
364 | 370 |
365 /** | 371 /** |
366 * Returns the y-coordinate of the next row to be returned by the scanline | 372 * Returns the y-coordinate of the next row to be returned by the scanline |
367 * decoder. This will be overridden in the case of | 373 * decoder. |
368 * kOutOfOrder_SkScanlineOrder and should be unnecessary in the case of | 374 * |
369 * kNone_SkScanlineOrder. | 375 * This will equal fCurrScanline, except in the case of strangely |
376 * encoded image types (bottom-up bmps, interlaced gifs). | |
370 * | 377 * |
371 * Results are undefined when not in scanline decoding mode. | 378 * Results are undefined when not in scanline decoding mode. |
372 */ | 379 */ |
373 int nextScanline() const { | 380 int nextScanline() const { return this->outputScanline(fCurrScanline); } |
374 return this->onNextScanline(); | 381 |
375 } | 382 /** |
383 * Returns the output y-coordinate of the row that corresponds to an input | |
384 * y-coordinate. The input y-coordinate represents where the scanline | |
385 * is located in the encoded data. | |
386 * | |
387 * This will equal inputScanline, except in the case of strangely | |
388 * encoded image types (bottom-up bmps, interlaced gifs). | |
389 */ | |
390 int outputScanline(int inputScanline) const; | |
376 | 391 |
377 protected: | 392 protected: |
378 SkCodec(const SkImageInfo&, SkStream*); | 393 SkCodec(const SkImageInfo&, SkStream*); |
379 | 394 |
380 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { | 395 virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { |
381 // By default, scaling is not supported. | 396 // By default, scaling is not supported. |
382 return this->getInfo().dimensions(); | 397 return this->getInfo().dimensions(); |
383 } | 398 } |
384 | 399 |
385 virtual SkEncodedFormat onGetEncodedFormat() const = 0; | 400 virtual SkEncodedFormat onGetEncodedFormat() const = 0; |
386 | 401 |
402 /** | |
403 * @param rowsDecoded When the encoded image stream is incomplete, this func tion | |
404 * will return kIncompleteInput and rowsDecoded will be s et to | |
405 * the number of scanlines that were successfully decoded . | |
406 * This will allow getPixels() to fill the uninitialized memory. | |
407 */ | |
387 virtual Result onGetPixels(const SkImageInfo& info, | 408 virtual Result onGetPixels(const SkImageInfo& info, |
388 void* pixels, size_t rowBytes, const Options&, | 409 void* pixels, size_t rowBytes, const Options&, |
389 SkPMColor ctable[], int* ctableCount) = 0; | 410 SkPMColor ctable[], int* ctableCount, |
411 int* rowsDecoded) = 0; | |
390 | 412 |
391 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { | 413 virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { |
392 // By default, subsets are not supported. | 414 // By default, subsets are not supported. |
393 return false; | 415 return false; |
394 } | 416 } |
395 | 417 |
396 virtual bool onReallyHasAlpha() const { return false; } | 418 virtual bool onReallyHasAlpha() const { return false; } |
397 | 419 |
398 /** | 420 /** |
399 * If the stream was previously read, attempt to rewind. | 421 * If the stream was previously read, attempt to rewind. |
(...skipping 10 matching lines...) Expand all Loading... | |
410 /** | 432 /** |
411 * Called by rewindIfNeeded, if the stream needed to be rewound. | 433 * Called by rewindIfNeeded, if the stream needed to be rewound. |
412 * | 434 * |
413 * Subclasses should do any set up needed after a rewind. | 435 * Subclasses should do any set up needed after a rewind. |
414 */ | 436 */ |
415 virtual bool onRewind() { | 437 virtual bool onRewind() { |
416 return true; | 438 return true; |
417 } | 439 } |
418 | 440 |
419 /** | 441 /** |
442 * On an incomplete input, getPixels() and getScanlines() will fill any unin itialized | |
443 * scanlines. This allows the subclass to indicate what value to fill with. | |
444 * | |
445 * @param colorType Destination color type. | |
446 * @param alphaType Destination alpha type. | |
447 * @return The value with which to fill uninitialized pixels. | |
448 * | |
449 * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color, | |
450 * an 8-bit gray color, or an 8-bit index into a color table, depending on t he color | |
451 * type specified in dstInfo. | |
452 */ | |
453 uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const { | |
454 return this->onGetFillValue(colorType, alphaType); | |
455 } | |
456 | |
457 /** | |
458 * Some subclasses will override this function, but this is a useful default for the color | |
459 * types that we support. Note that for color types that do not use the ful l 32-bits, | |
460 * we will simply take the low bits of the fill value. | |
461 * | |
462 * kN32_SkColorType: Transparent or Black | |
463 * kRGB_565_SkColorType: Black | |
464 * kGray_8_SkColorType: Black | |
465 * kIndex_8_SkColorType: First color in color table | |
466 */ | |
467 virtual uint32_t onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const { | |
468 return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSP ARENT; | |
469 } | |
470 | |
471 /** | |
420 * Get method for the input stream | 472 * Get method for the input stream |
421 */ | 473 */ |
422 SkStream* stream() { | 474 SkStream* stream() { |
423 return fStream.get(); | 475 return fStream.get(); |
424 } | 476 } |
425 | 477 |
426 /** | 478 /** |
427 * The remaining functions revolve around decoding scanlines. | 479 * The remaining functions revolve around decoding scanlines. |
428 */ | 480 */ |
429 | 481 |
430 /** | 482 /** |
431 * Most images types will be kTopDown and will not need to override this fu nction. | 483 * Most images types will be kTopDown and will not need to override this fu nction. |
432 */ | 484 */ |
433 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; } | 485 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl ineOrder; } |
434 | 486 |
435 /** | 487 /** |
436 * Most images will be kTopDown and will not need to override this function . | |
437 */ | |
438 virtual int onNextScanline() const { return fCurrScanline; } | |
439 | |
440 /** | |
441 * Update the next scanline. Used by interlaced png. | 488 * Update the next scanline. Used by interlaced png. |
442 */ | 489 */ |
443 void updateNextScanline(int newY) { fCurrScanline = newY; } | 490 void updateNextScanline(int newY) { fCurrScanline = newY; } |
444 | 491 |
445 const SkImageInfo& dstInfo() const { return fDstInfo; } | 492 const SkImageInfo& dstInfo() const { return fDstInfo; } |
446 | 493 |
447 const SkCodec::Options& options() const { return fOptions; } | 494 const SkCodec::Options& options() const { return fOptions; } |
448 | 495 |
449 private: | 496 private: |
450 const SkImageInfo fSrcInfo; | 497 const SkImageInfo fSrcInfo; |
451 SkAutoTDelete<SkStream> fStream; | 498 SkAutoTDelete<SkStream> fStream; |
452 bool fNeedsRewind; | 499 bool fNeedsRewind; |
453 // These fields are only meaningful during scanline decodes. | 500 // These fields are only meaningful during scanline decodes. |
454 SkImageInfo fDstInfo; | 501 SkImageInfo fDstInfo; |
455 SkCodec::Options fOptions; | 502 SkCodec::Options fOptions; |
456 int fCurrScanline; | 503 int fCurrScanline; |
457 | 504 |
458 // Methods for scanline decoding. | 505 // Methods for scanline decoding. |
459 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, | 506 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, |
460 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { | 507 const SkCodec::Options& options, SkPMColor ctable[], int* ctableCoun t) { |
461 return kUnimplemented; | 508 return kUnimplemented; |
462 } | 509 } |
463 | 510 |
464 // Naive default version just calls onGetScanlines on temp memory. | 511 // Naive default version just calls onGetScanlines on temp memory. |
465 virtual SkCodec::Result onSkipScanlines(int countLines) { | 512 virtual bool onSkipScanlines(int countLines) { |
513 // FIXME (msarett): Make this a pure virtual and always override this. | |
466 SkAutoMalloc storage(fDstInfo.minRowBytes()); | 514 SkAutoMalloc storage(fDstInfo.minRowBytes()); |
515 | |
467 // Note that we pass 0 to rowBytes so we continue to use the same memory . | 516 // Note that we pass 0 to rowBytes so we continue to use the same memory . |
468 // Also note that while getScanlines checks that rowBytes is big enough, | 517 // Also note that while getScanlines checks that rowBytes is big enough, |
469 // onGetScanlines bypasses that check. | 518 // onGetScanlines bypasses that check. |
470 // Calling the virtual method also means we do not double count | 519 // Calling the virtual method also means we do not double count |
471 // countLines. | 520 // countLines. |
472 return this->onGetScanlines(storage.get(), countLines, 0); | 521 return countLines == this->onGetScanlines(storage.get(), countLines, 0); |
473 } | 522 } |
474 | 523 |
475 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, | 524 virtual int onGetScanlines(void* dst, int countLines, size_t rowBytes) { ret urn 0; } |
476 size_t rowBytes) { | |
477 return kUnimplemented; | |
478 } | |
479 | 525 |
526 /** | |
527 * On an incomplete decode, getPixels() and getScanlines() will call this fu nction | |
528 * to fill any uinitialized memory. | |
529 * | |
530 * @param info Destination image info | |
531 * @param dst Pointer to the start of destination pixel memory | |
532 * @param rowBytes Stride length in destination pixel memory | |
533 * @param zeroInit Indicates if memory is zero initialized | |
534 * @param linesRequested Number of lines that the client requested | |
535 * @param linesDecoded Number of lines that were successfully decoded | |
536 */ | |
537 void fillIncompleteImage(const SkImageInfo& info, void* dst, size_t rowBytes , | |
538 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); | |
539 | |
540 // Needed to call getFillColor() | |
541 friend class SkScaledCodec; | |
480 }; | 542 }; |
481 #endif // SkCodec_DEFINED | 543 #endif // SkCodec_DEFINED |
OLD | NEW |