41 return *((
char*)&(
ONE)) == 1;
54 unsigned char *fp = (
unsigned char*)&fixedPoint;
63 const unsigned char *data
67 unsigned char *fp = (
unsigned char*)&fixedPoint;
92 unsigned int mask = 0xf0000000;
93 unsigned int init = x & mask;
105 for (i=l; i<8; i++) {
106 res[1+i-l] =
static_cast<unsigned char>( x >> (4*(i-l)) );
108 *res_length += 1+8-l;
110 }
else if (init == mask) {
112 for (i=0; i<8; i++) {
120 for (i=l; i<8; i++) {
121 res[1+i-l] =
static_cast<unsigned char>( x >> (4*(i-l)) );
123 *res_length += 1+8-l;
127 for (i=0; i<8; i++) {
128 res[1+i] =
static_cast<unsigned char>( x >> (4*i) );
152 const unsigned char *data,
159 unsigned int mask, m;
168 head = data[*di] >> 4;
170 head = data[*di] & 0xf;
182 for (i=0; i<n; i++) {
192 if (*di + ((8 - n) - (1 - *half)) / 2 >= max_di) {
193 throw "[MSNumpress::decodeInt] Corrupt input data! ";
196 for (i=n; i<8; i++) {
200 hb = data[*di] & 0xf;
203 *res = *res | (
static_cast<unsigned int>(hb) << ((i-n)*4));
218 if (dataSize < 3)
return 0;
223 double maxFP = 0.5 / mass_acc;
229 if (maxFP > maxFP_overflow)
return -1;
253 if (dataSize == 0)
return 0;
254 if (dataSize == 1)
return floor(0x7FFFFFFFl / data[0]);
255 double maxDouble = max(data[0], data[1]);
259 for (
size_t i=2; i<dataSize; i++) {
260 extrapol = data[i-1] + (data[i-1] - data[i-2]);
261 diff = data[i] - extrapol;
262 maxDouble = max(maxDouble, ceil(abs(diff)+1));
265 return floor(0x7FFFFFFFl / maxDouble);
273 unsigned char *result,
278 unsigned char halfBytes[10];
279 size_t halfByteCount;
288 if (dataSize == 0)
return 8;
290 ints[1] =
static_cast<long long>(data[0] * fixedPoint + 0.5);
291 for (i=0; i<4; i++) {
292 result[8+i] = (ints[1] >> (i*8)) & 0xff;
295 if (dataSize == 1)
return 12;
297 ints[2] =
static_cast<long long>(data[1] * fixedPoint + 0.5);
298 for (i=0; i<4; i++) {
299 result[12+i] = (ints[2] >> (i*8)) & 0xff;
305 for (i=2; i<dataSize; i++) {
309 data[i] * fixedPoint + 0.5 > LLONG_MAX ) {
310 throw "[MSNumpress::encodeLinear] Next number overflows LLONG_MAX.";
313 ints[2] =
static_cast<long long>(data[i] * fixedPoint + 0.5);
314 extrapol = ints[1] + (ints[1] - ints[0]);
317 ( ints[2] - extrapol > INT_MAX
318 || ints[2] - extrapol < INT_MIN )) {
319 throw "[MSNumpress::encodeLinear] Cannot encode a number that exceeds the bounds of [-INT_MAX, INT_MAX].";
322 diff =
static_cast<int>(ints[2] - extrapol);
325 static_cast<unsigned int>(diff),
326 &halfBytes[halfByteCount],
338 for (hbi=1; hbi < halfByteCount; hbi+=2) {
339 result[ri] =
static_cast<unsigned char>(
340 (halfBytes[hbi-1] << 4) | (halfBytes[hbi] & 0xf)
345 if (halfByteCount % 2 != 0) {
346 halfBytes[0] = halfBytes[halfByteCount-1];
352 if (halfByteCount == 1) {
353 result[ri] =
static_cast<unsigned char>(halfBytes[0] << 4);
362 const unsigned char *data,
363 const size_t dataSize,
368 unsigned int init, buff;
380 if (dataSize == 8)
return 0;
383 throw "[MSNumpress::decodeLinear] Corrupt input data: not enough bytes to read fixed point! ";
389 throw "[MSNumpress::decodeLinear] Corrupt input data: not enough bytes to read first value! ";
392 for (i=0; i<4; i++) {
393 ints[1] = ints[1] | ((0xff & (init = data[8+i])) << (i*8));
395 result[0] = ints[1] / fixedPoint;
397 if (dataSize == 12)
return 1;
399 throw "[MSNumpress::decodeLinear] Corrupt input data: not enough bytes to read second value! ";
402 for (i=0; i<4; i++) {
403 ints[2] = ints[2] | ((0xff & (init = data[12+i])) << (i*8));
405 result[1] = ints[2] / fixedPoint;
413 while (di < dataSize) {
414 if (di == (dataSize - 1) && half == 1) {
415 if ((data[di] & 0xf) == 0x0) {
423 decodeInt(data, &di, dataSize, &half, &buff);
424 diff =
static_cast<int>(buff);
426 extrapol = ints[1] + (ints[1] - ints[0]);
429 result[ri++] = y / fixedPoint;
439 const std::vector<double> &data,
440 std::vector<unsigned char> &result,
443 size_t dataSize = data.size();
444 result.resize(dataSize * 5 + 8);
445 size_t encodedLength =
encodeLinear(&data[0], dataSize, &result[0], fixedPoint);
446 result.resize(encodedLength);
452 const std::vector<unsigned char> &data,
453 std::vector<double> &result
455 size_t dataSize = data.size();
456 result.resize((dataSize - 8) * 2);
457 size_t decodedLength =
decodeLinear(&data[0], dataSize, &result[0]);
458 result.resize(decodedLength);
466 const size_t dataSize,
467 unsigned char *result
471 double extrapol, diff;
472 const unsigned char *fp;
476 if (dataSize == 0)
return ri;
479 fp = (
unsigned char*)data;
480 for (i=0; i<8; i++) {
484 if (dataSize == 1)
return ri;
487 fp = (
unsigned char*)&(data[1]);
488 for (i=0; i<8; i++) {
492 fp = (
unsigned char*)&diff;
493 for (i=2; i<dataSize; i++) {
494 latest[0] = latest[1];
495 latest[1] = latest[2];
497 extrapol = latest[1] + (latest[1] - latest[0]);
498 diff = latest[2] - extrapol;
500 for (j=0; j<8; j++) {
511 const unsigned char *data,
512 const size_t dataSize,
516 double extrapol, diff;
520 if (dataSize % 8 != 0)
521 throw "[MSNumpress::decodeSafe] Corrupt input data: number of bytes needs to be multiple of 8! ";
526 fp = (
unsigned char*)&(latest[1]);
527 for (i=0; i<8; i++) {
530 result[0] = latest[1];
532 if (dataSize == 8)
return 1;
534 fp = (
unsigned char*)&(latest[2]);
535 for (i=0; i<8; i++) {
538 result[1] = latest[2];
542 fp = (
unsigned char*)&diff;
543 for (di = 16; di < dataSize; di += 8) {
544 latest[0] = latest[1];
545 latest[1] = latest[2];
547 for (i=0; i<8; i++) {
551 extrapol = latest[1] + (latest[1] - latest[0]);
552 latest[2] = extrapol + diff;
556 result[ri++] = latest[2];
559 throw "[MSNumpress::decodeSafe] Unknown error during decode! ";
571 unsigned char *result
575 unsigned char halfBytes[10];
576 size_t halfByteCount;
584 for (i=0; i<dataSize; i++) {
587 (data[i] + 0.5 > INT_MAX || data[i] < -0.5) ){
588 throw "[MSNumpress::encodePic] Cannot use Pic to encode a number larger than INT_MAX or smaller than 0.";
590 x =
static_cast<unsigned int>(data[i] + 0.5);
592 encodeInt(x, &halfBytes[halfByteCount], &halfByteCount);
594 for (hbi=1; hbi < halfByteCount; hbi+=2) {
595 result[ri] =
static_cast<unsigned char>(
596 (halfBytes[hbi-1] << 4) | (halfBytes[hbi] & 0xf)
601 if (halfByteCount % 2 != 0) {
602 halfBytes[0] = halfBytes[halfByteCount-1];
608 if (halfByteCount == 1) {
609 result[ri] =
static_cast<unsigned char>(halfBytes[0] << 4);
618 const unsigned char *data,
619 const size_t dataSize,
633 while (di < dataSize) {
634 if (di == (dataSize - 1) && half == 1) {
635 if ((data[di] & 0xf) == 0x0) {
640 decodeInt(&data[0], &di, dataSize, &half, &x);
645 result[ri++] =
static_cast<double>(x);
654 const std::vector<double> &data,
655 std::vector<unsigned char> &result
657 size_t dataSize = data.size();
658 result.resize(dataSize * 5);
659 size_t encodedLength =
encodePic(&data[0], dataSize, &result[0]);
660 result.resize(encodedLength);
666 const std::vector<unsigned char> &data,
667 std::vector<double> &result
669 size_t dataSize = data.size();
670 result.resize(dataSize * 2);
671 size_t decodedLength =
decodePic(&data[0], dataSize, &result[0]);
672 result.resize(decodedLength);
683 if (dataSize == 0)
return 0;
685 double maxDouble = 1;
689 for (
size_t i=0; i<dataSize; i++) {
691 maxDouble = max(maxDouble, x);
694 fp = floor(0xFFFF / maxDouble);
707 unsigned char *result,
716 for (i=0; i<dataSize; i++) {
717 temp = log(data[i]+1) * fixedPoint;
721 throw "[MSNumpress::encodeSlof] Cannot encode a number that overflows USHRT_MAX.";
724 x =
static_cast<unsigned short>(temp + 0.5);
725 result[ri++] = x & 0xff;
726 result[ri++] = (x >> 8) & 0xff;
734 const unsigned char *data,
735 const size_t dataSize,
743 throw "[MSNumpress::decodeSlof] Corrupt input data: not enough bytes to read fixed point! ";
748 for (i=8; i<dataSize; i+=2) {
749 x =
static_cast<unsigned short>(data[i] | (data[i+1] << 8));
750 result[ri++] = exp(x / fixedPoint) - 1;
758 const std::vector<double> &data,
759 std::vector<unsigned char> &result,
762 size_t dataSize = data.size();
763 result.resize(dataSize * 2 + 8);
764 size_t encodedLength =
encodeSlof(&data[0], dataSize, &result[0], fixedPoint);
765 result.resize(encodedLength);
771 const std::vector<unsigned char> &data,
772 std::vector<double> &result
774 size_t dataSize = data.size();
775 result.resize((dataSize - 8) / 2);
776 size_t decodedLength =
decodeSlof(&data[0], dataSize, &result[0]);
777 result.resize(decodedLength);
void optimalLinearFixedPointMass()
void optimalSlofFixedPoint()
void optimalLinearFixedPoint()
#define THROW_ON_OVERFLOW
static void encodeFixedPoint(double fixedPoint, unsigned char *result)
size_t encodePic(const double *data, size_t dataSize, unsigned char *result)
size_t decodeLinear(const unsigned char *data, const size_t dataSize, double *result)
static double decodeFixedPoint(const unsigned char *data)
size_t decodeSlof(const unsigned char *data, const size_t dataSize, double *result)
size_t encodeSlof(const double *data, size_t dataSize, unsigned char *result, double fixedPoint)
size_t encodeSafe(const double *data, const size_t dataSize, unsigned char *result)
size_t decodeSafe(const unsigned char *data, const size_t dataSize, double *result)
static void decodeInt(const unsigned char *data, size_t *di, size_t max_di, size_t *half, unsigned int *res)
size_t decodePic(const unsigned char *data, const size_t dataSize, double *result)
static bool is_little_endian()
static void encodeInt(const unsigned int x, unsigned char *res, size_t *res_length)