Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: include/codec/SkCodec.h

Issue 2045293002: Add support for multiple frames in SkCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Various fixes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkCodec_DEFINED 8 #ifndef SkCodec_DEFINED
9 #define SkCodec_DEFINED 9 #define SkCodec_DEFINED
10 10
11 #include "../private/SkTemplates.h" 11 #include "../private/SkTemplates.h"
12 #include "SkColor.h" 12 #include "SkColor.h"
13 #include "SkEncodedFormat.h" 13 #include "SkEncodedFormat.h"
14 #include "SkEncodedInfo.h" 14 #include "SkEncodedInfo.h"
15 #include "SkImageInfo.h" 15 #include "SkImageInfo.h"
16 #include "SkSize.h" 16 #include "SkSize.h"
17 #include "SkStream.h" 17 #include "SkStream.h"
18 #include "SkTypes.h" 18 #include "SkTypes.h"
19 #include "SkYUVSizeInfo.h" 19 #include "SkYUVSizeInfo.h"
20 20
21 #include <vector>
22
21 class SkColorSpace; 23 class SkColorSpace;
22 class SkData; 24 class SkData;
23 class SkPngChunkReader; 25 class SkPngChunkReader;
24 class SkSampler; 26 class SkSampler;
25 27
26 namespace DM { 28 namespace DM {
27 class CodecSrc; 29 class CodecSrc;
28 class ColorCodecSrc; 30 class ColorCodecSrc;
29 } 31 }
30 class ColorCodecBench; 32 class ColorCodecBench;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 */ 215 */
214 kCouldNotRewind, 216 kCouldNotRewind,
215 /** 217 /**
216 * This method is not implemented by this codec. 218 * This method is not implemented by this codec.
217 * FIXME: Perhaps this should be kUnsupported? 219 * FIXME: Perhaps this should be kUnsupported?
218 */ 220 */
219 kUnimplemented, 221 kUnimplemented,
220 }; 222 };
221 223
222 /** 224 /**
225 * Additional options that only apply to multiframe images.
226 */
227 struct MultiFrameOptions {
228 MultiFrameOptions()
229 : fIndex(0)
230 , fHasPriorFrame(false)
231 {}
232
233 /**
234 * The frame to decode.
235 */
236 size_t fIndex;
237
238 /**
239 * If true, the dst already contains the prior frame.
240 *
241 * If fIndex needs to be blended with a prior frame (as reported by
242 * getFrameInfo[fIndex].fRequiredFrame), the client can set this to
243 * either true or false:
244 *
245 * true means that the prior frame is already in the dst, and this
246 * codec only needs to decode fIndex and blend it with the dst.
247 * Options.fZeroInitialized is ignored in this case.
248 *
249 * false means that the dst does not contain the prior frame, so this
250 * codec needs to first decode the prior frame (which in turn may need
251 * to decode its prior frame).
252 */
253 bool fHasPriorFrame;
254 };
255
256 /**
223 * Whether or not the memory passed to getPixels is zero initialized. 257 * Whether or not the memory passed to getPixels is zero initialized.
224 */ 258 */
225 enum ZeroInitialized { 259 enum ZeroInitialized {
226 /** 260 /**
227 * The memory passed to getPixels is zero initialized. The SkCodec 261 * The memory passed to getPixels is zero initialized. The SkCodec
228 * may take advantage of this by skipping writing zeroes. 262 * may take advantage of this by skipping writing zeroes.
229 */ 263 */
230 kYes_ZeroInitialized, 264 kYes_ZeroInitialized,
231 /** 265 /**
232 * The memory passed to getPixels has not been initialized to zero, 266 * The memory passed to getPixels has not been initialized to zero,
233 * so the SkCodec must write all zeroes to memory. 267 * so the SkCodec must write all zeroes to memory.
234 * 268 *
235 * This is the default. It will be used if no Options struct is used. 269 * This is the default. It will be used if no Options struct is used.
236 */ 270 */
237 kNo_ZeroInitialized, 271 kNo_ZeroInitialized,
238 }; 272 };
239 273
240 /** 274 /**
241 * Additional options to pass to getPixels. 275 * Additional options to pass to getPixels.
242 */ 276 */
243 struct Options { 277 struct Options {
244 Options() 278 Options()
245 : fZeroInitialized(kNo_ZeroInitialized) 279 : fZeroInitialized(kNo_ZeroInitialized)
246 , fSubset(NULL) 280 , fSubset(nullptr)
281 , fFrameOptions(nullptr)
247 {} 282 {}
248 283
249 ZeroInitialized fZeroInitialized; 284 ZeroInitialized fZeroInitialized;
250 /** 285 /**
251 * If not NULL, represents a subset of the original image to decode. 286 * If not NULL, represents a subset of the original image to decode.
252 * Must be within the bounds returned by getInfo(). 287 * Must be within the bounds returned by getInfo().
253 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which 288 * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
254 * currently supports subsets), the top and left values must be even. 289 * currently supports subsets), the top and left values must be even.
255 * 290 *
256 * In getPixels and incremental decode, we will attempt to decode the 291 * In getPixels and incremental decode, we will attempt to decode the
257 * exact rectangular subset specified by fSubset. 292 * exact rectangular subset specified by fSubset.
258 * 293 *
259 * In a scanline decode, it does not make sense to specify a subset 294 * In a scanline decode, it does not make sense to specify a subset
260 * top or subset height, since the client already controls which rows 295 * top or subset height, since the client already controls which rows
261 * to get and which rows to skip. During scanline decodes, we will 296 * to get and which rows to skip. During scanline decodes, we will
262 * require that the subset top be zero and the subset height be equal 297 * require that the subset top be zero and the subset height be equal
263 * to the full height. We will, however, use the values of 298 * to the full height. We will, however, use the values of
264 * subset left and subset width to decode partial scanlines on calls 299 * subset left and subset width to decode partial scanlines on calls
265 * to getScanlines(). 300 * to getScanlines().
266 */ 301 */
267 SkIRect* fSubset; 302 const SkIRect* fSubset;
303
304 /**
305 * Options that are only relevant for multi-frame images.
306 *
307 * Unowned pointer.
308 */
309 const MultiFrameOptions* fFrameOptions;
268 }; 310 };
269 311
270 /** 312 /**
271 * Decode into the given pixels, a block of memory of size at 313 * Decode into the given pixels, a block of memory of size at
272 * least (info.fHeight - 1) * rowBytes + (info.fWidth * 314 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
273 * bytesPerPixel) 315 * bytesPerPixel)
274 * 316 *
275 * Repeated calls to this function should give the same results, 317 * Repeated calls to this function should give the same results,
276 * allowing the PixelRef to be immutable. 318 * allowing the PixelRef to be immutable.
277 * 319 *
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 * For subset decodes and sampling, it is simplest to get and skip 557 * For subset decodes and sampling, it is simplest to get and skip
516 * scanlines one at a time, using the nextScanline() API. It is 558 * scanlines one at a time, using the nextScanline() API. It is
517 * possible to ask for larger chunks at a time, but this should be used 559 * possible to ask for larger chunks at a time, but this should be used
518 * with caution. As with full image decodes, the decoder will handle 560 * with caution. As with full image decodes, the decoder will handle
519 * inverting the requested rows, but rows will still be delivered 561 * inverting the requested rows, but rows will still be delivered
520 * starting from the bottom of the image. 562 * starting from the bottom of the image.
521 * 563 *
522 * Upside down bmps are an example. 564 * Upside down bmps are an example.
523 */ 565 */
524 kBottomUp_SkScanlineOrder, 566 kBottomUp_SkScanlineOrder,
525
526 /*
527 * This indicates that the scanline decoder reliably outputs rows, but
528 * they will not be in logical order. If the scanline format is
529 * kOutOfOrder, the nextScanline() API should be used to determine the
530 * actual y-coordinate of the next output row.
531 *
532 * For this scanline ordering, it is advisable to get and skip
533 * scanlines one at a time.
534 *
535 * Interlaced gifs are an example.
536 */
537 kOutOfOrder_SkScanlineOrder,
538 }; 567 };
539 568
540 /** 569 /**
541 * An enum representing the order in which scanlines will be returned by 570 * An enum representing the order in which scanlines will be returned by
542 * the scanline decoder. 571 * the scanline decoder.
543 * 572 *
544 * This is undefined before startScanlineDecode() is called. 573 * This is undefined before startScanlineDecode() is called.
545 */ 574 */
546 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; } 575 SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder() ; }
547 576
548 /** 577 /**
549 * Returns the y-coordinate of the next row to be returned by the scanline 578 * Returns the y-coordinate of the next row to be returned by the scanline
550 * decoder. 579 * decoder.
551 * 580 *
552 * This will equal fCurrScanline, except in the case of strangely 581 * This will equal fCurrScanline, except in the case of strangely
553 * encoded image types (bottom-up bmps, interlaced gifs). 582 * encoded image types (bottom-up bmps).
554 * 583 *
555 * Results are undefined when not in scanline decoding mode. 584 * Results are undefined when not in scanline decoding mode.
556 */ 585 */
557 int nextScanline() const { return this->outputScanline(fCurrScanline); } 586 int nextScanline() const { return this->outputScanline(fCurrScanline); }
558 587
559 /** 588 /**
560 * Returns the output y-coordinate of the row that corresponds to an input 589 * Returns the output y-coordinate of the row that corresponds to an input
561 * y-coordinate. The input y-coordinate represents where the scanline 590 * y-coordinate. The input y-coordinate represents where the scanline
562 * is located in the encoded data. 591 * is located in the encoded data.
563 * 592 *
564 * This will equal inputScanline, except in the case of strangely 593 * This will equal inputScanline, except in the case of strangely
565 * encoded image types (bottom-up bmps, interlaced gifs). 594 * encoded image types (bottom-up bmps, interlaced gifs).
566 */ 595 */
567 int outputScanline(int inputScanline) const; 596 int outputScanline(int inputScanline) const;
568 597
598 // The required frame for an independent frame is marked as
599 // kIndependentFrame.
600 static constexpr size_t kIndependentFrame = static_cast<size_t>(-1);
601
602 /**
603 * Information about individual frames in a multi-framed image.
604 */
605 struct FrameInfo {
606 /**
607 * The frame that this frame needs to be blended with, or
608 * kIndependentFrame.
609 */
610 size_t fRequiredFrame;
611
612 /**
613 * Number of milliseconds to show this frame.
614 */
615 size_t fDuration;
616 };
617
618 /**
619 * Return info about the frames in the image.
620 *
621 * May require reading through the stream to determine the number of
622 * frames.
623 *
624 * As such, future decoding calls may require a rewind.
625 *
626 * For single-frame images, this will return an empty vector.
627 */
628 std::vector<FrameInfo> getFrameInfo() {
629 return this->onGetFrameInfo();
630 }
631
569 protected: 632 protected:
570 /** 633 /**
571 * Takes ownership of SkStream* 634 * Takes ownership of SkStream*
572 */ 635 */
573 SkCodec(int width, 636 SkCodec(int width,
574 int height, 637 int height,
575 const SkEncodedInfo&, 638 const SkEncodedInfo&,
576 SkStream*, 639 SkStream*,
577 sk_sp<SkColorSpace> = nullptr, 640 sk_sp<SkColorSpace> = nullptr,
578 Origin = kTopLeft_Origin); 641 Origin = kTopLeft_Origin);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 /** 762 /**
700 * Returns the number of scanlines that have been decoded so far. 763 * Returns the number of scanlines that have been decoded so far.
701 * This is unaffected by the SkScanlineOrder. 764 * This is unaffected by the SkScanlineOrder.
702 * 765 *
703 * Returns -1 if we have not started a scanline decode. 766 * Returns -1 if we have not started a scanline decode.
704 */ 767 */
705 int currScanline() const { return fCurrScanline; } 768 int currScanline() const { return fCurrScanline; }
706 769
707 virtual int onOutputScanline(int inputScanline) const; 770 virtual int onOutputScanline(int inputScanline) const;
708 771
772 virtual std::vector<FrameInfo> onGetFrameInfo() {
773 // empty vector - this is not animated.
774 return {};
775 }
776
709 /** 777 /**
710 * Used for testing with qcms. 778 * Used for testing with qcms.
711 * FIXME: Remove this when we are done comparing with qcms. 779 * FIXME: Remove this when we are done comparing with qcms.
712 */ 780 */
713 virtual sk_sp<SkData> getICCData() const { return nullptr; } 781 virtual sk_sp<SkData> getICCData() const { return nullptr; }
714 private: 782 private:
715 const SkEncodedInfo fEncodedInfo; 783 const SkEncodedInfo fEncodedInfo;
716 const SkImageInfo fSrcInfo; 784 const SkImageInfo fSrcInfo;
717 SkAutoTDelete<SkStream> fStream; 785 SkAutoTDelete<SkStream> fStream;
718 bool fNeedsRewind; 786 bool fNeedsRewind;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 */ 843 */
776 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBy tes, 844 void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBy tes,
777 ZeroInitialized zeroInit, int linesRequested, int linesDecoded); 845 ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
778 846
779 /** 847 /**
780 * Return an object which will allow forcing scanline decodes to sample in X. 848 * Return an object which will allow forcing scanline decodes to sample in X.
781 * 849 *
782 * May create a sampler, if one is not currently being used. Otherwise, doe s 850 * May create a sampler, if one is not currently being used. Otherwise, doe s
783 * not affect ownership. 851 * not affect ownership.
784 * 852 *
785 * Only valid during scanline decoding. 853 * Only valid during scanline decoding or incremental decoding.
786 */ 854 */
787 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; } 855 virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
788 856
789 // For testing with qcms 857 // For testing with qcms
790 // FIXME: Remove these when we are done comparing with qcms. 858 // FIXME: Remove these when we are done comparing with qcms.
791 friend class DM::ColorCodecSrc; 859 friend class DM::ColorCodecSrc;
792 friend class ColorCodecBench; 860 friend class ColorCodecBench;
793 861
794 friend class DM::CodecSrc; // for fillIncompleteImage 862 friend class DM::CodecSrc; // for fillIncompleteImage
795 friend class SkSampledCodec; 863 friend class SkSampledCodec;
796 friend class SkIcoCodec; 864 friend class SkIcoCodec;
797 }; 865 };
798 #endif // SkCodec_DEFINED 866 #endif // SkCodec_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698