Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions Userland/Libraries/LibGfx/ImageFormats/BilevelImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,6 @@ ErrorOr<NonnullOwnPtr<BilevelImage>> BilevelImage::create_from_byte_buffer(ByteB
return adopt_nonnull_own_or_enomem(new (nothrow) BilevelImage(move(bitmap), width, height, pitch));
}

bool BilevelImage::get_bit(size_t x, size_t y) const
{
VERIFY(x < m_width);
VERIFY(y < m_height);
size_t byte_offset = x / 8;
size_t bit_offset = x % 8;
u8 byte = m_bits[y * m_pitch + byte_offset];
byte = (byte >> (8 - 1 - bit_offset)) & 1;
return byte != 0;
}

void BilevelImage::set_bit(size_t x, size_t y, bool b)
{
VERIFY(x < m_width);
VERIFY(y < m_height);
size_t byte_offset = x / 8;
size_t bit_offset = x % 8;
u8 byte = m_bits[y * m_pitch + byte_offset];
u8 mask = 1u << (8 - 1 - bit_offset);
if (b)
byte |= mask;
else
byte &= ~mask;
m_bits[y * m_pitch + byte_offset] = byte;
}

void BilevelImage::fill(bool b)
{
u8 fill_byte = b ? 0xff : 0;
Expand Down
28 changes: 26 additions & 2 deletions Userland/Libraries/LibGfx/ImageFormats/BilevelImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,32 @@ class BilevelImage {
static ErrorOr<NonnullOwnPtr<BilevelImage>> create_from_byte_buffer(ByteBuffer bitmap, size_t width, size_t height);
static ErrorOr<NonnullOwnPtr<BilevelImage>> create_from_bitmap(Gfx::Bitmap const& bitmap, DitheringAlgorithm dithering_algorithm);

bool get_bit(size_t x, size_t y) const;
void set_bit(size_t x, size_t y, bool b);
ALWAYS_INLINE bool get_bit(size_t x, size_t y) const
{
VERIFY(x < m_width);
VERIFY(y < m_height);
size_t byte_offset = x / 8;
size_t bit_offset = x % 8;
u8 byte = m_bits[y * m_pitch + byte_offset];
byte = (byte >> (8 - 1 - bit_offset)) & 1;
return byte != 0;
}

ALWAYS_INLINE void set_bit(size_t x, size_t y, bool b)
{
VERIFY(x < m_width);
VERIFY(y < m_height);
size_t byte_offset = x / 8;
size_t bit_offset = x % 8;
u8 byte = m_bits[y * m_pitch + byte_offset];
u8 mask = 1u << (8 - 1 - bit_offset);
if (b)
byte |= mask;
else
byte &= ~mask;
m_bits[y * m_pitch + byte_offset] = byte;
}

void fill(bool b);

ErrorOr<NonnullOwnPtr<BilevelImage>> subbitmap(Gfx::IntRect const& rect) const;
Expand Down
8 changes: 7 additions & 1 deletion Userland/Libraries/LibGfx/ImageFormats/CCITTDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ ErrorOr<CCITTStatus> decode_single_ccitt_2d_line(
Group4Options const& options = {})
{
CCITTStatus status {};

// status.current_line stores the color changes in the line. In the worst case scenario,
// the image is a checkerboard and there is a color change at every pixel (+1 for the
// right edge), so let's pre-allocate for this scenario.
TRY(status.current_line.try_ensure_capacity(image_width + 1));

Color current_color { ccitt_white };
u32 column {};
u32 remainder_from_pass_mode {};
Expand Down Expand Up @@ -240,7 +246,7 @@ ErrorOr<CCITTStatus> decode_single_ccitt_2d_line(
current_color = invert(current_color);
remainder_from_pass_mode = 0;

TRY(status.current_line.try_empend(current_color, column));
status.current_line.unchecked_append({ current_color, column });
return {};
};

Expand Down
10 changes: 2 additions & 8 deletions Userland/Libraries/LibGfx/ImageFormats/JBIG2Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1428,18 +1428,12 @@ static ErrorOr<NonnullOwnPtr<BilevelImage>> generic_region_decoding_procedure(Ge
// bytes, beginning and ending on a byte boundary."
// This means we can pass in a stream to CCITT::decode_ccitt_group4() and that can use a bit stream internally.
auto buffer = TRY(CCITT::decode_ccitt_group4(*inputs.stream, inputs.region_width, inputs.region_height, options));
auto result = TRY(BilevelImage::create(inputs.region_width, inputs.region_height));

size_t bytes_per_row = ceil_div(inputs.region_width, 8);
if (buffer.size() != bytes_per_row * inputs.region_height)
return Error::from_string_literal("JBIG2ImageDecoderPlugin: Decoded MMR data has wrong size");

// FIXME: Could probably just copy the ByteBuffer directly into the BilevelImage's internal ByteBuffer instead.
for (size_t y = 0; y < inputs.region_height; ++y) {
for (size_t x = 0; x < inputs.region_width; ++x) {
bool bit = buffer[y * bytes_per_row + x / 8] & (1 << (7 - x % 8));
result->set_bit(x, y, bit);
}
}
auto result = TRY(BilevelImage::create_from_byte_buffer(move(buffer), inputs.region_width, inputs.region_height));
return result;
}

Expand Down
3 changes: 2 additions & 1 deletion Userland/Libraries/LibPDF/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1616,11 +1616,12 @@ PDFErrorOr<Renderer::LoadedImage> Renderer::load_image(NonnullRefPtr<StreamObjec

auto const bytes_per_line = ceil_div(width, 8);
for (int y = 0; y < height; ++y) {
u32* scanline = bitmap->scanline(y);
for (int x = 0; x < width; ++x) {
auto byte = content[y * bytes_per_line + x / 8];
auto bit = 7 - (x % 8);
auto color = colors[(byte >> bit) & 1];
bitmap->set_pixel(x, y, color);
scanline[x] = color.value();
}
}

Expand Down
Loading