#include "fpl_Compression.h"
#include "fpl_EsriHuffman.h"
#include <assert.h>
#include <cmath>
#include <cstring>
#include <climits>
USING_NAMESPACE_LERC
static const bool use_esri_huffman = true;
static const bool use_rle = true;
size_t fpl_Compression::extract_buffer(const char* data, size_t size, size_t uncompressed_size, char** output)
{
if (use_esri_huffman)
{
size_t expected_size = uncompressed_size;
bool ret = fpl_EsriHuffman::DecodeHuffman((const unsigned char*)data, size, expected_size, (unsigned char**)output);
assert(ret);
return uncompressed_size;
}
assert(0);
return 0;
}
size_t fpl_Compression::compress_buffer(const char* data, size_t size, char** output, bool fast)
{
if (use_esri_huffman)
{
if (fast && !output)
{
return getEntropySize((unsigned char*)data, size); }
assert(size > 0);
int ret = fpl_EsriHuffman::EncodeHuffman(data, size, (unsigned char**)output, use_rle);
if (ret < 0)
{
#ifdef _DEBUG
#endif
return (size_t)UINT_MAX + 1;
}
return ret;
}
return 0;
}
long fpl_Compression::getEntropySize(const unsigned char* ptr, const size_t size)
{
unsigned long table[256];
memset(table, 0, sizeof(table));
int total_count = 0;
for (size_t i = 0; i < size; i += PRIME_MULT)
{
table[ptr[i]]++;
total_count++;
}
double total_bits = 0;
for (size_t i = 0; i < 256; i++)
{
if (table[i] == 0) continue;
double p = (double)total_count / table[i];
double bits = log2(p);
total_bits += (bits * table[i]);
}
return (long)((total_bits + 7) / 8);
}