mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 12:35:14 +00:00
LibGfx/ILBMLoader: Add support for PC DeluxePaint files
This commit is contained in:
parent
b108d51c5b
commit
cd6c7f3fc4
Notes:
sideshowbarker
2024-07-16 17:05:37 +09:00
Author: https://github.com/warpdesign Commit: https://github.com/SerenityOS/serenity/commit/cd6c7f3fc4 Pull-request: https://github.com/SerenityOS/serenity/pull/22209 Reviewed-by: https://github.com/LucasChollet ✅
6 changed files with 35 additions and 5 deletions
|
@ -4,4 +4,4 @@ Executable=/bin/ImageViewer
|
|||
Category=Graphics
|
||||
|
||||
[Launcher]
|
||||
FileTypes=bmp,dds,gif,ico,iff,jpeg,jpg,jxl,pbm,pgm,png,ppm,qoi,tga,tiff,tif,tvg
|
||||
FileTypes=bmp,dds,gif,ico,iff,jpeg,jpg,jxl,lbm,pbm,pgm,png,ppm,qoi,tga,tiff,tif,tvg
|
||||
|
|
|
@ -149,6 +149,17 @@ TEST_CASE(test_ilbm_ham6)
|
|||
EXPECT_EQ(frame.image->get_pixel(77, 107), Gfx::Color(0xf0, 0x40, 0x40, 0xff));
|
||||
}
|
||||
|
||||
TEST_CASE(test_ilbm_dos)
|
||||
{
|
||||
auto file = MUST(Core::MappedFile::map(TEST_INPUT("ilbm/serenity.lbm"sv)));
|
||||
EXPECT(Gfx::ILBMImageDecoderPlugin::sniff(file->bytes()));
|
||||
auto plugin_decoder = TRY_OR_FAIL(Gfx::ILBMImageDecoderPlugin::create(file->bytes()));
|
||||
|
||||
auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 640, 480 }));
|
||||
|
||||
EXPECT_EQ(frame.image->get_pixel(315, 134), Gfx::Color::NamedColor::Red);
|
||||
}
|
||||
|
||||
TEST_CASE(test_ilbm_malformed_header)
|
||||
{
|
||||
Array test_inputs = {
|
||||
|
|
BIN
Tests/LibGfx/test-inputs/ilbm/serenity.lbm
Normal file
BIN
Tests/LibGfx/test-inputs/ilbm/serenity.lbm
Normal file
Binary file not shown.
|
@ -123,7 +123,7 @@ static Array const s_registered_mime_type = {
|
|||
MimeType { .name = "image/vnd.ms-dds"sv, .common_extensions = { ".dds"sv }, .description = "DDS image data"sv, .magic_bytes = Vector<u8> { 'D', 'D', 'S', ' ' } },
|
||||
MimeType { .name = "image/webp"sv, .common_extensions = { ".webp"sv }, .description = "WebP image data"sv, .magic_bytes = Vector<u8> { 'W', 'E', 'B', 'P' }, .offset = 8 },
|
||||
MimeType { .name = "image/x-icon"sv, .common_extensions = { ".ico"sv }, .description = "ICO image data"sv },
|
||||
MimeType { .name = "image/x-ilbm"sv, .common_extensions = { ".iff"sv }, .description = "Interleaved bitmap image data"sv, .magic_bytes = Vector<u8> { 0x46, 0x4F, 0x52, 0x4F } },
|
||||
MimeType { .name = "image/x-ilbm"sv, .common_extensions = { ".iff"sv, ".lbm"sv }, .description = "Interleaved bitmap image data"sv, .magic_bytes = Vector<u8> { 0x46, 0x4F, 0x52, 0x4F } },
|
||||
MimeType { .name = "image/x-portable-bitmap"sv, .common_extensions = { ".pbm"sv }, .description = "PBM image data"sv, .magic_bytes = Vector<u8> { 0x50, 0x31, 0x0A } },
|
||||
MimeType { .name = "image/x-portable-graymap"sv, .common_extensions = { ".pgm"sv }, .description = "PGM image data"sv, .magic_bytes = Vector<u8> { 0x50, 0x32, 0x0A } },
|
||||
MimeType { .name = "image/x-portable-pixmap"sv, .common_extensions = { ".ppm"sv }, .description = "PPM image data"sv, .magic_bytes = Vector<u8> { 0x50, 0x33, 0x0A } },
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
__ENUMERATE_IMAGE_FORMAT(jpeg, ".jpeg") \
|
||||
__ENUMERATE_IMAGE_FORMAT(jpeg, ".jpg") \
|
||||
__ENUMERATE_IMAGE_FORMAT(jxl, ".jxl") \
|
||||
__ENUMERATE_IMAGE_FORMAT(iff, ".lbm") \
|
||||
__ENUMERATE_IMAGE_FORMAT(pbm, ".pbm") \
|
||||
__ENUMERATE_IMAGE_FORMAT(pgm, ".pgm") \
|
||||
__ENUMERATE_IMAGE_FORMAT(png, ".png") \
|
||||
|
|
|
@ -46,6 +46,13 @@ enum class ViewportMode : u32 {
|
|||
HAM = 0x800
|
||||
};
|
||||
|
||||
enum class Format : u8 {
|
||||
// Amiga interleaved format
|
||||
ILBM = 0,
|
||||
// PC-DeluxePaint chunky format
|
||||
PBM = 1
|
||||
};
|
||||
|
||||
AK_ENUM_BITWISE_OPERATORS(ViewportMode);
|
||||
|
||||
struct ChunkHeader {
|
||||
|
@ -96,6 +103,8 @@ struct ILBMLoadingContext {
|
|||
RefPtr<Gfx::Bitmap> bitmap;
|
||||
|
||||
BMHDHeader bm_header;
|
||||
|
||||
Format format;
|
||||
};
|
||||
|
||||
static ErrorOr<void> decode_iff_ilbm_header(ILBMLoadingContext& context)
|
||||
|
@ -107,9 +116,12 @@ static ErrorOr<void> decode_iff_ilbm_header(ILBMLoadingContext& context)
|
|||
return Error::from_string_literal("Missing IFF header");
|
||||
|
||||
auto& header = *bit_cast<IFFHeader const*>(context.data.data());
|
||||
if (header.form != FourCC("FORM") || header.format != FourCC("ILBM"))
|
||||
|
||||
if (header.form != FourCC("FORM") || (header.format != FourCC("ILBM") && header.format != FourCC("PBM ")))
|
||||
return Error::from_string_literal("Invalid IFF-ILBM header");
|
||||
|
||||
context.format = header.format == FourCC("ILBM") ? Format::ILBM : Format::PBM;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -292,9 +304,15 @@ static ErrorOr<void> decode_body_chunk(Chunk body_chunk, ILBMLoadingContext& con
|
|||
|
||||
if (context.bm_header.compression == CompressionType::ByteRun) {
|
||||
auto plane_data = TRY(uncompress_byte_run(body_chunk.data, context));
|
||||
pixel_data = TRY(planar_to_chunky(plane_data, context));
|
||||
if (context.format == Format::ILBM)
|
||||
pixel_data = TRY(planar_to_chunky(plane_data, context));
|
||||
else
|
||||
pixel_data = plane_data;
|
||||
} else {
|
||||
pixel_data = TRY(planar_to_chunky(body_chunk.data, context));
|
||||
if (context.format == Format::ILBM)
|
||||
pixel_data = TRY(planar_to_chunky(body_chunk.data, context));
|
||||
else
|
||||
pixel_data = TRY(ByteBuffer::copy(body_chunk.data.data(), body_chunk.data.size()));
|
||||
}
|
||||
|
||||
// Some files already have 64 colors defined in the palette,
|
||||
|
|
Loading…
Add table
Reference in a new issue