diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-19 17:43:47 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-19 17:43:47 +0200 |
commit | 8acc61f19ac35645abf286fc5751420784ddd3b3 (patch) | |
tree | 25c530177255b53459af3b0aa3cc7641f6a6eedf /Libraries/LibDraw | |
parent | fed668f20fb227ff0dc3e26f614827d10f2f581c (diff) | |
download | serenity-8acc61f19ac35645abf286fc5751420784ddd3b3.zip |
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.
Diffstat (limited to 'Libraries/LibDraw')
-rw-r--r-- | Libraries/LibDraw/PNGLoader.cpp | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/Libraries/LibDraw/PNGLoader.cpp b/Libraries/LibDraw/PNGLoader.cpp index d26224a60f..c592bdb3a9 100644 --- a/Libraries/LibDraw/PNGLoader.cpp +++ b/Libraries/LibDraw/PNGLoader.cpp @@ -65,6 +65,7 @@ struct [[gnu::packed]] Quad16 struct PNGLoadingContext { enum State { NotDecoded = 0, + Error, HeaderDecoded, SizeDecoded, ChunksDecoded, @@ -401,6 +402,7 @@ static bool decode_png_header(PNGLoadingContext& context) if (memcmp(context.data, png_header, sizeof(png_header)) != 0) { dbg() << "Invalid PNG header"; + context.state = PNGLoadingContext::State::Error; return false; } @@ -424,6 +426,7 @@ static bool decode_png_size(PNGLoadingContext& context) Streamer streamer(data_ptr, data_remaining); while (!streamer.at_end()) { if (!process_chunk(streamer, context, true)) { + context.state = PNGLoadingContext::State::Error; return false; } if (context.width && context.height) { @@ -453,6 +456,7 @@ static bool decode_png_chunks(PNGLoadingContext& context) Streamer streamer(data_ptr, data_remaining); while (!streamer.at_end()) { if (!process_chunk(streamer, context, false)) { + context.state = PNGLoadingContext::State::Error; return false; } } @@ -478,8 +482,10 @@ static bool decode_png_bitmap(PNGLoadingContext& context) unsigned long srclen = context.compressed_data.size() - 6; unsigned long destlen = context.decompression_buffer_size; 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; + } context.compressed_data.clear(); } @@ -491,13 +497,17 @@ static bool decode_png_bitmap(PNGLoadingContext& context) Streamer streamer(context.decompression_buffer, context.decompression_buffer_size); for (int y = 0; y < context.height; ++y) { u8 filter; - if (!streamer.read(filter)) + if (!streamer.read(filter)) { + context.state = PNGLoadingContext::State::Error; return false; + } context.scanlines.append({ filter }); 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; + } } } @@ -664,9 +674,13 @@ PNGImageLoaderPlugin::~PNGImageLoaderPlugin() Size PNGImageLoaderPlugin::size() { + if (m_context->state == PNGLoadingContext::State::Error) + return {}; + if (m_context->state < PNGLoadingContext::State::SizeDecoded) { bool success = decode_png_size(*m_context); - ASSERT(success); + if (!success) + return {}; } return { m_context->width, m_context->height }; @@ -674,10 +688,14 @@ Size PNGImageLoaderPlugin::size() RefPtr<GraphicsBitmap> PNGImageLoaderPlugin::bitmap() { + if (m_context->state == PNGLoadingContext::State::Error) + return nullptr; + if (m_context->state < PNGLoadingContext::State::BitmapDecoded) { // NOTE: This forces the chunk decoding to happen. bool success = decode_png_bitmap(*m_context); - ASSERT(success); + if (!success) + return nullptr; } ASSERT(m_context->bitmap); |