| 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 | 
|---|