Some encode/decode practice.

This commit is contained in:
James Grogan 2022-11-21 17:45:12 +00:00
parent 8a41337e2d
commit ff962a6b16
29 changed files with 727 additions and 305 deletions

View file

@ -1,7 +1,6 @@
#include "PngReader.h"
#include "BinaryStream.h"
#include "Image.h"
#include "BinaryStream.h"
#include <iostream>
#include <sstream>
@ -11,120 +10,135 @@ PngReader::~PngReader()
}
void PngReader::setPath(const std::string& path)
void PngReader::setPath(const Path& path)
{
mPath = path;
mPath = path;
}
bool PngReader::checkSignature()
{
const int highBitCheck = 0x89;
const auto firstPos = mFile->GetInHandle()->get();
if (firstPos != highBitCheck)
{
return false;
}
const int highBitCheck = 0x89;
const auto firstPos = mFile->GetInHandle()->get();
if (firstPos != highBitCheck)
{
return false;
}
std::string fileType;
BinaryStream::getNextString(mFile->GetInHandle(), fileType, 3);
if (fileType != "PNG")
{
return false;
}
std::string fileType;
BinaryStream::getNextString(mFile->GetInHandle(), fileType, 3);
if (fileType != "PNG")
{
return false;
}
std::vector<char> sequence{13, 10, 26, 10};
for (auto c : sequence)
{
if (mFile->GetInHandle()->get() != c)
{
return false;
}
}
std::vector<char> sequence{13, 10, 26, 10};
for (auto c : sequence)
{
if (mFile->GetInHandle()->get() != c)
{
return false;
}
}
mCurrentOffset += 8;
return true;
mCurrentOffset += 8;
return true;
}
bool PngReader::readChunk()
{
unsigned length = *BinaryStream::getNextDWord(mFile->GetInHandle());
unsigned length = *BinaryStream::getNextDWord(mFile->GetInHandle());
std::string chunkType;
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4);
mCurrentOffset += 8;
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")
{
parseHeader();
}
else if(chunkType == "IEND")
{
lastChunk = true;
}
else
{
for(unsigned idx=0;idx<length;idx++)
{
mFile->GetInHandle()->get();
}
}
std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
bool lastChunk = false;
if (chunkType == "IHDR")
{
readHeaderChunk();
}
else if(chunkType == "IEND")
{
lastChunk = true;
}
else if(chunkType == "IDAT")
{
readIDATChunk(length);
}
else
{
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;
mCurrentOffset += 4;
return !lastChunk;
}
void PngReader::parseHeader()
void PngReader::readIDATChunk(unsigned length)
{
mIHDRChunk.width = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.height = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.bitDepth = mFile->GetInHandle()->get();
mIHDRChunk.colorType = mFile->GetInHandle()->get();
mIHDRChunk.compressionMethod = mFile->GetInHandle()->get();
mIHDRChunk.filterMethod = mFile->GetInHandle()->get();
mIHDRChunk.interlaceMethod = mFile->GetInHandle()->get();
if (mAwaitingDataBlock)
{
mImageData.setCompressionMethod(mFile->readNextByte());
mImageData.setExtraFlags(mFile->readNextByte());
mImageData.setDataSize(length-2);
for(unsigned idx=0; idx<length-2; idx++)
{
mImageData.setByte(idx, mFile->readNextByte());
}
mAwaitingDataBlock = false;
}
else
{
for(unsigned idx=0; idx<length; idx++)
{
mImageData.setByte(idx, mFile->readNextByte());
}
}
}
mCurrentOffset += 13;
void PngReader::readHeaderChunk()
{
mIHDRChunk.width = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.height = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.bitDepth = mFile->GetInHandle()->get();
mIHDRChunk.colorType = mFile->GetInHandle()->get();
mIHDRChunk.compressionMethod = mFile->GetInHandle()->get();
mIHDRChunk.filterMethod = mFile->GetInHandle()->get();
mIHDRChunk.interlaceMethod = mFile->GetInHandle()->get();
logHeader();
mCurrentOffset += 13;
logHeader();
}
void PngReader::logHeader()
{
std::stringstream sstr;
sstr << "IHDR\n";
sstr << "width: " << mIHDRChunk.width << "\n";
sstr << "height: " << mIHDRChunk.height << "\n";
sstr << "bitDepth: " << (int)mIHDRChunk.bitDepth << "\n";
sstr << "colorType: " << (int)mIHDRChunk.colorType << "\n";
sstr << "compressionMethod: " << (int)mIHDRChunk.compressionMethod << "\n";
sstr << "filterMethod: " << (int)mIHDRChunk.filterMethod << "\n";
sstr << "interlaceMethod: " << (int)mIHDRChunk.interlaceMethod << "\n";
sstr << "************\n";
std::cout << sstr.str() << std::endl;
std::cout << "IHDR\n" << mIHDRChunk.toString() << "*************\n";
}
std::unique_ptr<Image<unsigned char> > PngReader::read()
{
auto image = std::make_unique<Image<unsigned char> >(5, 5);
auto image = std::make_unique<Image<unsigned char> >(5, 5);
mFile = std::make_unique<File>(mPath);
mFile->Open(true);
if (!checkSignature())
{
std::cout << "Signature check failed" << std::endl;
return image;
std::cout << "Signature check failed" << std::endl;
return image;
}
while(readChunk())
{
}
return std::move(image);
mImageData.processData();
return std::move(image);
}