Continue png writing.

This commit is contained in:
James Grogan 2022-11-24 16:15:41 +00:00
parent 5400a232dd
commit 8f97e9b7a1
29 changed files with 714 additions and 302 deletions

View file

@ -6,13 +6,14 @@
#include "OutputBitStream.h"
#include "ImageBitStream.h"
#include "PngFilter.h"
#include "Lz77Encoder.h"
#include "ZlibEncoder.h"
#include "CyclicRedundancyChecker.h"
#include "ByteUtils.h"
#include <stdio.h>
#include <iostream>
PngWriter::PngWriter()
{
@ -82,6 +83,8 @@ void PngWriter::writeHeader()
mPngHeader.updateData();
mOutStream->writeBytes(mPngHeader.getData());
std::cout << "Writing header " << mPngHeader.toString() << std::endl;
auto crc = mPngHeader.getCrc();
mOutStream->write(crc);
}
@ -92,17 +95,24 @@ void PngWriter::writeEndChunk()
mOutStream->write(length);
mOutStream->writeBytes(StringUtils::toBytes("IEND"));
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
CyclicRedundancyChecker crc_check;
auto crc = crc_check.doCrc(nullptr, 0);
auto crc = crc_check.doCrc(char_data.data(), char_data.size());
mOutStream->write(crc);
std::cout << "Writing end chunk" << std::endl;
}
void PngWriter::writeDataChunks(const BufferBitStream& buffer)
{
auto num_bytes = buffer.getBuffer().size();
auto max_bytes{32000};
std::vector<unsigned char> crc_buffer(max_bytes, 0);
std::vector<unsigned char> crc_buffer(num_bytes + 4, 0);
crc_buffer[0] = 'I';
crc_buffer[1] = 'D';
crc_buffer[2] = 'A';
crc_buffer[3] = 'T';
unsigned num_dat_chunks = num_bytes/max_bytes + 1;
unsigned offset = 0;
@ -114,19 +124,22 @@ void PngWriter::writeDataChunks(const BufferBitStream& buffer)
length = num_bytes - num_dat_chunks*num_bytes;
}
mOutStream->write(length);
std::cout << "Writing idat length " << num_bytes << std::endl;
mOutStream->write(num_bytes);
mOutStream->writeBytes(StringUtils::toBytes("IDAT"));
for(unsigned jdx=0; jdx<length; jdx++)
for(unsigned jdx=0; jdx<num_bytes; jdx++)
{
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
crc_buffer[jdx] = val;
crc_buffer[jdx + 4] = val;
mOutStream->writeByte(val);
}
CyclicRedundancyChecker crc_check;
auto crc = crc_check.doCrc(crc_buffer.data(), crc_buffer.size());
std::cout << "Writing idat crc" << crc << std::endl;
mOutStream->write(crc);
}
}
@ -146,18 +159,41 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
}
mWorkingImage = image.get();
mInStream = std::make_unique<ImageBitStream>(image.get());
auto image_bit_stream = std::make_unique<ImageBitStream>(image.get());
auto raw_image_stream = image_bit_stream.get();
mInStream = std::move(image_bit_stream);
writeHeader();
BufferBitStream lz77_out_stream;
Lz77Encoder lz77_encoder(mInStream.get(), &lz77_out_stream);
auto filter_out_stream = std::make_unique<BufferBitStream>();
PngFilter filter(raw_image_stream, filter_out_stream.get());
filter.encode();
//while(!filter_out_stream->isFinished())
//{
//std::cout << "Got pix " << static_cast<int>(*filter_out_stream->readNextByte()) << std::endl;
//}
lz77_encoder.encode();
lz77_out_stream.resetOffsets();
filter_out_stream->resetOffsets();
std::unique_ptr<BufferBitStream> lz77_out_stream;
if (mCompressionMethod == Deflate::CompressionMethod::NONE)
{
lz77_out_stream = std::move(filter_out_stream);
}
else
{
lz77_out_stream = std::make_unique<BufferBitStream>();
Lz77Encoder lz77_encoder(filter_out_stream.get(), lz77_out_stream.get());
lz77_encoder.encode();
lz77_out_stream->resetOffsets();
}
BufferBitStream zlib_out_stream;
ZlibEncoder zlib_encoder(&lz77_out_stream, &zlib_out_stream);
ZlibEncoder zlib_encoder(lz77_out_stream.get(), &zlib_out_stream);
zlib_encoder.encode();
zlib_out_stream.resetOffsets();