1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:07:34 +00:00

LibGfx: Improve PNG encoder API somewhat

This is still far from ideal, but let's at least make it take a
Gfx::Bitmap const&.
This commit is contained in:
Andreas Kling 2021-04-19 23:43:04 +02:00
parent 51fe25fdbb
commit 6793574003
4 changed files with 31 additions and 30 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2021, Pierre Hoffmeister
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,17 +25,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PNGWriter.h"
#include <AK/String.h>
#include <LibCrypto/Checksum/CRC32.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/PNGWriter.h>
namespace Gfx {
class PNGChunk {
public:
PNGChunk(const String&);
const Vector<u8>& data() const { return m_data; };
const String& type() const { return m_type; };
explicit PNGChunk(String);
Vector<u8> const& data() const { return m_data; };
String const& type() const { return m_type; };
void add_u8(u8);
void add_u16_big(u16);
void add_u32_big(u32);
@ -51,8 +53,8 @@ public:
void finalize(PNGChunk&);
void add_byte_to_block(u8 data, PNGChunk&);
u32 adler_s1() { return m_adler_s1; }
u32 adler_s2() { return m_adler_s2; }
u32 adler_s1() const { return m_adler_s1; }
u32 adler_s2() const { return m_adler_s2; }
private:
void add_block_to_chunk(PNGChunk&, bool);
@ -63,7 +65,7 @@ private:
u32 m_adler_s2 { 0 };
};
PNGChunk::PNGChunk(const String& type)
PNGChunk::PNGChunk(String type)
: m_type(move(type))
{
}
@ -141,7 +143,7 @@ void NonCompressibleBlock::update_adler(u8 data)
m_adler_s2 = (m_adler_s2 + m_adler_s1) % 65521;
}
void PNGWriter::add_chunk(const PNGChunk& png_chunk)
void PNGWriter::add_chunk(PNGChunk const& png_chunk)
{
Vector<u8> combined;
for (auto character : png_chunk.type()) {
@ -185,7 +187,7 @@ void PNGWriter::add_IEND_chunk()
add_chunk(png_chunk);
}
void PNGWriter::add_IDAT_chunk(const RefPtr<Bitmap> bitmap)
void PNGWriter::add_IDAT_chunk(Gfx::Bitmap const& bitmap)
{
PNGChunk png_chunk { "IDAT" };
@ -194,11 +196,11 @@ void PNGWriter::add_IDAT_chunk(const RefPtr<Bitmap> bitmap)
NonCompressibleBlock non_compressible_block;
for (int y = 0; y < bitmap->height(); ++y) {
for (int y = 0; y < bitmap.height(); ++y) {
non_compressible_block.add_byte_to_block(0, png_chunk);
for (int x = 0; x < bitmap->width(); ++x) {
auto pixel = bitmap->get_pixel(x, y);
for (int x = 0; x < bitmap.width(); ++x) {
auto pixel = bitmap.get_pixel(x, y);
non_compressible_block.add_byte_to_block(pixel.red(), png_chunk);
non_compressible_block.add_byte_to_block(pixel.green(), png_chunk);
non_compressible_block.add_byte_to_block(pixel.blue(), png_chunk);
@ -213,16 +215,14 @@ void PNGWriter::add_IDAT_chunk(const RefPtr<Bitmap> bitmap)
add_chunk(png_chunk);
}
ByteBuffer PNGWriter::write(const RefPtr<Bitmap> bitmap)
ByteBuffer PNGWriter::encode(Gfx::Bitmap const& bitmap)
{
add_png_header();
add_IHDR_chunk(bitmap->width(), bitmap->height(), 8, 6, 0, 0, 0);
add_IDAT_chunk(bitmap);
add_IEND_chunk();
ByteBuffer buf;
buf.append(m_data.data(), m_data.size());
return buf;
PNGWriter writer;
writer.add_png_header();
writer.add_IHDR_chunk(bitmap.width(), bitmap.height(), 8, 6, 0, 0, 0);
writer.add_IDAT_chunk(bitmap);
writer.add_IEND_chunk();
return ByteBuffer::copy(writer.m_data);
}
}