diff options
author | Karol Kosek <krkk@serenityos.org> | 2022-07-10 00:14:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-07-10 15:01:07 +0200 |
commit | 98a90d79de57fa7690ed68cee5af32c22bfa3fbe (patch) | |
tree | 9335ad57d421e962b037dc4cc22a7f44e0d135f0 /Userland | |
parent | ebc20f7ac3090654823746d587b49ffab1e66bed (diff) | |
download | serenity-98a90d79de57fa7690ed68cee5af32c22bfa3fbe.zip |
LibGfx: Move PNG header and paeth_predictor function to a shared header
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGfx/PNGLoader.cpp | 35 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/PNGShared.h | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/PNGWriter.cpp | 3 |
3 files changed, 28 insertions, 27 deletions
diff --git a/Userland/Libraries/LibGfx/PNGLoader.cpp b/Userland/Libraries/LibGfx/PNGLoader.cpp index 00195a9a79..6a32c7da81 100644 --- a/Userland/Libraries/LibGfx/PNGLoader.cpp +++ b/Userland/Libraries/LibGfx/PNGLoader.cpp @@ -20,8 +20,6 @@ namespace Gfx { -static constexpr Array<u8, 8> png_header = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 }; - struct PNG_IHDR { NetworkOrdered<u32> width; NetworkOrdered<u32> height; @@ -166,19 +164,6 @@ private: static bool process_chunk(Streamer&, PNGLoadingContext& context); -ALWAYS_INLINE static u8 paeth_predictor(int a, int b, int c) -{ - int p = a + b - c; - int pa = abs(p - a); - int pb = abs(p - b); - int pc = abs(p - c); - if (pa <= pb && pa <= pc) - return a; - if (pb <= pc) - return b; - return c; -} - union [[gnu::packed]] Pixel { ARGB32 rgba { 0 }; u8 v[4]; @@ -264,11 +249,11 @@ ALWAYS_INLINE static void unfilter_impl(Gfx::Bitmap& bitmap, int y, void const* a = pixels[i - 1]; c = pixels_y_minus_1[i - 1]; } - x.v[0] += paeth_predictor(a.v[0], b.v[0], c.v[0]); - x.v[1] += paeth_predictor(a.v[1], b.v[1], c.v[1]); - x.v[2] += paeth_predictor(a.v[2], b.v[2], c.v[2]); + x.v[0] += PNG::paeth_predictor(a.v[0], b.v[0], c.v[0]); + x.v[1] += PNG::paeth_predictor(a.v[1], b.v[1], c.v[1]); + x.v[2] += PNG::paeth_predictor(a.v[2], b.v[2], c.v[2]); if constexpr (has_alpha) - x.v[3] += paeth_predictor(a.v[3], b.v[3], c.v[3]); + x.v[3] += PNG::paeth_predictor(a.v[3], b.v[3], c.v[3]); } } } @@ -513,13 +498,13 @@ static bool decode_png_header(PNGLoadingContext& context) if (context.state >= PNGLoadingContext::HeaderDecoded) return true; - if (!context.data || context.data_size < sizeof(png_header)) { + if (!context.data || context.data_size < sizeof(PNG::header)) { dbgln_if(PNG_DEBUG, "Missing PNG header"); context.state = PNGLoadingContext::State::Error; return false; } - if (memcmp(context.data, png_header.span().data(), sizeof(png_header)) != 0) { + if (memcmp(context.data, PNG::header.span().data(), sizeof(PNG::header)) != 0) { dbgln_if(PNG_DEBUG, "Invalid PNG header"); context.state = PNGLoadingContext::State::Error; return false; @@ -539,8 +524,8 @@ static bool decode_png_size(PNGLoadingContext& context) return false; } - u8 const* data_ptr = context.data + sizeof(png_header); - size_t data_remaining = context.data_size - sizeof(png_header); + u8 const* data_ptr = context.data + sizeof(PNG::header); + size_t data_remaining = context.data_size - sizeof(PNG::header); Streamer streamer(data_ptr, data_remaining); while (!streamer.at_end()) { @@ -567,8 +552,8 @@ static bool decode_png_chunks(PNGLoadingContext& context) return false; } - u8 const* data_ptr = context.data + sizeof(png_header); - int data_remaining = context.data_size - sizeof(png_header); + u8 const* data_ptr = context.data + sizeof(PNG::header); + int data_remaining = context.data_size - sizeof(PNG::header); context.compressed_data.ensure_capacity(context.data_size); diff --git a/Userland/Libraries/LibGfx/PNGShared.h b/Userland/Libraries/LibGfx/PNGShared.h index 3486456f86..6f60d848ae 100644 --- a/Userland/Libraries/LibGfx/PNGShared.h +++ b/Userland/Libraries/LibGfx/PNGShared.h @@ -8,6 +8,9 @@ namespace Gfx::PNG { +// https://www.w3.org/TR/PNG/#5PNG-file-signature +static constexpr Array<u8, 8> header = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 }; + // https://www.w3.org/TR/PNG/#6Colour-values enum class ColorType : u8 { Greyscale = 0, @@ -26,4 +29,18 @@ enum class FilterType : u8 { Paeth, }; +// https://www.w3.org/TR/PNG/#9Filter-type-4-Paeth +ALWAYS_INLINE u8 paeth_predictor(u8 a, u8 b, u8 c) +{ + int p = a + b - c; + int pa = abs(p - a); + int pb = abs(p - b); + int pc = abs(p - c); + if (pa <= pb && pa <= pc) + return a; + if (pb <= pc) + return b; + return c; +} + }; diff --git a/Userland/Libraries/LibGfx/PNGWriter.cpp b/Userland/Libraries/LibGfx/PNGWriter.cpp index 79ad181994..950815cfb6 100644 --- a/Userland/Libraries/LibGfx/PNGWriter.cpp +++ b/Userland/Libraries/LibGfx/PNGWriter.cpp @@ -112,8 +112,7 @@ void PNGWriter::add_chunk(PNGChunk& png_chunk) void PNGWriter::add_png_header() { - const u8 png_header[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 }; - m_data.append(png_header, sizeof(png_header)); + m_data.append(PNG::header.data(), PNG::header.size()); } void PNGWriter::add_IHDR_chunk(u32 width, u32 height, u8 bit_depth, PNG::ColorType color_type, u8 compression_method, u8 filter_method, u8 interlace_method) |