Sfoglia il codice sorgente

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.
Aziz Berkay Yesilyurt 4 anni fa
parent
commit
b70f2b00a3

+ 23 - 10
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()

+ 1 - 1
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&);