forked from KolibriOS/kolibrios
360 lines
7.7 KiB
C
360 lines
7.7 KiB
C
|
#include "layer3.h"
|
||
|
#include "l3huff.h"
|
||
|
|
||
|
//#ifdef _MSC_VER
|
||
|
//#pragma warning(disable: 4505)
|
||
|
//#endif
|
||
|
|
||
|
/*===============================================================*/
|
||
|
|
||
|
/* max bits required for any lookup - change if htable changes */
|
||
|
/* quad required 10 bit w/signs must have (MAXBITS+2) >= 10 */
|
||
|
#define MAXBITS 9
|
||
|
|
||
|
static HUFF_ELEMENT huff_table_0[] =
|
||
|
{0, 0, 0, 64}; /* dummy must not use */
|
||
|
|
||
|
/*-- 6 bit lookup (purgebits, value) --*/
|
||
|
static unsigned char quad_table_a[][2] =
|
||
|
{
|
||
|
6, 11, 6, 15, 6, 13, 6, 14, 6, 7, 6, 5, 5, 9,
|
||
|
5, 9, 5, 6, 5, 6, 5, 3, 5, 3, 5, 10, 5, 10,
|
||
|
5, 12, 5, 12, 4, 2, 4, 2, 4, 2, 4, 2, 4, 1,
|
||
|
4, 1, 4, 1, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4,
|
||
|
4, 8, 4, 8, 4, 8, 4, 8, 1, 0, 1, 0, 1, 0,
|
||
|
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
|
||
|
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
|
||
|
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
|
||
|
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
|
||
|
1, 0,
|
||
|
};
|
||
|
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
HUFF_ELEMENT *table;
|
||
|
int linbits;
|
||
|
int ncase;
|
||
|
}
|
||
|
HUFF_SETUP;
|
||
|
|
||
|
#define no_bits 0
|
||
|
#define one_shot 1
|
||
|
#define no_linbits 2
|
||
|
#define have_linbits 3
|
||
|
#define quad_a 4
|
||
|
#define quad_b 5
|
||
|
|
||
|
|
||
|
static HUFF_SETUP table_look[] =
|
||
|
{
|
||
|
huff_table_0, 0, no_bits,
|
||
|
huff_table_1, 0, one_shot,
|
||
|
huff_table_2, 0, one_shot,
|
||
|
huff_table_3, 0, one_shot,
|
||
|
huff_table_0, 0, no_bits,
|
||
|
huff_table_5, 0, one_shot,
|
||
|
huff_table_6, 0, one_shot,
|
||
|
huff_table_7, 0, no_linbits,
|
||
|
huff_table_8, 0, no_linbits,
|
||
|
huff_table_9, 0, no_linbits,
|
||
|
huff_table_10, 0, no_linbits,
|
||
|
huff_table_11, 0, no_linbits,
|
||
|
huff_table_12, 0, no_linbits,
|
||
|
huff_table_13, 0, no_linbits,
|
||
|
huff_table_0, 0, no_bits,
|
||
|
huff_table_15, 0, no_linbits,
|
||
|
huff_table_16, 1, have_linbits,
|
||
|
huff_table_16, 2, have_linbits,
|
||
|
huff_table_16, 3, have_linbits,
|
||
|
huff_table_16, 4, have_linbits,
|
||
|
huff_table_16, 6, have_linbits,
|
||
|
huff_table_16, 8, have_linbits,
|
||
|
huff_table_16, 10, have_linbits,
|
||
|
huff_table_16, 13, have_linbits,
|
||
|
huff_table_24, 4, have_linbits,
|
||
|
huff_table_24, 5, have_linbits,
|
||
|
huff_table_24, 6, have_linbits,
|
||
|
huff_table_24, 7, have_linbits,
|
||
|
huff_table_24, 8, have_linbits,
|
||
|
huff_table_24, 9, have_linbits,
|
||
|
huff_table_24, 11, have_linbits,
|
||
|
huff_table_24, 13, have_linbits,
|
||
|
huff_table_0, 0, quad_a,
|
||
|
huff_table_0, 0, quad_b,
|
||
|
};
|
||
|
|
||
|
/*========================================================*/
|
||
|
void huffman(int xy[][2], int n, int ntable)
|
||
|
{
|
||
|
int i;
|
||
|
HUFF_ELEMENT *t;
|
||
|
HUFF_ELEMENT *t0;
|
||
|
int linbits;
|
||
|
int bits;
|
||
|
int code;
|
||
|
int x, y;
|
||
|
|
||
|
if (n <= 0)
|
||
|
return;
|
||
|
n = n >> 1; /* huff in pairs */
|
||
|
/*-------------*/
|
||
|
t0 = table_look[ntable].table;
|
||
|
linbits = table_look[ntable].linbits;
|
||
|
switch (table_look[ntable].ncase)
|
||
|
{
|
||
|
default:
|
||
|
/*------------------------------------------*/
|
||
|
case no_bits:
|
||
|
/*- table 0, no data, x=y=0--*/
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
xy[i][0] = 0;
|
||
|
xy[i][1] = 0;
|
||
|
}
|
||
|
return;
|
||
|
/*------------------------------------------*/
|
||
|
case one_shot:
|
||
|
/*- single lookup, no escapes -*/
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
mac_bitget_check((MAXBITS + 2));
|
||
|
bits = t0[0].b.signbits;
|
||
|
code = mac_bitget2(bits);
|
||
|
mac_bitget_purge(t0[1 + code].b.purgebits);
|
||
|
x = t0[1 + code].b.x;
|
||
|
y = t0[1 + code].b.y;
|
||
|
if (x)
|
||
|
if (mac_bitget_1bit())
|
||
|
x = -x;
|
||
|
if (y)
|
||
|
if (mac_bitget_1bit())
|
||
|
y = -y;
|
||
|
xy[i][0] = x;
|
||
|
xy[i][1] = y;
|
||
|
if (bitget_overrun())
|
||
|
break; // bad data protect
|
||
|
|
||
|
}
|
||
|
return;
|
||
|
/*------------------------------------------*/
|
||
|
case no_linbits:
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
t = t0;
|
||
|
for (;;)
|
||
|
{
|
||
|
mac_bitget_check((MAXBITS + 2));
|
||
|
bits = t[0].b.signbits;
|
||
|
code = mac_bitget2(bits);
|
||
|
if (t[1 + code].b.purgebits)
|
||
|
break;
|
||
|
t += t[1 + code].ptr; /* ptr include 1+code */
|
||
|
mac_bitget_purge(bits);
|
||
|
}
|
||
|
mac_bitget_purge(t[1 + code].b.purgebits);
|
||
|
x = t[1 + code].b.x;
|
||
|
y = t[1 + code].b.y;
|
||
|
if (x)
|
||
|
if (mac_bitget_1bit())
|
||
|
x = -x;
|
||
|
if (y)
|
||
|
if (mac_bitget_1bit())
|
||
|
y = -y;
|
||
|
xy[i][0] = x;
|
||
|
xy[i][1] = y;
|
||
|
if (bitget_overrun())
|
||
|
break; // bad data protect
|
||
|
|
||
|
}
|
||
|
return;
|
||
|
/*------------------------------------------*/
|
||
|
case have_linbits:
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
t = t0;
|
||
|
for (;;)
|
||
|
{
|
||
|
bits = t[0].b.signbits;
|
||
|
code = bitget2(bits);
|
||
|
if (t[1 + code].b.purgebits)
|
||
|
break;
|
||
|
t += t[1 + code].ptr; /* ptr includes 1+code */
|
||
|
mac_bitget_purge(bits);
|
||
|
}
|
||
|
mac_bitget_purge(t[1 + code].b.purgebits);
|
||
|
x = t[1 + code].b.x;
|
||
|
y = t[1 + code].b.y;
|
||
|
if (x == 15)
|
||
|
x += bitget_lb(linbits);
|
||
|
if (x)
|
||
|
if (mac_bitget_1bit())
|
||
|
x = -x;
|
||
|
if (y == 15)
|
||
|
y += bitget_lb(linbits);
|
||
|
if (y)
|
||
|
if (mac_bitget_1bit())
|
||
|
y = -y;
|
||
|
xy[i][0] = x;
|
||
|
xy[i][1] = y;
|
||
|
if (bitget_overrun())
|
||
|
break; // bad data protect
|
||
|
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
/*--- end switch ---*/
|
||
|
|
||
|
}
|
||
|
|
||
|
int huffman_quad(int vwxy[][4], int n, int nbits, int ntable)
|
||
|
{
|
||
|
int i;
|
||
|
int code;
|
||
|
int x, y, v, w;
|
||
|
int tmp;
|
||
|
int i_non_zero, tmp_nz;
|
||
|
|
||
|
tmp_nz = 15;
|
||
|
i_non_zero = -1;
|
||
|
|
||
|
n = n >> 2; /* huff in quads */
|
||
|
|
||
|
if (ntable)
|
||
|
goto case_quad_b;
|
||
|
|
||
|
/* case_quad_a: */
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
if (nbits <= 0)
|
||
|
break;
|
||
|
mac_bitget_check(10);
|
||
|
code = mac_bitget2(6);
|
||
|
nbits -= quad_table_a[code][0];
|
||
|
mac_bitget_purge(quad_table_a[code][0]);
|
||
|
tmp = quad_table_a[code][1];
|
||
|
if (tmp)
|
||
|
{
|
||
|
i_non_zero = i;
|
||
|
tmp_nz = tmp;
|
||
|
}
|
||
|
v = (tmp >> 3) & 1;
|
||
|
w = (tmp >> 2) & 1;
|
||
|
x = (tmp >> 1) & 1;
|
||
|
y = tmp & 1;
|
||
|
if (v)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
v = -v;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (w)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
w = -w;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (x)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
x = -x;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (y)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
y = -y;
|
||
|
nbits--;
|
||
|
}
|
||
|
vwxy[i][0] = v;
|
||
|
vwxy[i][1] = w;
|
||
|
vwxy[i][2] = x;
|
||
|
vwxy[i][3] = y;
|
||
|
if (bitget_overrun())
|
||
|
break; // bad data protect
|
||
|
|
||
|
}
|
||
|
if (nbits < 0)
|
||
|
{
|
||
|
i--;
|
||
|
vwxy[i][0] = 0;
|
||
|
vwxy[i][1] = 0;
|
||
|
vwxy[i][2] = 0;
|
||
|
vwxy[i][3] = 0;
|
||
|
}
|
||
|
|
||
|
i_non_zero = (i_non_zero + 1) << 2;
|
||
|
|
||
|
if ((tmp_nz & 3) == 0)
|
||
|
i_non_zero -= 2;
|
||
|
|
||
|
return i_non_zero;
|
||
|
|
||
|
/*--------------------*/
|
||
|
case_quad_b:
|
||
|
for (i = 0; i < n; i++)
|
||
|
{
|
||
|
if (nbits < 4)
|
||
|
break;
|
||
|
nbits -= 4;
|
||
|
mac_bitget_check(8);
|
||
|
tmp = mac_bitget(4) ^ 15; /* one's complement of bitstream */
|
||
|
if (tmp)
|
||
|
{
|
||
|
i_non_zero = i;
|
||
|
tmp_nz = tmp;
|
||
|
}
|
||
|
v = (tmp >> 3) & 1;
|
||
|
w = (tmp >> 2) & 1;
|
||
|
x = (tmp >> 1) & 1;
|
||
|
y = tmp & 1;
|
||
|
if (v)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
v = -v;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (w)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
w = -w;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (x)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
x = -x;
|
||
|
nbits--;
|
||
|
}
|
||
|
if (y)
|
||
|
{
|
||
|
if (mac_bitget_1bit())
|
||
|
y = -y;
|
||
|
nbits--;
|
||
|
}
|
||
|
vwxy[i][0] = v;
|
||
|
vwxy[i][1] = w;
|
||
|
vwxy[i][2] = x;
|
||
|
vwxy[i][3] = y;
|
||
|
if (bitget_overrun())
|
||
|
break; // bad data protect
|
||
|
|
||
|
}
|
||
|
if (nbits < 0)
|
||
|
{
|
||
|
i--;
|
||
|
vwxy[i][0] = 0;
|
||
|
vwxy[i][1] = 0;
|
||
|
vwxy[i][2] = 0;
|
||
|
vwxy[i][3] = 0;
|
||
|
}
|
||
|
|
||
|
i_non_zero = (i_non_zero + 1) << 2;
|
||
|
|
||
|
if ((tmp_nz & 3) == 0)
|
||
|
i_non_zero -= 2;
|
||
|
|
||
|
return i_non_zero; /* return non-zero sample (to nearest pair) */
|
||
|
|
||
|
}
|