|
|
|
|
|
#ifndef DLIB_ENTROPY_ENCODER_KERNEL_1_CPp_ |
|
#define DLIB_ENTROPY_ENCODER_KERNEL_1_CPp_ |
|
#include "entropy_encoder_kernel_1.h" |
|
#include <iostream> |
|
#include <streambuf> |
|
|
|
namespace dlib |
|
{ |
|
|
|
|
|
|
|
|
|
entropy_encoder_kernel_1:: |
|
entropy_encoder_kernel_1( |
|
) : |
|
initial_low(0x00000001), |
|
initial_high(0xffffffff), |
|
out(0), |
|
low(initial_low), |
|
high(initial_high), |
|
buf(0), |
|
buf_used(0) |
|
{ |
|
} |
|
|
|
|
|
|
|
entropy_encoder_kernel_1:: |
|
~entropy_encoder_kernel_1 ( |
|
) |
|
{ |
|
try { |
|
if (out != 0) |
|
{ |
|
flush(); |
|
} |
|
} catch (...) {} |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_1:: |
|
clear( |
|
) |
|
{ |
|
if (out != 0) |
|
{ |
|
flush(); |
|
} |
|
out = 0; |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_1:: |
|
set_stream ( |
|
std::ostream& out_ |
|
) |
|
{ |
|
if (out != 0) |
|
{ |
|
|
|
|
|
flush(); |
|
} |
|
|
|
out = &out_; |
|
streambuf = out_.rdbuf(); |
|
|
|
|
|
buf_used = 0; |
|
buf = 0; |
|
low = initial_low; |
|
high = initial_high; |
|
} |
|
|
|
|
|
|
|
bool entropy_encoder_kernel_1:: |
|
stream_is_set ( |
|
) const |
|
{ |
|
if (out != 0) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
|
|
|
|
std::ostream& entropy_encoder_kernel_1:: |
|
get_stream ( |
|
) const |
|
{ |
|
return *out; |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_1:: |
|
encode ( |
|
uint32 low_count, |
|
uint32 high_count, |
|
uint32 total |
|
) |
|
{ |
|
|
|
|
|
uint32 r = (high-low+1)/total; |
|
|
|
|
|
|
|
high = low + r*high_count-1; |
|
low = low + r*low_count; |
|
|
|
|
|
while (true) |
|
{ |
|
|
|
|
|
if ( low >= 0x80000000 || high < 0x80000000) |
|
{ |
|
|
|
if (buf_used == 8) |
|
{ |
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0) |
|
{ |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
} |
|
buf = 0; |
|
buf_used = 0; |
|
} |
|
|
|
|
|
|
|
buf <<= 1; |
|
++buf_used; |
|
if (low&0x80000000) |
|
buf |= 0x1; |
|
|
|
|
|
low <<= 1; |
|
high <<= 1; |
|
high |= 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (low == 0) |
|
low = 1; |
|
} |
|
|
|
|
|
else if (high-low < 0x10000) |
|
{ |
|
if (high == 0x80000000) |
|
high = 0x7fffffff; |
|
else |
|
low = 0x80000000; |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_1:: |
|
flush ( |
|
) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
if (buf_used != 8) |
|
{ |
|
buf <<= (8-buf_used); |
|
buf |= static_cast<unsigned char>(low>>(24+buf_used)); |
|
low <<= (8-buf_used); |
|
} |
|
|
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1) == 0) |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
|
|
|
|
|
|
buf = static_cast<unsigned char>((low >> 24)&0xFF); |
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1) == 0) |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
|
|
|
|
|
|
|
|
buf = static_cast<unsigned char>((low >> 16)&0xFF); |
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0) |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
|
|
|
|
|
|
buf = static_cast<unsigned char>((low >> 8)&0xFF); |
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0) |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
|
|
|
|
|
|
if (buf_used != 0) |
|
{ |
|
buf = static_cast<unsigned char>((low)&0xFF); |
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0) |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
} |
|
|
|
|
|
|
|
|
|
streambuf->pubsync(); |
|
|
|
|
|
|
|
buf_used = 0; |
|
buf = 0; |
|
low = initial_low; |
|
high = initial_high; |
|
} |
|
|
|
|
|
|
|
} |
|
#endif |
|
|
|
|