#pragma once
#include "IntSize.h"
#include <wtf/EnumTraits.h>
#include <wtf/Optional.h>
#include <wtf/Variant.h>
namespace WebCore {
enum class DecodingMode : uint8_t {
Auto,
Synchronous,
Asynchronous
};
class DecodingOptions {
public:
explicit DecodingOptions(DecodingMode decodingMode = DecodingMode::Auto)
: m_decodingModeOrSize(decodingMode)
{
}
DecodingOptions(const Optional<IntSize>& sizeForDrawing)
: m_decodingModeOrSize(sizeForDrawing)
{
}
bool operator==(const DecodingOptions& other) const
{
return m_decodingModeOrSize == other.m_decodingModeOrSize;
}
bool isAuto() const
{
return hasDecodingMode() && WTF::get<DecodingMode>(m_decodingModeOrSize) == DecodingMode::Auto;
}
bool isSynchronous() const
{
return hasDecodingMode() && WTF::get<DecodingMode>(m_decodingModeOrSize) == DecodingMode::Synchronous;
}
bool isAsynchronous() const
{
return hasDecodingMode() && WTF::get<DecodingMode>(m_decodingModeOrSize) == DecodingMode::Asynchronous;
}
bool isAsynchronousCompatibleWith(const DecodingOptions& decodingOptions) const
{
if (isAuto() || decodingOptions.isAuto())
return false;
ASSERT(!isAsynchronous());
if (isAsynchronous() || decodingOptions.isSynchronous())
return false;
if (isSynchronous() || decodingOptions.isAsynchronous())
return true;
ASSERT(decodingOptions.hasSize());
if (decodingOptions.hasFullSize())
return hasFullSize();
ASSERT(decodingOptions.hasSizeForDrawing());
if (hasFullSize())
return true;
ASSERT(hasSizeForDrawing());
return maxDimension(*sizeForDrawing()) >= maxDimension(*decodingOptions.sizeForDrawing());
}
bool hasFullSize() const
{
return hasSize() && !sizeForDrawing();
}
bool hasSizeForDrawing() const
{
return hasSize() && sizeForDrawing();
}
Optional<IntSize> sizeForDrawing() const
{
ASSERT(hasSize());
return WTF::get<Optional<IntSize>>(m_decodingModeOrSize);
}
static int maxDimension(const IntSize& size)
{
return std::max(size.width(), size.height());
}
private:
template<typename T>
bool has() const
{
return WTF::holds_alternative<T>(m_decodingModeOrSize);
}
bool hasDecodingMode() const
{
return has<DecodingMode>();
}
bool hasSize() const
{
return has<Optional<IntSize>>();
}
using DecodingModeOrSize = Variant<DecodingMode, Optional<IntSize>>;
DecodingModeOrSize m_decodingModeOrSize;
};
}
namespace WTF {
template<> struct EnumTraits<WebCore::DecodingMode> {
using values = EnumValues<
WebCore::DecodingMode,
WebCore::DecodingMode::Auto,
WebCore::DecodingMode::Synchronous,
WebCore::DecodingMode::Asynchronous
>;
};
}