blob: 1d6d904e28391ce396bc926248f8559327dc460f [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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
bungemanf3c15b72015-08-19 11:56:48 -070011#include "../private/SkTemplates.h"
Leon Scroggins III33deb7e2017-06-07 12:31:51 -040012#include "SkCodecAnimation.h"
scroggoeb602a52015-07-09 08:16:03 -070013#include "SkColor.h"
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -040014#include "SkColorSpaceXform.h"
Hal Canarydb683012016-11-23 08:55:18 -070015#include "SkEncodedImageFormat.h"
msarettc30c4182016-04-20 11:53:35 -070016#include "SkEncodedInfo.h"
scroggof24f2242015-03-03 08:59:20 -080017#include "SkImageInfo.h"
18#include "SkSize.h"
scroggofffeede2015-03-18 10:50:37 -070019#include "SkStream.h"
scroggof24f2242015-03-03 08:59:20 -080020#include "SkTypes.h"
msarett4984c3c2016-03-10 05:44:43 -080021#include "SkYUVSizeInfo.h"
scroggof24f2242015-03-03 08:59:20 -080022
scroggo19b91532016-10-24 09:03:26 -070023#include <vector>
24
msarettad8bcfe2016-03-07 07:09:03 -080025class SkColorSpace;
scroggof24f2242015-03-03 08:59:20 -080026class SkData;
Leon Scroggins III1f6af6b2017-06-12 16:41:09 -040027class SkFrameHolder;
scroggocf98fa92015-11-23 08:14:40 -080028class SkPngChunkReader;
scroggoe7fc14b2015-10-02 13:14:46 -070029class SkSampler;
scroggof24f2242015-03-03 08:59:20 -080030
msarett9876ac52016-06-01 14:47:18 -070031namespace DM {
scroggo8e6c7ad2016-09-16 08:20:38 -070032class CodecSrc;
msarett9876ac52016-06-01 14:47:18 -070033class ColorCodecSrc;
34}
msarett2cee9022016-06-03 08:25:21 -070035class ColorCodecBench;
msarett9876ac52016-06-01 14:47:18 -070036
scroggof24f2242015-03-03 08:59:20 -080037/**
38 * Abstraction layer directly on top of an image codec.
39 */
Florin Malita78c212a2016-12-14 13:17:01 -050040class SK_API SkCodec : SkNoncopyable {
scroggof24f2242015-03-03 08:59:20 -080041public:
42 /**
scroggodb30be22015-12-08 18:54:13 -080043 * Minimum number of bytes that must be buffered in SkStream input.
44 *
45 * An SkStream passed to NewFromStream must be able to use this many
46 * bytes to determine the image type. Then the same SkStream must be
47 * passed to the correct decoder to read from the beginning.
48 *
49 * This can be accomplished by implementing peek() to support peeking
50 * this many bytes, or by implementing rewind() to be able to rewind()
51 * after reading this many bytes.
52 */
53 static size_t MinBufferedBytesNeeded();
54
55 /**
Leon Scroggins III588fb042017-07-14 16:32:31 -040056 * Error codes for various SkCodec methods.
57 */
58 enum Result {
59 /**
60 * General return value for success.
61 */
62 kSuccess,
63 /**
64 * The input is incomplete. A partial image was generated.
65 */
66 kIncompleteInput,
67 /**
68 * Like kIncompleteInput, except the input had an error.
69 *
70 * If returned from an incremental decode, decoding cannot continue,
71 * even with more data.
72 */
73 kErrorInInput,
74 /**
75 * The generator cannot convert to match the request, ignoring
76 * dimensions.
77 */
78 kInvalidConversion,
79 /**
80 * The generator cannot scale to requested size.
81 */
82 kInvalidScale,
83 /**
84 * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
85 * too small, etc.
86 */
87 kInvalidParameters,
88 /**
89 * The input did not contain a valid image.
90 */
91 kInvalidInput,
92 /**
93 * Fulfilling this request requires rewinding the input, which is not
94 * supported for this input.
95 */
96 kCouldNotRewind,
97 /**
98 * An internal error, such as OOM.
99 */
100 kInternalError,
101 /**
102 * This method is not implemented by this codec.
103 * FIXME: Perhaps this should be kUnsupported?
104 */
105 kUnimplemented,
106 };
107
108 /**
scroggof24f2242015-03-03 08:59:20 -0800109 * If this stream represents an encoded image that we know how to decode,
110 * return an SkCodec that can decode it. Otherwise return NULL.
111 *
scroggodb30be22015-12-08 18:54:13 -0800112 * As stated above, this call must be able to peek or read
113 * MinBufferedBytesNeeded to determine the correct format, and then start
114 * reading from the beginning. First it will attempt to peek, and it
115 * assumes that if less than MinBufferedBytesNeeded bytes (but more than
116 * zero) are returned, this is because the stream is shorter than this,
117 * so falling back to reading would not provide more data. If peek()
118 * returns zero bytes, this call will instead attempt to read(). This
119 * will require that the stream can be rewind()ed.
120 *
Leon Scroggins III588fb042017-07-14 16:32:31 -0400121 * If Result is not NULL, it will be set to either kSuccess if an SkCodec
122 * is returned or a reason for the failure if NULL is returned.
123 *
scroggodb30be22015-12-08 18:54:13 -0800124 * If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
125 * the image is a png.
126 *
msarett7d5105c2015-12-02 07:02:41 -0800127 * If the SkPngChunkReader is not NULL then:
128 * If the image is not a PNG, the SkPngChunkReader will be ignored.
129 * If the image is a PNG, the SkPngChunkReader will be reffed.
130 * If the PNG has unknown chunks, the SkPngChunkReader will be used
131 * to handle these chunks. SkPngChunkReader will be called to read
132 * any unknown chunk at any point during the creation of the codec
133 * or the decode. Note that if SkPngChunkReader fails to read a
134 * chunk, this could result in a failure to create the codec or a
135 * failure to decode the image.
136 * If the PNG does not contain unknown chunks, the SkPngChunkReader
137 * will not be used or modified.
scroggocf98fa92015-11-23 08:14:40 -0800138 *
scroggof24f2242015-03-03 08:59:20 -0800139 * If NULL is returned, the stream is deleted immediately. Otherwise, the
140 * SkCodec takes ownership of it, and will delete it when done with it.
141 */
Mike Reedede7bac2017-07-23 15:30:02 -0400142 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result* = nullptr,
143 SkPngChunkReader* = nullptr);
scroggof24f2242015-03-03 08:59:20 -0800144
145 /**
146 * If this data represents an encoded image that we know how to decode,
147 * return an SkCodec that can decode it. Otherwise return NULL.
148 *
msarett7d5105c2015-12-02 07:02:41 -0800149 * If the SkPngChunkReader is not NULL then:
150 * If the image is not a PNG, the SkPngChunkReader will be ignored.
151 * If the image is a PNG, the SkPngChunkReader will be reffed.
152 * If the PNG has unknown chunks, the SkPngChunkReader will be used
153 * to handle these chunks. SkPngChunkReader will be called to read
154 * any unknown chunk at any point during the creation of the codec
155 * or the decode. Note that if SkPngChunkReader fails to read a
156 * chunk, this could result in a failure to create the codec or a
157 * failure to decode the image.
158 * If the PNG does not contain unknown chunks, the SkPngChunkReader
159 * will not be used or modified.
scroggof24f2242015-03-03 08:59:20 -0800160 */
Mike Reedede7bac2017-07-23 15:30:02 -0400161 static std::unique_ptr<SkCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
162
163#ifdef SK_SUPPORT_LEGACY_CODEC_NEW
164 static SkCodec* NewFromStream(SkStream* str, Result* res, SkPngChunkReader* chunk);
165 static SkCodec* NewFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
reed42943c82016-09-12 12:01:44 -0700166 static SkCodec* NewFromData(SkData* data, SkPngChunkReader* reader) {
167 return NewFromData(sk_ref_sp(data), reader);
168 }
Mike Reedede7bac2017-07-23 15:30:02 -0400169#endif
scroggof24f2242015-03-03 08:59:20 -0800170
scroggoeb602a52015-07-09 08:16:03 -0700171 virtual ~SkCodec();
172
173 /**
174 * Return the ImageInfo associated with this codec.
175 */
scroggo46c57472015-09-30 08:57:13 -0700176 const SkImageInfo& getInfo() const { return fSrcInfo; }
scroggoeb602a52015-07-09 08:16:03 -0700177
msarettc30c4182016-04-20 11:53:35 -0700178 const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
179
msarett0e6274f2016-03-21 08:04:40 -0700180 enum Origin {
181 kTopLeft_Origin = 1, // Default
182 kTopRight_Origin = 2, // Reflected across y-axis
183 kBottomRight_Origin = 3, // Rotated 180
184 kBottomLeft_Origin = 4, // Reflected across x-axis
185 kLeftTop_Origin = 5, // Reflected across x-axis, Rotated 90 CCW
186 kRightTop_Origin = 6, // Rotated 90 CW
187 kRightBottom_Origin = 7, // Reflected across x-axis, Rotated 90 CW
188 kLeftBottom_Origin = 8, // Rotated 90 CCW
189 kDefault_Origin = kTopLeft_Origin,
190 kLast_Origin = kLeftBottom_Origin,
191 };
192
193 /**
194 * Returns the image orientation stored in the EXIF data.
195 * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
196 */
197 Origin getOrigin() const { return fOrigin; }
198
msarett6a738212016-03-04 13:27:35 -0800199 /**
scroggof24f2242015-03-03 08:59:20 -0800200 * Return a size that approximately supports the desired scale factor.
201 * The codec may not be able to scale efficiently to the exact scale
202 * factor requested, so return a size that approximates that scale.
emmaleer8f4ba762015-08-14 07:44:46 -0700203 * The returned value is the codec's suggestion for the closest valid
204 * scale that it can natively support
scroggof24f2242015-03-03 08:59:20 -0800205 */
scroggofffeede2015-03-18 10:50:37 -0700206 SkISize getScaledDimensions(float desiredScale) const {
msarettb32758a2015-08-18 13:22:46 -0700207 // Negative and zero scales are errors.
208 SkASSERT(desiredScale > 0.0f);
209 if (desiredScale <= 0.0f) {
210 return SkISize::Make(0, 0);
211 }
212
213 // Upscaling is not supported. Return the original size if the client
214 // requests an upscale.
215 if (desiredScale >= 1.0f) {
216 return this->getInfo().dimensions();
217 }
scroggofffeede2015-03-18 10:50:37 -0700218 return this->onGetScaledDimensions(desiredScale);
219 }
scroggof24f2242015-03-03 08:59:20 -0800220
scroggo1dd3ea92015-03-20 11:55:55 -0700221 /**
scroggob636b452015-07-22 07:16:20 -0700222 * Return (via desiredSubset) a subset which can decoded from this codec,
223 * or false if this codec cannot decode subsets or anything similar to
224 * desiredSubset.
225 *
226 * @param desiredSubset In/out parameter. As input, a desired subset of
227 * the original bounds (as specified by getInfo). If true is returned,
228 * desiredSubset may have been modified to a subset which is
229 * supported. Although a particular change may have been made to
230 * desiredSubset to create something supported, it is possible other
231 * changes could result in a valid subset.
232 * If false is returned, desiredSubset's value is undefined.
233 * @return true if this codec supports decoding desiredSubset (as
234 * returned, potentially modified)
235 */
236 bool getValidSubset(SkIRect* desiredSubset) const {
237 return this->onGetValidSubset(desiredSubset);
238 }
239
240 /**
scroggo1dd3ea92015-03-20 11:55:55 -0700241 * Format of the encoded data.
242 */
Hal Canarydb683012016-11-23 08:55:18 -0700243 SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
scroggo1dd3ea92015-03-20 11:55:55 -0700244
scroggo05245902015-03-25 11:11:52 -0700245 /**
scroggoeb602a52015-07-09 08:16:03 -0700246 * Whether or not the memory passed to getPixels is zero initialized.
247 */
248 enum ZeroInitialized {
249 /**
250 * The memory passed to getPixels is zero initialized. The SkCodec
251 * may take advantage of this by skipping writing zeroes.
252 */
253 kYes_ZeroInitialized,
254 /**
255 * The memory passed to getPixels has not been initialized to zero,
256 * so the SkCodec must write all zeroes to memory.
257 *
258 * This is the default. It will be used if no Options struct is used.
259 */
260 kNo_ZeroInitialized,
261 };
262
263 /**
264 * Additional options to pass to getPixels.
265 */
266 struct Options {
267 Options()
scroggob636b452015-07-22 07:16:20 -0700268 : fZeroInitialized(kNo_ZeroInitialized)
scroggo19b91532016-10-24 09:03:26 -0700269 , fSubset(nullptr)
270 , fFrameIndex(0)
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400271 , fPriorFrame(kNone)
Matt Sarettcf3f2342017-03-23 15:32:25 -0400272 , fPremulBehavior(SkTransferFunctionBehavior::kRespect)
scroggob636b452015-07-22 07:16:20 -0700273 {}
scroggoeb602a52015-07-09 08:16:03 -0700274
Matt Sarettcf3f2342017-03-23 15:32:25 -0400275 ZeroInitialized fZeroInitialized;
scroggob636b452015-07-22 07:16:20 -0700276 /**
277 * If not NULL, represents a subset of the original image to decode.
scroggob636b452015-07-22 07:16:20 -0700278 * Must be within the bounds returned by getInfo().
Hal Canarydb683012016-11-23 08:55:18 -0700279 * If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which
scroggob636b452015-07-22 07:16:20 -0700280 * currently supports subsets), the top and left values must be even.
msarettfdb47572015-10-13 12:50:14 -0700281 *
scroggo8e6c7ad2016-09-16 08:20:38 -0700282 * In getPixels and incremental decode, we will attempt to decode the
283 * exact rectangular subset specified by fSubset.
msarettfdb47572015-10-13 12:50:14 -0700284 *
285 * In a scanline decode, it does not make sense to specify a subset
286 * top or subset height, since the client already controls which rows
287 * to get and which rows to skip. During scanline decodes, we will
288 * require that the subset top be zero and the subset height be equal
289 * to the full height. We will, however, use the values of
290 * subset left and subset width to decode partial scanlines on calls
291 * to getScanlines().
scroggob636b452015-07-22 07:16:20 -0700292 */
Matt Sarettcf3f2342017-03-23 15:32:25 -0400293 const SkIRect* fSubset;
scroggo19b91532016-10-24 09:03:26 -0700294
295 /**
296 * The frame to decode.
297 *
298 * Only meaningful for multi-frame images.
299 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400300 int fFrameIndex;
scroggo19b91532016-10-24 09:03:26 -0700301
302 /**
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400303 * If not kNone, the dst already contains the prior frame at this index.
scroggo19b91532016-10-24 09:03:26 -0700304 *
305 * Only meaningful for multi-frame images.
306 *
307 * If fFrameIndex needs to be blended with a prior frame (as reported by
308 * getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400309 * any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to
310 * indicate that that frame is already in the dst. Options.fZeroInitialized
311 * is ignored in this case.
scroggo19b91532016-10-24 09:03:26 -0700312 *
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400313 * If set to kNone, the codec will decode any necessary required frame(s) first.
scroggo19b91532016-10-24 09:03:26 -0700314 */
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400315 int fPriorFrame;
Matt Sarettcf3f2342017-03-23 15:32:25 -0400316
317 /**
318 * Indicates whether we should do a linear premultiply or a legacy premultiply.
319 *
320 * In the case where the dst SkColorSpace is nullptr, this flag is ignored and
321 * we will always do a legacy premultiply.
322 */
323 SkTransferFunctionBehavior fPremulBehavior;
scroggoeb602a52015-07-09 08:16:03 -0700324 };
325
326 /**
327 * Decode into the given pixels, a block of memory of size at
328 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
329 * bytesPerPixel)
330 *
331 * Repeated calls to this function should give the same results,
332 * allowing the PixelRef to be immutable.
333 *
334 * @param info A description of the format (config, size)
335 * expected by the caller. This can simply be identical
336 * to the info returned by getInfo().
337 *
338 * This contract also allows the caller to specify
339 * different output-configs, which the implementation can
340 * decide to support or not.
341 *
342 * A size that does not match getInfo() implies a request
343 * to scale. If the generator cannot perform this scale,
344 * it will return kInvalidScale.
345 *
msarett50ce1f22016-07-29 06:23:33 -0700346 * If the info contains a non-null SkColorSpace, the codec
347 * will perform the appropriate color space transformation.
348 * If the caller passes in the same color space that was
349 * reported by the codec, the color space transformation is
350 * a no-op.
351 *
scroggo46c57472015-09-30 08:57:13 -0700352 * If a scanline decode is in progress, scanline mode will end, requiring the client to call
353 * startScanlineDecode() in order to return to decoding scanlines.
354 *
scroggoeb602a52015-07-09 08:16:03 -0700355 * @return Result kSuccess, or another value explaining the type of failure.
356 */
Leon Scroggins571b30f2017-07-11 17:35:31 +0000357 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*);
scroggoeb602a52015-07-09 08:16:03 -0700358
359 /**
Leon Scroggins571b30f2017-07-11 17:35:31 +0000360 * Simplified version of getPixels() that uses the default Options.
scroggoeb602a52015-07-09 08:16:03 -0700361 */
Leon Scroggins571b30f2017-07-11 17:35:31 +0000362 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
363 return this->getPixels(info, pixels, rowBytes, nullptr);
364 }
scroggoeb602a52015-07-09 08:16:03 -0700365
msarettb714fb02016-01-22 14:46:42 -0800366 /**
367 * If decoding to YUV is supported, this returns true. Otherwise, this
368 * returns false and does not modify any of the parameters.
369 *
370 * @param sizeInfo Output parameter indicating the sizes and required
371 * allocation widths of the Y, U, and V planes.
372 * @param colorSpace Output parameter. If non-NULL this is set to kJPEG,
373 * otherwise this is ignored.
374 */
msarett4984c3c2016-03-10 05:44:43 -0800375 bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
msarettb714fb02016-01-22 14:46:42 -0800376 if (nullptr == sizeInfo) {
377 return false;
378 }
379
380 return this->onQueryYUV8(sizeInfo, colorSpace);
381 }
382
383 /**
384 * Returns kSuccess, or another value explaining the type of failure.
385 * This always attempts to perform a full decode. If the client only
386 * wants size, it should call queryYUV8().
387 *
388 * @param sizeInfo Needs to exactly match the values returned by the
389 * query, except the WidthBytes may be larger than the
390 * recommendation (but not smaller).
391 * @param planes Memory for each of the Y, U, and V planes.
392 */
msarett4984c3c2016-03-10 05:44:43 -0800393 Result getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) {
msarettb714fb02016-01-22 14:46:42 -0800394 if (nullptr == planes || nullptr == planes[0] || nullptr == planes[1] ||
395 nullptr == planes[2]) {
396 return kInvalidInput;
397 }
398
399 if (!this->rewindIfNeeded()) {
400 return kCouldNotRewind;
401 }
402
403 return this->onGetYUV8Planes(sizeInfo, planes);
404 }
405
scroggoeb602a52015-07-09 08:16:03 -0700406 /**
scroggo8e6c7ad2016-09-16 08:20:38 -0700407 * Prepare for an incremental decode with the specified options.
408 *
409 * This may require a rewind.
410 *
411 * @param dstInfo Info of the destination. If the dimensions do not match
412 * those of getInfo, this implies a scale.
413 * @param dst Memory to write to. Needs to be large enough to hold the subset,
414 * if present, or the full image as described in dstInfo.
415 * @param options Contains decoding options, including if memory is zero
416 * initialized and whether to decode a subset.
scroggo8e6c7ad2016-09-16 08:20:38 -0700417 * @return Enum representing success or reason for failure.
418 */
419 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
Leon Scroggins571b30f2017-07-11 17:35:31 +0000420 const Options*);
scroggo8e6c7ad2016-09-16 08:20:38 -0700421
422 Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
Leon Scroggins571b30f2017-07-11 17:35:31 +0000423 return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr);
scroggo8e6c7ad2016-09-16 08:20:38 -0700424 }
425
426 /**
427 * Start/continue the incremental decode.
428 *
429 * Not valid to call before calling startIncrementalDecode().
430 *
431 * After the first call, should only be called again if more data has been
432 * provided to the source SkStream.
433 *
434 * Unlike getPixels and getScanlines, this does not do any filling. This is
435 * left up to the caller, since they may be skipping lines or continuing the
436 * decode later. In the latter case, they may choose to initialize all lines
437 * first, or only initialize the remaining lines after the first call.
438 *
439 * @param rowsDecoded Optional output variable returning the total number of
440 * lines initialized. Only meaningful if this method returns kIncompleteInput.
441 * Otherwise the implementation may not set it.
442 * Note that some implementations may have initialized this many rows, but
443 * not necessarily finished those rows (e.g. interlaced PNG). This may be
444 * useful for determining what rows the client needs to initialize.
445 * @return kSuccess if all lines requested in startIncrementalDecode have
446 * been completely decoded. kIncompleteInput otherwise.
447 */
448 Result incrementalDecode(int* rowsDecoded = nullptr) {
449 if (!fStartedIncrementalDecode) {
450 return kInvalidParameters;
451 }
452 return this->onIncrementalDecode(rowsDecoded);
453 }
454
455 /**
scroggo46c57472015-09-30 08:57:13 -0700456 * The remaining functions revolve around decoding scanlines.
457 */
458
459 /**
460 * Prepare for a scanline decode with the specified options.
461 *
462 * After this call, this class will be ready to decode the first scanline.
463 *
464 * This must be called in order to call getScanlines or skipScanlines.
465 *
466 * This may require rewinding the stream.
467 *
468 * Not all SkCodecs support this.
469 *
470 * @param dstInfo Info of the destination. If the dimensions do not match
471 * those of getInfo, this implies a scale.
472 * @param options Contains decoding options, including if memory is zero
473 * initialized.
scroggo46c57472015-09-30 08:57:13 -0700474 * @return Enum representing success or reason for failure.
475 */
Leon Scroggins571b30f2017-07-11 17:35:31 +0000476 Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options);
scroggo46c57472015-09-30 08:57:13 -0700477
478 /**
Leon Scroggins571b30f2017-07-11 17:35:31 +0000479 * Simplified version of startScanlineDecode() that uses the default Options.
scroggo46c57472015-09-30 08:57:13 -0700480 */
Leon Scroggins571b30f2017-07-11 17:35:31 +0000481 Result startScanlineDecode(const SkImageInfo& dstInfo) {
482 return this->startScanlineDecode(dstInfo, nullptr);
483 }
scroggo46c57472015-09-30 08:57:13 -0700484
485 /**
486 * Write the next countLines scanlines into dst.
487 *
488 * Not valid to call before calling startScanlineDecode().
489 *
490 * @param dst Must be non-null, and large enough to hold countLines
491 * scanlines of size rowBytes.
492 * @param countLines Number of lines to write.
493 * @param rowBytes Number of bytes per row. Must be large enough to hold
494 * a scanline based on the SkImageInfo used to create this object.
msarette6dd0042015-10-09 11:07:34 -0700495 * @return the number of lines successfully decoded. If this value is
496 * less than countLines, this will fill the remaining lines with a
497 * default value.
scroggo46c57472015-09-30 08:57:13 -0700498 */
msarette6dd0042015-10-09 11:07:34 -0700499 int getScanlines(void* dst, int countLines, size_t rowBytes);
scroggo46c57472015-09-30 08:57:13 -0700500
501 /**
502 * Skip count scanlines.
503 *
504 * Not valid to call before calling startScanlineDecode().
505 *
506 * The default version just calls onGetScanlines and discards the dst.
507 * NOTE: If skipped lines are the only lines with alpha, this default
508 * will make reallyHasAlpha return true, when it could have returned
509 * false.
msarette6dd0042015-10-09 11:07:34 -0700510 *
511 * @return true if the scanlines were successfully skipped
512 * false on failure, possible reasons for failure include:
513 * An incomplete input image stream.
514 * Calling this function before calling startScanlineDecode().
515 * If countLines is less than zero or so large that it moves
516 * the current scanline past the end of the image.
scroggo46c57472015-09-30 08:57:13 -0700517 */
msarette6dd0042015-10-09 11:07:34 -0700518 bool skipScanlines(int countLines);
scroggo46c57472015-09-30 08:57:13 -0700519
520 /**
521 * The order in which rows are output from the scanline decoder is not the
522 * same for all variations of all image types. This explains the possible
523 * output row orderings.
524 */
525 enum SkScanlineOrder {
526 /*
527 * By far the most common, this indicates that the image can be decoded
528 * reliably using the scanline decoder, and that rows will be output in
529 * the logical order.
530 */
531 kTopDown_SkScanlineOrder,
532
533 /*
534 * This indicates that the scanline decoder reliably outputs rows, but
535 * they will be returned in reverse order. If the scanline format is
536 * kBottomUp, the nextScanline() API can be used to determine the actual
537 * y-coordinate of the next output row, but the client is not forced
538 * to take advantage of this, given that it's not too tough to keep
539 * track independently.
540 *
541 * For full image decodes, it is safe to get all of the scanlines at
542 * once, since the decoder will handle inverting the rows as it
543 * decodes.
544 *
545 * For subset decodes and sampling, it is simplest to get and skip
546 * scanlines one at a time, using the nextScanline() API. It is
547 * possible to ask for larger chunks at a time, but this should be used
548 * with caution. As with full image decodes, the decoder will handle
549 * inverting the requested rows, but rows will still be delivered
550 * starting from the bottom of the image.
551 *
552 * Upside down bmps are an example.
553 */
554 kBottomUp_SkScanlineOrder,
scroggo46c57472015-09-30 08:57:13 -0700555 };
556
557 /**
558 * An enum representing the order in which scanlines will be returned by
559 * the scanline decoder.
msarettbe8216a2015-12-04 08:00:50 -0800560 *
561 * This is undefined before startScanlineDecode() is called.
scroggo46c57472015-09-30 08:57:13 -0700562 */
563 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
564
565 /**
566 * Returns the y-coordinate of the next row to be returned by the scanline
msarette6dd0042015-10-09 11:07:34 -0700567 * decoder.
568 *
569 * This will equal fCurrScanline, except in the case of strangely
scroggo19b91532016-10-24 09:03:26 -0700570 * encoded image types (bottom-up bmps).
scroggo46c57472015-09-30 08:57:13 -0700571 *
572 * Results are undefined when not in scanline decoding mode.
573 */
msarette6dd0042015-10-09 11:07:34 -0700574 int nextScanline() const { return this->outputScanline(fCurrScanline); }
575
576 /**
msarettcb0d5c92015-12-03 12:23:43 -0800577 * Returns the output y-coordinate of the row that corresponds to an input
578 * y-coordinate. The input y-coordinate represents where the scanline
579 * is located in the encoded data.
msarette6dd0042015-10-09 11:07:34 -0700580 *
581 * This will equal inputScanline, except in the case of strangely
582 * encoded image types (bottom-up bmps, interlaced gifs).
583 */
584 int outputScanline(int inputScanline) const;
scroggo46c57472015-09-30 08:57:13 -0700585
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400586 /**
587 * Return the number of frames in the image.
588 *
589 * May require reading through the stream.
590 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400591 int getFrameCount() {
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400592 return this->onGetFrameCount();
593 }
594
scroggo19b91532016-10-24 09:03:26 -0700595 // The required frame for an independent frame is marked as
596 // kNone.
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400597 static constexpr int kNone = -1;
scroggo19b91532016-10-24 09:03:26 -0700598
599 /**
600 * Information about individual frames in a multi-framed image.
601 */
602 struct FrameInfo {
603 /**
604 * The frame that this frame needs to be blended with, or
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400605 * kNone if this frame is independent.
606 *
607 * Note that this is the *earliest* frame that can be used
608 * for blending. Any frame from [fRequiredFrame, i) can be
609 * used, unless its fDisposalMethod is kRestorePrevious.
scroggo19b91532016-10-24 09:03:26 -0700610 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400611 int fRequiredFrame;
scroggo19b91532016-10-24 09:03:26 -0700612
613 /**
614 * Number of milliseconds to show this frame.
615 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400616 int fDuration;
Leon Scroggins III3639faa2016-12-08 11:38:58 -0500617
618 /**
619 * Whether the end marker for this frame is contained in the stream.
620 *
621 * Note: this does not guarantee that an attempt to decode will be complete.
622 * There could be an error in the stream.
623 */
624 bool fFullyReceived;
Leon Scroggins IIIa4db9be2017-04-11 10:32:02 -0400625
626 /**
627 * This is conservative; it will still return non-opaque if e.g. a
628 * color index-based frame has a color with alpha but does not use it.
629 */
630 SkAlphaType fAlphaType;
Leon Scroggins III33deb7e2017-06-07 12:31:51 -0400631
632 /**
633 * How this frame should be modified before decoding the next one.
634 */
635 SkCodecAnimation::DisposalMethod fDisposalMethod;
scroggo19b91532016-10-24 09:03:26 -0700636 };
637
638 /**
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400639 * Return info about a single frame.
640 *
641 * Only supported by multi-frame images. Does not read through the stream,
642 * so it should be called after getFrameCount() to parse any frames that
643 * have not already been parsed.
644 */
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400645 bool getFrameInfo(int index, FrameInfo* info) const {
Leon Scroggins III557fbbe2017-05-23 09:37:21 -0400646 if (index < 0) {
647 return false;
648 }
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400649 return this->onGetFrameInfo(index, info);
650 }
651
652 /**
653 * Return info about all the frames in the image.
scroggo19b91532016-10-24 09:03:26 -0700654 *
scroggoe71b1a12016-11-01 08:28:28 -0700655 * May require reading through the stream to determine info about the
656 * frames (including the count).
scroggo19b91532016-10-24 09:03:26 -0700657 *
658 * As such, future decoding calls may require a rewind.
659 *
660 * For single-frame images, this will return an empty vector.
661 */
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400662 std::vector<FrameInfo> getFrameInfo();
scroggo19b91532016-10-24 09:03:26 -0700663
scroggoe71b1a12016-11-01 08:28:28 -0700664 static constexpr int kRepetitionCountInfinite = -1;
665
666 /**
667 * Return the number of times to repeat, if this image is animated.
668 *
669 * May require reading the stream to find the repetition count.
670 *
671 * As such, future decoding calls may require a rewind.
672 *
673 * For single-frame images, this will return 0.
674 */
675 int getRepetitionCount() {
676 return this->onGetRepetitionCount();
677 }
678
scroggof24f2242015-03-03 08:59:20 -0800679protected:
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400680 using XformFormat = SkColorSpaceXform::ColorFormat;
681
msarettc30c4182016-04-20 11:53:35 -0700682 SkCodec(int width,
683 int height,
684 const SkEncodedInfo&,
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400685 XformFormat srcFormat,
Mike Reedede7bac2017-07-23 15:30:02 -0400686 std::unique_ptr<SkStream>,
Matt Sarett7f650bd2016-10-30 21:25:34 -0400687 sk_sp<SkColorSpace>,
msarett0e6274f2016-03-21 08:04:40 -0700688 Origin = kTopLeft_Origin);
scroggof24f2242015-03-03 08:59:20 -0800689
msarett549ca322016-08-17 08:54:08 -0700690 /**
msarett549ca322016-08-17 08:54:08 -0700691 * Allows the subclass to set the recommended SkImageInfo
692 */
693 SkCodec(const SkEncodedInfo&,
694 const SkImageInfo&,
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400695 XformFormat srcFormat,
Mike Reedede7bac2017-07-23 15:30:02 -0400696 std::unique_ptr<SkStream>,
msarett549ca322016-08-17 08:54:08 -0700697 Origin = kTopLeft_Origin);
698
msarettb714fb02016-01-22 14:46:42 -0800699 virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
scroggof24f2242015-03-03 08:59:20 -0800700 // By default, scaling is not supported.
halcanaryb880d7f2015-03-26 06:29:03 -0700701 return this->getInfo().dimensions();
scroggof24f2242015-03-03 08:59:20 -0800702 }
703
scroggoe7fc14b2015-10-02 13:14:46 -0700704 // FIXME: What to do about subsets??
705 /**
706 * Subclasses should override if they support dimensions other than the
707 * srcInfo's.
708 */
709 virtual bool onDimensionsSupported(const SkISize&) {
710 return false;
711 }
712
Hal Canarydb683012016-11-23 08:55:18 -0700713 virtual SkEncodedImageFormat onGetEncodedFormat() const = 0;
scroggo1dd3ea92015-03-20 11:55:55 -0700714
msarette6dd0042015-10-09 11:07:34 -0700715 /**
716 * @param rowsDecoded When the encoded image stream is incomplete, this function
717 * will return kIncompleteInput and rowsDecoded will be set to
718 * the number of scanlines that were successfully decoded.
719 * This will allow getPixels() to fill the uninitialized memory.
720 */
scroggoeb602a52015-07-09 08:16:03 -0700721 virtual Result onGetPixels(const SkImageInfo& info,
722 void* pixels, size_t rowBytes, const Options&,
msarette6dd0042015-10-09 11:07:34 -0700723 int* rowsDecoded) = 0;
scroggoeb602a52015-07-09 08:16:03 -0700724
msarett4984c3c2016-03-10 05:44:43 -0800725 virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
msarettb714fb02016-01-22 14:46:42 -0800726 return false;
727 }
728
msarett4984c3c2016-03-10 05:44:43 -0800729 virtual Result onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
msarettb714fb02016-01-22 14:46:42 -0800730 return kUnimplemented;
731 }
732
733 virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const {
scroggob636b452015-07-22 07:16:20 -0700734 // By default, subsets are not supported.
735 return false;
736 }
737
msarett90c4d5f2015-12-10 13:09:24 -0800738 /**
scroggof24f2242015-03-03 08:59:20 -0800739 * If the stream was previously read, attempt to rewind.
scroggob427db12015-08-12 07:24:13 -0700740 *
741 * If the stream needed to be rewound, call onRewind.
742 * @returns true if the codec is at the right position and can be used.
743 * false if there was a failure to rewind.
halcanarya096d7a2015-03-27 12:16:53 -0700744 *
scroggo3a7701c2015-09-30 09:15:14 -0700745 * This is called by getPixels() and start(). Subclasses may call if they
746 * need to rewind at another time.
scroggof24f2242015-03-03 08:59:20 -0800747 */
scroggob427db12015-08-12 07:24:13 -0700748 bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
749
750 /**
751 * Called by rewindIfNeeded, if the stream needed to be rewound.
752 *
753 * Subclasses should do any set up needed after a rewind.
754 */
755 virtual bool onRewind() {
756 return true;
757 }
scroggof24f2242015-03-03 08:59:20 -0800758
msarettc0e80c12015-07-01 06:50:35 -0700759 /**
msarette6dd0042015-10-09 11:07:34 -0700760 * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
761 * scanlines. This allows the subclass to indicate what value to fill with.
762 *
msarettf7eb6fc2016-09-13 09:04:11 -0700763 * @param dstInfo Describes the destination.
msarette6dd0042015-10-09 11:07:34 -0700764 * @return The value with which to fill uninitialized pixels.
765 *
msarettf7eb6fc2016-09-13 09:04:11 -0700766 * Note that we can interpret the return value as a 64-bit Float16 color, a SkPMColor,
767 * a 16-bit 565 color, an 8-bit gray color, or an 8-bit index into a color table,
768 * depending on the color type.
msarette6dd0042015-10-09 11:07:34 -0700769 */
msarettf7eb6fc2016-09-13 09:04:11 -0700770 uint64_t getFillValue(const SkImageInfo& dstInfo) const {
771 return this->onGetFillValue(dstInfo);
msarette6dd0042015-10-09 11:07:34 -0700772 }
773
774 /**
775 * Some subclasses will override this function, but this is a useful default for the color
msarettf7eb6fc2016-09-13 09:04:11 -0700776 * types that we support. Note that for color types that do not use the full 64-bits,
msarette6dd0042015-10-09 11:07:34 -0700777 * we will simply take the low bits of the fill value.
778 *
msarettf7eb6fc2016-09-13 09:04:11 -0700779 * The defaults are:
780 * kRGBA_F16_SkColorType: Transparent or Black, depending on the src alpha type
scroggoc5560be2016-02-03 09:42:42 -0800781 * kN32_SkColorType: Transparent or Black, depending on the src alpha type
msarette6dd0042015-10-09 11:07:34 -0700782 * kRGB_565_SkColorType: Black
783 * kGray_8_SkColorType: Black
msarette6dd0042015-10-09 11:07:34 -0700784 */
msarettf7eb6fc2016-09-13 09:04:11 -0700785 virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const;
msarette6dd0042015-10-09 11:07:34 -0700786
787 /**
msarett74114382015-03-16 11:55:18 -0700788 * Get method for the input stream
msarett74114382015-03-16 11:55:18 -0700789 */
790 SkStream* stream() {
791 return fStream.get();
792 }
793
scroggo46c57472015-09-30 08:57:13 -0700794 /**
795 * The remaining functions revolve around decoding scanlines.
796 */
797
798 /**
799 * Most images types will be kTopDown and will not need to override this function.
800 */
801 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
802
scroggo46c57472015-09-30 08:57:13 -0700803 const SkImageInfo& dstInfo() const { return fDstInfo; }
804
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400805 const Options& options() const { return fOptions; }
scroggo46c57472015-09-30 08:57:13 -0700806
msarettcb0d5c92015-12-03 12:23:43 -0800807 /**
808 * Returns the number of scanlines that have been decoded so far.
809 * This is unaffected by the SkScanlineOrder.
810 *
811 * Returns -1 if we have not started a scanline decode.
812 */
813 int currScanline() const { return fCurrScanline; }
814
msarette6dd0042015-10-09 11:07:34 -0700815 virtual int onOutputScanline(int inputScanline) const;
816
Matt Sarettcf3f2342017-03-23 15:32:25 -0400817 bool initializeColorXform(const SkImageInfo& dstInfo,
818 SkTransferFunctionBehavior premulBehavior);
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400819 void applyColorXform(void* dst, const void* src, int count, SkAlphaType) const;
820 void applyColorXform(void* dst, const void* src, int count) const;
821
Matt Sarett313c4632016-10-20 12:35:23 -0400822 SkColorSpaceXform* colorXform() const { return fColorXform.get(); }
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400823 bool xformOnDecode() const { return fXformOnDecode; }
Matt Sarett313c4632016-10-20 12:35:23 -0400824
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400825 virtual int onGetFrameCount() {
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400826 return 1;
827 }
828
Leon Scroggins III249b8e32017-04-17 12:46:33 -0400829 virtual bool onGetFrameInfo(int, FrameInfo*) const {
Leon Scroggins IIIe132e7b2017-04-12 10:49:52 -0400830 return false;
scroggo19b91532016-10-24 09:03:26 -0700831 }
832
scroggoe71b1a12016-11-01 08:28:28 -0700833 virtual int onGetRepetitionCount() {
834 return 0;
835 }
836
Matt Sarett313c4632016-10-20 12:35:23 -0400837private:
838 const SkEncodedInfo fEncodedInfo;
839 const SkImageInfo fSrcInfo;
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400840 const XformFormat fSrcXformFormat;
bungeman6bd52842016-10-27 09:30:08 -0700841 std::unique_ptr<SkStream> fStream;
Matt Sarett313c4632016-10-20 12:35:23 -0400842 bool fNeedsRewind;
843 const Origin fOrigin;
844
845 SkImageInfo fDstInfo;
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400846 Options fOptions;
847 XformFormat fDstXformFormat; // Based on fDstInfo.
Matt Sarett313c4632016-10-20 12:35:23 -0400848 std::unique_ptr<SkColorSpaceXform> fColorXform;
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400849 bool fXformOnDecode;
scroggo8e6c7ad2016-09-16 08:20:38 -0700850
851 // Only meaningful during scanline decodes.
Matt Sarett313c4632016-10-20 12:35:23 -0400852 int fCurrScanline;
scroggo46c57472015-09-30 08:57:13 -0700853
Matt Sarett313c4632016-10-20 12:35:23 -0400854 bool fStartedIncrementalDecode;
scroggo8e6c7ad2016-09-16 08:20:38 -0700855
scroggoe7fc14b2015-10-02 13:14:46 -0700856 /**
857 * Return whether these dimensions are supported as a scale.
858 *
859 * The codec may choose to cache the information about scale and subset.
860 * Either way, the same information will be passed to onGetPixels/onStart
861 * on success.
862 *
863 * This must return true for a size returned from getScaledDimensions.
864 */
865 bool dimensionsSupported(const SkISize& dim) {
866 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim);
867 }
868
Leon Scroggins III1f6af6b2017-06-12 16:41:09 -0400869 /**
870 * For multi-framed images, return the object with information about the frames.
871 */
872 virtual const SkFrameHolder* getFrameHolder() const {
873 return nullptr;
874 }
875
876 /**
877 * Check for a valid Options.fFrameIndex, and decode prior frames if necessary.
878 */
879 Result handleFrameIndex(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&);
880
scroggo46c57472015-09-30 08:57:13 -0700881 // Methods for scanline decoding.
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -0400882 virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
Leon Scroggins571b30f2017-07-11 17:35:31 +0000883 const Options& /*options*/) {
scroggo46c57472015-09-30 08:57:13 -0700884 return kUnimplemented;
885 }
886
scroggo8e6c7ad2016-09-16 08:20:38 -0700887 virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
Leon Scroggins571b30f2017-07-11 17:35:31 +0000888 const Options&) {
scroggo8e6c7ad2016-09-16 08:20:38 -0700889 return kUnimplemented;
890 }
891
892 virtual Result onIncrementalDecode(int*) {
893 return kUnimplemented;
894 }
895
896
msarett9b9497e2016-02-11 13:29:36 -0800897 virtual bool onSkipScanlines(int /*countLines*/) { return false; }
scroggo46c57472015-09-30 08:57:13 -0700898
msarett33bee092015-11-11 12:43:07 -0800899 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
msarette6dd0042015-10-09 11:07:34 -0700900
901 /**
902 * On an incomplete decode, getPixels() and getScanlines() will call this function
903 * to fill any uinitialized memory.
904 *
905 * @param dstInfo Contains the destination color type
906 * Contains the destination alpha type
907 * Contains the destination width
908 * The height stored in this info is unused
909 * @param dst Pointer to the start of destination pixel memory
910 * @param rowBytes Stride length in destination pixel memory
911 * @param zeroInit Indicates if memory is zero initialized
912 * @param linesRequested Number of lines that the client requested
913 * @param linesDecoded Number of lines that were successfully decoded
914 */
915 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
916 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
scroggo46c57472015-09-30 08:57:13 -0700917
scroggoe7fc14b2015-10-02 13:14:46 -0700918 /**
919 * Return an object which will allow forcing scanline decodes to sample in X.
920 *
921 * May create a sampler, if one is not currently being used. Otherwise, does
922 * not affect ownership.
923 *
scroggo19b91532016-10-24 09:03:26 -0700924 * Only valid during scanline decoding or incremental decoding.
scroggoe7fc14b2015-10-02 13:14:46 -0700925 */
msarett33bee092015-11-11 12:43:07 -0800926 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
scroggoe7fc14b2015-10-02 13:14:46 -0700927
scroggo8e6c7ad2016-09-16 08:20:38 -0700928 friend class DM::CodecSrc; // for fillIncompleteImage
msarett3d9d7a72015-10-21 10:27:10 -0700929 friend class SkSampledCodec;
msarettbe8216a2015-12-04 08:00:50 -0800930 friend class SkIcoCodec;
scroggof24f2242015-03-03 08:59:20 -0800931};
932#endif // SkCodec_DEFINED