summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorKarol Kosek <krkk@serenityos.org>2022-07-10 00:14:19 +0200
committerAndreas Kling <kling@serenityos.org>2022-07-10 15:01:07 +0200
commit98a90d79de57fa7690ed68cee5af32c22bfa3fbe (patch)
tree9335ad57d421e962b037dc4cc22a7f44e0d135f0 /Userland
parentebc20f7ac3090654823746d587b49ffab1e66bed (diff)
downloadserenity-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.cpp35
-rw-r--r--Userland/Libraries/LibGfx/PNGShared.h17
-rw-r--r--Userland/Libraries/LibGfx/PNGWriter.cpp3
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)