Aging_MouthReplace / dlibs /dlib /entropy_decoder /entropy_decoder_kernel_2.cpp
AshanGimhana's picture
Upload folder using huggingface_hub
9375c9a verified
// Copyright (C) 2004 Davis E. King ([email protected])
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_KERNEL_2_CPp_
#define DLIB_ENTROPY_DECODER_KERNEL_2_CPp_
#include "entropy_decoder_kernel_2.h"
#include <iostream>
#include <streambuf>
#include <sstream>
#include "../assert.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
entropy_decoder_kernel_2::
entropy_decoder_kernel_2(
) :
initial_low(0x00000001),
initial_high(0xffffffff),
in(0),
low(initial_low),
high(initial_high),
target(0x00000000),
r(0)
{
}
// ----------------------------------------------------------------------------------------
entropy_decoder_kernel_2::
~entropy_decoder_kernel_2 (
)
{
}
// ----------------------------------------------------------------------------------------
void entropy_decoder_kernel_2::
clear(
)
{
in = 0;
r = 0;
low = initial_low;
high = initial_high;
target = 0x00000000;
}
// ----------------------------------------------------------------------------------------
void entropy_decoder_kernel_2::
set_stream (
std::istream& in_
)
{
r = 0;
low = initial_low;
high = initial_high;
target = 0x00000000;
in = &in_;
streambuf = in_.rdbuf();
unsigned char ch;
streambuf->sgetn((char*)&ch,1);
target = ch;
target <<= 8;
if (streambuf->sgetn((char*)&ch,1))
target += ch;
target <<= 8;
if (streambuf->sgetn((char*)&ch,1))
target += ch;
target <<= 8;
if (streambuf->sgetn((char*)&ch,1))
target += ch;
}
// ----------------------------------------------------------------------------------------
bool entropy_decoder_kernel_2::
stream_is_set (
) const
{
if (in != 0)
return true;
else
return false;
}
// ----------------------------------------------------------------------------------------
std::istream& entropy_decoder_kernel_2::
get_stream (
) const
{
return *in;
}
// ----------------------------------------------------------------------------------------
void entropy_decoder_kernel_2::
decode (
uint32 low_count,
uint32 high_count
)
{
// note that we must subtract 1 to preserve the convention that
// high == the real upper range - 1
high = low + r*high_count - 1;
low = low + r*low_count;
r = 0;
while (true )
{
// if high and low don't have the same 8 high order bits
if ((high&0xFF000000) != (low&0xFF000000))
{
// if the distance between high and low is small and there aren't
// any bits we can roll off then force high and low to have common high
// order bits.
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
{
// there are no bits to roll off and high and low are not
// too close so just quit the loop
break;
}
}
// else if there are 8 bits we can roll off
else
{
unsigned char buf;
if (streambuf->sgetn(reinterpret_cast<char*>(&buf),1)==0)
{
// if there isn't anything else in the streambuffer then just
// make buf zero.
buf = 0;
}
// also roll off the bits in target
target <<= 8;
// roll off the bits
high <<= 8;
low <<= 8;
high |= 0xFF; // note that it is ok to add 0xFF to high here because
// of the convention that high == real upper range - 1.
// so that means that if we want to shift the upper range
// left by one then we must shift a one into high also
// since real upper range == high + 0.999999999...
// make sure low is never zero
if (low == 0)
low = 1;
// put the new bits into target
target |= static_cast<uint32>(buf);
}
} // while (true)
}
// ----------------------------------------------------------------------------------------
bool entropy_decoder_kernel_2::
get_target_called (
) const
{
return (r != 0);
}
// ----------------------------------------------------------------------------------------
uint32 entropy_decoder_kernel_2::
get_target (
uint32 total
)
{
// note that we must add one because of the convention that
// high == the real upper range minus 1
r = (high-low+1)/total;
uint32 temp = (target-low)/r;
if (temp < total)
return temp;
else
return total-1;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_DECODER_KERNEL_2_CPp_