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