GraphicsBitmap: Add a new "Indexed8" format that uses a 256-entry palette.
These bitmaps should only be used as a source bitmap, we won't support painting into them using Painter. You can however manipulate the raw pixel data. :^)
This commit is contained in:
parent
cec16105cc
commit
61e3ecec79
Notes:
sideshowbarker
2024-07-19 14:13:19 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/61e3ecec798
3 changed files with 56 additions and 8 deletions
|
@ -17,6 +17,8 @@ GraphicsBitmap::GraphicsBitmap(Format format, const Size& size)
|
|||
, m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16))
|
||||
, m_format(format)
|
||||
{
|
||||
if (format == Format::Indexed8)
|
||||
m_palette = new RGBA32[256];
|
||||
m_data = (RGBA32*)mmap(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
|
||||
ASSERT(m_data && m_data != (void*)-1);
|
||||
m_needs_munmap = true;
|
||||
|
@ -47,6 +49,7 @@ GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, RGBA32* data)
|
|||
, m_pitch(round_up_to_power_of_two(size.width() * sizeof(RGBA32), 16))
|
||||
, m_format(format)
|
||||
{
|
||||
ASSERT(format != Format::Indexed8);
|
||||
}
|
||||
|
||||
GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, MappedFile&& mapped_file)
|
||||
|
@ -56,6 +59,7 @@ GraphicsBitmap::GraphicsBitmap(Format format, const Size& size, MappedFile&& map
|
|||
, m_format(format)
|
||||
, m_mapped_file(move(mapped_file))
|
||||
{
|
||||
ASSERT(format != Format::Indexed8);
|
||||
}
|
||||
|
||||
Retained<GraphicsBitmap> GraphicsBitmap::create_with_shared_buffer(Format format, Retained<SharedBuffer>&& shared_buffer, const Size& size)
|
||||
|
@ -70,6 +74,7 @@ GraphicsBitmap::GraphicsBitmap(Format format, Retained<SharedBuffer>&& shared_bu
|
|||
, m_format(format)
|
||||
, m_shared_buffer(move(shared_buffer))
|
||||
{
|
||||
ASSERT(format != Format::Indexed8);
|
||||
}
|
||||
|
||||
GraphicsBitmap::~GraphicsBitmap()
|
||||
|
@ -79,6 +84,7 @@ GraphicsBitmap::~GraphicsBitmap()
|
|||
ASSERT(rc == 0);
|
||||
}
|
||||
m_data = nullptr;
|
||||
delete [] m_palette;
|
||||
}
|
||||
|
||||
void GraphicsBitmap::set_mmap_name(const String& name)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
class GraphicsBitmap : public Retainable<GraphicsBitmap> {
|
||||
public:
|
||||
enum class Format { Invalid, RGB32, RGBA32 };
|
||||
enum class Format { Invalid, RGB32, RGBA32, Indexed8 };
|
||||
|
||||
static Retained<GraphicsBitmap> create(Format, const Size&);
|
||||
static Retained<GraphicsBitmap> create_wrapper(Format, const Size&, RGBA32*);
|
||||
|
@ -23,6 +23,8 @@ public:
|
|||
RGBA32* scanline(int y);
|
||||
const RGBA32* scanline(int y) const;
|
||||
|
||||
const byte* bits(int y) const;
|
||||
|
||||
Rect rect() const { return { {}, m_size }; }
|
||||
Size size() const { return m_size; }
|
||||
int width() const { return m_size.width(); }
|
||||
|
@ -37,6 +39,23 @@ public:
|
|||
|
||||
size_t size_in_bytes() const { return m_pitch * m_size.height() * sizeof(RGBA32); }
|
||||
|
||||
Color palette_color(byte index) const { return Color::from_rgba(m_palette[index]); }
|
||||
void set_palette_color(byte index, Color color) { m_palette[index] = color.value(); }
|
||||
|
||||
Color get_pixel(int x, int y) const
|
||||
{
|
||||
switch (m_format) {
|
||||
case Format::RGB32:
|
||||
return Color::from_rgb(scanline(y)[x]);
|
||||
case Format::RGBA32:
|
||||
return Color::from_rgba(scanline(y)[x]);
|
||||
case Format::Indexed8:
|
||||
return Color::from_rgba(m_palette[bits(y)[x]]);
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GraphicsBitmap(Format, const Size&);
|
||||
GraphicsBitmap(Format, const Size&, RGBA32*);
|
||||
|
@ -45,6 +64,7 @@ private:
|
|||
|
||||
Size m_size;
|
||||
RGBA32* m_data { nullptr };
|
||||
RGBA32* m_palette { nullptr };
|
||||
size_t m_pitch { 0 };
|
||||
Format m_format { Format::Invalid };
|
||||
bool m_needs_munmap { false };
|
||||
|
@ -61,3 +81,8 @@ inline const RGBA32* GraphicsBitmap::scanline(int y) const
|
|||
{
|
||||
return reinterpret_cast<const RGBA32*>((((const byte*)m_data) + (y * m_pitch)));
|
||||
}
|
||||
|
||||
inline const byte* GraphicsBitmap::bits(int y) const
|
||||
{
|
||||
return reinterpret_cast<const byte*>(scanline(y));
|
||||
}
|
||||
|
|
|
@ -308,15 +308,32 @@ void Painter::blit(const Point& position, const GraphicsBitmap& source, const Re
|
|||
const int last_row = clipped_rect.bottom() - dst_rect.top();
|
||||
const int first_column = clipped_rect.left() - dst_rect.left();
|
||||
RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
|
||||
const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column;
|
||||
const size_t dst_skip = m_target->pitch() / sizeof(RGBA32);
|
||||
const size_t src_skip = source.pitch() / sizeof(RGBA32);
|
||||
|
||||
for (int row = first_row; row <= last_row; ++row) {
|
||||
fast_dword_copy(dst, src, clipped_rect.width());
|
||||
dst += dst_skip;
|
||||
src += src_skip;
|
||||
if (source.format() == GraphicsBitmap::Format::RGB32 || source.format() == GraphicsBitmap::Format::RGBA32) {
|
||||
const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column;
|
||||
const size_t src_skip = source.pitch() / sizeof(RGBA32);
|
||||
for (int row = first_row; row <= last_row; ++row) {
|
||||
fast_dword_copy(dst, src, clipped_rect.width());
|
||||
dst += dst_skip;
|
||||
src += src_skip;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.format() == GraphicsBitmap::Format::Indexed8) {
|
||||
const byte* src = source.bits(src_rect.top() + first_row) + src_rect.left() + first_column;
|
||||
const size_t src_skip = source.pitch();
|
||||
for (int row = first_row; row <= last_row; ++row) {
|
||||
for (int i = 0; i < clipped_rect.width(); ++i)
|
||||
dst[i] = source.palette_color(src[i]).value();
|
||||
dst += dst_skip;
|
||||
src += src_skip;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void Painter::draw_scaled_bitmap(const Rect& a_dst_rect, const GraphicsBitmap& source, const Rect& src_rect)
|
||||
|
@ -345,7 +362,7 @@ void Painter::draw_scaled_bitmap(const Rect& a_dst_rect, const GraphicsBitmap& s
|
|||
|
||||
auto scaled_x = (float)(x - dst_rect.x()) * hscale;
|
||||
auto scaled_y = (float)(y - dst_rect.y()) * vscale;
|
||||
auto src_pixel = Color::from_rgba(source.scanline((int)scaled_y)[(int)scaled_x]);
|
||||
auto src_pixel = source.get_pixel(scaled_x, scaled_y);
|
||||
|
||||
if (!src_pixel.alpha())
|
||||
continue;
|
||||
|
|
Loading…
Add table
Reference in a new issue