From 33deb7ed4d583c88187ba240efb749e9a1fd6843 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Wed, 7 Jun 2017 12:31:51 -0400 Subject: Make SkCodec more flexible about its required frame SkCodec sets fRequiredFrame to be the earliest possible frame that a given frame can depend on. e.g. - Frame A fills the screen, Keep - Frame B does not cover A, Keep - Frame C covers B but not A, and is opaque Frame C can depend on either A or B. SkCodec already reports that C depends on A. This CL allows a client of SkCodec to use either A or B to create C. Also expose the DisposalMethod. Since any frame between A and C can be used to create C except for DisposePrevious frames, the client needs to be able to know the disposal method so they do not try to use such a frame to create C. Further, the disposal method can be used to give the client a better idea whether they will continue to need a frame. (e.g. if frame i is DisposePrevious and depends on i-1, the client may not want to steal i-1 to create i, since i+1 may also depend on i-1.) TODO: Share code for decoding prior frames between GIF and WEBP Change-Id: I91a5ae22ba3d8dfbe0bde833fa67ae3da0d81ed6 Reviewed-on: https://skia-review.googlesource.com/13722 Reviewed-by: Mike Reed Reviewed-by: Chris Blume Reviewed-by: Matt Sarett Commit-Queue: Leon Scroggins --- include/codec/SkCodec.h | 30 +++++++++++++++++----------- include/codec/SkCodecAnimation.h | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 include/codec/SkCodecAnimation.h (limited to 'include/codec') diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h index d498007486..640ff468c5 100644 --- a/include/codec/SkCodec.h +++ b/include/codec/SkCodec.h @@ -9,6 +9,7 @@ #define SkCodec_DEFINED #include "../private/SkTemplates.h" +#include "SkCodecAnimation.h" #include "SkColor.h" #include "SkColorSpaceXform.h" #include "SkEncodedImageFormat.h" @@ -249,7 +250,7 @@ public: : fZeroInitialized(kNo_ZeroInitialized) , fSubset(nullptr) , fFrameIndex(0) - , fHasPriorFrame(false) + , fPriorFrame(kNone) , fPremulBehavior(SkTransferFunctionBehavior::kRespect) {} @@ -281,23 +282,19 @@ public: int fFrameIndex; /** - * If true, the dst already contains the prior frame. + * If not kNone, the dst already contains the prior frame at this index. * * Only meaningful for multi-frame images. * * If fFrameIndex needs to be blended with a prior frame (as reported by * getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to - * either true or false: + * any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to + * indicate that that frame is already in the dst. Options.fZeroInitialized + * is ignored in this case. * - * true means that the prior frame is already in the dst, and this - * codec only needs to decode fFrameIndex and blend it with the dst. - * Options.fZeroInitialized is ignored in this case. - * - * false means that the dst does not contain the prior frame, so this - * codec needs to first decode the prior frame (which in turn may need - * to decode its prior frame). + * If set to kNone, the codec will decode any necessary required frame(s) first. */ - bool fHasPriorFrame; + int fPriorFrame; /** * Indicates whether we should do a linear premultiply or a legacy premultiply. @@ -613,7 +610,11 @@ public: struct FrameInfo { /** * The frame that this frame needs to be blended with, or - * kNone. + * kNone if this frame is independent. + * + * Note that this is the *earliest* frame that can be used + * for blending. Any frame from [fRequiredFrame, i) can be + * used, unless its fDisposalMethod is kRestorePrevious. */ int fRequiredFrame; @@ -635,6 +636,11 @@ public: * color index-based frame has a color with alpha but does not use it. */ SkAlphaType fAlphaType; + + /** + * How this frame should be modified before decoding the next one. + */ + SkCodecAnimation::DisposalMethod fDisposalMethod; }; /** diff --git a/include/codec/SkCodecAnimation.h b/include/codec/SkCodecAnimation.h new file mode 100644 index 0000000000..9a4daff8ae --- /dev/null +++ b/include/codec/SkCodecAnimation.h @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkCodecAnimation_DEFINED +#define SkCodecAnimation_DEFINED + +namespace SkCodecAnimation { + /** + * This specifies how the next frame is based on this frame. + * + * Names are based on the GIF 89a spec. + * + * The numbers correspond to values in a GIF. + */ + enum class DisposalMethod { + /** + * The next frame should be drawn on top of this one. + * + * In a GIF, a value of 0 (not specified) is also treated as Keep. + */ + kKeep = 1, + + /** + * Similar to Keep, except the area inside this frame's rectangle + * should be cleared to the BackGround color (transparent) before + * drawing the next frame. + */ + kRestoreBGColor = 2, + + /** + * The next frame should be drawn on top of the previous frame - i.e. + * disregarding this one. + * + * In a GIF, a value of 4 is also treated as RestorePrevious. + */ + kRestorePrevious = 3, + }; +}; +#endif // SkCodecAnimation_DEFINED -- cgit v1.2.3