Further compression and png work.

This commit is contained in:
James Grogan 2022-11-23 15:41:33 +00:00
parent 318b481ccc
commit 9c8faa534b
34 changed files with 1164 additions and 203 deletions

View file

@ -7,6 +7,7 @@ list(APPEND image_LIB_INCLUDES
Image.cpp
PngWriter.cpp
PngReader.cpp
ImageBitStream.cpp
)
list(APPEND image_LIBS core compression)

View file

@ -0,0 +1,29 @@
#include "ImageBitStream.h"
ImageBitStream::ImageBitStream(Image<unsigned char>* image)
: BitStream(),
mImage(image)
{
}
bool ImageBitStream::isFinished() const
{
return true;
}
std::vector<unsigned char> ImageBitStream::peekNextNBytes(unsigned n) const
{
return {};
}
std::optional<unsigned char> ImageBitStream::readNextByte()
{
return std::nullopt;
}
void ImageBitStream::writeByte(unsigned char data)
{
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "BitStream.h"
#include "Image.h"
class ImageBitStream : public BitStream
{
public:
ImageBitStream(Image<unsigned char>* image);
bool isFinished() const override;
std::vector<unsigned char> peekNextNBytes(unsigned n) const override;
std::optional<unsigned char> readNextByte() override;
void writeByte(unsigned char data) override;
private:
Image<unsigned char>* mImage{nullptr};
};

View file

@ -3,9 +3,18 @@
#include <string>
#include <sstream>
namespace Png
{
inline unsigned char getHighBitCheck()
{
return 0x89;
}
inline std::vector<unsigned char> getSignature()
{
return {13, 10, 26, 10};
}
struct IHDRChunk
{
unsigned width{0};

View file

@ -1,6 +1,10 @@
#include "PngReader.h"
#include "BinaryStream.h"
#include "BitStream.h"
#include "BufferBitStream.h"
#include "ZlibEncoder.h"
#include <iostream>
#include <sstream>
@ -84,12 +88,11 @@ void PngReader::readIDATChunk(unsigned length)
{
if (mAwaitingDataBlock)
{
mImageData.setCompressionMethod(mFile->readNextByte());
mImageData.setExtraFlags(mFile->readNextByte());
mImageData.setDataSize(length-2);
mEncoder->setCompressionMethod(mFile->readNextByte());
mEncoder->setExtraFlags(mFile->readNextByte());
for(unsigned idx=0; idx<length-2; idx++)
{
mImageData.setByte(idx, mFile->readNextByte());
mInputStream->writeByte(mFile->readNextByte());
}
mAwaitingDataBlock = false;
}
@ -97,7 +100,7 @@ void PngReader::readIDATChunk(unsigned length)
{
for(unsigned idx=0; idx<length; idx++)
{
mImageData.setByte(idx, mFile->readNextByte());
mInputStream->writeByte(mFile->readNextByte());
}
}
}
@ -135,10 +138,14 @@ std::unique_ptr<Image<unsigned char> > PngReader::read()
return image;
}
mInputStream = std::make_unique<BufferBitStream>();
mOutputStream = std::make_unique<BufferBitStream>();
mEncoder = std::make_unique<ZlibEncoder>(mInputStream.get(), mOutputStream.get());
while(readChunk())
{
}
mImageData.processData();
mEncoder->decode();
return std::move(image);
}

View file

@ -3,12 +3,15 @@
#include "File.h"
#include "Image.h"
#include "PngElements.h"
#include "ZlibData.h"
#include "ZlibEncoder.h"
#include <string>
#include <memory>
#include <filesystem>
class BitStream;
class ZlibEncoder;
using Path = std::filesystem::path;
class PngReader
@ -37,6 +40,8 @@ private:
std::unique_ptr<File> mFile;
Path mPath;
ZlibData mImageData;
std::unique_ptr<ZlibEncoder> mEncoder;
std::unique_ptr<BitStream> mInputStream;
std::unique_ptr<BitStream> mOutputStream;
bool mAwaitingDataBlock{true};
};

View file

@ -1,6 +1,13 @@
#include "PngWriter.h"
#include "PngElements.h"
#include "Image.h"
#include "File.h"
#include "BufferBitStream.h"
#include "OutputBitStream.h"
#include "ImageBitStream.h"
#include "Lz77Encoder.h"
#include <stdio.h>
@ -9,6 +16,11 @@ PngWriter::PngWriter()
}
PngWriter::~PngWriter()
{
}
std::unique_ptr<PngWriter> PngWriter::Create()
{
return std::make_unique<PngWriter>();
@ -19,8 +31,40 @@ void PngWriter::setPath(const Path& path)
mPath = path;
}
void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image) const
void PngWriter::writeSignature()
{
mOutStream->writeByte(Png::getHighBitCheck());
for (auto byte : Png::getSignature())
{
mOutStream->writeByte(byte);
}
}
void PngWriter::writeHeader()
{
writeSignature();
}
void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image)
{
if (!mPath.empty())
{
mWorkingFile = std::make_unique<File>(mPath);
mWorkingFile->Open(true);
mOutStream = std::make_unique<OutputBitStream>(mWorkingFile->GetOutHandle());
}
else
{
mOutStream = std::make_unique<BufferBitStream>();
}
mWorkingImage = image.get();
mInStream = std::make_unique<ImageBitStream>(image.get());
writeHeader();
//mImpl->write(image);
//auto fp = fopen(mPath.c_str(), "wb");
@ -76,4 +120,9 @@ void PngWriter::write(const std::unique_ptr<Image<unsigned char> >& image) const
//fclose(fp);
//return;
if (mWorkingFile)
{
mWorkingFile->Close();
}
}

View file

@ -8,19 +8,31 @@
using Path = std::filesystem::path;
class BitStream;
class File;
class PngWriter
{
public:
PngWriter();
~PngWriter();
static std::unique_ptr<PngWriter> Create();
void setPath(const Path& path);
void write(const std::unique_ptr<Image<unsigned char> >& image) const;
void write(const std::unique_ptr<Image<unsigned char> >& image);
private:
void writeSignature();
void writeHeader();
Path mPath;
Image<unsigned char>* mWorkingImage{nullptr};
std::unique_ptr<BitStream> mInStream;
std::unique_ptr<BitStream> mOutStream;
std::unique_ptr<File> mWorkingFile;
};
using PngWriterPtr = std::unique_ptr<PngWriter>;