mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 09:39:39 +00:00
LibPDF: Add a fastpath for 1bpp grayscale to load_image()
We used to expand every bit in an 1bpp image to a 0 or 255 byte, then map that to a float that's either 0.0f or 1.0f (or whatever's in /DecodeArray), then multiply that by 255.0f to convert it to a u8 and put that in the rgb channels of a Color. Now we precompute the two possible outcomes (almost always Black and White) and do a per-bit lookup. Reduces time for Build/lagom/bin/pdf --render-bench --render-repeats 20 --page 36 \ ~/Downloads/Flatland.pdf (the "decoded data cached" case) from 3.3s to 1.1s on my system. Reduces time for Build/lagom/bin/pdf --debugging-stats ~/Downloads/0000/0000231.pdf (the "need to decode each page" case) from 52s to 43s on my machine. Also makes paging through PDFs that contain a 1700x2200 pixel CCITT or JBIG2 bitmap on each page noticeably snappier.
This commit is contained in:
parent
c01acdd733
commit
40780304b8
Notes:
sideshowbarker
2024-07-17 02:08:15 +09:00
Author: https://github.com/nico
Commit: 40780304b8
Pull-request: https://github.com/SerenityOS/serenity/pull/23781
Reviewed-by: https://github.com/LucasChollet ✅
1 changed files with 24 additions and 0 deletions
|
@ -1173,6 +1173,30 @@ PDFErrorOr<Renderer::LoadedImage> Renderer::load_image(NonnullRefPtr<StreamObjec
|
|||
decode_array = color_space->default_decode();
|
||||
}
|
||||
|
||||
if (bits_per_component == 1 && color_space->family() == ColorSpaceFamily::DeviceGray) {
|
||||
// Fast path for 1bpp grayscale. Used for masks and scanned pages (CCITT or JBIG2).
|
||||
// FIXME: This fast path could work for CalGray and Indexed too,
|
||||
// but IndexedColorSpace::default_decode() currently assumes 8bpp.
|
||||
auto bitmap = TRY(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { width, height }));
|
||||
|
||||
Color colors[] = {
|
||||
TRY(color_space->style({ &decode_array[0], 1 })).get<Color>(),
|
||||
TRY(color_space->style({ &decode_array[1], 1 })).get<Color>(),
|
||||
};
|
||||
|
||||
auto const bytes_per_line = ceil_div(width, 8);
|
||||
for (int y = 0; y < height; ++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);
|
||||
}
|
||||
}
|
||||
|
||||
return LoadedImage { bitmap, is_image_mask };
|
||||
}
|
||||
|
||||
Vector<u8> resampled_storage;
|
||||
if (bits_per_component < 8) {
|
||||
UpsampleMode mode = color_space->family() == ColorSpaceFamily::Indexed ? UpsampleMode::StoreValuesUnchanged : UpsampleMode::UpsampleTo8Bit;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue