mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 22:57:44 +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:
parent
51fe25fdbb
commit
6793574003
4 changed files with 31 additions and 30 deletions
|
@ -155,11 +155,11 @@ void Image::export_bmp(const String& file_path)
|
|||
void Image::export_png(const String& file_path)
|
||||
{
|
||||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, m_size);
|
||||
VERIFY(bitmap);
|
||||
GUI::Painter painter(*bitmap);
|
||||
paint_into(painter, { 0, 0, m_size.width(), m_size.height() });
|
||||
|
||||
Gfx::PNGWriter png_writer;
|
||||
auto png = png_writer.write(bitmap);
|
||||
auto png = Gfx::PNGWriter::encode(*bitmap);
|
||||
auto file = fopen(file_path.characters(), "wb");
|
||||
fwrite(png.data(), sizeof(u8), png.size(), file);
|
||||
fclose(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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -26,9 +27,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
|
@ -36,14 +36,16 @@ class PNGChunk;
|
|||
|
||||
class PNGWriter {
|
||||
public:
|
||||
ByteBuffer write(const RefPtr<Bitmap>);
|
||||
static ByteBuffer encode(Gfx::Bitmap const&);
|
||||
|
||||
private:
|
||||
PNGWriter() { }
|
||||
|
||||
Vector<u8> m_data;
|
||||
void add_chunk(const PNGChunk&);
|
||||
void add_chunk(PNGChunk const&);
|
||||
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(const RefPtr<Bitmap>);
|
||||
void add_IDAT_chunk(Gfx::Bitmap const&);
|
||||
void add_IEND_chunk();
|
||||
};
|
||||
|
||||
|
|
|
@ -67,8 +67,7 @@ int main(int argc, char** argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Gfx::PNGWriter writer;
|
||||
auto encoded_bitmap = writer.write(bitmap);
|
||||
auto encoded_bitmap = Gfx::PNGWriter::encode(*bitmap);
|
||||
if (encoded_bitmap.is_empty()) {
|
||||
warnln("Failed to encode PNG");
|
||||
return 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue