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