mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
LibGfx: Move PNG header and paeth_predictor function to a shared header
This commit is contained in:
parent
ebc20f7ac3
commit
98a90d79de
Notes:
sideshowbarker
2024-07-17 16:23:06 +09:00
Author: https://github.com/krkk Commit: https://github.com/SerenityOS/serenity/commit/98a90d79de Pull-request: https://github.com/SerenityOS/serenity/pull/14537 Reviewed-by: https://github.com/awesomekling
3 changed files with 28 additions and 27 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue