|
|
|
|
|
#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 |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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: |
|
|
|
|
|
compress_stream_kernel_1(compress_stream_kernel_1&); |
|
compress_stream_kernel_1& operator=(compress_stream_kernel_1&); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) |
|
{ |
|
|
|
if (count == 20000) |
|
{ |
|
count = 0; |
|
coder.encode(1500,1501,8000); |
|
} |
|
++count; |
|
|
|
|
|
temp = in.sbumpc(); |
|
|
|
|
|
if (temp != EOF) |
|
{ |
|
|
|
model.encode(static_cast<unsigned long>(temp)); |
|
crc.add(static_cast<unsigned char>(temp)); |
|
continue; |
|
} |
|
else |
|
{ |
|
model.encode(eof_symbol); |
|
|
|
|
|
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; |
|
|
|
|
|
while (true) |
|
{ |
|
|
|
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; |
|
|
|
|
|
model.decode(symbol); |
|
if (symbol != eof_symbol) |
|
{ |
|
crc.add(static_cast<unsigned char>(symbol)); |
|
|
|
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 |
|
{ |
|
|
|
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; |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|