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