Continue work on png writer.
This commit is contained in:
parent
9c8faa534b
commit
86bc0d89f6
19 changed files with 225 additions and 19 deletions
|
@ -17,6 +17,11 @@ public:
|
|||
|
||||
void writeByte(unsigned char data) override;
|
||||
|
||||
void writeBytes(const std::vector<unsigned char> data) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
Image<unsigned char>* mImage{nullptr};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "CyclicRedundancyChecker.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -15,15 +17,23 @@ namespace Png
|
|||
return {13, 10, 26, 10};
|
||||
}
|
||||
|
||||
inline std::string getName()
|
||||
{
|
||||
return "PNG";
|
||||
}
|
||||
|
||||
struct IHDRChunk
|
||||
{
|
||||
unsigned width{0};
|
||||
unsigned height{0};
|
||||
char bitDepth{0};
|
||||
char colorType{0};
|
||||
char compressionMethod{0};
|
||||
char filterMethod{0};
|
||||
char interlaceMethod{0};
|
||||
uint32_t width{0};
|
||||
uint32_t height{0};
|
||||
unsigned char bitDepth{0};
|
||||
unsigned char colorType{0};
|
||||
unsigned char compressionMethod{0};
|
||||
unsigned char filterMethod{0};
|
||||
unsigned char interlaceMethod{0};
|
||||
std::string name{"IHDR"};
|
||||
|
||||
std::vector<unsigned char> mData;
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
|
@ -37,6 +47,42 @@ namespace Png
|
|||
sstr << "interlaceMethod: " << (int)interlaceMethod << "\n";
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
uint32_t getLength() const
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
void updateData()
|
||||
{
|
||||
mData.clear();
|
||||
unsigned num_bytes = sizeof(uint32_t);
|
||||
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mData.push_back(ByteUtils::getByteN(width, idx));
|
||||
}
|
||||
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mData.push_back(ByteUtils::getByteN(height, idx));
|
||||
}
|
||||
mData.push_back(bitDepth);
|
||||
mData.push_back(colorType);
|
||||
mData.push_back(compressionMethod);
|
||||
mData.push_back(filterMethod);
|
||||
mData.push_back(interlaceMethod);
|
||||
}
|
||||
|
||||
uint32_t getCrc() const
|
||||
{
|
||||
CyclicRedundancyChecker crc_check;
|
||||
std::vector<unsigned char> char_data = StringUtils::toBytes(name);
|
||||
std::copy(mData.begin(), mData.end(), std::back_inserter(char_data));
|
||||
|
||||
auto result = crc_check.doCrc(char_data.data(), char_data.size());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -88,11 +88,11 @@ void PngReader::readIDATChunk(unsigned length)
|
|||
{
|
||||
if (mAwaitingDataBlock)
|
||||
{
|
||||
mEncoder->setCompressionMethod(mFile->readNextByte());
|
||||
mEncoder->setExtraFlags(mFile->readNextByte());
|
||||
mEncoder->setCompressionMethod(*mFile->readNextByte());
|
||||
mEncoder->setExtraFlags(*mFile->readNextByte());
|
||||
for(unsigned idx=0; idx<length-2; idx++)
|
||||
{
|
||||
mInputStream->writeByte(mFile->readNextByte());
|
||||
mInputStream->writeByte(*mFile->readNextByte());
|
||||
}
|
||||
mAwaitingDataBlock = false;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void PngReader::readIDATChunk(unsigned length)
|
|||
{
|
||||
for(unsigned idx=0; idx<length; idx++)
|
||||
{
|
||||
mInputStream->writeByte(mFile->readNextByte());
|
||||
mInputStream->writeByte(*mFile->readNextByte());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "Lz77Encoder.h"
|
||||
|
||||
#include "ByteUtils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
PngWriter::PngWriter()
|
||||
|
@ -34,15 +36,49 @@ void PngWriter::setPath(const Path& path)
|
|||
void PngWriter::writeSignature()
|
||||
{
|
||||
mOutStream->writeByte(Png::getHighBitCheck());
|
||||
for (auto byte : Png::getSignature())
|
||||
{
|
||||
mOutStream->writeByte(byte);
|
||||
}
|
||||
mOutStream->writeBytes(StringUtils::toBytes(Png::getName()));
|
||||
mOutStream->writeBytes(Png::getSignature());
|
||||
}
|
||||
|
||||
void PngWriter::writeHeader()
|
||||
{
|
||||
writeSignature();
|
||||
|
||||
Png::IHDRChunk header_chunk;
|
||||
header_chunk.width = mWorkingImage->getWidth();
|
||||
header_chunk.height = mWorkingImage->getHeight();
|
||||
header_chunk.bitDepth = mWorkingImage->getBitDepth();
|
||||
header_chunk.colorType = 6;
|
||||
|
||||
auto length = header_chunk.getLength();
|
||||
auto crc = header_chunk.getCrc();
|
||||
|
||||
unsigned num_bytes = sizeof(uint32_t);
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mOutStream->writeByte(ByteUtils::getByteN(length, idx));
|
||||
}
|
||||
mOutStream->writeBytes(StringUtils::toBytes(header_chunk.name));
|
||||
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mOutStream->writeByte(ByteUtils::getByteN(header_chunk.width, idx));
|
||||
}
|
||||
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mOutStream->writeByte(ByteUtils::getByteN(header_chunk.height, idx));
|
||||
}
|
||||
mOutStream->writeByte(header_chunk.bitDepth);
|
||||
mOutStream->writeByte(header_chunk.colorType);
|
||||
mOutStream->writeByte(header_chunk.compressionMethod);
|
||||
mOutStream->writeByte(header_chunk.filterMethod);
|
||||
mOutStream->writeByte(header_chunk.interlaceMethod);
|
||||
|
||||
for(unsigned idx=0; idx<num_bytes;idx++)
|
||||
{
|
||||
mOutStream->writeByte(ByteUtils::getByteN(crc, idx));
|
||||
}
|
||||
}
|
||||
|
||||
void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
|
||||
|
@ -50,6 +86,7 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
|
|||
if (!mPath.empty())
|
||||
{
|
||||
mWorkingFile = std::make_unique<File>(mPath);
|
||||
mWorkingFile->SetAccessMode(File::AccessMode::Write);
|
||||
mWorkingFile->Open(true);
|
||||
mOutStream = std::make_unique<OutputBitStream>(mWorkingFile->GetOutHandle());
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ private:
|
|||
void writeSignature();
|
||||
void writeHeader();
|
||||
|
||||
//void writeIDatChunk();
|
||||
|
||||
Path mPath;
|
||||
Image<unsigned char>* mWorkingImage{nullptr};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue