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