/* * Copyright (c) 2018-2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include #include #include #include namespace Gfx { static ErrorOr> probe_and_sniff_for_appropriate_plugin(ReadonlyBytes bytes) { struct ImagePluginInitializer { bool (*sniff)(ReadonlyBytes) = nullptr; ErrorOr> (*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 {}; } ErrorOr ImageDecoder::color_space() { auto maybe_cicp = TRY(m_plugin->cicp()); if (maybe_cicp.has_value()) return ColorSpace::from_cicp(*maybe_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> ImageDecoder::try_create_for_raw_bytes(ReadonlyBytes bytes, [[maybe_unused]] Optional 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(NonnullOwnPtr plugin) : m_plugin(move(plugin)) { } }