Home | History | Annotate | Download | only in codec
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkCodec_DEFINED
      9 #define SkCodec_DEFINED
     10 
     11 #include "../private/SkTemplates.h"
     12 #include "../private/SkEncodedInfo.h"
     13 #include "SkCodecAnimation.h"
     14 #include "SkColor.h"
     15 #include "SkColorSpaceXform.h"
     16 #include "SkEncodedImageFormat.h"
     17 #include "SkEncodedOrigin.h"
     18 #include "SkImageInfo.h"
     19 #include "SkPixmap.h"
     20 #include "SkSize.h"
     21 #include "SkStream.h"
     22 #include "SkTypes.h"
     23 #include "SkYUVSizeInfo.h"
     24 
     25 #include <vector>
     26 
     27 class SkColorSpace;
     28 class SkData;
     29 class SkFrameHolder;
     30 class SkPngChunkReader;
     31 class SkSampler;
     32 
     33 namespace DM {
     34 class CodecSrc;
     35 class ColorCodecSrc;
     36 }
     37 class ColorCodecBench;
     38 
     39 /**
     40  *  Abstraction layer directly on top of an image codec.
     41  */
     42 class SK_API SkCodec : SkNoncopyable {
     43 public:
     44     /**
     45      *  Minimum number of bytes that must be buffered in SkStream input.
     46      *
     47      *  An SkStream passed to NewFromStream must be able to use this many
     48      *  bytes to determine the image type. Then the same SkStream must be
     49      *  passed to the correct decoder to read from the beginning.
     50      *
     51      *  This can be accomplished by implementing peek() to support peeking
     52      *  this many bytes, or by implementing rewind() to be able to rewind()
     53      *  after reading this many bytes.
     54      */
     55     static constexpr size_t MinBufferedBytesNeeded() { return 32; }
     56 
     57     /**
     58      *  Error codes for various SkCodec methods.
     59      */
     60     enum Result {
     61         /**
     62          *  General return value for success.
     63          */
     64         kSuccess,
     65         /**
     66          *  The input is incomplete. A partial image was generated.
     67          */
     68         kIncompleteInput,
     69         /**
     70          *  Like kIncompleteInput, except the input had an error.
     71          *
     72          *  If returned from an incremental decode, decoding cannot continue,
     73          *  even with more data.
     74          */
     75         kErrorInInput,
     76         /**
     77          *  The generator cannot convert to match the request, ignoring
     78          *  dimensions.
     79          */
     80         kInvalidConversion,
     81         /**
     82          *  The generator cannot scale to requested size.
     83          */
     84         kInvalidScale,
     85         /**
     86          *  Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
     87          *  too small, etc.
     88          */
     89         kInvalidParameters,
     90         /**
     91          *  The input did not contain a valid image.
     92          */
     93         kInvalidInput,
     94         /**
     95          *  Fulfilling this request requires rewinding the input, which is not
     96          *  supported for this input.
     97          */
     98         kCouldNotRewind,
     99         /**
    100          *  An internal error, such as OOM.
    101          */
    102         kInternalError,
    103         /**
    104          *  This method is not implemented by this codec.
    105          *  FIXME: Perhaps this should be kUnsupported?
    106          */
    107         kUnimplemented,
    108     };
    109 
    110     /**
    111      *  Readable string representing the error code.
    112      */
    113     static const char* ResultToString(Result);
    114 
    115     /**
    116      *  If this stream represents an encoded image that we know how to decode,
    117      *  return an SkCodec that can decode it. Otherwise return NULL.
    118      *
    119      *  As stated above, this call must be able to peek or read
    120      *  MinBufferedBytesNeeded to determine the correct format, and then start
    121      *  reading from the beginning. First it will attempt to peek, and it
    122      *  assumes that if less than MinBufferedBytesNeeded bytes (but more than
    123      *  zero) are returned, this is because the stream is shorter than this,
    124      *  so falling back to reading would not provide more data. If peek()
    125      *  returns zero bytes, this call will instead attempt to read(). This
    126      *  will require that the stream can be rewind()ed.
    127      *
    128      *  If Result is not NULL, it will be set to either kSuccess if an SkCodec
    129      *  is returned or a reason for the failure if NULL is returned.
    130      *
    131      *  If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
    132      *  the image is a png.
    133      *
    134      *  If the SkPngChunkReader is not NULL then:
    135      *      If the image is not a PNG, the SkPngChunkReader will be ignored.
    136      *      If the image is a PNG, the SkPngChunkReader will be reffed.
    137      *      If the PNG has unknown chunks, the SkPngChunkReader will be used
    138      *      to handle these chunks.  SkPngChunkReader will be called to read
    139      *      any unknown chunk at any point during the creation of the codec
    140      *      or the decode.  Note that if SkPngChunkReader fails to read a
    141      *      chunk, this could result in a failure to create the codec or a
    142      *      failure to decode the image.
    143      *      If the PNG does not contain unknown chunks, the SkPngChunkReader
    144      *      will not be used or modified.
    145      *
    146      *  If NULL is returned, the stream is deleted immediately. Otherwise, the
    147      *  SkCodec takes ownership of it, and will delete it when done with it.
    148      */
    149     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result* = nullptr,
    150                                                    SkPngChunkReader* = nullptr);
    151 
    152     /**
    153      *  If this data represents an encoded image that we know how to decode,
    154      *  return an SkCodec that can decode it. Otherwise return NULL.
    155      *
    156      *  If the SkPngChunkReader is not NULL then:
    157      *      If the image is not a PNG, the SkPngChunkReader will be ignored.
    158      *      If the image is a PNG, the SkPngChunkReader will be reffed.
    159      *      If the PNG has unknown chunks, the SkPngChunkReader will be used
    160      *      to handle these chunks.  SkPngChunkReader will be called to read
    161      *      any unknown chunk at any point during the creation of the codec
    162      *      or the decode.  Note that if SkPngChunkReader fails to read a
    163      *      chunk, this could result in a failure to create the codec or a
    164      *      failure to decode the image.
    165      *      If the PNG does not contain unknown chunks, the SkPngChunkReader
    166      *      will not be used or modified.
    167      */
    168     static std::unique_ptr<SkCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
    169 
    170     virtual ~SkCodec();
    171 
    172     /**
    173      *  Return the ImageInfo associated with this codec.
    174      */
    175     const SkImageInfo& getInfo() const { return fSrcInfo; }
    176 
    177     /**
    178      *  Returns the image orientation stored in the EXIF data.
    179      *  If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
    180      */
    181     SkEncodedOrigin getOrigin() const { return fOrigin; }
    182 
    183     /**
    184      *  Return a size that approximately supports the desired scale factor.
    185      *  The codec may not be able to scale efficiently to the exact scale
    186      *  factor requested, so return a size that approximates that scale.
    187      *  The returned value is the codec's suggestion for the closest valid
    188      *  scale that it can natively support
    189      */
    190     SkISize getScaledDimensions(float desiredScale) const {
    191         // Negative and zero scales are errors.
    192         SkASSERT(desiredScale > 0.0f);
    193         if (desiredScale <= 0.0f) {
    194             return SkISize::Make(0, 0);
    195         }
    196 
    197         // Upscaling is not supported. Return the original size if the client
    198         // requests an upscale.
    199         if (desiredScale >= 1.0f) {
    200             return this->getInfo().dimensions();
    201         }
    202         return this->onGetScaledDimensions(desiredScale);
    203     }
    204 
    205     /**
    206      *  Return (via desiredSubset) a subset which can decoded from this codec,
    207      *  or false if this codec cannot decode subsets or anything similar to
    208      *  desiredSubset.
    209      *
    210      *  @param desiredSubset In/out parameter. As input, a desired subset of
    211      *      the original bounds (as specified by getInfo). If true is returned,
    212      *      desiredSubset may have been modified to a subset which is
    213      *      supported. Although a particular change may have been made to
    214      *      desiredSubset to create something supported, it is possible other
    215      *      changes could result in a valid subset.
    216      *      If false is returned, desiredSubset's value is undefined.
    217      *  @return true if this codec supports decoding desiredSubset (as
    218      *      returned, potentially modified)
    219      */
    220     bool getValidSubset(SkIRect* desiredSubset) const {
    221         return this->onGetValidSubset(desiredSubset);
    222     }
    223 
    224     /**
    225      *  Format of the encoded data.
    226      */
    227     SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
    228 
    229     /**
    230      *  Whether or not the memory passed to getPixels is zero initialized.
    231      */
    232     enum ZeroInitialized {
    233         /**
    234          *  The memory passed to getPixels is zero initialized. The SkCodec
    235          *  may take advantage of this by skipping writing zeroes.
    236          */
    237         kYes_ZeroInitialized,
    238         /**
    239          *  The memory passed to getPixels has not been initialized to zero,
    240          *  so the SkCodec must write all zeroes to memory.
    241          *
    242          *  This is the default. It will be used if no Options struct is used.
    243          */
    244         kNo_ZeroInitialized,
    245     };
    246 
    247     /**
    248      *  Additional options to pass to getPixels.
    249      */
    250     struct Options {
    251         Options()
    252             : fZeroInitialized(kNo_ZeroInitialized)
    253             , fSubset(nullptr)
    254             , fFrameIndex(0)
    255             , fPriorFrame(kNone)
    256             , fPremulBehavior(SkTransferFunctionBehavior::kRespect)
    257         {}
    258 
    259         ZeroInitialized            fZeroInitialized;
    260         /**
    261          *  If not NULL, represents a subset of the original image to decode.
    262          *  Must be within the bounds returned by getInfo().
    263          *  If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which
    264          *  currently supports subsets), the top and left values must be even.
    265          *
    266          *  In getPixels and incremental decode, we will attempt to decode the
    267          *  exact rectangular subset specified by fSubset.
    268          *
    269          *  In a scanline decode, it does not make sense to specify a subset
    270          *  top or subset height, since the client already controls which rows
    271          *  to get and which rows to skip.  During scanline decodes, we will
    272          *  require that the subset top be zero and the subset height be equal
    273          *  to the full height.  We will, however, use the values of
    274          *  subset left and subset width to decode partial scanlines on calls
    275          *  to getScanlines().
    276          */
    277         const SkIRect*             fSubset;
    278 
    279         /**
    280          *  The frame to decode.
    281          *
    282          *  Only meaningful for multi-frame images.
    283          */
    284         int                        fFrameIndex;
    285 
    286         /**
    287          *  If not kNone, the dst already contains the prior frame at this index.
    288          *
    289          *  Only meaningful for multi-frame images.
    290          *
    291          *  If fFrameIndex needs to be blended with a prior frame (as reported by
    292          *  getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to
    293          *  any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to
    294          *  indicate that that frame is already in the dst. Options.fZeroInitialized
    295          *  is ignored in this case.
    296          *
    297          *  If set to kNone, the codec will decode any necessary required frame(s) first.
    298          */
    299         int                        fPriorFrame;
    300 
    301         /**
    302          *  Indicates whether we should do a linear premultiply or a legacy premultiply.
    303          *
    304          *  In the case where the dst SkColorSpace is nullptr, this flag is ignored and
    305          *  we will always do a legacy premultiply.
    306          */
    307         SkTransferFunctionBehavior fPremulBehavior;
    308     };
    309 
    310     /**
    311      *  Decode into the given pixels, a block of memory of size at
    312      *  least (info.fHeight - 1) * rowBytes + (info.fWidth *
    313      *  bytesPerPixel)
    314      *
    315      *  Repeated calls to this function should give the same results,
    316      *  allowing the PixelRef to be immutable.
    317      *
    318      *  @param info A description of the format (config, size)
    319      *         expected by the caller.  This can simply be identical
    320      *         to the info returned by getInfo().
    321      *
    322      *         This contract also allows the caller to specify
    323      *         different output-configs, which the implementation can
    324      *         decide to support or not.
    325      *
    326      *         A size that does not match getInfo() implies a request
    327      *         to scale. If the generator cannot perform this scale,
    328      *         it will return kInvalidScale.
    329      *
    330      *         If the info contains a non-null SkColorSpace, the codec
    331      *         will perform the appropriate color space transformation.
    332      *         If the caller passes in the same color space that was
    333      *         reported by the codec, the color space transformation is
    334      *         a no-op.
    335      *
    336      *  If a scanline decode is in progress, scanline mode will end, requiring the client to call
    337      *  startScanlineDecode() in order to return to decoding scanlines.
    338      *
    339      *  @return Result kSuccess, or another value explaining the type of failure.
    340      */
    341     Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*);
    342 
    343     /**
    344      *  Simplified version of getPixels() that uses the default Options.
    345      */
    346     Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
    347         return this->getPixels(info, pixels, rowBytes, nullptr);
    348     }
    349 
    350     Result getPixels(const SkPixmap& pm, const Options* opts = nullptr) {
    351         return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), opts);
    352     }
    353 
    354     /**
    355      *  If decoding to YUV is supported, this returns true.  Otherwise, this
    356      *  returns false and does not modify any of the parameters.
    357      *
    358      *  @param sizeInfo   Output parameter indicating the sizes and required
    359      *                    allocation widths of the Y, U, and V planes.
    360      *  @param colorSpace Output parameter.  If non-NULL this is set to kJPEG,
    361      *                    otherwise this is ignored.
    362      */
    363     bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
    364         if (nullptr == sizeInfo) {
    365             return false;
    366         }
    367 
    368         return this->onQueryYUV8(sizeInfo, colorSpace);
    369     }
    370 
    371     /**
    372      *  Returns kSuccess, or another value explaining the type of failure.
    373      *  This always attempts to perform a full decode.  If the client only
    374      *  wants size, it should call queryYUV8().
    375      *
    376      *  @param sizeInfo   Needs to exactly match the values returned by the
    377      *                    query, except the WidthBytes may be larger than the
    378      *                    recommendation (but not smaller).
    379      *  @param planes     Memory for each of the Y, U, and V planes.
    380      */
    381     Result getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) {
    382         if (nullptr == planes || nullptr == planes[0] || nullptr == planes[1] ||
    383                 nullptr == planes[2]) {
    384             return kInvalidInput;
    385         }
    386 
    387         if (!this->rewindIfNeeded()) {
    388             return kCouldNotRewind;
    389         }
    390 
    391         return this->onGetYUV8Planes(sizeInfo, planes);
    392     }
    393 
    394     /**
    395      *  Prepare for an incremental decode with the specified options.
    396      *
    397      *  This may require a rewind.
    398      *
    399      *  @param dstInfo Info of the destination. If the dimensions do not match
    400      *      those of getInfo, this implies a scale.
    401      *  @param dst Memory to write to. Needs to be large enough to hold the subset,
    402      *      if present, or the full image as described in dstInfo.
    403      *  @param options Contains decoding options, including if memory is zero
    404      *      initialized and whether to decode a subset.
    405      *  @return Enum representing success or reason for failure.
    406      */
    407     Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
    408             const Options*);
    409 
    410     Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
    411         return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr);
    412     }
    413 
    414     /**
    415      *  Start/continue the incremental decode.
    416      *
    417      *  Not valid to call before calling startIncrementalDecode().
    418      *
    419      *  After the first call, should only be called again if more data has been
    420      *  provided to the source SkStream.
    421      *
    422      *  Unlike getPixels and getScanlines, this does not do any filling. This is
    423      *  left up to the caller, since they may be skipping lines or continuing the
    424      *  decode later. In the latter case, they may choose to initialize all lines
    425      *  first, or only initialize the remaining lines after the first call.
    426      *
    427      *  @param rowsDecoded Optional output variable returning the total number of
    428      *      lines initialized. Only meaningful if this method returns kIncompleteInput.
    429      *      Otherwise the implementation may not set it.
    430      *      Note that some implementations may have initialized this many rows, but
    431      *      not necessarily finished those rows (e.g. interlaced PNG). This may be
    432      *      useful for determining what rows the client needs to initialize.
    433      *  @return kSuccess if all lines requested in startIncrementalDecode have
    434      *      been completely decoded. kIncompleteInput otherwise.
    435      */
    436     Result incrementalDecode(int* rowsDecoded = nullptr) {
    437         if (!fStartedIncrementalDecode) {
    438             return kInvalidParameters;
    439         }
    440         return this->onIncrementalDecode(rowsDecoded);
    441     }
    442 
    443     /**
    444      * The remaining functions revolve around decoding scanlines.
    445      */
    446 
    447     /**
    448      *  Prepare for a scanline decode with the specified options.
    449      *
    450      *  After this call, this class will be ready to decode the first scanline.
    451      *
    452      *  This must be called in order to call getScanlines or skipScanlines.
    453      *
    454      *  This may require rewinding the stream.
    455      *
    456      *  Not all SkCodecs support this.
    457      *
    458      *  @param dstInfo Info of the destination. If the dimensions do not match
    459      *      those of getInfo, this implies a scale.
    460      *  @param options Contains decoding options, including if memory is zero
    461      *      initialized.
    462      *  @return Enum representing success or reason for failure.
    463      */
    464     Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options);
    465 
    466     /**
    467      *  Simplified version of startScanlineDecode() that uses the default Options.
    468      */
    469     Result startScanlineDecode(const SkImageInfo& dstInfo) {
    470         return this->startScanlineDecode(dstInfo, nullptr);
    471     }
    472 
    473     /**
    474      *  Write the next countLines scanlines into dst.
    475      *
    476      *  Not valid to call before calling startScanlineDecode().
    477      *
    478      *  @param dst Must be non-null, and large enough to hold countLines
    479      *      scanlines of size rowBytes.
    480      *  @param countLines Number of lines to write.
    481      *  @param rowBytes Number of bytes per row. Must be large enough to hold
    482      *      a scanline based on the SkImageInfo used to create this object.
    483      *  @return the number of lines successfully decoded.  If this value is
    484      *      less than countLines, this will fill the remaining lines with a
    485      *      default value.
    486      */
    487     int getScanlines(void* dst, int countLines, size_t rowBytes);
    488 
    489     /**
    490      *  Skip count scanlines.
    491      *
    492      *  Not valid to call before calling startScanlineDecode().
    493      *
    494      *  The default version just calls onGetScanlines and discards the dst.
    495      *  NOTE: If skipped lines are the only lines with alpha, this default
    496      *  will make reallyHasAlpha return true, when it could have returned
    497      *  false.
    498      *
    499      *  @return true if the scanlines were successfully skipped
    500      *          false on failure, possible reasons for failure include:
    501      *              An incomplete input image stream.
    502      *              Calling this function before calling startScanlineDecode().
    503      *              If countLines is less than zero or so large that it moves
    504      *                  the current scanline past the end of the image.
    505      */
    506     bool skipScanlines(int countLines);
    507 
    508     /**
    509      *  The order in which rows are output from the scanline decoder is not the
    510      *  same for all variations of all image types.  This explains the possible
    511      *  output row orderings.
    512      */
    513     enum SkScanlineOrder {
    514         /*
    515          * By far the most common, this indicates that the image can be decoded
    516          * reliably using the scanline decoder, and that rows will be output in
    517          * the logical order.
    518          */
    519         kTopDown_SkScanlineOrder,
    520 
    521         /*
    522          * This indicates that the scanline decoder reliably outputs rows, but
    523          * they will be returned in reverse order.  If the scanline format is
    524          * kBottomUp, the nextScanline() API can be used to determine the actual
    525          * y-coordinate of the next output row, but the client is not forced
    526          * to take advantage of this, given that it's not too tough to keep
    527          * track independently.
    528          *
    529          * For full image decodes, it is safe to get all of the scanlines at
    530          * once, since the decoder will handle inverting the rows as it
    531          * decodes.
    532          *
    533          * For subset decodes and sampling, it is simplest to get and skip
    534          * scanlines one at a time, using the nextScanline() API.  It is
    535          * possible to ask for larger chunks at a time, but this should be used
    536          * with caution.  As with full image decodes, the decoder will handle
    537          * inverting the requested rows, but rows will still be delivered
    538          * starting from the bottom of the image.
    539          *
    540          * Upside down bmps are an example.
    541          */
    542         kBottomUp_SkScanlineOrder,
    543     };
    544 
    545     /**
    546      *  An enum representing the order in which scanlines will be returned by
    547      *  the scanline decoder.
    548      *
    549      *  This is undefined before startScanlineDecode() is called.
    550      */
    551     SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
    552 
    553     /**
    554      *  Returns the y-coordinate of the next row to be returned by the scanline
    555      *  decoder.
    556      *
    557      *  This will equal fCurrScanline, except in the case of strangely
    558      *  encoded image types (bottom-up bmps).
    559      *
    560      *  Results are undefined when not in scanline decoding mode.
    561      */
    562     int nextScanline() const { return this->outputScanline(fCurrScanline); }
    563 
    564     /**
    565      *  Returns the output y-coordinate of the row that corresponds to an input
    566      *  y-coordinate.  The input y-coordinate represents where the scanline
    567      *  is located in the encoded data.
    568      *
    569      *  This will equal inputScanline, except in the case of strangely
    570      *  encoded image types (bottom-up bmps, interlaced gifs).
    571      */
    572     int outputScanline(int inputScanline) const;
    573 
    574     /**
    575      *  Return the number of frames in the image.
    576      *
    577      *  May require reading through the stream.
    578      */
    579     int getFrameCount() {
    580         return this->onGetFrameCount();
    581     }
    582 
    583     // The required frame for an independent frame is marked as
    584     // kNone.
    585     static constexpr int kNone = -1;
    586 
    587     /**
    588      *  Information about individual frames in a multi-framed image.
    589      */
    590     struct FrameInfo {
    591         /**
    592          *  The frame that this frame needs to be blended with, or
    593          *  kNone if this frame is independent.
    594          *
    595          *  Note that this is the *earliest* frame that can be used
    596          *  for blending. Any frame from [fRequiredFrame, i) can be
    597          *  used, unless its fDisposalMethod is kRestorePrevious.
    598          */
    599         int fRequiredFrame;
    600 
    601         /**
    602          *  Number of milliseconds to show this frame.
    603          */
    604         int fDuration;
    605 
    606         /**
    607          *  Whether the end marker for this frame is contained in the stream.
    608          *
    609          *  Note: this does not guarantee that an attempt to decode will be complete.
    610          *  There could be an error in the stream.
    611          */
    612         bool fFullyReceived;
    613 
    614         /**
    615          *  This is conservative; it will still return non-opaque if e.g. a
    616          *  color index-based frame has a color with alpha but does not use it.
    617          */
    618         SkAlphaType fAlphaType;
    619 
    620         /**
    621          *  How this frame should be modified before decoding the next one.
    622          */
    623         SkCodecAnimation::DisposalMethod fDisposalMethod;
    624     };
    625 
    626     /**
    627      *  Return info about a single frame.
    628      *
    629      *  Only supported by multi-frame images. Does not read through the stream,
    630      *  so it should be called after getFrameCount() to parse any frames that
    631      *  have not already been parsed.
    632      */
    633     bool getFrameInfo(int index, FrameInfo* info) const {
    634         if (index < 0) {
    635             return false;
    636         }
    637         return this->onGetFrameInfo(index, info);
    638     }
    639 
    640     /**
    641      *  Return info about all the frames in the image.
    642      *
    643      *  May require reading through the stream to determine info about the
    644      *  frames (including the count).
    645      *
    646      *  As such, future decoding calls may require a rewind.
    647      *
    648      *  For single-frame images, this will return an empty vector.
    649      */
    650     std::vector<FrameInfo> getFrameInfo();
    651 
    652     static constexpr int kRepetitionCountInfinite = -1;
    653 
    654     /**
    655      *  Return the number of times to repeat, if this image is animated.
    656      *
    657      *  May require reading the stream to find the repetition count.
    658      *
    659      *  As such, future decoding calls may require a rewind.
    660      *
    661      *  For single-frame images, this will return 0.
    662      */
    663     int getRepetitionCount() {
    664         return this->onGetRepetitionCount();
    665     }
    666 
    667 protected:
    668     const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
    669 
    670     using XformFormat = SkColorSpaceXform::ColorFormat;
    671 
    672     SkCodec(int width,
    673             int height,
    674             const SkEncodedInfo&,
    675             XformFormat srcFormat,
    676             std::unique_ptr<SkStream>,
    677             sk_sp<SkColorSpace>,
    678             SkEncodedOrigin = kTopLeft_SkEncodedOrigin);
    679 
    680     /**
    681      *  Allows the subclass to set the recommended SkImageInfo
    682      */
    683     SkCodec(const SkEncodedInfo&,
    684             const SkImageInfo&,
    685             XformFormat srcFormat,
    686             std::unique_ptr<SkStream>,
    687             SkEncodedOrigin = kTopLeft_SkEncodedOrigin);
    688 
    689     virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
    690         // By default, scaling is not supported.
    691         return this->getInfo().dimensions();
    692     }
    693 
    694     // FIXME: What to do about subsets??
    695     /**
    696      *  Subclasses should override if they support dimensions other than the
    697      *  srcInfo's.
    698      */
    699     virtual bool onDimensionsSupported(const SkISize&) {
    700         return false;
    701     }
    702 
    703     virtual SkEncodedImageFormat onGetEncodedFormat() const = 0;
    704 
    705     /**
    706      * @param rowsDecoded When the encoded image stream is incomplete, this function
    707      *                    will return kIncompleteInput and rowsDecoded will be set to
    708      *                    the number of scanlines that were successfully decoded.
    709      *                    This will allow getPixels() to fill the uninitialized memory.
    710      */
    711     virtual Result onGetPixels(const SkImageInfo& info,
    712                                void* pixels, size_t rowBytes, const Options&,
    713                                int* rowsDecoded) = 0;
    714 
    715     virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
    716         return false;
    717     }
    718 
    719     virtual Result onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
    720         return kUnimplemented;
    721     }
    722 
    723     virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const {
    724         // By default, subsets are not supported.
    725         return false;
    726     }
    727 
    728     /**
    729      *  If the stream was previously read, attempt to rewind.
    730      *
    731      *  If the stream needed to be rewound, call onRewind.
    732      *  @returns true if the codec is at the right position and can be used.
    733      *      false if there was a failure to rewind.
    734      *
    735      *  This is called by getPixels() and start(). Subclasses may call if they
    736      *  need to rewind at another time.
    737      */
    738     bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
    739 
    740     /**
    741      *  Called by rewindIfNeeded, if the stream needed to be rewound.
    742      *
    743      *  Subclasses should do any set up needed after a rewind.
    744      */
    745     virtual bool onRewind() {
    746         return true;
    747     }
    748 
    749     /**
    750      * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
    751      * scanlines.  This allows the subclass to indicate what value to fill with.
    752      *
    753      * @param dstInfo   Describes the destination.
    754      * @return          The value with which to fill uninitialized pixels.
    755      *
    756      * Note that we can interpret the return value as a 64-bit Float16 color, a SkPMColor,
    757      * a 16-bit 565 color, an 8-bit gray color, or an 8-bit index into a color table,
    758      * depending on the color type.
    759      */
    760     uint64_t getFillValue(const SkImageInfo& dstInfo) const {
    761         return this->onGetFillValue(dstInfo);
    762     }
    763 
    764     /**
    765      * Some subclasses will override this function, but this is a useful default for the color
    766      * types that we support.  Note that for color types that do not use the full 64-bits,
    767      * we will simply take the low bits of the fill value.
    768      *
    769      * The defaults are:
    770      * kRGBA_F16_SkColorType: Transparent or Black, depending on the src alpha type
    771      * kN32_SkColorType: Transparent or Black, depending on the src alpha type
    772      * kRGB_565_SkColorType: Black
    773      * kGray_8_SkColorType: Black
    774      */
    775     virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const;
    776 
    777     /**
    778      * Get method for the input stream
    779      */
    780     SkStream* stream() {
    781         return fStream.get();
    782     }
    783 
    784     /**
    785      *  The remaining functions revolve around decoding scanlines.
    786      */
    787 
    788     /**
    789      *  Most images types will be kTopDown and will not need to override this function.
    790      */
    791     virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
    792 
    793     const SkImageInfo& dstInfo() const { return fDstInfo; }
    794 
    795     const Options& options() const { return fOptions; }
    796 
    797     /**
    798      *  Returns the number of scanlines that have been decoded so far.
    799      *  This is unaffected by the SkScanlineOrder.
    800      *
    801      *  Returns -1 if we have not started a scanline decode.
    802      */
    803     int currScanline() const { return fCurrScanline; }
    804 
    805     virtual int onOutputScanline(int inputScanline) const;
    806 
    807     bool initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Alpha,
    808                               SkTransferFunctionBehavior premulBehavior);
    809     // Some classes never need a colorXform e.g.
    810     // - ICO uses its embedded codec's colorXform
    811     // - WBMP is just Black/White
    812     virtual bool usesColorXform() const { return true; }
    813     void applyColorXform(void* dst, const void* src, int count, SkAlphaType) const;
    814     void applyColorXform(void* dst, const void* src, int count) const;
    815 
    816     SkColorSpaceXform* colorXform() const { return fColorXform.get(); }
    817     bool xformOnDecode() const { return fXformOnDecode; }
    818 
    819     virtual int onGetFrameCount() {
    820         return 1;
    821     }
    822 
    823     virtual bool onGetFrameInfo(int, FrameInfo*) const {
    824         return false;
    825     }
    826 
    827     virtual int onGetRepetitionCount() {
    828         return 0;
    829     }
    830 
    831 private:
    832     const SkEncodedInfo                fEncodedInfo;
    833     const SkImageInfo                  fSrcInfo;
    834     const XformFormat                  fSrcXformFormat;
    835     std::unique_ptr<SkStream>          fStream;
    836     bool                               fNeedsRewind;
    837     const SkEncodedOrigin              fOrigin;
    838 
    839     SkImageInfo                        fDstInfo;
    840     Options                            fOptions;
    841     XformFormat                        fDstXformFormat; // Based on fDstInfo.
    842     std::unique_ptr<SkColorSpaceXform> fColorXform;
    843     bool                               fXformOnDecode;
    844 
    845     // Only meaningful during scanline decodes.
    846     int                                fCurrScanline;
    847 
    848     bool                               fStartedIncrementalDecode;
    849 
    850     /**
    851      *  Return whether {srcColor, srcIsOpaque, srcCS} can convert to dst.
    852      *
    853      *  Will be called for the appropriate frame, prior to initializing the colorXform.
    854      */
    855     virtual bool conversionSupported(const SkImageInfo& dst, SkColorType srcColor,
    856                                      bool srcIsOpaque, const SkColorSpace* srcCS) const;
    857     /**
    858      *  Return whether these dimensions are supported as a scale.
    859      *
    860      *  The codec may choose to cache the information about scale and subset.
    861      *  Either way, the same information will be passed to onGetPixels/onStart
    862      *  on success.
    863      *
    864      *  This must return true for a size returned from getScaledDimensions.
    865      */
    866     bool dimensionsSupported(const SkISize& dim) {
    867         return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim);
    868     }
    869 
    870     /**
    871      *  For multi-framed images, return the object with information about the frames.
    872      */
    873     virtual const SkFrameHolder* getFrameHolder() const {
    874         return nullptr;
    875     }
    876 
    877     /**
    878      *  Check for a valid Options.fFrameIndex, and decode prior frames if necessary.
    879      */
    880     Result handleFrameIndex(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&);
    881 
    882     // Methods for scanline decoding.
    883     virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
    884             const Options& /*options*/) {
    885         return kUnimplemented;
    886     }
    887 
    888     virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
    889             const Options&) {
    890         return kUnimplemented;
    891     }
    892 
    893     virtual Result onIncrementalDecode(int*) {
    894         return kUnimplemented;
    895     }
    896 
    897 
    898     virtual bool onSkipScanlines(int /*countLines*/) { return false; }
    899 
    900     virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
    901 
    902     /**
    903      * On an incomplete decode, getPixels() and getScanlines() will call this function
    904      * to fill any uinitialized memory.
    905      *
    906      * @param dstInfo        Contains the destination color type
    907      *                       Contains the destination alpha type
    908      *                       Contains the destination width
    909      *                       The height stored in this info is unused
    910      * @param dst            Pointer to the start of destination pixel memory
    911      * @param rowBytes       Stride length in destination pixel memory
    912      * @param zeroInit       Indicates if memory is zero initialized
    913      * @param linesRequested Number of lines that the client requested
    914      * @param linesDecoded   Number of lines that were successfully decoded
    915      */
    916     void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
    917             ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
    918 
    919     /**
    920      *  Return an object which will allow forcing scanline decodes to sample in X.
    921      *
    922      *  May create a sampler, if one is not currently being used. Otherwise, does
    923      *  not affect ownership.
    924      *
    925      *  Only valid during scanline decoding or incremental decoding.
    926      */
    927     virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
    928 
    929     friend class DM::CodecSrc;  // for fillIncompleteImage
    930     friend class SkSampledCodec;
    931     friend class SkIcoCodec;
    932     friend class SkAndroidCodec; // for fEncodedInfo
    933 };
    934 #endif // SkCodec_DEFINED
    935