mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:57:36 +00:00
LibDraw: Have the PNGImageLoaderPlugin remember if it failed to decode
Instead of trying again when asked repeatedly, just remember if it didn't work out the first time.
This commit is contained in:
parent
fed668f20f
commit
8acc61f19a
1 changed files with 23 additions and 5 deletions
|
@ -65,6 +65,7 @@ struct [[gnu::packed]] Quad16
|
||||||
struct PNGLoadingContext {
|
struct PNGLoadingContext {
|
||||||
enum State {
|
enum State {
|
||||||
NotDecoded = 0,
|
NotDecoded = 0,
|
||||||
|
Error,
|
||||||
HeaderDecoded,
|
HeaderDecoded,
|
||||||
SizeDecoded,
|
SizeDecoded,
|
||||||
ChunksDecoded,
|
ChunksDecoded,
|
||||||
|
@ -401,6 +402,7 @@ static bool decode_png_header(PNGLoadingContext& context)
|
||||||
|
|
||||||
if (memcmp(context.data, png_header, sizeof(png_header)) != 0) {
|
if (memcmp(context.data, png_header, sizeof(png_header)) != 0) {
|
||||||
dbg() << "Invalid PNG header";
|
dbg() << "Invalid PNG header";
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,6 +426,7 @@ static bool decode_png_size(PNGLoadingContext& context)
|
||||||
Streamer streamer(data_ptr, data_remaining);
|
Streamer streamer(data_ptr, data_remaining);
|
||||||
while (!streamer.at_end()) {
|
while (!streamer.at_end()) {
|
||||||
if (!process_chunk(streamer, context, true)) {
|
if (!process_chunk(streamer, context, true)) {
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (context.width && context.height) {
|
if (context.width && context.height) {
|
||||||
|
@ -453,6 +456,7 @@ static bool decode_png_chunks(PNGLoadingContext& context)
|
||||||
Streamer streamer(data_ptr, data_remaining);
|
Streamer streamer(data_ptr, data_remaining);
|
||||||
while (!streamer.at_end()) {
|
while (!streamer.at_end()) {
|
||||||
if (!process_chunk(streamer, context, false)) {
|
if (!process_chunk(streamer, context, false)) {
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,8 +482,10 @@ static bool decode_png_bitmap(PNGLoadingContext& context)
|
||||||
unsigned long srclen = context.compressed_data.size() - 6;
|
unsigned long srclen = context.compressed_data.size() - 6;
|
||||||
unsigned long destlen = context.decompression_buffer_size;
|
unsigned long destlen = context.decompression_buffer_size;
|
||||||
int ret = puff(context.decompression_buffer, &destlen, context.compressed_data.data() + 2, &srclen);
|
int ret = puff(context.decompression_buffer, &destlen, context.compressed_data.data() + 2, &srclen);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
context.compressed_data.clear();
|
context.compressed_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,13 +497,17 @@ static bool decode_png_bitmap(PNGLoadingContext& context)
|
||||||
Streamer streamer(context.decompression_buffer, context.decompression_buffer_size);
|
Streamer streamer(context.decompression_buffer, context.decompression_buffer_size);
|
||||||
for (int y = 0; y < context.height; ++y) {
|
for (int y = 0; y < context.height; ++y) {
|
||||||
u8 filter;
|
u8 filter;
|
||||||
if (!streamer.read(filter))
|
if (!streamer.read(filter)) {
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
context.scanlines.append({ filter });
|
context.scanlines.append({ filter });
|
||||||
auto& scanline_buffer = context.scanlines.last().data;
|
auto& scanline_buffer = context.scanlines.last().data;
|
||||||
if (!streamer.wrap_bytes(scanline_buffer, context.width * context.bytes_per_pixel))
|
if (!streamer.wrap_bytes(scanline_buffer, context.width * context.bytes_per_pixel)) {
|
||||||
|
context.state = PNGLoadingContext::State::Error;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,9 +674,13 @@ PNGImageLoaderPlugin::~PNGImageLoaderPlugin()
|
||||||
|
|
||||||
Size PNGImageLoaderPlugin::size()
|
Size PNGImageLoaderPlugin::size()
|
||||||
{
|
{
|
||||||
|
if (m_context->state == PNGLoadingContext::State::Error)
|
||||||
|
return {};
|
||||||
|
|
||||||
if (m_context->state < PNGLoadingContext::State::SizeDecoded) {
|
if (m_context->state < PNGLoadingContext::State::SizeDecoded) {
|
||||||
bool success = decode_png_size(*m_context);
|
bool success = decode_png_size(*m_context);
|
||||||
ASSERT(success);
|
if (!success)
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { m_context->width, m_context->height };
|
return { m_context->width, m_context->height };
|
||||||
|
@ -674,10 +688,14 @@ Size PNGImageLoaderPlugin::size()
|
||||||
|
|
||||||
RefPtr<GraphicsBitmap> PNGImageLoaderPlugin::bitmap()
|
RefPtr<GraphicsBitmap> PNGImageLoaderPlugin::bitmap()
|
||||||
{
|
{
|
||||||
|
if (m_context->state == PNGLoadingContext::State::Error)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (m_context->state < PNGLoadingContext::State::BitmapDecoded) {
|
if (m_context->state < PNGLoadingContext::State::BitmapDecoded) {
|
||||||
// NOTE: This forces the chunk decoding to happen.
|
// NOTE: This forces the chunk decoding to happen.
|
||||||
bool success = decode_png_bitmap(*m_context);
|
bool success = decode_png_bitmap(*m_context);
|
||||||
ASSERT(success);
|
if (!success)
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(m_context->bitmap);
|
ASSERT(m_context->bitmap);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue