#include "PngReader.h" #include "BinaryStream.h" #include "BitStream.h" #include "BufferBitStream.h" #include "ZlibEncoder.h" #include #include PngReader::~PngReader() { } void PngReader::setPath(const Path& path) { mPath = path; } bool PngReader::checkSignature() { 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::vector sequence{13, 10, 26, 10}; for (auto c : sequence) { if (mFile->GetInHandle()->get() != c) { return false; } } mCurrentOffset += 8; return true; } bool PngReader::readChunk() { unsigned length = *BinaryStream::getNextDWord(mFile->GetInHandle()); 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(); } else if(chunkType == "IEND") { lastChunk = true; } else if(chunkType == "IDAT") { readIDATChunk(length); } else { for(unsigned idx=0;idxGetInHandle()->get(); } } unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle()); mCurrentOffset += 4; return !lastChunk; } void PngReader::readIDATChunk(unsigned length) { if (mAwaitingDataBlock) { mEncoder->setCompressionMethod(*mFile->readNextByte()); mEncoder->setExtraFlags(*mFile->readNextByte()); for(unsigned idx=0; idxwriteByte(*mFile->readNextByte()); } mAwaitingDataBlock = false; } else { for(unsigned idx=0; idxwriteByte(*mFile->readNextByte()); } } } 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(); mCurrentOffset += 13; logHeader(); } void PngReader::logHeader() { std::cout << "IHDR\n" << mIHDRChunk.toString() << "*************\n"; } std::unique_ptr > PngReader::read() { auto image = std::make_unique >(5, 5); mFile = std::make_unique(mPath); mFile->Open(true); if (!checkSignature()) { std::cout << "Signature check failed" << std::endl; return image; } mInputStream = std::make_unique(); mOutputStream = std::make_unique(); mEncoder = std::make_unique(mInputStream.get(), mOutputStream.get()); while(readChunk()) { } mEncoder->decode(); return std::move(image); }