From 59cc910d58ceb1f3d1f0b8c7406e9e7eba124a65 Mon Sep 17 00:00:00 2001 From: James Grogan Date: Wed, 23 Nov 2022 20:26:58 +0000 Subject: [PATCH] Small png cleaning. --- src/core/streams/BitStream.cpp | 8 ++ src/core/streams/BitStream.h | 2 + src/core/streams/BufferBitStream.h | 6 ++ src/image/PngElements.h | 3 + src/image/PngWriter.cpp | 133 +++++++++++++---------------- src/image/PngWriter.h | 5 ++ 6 files changed, 83 insertions(+), 74 deletions(-) diff --git a/src/core/streams/BitStream.cpp b/src/core/streams/BitStream.cpp index dc1b044..678b234 100644 --- a/src/core/streams/BitStream.cpp +++ b/src/core/streams/BitStream.cpp @@ -19,6 +19,14 @@ unsigned char BitStream::getCurrentByte() return mCurrentByte; } +void BitStream::write(uint32_t data) +{ + unsigned num_bytes = sizeof(uint32_t); + for(unsigned idx=0; idx data) = 0; protected: diff --git a/src/core/streams/BufferBitStream.h b/src/core/streams/BufferBitStream.h index 1a3639c..4d570fc 100644 --- a/src/core/streams/BufferBitStream.h +++ b/src/core/streams/BufferBitStream.h @@ -27,6 +27,12 @@ public: return mBuffer; } + void resetOffsets() + { + mByteOffset = 0; + mBitOffset = 0; + } + private: std::vector mBuffer; }; diff --git a/src/image/PngElements.h b/src/image/PngElements.h index d9612f1..a1867db 100644 --- a/src/image/PngElements.h +++ b/src/image/PngElements.h @@ -2,6 +2,9 @@ #include "CyclicRedundancyChecker.h" +#include "ByteUtils.h" +#include "StringUtils.h" + #include #include diff --git a/src/image/PngWriter.cpp b/src/image/PngWriter.cpp index 73a3384..2159700 100644 --- a/src/image/PngWriter.cpp +++ b/src/image/PngWriter.cpp @@ -8,6 +8,8 @@ #include "ImageBitStream.h" #include "Lz77Encoder.h" +#include "ZlibEncoder.h" +#include "CyclicRedundancyChecker.h" #include "ByteUtils.h" @@ -51,33 +53,59 @@ void PngWriter::writeHeader() header_chunk.colorType = 6; auto length = header_chunk.getLength(); - auto crc = header_chunk.getCrc(); + mOutStream->write(length); - unsigned num_bytes = sizeof(uint32_t); - for(unsigned idx=0; idxwriteByte(ByteUtils::getByteN(length, idx)); - } mOutStream->writeBytes(StringUtils::toBytes(header_chunk.name)); - for(unsigned idx=0; idxwriteByte(ByteUtils::getByteN(header_chunk.width, idx)); - } + header_chunk.updateData(); + mOutStream->writeBytes(header_chunk.mData); - for(unsigned idx=0; idxwriteByte(ByteUtils::getByteN(header_chunk.height, idx)); - } - mOutStream->writeByte(header_chunk.bitDepth); - mOutStream->writeByte(header_chunk.colorType); - mOutStream->writeByte(header_chunk.compressionMethod); - mOutStream->writeByte(header_chunk.filterMethod); - mOutStream->writeByte(header_chunk.interlaceMethod); + auto crc = header_chunk.getCrc(); + mOutStream->write(crc); +} - for(unsigned idx=0; idxwrite(length); + + mOutStream->writeBytes(StringUtils::toBytes("IEND")); + + CyclicRedundancyChecker crc_check; + auto crc = crc_check.doCrc(nullptr, 0); + mOutStream->write(crc); +} + +void PngWriter::writeDataChunks(const BufferBitStream& buffer) +{ + auto num_bytes = buffer.getBuffer().size(); + auto max_bytes{32000}; + std::vector crc_buffer(max_bytes, 0); + + unsigned num_dat_chunks = num_bytes/max_bytes + 1; + unsigned offset = 0; + for(unsigned idx=0;idxwriteByte(ByteUtils::getByteN(crc, idx)); + auto length = max_bytes; + if (idx == num_dat_chunks - 1) + { + length = num_bytes - num_dat_chunks*num_bytes; + } + + mOutStream->write(length); + + mOutStream->writeBytes(StringUtils::toBytes("IDAT")); + + for(unsigned jdx=0; jdxwriteByte(val); + } + + CyclicRedundancyChecker crc_check; + auto crc = crc_check.doCrc(crc_buffer.data(), crc_buffer.size()); + mOutStream->write(crc); } } @@ -100,63 +128,20 @@ void PngWriter::write(const std::unique_ptr >& image) writeHeader(); + BufferBitStream lz77_out_stream; + Lz77Encoder lz77_encoder(mInStream.get(), &lz77_out_stream); + lz77_encoder.encode(); + lz77_out_stream.resetOffsets(); - //mImpl->write(image); - //auto fp = fopen(mPath.c_str(), "wb"); + BufferBitStream zlib_out_stream; + ZlibEncoder zlib_encoder(&lz77_out_stream, &zlib_out_stream); + zlib_encoder.encode(); + zlib_out_stream.resetOffsets(); - //auto png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - //auto info_ptr = png_create_info_struct(png_ptr); + writeDataChunks(zlib_out_stream); - //if (setjmp(png_jmpbuf(png_ptr))) - //{ - // return; - //} - //png_init_io(png_ptr, fp); - - - //if (setjmp(png_jmpbuf(png_ptr))) - //{ - // return; - //} - //auto color_type = PNG_COLOR_TYPE_RGB; - //png_set_IHDR(png_ptr, info_ptr, image->GetWidth(), image->GetHeight(), - // image->GetBitDepth(), color_type, PNG_INTERLACE_NONE, - // PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - //png_write_info(png_ptr, info_ptr); - - //if (setjmp(png_jmpbuf(png_ptr))) - //{ - // return; - //} - - //png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * image->GetHeight()); - //auto row_size = image->GetBytesPerRow(); - //for(unsigned jdx=0;jdxGetHeight();jdx++) - //{ - // row_pointers[jdx]=(png_byte*)malloc(sizeof(png_byte)*row_size); - // for(unsigned idx=0;idxGetByte(idx, jdx); - // } - //} - //png_write_image(png_ptr, row_pointers); - //if (setjmp(png_jmpbuf(png_ptr))) - //{ - // return; - //} - - //png_write_end(png_ptr, nullptr); - - //for (unsigned y=0; yGetHeight(); y++) - //{ - // free(row_pointers[y]); - //} - //free(row_pointers); - - //fclose(fp); - //return; + writeEndChunk(); if (mWorkingFile) { diff --git a/src/image/PngWriter.h b/src/image/PngWriter.h index db96936..d4d1d4d 100644 --- a/src/image/PngWriter.h +++ b/src/image/PngWriter.h @@ -9,6 +9,7 @@ using Path = std::filesystem::path; class BitStream; +class BufferBitStream; class File; class PngWriter @@ -27,6 +28,10 @@ private: void writeSignature(); void writeHeader(); + void writeDataChunks(const BufferBitStream& buffer); + + void writeEndChunk(); + //void writeIDatChunk(); Path mPath;