blob: c3a5873d7f9fb77e03027f684d573061bc9c3dd2 [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"
scroggoeb602a52015-07-09 08:16:03 -070012#include "SkColor.h"
scroggo1dd3ea92015-03-20 11:55:55 -070013#include "SkEncodedFormat.h"
scroggof24f2242015-03-03 08:59:20 -080014#include "SkImageInfo.h"
15#include "SkSize.h"
scroggofffeede2015-03-18 10:50:37 -070016#include "SkStream.h"
scroggof24f2242015-03-03 08:59:20 -080017#include "SkTypes.h"
18
19class SkData;
scroggocf98fa92015-11-23 08:14:40 -080020class SkPngChunkReader;
scroggoe7fc14b2015-10-02 13:14:46 -070021class SkSampler;
scroggof24f2242015-03-03 08:59:20 -080022
23/**
24 * Abstraction layer directly on top of an image codec.
25 */
scroggoeb602a52015-07-09 08:16:03 -070026class SkCodec : SkNoncopyable {
scroggof24f2242015-03-03 08:59:20 -080027public:
28 /**
scroggodb30be22015-12-08 18:54:13 -080029 * Minimum number of bytes that must be buffered in SkStream input.
30 *
31 * An SkStream passed to NewFromStream must be able to use this many
32 * bytes to determine the image type. Then the same SkStream must be
33 * passed to the correct decoder to read from the beginning.
34 *
35 * This can be accomplished by implementing peek() to support peeking
36 * this many bytes, or by implementing rewind() to be able to rewind()
37 * after reading this many bytes.
38 */
39 static size_t MinBufferedBytesNeeded();
40
41 /**
scroggof24f2242015-03-03 08:59:20 -080042 * If this stream represents an encoded image that we know how to decode,
43 * return an SkCodec that can decode it. Otherwise return NULL.
44 *
scroggodb30be22015-12-08 18:54:13 -080045 * As stated above, this call must be able to peek or read
46 * MinBufferedBytesNeeded to determine the correct format, and then start
47 * reading from the beginning. First it will attempt to peek, and it
48 * assumes that if less than MinBufferedBytesNeeded bytes (but more than
49 * zero) are returned, this is because the stream is shorter than this,
50 * so falling back to reading would not provide more data. If peek()
51 * returns zero bytes, this call will instead attempt to read(). This
52 * will require that the stream can be rewind()ed.
53 *
54 * If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
55 * the image is a png.
56 *
msarett7d5105c2015-12-02 07:02:41 -080057 * If the SkPngChunkReader is not NULL then:
58 * If the image is not a PNG, the SkPngChunkReader will be ignored.
59 * If the image is a PNG, the SkPngChunkReader will be reffed.
60 * If the PNG has unknown chunks, the SkPngChunkReader will be used
61 * to handle these chunks. SkPngChunkReader will be called to read
62 * any unknown chunk at any point during the creation of the codec
63 * or the decode. Note that if SkPngChunkReader fails to read a
64 * chunk, this could result in a failure to create the codec or a
65 * failure to decode the image.
66 * If the PNG does not contain unknown chunks, the SkPngChunkReader
67 * will not be used or modified.
scroggocf98fa92015-11-23 08:14:40 -080068 *
scroggof24f2242015-03-03 08:59:20 -080069 * If NULL is returned, the stream is deleted immediately. Otherwise, the
70 * SkCodec takes ownership of it, and will delete it when done with it.
71 */
scroggocf98fa92015-11-23 08:14:40 -080072 static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL);
scroggof24f2242015-03-03 08:59:20 -080073
74 /**
75 * If this data represents an encoded image that we know how to decode,
76 * return an SkCodec that can decode it. Otherwise return NULL.
77 *
msarett7d5105c2015-12-02 07:02:41 -080078 * If the SkPngChunkReader is not NULL then:
79 * If the image is not a PNG, the SkPngChunkReader will be ignored.
80 * If the image is a PNG, the SkPngChunkReader will be reffed.
81 * If the PNG has unknown chunks, the SkPngChunkReader will be used
82 * to handle these chunks. SkPngChunkReader will be called to read
83 * any unknown chunk at any point during the creation of the codec
84 * or the decode. Note that if SkPngChunkReader fails to read a
85 * chunk, this could result in a failure to create the codec or a
86 * failure to decode the image.
87 * If the PNG does not contain unknown chunks, the SkPngChunkReader
88 * will not be used or modified.
scroggocf98fa92015-11-23 08:14:40 -080089 *
scroggof24f2242015-03-03 08:59:20 -080090 * Will take a ref if it returns a codec, else will not affect the data.
91 */
scroggocf98fa92015-11-23 08:14:40 -080092 static SkCodec* NewFromData(SkData*, SkPngChunkReader* = NULL);
scroggof24f2242015-03-03 08:59:20 -080093
scroggoeb602a52015-07-09 08:16:03 -070094 virtual ~SkCodec();
95
96 /**
97 * Return the ImageInfo associated with this codec.
98 */
scroggo46c57472015-09-30 08:57:13 -070099 const SkImageInfo& getInfo() const { return fSrcInfo; }
scroggoeb602a52015-07-09 08:16:03 -0700100
scroggof24f2242015-03-03 08:59:20 -0800101 /**
102 * Return a size that approximately supports the desired scale factor.
103 * The codec may not be able to scale efficiently to the exact scale
104 * factor requested, so return a size that approximates that scale.
emmaleer8f4ba762015-08-14 07:44:46 -0700105 * The returned value is the codec's suggestion for the closest valid
106 * scale that it can natively support
scroggof24f2242015-03-03 08:59:20 -0800107 */
scroggofffeede2015-03-18 10:50:37 -0700108 SkISize getScaledDimensions(float desiredScale) const {
msarettb32758a2015-08-18 13:22:46 -0700109 // Negative and zero scales are errors.
110 SkASSERT(desiredScale > 0.0f);
111 if (desiredScale <= 0.0f) {
112 return SkISize::Make(0, 0);
113 }
114
115 // Upscaling is not supported. Return the original size if the client
116 // requests an upscale.
117 if (desiredScale >= 1.0f) {
118 return this->getInfo().dimensions();
119 }
scroggofffeede2015-03-18 10:50:37 -0700120 return this->onGetScaledDimensions(desiredScale);
121 }
scroggof24f2242015-03-03 08:59:20 -0800122
scroggo1dd3ea92015-03-20 11:55:55 -0700123 /**
scroggob636b452015-07-22 07:16:20 -0700124 * Return (via desiredSubset) a subset which can decoded from this codec,
125 * or false if this codec cannot decode subsets or anything similar to
126 * desiredSubset.
127 *
128 * @param desiredSubset In/out parameter. As input, a desired subset of
129 * the original bounds (as specified by getInfo). If true is returned,
130 * desiredSubset may have been modified to a subset which is
131 * supported. Although a particular change may have been made to
132 * desiredSubset to create something supported, it is possible other
133 * changes could result in a valid subset.
134 * If false is returned, desiredSubset's value is undefined.
135 * @return true if this codec supports decoding desiredSubset (as
136 * returned, potentially modified)
137 */
138 bool getValidSubset(SkIRect* desiredSubset) const {
139 return this->onGetValidSubset(desiredSubset);
140 }
141
142 /**
scroggo1dd3ea92015-03-20 11:55:55 -0700143 * Format of the encoded data.
144 */
145 SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
146
scroggo05245902015-03-25 11:11:52 -0700147 /**
scroggoeb602a52015-07-09 08:16:03 -0700148 * Used to describe the result of a call to getPixels().
149 *
150 * Result is the union of possible results from subclasses.
151 */
152 enum Result {
153 /**
154 * General return value for success.
155 */
156 kSuccess,
157 /**
158 * The input is incomplete. A partial image was generated.
159 */
160 kIncompleteInput,
161 /**
162 * The generator cannot convert to match the request, ignoring
163 * dimensions.
164 */
165 kInvalidConversion,
166 /**
167 * The generator cannot scale to requested size.
168 */
169 kInvalidScale,
170 /**
171 * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
172 * too small, etc.
173 */
174 kInvalidParameters,
175 /**
176 * The input did not contain a valid image.
177 */
178 kInvalidInput,
179 /**
180 * Fulfilling this request requires rewinding the input, which is not
181 * supported for this input.
182 */
183 kCouldNotRewind,
184 /**
scroggo46c57472015-09-30 08:57:13 -0700185 * This method is not implemented by this codec.
186 * FIXME: Perhaps this should be kUnsupported?
scroggoeb602a52015-07-09 08:16:03 -0700187 */
188 kUnimplemented,
189 };
190
191 /**
192 * Whether or not the memory passed to getPixels is zero initialized.
193 */
194 enum ZeroInitialized {
195 /**
196 * The memory passed to getPixels is zero initialized. The SkCodec
197 * may take advantage of this by skipping writing zeroes.
198 */
199 kYes_ZeroInitialized,
200 /**
201 * The memory passed to getPixels has not been initialized to zero,
202 * so the SkCodec must write all zeroes to memory.
203 *
204 * This is the default. It will be used if no Options struct is used.
205 */
206 kNo_ZeroInitialized,
207 };
208
209 /**
210 * Additional options to pass to getPixels.
211 */
212 struct Options {
213 Options()
scroggob636b452015-07-22 07:16:20 -0700214 : fZeroInitialized(kNo_ZeroInitialized)
215 , fSubset(NULL)
216 {}
scroggoeb602a52015-07-09 08:16:03 -0700217
218 ZeroInitialized fZeroInitialized;
scroggob636b452015-07-22 07:16:20 -0700219 /**
220 * If not NULL, represents a subset of the original image to decode.
scroggob636b452015-07-22 07:16:20 -0700221 * Must be within the bounds returned by getInfo().
scroggob636b452015-07-22 07:16:20 -0700222 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
223 * currently supports subsets), the top and left values must be even.
msarettfdb47572015-10-13 12:50:14 -0700224 *
225 * In getPixels, we will attempt to decode the exact rectangular
226 * subset specified by fSubset.
227 *
228 * In a scanline decode, it does not make sense to specify a subset
229 * top or subset height, since the client already controls which rows
230 * to get and which rows to skip. During scanline decodes, we will
231 * require that the subset top be zero and the subset height be equal
232 * to the full height. We will, however, use the values of
233 * subset left and subset width to decode partial scanlines on calls
234 * to getScanlines().
scroggob636b452015-07-22 07:16:20 -0700235 */
236 SkIRect* fSubset;
scroggoeb602a52015-07-09 08:16:03 -0700237 };
238
239 /**
240 * Decode into the given pixels, a block of memory of size at
241 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
242 * bytesPerPixel)
243 *
244 * Repeated calls to this function should give the same results,
245 * allowing the PixelRef to be immutable.
246 *
247 * @param info A description of the format (config, size)
248 * expected by the caller. This can simply be identical
249 * to the info returned by getInfo().
250 *
251 * This contract also allows the caller to specify
252 * different output-configs, which the implementation can
253 * decide to support or not.
254 *
255 * A size that does not match getInfo() implies a request
256 * to scale. If the generator cannot perform this scale,
257 * it will return kInvalidScale.
258 *
259 * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
260 * SkPMColor values in ctable. On success the generator must copy N colors into that storage,
261 * (where N is the logical number of table entries) and set ctableCount to N.
262 *
263 * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
264 * is not null, it will be set to 0.
265 *
scroggo46c57472015-09-30 08:57:13 -0700266 * If a scanline decode is in progress, scanline mode will end, requiring the client to call
267 * startScanlineDecode() in order to return to decoding scanlines.
268 *
scroggoeb602a52015-07-09 08:16:03 -0700269 * @return Result kSuccess, or another value explaining the type of failure.
270 */
271 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*,
272 SkPMColor ctable[], int* ctableCount);
273
274 /**
275 * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
276 * uses the default Options.
277 */
278 Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
279
msarettb714fb02016-01-22 14:46:42 -0800280 struct YUVSizeInfo {
281 SkISize fYSize;
282 SkISize fUSize;
283 SkISize fVSize;
284
285 /**
286 * While the widths of the Y, U, and V planes are not restricted, the
287 * implementation requires that the width of the memory allocated for
288 * each plane be a multiple of DCTSIZE (which is always 8).
289 *
290 * This struct allows us to inform the client how many "widthBytes"
291 * that we need. Note that we use the new idea of "widthBytes"
292 * because this idea is distinct from "rowBytes" (used elsewhere in
293 * Skia). "rowBytes" allow the last row of the allocation to not
294 * include any extra padding, while, in this case, every single row of
295 * the allocation must be at least "widthBytes".
296 */
297 size_t fYWidthBytes;
298 size_t fUWidthBytes;
299 size_t fVWidthBytes;
300 };
301
302 /**
303 * If decoding to YUV is supported, this returns true. Otherwise, this
304 * returns false and does not modify any of the parameters.
305 *
306 * @param sizeInfo Output parameter indicating the sizes and required
307 * allocation widths of the Y, U, and V planes.
308 * @param colorSpace Output parameter. If non-NULL this is set to kJPEG,
309 * otherwise this is ignored.
310 */
311 bool queryYUV8(YUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
312 if (nullptr == sizeInfo) {
313 return false;
314 }
315
316 return this->onQueryYUV8(sizeInfo, colorSpace);
317 }
318
319 /**
320 * Returns kSuccess, or another value explaining the type of failure.
321 * This always attempts to perform a full decode. If the client only
322 * wants size, it should call queryYUV8().
323 *
324 * @param sizeInfo Needs to exactly match the values returned by the
325 * query, except the WidthBytes may be larger than the
326 * recommendation (but not smaller).
327 * @param planes Memory for each of the Y, U, and V planes.
328 */
329 Result getYUV8Planes(const YUVSizeInfo& sizeInfo, void* planes[3]) {
330 if (nullptr == planes || nullptr == planes[0] || nullptr == planes[1] ||
331 nullptr == planes[2]) {
332 return kInvalidInput;
333 }
334
335 if (!this->rewindIfNeeded()) {
336 return kCouldNotRewind;
337 }
338
339 return this->onGetYUV8Planes(sizeInfo, planes);
340 }
341
scroggoeb602a52015-07-09 08:16:03 -0700342 /**
scroggo46c57472015-09-30 08:57:13 -0700343 * The remaining functions revolve around decoding scanlines.
344 */
345
346 /**
347 * Prepare for a scanline decode with the specified options.
348 *
349 * After this call, this class will be ready to decode the first scanline.
350 *
351 * This must be called in order to call getScanlines or skipScanlines.
352 *
353 * This may require rewinding the stream.
354 *
355 * Not all SkCodecs support this.
356 *
357 * @param dstInfo Info of the destination. If the dimensions do not match
358 * those of getInfo, this implies a scale.
359 * @param options Contains decoding options, including if memory is zero
360 * initialized.
361 * @param ctable A pointer to a color table. When dstInfo.colorType() is
362 * kIndex8, this should be non-NULL and have enough storage for 256
363 * colors. The color table will be populated after decoding the palette.
364 * @param ctableCount A pointer to the size of the color table. When
365 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
366 * be modified to the true size of the color table (<= 256) after
367 * decoding the palette.
368 * @return Enum representing success or reason for failure.
369 */
370 Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options,
msarettfdb47572015-10-13 12:50:14 -0700371 SkPMColor ctable[], int* ctableCount);
scroggo46c57472015-09-30 08:57:13 -0700372
373 /**
374 * Simplified version of startScanlineDecode() that asserts that info is NOT
375 * kIndex8_SkColorType and uses the default Options.
376 */
377 Result startScanlineDecode(const SkImageInfo& dstInfo);
378
379 /**
380 * Write the next countLines scanlines into dst.
381 *
382 * Not valid to call before calling startScanlineDecode().
383 *
384 * @param dst Must be non-null, and large enough to hold countLines
385 * scanlines of size rowBytes.
386 * @param countLines Number of lines to write.
387 * @param rowBytes Number of bytes per row. Must be large enough to hold
388 * a scanline based on the SkImageInfo used to create this object.
msarette6dd0042015-10-09 11:07:34 -0700389 * @return the number of lines successfully decoded. If this value is
390 * less than countLines, this will fill the remaining lines with a
391 * default value.
scroggo46c57472015-09-30 08:57:13 -0700392 */
msarette6dd0042015-10-09 11:07:34 -0700393 int getScanlines(void* dst, int countLines, size_t rowBytes);
scroggo46c57472015-09-30 08:57:13 -0700394
395 /**
396 * Skip count scanlines.
397 *
398 * Not valid to call before calling startScanlineDecode().
399 *
400 * The default version just calls onGetScanlines and discards the dst.
401 * NOTE: If skipped lines are the only lines with alpha, this default
402 * will make reallyHasAlpha return true, when it could have returned
403 * false.
msarette6dd0042015-10-09 11:07:34 -0700404 *
405 * @return true if the scanlines were successfully skipped
406 * false on failure, possible reasons for failure include:
407 * An incomplete input image stream.
408 * Calling this function before calling startScanlineDecode().
409 * If countLines is less than zero or so large that it moves
410 * the current scanline past the end of the image.
scroggo46c57472015-09-30 08:57:13 -0700411 */
msarette6dd0042015-10-09 11:07:34 -0700412 bool skipScanlines(int countLines);
scroggo46c57472015-09-30 08:57:13 -0700413
414 /**
415 * The order in which rows are output from the scanline decoder is not the
416 * same for all variations of all image types. This explains the possible
417 * output row orderings.
418 */
419 enum SkScanlineOrder {
420 /*
421 * By far the most common, this indicates that the image can be decoded
422 * reliably using the scanline decoder, and that rows will be output in
423 * the logical order.
424 */
425 kTopDown_SkScanlineOrder,
426
427 /*
428 * This indicates that the scanline decoder reliably outputs rows, but
429 * they will be returned in reverse order. If the scanline format is
430 * kBottomUp, the nextScanline() API can be used to determine the actual
431 * y-coordinate of the next output row, but the client is not forced
432 * to take advantage of this, given that it's not too tough to keep
433 * track independently.
434 *
435 * For full image decodes, it is safe to get all of the scanlines at
436 * once, since the decoder will handle inverting the rows as it
437 * decodes.
438 *
439 * For subset decodes and sampling, it is simplest to get and skip
440 * scanlines one at a time, using the nextScanline() API. It is
441 * possible to ask for larger chunks at a time, but this should be used
442 * with caution. As with full image decodes, the decoder will handle
443 * inverting the requested rows, but rows will still be delivered
444 * starting from the bottom of the image.
445 *
446 * Upside down bmps are an example.
447 */
448 kBottomUp_SkScanlineOrder,
449
450 /*
451 * This indicates that the scanline decoder reliably outputs rows, but
452 * they will not be in logical order. If the scanline format is
453 * kOutOfOrder, the nextScanline() API should be used to determine the
454 * actual y-coordinate of the next output row.
455 *
456 * For this scanline ordering, it is advisable to get and skip
457 * scanlines one at a time.
458 *
459 * Interlaced gifs are an example.
460 */
461 kOutOfOrder_SkScanlineOrder,
462
463 /*
464 * Indicates that the entire image must be decoded in order to output
465 * any amount of scanlines. In this case, it is a REALLY BAD IDEA to
466 * request scanlines 1-by-1 or in small chunks. The client should
467 * determine which scanlines are needed and ask for all of them in
468 * a single call to getScanlines().
469 *
470 * Interlaced pngs are an example.
471 */
472 kNone_SkScanlineOrder,
473 };
474
475 /**
476 * An enum representing the order in which scanlines will be returned by
477 * the scanline decoder.
msarettbe8216a2015-12-04 08:00:50 -0800478 *
479 * This is undefined before startScanlineDecode() is called.
scroggo46c57472015-09-30 08:57:13 -0700480 */
481 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
482
483 /**
484 * Returns the y-coordinate of the next row to be returned by the scanline
msarette6dd0042015-10-09 11:07:34 -0700485 * decoder.
486 *
487 * This will equal fCurrScanline, except in the case of strangely
488 * encoded image types (bottom-up bmps, interlaced gifs).
scroggo46c57472015-09-30 08:57:13 -0700489 *
490 * Results are undefined when not in scanline decoding mode.
491 */
msarette6dd0042015-10-09 11:07:34 -0700492 int nextScanline() const { return this->outputScanline(fCurrScanline); }
493
494 /**
msarettcb0d5c92015-12-03 12:23:43 -0800495 * Returns the output y-coordinate of the row that corresponds to an input
496 * y-coordinate. The input y-coordinate represents where the scanline
497 * is located in the encoded data.
msarette6dd0042015-10-09 11:07:34 -0700498 *
499 * This will equal inputScanline, except in the case of strangely
500 * encoded image types (bottom-up bmps, interlaced gifs).
501 */
502 int outputScanline(int inputScanline) const;
scroggo46c57472015-09-30 08:57:13 -0700503
scroggof24f2242015-03-03 08:59:20 -0800504protected:
505 SkCodec(const SkImageInfo&, SkStream*);
506
msarettb714fb02016-01-22 14:46:42 -0800507 virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
scroggof24f2242015-03-03 08:59:20 -0800508 // By default, scaling is not supported.
halcanaryb880d7f2015-03-26 06:29:03 -0700509 return this->getInfo().dimensions();
scroggof24f2242015-03-03 08:59:20 -0800510 }
511
scroggoe7fc14b2015-10-02 13:14:46 -0700512 // FIXME: What to do about subsets??
513 /**
514 * Subclasses should override if they support dimensions other than the
515 * srcInfo's.
516 */
517 virtual bool onDimensionsSupported(const SkISize&) {
518 return false;
519 }
520
scroggo1dd3ea92015-03-20 11:55:55 -0700521 virtual SkEncodedFormat onGetEncodedFormat() const = 0;
522
msarette6dd0042015-10-09 11:07:34 -0700523 /**
524 * @param rowsDecoded When the encoded image stream is incomplete, this function
525 * will return kIncompleteInput and rowsDecoded will be set to
526 * the number of scanlines that were successfully decoded.
527 * This will allow getPixels() to fill the uninitialized memory.
528 */
scroggoeb602a52015-07-09 08:16:03 -0700529 virtual Result onGetPixels(const SkImageInfo& info,
530 void* pixels, size_t rowBytes, const Options&,
msarette6dd0042015-10-09 11:07:34 -0700531 SkPMColor ctable[], int* ctableCount,
532 int* rowsDecoded) = 0;
scroggoeb602a52015-07-09 08:16:03 -0700533
msarettb714fb02016-01-22 14:46:42 -0800534 virtual bool onQueryYUV8(YUVSizeInfo*, SkYUVColorSpace*) const {
535 return false;
536 }
537
538 virtual Result onGetYUV8Planes(const YUVSizeInfo&, void*[3] /*planes*/) {
539 return kUnimplemented;
540 }
541
542 virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const {
scroggob636b452015-07-22 07:16:20 -0700543 // By default, subsets are not supported.
544 return false;
545 }
546
msarett90c4d5f2015-12-10 13:09:24 -0800547 /**
scroggof24f2242015-03-03 08:59:20 -0800548 * If the stream was previously read, attempt to rewind.
scroggob427db12015-08-12 07:24:13 -0700549 *
550 * If the stream needed to be rewound, call onRewind.
551 * @returns true if the codec is at the right position and can be used.
552 * false if there was a failure to rewind.
halcanarya096d7a2015-03-27 12:16:53 -0700553 *
scroggo3a7701c2015-09-30 09:15:14 -0700554 * This is called by getPixels() and start(). Subclasses may call if they
555 * need to rewind at another time.
scroggof24f2242015-03-03 08:59:20 -0800556 */
scroggob427db12015-08-12 07:24:13 -0700557 bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
558
559 /**
560 * Called by rewindIfNeeded, if the stream needed to be rewound.
561 *
562 * Subclasses should do any set up needed after a rewind.
563 */
564 virtual bool onRewind() {
565 return true;
566 }
scroggof24f2242015-03-03 08:59:20 -0800567
msarettc0e80c12015-07-01 06:50:35 -0700568 /**
msarette6dd0042015-10-09 11:07:34 -0700569 * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
570 * scanlines. This allows the subclass to indicate what value to fill with.
571 *
572 * @param colorType Destination color type.
msarette6dd0042015-10-09 11:07:34 -0700573 * @return The value with which to fill uninitialized pixels.
574 *
575 * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
576 * an 8-bit gray color, or an 8-bit index into a color table, depending on the color
577 * type.
578 */
scroggoc5560be2016-02-03 09:42:42 -0800579 uint32_t getFillValue(SkColorType colorType) const {
580 return this->onGetFillValue(colorType);
msarette6dd0042015-10-09 11:07:34 -0700581 }
582
583 /**
584 * Some subclasses will override this function, but this is a useful default for the color
585 * types that we support. Note that for color types that do not use the full 32-bits,
586 * we will simply take the low bits of the fill value.
587 *
scroggoc5560be2016-02-03 09:42:42 -0800588 * kN32_SkColorType: Transparent or Black, depending on the src alpha type
msarette6dd0042015-10-09 11:07:34 -0700589 * kRGB_565_SkColorType: Black
590 * kGray_8_SkColorType: Black
591 * kIndex_8_SkColorType: First color in color table
592 */
scroggoc5560be2016-02-03 09:42:42 -0800593 virtual uint32_t onGetFillValue(SkColorType /*colorType*/) const {
594 return kOpaque_SkAlphaType == fSrcInfo.alphaType() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
msarette6dd0042015-10-09 11:07:34 -0700595 }
596
597 /**
msarett74114382015-03-16 11:55:18 -0700598 * Get method for the input stream
msarett74114382015-03-16 11:55:18 -0700599 */
600 SkStream* stream() {
601 return fStream.get();
602 }
603
scroggo46c57472015-09-30 08:57:13 -0700604 /**
605 * The remaining functions revolve around decoding scanlines.
606 */
607
608 /**
609 * Most images types will be kTopDown and will not need to override this function.
610 */
611 virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
612
613 /**
msarettcb0d5c92015-12-03 12:23:43 -0800614 * Update the current scanline. Used by interlaced png.
scroggo46c57472015-09-30 08:57:13 -0700615 */
msarettcb0d5c92015-12-03 12:23:43 -0800616 void updateCurrScanline(int newY) { fCurrScanline = newY; }
scroggo46c57472015-09-30 08:57:13 -0700617
618 const SkImageInfo& dstInfo() const { return fDstInfo; }
619
620 const SkCodec::Options& options() const { return fOptions; }
621
msarettcb0d5c92015-12-03 12:23:43 -0800622 /**
623 * Returns the number of scanlines that have been decoded so far.
624 * This is unaffected by the SkScanlineOrder.
625 *
626 * Returns -1 if we have not started a scanline decode.
627 */
628 int currScanline() const { return fCurrScanline; }
629
msarette6dd0042015-10-09 11:07:34 -0700630 virtual int onOutputScanline(int inputScanline) const;
631
scroggof24f2242015-03-03 08:59:20 -0800632private:
scroggo46c57472015-09-30 08:57:13 -0700633 const SkImageInfo fSrcInfo;
scroggoeb602a52015-07-09 08:16:03 -0700634 SkAutoTDelete<SkStream> fStream;
635 bool fNeedsRewind;
scroggo46c57472015-09-30 08:57:13 -0700636 // These fields are only meaningful during scanline decodes.
637 SkImageInfo fDstInfo;
638 SkCodec::Options fOptions;
639 int fCurrScanline;
640
scroggoe7fc14b2015-10-02 13:14:46 -0700641 /**
642 * Return whether these dimensions are supported as a scale.
643 *
644 * The codec may choose to cache the information about scale and subset.
645 * Either way, the same information will be passed to onGetPixels/onStart
646 * on success.
647 *
648 * This must return true for a size returned from getScaledDimensions.
649 */
650 bool dimensionsSupported(const SkISize& dim) {
651 return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim);
652 }
653
scroggo46c57472015-09-30 08:57:13 -0700654 // Methods for scanline decoding.
msarett33bee092015-11-11 12:43:07 -0800655 virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
656 const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*ctableCount*/) {
scroggo46c57472015-09-30 08:57:13 -0700657 return kUnimplemented;
658 }
659
msarett9b9497e2016-02-11 13:29:36 -0800660 virtual bool onSkipScanlines(int /*countLines*/) { return false; }
scroggo46c57472015-09-30 08:57:13 -0700661
msarett33bee092015-11-11 12:43:07 -0800662 virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
msarette6dd0042015-10-09 11:07:34 -0700663
664 /**
665 * On an incomplete decode, getPixels() and getScanlines() will call this function
666 * to fill any uinitialized memory.
667 *
668 * @param dstInfo Contains the destination color type
669 * Contains the destination alpha type
670 * Contains the destination width
671 * The height stored in this info is unused
672 * @param dst Pointer to the start of destination pixel memory
673 * @param rowBytes Stride length in destination pixel memory
674 * @param zeroInit Indicates if memory is zero initialized
675 * @param linesRequested Number of lines that the client requested
676 * @param linesDecoded Number of lines that were successfully decoded
677 */
678 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
679 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
scroggo46c57472015-09-30 08:57:13 -0700680
scroggoe7fc14b2015-10-02 13:14:46 -0700681 /**
682 * Return an object which will allow forcing scanline decodes to sample in X.
683 *
684 * May create a sampler, if one is not currently being used. Otherwise, does
685 * not affect ownership.
686 *
687 * Only valid during scanline decoding.
688 */
msarett33bee092015-11-11 12:43:07 -0800689 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
scroggoe7fc14b2015-10-02 13:14:46 -0700690
msarett3d9d7a72015-10-21 10:27:10 -0700691 friend class SkSampledCodec;
msarettbe8216a2015-12-04 08:00:50 -0800692 friend class SkIcoCodec;
scroggof24f2242015-03-03 08:59:20 -0800693};
694#endif // SkCodec_DEFINED