Small png cleaning.

This commit is contained in:
James Grogan 2022-11-23 20:26:58 +00:00
parent 86bc0d89f6
commit 59cc910d58
6 changed files with 83 additions and 74 deletions

View file

@ -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<num_bytes;idx++)
{
writeByte(ByteUtils::getByteN(data, idx));
}
}
int BitStream::getCurrentByteOffset() const
{

View file

@ -27,6 +27,8 @@ public:
virtual void writeByte(unsigned char data) = 0;
void write(uint32_t data);
virtual void writeBytes(const std::vector<unsigned char> data) = 0;
protected:

View file

@ -27,6 +27,12 @@ public:
return mBuffer;
}
void resetOffsets()
{
mByteOffset = 0;
mBitOffset = 0;
}
private:
std::vector<unsigned char> mBuffer;
};

View file

@ -2,6 +2,9 @@
#include "CyclicRedundancyChecker.h"
#include "ByteUtils.h"
#include "StringUtils.h"
#include <string>
#include <sstream>

View file

@ -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; idx<num_bytes;idx++)
{
mOutStream->writeByte(ByteUtils::getByteN(length, idx));
}
mOutStream->writeBytes(StringUtils::toBytes(header_chunk.name));
for(unsigned idx=0; idx<num_bytes;idx++)
{
mOutStream->writeByte(ByteUtils::getByteN(header_chunk.width, idx));
header_chunk.updateData();
mOutStream->writeBytes(header_chunk.mData);
auto crc = header_chunk.getCrc();
mOutStream->write(crc);
}
for(unsigned idx=0; idx<num_bytes;idx++)
void PngWriter::writeEndChunk()
{
mOutStream->writeByte(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);
unsigned length{0};
mOutStream->write(length);
for(unsigned idx=0; idx<num_bytes;idx++)
mOutStream->writeBytes(StringUtils::toBytes("IEND"));
CyclicRedundancyChecker crc_check;
auto crc = crc_check.doCrc(nullptr, 0);
mOutStream->write(crc);
}
void PngWriter::writeDataChunks(const BufferBitStream& buffer)
{
mOutStream->writeByte(ByteUtils::getByteN(crc, idx));
auto num_bytes = buffer.getBuffer().size();
auto max_bytes{32000};
std::vector<unsigned char> crc_buffer(max_bytes, 0);
unsigned num_dat_chunks = num_bytes/max_bytes + 1;
unsigned offset = 0;
for(unsigned idx=0;idx<num_dat_chunks;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; jdx<length; jdx++)
{
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
crc_buffer[jdx] = val;
mOutStream->writeByte(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<unsigned char> >& 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;jdx<image->GetHeight();jdx++)
//{
// row_pointers[jdx]=(png_byte*)malloc(sizeof(png_byte)*row_size);
// for(unsigned idx=0;idx<row_size;idx++)
// {
// row_pointers[jdx][idx] = image->GetByte(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; y<image->GetHeight(); y++)
//{
// free(row_pointers[y]);
//}
//free(row_pointers);
//fclose(fp);
//return;
writeEndChunk();
if (mWorkingFile)
{

View file

@ -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;