mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
ImageDecoder itself can check the matrix coefficients and range flag instead. In the future, ImageDecoder should probably convert its images into RGB color space using the same solution as for video.
85 lines
3.1 KiB
C++
85 lines
3.1 KiB
C++
/*
|
|
* Copyright (c) 2018-2021, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibGfx/ImageFormats/AVIFLoader.h>
|
|
#include <LibGfx/ImageFormats/BMPLoader.h>
|
|
#include <LibGfx/ImageFormats/GIFLoader.h>
|
|
#include <LibGfx/ImageFormats/ICOLoader.h>
|
|
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
|
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
|
#include <LibGfx/ImageFormats/JPEGXLLoader.h>
|
|
#include <LibGfx/ImageFormats/PNGLoader.h>
|
|
#include <LibGfx/ImageFormats/TIFFLoader.h>
|
|
#include <LibGfx/ImageFormats/TinyVGLoader.h>
|
|
#include <LibGfx/ImageFormats/WebPLoader.h>
|
|
|
|
namespace Gfx {
|
|
|
|
static ErrorOr<OwnPtr<ImageDecoderPlugin>> probe_and_sniff_for_appropriate_plugin(ReadonlyBytes bytes)
|
|
{
|
|
struct ImagePluginInitializer {
|
|
bool (*sniff)(ReadonlyBytes) = nullptr;
|
|
ErrorOr<NonnullOwnPtr<ImageDecoderPlugin>> (*create)(ReadonlyBytes) = nullptr;
|
|
};
|
|
|
|
static constexpr ImagePluginInitializer s_initializers[] = {
|
|
{ BMPImageDecoderPlugin::sniff, BMPImageDecoderPlugin::create },
|
|
{ GIFImageDecoderPlugin::sniff, GIFImageDecoderPlugin::create },
|
|
{ ICOImageDecoderPlugin::sniff, ICOImageDecoderPlugin::create },
|
|
{ JPEGImageDecoderPlugin::sniff, JPEGImageDecoderPlugin::create },
|
|
{ JPEGXLImageDecoderPlugin::sniff, JPEGXLImageDecoderPlugin::create },
|
|
{ PNGImageDecoderPlugin::sniff, PNGImageDecoderPlugin::create },
|
|
{ TIFFImageDecoderPlugin::sniff, TIFFImageDecoderPlugin::create },
|
|
{ TinyVGImageDecoderPlugin::sniff, TinyVGImageDecoderPlugin::create },
|
|
{ WebPImageDecoderPlugin::sniff, WebPImageDecoderPlugin::create },
|
|
{ AVIFImageDecoderPlugin::sniff, AVIFImageDecoderPlugin::create }
|
|
};
|
|
|
|
for (auto& plugin : s_initializers) {
|
|
auto sniff_result = plugin.sniff(bytes);
|
|
if (!sniff_result)
|
|
continue;
|
|
return TRY(plugin.create(bytes));
|
|
}
|
|
return OwnPtr<ImageDecoderPlugin> {};
|
|
}
|
|
|
|
ErrorOr<ColorSpace> ImageDecoder::color_space()
|
|
{
|
|
auto maybe_cicp = TRY(m_plugin->cicp());
|
|
if (maybe_cicp.has_value()) {
|
|
auto cicp = maybe_cicp.release_value();
|
|
|
|
if (cicp.matrix_coefficients() != Media::MatrixCoefficients::Identity)
|
|
return Error::from_string_literal("Unsupported matrix coefficients for CICP");
|
|
|
|
if (cicp.video_full_range_flag() != Media::VideoFullRangeFlag::Full)
|
|
return Error::from_string_literal("Studio range is not supported");
|
|
|
|
return ColorSpace::from_cicp(cicp);
|
|
}
|
|
|
|
auto maybe_icc_data = TRY(icc_data());
|
|
if (!maybe_icc_data.has_value())
|
|
return ColorSpace {};
|
|
return ColorSpace::load_from_icc_bytes(maybe_icc_data.value());
|
|
}
|
|
|
|
ErrorOr<RefPtr<ImageDecoder>> ImageDecoder::try_create_for_raw_bytes(ReadonlyBytes bytes, [[maybe_unused]] Optional<ByteString> mime_type)
|
|
{
|
|
if (auto plugin = TRY(probe_and_sniff_for_appropriate_plugin(bytes)); plugin)
|
|
return adopt_ref_if_nonnull(new (nothrow) ImageDecoder(plugin.release_nonnull()));
|
|
|
|
return RefPtr<ImageDecoder> {};
|
|
}
|
|
|
|
ImageDecoder::ImageDecoder(NonnullOwnPtr<ImageDecoderPlugin> plugin)
|
|
: m_plugin(move(plugin))
|
|
{
|
|
}
|
|
|
|
}
|