summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAziz Berkay Yesilyurt <abyesilyurt@gmail.com>2021-07-11 21:33:37 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-14 13:37:18 +0200
commitb70f2b00a3e77ca15aee60ff5058594e29337492 (patch)
treed17d6b4e6c95ddcb3168cca1cedc556812acb19a /Userland
parentdb36ddc7630ef57d9e546610d4de6f95330c4d92 (diff)
downloadserenity-b70f2b00a3e77ca15aee60ff5058594e29337492.zip
LibGfx: Store the size of the chunk from start in PNGWriter
Before this change PNGWriter::add_chunk used to make a copy of PNGChunk's ByteBuffer to prepend the size of the data. With this change, 4-byte space is saved from the beginning and written at the end of the operation. Avoiding this copy yields significant speed up.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibGfx/PNGWriter.cpp33
-rw-r--r--Userland/Libraries/LibGfx/PNGWriter.h2
2 files changed, 24 insertions, 11 deletions
diff --git a/Userland/Libraries/LibGfx/PNGWriter.cpp b/Userland/Libraries/LibGfx/PNGWriter.cpp
index e9aa6cf693..2812aa29f8 100644
--- a/Userland/Libraries/LibGfx/PNGWriter.cpp
+++ b/Userland/Libraries/LibGfx/PNGWriter.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2021, Pierre Hoffmeister
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2021, Aziz Berkay Yesilyurt <abyesilyurt@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -14,6 +15,8 @@
namespace Gfx {
class PNGChunk {
+ using data_length_type = u32;
+
public:
explicit PNGChunk(String);
auto const& data() const { return m_data; };
@@ -29,6 +32,8 @@ public:
void add_u8(u8);
void store_type();
+ void store_data_length();
+ u32 crc();
private:
template<typename T>
@@ -58,6 +63,7 @@ private:
PNGChunk::PNGChunk(String type)
: m_type(move(type))
{
+ add<data_length_type>(0);
store_type();
}
@@ -68,6 +74,18 @@ void PNGChunk::store_type()
}
}
+void PNGChunk::store_data_length()
+{
+ auto data_lenth = BigEndian(m_data.size() - sizeof(data_length_type) - m_type.length());
+ __builtin_memcpy(m_data.offset_pointer(0), &data_lenth, sizeof(u32));
+}
+
+u32 PNGChunk::crc()
+{
+ u32 crc = Crypto::Checksum::CRC32({ m_data.offset_pointer(sizeof(data_length_type)), m_data.size() - sizeof(data_length_type) }).digest();
+ return crc;
+}
+
template<typename T>
requires(IsUnsigned<T>) void PNGChunk::add(T data)
{
@@ -129,17 +147,12 @@ void NonCompressibleBlock::update_adler(u8 data)
m_adler_s2 = (m_adler_s2 + m_adler_s1) % 65521;
}
-void PNGWriter::add_chunk(PNGChunk const& png_chunk)
+void PNGWriter::add_chunk(PNGChunk& png_chunk)
{
- auto crc = BigEndian(Crypto::Checksum::CRC32({ (const u8*)png_chunk.data().data(), png_chunk.data().size() }).digest());
- auto data_len = BigEndian(png_chunk.data().size() - png_chunk.type().length());
-
- ByteBuffer buf;
- buf.append(&data_len, sizeof(u32));
- buf.append(png_chunk.data().data(), png_chunk.data().size());
- buf.append(&crc, sizeof(u32));
-
- m_data.append(buf.data(), buf.size());
+ png_chunk.store_data_length();
+ u32 crc = png_chunk.crc();
+ png_chunk.add_as_big_endian(crc);
+ m_data.append(png_chunk.data().data(), png_chunk.data().size());
}
void PNGWriter::add_png_header()
diff --git a/Userland/Libraries/LibGfx/PNGWriter.h b/Userland/Libraries/LibGfx/PNGWriter.h
index 587aba1b9c..bc7b110b48 100644
--- a/Userland/Libraries/LibGfx/PNGWriter.h
+++ b/Userland/Libraries/LibGfx/PNGWriter.h
@@ -22,7 +22,7 @@ private:
PNGWriter() { }
Vector<u8> m_data;
- void add_chunk(PNGChunk const&);
+ void add_chunk(PNGChunk&);
void add_png_header();
void add_IHDR_chunk(u32 width, u32 height, u8 bit_depth, u8 color_type, u8 compression_method, u8 filter_method, u8 interlace_method);
void add_IDAT_chunk(Gfx::Bitmap const&);