stuff-from-scratch/src/base/compression/deflate/DeflateEncoder.cpp
2024-01-02 16:14:23 +00:00

88 lines
2.2 KiB
C++

#include "DeflateEncoder.h"
#include "BitStream.h"
#include "Bits.h"
#include "DeflateBlock.h"
#include "BufferBitStream.h"
#include <iostream>
DeflateEncoder::DeflateEncoder(BitStream* inputStream, BitStream* outputStream)
: AbstractEncoder(inputStream, outputStream)
{
}
DeflateEncoder::~DeflateEncoder()
{
}
bool DeflateEncoder::encode()
{
uint16_t count = 0;
BufferBitStream stream;
Ptr<DeflateBlock> working_block = std::make_unique<DeflateBlock>(&stream, mOutputStream);
working_block->setCompressionMethod(mCompressionMethod);
if (mChecksumCalculators.size() > 0)
{
//std::cout << "Setting checksum calculator " << std::endl;
mOutputStream->setChecksumCalculator(mChecksumCalculators[0]);
}
while(true)
{
if (count == mMaxBlockSize)
{
//std::cout << working_block->getMetaData();
working_block->write(count);
working_block = std::make_unique<DeflateBlock>(&stream, mOutputStream);
working_block->setCompressionMethod(mCompressionMethod);
stream.reset();
}
if (auto byte = mInputStream->readNextByte())
{
//std::cout << "Adding byte " << Bits::toString(*byte) << " to deflate block input" << std::endl;
stream.writeByte(*byte);
}
else
{
if (const auto& remaining_bits = mInputStream->getRemainingBits(); remaining_bits.second > 0)
{
stream.writeNBits(remaining_bits.first, remaining_bits.second);
}
stream.resetOffsets();
working_block->setIsFinalBlock(true);
//std::cout << working_block->getMetaData();
working_block->write(count);
break;
}
count++;
}
mOutputStream->flushRemainingBits();
mOutputStream->clearChecksumCalculator();
return true;
}
bool DeflateEncoder::decode()
{
auto working_block = std::make_unique<DeflateBlock>(mInputStream, mOutputStream);
working_block->read();
//std::cout << working_block->getMetaData() << std::endl;
DeflateBlock* raw_block = working_block.get();
while(!raw_block->isFinalBlock())
{
break;
}
return true;
}