From 4ab2903e2507ae48a9cafb61f1ac722f167ab61e Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Sun, 12 Nov 2023 18:34:37 -0500 Subject: [PATCH] LibGfx/TIFF: Make `TIFFLoadingContext::handle_tag` be a free function And move it to another file. This code is going to be generated soon, so let's put it in another file. --- Userland/Libraries/LibGfx/CMakeLists.txt | 1 + .../LibGfx/ImageFormats/TIFFLoader.cpp | 154 +--------------- .../LibGfx/ImageFormats/TIFFMetadata.h | 4 + .../LibGfx/ImageFormats/TIFFTagHandler.cpp | 165 ++++++++++++++++++ 4 files changed, 171 insertions(+), 153 deletions(-) create mode 100644 Userland/Libraries/LibGfx/ImageFormats/TIFFTagHandler.cpp diff --git a/Userland/Libraries/LibGfx/CMakeLists.txt b/Userland/Libraries/LibGfx/CMakeLists.txt index 19ec43bea3..7e2ca487c4 100644 --- a/Userland/Libraries/LibGfx/CMakeLists.txt +++ b/Userland/Libraries/LibGfx/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCES ImageFormats/BMPWriter.cpp ImageFormats/BooleanDecoder.cpp ImageFormats/TIFFLoader.cpp + ImageFormats/TIFFTagHandler.cpp ImageFormats/DDSLoader.cpp ImageFormats/GIFLoader.cpp ImageFormats/ICOLoader.cpp diff --git a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp index 4bc57c553e..408a96b3f1 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp @@ -416,159 +416,7 @@ private: } } - TRY(handle_tag(tag, type, count, tiff_value)); - - return {}; - } - - ErrorOr handle_tag(u16 tag, Type type, u32 count, Vector const& value) - { - // FIXME: Make that easy to extend - switch (tag) { - case 256: - // ImageWidth - if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 256"); - - value[0].visit( - [this] T>(T const& width) { - m_metadata.size.set_width(width); - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - break; - - case 257: - // ImageLength - if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 257"); - - value[0].visit( - [this] T>(T const& width) { - m_metadata.size.set_height(width); - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - break; - - case 258: - // BitsPerSample - if (type != Type::UnsignedShort || count != 3) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 258"); - - for (u8 i = 0; i < m_metadata.bits_per_sample.size(); ++i) { - value[i].visit( - [this, i](u16 const& bits_per_sample) { - m_metadata.bits_per_sample[i] = bits_per_sample; - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - } - break; - - case 259: - // Compression - if (type != Type::UnsignedShort || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 259"); - - TRY(value[0].visit( - [this](u16 const& compression) -> ErrorOr { - if (compression > 6 && compression != to_underlying(Compression::PackBits)) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid compression value"); - - m_metadata.compression = static_cast(compression); - return {}; - }, - [&](auto const&) -> ErrorOr { - VERIFY_NOT_REACHED(); - })); - break; - - case 273: - // StripOffsets - if (type != Type::UnsignedShort && type != Type::UnsignedLong) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 273"); - - TRY(m_metadata.strip_offsets.try_ensure_capacity(count)); - for (u32 i = 0; i < count; ++i) { - value[i].visit( - [this] T>(T const& offset) { - m_metadata.strip_offsets.append(offset); - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - } - break; - - case 277: - // SamplesPerPixel - if (type != Type::UnsignedShort || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 277"); - TRY(value[0].visit( - [](u16 const& samples_per_pixels) -> ErrorOr { - if (samples_per_pixels != 3) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 277"); - return {}; - }, - [&](auto const&) -> ErrorOr { - VERIFY_NOT_REACHED(); - })); - break; - - case 278: - // RowsPerStrip - if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 278"); - - value[0].visit( - [this] T>(T const& rows_per_strip) { - m_metadata.rows_per_strip = rows_per_strip; - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - break; - - case 279: - // StripByteCounts - if (type != Type::UnsignedShort && type != Type::UnsignedLong) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 279"); - - TRY(m_metadata.strip_bytes_count.try_ensure_capacity(count)); - for (u32 i = 0; i < count; ++i) { - value[i].visit( - [this] T>(T const& offset) { - m_metadata.strip_bytes_count.append(offset); - }, - [&](auto const&) { - VERIFY_NOT_REACHED(); - }); - } - break; - case 317: - // Predictor - if (type != Type::UnsignedShort || count != 1) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 317"); - - TRY(value[0].visit( - [this](u16 const& predictor) -> ErrorOr { - if (predictor != 1 && predictor != 2) - return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid predictor value"); - - m_metadata.predictor = static_cast(predictor); - return {}; - }, - [&](auto const&) -> ErrorOr { - VERIFY_NOT_REACHED(); - })); - break; - default: - dbgln_if(TIFF_DEBUG, "Unknown tag: {}", tag); - } + TRY(handle_tag(m_metadata, tag, type, count, tiff_value)); return {}; } diff --git a/Userland/Libraries/LibGfx/ImageFormats/TIFFMetadata.h b/Userland/Libraries/LibGfx/ImageFormats/TIFFMetadata.h index f98fb620d7..f351237785 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TIFFMetadata.h +++ b/Userland/Libraries/LibGfx/ImageFormats/TIFFMetadata.h @@ -12,6 +12,8 @@ namespace Gfx { +struct Metadata; + namespace TIFF { enum class Type { @@ -54,6 +56,8 @@ enum class Predictor { HorizontalDifferencing = 2, }; +ErrorOr handle_tag(Metadata& metadata, u16 tag, Type type, u32 count, Vector const& value); + } struct Metadata { diff --git a/Userland/Libraries/LibGfx/ImageFormats/TIFFTagHandler.cpp b/Userland/Libraries/LibGfx/ImageFormats/TIFFTagHandler.cpp new file mode 100644 index 0000000000..7dc5a2b750 --- /dev/null +++ b/Userland/Libraries/LibGfx/ImageFormats/TIFFTagHandler.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2023, Lucas Chollet + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Gfx::TIFF { + +ErrorOr handle_tag(Metadata& metadata, u16 tag, Type type, u32 count, Vector const& value) +{ + // FIXME: Make that easy to extend + switch (tag) { + case 256: + // ImageWidth + if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 256"); + + value[0].visit( + [&metadata] T>(T const& width) { + metadata.size.set_width(width); + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + break; + + case 257: + // ImageLength + if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 257"); + + value[0].visit( + [&metadata] T>(T const& width) { + metadata.size.set_height(width); + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + break; + + case 258: + // BitsPerSample + if (type != Type::UnsignedShort || count != 3) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 258"); + + for (u8 i = 0; i < metadata.bits_per_sample.size(); ++i) { + value[i].visit( + [&metadata, i](u16 const& bits_per_sample) { + metadata.bits_per_sample[i] = bits_per_sample; + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + } + break; + + case 259: + // Compression + if (type != Type::UnsignedShort || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 259"); + + TRY(value[0].visit( + [&metadata](u16 const& compression) -> ErrorOr { + if (compression > 6 && compression != to_underlying(Compression::PackBits)) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid compression value"); + + metadata.compression = static_cast(compression); + return {}; + }, + [&](auto const&) -> ErrorOr { + VERIFY_NOT_REACHED(); + })); + break; + + case 273: + // StripOffsets + if (type != Type::UnsignedShort && type != Type::UnsignedLong) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 273"); + + TRY(metadata.strip_offsets.try_ensure_capacity(count)); + for (u32 i = 0; i < count; ++i) { + value[i].visit( + [&metadata] T>(T const& offset) { + metadata.strip_offsets.append(offset); + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + } + break; + + case 277: + // SamplesPerPixel + if (type != Type::UnsignedShort || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 277"); + TRY(value[0].visit( + [](u16 const& samples_per_pixels) -> ErrorOr { + if (samples_per_pixels != 3) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 277"); + return {}; + }, + [&](auto const&) -> ErrorOr { + VERIFY_NOT_REACHED(); + })); + break; + + case 278: + // RowsPerStrip + if ((type != Type::UnsignedShort && type != Type::UnsignedLong) || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 278"); + + value[0].visit( + [&metadata] T>(T const& rows_per_strip) { + metadata.rows_per_strip = rows_per_strip; + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + break; + + case 279: + // StripByteCounts + if (type != Type::UnsignedShort && type != Type::UnsignedLong) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 279"); + + TRY(metadata.strip_bytes_count.try_ensure_capacity(count)); + for (u32 i = 0; i < count; ++i) { + value[i].visit( + [&metadata] T>(T const& offset) { + metadata.strip_bytes_count.append(offset); + }, + [&](auto const&) { + VERIFY_NOT_REACHED(); + }); + } + break; + case 317: + // Predictor + if (type != Type::UnsignedShort || count != 1) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag 317"); + + TRY(value[0].visit( + [&metadata](u16 const& predictor) -> ErrorOr { + if (predictor != 1 && predictor != 2) + return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid predictor value"); + + metadata.predictor = static_cast(predictor); + return {}; + }, + [&](auto const&) -> ErrorOr { + VERIFY_NOT_REACHED(); + })); + break; + default: + dbgln_if(TIFF_DEBUG, "Unknown tag: {}", tag); + } + + return {}; +} + +}