mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
LibGfx/JPEG: Expose the Exif metadata
The Exif metadata is contained in the APP1 segment. We only need to call the TIFF decoder to get the metadata back :^).
This commit is contained in:
parent
f6f647bf13
commit
6eb574a2b6
Notes:
sideshowbarker
2024-07-18 04:38:32 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/6eb574a2b6 Pull-request: https://github.com/SerenityOS/serenity/pull/22891 Reviewed-by: https://github.com/ADKaster ✅
2 changed files with 36 additions and 0 deletions
|
@ -18,6 +18,8 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <LibGfx/ImageFormats/JPEGLoader.h>
|
||||
#include <LibGfx/ImageFormats/JPEGShared.h>
|
||||
#include <LibGfx/ImageFormats/TIFFLoader.h>
|
||||
#include <LibGfx/ImageFormats/TIFFMetadata.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
|
@ -466,6 +468,8 @@ struct JPEGLoadingContext {
|
|||
|
||||
Optional<ColorTransform> color_transform {};
|
||||
|
||||
OwnPtr<ExifMetadata> exif_metadata {};
|
||||
|
||||
Optional<ICCMultiChunkState> icc_multi_chunk_state;
|
||||
Optional<ByteBuffer> icc_data;
|
||||
};
|
||||
|
@ -1163,6 +1167,26 @@ static ErrorOr<void> read_colour_encoding(JPEGStream& stream, [[maybe_unused]] J
|
|||
return {};
|
||||
}
|
||||
|
||||
static ErrorOr<void> read_exif(JPEGStream& stream, JPEGLoadingContext& context, int bytes_to_read)
|
||||
{
|
||||
// This refers to Exif's specification, see TIFFLoader for more information.
|
||||
// 4.7.2.2. - APP1 internal structure
|
||||
if (bytes_to_read <= 1) {
|
||||
TRY(stream.discard(bytes_to_read));
|
||||
return {};
|
||||
}
|
||||
|
||||
// Discard padding byte
|
||||
TRY(stream.discard(1));
|
||||
|
||||
auto exif_buffer = TRY(ByteBuffer::create_uninitialized(bytes_to_read - 1));
|
||||
TRY(stream.read_until_filled(exif_buffer));
|
||||
|
||||
context.exif_metadata = TRY(TIFFImageDecoderPlugin::read_exif_metadata(exif_buffer));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
static ErrorOr<void> read_app_marker(JPEGStream& stream, JPEGLoadingContext& context, int app_marker_number)
|
||||
{
|
||||
// B.2.4.6 - Application data syntax
|
||||
|
@ -1187,6 +1211,8 @@ static ErrorOr<void> read_app_marker(JPEGStream& stream, JPEGLoadingContext& con
|
|||
|
||||
auto app_id = TRY(builder.to_string());
|
||||
|
||||
if (app_marker_number == 1 && app_id == "Exif"sv)
|
||||
return read_exif(stream, context, bytes_to_read);
|
||||
if (app_marker_number == 2 && app_id == "ICC_PROFILE"sv)
|
||||
return read_icc_profile(stream, context, bytes_to_read);
|
||||
if (app_marker_number == 14 && app_id == "Adobe"sv)
|
||||
|
@ -2006,6 +2032,13 @@ ErrorOr<ImageFrameDescriptor> JPEGImageDecoderPlugin::frame(size_t index, Option
|
|||
return ImageFrameDescriptor { m_context->bitmap, 0 };
|
||||
}
|
||||
|
||||
Optional<Metadata const&> JPEGImageDecoderPlugin::metadata()
|
||||
{
|
||||
if (m_context->exif_metadata)
|
||||
return *m_context->exif_metadata;
|
||||
return OptionalNone {};
|
||||
}
|
||||
|
||||
ErrorOr<Optional<ReadonlyBytes>> JPEGImageDecoderPlugin::icc_data()
|
||||
{
|
||||
if (m_context->icc_data.has_value())
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
virtual IntSize size() override;
|
||||
|
||||
virtual ErrorOr<ImageFrameDescriptor> frame(size_t index, Optional<IntSize> ideal_size = {}) override;
|
||||
|
||||
virtual Optional<Metadata const&> metadata() override;
|
||||
|
||||
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
|
||||
|
||||
virtual NaturalFrameFormat natural_frame_format() const override;
|
||||
|
|
Loading…
Reference in a new issue