mirror of
https://github.com/nzp-team/vhlt.git
synced 2024-11-24 21:02:22 +00:00
318 lines
6.8 KiB
C
318 lines
6.8 KiB
C
#include "cmdlib.h" //--vluzacn
|
|
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
#error
|
|
#endif
|
|
|
|
extern void compress_compatability_test (void);
|
|
|
|
extern const size_t unused_size; // located at the end of a block
|
|
|
|
typedef enum
|
|
{
|
|
FLOAT32 = 0,
|
|
FLOAT16,
|
|
FLOAT8,
|
|
float_type_count
|
|
}
|
|
float_type;
|
|
|
|
extern const char *float_type_string[];
|
|
|
|
extern const size_t float_size[];
|
|
|
|
typedef enum
|
|
{
|
|
VECTOR96 = 0,
|
|
VECTOR48,
|
|
VECTOR32,
|
|
VECTOR24,
|
|
vector_type_count
|
|
}
|
|
vector_type;
|
|
|
|
extern const char *vector_type_string[];
|
|
|
|
extern const size_t vector_size[];
|
|
|
|
inline unsigned int bitget
|
|
(unsigned int i, unsigned int start, unsigned int end)
|
|
{
|
|
return (i & ~(~0u << end)) >> start;
|
|
}
|
|
|
|
inline unsigned int bitput
|
|
(unsigned int i, unsigned int start, unsigned int end)
|
|
{
|
|
return i << start;
|
|
}
|
|
|
|
inline unsigned int bitclr
|
|
(unsigned int i, unsigned int start, unsigned int end)
|
|
{
|
|
return i & (~(~0u << start) | (~0u << end));
|
|
}
|
|
|
|
inline unsigned int float_iswrong
|
|
(unsigned int i)
|
|
{
|
|
return i >= 0x7F800000u;
|
|
}
|
|
|
|
inline unsigned int float_istoobig
|
|
(unsigned int i)
|
|
{
|
|
return i >= 0x40000000u;
|
|
}
|
|
|
|
inline unsigned int float_istoosmall
|
|
(unsigned int i)
|
|
{
|
|
return i < 0x30800000u;
|
|
}
|
|
|
|
inline void float_compress
|
|
(float_type t, void *s, const float *f)
|
|
{
|
|
unsigned int *m = (unsigned int *)s;
|
|
const unsigned int *p = (const unsigned int *)f;
|
|
switch (t)
|
|
{
|
|
case FLOAT32:
|
|
m[0] = *p;
|
|
break;
|
|
case FLOAT16:
|
|
m[0] = bitclr (m[0], 0, 16);
|
|
if (float_iswrong (*p))
|
|
;
|
|
else if (float_istoobig (*p))
|
|
m[0] |= bitget (~0u, 0, 16);
|
|
else if (float_istoosmall (*p))
|
|
;
|
|
else
|
|
m[0] |= bitget (*p, 12, 28);
|
|
break;
|
|
case FLOAT8:
|
|
m[0] = bitclr (m[0], 0, 8);
|
|
if (float_iswrong (*p))
|
|
;
|
|
else if (float_istoobig (*p))
|
|
m[0] |= bitget (~0u, 0, 8);
|
|
else if (float_istoosmall (*p))
|
|
;
|
|
else
|
|
m[0] |= bitget (*p, 20, 28);
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
|
|
inline void float_decompress
|
|
(float_type t, const void *s, float *f)
|
|
{
|
|
const unsigned int *m = (const unsigned int *)s;
|
|
unsigned int *p = (unsigned int *)f;
|
|
switch (t)
|
|
{
|
|
case FLOAT32:
|
|
*p = m[0];
|
|
break;
|
|
case FLOAT16:
|
|
if (bitget (m[0], 0, 16) == 0)
|
|
*p = 0;
|
|
else
|
|
*p
|
|
= bitput (1, 11, 12)
|
|
| bitput (bitget (m[0], 0, 16), 12, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
break;
|
|
case FLOAT8:
|
|
if (bitget (m[0], 0, 8) == 0)
|
|
*p = 0;
|
|
else
|
|
*p
|
|
= bitput (1, 19, 20)
|
|
| bitput (bitget (m[0], 0, 8), 20, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
|
|
inline void vector_compress
|
|
(vector_type t, void *s, const float *f1, const float *f2, const float *f3)
|
|
{
|
|
unsigned int *m = (unsigned int *)s;
|
|
const unsigned int *p1 = (const unsigned int *)f1;
|
|
const unsigned int *p2 = (const unsigned int *)f2;
|
|
const unsigned int *p3 = (const unsigned int *)f3;
|
|
unsigned int max, i1, i2, i3;
|
|
switch (t)
|
|
{
|
|
case VECTOR96:
|
|
m[0] = *p1;
|
|
m[1] = *p2;
|
|
m[2] = *p3;
|
|
break;
|
|
case VECTOR48:
|
|
if (float_iswrong (*p1) || float_iswrong (*p2) || float_iswrong (*p3))
|
|
break;
|
|
m[0] = 0, m[1] = bitclr (m[1], 0, 16);
|
|
if (float_istoobig (*p1))
|
|
m[0] |= bitget (~0u, 0, 16);
|
|
else if (float_istoosmall (*p1))
|
|
;
|
|
else
|
|
m[0] |= bitget (*p1, 12, 28);
|
|
if (float_istoobig (*p2))
|
|
m[0] |= bitput (bitget (~0u, 0, 16), 16, 32);
|
|
else if (float_istoosmall (*p2))
|
|
;
|
|
else
|
|
m[0] |= bitput (bitget (*p2, 12, 28), 16, 32);
|
|
if (float_istoobig (*p3))
|
|
m[1] |= bitget (~0u, 0, 16);
|
|
else if (float_istoosmall (*p3))
|
|
;
|
|
else
|
|
m[1] |= bitget (*p3, 12, 28);
|
|
break;
|
|
case VECTOR32:
|
|
case VECTOR24:
|
|
if (float_iswrong (*p1) || float_iswrong (*p2) || float_iswrong (*p3))
|
|
{
|
|
max = i1 = i2 = i3 = 0;
|
|
}
|
|
else
|
|
{
|
|
max = *p1>*p2? (*p1>*p3? *p1: *p3): (*p2>*p3? *p2: *p3);
|
|
max = float_istoobig (max)? 0x7F : float_istoosmall (max)? 0x60 : bitget (max, 23, 31);
|
|
i1 = float_istoobig (*p1)? ~0u : (bitget (*p1, 0, 23) | bitput (1, 23, 24)) >> (1 + max - bitget (*p1, 23, 31));
|
|
i2 = float_istoobig (*p2)? ~0u : (bitget (*p2, 0, 23) | bitput (1, 23, 24)) >> (1 + max - bitget (*p2, 23, 31));
|
|
i3 = float_istoobig (*p3)? ~0u : (bitget (*p3, 0, 23) | bitput (1, 23, 24)) >> (1 + max - bitget (*p3, 23, 31));
|
|
}
|
|
if (t == VECTOR32)
|
|
m[0] = 0
|
|
| bitput (bitget (i1, 14, 23), 0, 9)
|
|
| bitput (bitget (i2, 14, 23), 9, 18)
|
|
| bitput (bitget (i3, 14, 23), 18, 27)
|
|
| bitput (bitget (max, 0, 5), 27, 32)
|
|
;
|
|
else
|
|
m[0] = bitclr (m[0], 0, 24)
|
|
| bitput (bitget (i1, 17, 23), 0, 6)
|
|
| bitput (bitget (i2, 17, 23), 6, 12)
|
|
| bitput (bitget (i3, 17, 23), 12, 18)
|
|
| bitput (bitget (max, 0, 5), 18, 23)
|
|
;
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
|
|
inline void vector_decompress
|
|
(vector_type t, const void *s, float *f1, float *f2, float *f3)
|
|
{
|
|
const unsigned int *m = (const unsigned int *)s;
|
|
unsigned int *p1 = (unsigned int *)f1;
|
|
unsigned int *p2 = (unsigned int *)f2;
|
|
unsigned int *p3 = (unsigned int *)f3;
|
|
switch (t)
|
|
{
|
|
case VECTOR96:
|
|
*p1 = m[0];
|
|
*p2 = m[1];
|
|
*p3 = m[2];
|
|
break;
|
|
case VECTOR48:
|
|
if (bitget (m[0], 0, 16) == 0)
|
|
*p1 = 0;
|
|
else
|
|
*p1
|
|
= bitput (1, 11, 12)
|
|
| bitput (bitget (m[0], 0, 16), 12, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
if (bitget (m[0], 16, 32) == 0)
|
|
*p2 = 0;
|
|
else
|
|
*p2
|
|
= bitput (1, 11, 12)
|
|
| bitput (bitget (m[0], 16, 32), 12, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
if (bitget (m[1], 0, 16) == 0)
|
|
*p3 = 0;
|
|
else
|
|
*p3
|
|
= bitput (1, 11, 12)
|
|
| bitput (bitget (m[1], 0, 16), 12, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
break;
|
|
case VECTOR32: case VECTOR24:
|
|
float f;
|
|
if (t == VECTOR32)
|
|
{
|
|
*p1
|
|
= bitput (1, 13, 14)
|
|
| bitput (bitget (m[0], 0, 9), 14, 23)
|
|
| bitput (bitget (m[0], 27, 32), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*p2
|
|
= bitput (1, 13, 14)
|
|
| bitput (bitget (m[0], 9, 18), 14, 23)
|
|
| bitput (bitget (m[0], 27, 32), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*p3
|
|
= bitput (1, 13, 14)
|
|
| bitput (bitget (m[0], 18, 27), 14, 23)
|
|
| bitput (bitget (m[0], 27, 32), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*((unsigned int *)&f)
|
|
= bitput (bitget (m[0], 27, 32), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
}
|
|
else
|
|
{
|
|
*p1
|
|
= bitput (1, 16, 17)
|
|
| bitput (bitget (m[0], 0, 6), 17, 23)
|
|
| bitput (bitget (m[0], 18, 23), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*p2
|
|
= bitput (1, 16, 17)
|
|
| bitput (bitget (m[0], 6, 12), 17, 23)
|
|
| bitput (bitget (m[0], 18, 23), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*p3
|
|
= bitput (1, 16, 17)
|
|
| bitput (bitget (m[0], 12, 18), 17, 23)
|
|
| bitput (bitget (m[0], 18, 23), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
*((unsigned int *)&f)
|
|
= bitput (bitget (m[0], 18, 23), 23, 28)
|
|
| bitput (3, 28, 32)
|
|
;
|
|
}
|
|
*f1 = (*f1-f) * 2.f;
|
|
*f2 = (*f2-f) * 2.f;
|
|
*f3 = (*f3-f) * 2.f;
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
}
|