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 "../private/SkTemplates.h" | 11 #include "../private/SkTemplates.h" |
12 #include "SkColor.h" | 12 #include "SkColor.h" |
13 #include "SkEncodedFormat.h" | 13 #include "SkEncodedFormat.h" |
14 #include "SkEncodedInfo.h" | 14 #include "SkEncodedInfo.h" |
15 #include "SkImageInfo.h" | 15 #include "SkImageInfo.h" |
16 #include "SkSize.h" | 16 #include "SkSize.h" |
17 #include "SkStream.h" | 17 #include "SkStream.h" |
18 #include "SkTypes.h" | 18 #include "SkTypes.h" |
19 #include "SkYUVSizeInfo.h" | 19 #include "SkYUVSizeInfo.h" |
20 | 20 |
21 class SkColorSpace; | 21 class SkColorSpace; |
22 class SkData; | 22 class SkData; |
23 class SkPngChunkReader; | 23 class SkPngChunkReader; |
24 class SkSampler; | 24 class SkSampler; |
25 | 25 |
26 namespace DM { | 26 namespace DM { |
| 27 class CodecSrc; |
27 class ColorCodecSrc; | 28 class ColorCodecSrc; |
28 } | 29 } |
29 class ColorCodecBench; | 30 class ColorCodecBench; |
30 | 31 |
31 | |
32 /** | 32 /** |
33 * Abstraction layer directly on top of an image codec. | 33 * Abstraction layer directly on top of an image codec. |
34 */ | 34 */ |
35 class SkCodec : SkNoncopyable { | 35 class SkCodec : SkNoncopyable { |
36 public: | 36 public: |
37 /** | 37 /** |
38 * Minimum number of bytes that must be buffered in SkStream input. | 38 * Minimum number of bytes that must be buffered in SkStream input. |
39 * | 39 * |
40 * An SkStream passed to NewFromStream must be able to use this many | 40 * An SkStream passed to NewFromStream must be able to use this many |
41 * bytes to determine the image type. Then the same SkStream must be | 41 * bytes to determine the image type. Then the same SkStream must be |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 , fSubset(NULL) | 246 , fSubset(NULL) |
247 {} | 247 {} |
248 | 248 |
249 ZeroInitialized fZeroInitialized; | 249 ZeroInitialized fZeroInitialized; |
250 /** | 250 /** |
251 * If not NULL, represents a subset of the original image to decode. | 251 * If not NULL, represents a subset of the original image to decode. |
252 * Must be within the bounds returned by getInfo(). | 252 * Must be within the bounds returned by getInfo(). |
253 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which | 253 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which |
254 * currently supports subsets), the top and left values must be even. | 254 * currently supports subsets), the top and left values must be even. |
255 * | 255 * |
256 * In getPixels, we will attempt to decode the exact rectangular | 256 * In getPixels and incremental decode, we will attempt to decode the |
257 * subset specified by fSubset. | 257 * exact rectangular subset specified by fSubset. |
258 * | 258 * |
259 * In a scanline decode, it does not make sense to specify a subset | 259 * In a scanline decode, it does not make sense to specify a subset |
260 * top or subset height, since the client already controls which rows | 260 * top or subset height, since the client already controls which rows |
261 * to get and which rows to skip. During scanline decodes, we will | 261 * to get and which rows to skip. During scanline decodes, we will |
262 * require that the subset top be zero and the subset height be equal | 262 * require that the subset top be zero and the subset height be equal |
263 * to the full height. We will, however, use the values of | 263 * to the full height. We will, however, use the values of |
264 * subset left and subset width to decode partial scanlines on calls | 264 * subset left and subset width to decode partial scanlines on calls |
265 * to getScanlines(). | 265 * to getScanlines(). |
266 */ | 266 */ |
267 SkIRect* fSubset; | 267 SkIRect* fSubset; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 } | 348 } |
349 | 349 |
350 if (!this->rewindIfNeeded()) { | 350 if (!this->rewindIfNeeded()) { |
351 return kCouldNotRewind; | 351 return kCouldNotRewind; |
352 } | 352 } |
353 | 353 |
354 return this->onGetYUV8Planes(sizeInfo, planes); | 354 return this->onGetYUV8Planes(sizeInfo, planes); |
355 } | 355 } |
356 | 356 |
357 /** | 357 /** |
| 358 * Prepare for an incremental decode with the specified options. |
| 359 * |
| 360 * This may require a rewind. |
| 361 * |
| 362 * @param dstInfo Info of the destination. If the dimensions do not match |
| 363 * those of getInfo, this implies a scale. |
| 364 * @param dst Memory to write to. Needs to be large enough to hold the subs
et, |
| 365 * if present, or the full image as described in dstInfo. |
| 366 * @param options Contains decoding options, including if memory is zero |
| 367 * initialized and whether to decode a subset. |
| 368 * @param ctable A pointer to a color table. When dstInfo.colorType() is |
| 369 * kIndex8, this should be non-NULL and have enough storage for 256 |
| 370 * colors. The color table will be populated after decoding the palett
e. |
| 371 * @param ctableCount A pointer to the size of the color table. When |
| 372 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will |
| 373 * be modified to the true size of the color table (<= 256) after |
| 374 * decoding the palette. |
| 375 * @return Enum representing success or reason for failure. |
| 376 */ |
| 377 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t
rowBytes, |
| 378 const SkCodec::Options*, SkPMColor* ctable, int* ctableCount); |
| 379 |
| 380 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t
rowBytes, |
| 381 const SkCodec::Options* options) { |
| 382 return this->startIncrementalDecode(dstInfo, dst, rowBytes, options, nul
lptr, nullptr); |
| 383 } |
| 384 |
| 385 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t
rowBytes) { |
| 386 return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr, nul
lptr, nullptr); |
| 387 } |
| 388 |
| 389 /** |
| 390 * Start/continue the incremental decode. |
| 391 * |
| 392 * Not valid to call before calling startIncrementalDecode(). |
| 393 * |
| 394 * After the first call, should only be called again if more data has been |
| 395 * provided to the source SkStream. |
| 396 * |
| 397 * Unlike getPixels and getScanlines, this does not do any filling. This is |
| 398 * left up to the caller, since they may be skipping lines or continuing th
e |
| 399 * decode later. In the latter case, they may choose to initialize all line
s |
| 400 * first, or only initialize the remaining lines after the first call. |
| 401 * |
| 402 * @param rowsDecoded Optional output variable returning the total number o
f |
| 403 * lines initialized. Only meaningful if this method returns kIncomplet
eInput. |
| 404 * Otherwise the implementation may not set it. |
| 405 * Note that some implementations may have initialized this many rows,
but |
| 406 * not necessarily finished those rows (e.g. interlaced PNG). This may
be |
| 407 * useful for determining what rows the client needs to initialize. |
| 408 * @return kSuccess if all lines requested in startIncrementalDecode have |
| 409 * been completely decoded. kIncompleteInput otherwise. |
| 410 */ |
| 411 Result incrementalDecode(int* rowsDecoded = nullptr) { |
| 412 if (!fStartedIncrementalDecode) { |
| 413 return kInvalidParameters; |
| 414 } |
| 415 return this->onIncrementalDecode(rowsDecoded); |
| 416 } |
| 417 |
| 418 /** |
358 * The remaining functions revolve around decoding scanlines. | 419 * The remaining functions revolve around decoding scanlines. |
359 */ | 420 */ |
360 | 421 |
361 /** | 422 /** |
362 * Prepare for a scanline decode with the specified options. | 423 * Prepare for a scanline decode with the specified options. |
363 * | 424 * |
364 * After this call, this class will be ready to decode the first scanline. | 425 * After this call, this class will be ready to decode the first scanline. |
365 * | 426 * |
366 * This must be called in order to call getScanlines or skipScanlines. | 427 * This must be called in order to call getScanlines or skipScanlines. |
367 * | 428 * |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 * they will not be in logical order. If the scanline format is | 528 * they will not be in logical order. If the scanline format is |
468 * kOutOfOrder, the nextScanline() API should be used to determine the | 529 * kOutOfOrder, the nextScanline() API should be used to determine the |
469 * actual y-coordinate of the next output row. | 530 * actual y-coordinate of the next output row. |
470 * | 531 * |
471 * For this scanline ordering, it is advisable to get and skip | 532 * For this scanline ordering, it is advisable to get and skip |
472 * scanlines one at a time. | 533 * scanlines one at a time. |
473 * | 534 * |
474 * Interlaced gifs are an example. | 535 * Interlaced gifs are an example. |
475 */ | 536 */ |
476 kOutOfOrder_SkScanlineOrder, | 537 kOutOfOrder_SkScanlineOrder, |
477 | |
478 /* | |
479 * Indicates that the entire image must be decoded in order to output | |
480 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to | |
481 * request scanlines 1-by-1 or in small chunks. The client should | |
482 * determine which scanlines are needed and ask for all of them in | |
483 * a single call to getScanlines(). | |
484 * | |
485 * Interlaced pngs are an example. | |
486 */ | |
487 kNone_SkScanlineOrder, | |
488 }; | 538 }; |
489 | 539 |
490 /** | 540 /** |
491 * An enum representing the order in which scanlines will be returned by | 541 * An enum representing the order in which scanlines will be returned by |
492 * the scanline decoder. | 542 * the scanline decoder. |
493 * | 543 * |
494 * This is undefined before startScanlineDecode() is called. | 544 * This is undefined before startScanlineDecode() is called. |
495 */ | 545 */ |
496 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } | 546 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } |
497 | 547 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 685 |
636 /** | 686 /** |
637 * The remaining functions revolve around decoding scanlines. | 687 * The remaining functions revolve around decoding scanlines. |
638 */ | 688 */ |
639 | 689 |
640 /** | 690 /** |
641 * Most images types will be kTopDown and will not need to override this fu
nction. | 691 * Most images types will be kTopDown and will not need to override this fu
nction. |
642 */ | 692 */ |
643 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl
ineOrder; } | 693 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl
ineOrder; } |
644 | 694 |
645 /** | |
646 * Update the current scanline. Used by interlaced png. | |
647 */ | |
648 void updateCurrScanline(int newY) { fCurrScanline = newY; } | |
649 | |
650 const SkImageInfo& dstInfo() const { return fDstInfo; } | 695 const SkImageInfo& dstInfo() const { return fDstInfo; } |
651 | 696 |
652 const SkCodec::Options& options() const { return fOptions; } | 697 const SkCodec::Options& options() const { return fOptions; } |
653 | 698 |
654 /** | 699 /** |
655 * Returns the number of scanlines that have been decoded so far. | 700 * Returns the number of scanlines that have been decoded so far. |
656 * This is unaffected by the SkScanlineOrder. | 701 * This is unaffected by the SkScanlineOrder. |
657 * | 702 * |
658 * Returns -1 if we have not started a scanline decode. | 703 * Returns -1 if we have not started a scanline decode. |
659 */ | 704 */ |
660 int currScanline() const { return fCurrScanline; } | 705 int currScanline() const { return fCurrScanline; } |
661 | 706 |
662 virtual int onOutputScanline(int inputScanline) const; | 707 virtual int onOutputScanline(int inputScanline) const; |
663 | 708 |
664 /** | 709 /** |
665 * Used for testing with qcms. | 710 * Used for testing with qcms. |
666 * FIXME: Remove this when we are done comparing with qcms. | 711 * FIXME: Remove this when we are done comparing with qcms. |
667 */ | 712 */ |
668 virtual sk_sp<SkData> getICCData() const { return nullptr; } | 713 virtual sk_sp<SkData> getICCData() const { return nullptr; } |
669 private: | 714 private: |
670 const SkEncodedInfo fEncodedInfo; | 715 const SkEncodedInfo fEncodedInfo; |
671 const SkImageInfo fSrcInfo; | 716 const SkImageInfo fSrcInfo; |
672 SkAutoTDelete<SkStream> fStream; | 717 SkAutoTDelete<SkStream> fStream; |
673 bool fNeedsRewind; | 718 bool fNeedsRewind; |
674 const Origin fOrigin; | 719 const Origin fOrigin; |
675 | 720 |
676 // These fields are only meaningful during scanline decodes. | |
677 SkImageInfo fDstInfo; | 721 SkImageInfo fDstInfo; |
678 SkCodec::Options fOptions; | 722 SkCodec::Options fOptions; |
| 723 |
| 724 // Only meaningful during scanline decodes. |
679 int fCurrScanline; | 725 int fCurrScanline; |
680 | 726 |
| 727 bool fStartedIncrementalDecode; |
| 728 |
681 /** | 729 /** |
682 * Return whether these dimensions are supported as a scale. | 730 * Return whether these dimensions are supported as a scale. |
683 * | 731 * |
684 * The codec may choose to cache the information about scale and subset. | 732 * The codec may choose to cache the information about scale and subset. |
685 * Either way, the same information will be passed to onGetPixels/onStart | 733 * Either way, the same information will be passed to onGetPixels/onStart |
686 * on success. | 734 * on success. |
687 * | 735 * |
688 * This must return true for a size returned from getScaledDimensions. | 736 * This must return true for a size returned from getScaledDimensions. |
689 */ | 737 */ |
690 bool dimensionsSupported(const SkISize& dim) { | 738 bool dimensionsSupported(const SkISize& dim) { |
691 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); | 739 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); |
692 } | 740 } |
693 | 741 |
694 // Methods for scanline decoding. | 742 // Methods for scanline decoding. |
695 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/
, | 743 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/
, |
696 const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*c
tableCount*/) { | 744 const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*c
tableCount*/) { |
697 return kUnimplemented; | 745 return kUnimplemented; |
698 } | 746 } |
699 | 747 |
| 748 virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void
*, size_t, |
| 749 const SkCodec::Options&, SkPMColor*, int*) { |
| 750 return kUnimplemented; |
| 751 } |
| 752 |
| 753 virtual Result onIncrementalDecode(int*) { |
| 754 return kUnimplemented; |
| 755 } |
| 756 |
| 757 |
700 virtual bool onSkipScanlines(int /*countLines*/) { return false; } | 758 virtual bool onSkipScanlines(int /*countLines*/) { return false; } |
701 | 759 |
702 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBy
tes*/) { return 0; } | 760 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBy
tes*/) { return 0; } |
703 | 761 |
704 /** | 762 /** |
705 * On an incomplete decode, getPixels() and getScanlines() will call this fu
nction | 763 * On an incomplete decode, getPixels() and getScanlines() will call this fu
nction |
706 * to fill any uinitialized memory. | 764 * to fill any uinitialized memory. |
707 * | 765 * |
708 * @param dstInfo Contains the destination color type | 766 * @param dstInfo Contains the destination color type |
709 * Contains the destination alpha type | 767 * Contains the destination alpha type |
(...skipping 16 matching lines...) Expand all Loading... |
726 * | 784 * |
727 * Only valid during scanline decoding. | 785 * Only valid during scanline decoding. |
728 */ | 786 */ |
729 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} | 787 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} |
730 | 788 |
731 // For testing with qcms | 789 // For testing with qcms |
732 // FIXME: Remove these when we are done comparing with qcms. | 790 // FIXME: Remove these when we are done comparing with qcms. |
733 friend class DM::ColorCodecSrc; | 791 friend class DM::ColorCodecSrc; |
734 friend class ColorCodecBench; | 792 friend class ColorCodecBench; |
735 | 793 |
| 794 friend class DM::CodecSrc; // for fillIncompleteImage |
736 friend class SkSampledCodec; | 795 friend class SkSampledCodec; |
737 friend class SkIcoCodec; | 796 friend class SkIcoCodec; |
738 }; | 797 }; |
739 #endif // SkCodec_DEFINED | 798 #endif // SkCodec_DEFINED |
OLD | NEW |