mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:47:34 +00:00
LibGfx/ILBMLoader: Add support for EHB mode
This commit is contained in:
parent
398d271a46
commit
7b4b5b735b
1 changed files with 37 additions and 4 deletions
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/ByteReader.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/Endian.h>
|
#include <AK/Endian.h>
|
||||||
#include <AK/FixedArray.h>
|
#include <AK/FixedArray.h>
|
||||||
|
@ -36,6 +37,13 @@ enum class MaskType : u8 {
|
||||||
HasLasso = 3
|
HasLasso = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ViewportMode : u32 {
|
||||||
|
EHB = 0x80,
|
||||||
|
HAM = 0x800
|
||||||
|
};
|
||||||
|
|
||||||
|
AK_ENUM_BITWISE_OPERATORS(ViewportMode);
|
||||||
|
|
||||||
struct ChunkHeader {
|
struct ChunkHeader {
|
||||||
FourCC chunk_type;
|
FourCC chunk_type;
|
||||||
BigEndian<u32> chunk_size;
|
BigEndian<u32> chunk_size;
|
||||||
|
@ -74,7 +82,9 @@ struct ILBMLoadingContext {
|
||||||
// max number of bytes per plane row
|
// max number of bytes per plane row
|
||||||
u16 pitch;
|
u16 pitch;
|
||||||
|
|
||||||
FixedArray<Color> color_table;
|
ViewportMode viewport_mode;
|
||||||
|
|
||||||
|
Vector<Color> color_table;
|
||||||
|
|
||||||
RefPtr<Gfx::Bitmap> bitmap;
|
RefPtr<Gfx::Bitmap> bitmap;
|
||||||
|
|
||||||
|
@ -96,13 +106,14 @@ static ErrorOr<void> decode_iff_ilbm_header(ILBMLoadingContext& context)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static ErrorOr<FixedArray<Color>> decode_cmap_chunk(Chunk cmap_chunk)
|
static ErrorOr<Vector<Color>> decode_cmap_chunk(Chunk cmap_chunk)
|
||||||
{
|
{
|
||||||
size_t const size = cmap_chunk.data.size() / 3;
|
size_t const size = cmap_chunk.data.size() / 3;
|
||||||
FixedArray<Color> color_table = TRY(FixedArray<Color>::create(size));
|
Vector<Color> color_table;
|
||||||
|
TRY(color_table.try_ensure_capacity(size));
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
color_table[i] = Color(cmap_chunk.data[i * 3], cmap_chunk.data[(i * 3) + 1], cmap_chunk.data[(i * 3) + 2]);
|
color_table.unchecked_append(Color(cmap_chunk.data[i * 3], cmap_chunk.data[(i * 3) + 1], cmap_chunk.data[(i * 3) + 2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return color_table;
|
return color_table;
|
||||||
|
@ -189,6 +200,17 @@ static ErrorOr<ByteBuffer> uncompress_byte_run(ReadonlyBytes data, ILBMLoadingCo
|
||||||
return plane_data;
|
return plane_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ErrorOr<void> extend_ehb_palette(ILBMLoadingContext& context)
|
||||||
|
{
|
||||||
|
dbgln_if(ILBM_DEBUG, "need to extend palette");
|
||||||
|
for (size_t i = 0; i < 32; ++i) {
|
||||||
|
auto const color = context.color_table[i];
|
||||||
|
TRY(context.color_table.try_append(color.darkened()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static ErrorOr<void> decode_body_chunk(Chunk body_chunk, ILBMLoadingContext& context)
|
static ErrorOr<void> decode_body_chunk(Chunk body_chunk, ILBMLoadingContext& context)
|
||||||
{
|
{
|
||||||
dbgln_if(ILBM_DEBUG, "decode_body_chunk {}", body_chunk.data.size());
|
dbgln_if(ILBM_DEBUG, "decode_body_chunk {}", body_chunk.data.size());
|
||||||
|
@ -202,6 +224,14 @@ static ErrorOr<void> decode_body_chunk(Chunk body_chunk, ILBMLoadingContext& con
|
||||||
pixel_data = TRY(planar_to_chunky(body_chunk.data, context));
|
pixel_data = TRY(planar_to_chunky(body_chunk.data, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some files already have 64 colours defined in the palette,
|
||||||
|
// maybe for upward compatibility with 256 colours software/hardware.
|
||||||
|
// DPaint 4 & previous files only have 32 colours so the
|
||||||
|
// palette needs to be extended only for these files.
|
||||||
|
if (has_flag(context.viewport_mode, ViewportMode::EHB) && context.color_table.size() < 64) {
|
||||||
|
TRY(extend_ehb_palette(context));
|
||||||
|
}
|
||||||
|
|
||||||
context.bitmap = TRY(chunky_to_bitmap(context, pixel_data));
|
context.bitmap = TRY(chunky_to_bitmap(context, pixel_data));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -253,6 +283,9 @@ static ErrorOr<void> decode_iff_chunks(ILBMLoadingContext& context)
|
||||||
context.state = ILBMLoadingContext::State::BitmapDecoded;
|
context.state = ILBMLoadingContext::State::BitmapDecoded;
|
||||||
} else if (chunk.type == FourCC("CRNG")) {
|
} else if (chunk.type == FourCC("CRNG")) {
|
||||||
dbgln_if(ILBM_DEBUG, "Chunk:CRNG");
|
dbgln_if(ILBM_DEBUG, "Chunk:CRNG");
|
||||||
|
} else if (chunk.type == FourCC("CAMG")) {
|
||||||
|
context.viewport_mode = static_cast<ViewportMode>(AK::convert_between_host_and_big_endian(ByteReader::load32(chunk.data.data())));
|
||||||
|
dbgln_if(ILBM_DEBUG, "Chunk:CAMG, Viewport={}, EHB={}, HAM={}", (u32)context.viewport_mode, has_flag(context.viewport_mode, ViewportMode::EHB), has_flag(context.viewport_mode, ViewportMode::HAM));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue