Files
2023-03-23 11:29:36 +01:00

186 lines
6.7 KiB
C

#include "bg.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int versionNumber[4] = {BG_VER_MAJOR,BG_VER_MINOR,BG_VER_BUILD,BG_VER_REVISION};
//int BG_SIZE_TYPE = 8;
int dataEndianType = LITTLE_ENDIAN_DATA; //*endian type of the data read from disk
int sysEndianType; //*sysEndianType is actually set automatically.
//the confparams should be separate between compression and decopmression, in case of mutual-affection when calling compression/decompression alternatively
bg_params *confparams_cpr = NULL; //used for compression
bg_params *confparams_dec = NULL; //used for decompression
bg_exedata *exe_params = NULL;
int bgMode_libpressio = BITGROOM;
int errorControlMode_libpressio = BG_NSD;
int nsd_libpressio = 5;
int dsd_libpressio = 5;
#if 0
unsigned char *BG_compress(int dataType, void *data, size_t *outSize, size_t nbEle)
{
return BG_compress_args(dataType, data, outSize, confparams_cpr->bgMode, confparams_cpr->errorControlMode, confparams_cpr->NSD, confparams_cpr->DSD, nbEle);
}
#endif
unsigned char* BG_compress_args(int dataType, void *data, size_t *outSize, int bgMode, int errorControlMode, int nsd, int dsd, size_t nbEle, unsigned char *data_)
{
int dataTypeLen = dataType==BG_FLOAT?sizeof(float):sizeof(double);
size_t bufferSize = dataTypeLen*nbEle;
const double bit_per_dcm_dgt_prc=M_LN10/M_LN2; /* 3.32 [frc] Bits per decimal digit of precision */
//const double dcm_per_bit_dgt_prc=M_LN2/M_LN10; /* 0.301 [frc] Bits per decimal digit of precision */
const int bit_xpl_nbr_sgn_flt=23; /* [nbr] Bits 0-22 of SP significands are explicit. Bit 23 is implicitly 1. */
const int bit_xpl_nbr_sgn_dbl=53; /* [nbr] Bits 0-52 of DP significands are explicit. Bit 53 is implicitly 1. */
//const int ieee_xpn_fst_flt=127; /* [nbr] IEEE "exponent bias" = actual exponent minus stored exponent */
double prc_bnr_xct; /* [nbr] Binary digits of precision, exact */
int bit_xpl_nbr_sgn=int_CEWI; /* [nbr] Number of explicit bits in significand */
int bit_xpl_nbr_zro; /* [nbr] Number of explicit bits to zero */
long idx;
unsigned int *u32_ptr;
unsigned int msk_f32_u32_zro;
unsigned int msk_f32_u32_one;
//unsigned int msk_f32_u32_hshv;
unsigned long long *u64_ptr;
unsigned long long msk_f64_u64_zro;
unsigned long long msk_f64_u64_one;
//unsigned long int msk_f64_u64_hshv;
unsigned short prc_bnr_ceil; /* [nbr] Exact binary digits of precision rounded-up */
unsigned short prc_bnr_xpl_rqr; /* [nbr] Explicitly represented binary digits required to retain */
if(errorControlMode == BG_NSD && (nsd < 0 || nsd >16))
{
printf("Error: wrong nsd input\n");
return NULL;
}
/* How many bits to preserve? */
prc_bnr_xct=nsd*bit_per_dcm_dgt_prc;
/* Be conservative, round upwards */
prc_bnr_ceil=(unsigned short)ceil(prc_bnr_xct);
/* First bit is implicit not explicit but corner cases prevent our taking advantage of this */
//prc_bnr_xpl_rqr=prc_bnr_ceil-1;
//prc_bnr_xpl_rqr=prc_bnr_ceil;
prc_bnr_xpl_rqr=prc_bnr_ceil+1;
//unsigned char* data_ = (unsigned char*)malloc(bufferSize);
memcpy(data_, data, bufferSize);
if(dataType == BG_DOUBLE) prc_bnr_xpl_rqr++; /* Seems necessary for double-precision ppc=array(1.234567,1.0e-6,$dmn) */
if(!(dataType == BG_FLOAT && prc_bnr_xpl_rqr >= bit_xpl_nbr_sgn_flt) || (dataType == BG_DOUBLE && prc_bnr_xpl_rqr >= bit_xpl_nbr_sgn_dbl)) //required # bits is greater than the full length of bits
{
if(dataType==BG_FLOAT)
{
bit_xpl_nbr_sgn=bit_xpl_nbr_sgn_flt;
bit_xpl_nbr_zro=bit_xpl_nbr_sgn-prc_bnr_xpl_rqr;
if(bit_xpl_nbr_zro > bit_xpl_nbr_sgn-NCO_PPC_BIT_XPL_NBR_MIN)
{
printf("Error: bit_xpl_nbr_zro > bit_xpl_nbr_sgn-NCO_PPC_BIT_XPL_NBR_MIN\n");
return NULL;
}
u32_ptr = (unsigned int*)data_;
/* Create mask */
msk_f32_u32_zro=0u; /* Zero all bits */
msk_f32_u32_zro=~msk_f32_u32_zro; /* Turn all bits to ones */
/* Bit Shave mask for AND: Left shift zeros into bits to be rounded, leave ones in untouched bits */
msk_f32_u32_zro <<= bit_xpl_nbr_zro;
/* Bit Set mask for OR: Put ones into bits to be set, zeros in untouched bits */
msk_f32_u32_one=~msk_f32_u32_zro;
//msk_f32_u32_hshv=msk_f32_u32_one & (msk_f32_u32_zro >> 1); /* Set one bit: the MSB of LSBs */
switch(bgMode)
{
case BITGROOM:
for(idx=0L;idx<nbEle;idx+=2L) u32_ptr[idx]&=msk_f32_u32_zro;
for(idx=1L;idx<nbEle;idx+=2L)
if(u32_ptr[idx] != 0U) /* Never quantize upwards floating point values of zero */
u32_ptr[idx]|=msk_f32_u32_one;
break;
case BITSHAVE:
for(idx=0L;idx<nbEle;idx++) u32_ptr[idx]&=msk_f32_u32_zro;
break;
case BITSET:
for(idx=0L;idx<nbEle;idx++)
if(u32_ptr[idx] != 0U) /* Never quantize upwards floating point values of zero */
u32_ptr[idx]|=msk_f32_u32_one;
break;
}
}
else //BG_DOUBLE
{
bit_xpl_nbr_sgn=bit_xpl_nbr_sgn_dbl;
bit_xpl_nbr_zro=bit_xpl_nbr_sgn-prc_bnr_xpl_rqr;
if(bit_xpl_nbr_zro > bit_xpl_nbr_sgn-NCO_PPC_BIT_XPL_NBR_MIN)
{
printf("Error: bit_xpl_nbr_zro > bit_xpl_nbr_sgn-NCO_PPC_BIT_XPL_NBR_MIN\n");
return NULL;
}
u64_ptr=(unsigned long int*)data_;
/* Create mask */
msk_f64_u64_zro=0ul; /* Zero all bits */
msk_f64_u64_zro=~msk_f64_u64_zro; /* Turn all bits to ones */
/* Bit Shave mask for AND: Left shift zeros into bits to be rounded, leave ones in untouched bits */
msk_f64_u64_zro <<= bit_xpl_nbr_zro;
/* Bit Set mask for OR: Put ones into bits to be set, zeros in untouched bits */
msk_f64_u64_one=~msk_f64_u64_zro;
//msk_f64_u64_hshv=msk_f64_u64_one & (msk_f64_u64_zro >> 1); /* Set one bit: the MSB of LSBs */
switch(bgMode)
{
case BITGROOM:
for(idx=0L;idx<nbEle;idx+=2L) u64_ptr[idx]&=msk_f64_u64_zro;
for(idx=1L;idx<nbEle;idx+=2L)
if(u64_ptr[idx] != 0UL) /* Never quantize upwards floating point values of zero */
u64_ptr[idx]|=msk_f64_u64_one;
break;
case BITSHAVE:
for(idx=0L;idx<nbEle;idx++) u64_ptr[idx]&=msk_f64_u64_zro;
break;
case BITSET:
for(idx=0L;idx<nbEle;idx++)
if(u64_ptr[idx] != 0UL) /* Never quantize upwards floating point values of zero */
u64_ptr[idx]|=msk_f64_u64_one;
break;
}
}
}
//perform DEFLATE algorithm by Zlib
//unsigned char* outBytes = NULL;
//*outSize = zlib_compress5(data_, bufferSize, &outBytes, 1);
//free(data_);
return data_; //outBytes;
}
#if 0
void *BG_decompress(int dataType, unsigned char *bytes, size_t byteLength, size_t nbEle)
{
if(dataType==BG_FLOAT)
{
unsigned char* decompressedData;
zlib_uncompress5(bytes, byteLength, &decompressedData, nbEle*sizeof(float));
return decompressedData;
}
else //BG_DOUBLE
{
unsigned char* decompressedData;
zlib_uncompress5(bytes, byteLength, &decompressedData, nbEle*sizeof(double));
return decompressedData;
}
}
#endif