mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-06 16:09:30 +00:00
LibGfx/ILBMLoader: Add support for EHB mode
This commit is contained in:
parent
398d271a46
commit
7b4b5b735b
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/ByteReader.h>
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Endian.h>
|
||||
#include <AK/FixedArray.h>
|
||||
|
@ -36,6 +37,13 @@ enum class MaskType : u8 {
|
|||
HasLasso = 3
|
||||
};
|
||||
|
||||
enum class ViewportMode : u32 {
|
||||
EHB = 0x80,
|
||||
HAM = 0x800
|
||||
};
|
||||
|
||||
AK_ENUM_BITWISE_OPERATORS(ViewportMode);
|
||||
|
||||
struct ChunkHeader {
|
||||
FourCC chunk_type;
|
||||
BigEndian<u32> chunk_size;
|
||||
|
@ -74,7 +82,9 @@ struct ILBMLoadingContext {
|
|||
// max number of bytes per plane row
|
||||
u16 pitch;
|
||||
|
||||
FixedArray<Color> color_table;
|
||||
ViewportMode viewport_mode;
|
||||
|
||||
Vector<Color> color_table;
|
||||
|
||||
RefPtr<Gfx::Bitmap> bitmap;
|
||||
|
||||
|
@ -96,13 +106,14 @@ static ErrorOr<void> decode_iff_ilbm_header(ILBMLoadingContext& context)
|
|||
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;
|
||||
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) {
|
||||
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;
|
||||
|
@ -189,6 +200,17 @@ static ErrorOr<ByteBuffer> uncompress_byte_run(ReadonlyBytes data, ILBMLoadingCo
|
|||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
// 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));
|
||||
|
||||
return {};
|
||||
|
@ -253,6 +283,9 @@ static ErrorOr<void> decode_iff_chunks(ILBMLoadingContext& context)
|
|||
context.state = ILBMLoadingContext::State::BitmapDecoded;
|
||||
} else if (chunk.type == FourCC("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…
Reference in a new issue