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