Toward first png.

This commit is contained in:
James Grogan 2022-11-24 17:43:31 +00:00
parent 8f97e9b7a1
commit 33369b1775
12 changed files with 190 additions and 102 deletions

View file

@ -11,6 +11,8 @@ std::string PngHeader::toString() const
sstr << "width: " << mWidth << "\n";
sstr << "height: " << mHeight << "\n";
sstr << "bitDepth: " << (int)mBitDepth << "\n";
sstr << "cached CRC: " << mCachedCrc << "\n";
sstr << mPngInfo.toString();
return sstr.str();
}
@ -66,14 +68,20 @@ void PngHeader::updateData()
mData.push_back(static_cast<unsigned char>(mPngInfo.mInterlaceMethod));
}
uint32_t PngHeader::getCrc() const
uint32_t PngHeader::getCrc()
{
CyclicRedundancyChecker crc_check;
std::vector<unsigned char> char_data = StringUtils::toBytes(mName);
std::copy(mData.begin(), mData.end(), std::back_inserter(char_data));
auto result = crc_check.doCrc(char_data.data(), char_data.size());
return result;
for (auto c : char_data)
{
crc_check.addValue(c);
}
for (auto entry : mData)
{
crc_check.addValue(entry);
}
mCachedCrc = crc_check.getChecksum();
return mCachedCrc;
}
void PngHeader::setPngInfo(const PngInfo& info)

View file

@ -9,7 +9,7 @@ class PngHeader
public:
uint32_t getLength() const;
uint32_t getCrc() const;
uint32_t getCrc();
const std::vector<unsigned char>& getData() const;
@ -36,5 +36,7 @@ private:
PngInfo mPngInfo;
std::string mName{"IHDR"};
uint32_t mCachedCrc{0};
std::vector<unsigned char> mData;
};

View file

@ -5,6 +5,7 @@
#include "BufferBitStream.h"
#include "ZlibEncoder.h"
#include "CyclicRedundancyChecker.h"
#include <iostream>
#include <sstream>
@ -43,8 +44,6 @@ bool PngReader::checkSignature()
return false;
}
}
mCurrentOffset += 8;
return true;
}
@ -54,45 +53,51 @@ bool PngReader::readChunk()
std::string chunkType;
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4);
mCurrentOffset += 8;
std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
bool lastChunk = false;
if (chunkType == "IHDR")
{
readHeaderChunk();
if (!readHeaderChunk())
{
return false;
}
}
else if(chunkType == "IEND")
{
lastChunk = true;
if (mProcessingDatablocks)
{
decodeData();
}
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
}
else if(chunkType == "IDAT")
{
readIDATChunk(length);
mProcessingDatablocks = true;
if(!readIDATChunk(length))
{
return false;
}
}
else
{
if (mProcessingDatablocks)
{
decodeData();
}
for(unsigned idx=0;idx<length;idx++)
{
mFile->GetInHandle()->get();
}
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
}
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
mCurrentOffset += 4;
return !lastChunk;
}
void PngReader::readIDATChunk(unsigned length)
{
for(unsigned idx=0; idx<length; idx++)
{
mInputStream->writeByte(*mFile->readNextByte());
}
}
void PngReader::readHeaderChunk()
bool PngReader::readHeaderChunk()
{
auto width = *BinaryStream::getNextDWord(mFile->GetInHandle());
auto height = *BinaryStream::getNextDWord(mFile->GetInHandle());
@ -106,15 +111,52 @@ void PngReader::readHeaderChunk()
info.mFilterMethod = static_cast<PngInfo::FilterMethod>(mFile->GetInHandle()->get());
info.mInterlaceMethod = static_cast<PngInfo::InterlaceMethod>(mFile->GetInHandle()->get());
mHeader.setPngInfo(info);
mHeader.updateData();
mCurrentOffset += 13;
uint32_t file_crc = *BinaryStream::getNextDWord(mFile->GetInHandle());
auto crc_calc = mHeader.getCrc();
logHeader();
std::cout << mHeader.toString() << "*************\n";
if (file_crc != crc_calc)
{
std::cout << "Header crc calc does not match file value. File: " << file_crc << " Header: " << crc_calc << std::endl;;
return false;
}
else
{
return true;
}
}
void PngReader::logHeader()
bool PngReader::readIDATChunk(unsigned length)
{
std::cout << "IHDR\n" << mHeader.toString() << "*************\n";
auto crc_check = std::make_unique<CyclicRedundancyChecker>();
std::vector<unsigned char> char_data = StringUtils::toBytes("IDAT");
for (auto c : char_data)
{
crc_check->addValue(c);
}
mInputStream->setChecksumCalculator(crc_check.get());
for(unsigned idx=0; idx<length; idx++)
{
mInputStream->writeByte(*mFile->readNextByte());
}
mInputStream->clearChecksumCalculator();
uint32_t file_crc = *BinaryStream::getNextDWord(mFile->GetInHandle());
auto crc_calc = crc_check->getChecksum();
if (file_crc != crc_calc)
{
std::cout << "IDAT crc calc does not match file value. File: " << file_crc << " Header: " << crc_calc << std::endl;;
return false;
}
else
{
return true;
}
}
std::unique_ptr<Image<unsigned char> > PngReader::read()
@ -138,8 +180,11 @@ std::unique_ptr<Image<unsigned char> > PngReader::read()
{
}
std::cout << mEncoder->getData() << std::endl;
mEncoder->decode();
return std::move(image);
}
void PngReader::decodeData()
{
mEncoder->decode();
std::cout << mEncoder->getData() << "***********" << std::endl;
}

View file

@ -24,15 +24,13 @@ public:
private:
bool readChunk();
void readHeaderChunk();
bool readHeaderChunk();
void readIDATChunk(unsigned length);
void logHeader();
bool readIDATChunk(unsigned length);
bool checkSignature();
unsigned mCurrentOffset{0};
void decodeData();
PngHeader mHeader;
@ -43,5 +41,5 @@ private:
std::unique_ptr<ZlibEncoder> mEncoder;
std::unique_ptr<BitStream> mInputStream;
std::unique_ptr<BitStream> mOutputStream;
bool mAwaitingDataBlock{true};
bool mProcessingDatablocks{false};
};

View file

@ -83,9 +83,9 @@ void PngWriter::writeHeader()
mPngHeader.updateData();
mOutStream->writeBytes(mPngHeader.getData());
std::cout << "Writing header " << mPngHeader.toString() << std::endl;
auto crc = mPngHeader.getCrc();
std::cout << mPngHeader.toString() << "*********" << std::endl;
mOutStream->write(crc);
}
@ -98,7 +98,11 @@ void PngWriter::writeEndChunk()
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
CyclicRedundancyChecker crc_check;
auto crc = crc_check.doCrc(char_data.data(), char_data.size());
for (auto c : char_data)
{
crc_check.addValue(c);
}
auto crc = crc_check.getChecksum();
mOutStream->write(crc);
std::cout << "Writing end chunk" << std::endl;
@ -108,11 +112,6 @@ void PngWriter::writeDataChunks(const BufferBitStream& buffer)
{
auto num_bytes = buffer.getBuffer().size();
auto max_bytes{32000};
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;
@ -127,18 +126,23 @@ void PngWriter::writeDataChunks(const BufferBitStream& buffer)
std::cout << "Writing idat length " << num_bytes << std::endl;
mOutStream->write(num_bytes);
mOutStream->writeBytes(StringUtils::toBytes("IDAT"));
std::vector<unsigned char> char_data = StringUtils::toBytes("IDAT");
mOutStream->writeBytes(char_data);
CyclicRedundancyChecker crc_check;
for (auto c : char_data)
{
crc_check.addValue(c);
}
for(unsigned jdx=0; jdx<num_bytes; jdx++)
{
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
crc_buffer[jdx + 4] = val;
mOutStream->writeByte(val);
crc_check.addValue(val);
}
CyclicRedundancyChecker crc_check;
auto crc = crc_check.doCrc(crc_buffer.data(), crc_buffer.size());
auto crc = crc_check.getChecksum();
std::cout << "Writing idat crc" << crc << std::endl;
mOutStream->write(crc);
}