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