Aging_MouthReplace / dlibs /dlib /compress_stream /compress_stream_kernel_1.h
AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
raw
history blame
7.27 kB
// Copyright (C) 2003 Davis E. King ([email protected])
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_COMPRESS_STREAM_KERNEl_1_
#define DLIB_COMPRESS_STREAM_KERNEl_1_
#include "../algs.h"
#include <iostream>
#include <streambuf>
#include <cstdio>
#include "compress_stream_kernel_abstract.h"
namespace dlib
{
template <
typename fce,
typename fcd,
typename crc32
>
class compress_stream_kernel_1
{
/*!
REQUIREMENTS ON fce
is an implementation of entropy_encoder_model/entropy_encoder_model_kernel_abstract.h
the alphabet_size of fce must be 257.
fce and fcd share the same kernel number.
REQUIREMENTS ON fcd
is an implementation of entropy_decoder_model/entropy_decoder_model_kernel_abstract.h
the alphabet_size of fcd must be 257.
fce and fcd share the same kernel number.
REQUIREMENTS ON crc32
is an implementation of crc32/crc32_kernel_abstract.h
INITIAL VALUE
this object has no state
CONVENTION
this object has no state
!*/
const static unsigned long eof_symbol = 256;
public:
class decompression_error : public dlib::error
{
public:
decompression_error(
const char* i
) :
dlib::error(std::string(i))
{}
decompression_error(
const std::string& i
) :
dlib::error(i)
{}
};
compress_stream_kernel_1 (
)
{}
~compress_stream_kernel_1 (
)
{}
void compress (
std::istream& in,
std::ostream& out
) const;
void decompress (
std::istream& in,
std::ostream& out
) const;
private:
// restricted functions
compress_stream_kernel_1(compress_stream_kernel_1&); // copy constructor
compress_stream_kernel_1& operator=(compress_stream_kernel_1&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename fce,
typename fcd,
typename crc32
>
void compress_stream_kernel_1<fce,fcd,crc32>::
compress (
std::istream& in_,
std::ostream& out_
) const
{
std::streambuf::int_type temp;
std::streambuf& in = *in_.rdbuf();
typename fce::entropy_encoder_type coder;
coder.set_stream(out_);
fce model(coder);
crc32 crc;
unsigned long count = 0;
while (true)
{
// write out a known value every 20000 symbols
if (count == 20000)
{
count = 0;
coder.encode(1500,1501,8000);
}
++count;
// get the next character
temp = in.sbumpc();
// if we have hit EOF then encode the marker symbol
if (temp != EOF)
{
// encode the symbol
model.encode(static_cast<unsigned long>(temp));
crc.add(static_cast<unsigned char>(temp));
continue;
}
else
{
model.encode(eof_symbol);
// now write the checksum
unsigned long checksum = crc.get_checksum();
unsigned char byte1 = static_cast<unsigned char>((checksum>>24)&0xFF);
unsigned char byte2 = static_cast<unsigned char>((checksum>>16)&0xFF);
unsigned char byte3 = static_cast<unsigned char>((checksum>>8)&0xFF);
unsigned char byte4 = static_cast<unsigned char>((checksum)&0xFF);
model.encode(byte1);
model.encode(byte2);
model.encode(byte3);
model.encode(byte4);
break;
}
}
}
// ----------------------------------------------------------------------------------------
template <
typename fce,
typename fcd,
typename crc32
>
void compress_stream_kernel_1<fce,fcd,crc32>::
decompress (
std::istream& in_,
std::ostream& out_
) const
{
std::streambuf& out = *out_.rdbuf();
typename fcd::entropy_decoder_type coder;
coder.set_stream(in_);
fcd model(coder);
unsigned long symbol;
unsigned long count = 0;
crc32 crc;
// decode until we hit the marker symbol
while (true)
{
// make sure this is the value we expect
if (count == 20000)
{
if (coder.get_target(8000) != 1500)
{
throw decompression_error("Error detected in compressed data stream.");
}
count = 0;
coder.decode(1500,1501);
}
++count;
// decode the next symbol
model.decode(symbol);
if (symbol != eof_symbol)
{
crc.add(static_cast<unsigned char>(symbol));
// write this symbol to out
if (out.sputc(static_cast<char>(symbol)) != static_cast<int>(symbol))
{
throw std::ios::failure("error occurred in compress_stream_kernel_1::decompress");
}
continue;
}
else
{
// we read eof from the encoded data. now we just have to check the checksum and we are done.
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
model.decode(symbol); byte1 = static_cast<unsigned char>(symbol);
model.decode(symbol); byte2 = static_cast<unsigned char>(symbol);
model.decode(symbol); byte3 = static_cast<unsigned char>(symbol);
model.decode(symbol); byte4 = static_cast<unsigned char>(symbol);
unsigned long checksum = byte1;
checksum <<= 8;
checksum |= byte2;
checksum <<= 8;
checksum |= byte3;
checksum <<= 8;
checksum |= byte4;
if (checksum != crc.get_checksum())
throw decompression_error("Error detected in compressed data stream.");
break;
}
} // while (true)
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_COMPRESS_STREAM_KERNEl_1_