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