88 lines
2.2 KiB
C++
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;
|
|
}
|
|
|