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