|
|
|
|
|
#ifndef DLIB_ENTROPY_ENCODER_KERNEL_2_CPp_ |
|
#define DLIB_ENTROPY_ENCODER_KERNEL_2_CPp_ |
|
#include "entropy_encoder_kernel_2.h" |
|
#include <iostream> |
|
#include <streambuf> |
|
|
|
namespace dlib |
|
{ |
|
|
|
|
|
|
|
|
|
entropy_encoder_kernel_2:: |
|
entropy_encoder_kernel_2( |
|
) : |
|
initial_low(0x00000001), |
|
initial_high(0xffffffff), |
|
out(0), |
|
low(initial_low), |
|
high(initial_high) |
|
{ |
|
} |
|
|
|
|
|
|
|
entropy_encoder_kernel_2:: |
|
~entropy_encoder_kernel_2 ( |
|
) |
|
{ |
|
try { |
|
if (out != 0) |
|
{ |
|
flush(); |
|
} |
|
} catch (...) {} |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_2:: |
|
clear( |
|
) |
|
{ |
|
if (out != 0) |
|
{ |
|
flush(); |
|
} |
|
out = 0; |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_2:: |
|
set_stream ( |
|
std::ostream& out_ |
|
) |
|
{ |
|
if (out != 0) |
|
{ |
|
|
|
|
|
flush(); |
|
} |
|
|
|
out = &out_; |
|
streambuf = out_.rdbuf(); |
|
|
|
|
|
low = initial_low; |
|
high = initial_high; |
|
} |
|
|
|
|
|
|
|
bool entropy_encoder_kernel_2:: |
|
stream_is_set ( |
|
) const |
|
{ |
|
if (out != 0) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
|
|
|
|
std::ostream& entropy_encoder_kernel_2:: |
|
get_stream ( |
|
) const |
|
{ |
|
return *out; |
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_2:: |
|
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 ((high&0xFF000000) != (low&0xFF000000)) |
|
{ |
|
|
|
|
|
|
|
if ((high-low < 0x10000)) |
|
{ |
|
if (high-low > 0x1000) |
|
{ |
|
high>>=1; |
|
low>>=1; |
|
high = low = high+low; |
|
high += 0xFF; |
|
low -= 0xFF; |
|
} |
|
else |
|
{ |
|
high>>=1; |
|
low>>=1; |
|
high = low = high+low; |
|
} |
|
} |
|
else |
|
{ |
|
|
|
|
|
break; |
|
} |
|
|
|
} |
|
|
|
else |
|
{ |
|
|
|
unsigned char buf = static_cast<unsigned char>(low>>24); |
|
|
|
|
|
|
|
high <<= 8; |
|
low <<= 8; |
|
high |= 0xFF; |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (low == 0) |
|
low = 1; |
|
|
|
|
|
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0) |
|
{ |
|
throw std::ios_base::failure("error occurred in the entropy_encoder object"); |
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void entropy_encoder_kernel_2:: |
|
flush ( |
|
) |
|
{ |
|
|
|
|
|
|
|
|
|
unsigned char buf; |
|
|
|
|
|
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"); |
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
low = initial_low; |
|
high = initial_high; |
|
} |
|
|
|
|
|
|
|
} |
|
#endif |
|
|
|
|