Skip to content

Commit

Permalink
LibGfx/TIFF: Explore underlying Image File Directories
Browse files Browse the repository at this point in the history
Every TIFF containers is composed of a main IFD. Some entries of this
one can be a pointer to a sub-IFD. We are now capable of exploring these
underlying structures. Note that we don't do anything with them yet.
  • Loading branch information
LucasChollet authored and ADKaster committed Feb 8, 2024
1 parent 4a7236c commit a43793e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
11 changes: 9 additions & 2 deletions Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,6 @@ class TIFFLoadingContext {
m_next_ifd = Optional<u32> { next_block_position };
else
m_next_ifd = OptionalNone {};
dbgln_if(TIFF_DEBUG, "Setting image file directory pointer to {}", m_next_ifd);
return {};
}

Expand Down Expand Up @@ -491,6 +490,8 @@ class TIFFLoadingContext {
if (!m_next_ifd.has_value())
return Error::from_string_literal("TIFFImageDecoderPlugin: Missing an Image File Directory");

dbgln_if(TIFF_DEBUG, "Reading image file directory at offset {}", m_next_ifd);

TRY(m_stream->seek(m_next_ifd.value()));

auto const number_of_field = TRY(read_value<u16>());
Expand Down Expand Up @@ -597,7 +598,13 @@ class TIFFLoadingContext {
return read_tiff_value(type, count, offset);
}()));

TRY(handle_tag(m_metadata, tag, type, count, move(tiff_value)));
auto subifd_handler = [&](u32 ifd_offset) -> ErrorOr<void> {
m_next_ifd = ifd_offset;
TRY(read_next_image_file_directory());
return {};
};

TRY(handle_tag(move(subifd_handler), m_metadata, tag, type, count, move(tiff_value)));

return {};
}
Expand Down
12 changes: 10 additions & 2 deletions Userland/Libraries/LibGfx/TIFFGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ class ExtraSample(EnumWithExportName):
Tag('34675', [TIFFType.Undefined], [], None, "ICCProfile"),
]

HANDLE_TAG_SIGNATURE_TEMPLATE = ("ErrorOr<void> {namespace}handle_tag(ExifMetadata& metadata, u16 tag,"
" {namespace}Type type, u32 count, Vector<{namespace}Value>&& value)")
HANDLE_TAG_SIGNATURE_TEMPLATE = ("ErrorOr<void> {namespace}handle_tag(Function<ErrorOr<void>(u32)>&& subifd_handler, "
"ExifMetadata& metadata, u16 tag, {namespace}Type type, u32 count, "
"Vector<{namespace}Value>&& value)")
HANDLE_TAG_SIGNATURE = HANDLE_TAG_SIGNATURE_TEMPLATE.format(namespace="")
HANDLE_TAG_SIGNATURE_TIFF_NAMESPACE = HANDLE_TAG_SIGNATURE_TEMPLATE.format(namespace="TIFF::")

Expand Down Expand Up @@ -478,13 +479,20 @@ def generate_tag_handler(tag: Tag) -> str:
}}
"""

handle_subifd = ''
if TIFFType.IFD in tag.types:
if tag.counts != [1]:
raise RuntimeError("Accessing `value[0]` in the C++ code might fail!")
handle_subifd = f'TRY(subifd_handler(value[0].get<{tiff_type_to_cpp(TIFFType.IFD)}>()));'

output = fR""" case {tag.id}:
// {tag.name}
dbgln_if(TIFF_DEBUG, "{tag.name}({{}}): {{}}", name_for_enum_tag_value(type), format_tiff_value(tag, value));
{pre_condition}
{check_value}
{handle_subifd}
metadata.add_entry("{tag.name}"sv, move(value));
break;
"""
Expand Down

0 comments on commit a43793e

Please sign in to comment.