#pragma once
#include "Color.h"
#include "ImageBackingStore.h"
#include "ImageOrientation.h"
#include "IntSize.h"
#include "NativeImage.h"
namespace WebCore {
class Color;
enum class SubsamplingLevel {
Undefinded = -1,
First = 0,
Default = First,
Level0 = First,
Level1,
Level2,
Level3,
Last = Level3,
Max
};
inline SubsamplingLevel& operator++(SubsamplingLevel& subsamplingLevel)
{
subsamplingLevel = static_cast<SubsamplingLevel>(static_cast<int>(subsamplingLevel) + 1);
ASSERT(subsamplingLevel <= SubsamplingLevel::Max);
return subsamplingLevel;
}
typedef int RepetitionCount;
enum {
RepetitionCountNone = 0,
RepetitionCountOnce = 1,
RepetitionCountInfinite = -1,
};
enum class AlphaOption {
Premultiplied,
NotPremultiplied
};
enum class GammaAndColorProfileOption {
Applied,
Ignored
};
enum class DecodingMode {
OnDemand,
Immediate
};
class ImageFrame {
friend class ImageFrameCache;
public:
enum class Caching { Empty, Metadata, MetadataAndImage };
enum class Decoding { Empty, BeingDecoded, Partial, Complete };
ImageFrame();
ImageFrame(const ImageFrame& other) { operator=(other); }
~ImageFrame();
static const ImageFrame& defaultFrame();
ImageFrame& operator=(const ImageFrame& other);
unsigned clearImage();
unsigned clear();
#if !USE(CG)
bool initialize(const ImageBackingStore&);
bool initialize(const IntSize&, bool premultiplyAlpha);
#endif
void setDecoding(Decoding decoding) { m_decoding = decoding; }
Decoding decoding() const { return m_decoding; }
bool isEmpty() const { return m_decoding == Decoding::Empty; }
bool isBeingDecoded() const { return m_decoding == Decoding::BeingDecoded; }
bool isPartial() const { return m_decoding == Decoding::Partial; }
bool isComplete() const { return m_decoding == Decoding::Complete; }
IntSize size() const;
IntSize sizeRespectingOrientation() const { return !m_orientation.usesWidthAsHeight() ? size() : size().transposedSize(); }
unsigned frameBytes() const { return hasNativeImage() ? (size().area() * sizeof(RGBA32)).unsafeGet() : 0; }
SubsamplingLevel subsamplingLevel() const { return m_subsamplingLevel; }
#if !USE(CG)
enum class DisposalMethod { Unspecified, DoNotDispose, RestoreToBackground, RestoreToPrevious };
void setDisposalMethod(DisposalMethod method) { m_disposalMethod = method; }
DisposalMethod disposalMethod() const { return m_disposalMethod; }
#endif
NativeImagePtr nativeImage() const { return m_nativeImage; }
void setOrientation(ImageOrientation orientation) { m_orientation = orientation; };
ImageOrientation orientation() const { return m_orientation; }
void setDuration(float duration) { m_duration = duration; }
float duration() const { return m_duration; }
void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
bool hasAlpha() const { return !hasMetadata() || m_hasAlpha; }
bool hasNativeImage() const { return m_nativeImage; }
bool hasValidNativeImage(SubsamplingLevel subsamplingLevel) const { return hasNativeImage() && subsamplingLevel >= m_subsamplingLevel; }
bool hasMetadata() const { return !size().isEmpty(); }
#if !USE(CG)
ImageBackingStore* backingStore() const { return m_backingStore ? m_backingStore.get() : nullptr; }
bool hasBackingStore() const { return backingStore(); }
#endif
Color singlePixelSolidColor() const;
private:
Decoding m_decoding { Decoding::Empty };
IntSize m_size;
#if !USE(CG)
std::unique_ptr<ImageBackingStore> m_backingStore;
DisposalMethod m_disposalMethod { DisposalMethod::Unspecified };
#endif
NativeImagePtr m_nativeImage;
SubsamplingLevel m_subsamplingLevel { SubsamplingLevel::Default };
ImageOrientation m_orientation { DefaultImageOrientation };
float m_duration { 0 };
bool m_hasAlpha { true };
};
}