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; | |
28 class ColorCodecSrc; | 27 class ColorCodecSrc; |
29 } | 28 } |
30 class ColorCodecBench; | 29 class ColorCodecBench; |
31 | 30 |
| 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 , fSubset(NULL) | 252 , fSubset(NULL) |
253 {} | 253 {} |
254 | 254 |
255 ZeroInitialized fZeroInitialized; | 255 ZeroInitialized fZeroInitialized; |
256 /** | 256 /** |
257 * If not NULL, represents a subset of the original image to decode. | 257 * If not NULL, represents a subset of the original image to decode. |
258 * Must be within the bounds returned by getInfo(). | 258 * Must be within the bounds returned by getInfo(). |
259 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which | 259 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which |
260 * currently supports subsets), the top and left values must be even. | 260 * currently supports subsets), the top and left values must be even. |
261 * | 261 * |
262 * In getPixels and incremental decode, we will attempt to decode the | 262 * In getPixels, we will attempt to decode the exact rectangular |
263 * exact rectangular subset specified by fSubset. | 263 * subset specified by fSubset. |
264 * | 264 * |
265 * In a scanline decode, it does not make sense to specify a subset | 265 * In a scanline decode, it does not make sense to specify a subset |
266 * top or subset height, since the client already controls which rows | 266 * top or subset height, since the client already controls which rows |
267 * to get and which rows to skip. During scanline decodes, we will | 267 * to get and which rows to skip. During scanline decodes, we will |
268 * require that the subset top be zero and the subset height be equal | 268 * require that the subset top be zero and the subset height be equal |
269 * to the full height. We will, however, use the values of | 269 * to the full height. We will, however, use the values of |
270 * subset left and subset width to decode partial scanlines on calls | 270 * subset left and subset width to decode partial scanlines on calls |
271 * to getScanlines(). | 271 * to getScanlines(). |
272 */ | 272 */ |
273 SkIRect* fSubset; | 273 SkIRect* fSubset; |
(...skipping 74 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 /** | |
419 * The remaining functions revolve around decoding scanlines. | 358 * The remaining functions revolve around decoding scanlines. |
420 */ | 359 */ |
421 | 360 |
422 /** | 361 /** |
423 * Prepare for a scanline decode with the specified options. | 362 * Prepare for a scanline decode with the specified options. |
424 * | 363 * |
425 * After this call, this class will be ready to decode the first scanline. | 364 * After this call, this class will be ready to decode the first scanline. |
426 * | 365 * |
427 * This must be called in order to call getScanlines or skipScanlines. | 366 * This must be called in order to call getScanlines or skipScanlines. |
428 * | 367 * |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 * they will not be in logical order. If the scanline format is | 467 * they will not be in logical order. If the scanline format is |
529 * kOutOfOrder, the nextScanline() API should be used to determine the | 468 * kOutOfOrder, the nextScanline() API should be used to determine the |
530 * actual y-coordinate of the next output row. | 469 * actual y-coordinate of the next output row. |
531 * | 470 * |
532 * For this scanline ordering, it is advisable to get and skip | 471 * For this scanline ordering, it is advisable to get and skip |
533 * scanlines one at a time. | 472 * scanlines one at a time. |
534 * | 473 * |
535 * Interlaced gifs are an example. | 474 * Interlaced gifs are an example. |
536 */ | 475 */ |
537 kOutOfOrder_SkScanlineOrder, | 476 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, |
538 }; | 488 }; |
539 | 489 |
540 /** | 490 /** |
541 * An enum representing the order in which scanlines will be returned by | 491 * An enum representing the order in which scanlines will be returned by |
542 * the scanline decoder. | 492 * the scanline decoder. |
543 * | 493 * |
544 * This is undefined before startScanlineDecode() is called. | 494 * This is undefined before startScanlineDecode() is called. |
545 */ | 495 */ |
546 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } | 496 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder()
; } |
547 | 497 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 | 626 |
677 /** | 627 /** |
678 * The remaining functions revolve around decoding scanlines. | 628 * The remaining functions revolve around decoding scanlines. |
679 */ | 629 */ |
680 | 630 |
681 /** | 631 /** |
682 * Most images types will be kTopDown and will not need to override this fu
nction. | 632 * Most images types will be kTopDown and will not need to override this fu
nction. |
683 */ | 633 */ |
684 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl
ineOrder; } | 634 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanl
ineOrder; } |
685 | 635 |
| 636 /** |
| 637 * Update the current scanline. Used by interlaced png. |
| 638 */ |
| 639 void updateCurrScanline(int newY) { fCurrScanline = newY; } |
| 640 |
686 const SkImageInfo& dstInfo() const { return fDstInfo; } | 641 const SkImageInfo& dstInfo() const { return fDstInfo; } |
687 | 642 |
688 const SkCodec::Options& options() const { return fOptions; } | 643 const SkCodec::Options& options() const { return fOptions; } |
689 | 644 |
690 /** | 645 /** |
691 * Returns the number of scanlines that have been decoded so far. | 646 * Returns the number of scanlines that have been decoded so far. |
692 * This is unaffected by the SkScanlineOrder. | 647 * This is unaffected by the SkScanlineOrder. |
693 * | 648 * |
694 * Returns -1 if we have not started a scanline decode. | 649 * Returns -1 if we have not started a scanline decode. |
695 */ | 650 */ |
(...skipping 11 matching lines...) Expand all Loading... |
707 const SkImageInfo fSrcInfo; | 662 const SkImageInfo fSrcInfo; |
708 SkAutoTDelete<SkStream> fStream; | 663 SkAutoTDelete<SkStream> fStream; |
709 bool fNeedsRewind; | 664 bool fNeedsRewind; |
710 sk_sp<SkColorSpace> fColorSpace; | 665 sk_sp<SkColorSpace> fColorSpace; |
711 const Origin fOrigin; | 666 const Origin fOrigin; |
712 | 667 |
713 // These fields are only meaningful during scanline decodes. | 668 // These fields are only meaningful during scanline decodes. |
714 SkImageInfo fDstInfo; | 669 SkImageInfo fDstInfo; |
715 SkCodec::Options fOptions; | 670 SkCodec::Options fOptions; |
716 int fCurrScanline; | 671 int fCurrScanline; |
717 bool fStartedIncrementalDecode; | |
718 | 672 |
719 /** | 673 /** |
720 * Return whether these dimensions are supported as a scale. | 674 * Return whether these dimensions are supported as a scale. |
721 * | 675 * |
722 * The codec may choose to cache the information about scale and subset. | 676 * The codec may choose to cache the information about scale and subset. |
723 * Either way, the same information will be passed to onGetPixels/onStart | 677 * Either way, the same information will be passed to onGetPixels/onStart |
724 * on success. | 678 * on success. |
725 * | 679 * |
726 * This must return true for a size returned from getScaledDimensions. | 680 * This must return true for a size returned from getScaledDimensions. |
727 */ | 681 */ |
728 bool dimensionsSupported(const SkISize& dim) { | 682 bool dimensionsSupported(const SkISize& dim) { |
729 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); | 683 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); |
730 } | 684 } |
731 | 685 |
732 // Methods for scanline decoding. | 686 // Methods for scanline decoding. |
733 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/
, | 687 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/
, |
734 const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*c
tableCount*/) { | 688 const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*c
tableCount*/) { |
735 return kUnimplemented; | 689 return kUnimplemented; |
736 } | 690 } |
737 | 691 |
738 virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void
*, size_t, | |
739 const SkCodec::Options&, SkPMColor*, int*) { | |
740 return kUnimplemented; | |
741 } | |
742 | |
743 virtual Result onIncrementalDecode(int*) { | |
744 return kUnimplemented; | |
745 } | |
746 | |
747 | |
748 virtual bool onSkipScanlines(int /*countLines*/) { return false; } | 692 virtual bool onSkipScanlines(int /*countLines*/) { return false; } |
749 | 693 |
750 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBy
tes*/) { return 0; } | 694 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBy
tes*/) { return 0; } |
751 | 695 |
752 /** | 696 /** |
753 * On an incomplete decode, getPixels() and getScanlines() will call this fu
nction | 697 * On an incomplete decode, getPixels() and getScanlines() will call this fu
nction |
754 * to fill any uinitialized memory. | 698 * to fill any uinitialized memory. |
755 * | 699 * |
756 * @param dstInfo Contains the destination color type | 700 * @param dstInfo Contains the destination color type |
757 * Contains the destination alpha type | 701 * Contains the destination alpha type |
(...skipping 16 matching lines...) Expand all Loading... |
774 * | 718 * |
775 * Only valid during scanline decoding. | 719 * Only valid during scanline decoding. |
776 */ | 720 */ |
777 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} | 721 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr;
} |
778 | 722 |
779 // For testing with qcms | 723 // For testing with qcms |
780 // FIXME: Remove these when we are done comparing with qcms. | 724 // FIXME: Remove these when we are done comparing with qcms. |
781 friend class DM::ColorCodecSrc; | 725 friend class DM::ColorCodecSrc; |
782 friend class ColorCodecBench; | 726 friend class ColorCodecBench; |
783 | 727 |
784 friend class DM::CodecSrc; // for fillIncompleteImage | |
785 friend class SkSampledCodec; | 728 friend class SkSampledCodec; |
786 friend class SkIcoCodec; | 729 friend class SkIcoCodec; |
787 }; | 730 }; |
788 #endif // SkCodec_DEFINED | 731 #endif // SkCodec_DEFINED |
OLD | NEW |