LibPDF: Send jpeg data down the same path as all other data

JPEG images now honor decode arrays and color spaces.
This commit is contained in:
Nico Weber 2024-01-07 22:12:20 -05:00 committed by Andreas Kling
parent d8ada20bae
commit e770cf06b0
Notes: sideshowbarker 2024-07-17 04:09:56 +09:00
2 changed files with 31 additions and 10 deletions

View file

@ -226,12 +226,38 @@ PDFErrorOr<ByteBuffer> Filter::decode_jbig2(ReadonlyBytes)
PDFErrorOr<ByteBuffer> Filter::decode_dct(ReadonlyBytes bytes)
{
if (Gfx::JPEGImageDecoderPlugin::sniff({ bytes.data(), bytes.size() })) {
auto decoder = TRY(Gfx::JPEGImageDecoderPlugin::create_with_options({ bytes.data(), bytes.size() }, { .cmyk = Gfx::JPEGDecoderOptions::CMYK::PDF }));
auto frame = TRY(decoder->frame(0));
return TRY(frame.image->serialize_to_byte_buffer());
if (!Gfx::JPEGImageDecoderPlugin::sniff({ bytes.data(), bytes.size() }))
return AK::Error::from_string_literal("Not a JPEG image!");
auto decoder = TRY(Gfx::JPEGImageDecoderPlugin::create_with_options({ bytes.data(), bytes.size() }, { .cmyk = Gfx::JPEGDecoderOptions::CMYK::PDF }));
auto internal_format = decoder->natural_frame_format();
if (internal_format == Gfx::NaturalFrameFormat::CMYK) {
auto bitmap = TRY(decoder->cmyk_frame());
// FIXME: Could give CMYKBitmap a method to steal its internal ByteBuffer.
auto size = bitmap->size().width() * bitmap->size().height() * 4;
auto buffer = TRY(ByteBuffer::create_uninitialized(size));
buffer.overwrite(0, bitmap->scanline(0), size);
return buffer;
}
return AK::Error::from_string_literal("Not a JPEG image!");
auto bitmap = TRY(decoder->frame(0)).image;
auto size = bitmap->size().width() * bitmap->size().height() * (internal_format == Gfx::NaturalFrameFormat::Grayscale ? 1 : 3);
ByteBuffer buffer;
TRY(buffer.try_ensure_capacity(size));
for (auto& pixel : *bitmap) {
Color color = Color::from_argb(pixel);
if (internal_format == Gfx::NaturalFrameFormat::Grayscale) {
// Either channel is fine, they're all the same.
buffer.append(color.red());
} else {
buffer.append(color.red());
buffer.append(color.green());
buffer.append(color.blue());
}
}
return buffer;
}
PDFErrorOr<ByteBuffer> Filter::decode_jpx(ReadonlyBytes)

View file

@ -1124,11 +1124,6 @@ PDFErrorOr<Renderer::LoadedImage> Renderer::load_image(NonnullRefPtr<StreamObjec
component_value_decoders.empend(0.0f, 255.0f, dmin, dmax);
}
if (TRY(is_filter(CommonNames::DCTDecode))) {
// TODO: stream objects could store Variant<bytes/Bitmap> to avoid serialisation/deserialisation here
return LoadedImage { TRY(Gfx::Bitmap::create_from_serialized_bytes(image->bytes())), is_image_mask };
}
auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { width, height }));
int x = 0;
int y = 0;