Toward first png.
This commit is contained in:
parent
8f97e9b7a1
commit
33369b1775
12 changed files with 190 additions and 102 deletions
|
@ -0,0 +1,42 @@
|
||||||
|
#include "CyclicRedundancyChecker.h"
|
||||||
|
|
||||||
|
void CyclicRedundancyChecker::createTable()
|
||||||
|
{
|
||||||
|
unsigned long c{0};
|
||||||
|
for (int n = 0; n < 256; n++)
|
||||||
|
{
|
||||||
|
c = (unsigned long) n;
|
||||||
|
for (int k = 0; k < 8; k++)
|
||||||
|
{
|
||||||
|
if (c & 1)
|
||||||
|
{
|
||||||
|
c = 0xedb88320L ^ (c >> 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = c >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mTable[n] = c;
|
||||||
|
}
|
||||||
|
mTableComputed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CyclicRedundancyChecker::addValue(unsigned char val)
|
||||||
|
{
|
||||||
|
if (!mTableComputed)
|
||||||
|
{
|
||||||
|
createTable();
|
||||||
|
}
|
||||||
|
mLastValue = mTable[(mLastValue ^ val) & 0xff] ^ (mLastValue >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CyclicRedundancyChecker::getChecksum() const
|
||||||
|
{
|
||||||
|
return mLastValue ^ 0xffffffffL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CyclicRedundancyChecker::reset()
|
||||||
|
{
|
||||||
|
mLastValue = 0xffffffffL;
|
||||||
|
}
|
|
@ -1,52 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class CyclicRedundancyChecker
|
#include "AbstractChecksumCalculator.h"
|
||||||
|
|
||||||
|
class CyclicRedundancyChecker : public AbstractChecksumCalculator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void addValue(unsigned char val) override;
|
||||||
|
|
||||||
void createTable()
|
uint32_t getChecksum() const override;
|
||||||
{
|
|
||||||
unsigned long c{0};
|
|
||||||
for (int n = 0; n < 256; n++)
|
|
||||||
{
|
|
||||||
c = (unsigned long) n;
|
|
||||||
for (int k = 0; k < 8; k++)
|
|
||||||
{
|
|
||||||
if (c & 1)
|
|
||||||
{
|
|
||||||
c = 0xedb88320L ^ (c >> 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c = c >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mTable[n] = c;
|
|
||||||
}
|
|
||||||
mTableComputed = true;
|
|
||||||
mTableComputed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long updateCrc(unsigned long crc, unsigned char *buf, int len)
|
void reset() override;
|
||||||
{
|
|
||||||
unsigned long c = crc;
|
|
||||||
if (!mTableComputed)
|
|
||||||
{
|
|
||||||
createTable();
|
|
||||||
}
|
|
||||||
for (int n = 0; n < len; n++)
|
|
||||||
{
|
|
||||||
c = mTable[(c ^ buf[n]) & 0xff] ^ (c >> 8);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long doCrc(unsigned char *buf, int len)
|
|
||||||
{
|
|
||||||
return updateCrc(0xffffffffL, buf, len) ^ 0xffffffffL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void createTable();
|
||||||
bool mTableComputed{false};
|
bool mTableComputed{false};
|
||||||
|
|
||||||
|
uint32_t mLastValue{0xffffffffL};
|
||||||
unsigned long mTable[256];
|
unsigned long mTable[256];
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,10 +61,16 @@ void ZlibEncoder::parseCompressionMethod(unsigned char method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZlibEncoder::parseExtraFlags(unsigned char extraFlags)
|
void ZlibEncoder::parseExtraFlags(unsigned char extraFlags, unsigned char compression_byte)
|
||||||
{
|
{
|
||||||
std::cout << "Got flags " << static_cast<int>(extraFlags) << std::endl;
|
std::cout << "Got flags " << static_cast<int>(extraFlags) << std::endl;
|
||||||
|
|
||||||
|
auto mod = ((static_cast<unsigned>(compression_byte) << 8) | extraFlags) % 31;
|
||||||
|
if (mod != 0)
|
||||||
|
{
|
||||||
|
std::cout << "Invalid header. Mod is " << mod << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
mFlagCheck = ByteUtils::getLowerNBits(extraFlags, 5);
|
mFlagCheck = ByteUtils::getLowerNBits(extraFlags, 5);
|
||||||
mUseDictionary = bool(ByteUtils::getBitN(extraFlags, 5));
|
mUseDictionary = bool(ByteUtils::getBitN(extraFlags, 5));
|
||||||
mFlagLevel = static_cast<CompressionLevel>(ByteUtils::getHigherNBits(extraFlags, 2));
|
mFlagLevel = static_cast<CompressionLevel>(ByteUtils::getHigherNBits(extraFlags, 2));
|
||||||
|
@ -76,11 +82,10 @@ std::string ZlibEncoder::getData() const
|
||||||
sstream << "ZlibEncoder data \n";
|
sstream << "ZlibEncoder data \n";
|
||||||
sstream << "Compression method: " << toString(mCompressionMethod) << '\n';
|
sstream << "Compression method: " << toString(mCompressionMethod) << '\n';
|
||||||
sstream << "Window size: " << mWindowSize << '\n';
|
sstream << "Window size: " << mWindowSize << '\n';
|
||||||
sstream << "Flag check: " << mFlagCheck << '\n';
|
sstream << "Flag check: " << static_cast<int>(mFlagCheck) << '\n';
|
||||||
sstream << "Use dictionary: " << mUseDictionary << '\n';
|
sstream << "Use dictionary: " << mUseDictionary << '\n';
|
||||||
sstream << "Flag level: " << toString(mFlagLevel) << '\n';
|
sstream << "Flag level: " << toString(mFlagLevel) << '\n';
|
||||||
return sstream.str();
|
return sstream.str();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZlibEncoder::encode()
|
bool ZlibEncoder::encode()
|
||||||
|
@ -126,15 +131,17 @@ bool ZlibEncoder::encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto checksum = mChecksumCalculator->getChecksum();
|
const auto checksum = mChecksumCalculator->getChecksum();
|
||||||
std::cout << "ZlibEncoder Writing Checksum " << checksum << std::endl;
|
std::cout << "ZlibEncoder Writing Adler32 Checksum " << checksum << std::endl;
|
||||||
mOutputStream->write(checksum);
|
mOutputStream->write(checksum);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZlibEncoder::decode()
|
bool ZlibEncoder::decode()
|
||||||
{
|
{
|
||||||
parseCompressionMethod(*mInputStream->readNextByte());
|
auto compression_byte = *mInputStream->readNextByte();
|
||||||
parseExtraFlags(*mInputStream->readNextByte());
|
|
||||||
|
parseCompressionMethod(compression_byte);
|
||||||
|
parseExtraFlags(*mInputStream->readNextByte(), compression_byte);
|
||||||
|
|
||||||
if (!mWorkingEncoder)
|
if (!mWorkingEncoder)
|
||||||
{
|
{
|
||||||
|
@ -149,5 +156,15 @@ bool ZlibEncoder::decode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mWorkingEncoder->decode();
|
auto valid = mWorkingEncoder->decode();
|
||||||
|
|
||||||
|
unsigned char byte0 = *mInputStream->readNextByte();
|
||||||
|
unsigned char byte1 = *mInputStream->readNextByte();
|
||||||
|
unsigned char byte2 = *mInputStream->readNextByte();
|
||||||
|
unsigned char byte3 = *mInputStream->readNextByte();
|
||||||
|
|
||||||
|
uint32_t adler32 = (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3;
|
||||||
|
std::cout << "Got adler 32 checksum " << adler32 << std::endl;
|
||||||
|
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseCompressionMethod(unsigned char method);
|
void parseCompressionMethod(unsigned char method);
|
||||||
void parseExtraFlags(unsigned char extraFlags);
|
void parseExtraFlags(unsigned char extraFlags, unsigned char compression_byte);
|
||||||
|
|
||||||
CompressionMethod mCompressionMethod{CompressionMethod::DEFLATE};
|
CompressionMethod mCompressionMethod{CompressionMethod::DEFLATE};
|
||||||
Deflate::CompressionMethod mDeflateCompressionMethod{Deflate::CompressionMethod::NONE};
|
Deflate::CompressionMethod mDeflateCompressionMethod{Deflate::CompressionMethod::NONE};
|
||||||
|
|
|
@ -261,7 +261,7 @@ void DeflateBlock::write(uint16_t datalength)
|
||||||
{
|
{
|
||||||
unsigned char working_block{0};
|
unsigned char working_block{0};
|
||||||
working_block |= static_cast<unsigned char>(mInFinalBlock);
|
working_block |= static_cast<unsigned char>(mInFinalBlock);
|
||||||
working_block |= static_cast<unsigned char>(mCompressionMethod) << 1;
|
working_block |= (static_cast<unsigned char>(mCompressionMethod) << 1);
|
||||||
|
|
||||||
if (mCompressionMethod == Deflate::CompressionMethod::NONE)
|
if (mCompressionMethod == Deflate::CompressionMethod::NONE)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +277,7 @@ void DeflateBlock::write(uint16_t datalength)
|
||||||
for(unsigned idx=0; idx<datalength;idx++)
|
for(unsigned idx=0; idx<datalength;idx++)
|
||||||
{
|
{
|
||||||
auto byte = *mInputStream->readNextByte();
|
auto byte = *mInputStream->readNextByte();
|
||||||
std::cout << "Writing next byte " << static_cast<int>(byte) << std::endl;
|
//std::cout << "Writing next byte " << static_cast<int>(byte) << std::endl;
|
||||||
mOutputStream->writeByte(byte);
|
mOutputStream->writeByte(byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,8 @@ bool DeflateEncoder::decode()
|
||||||
auto working_block = std::make_unique<DeflateBlock>(mInputStream, mOutputStream);
|
auto working_block = std::make_unique<DeflateBlock>(mInputStream, mOutputStream);
|
||||||
working_block->readHeader();
|
working_block->readHeader();
|
||||||
|
|
||||||
|
std::cout << working_block->getMetaData() << std::endl;
|
||||||
|
|
||||||
DeflateBlock* raw_block = working_block.get();
|
DeflateBlock* raw_block = working_block.get();
|
||||||
|
|
||||||
while(!raw_block->isFinalBlock())
|
while(!raw_block->isFinalBlock())
|
||||||
|
|
|
@ -11,6 +11,8 @@ std::string PngHeader::toString() const
|
||||||
sstr << "width: " << mWidth << "\n";
|
sstr << "width: " << mWidth << "\n";
|
||||||
sstr << "height: " << mHeight << "\n";
|
sstr << "height: " << mHeight << "\n";
|
||||||
sstr << "bitDepth: " << (int)mBitDepth << "\n";
|
sstr << "bitDepth: " << (int)mBitDepth << "\n";
|
||||||
|
sstr << "cached CRC: " << mCachedCrc << "\n";
|
||||||
|
|
||||||
sstr << mPngInfo.toString();
|
sstr << mPngInfo.toString();
|
||||||
return sstr.str();
|
return sstr.str();
|
||||||
}
|
}
|
||||||
|
@ -66,14 +68,20 @@ void PngHeader::updateData()
|
||||||
mData.push_back(static_cast<unsigned char>(mPngInfo.mInterlaceMethod));
|
mData.push_back(static_cast<unsigned char>(mPngInfo.mInterlaceMethod));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t PngHeader::getCrc() const
|
uint32_t PngHeader::getCrc()
|
||||||
{
|
{
|
||||||
CyclicRedundancyChecker crc_check;
|
CyclicRedundancyChecker crc_check;
|
||||||
std::vector<unsigned char> char_data = StringUtils::toBytes(mName);
|
std::vector<unsigned char> char_data = StringUtils::toBytes(mName);
|
||||||
std::copy(mData.begin(), mData.end(), std::back_inserter(char_data));
|
for (auto c : char_data)
|
||||||
|
{
|
||||||
auto result = crc_check.doCrc(char_data.data(), char_data.size());
|
crc_check.addValue(c);
|
||||||
return result;
|
}
|
||||||
|
for (auto entry : mData)
|
||||||
|
{
|
||||||
|
crc_check.addValue(entry);
|
||||||
|
}
|
||||||
|
mCachedCrc = crc_check.getChecksum();
|
||||||
|
return mCachedCrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PngHeader::setPngInfo(const PngInfo& info)
|
void PngHeader::setPngInfo(const PngInfo& info)
|
||||||
|
|
|
@ -9,7 +9,7 @@ class PngHeader
|
||||||
public:
|
public:
|
||||||
uint32_t getLength() const;
|
uint32_t getLength() const;
|
||||||
|
|
||||||
uint32_t getCrc() const;
|
uint32_t getCrc();
|
||||||
|
|
||||||
const std::vector<unsigned char>& getData() const;
|
const std::vector<unsigned char>& getData() const;
|
||||||
|
|
||||||
|
@ -36,5 +36,7 @@ private:
|
||||||
PngInfo mPngInfo;
|
PngInfo mPngInfo;
|
||||||
std::string mName{"IHDR"};
|
std::string mName{"IHDR"};
|
||||||
|
|
||||||
|
uint32_t mCachedCrc{0};
|
||||||
|
|
||||||
std::vector<unsigned char> mData;
|
std::vector<unsigned char> mData;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "BufferBitStream.h"
|
#include "BufferBitStream.h"
|
||||||
|
|
||||||
#include "ZlibEncoder.h"
|
#include "ZlibEncoder.h"
|
||||||
|
#include "CyclicRedundancyChecker.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -43,8 +44,6 @@ bool PngReader::checkSignature()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentOffset += 8;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,45 +53,51 @@ bool PngReader::readChunk()
|
||||||
|
|
||||||
std::string chunkType;
|
std::string chunkType;
|
||||||
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4);
|
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4);
|
||||||
mCurrentOffset += 8;
|
|
||||||
|
|
||||||
std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
|
std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
|
||||||
bool lastChunk = false;
|
bool lastChunk = false;
|
||||||
if (chunkType == "IHDR")
|
if (chunkType == "IHDR")
|
||||||
{
|
{
|
||||||
readHeaderChunk();
|
if (!readHeaderChunk())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(chunkType == "IEND")
|
else if(chunkType == "IEND")
|
||||||
{
|
{
|
||||||
lastChunk = true;
|
lastChunk = true;
|
||||||
|
if (mProcessingDatablocks)
|
||||||
|
{
|
||||||
|
decodeData();
|
||||||
|
}
|
||||||
|
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
|
||||||
}
|
}
|
||||||
else if(chunkType == "IDAT")
|
else if(chunkType == "IDAT")
|
||||||
{
|
{
|
||||||
readIDATChunk(length);
|
mProcessingDatablocks = true;
|
||||||
|
if(!readIDATChunk(length))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mProcessingDatablocks)
|
||||||
|
{
|
||||||
|
decodeData();
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned idx=0;idx<length;idx++)
|
for(unsigned idx=0;idx<length;idx++)
|
||||||
{
|
{
|
||||||
mFile->GetInHandle()->get();
|
mFile->GetInHandle()->get();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
|
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
|
||||||
|
}
|
||||||
mCurrentOffset += 4;
|
|
||||||
return !lastChunk;
|
return !lastChunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PngReader::readIDATChunk(unsigned length)
|
bool PngReader::readHeaderChunk()
|
||||||
{
|
|
||||||
for(unsigned idx=0; idx<length; idx++)
|
|
||||||
{
|
|
||||||
mInputStream->writeByte(*mFile->readNextByte());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PngReader::readHeaderChunk()
|
|
||||||
{
|
{
|
||||||
auto width = *BinaryStream::getNextDWord(mFile->GetInHandle());
|
auto width = *BinaryStream::getNextDWord(mFile->GetInHandle());
|
||||||
auto height = *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.mFilterMethod = static_cast<PngInfo::FilterMethod>(mFile->GetInHandle()->get());
|
||||||
info.mInterlaceMethod = static_cast<PngInfo::InterlaceMethod>(mFile->GetInHandle()->get());
|
info.mInterlaceMethod = static_cast<PngInfo::InterlaceMethod>(mFile->GetInHandle()->get());
|
||||||
mHeader.setPngInfo(info);
|
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()
|
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);
|
return std::move(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PngReader::decodeData()
|
||||||
|
{
|
||||||
|
mEncoder->decode();
|
||||||
|
std::cout << mEncoder->getData() << "***********" << std::endl;
|
||||||
|
}
|
||||||
|
|
|
@ -24,15 +24,13 @@ public:
|
||||||
private:
|
private:
|
||||||
bool readChunk();
|
bool readChunk();
|
||||||
|
|
||||||
void readHeaderChunk();
|
bool readHeaderChunk();
|
||||||
|
|
||||||
void readIDATChunk(unsigned length);
|
bool readIDATChunk(unsigned length);
|
||||||
|
|
||||||
void logHeader();
|
|
||||||
|
|
||||||
bool checkSignature();
|
bool checkSignature();
|
||||||
|
|
||||||
unsigned mCurrentOffset{0};
|
void decodeData();
|
||||||
|
|
||||||
PngHeader mHeader;
|
PngHeader mHeader;
|
||||||
|
|
||||||
|
@ -43,5 +41,5 @@ private:
|
||||||
std::unique_ptr<ZlibEncoder> mEncoder;
|
std::unique_ptr<ZlibEncoder> mEncoder;
|
||||||
std::unique_ptr<BitStream> mInputStream;
|
std::unique_ptr<BitStream> mInputStream;
|
||||||
std::unique_ptr<BitStream> mOutputStream;
|
std::unique_ptr<BitStream> mOutputStream;
|
||||||
bool mAwaitingDataBlock{true};
|
bool mProcessingDatablocks{false};
|
||||||
};
|
};
|
||||||
|
|
|
@ -83,9 +83,9 @@ void PngWriter::writeHeader()
|
||||||
mPngHeader.updateData();
|
mPngHeader.updateData();
|
||||||
mOutStream->writeBytes(mPngHeader.getData());
|
mOutStream->writeBytes(mPngHeader.getData());
|
||||||
|
|
||||||
std::cout << "Writing header " << mPngHeader.toString() << std::endl;
|
|
||||||
|
|
||||||
auto crc = mPngHeader.getCrc();
|
auto crc = mPngHeader.getCrc();
|
||||||
|
|
||||||
|
std::cout << mPngHeader.toString() << "*********" << std::endl;
|
||||||
mOutStream->write(crc);
|
mOutStream->write(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,11 @@ void PngWriter::writeEndChunk()
|
||||||
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
|
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
|
||||||
|
|
||||||
CyclicRedundancyChecker crc_check;
|
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);
|
mOutStream->write(crc);
|
||||||
|
|
||||||
std::cout << "Writing end chunk" << std::endl;
|
std::cout << "Writing end chunk" << std::endl;
|
||||||
|
@ -108,11 +112,6 @@ void PngWriter::writeDataChunks(const BufferBitStream& buffer)
|
||||||
{
|
{
|
||||||
auto num_bytes = buffer.getBuffer().size();
|
auto num_bytes = buffer.getBuffer().size();
|
||||||
auto max_bytes{32000};
|
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 num_dat_chunks = num_bytes/max_bytes + 1;
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
|
@ -127,18 +126,23 @@ void PngWriter::writeDataChunks(const BufferBitStream& buffer)
|
||||||
std::cout << "Writing idat length " << num_bytes << std::endl;
|
std::cout << "Writing idat length " << num_bytes << std::endl;
|
||||||
mOutStream->write(num_bytes);
|
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++)
|
for(unsigned jdx=0; jdx<num_bytes; jdx++)
|
||||||
{
|
{
|
||||||
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
|
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
|
||||||
crc_buffer[jdx + 4] = val;
|
|
||||||
mOutStream->writeByte(val);
|
mOutStream->writeByte(val);
|
||||||
|
crc_check.addValue(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
CyclicRedundancyChecker crc_check;
|
auto crc = crc_check.getChecksum();
|
||||||
auto crc = crc_check.doCrc(crc_buffer.data(), crc_buffer.size());
|
|
||||||
|
|
||||||
std::cout << "Writing idat crc" << crc << std::endl;
|
std::cout << "Writing idat crc" << crc << std::endl;
|
||||||
mOutStream->write(crc);
|
mOutStream->write(crc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ int main()
|
||||||
{
|
{
|
||||||
//const auto path = "/home/jmsgrogan/Downloads/test.png";
|
//const auto path = "/home/jmsgrogan/Downloads/test.png";
|
||||||
|
|
||||||
const auto path = "/home/jmsgrogan/Downloads/index.png";
|
//const auto path = "/home/jmsgrogan/Downloads/index.png";
|
||||||
|
|
||||||
|
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test.png";
|
||||||
|
|
||||||
PngReader reader;
|
PngReader reader;
|
||||||
reader.setPath(path);
|
reader.setPath(path);
|
||||||
|
|
Loading…
Reference in a new issue