159 lines
3.1 KiB
C
159 lines
3.1 KiB
C
#include "s16head.h"
|
|
#include "unpack.h"
|
|
|
|
|
|
#define BS 128
|
|
#define FRAC 0.10
|
|
#define S 16
|
|
#define PCHUNK 128
|
|
|
|
void pack(unsigned int *v, unsigned int b, unsigned int n, unsigned int *w);
|
|
|
|
|
|
int detailed_p4_encode(unsigned int **w, unsigned int* p, int num , int *chunk_size, int * exception_n)
|
|
{
|
|
int i, j, t, s;
|
|
|
|
unsigned int b = cnum[num];
|
|
int bb_e;
|
|
int bb_p;
|
|
int p_low;
|
|
unsigned int e_n = 0;
|
|
int max_p = 0;
|
|
int max_e = 0;
|
|
|
|
unsigned int* out = (unsigned*)malloc(sizeof(unsigned)*PCHUNK*2);
|
|
unsigned int* ex = (unsigned*)malloc(sizeof(unsigned)*PCHUNK*2);
|
|
unsigned int* po = (unsigned*)malloc(sizeof(unsigned)*PCHUNK*2);
|
|
|
|
unsigned int* tp = NULL;
|
|
unsigned int *_pp, *_ww;
|
|
|
|
if (b == 32)
|
|
{
|
|
(*w)[0] = ((b<<10)) + (0);
|
|
*w +=1;
|
|
for (i = 0; i < PCHUNK ; i++) (*w)[i] = p[i];
|
|
*w += (PCHUNK);
|
|
(*chunk_size) = 1 + BS;
|
|
|
|
free(out);
|
|
free(ex);
|
|
free(po);
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < PCHUNK ; i++)
|
|
{
|
|
if ( p[i] >= (1<<b) ) //exception
|
|
{
|
|
p_low = p[i] & ((1<<b)-1);
|
|
out[i] = p_low;
|
|
ex[e_n] = (p[i] >> b);
|
|
po[(e_n++)] = i; //
|
|
}
|
|
else
|
|
out[i] = p[i];
|
|
}
|
|
|
|
if (1) // force to pass every time
|
|
{
|
|
/*get the gap of position*/
|
|
for(j = e_n-1;j>0;j--)
|
|
{
|
|
po[j] = po[j] - po[j-1] ;
|
|
po[j] --;
|
|
}
|
|
|
|
s = ((b * PCHUNK)>>5);
|
|
tp = (*w);
|
|
(*w)[0] = ((num<<10))+e_n; // record b and number of exceptions into this value, in the other version we pick this value out and did not count it
|
|
(*w) += 1;
|
|
for (i = 0; i < s; i++) (*w)[i] = 0;
|
|
pack(out, b, PCHUNK , *w);
|
|
*w += s;
|
|
|
|
unsigned int *all_array = (unsigned*)malloc(sizeof(unsigned)*PCHUNK*4) ;
|
|
for(j=0;j<e_n;j++)
|
|
{
|
|
all_array[j] = po[j];
|
|
all_array[e_n+j] =ex[j];
|
|
}
|
|
for (_pp = all_array, _ww = (*w); _pp < &(all_array[2*e_n]); )
|
|
s16_encode(&_ww, &_pp, &(all_array[2*e_n]) - _pp);
|
|
|
|
(*chunk_size) = 1 + s + (_ww - (*w)) ;
|
|
|
|
(*w) += (_ww - (*w)) ;
|
|
|
|
(*exception_n) = e_n;
|
|
|
|
free(out);
|
|
free(ex);
|
|
free(po);
|
|
free(all_array);
|
|
return (e_n);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void pack(unsigned int *v, unsigned int b, unsigned int n, unsigned int *w)
|
|
{
|
|
int i, bp, wp, s;
|
|
|
|
for (bp = 0, i = 0; i < n; i++, bp += b)
|
|
{
|
|
wp = bp>>5;
|
|
s = 32 - b - (bp & 31);
|
|
if (s >= 0)
|
|
w[wp] |= (v[i]<<s);
|
|
else
|
|
{
|
|
s = -s;
|
|
w[wp] |= (v[i]>>s);
|
|
w[wp+1] = (v[i]<<(32-s));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*modified p4decode */
|
|
unsigned int *detailed_p4_decode(unsigned int *_p, unsigned int *_w, unsigned int * all_array)
|
|
{
|
|
|
|
int i, s;
|
|
unsigned int x;
|
|
int flag = _w[0];
|
|
(_w)++;
|
|
|
|
unsigned int *_ww,*_pp;
|
|
unsigned int b = ((flag>>10) & 31);
|
|
unsigned int e_n = (flag & 1023) ;
|
|
|
|
(unpack[b])(_p, _w);
|
|
|
|
b = cnum[b];
|
|
_w += ((b * BS)>>5);
|
|
unsigned int _k = 0;
|
|
unsigned int psum = 0;
|
|
if(e_n != 0 )
|
|
{
|
|
for (_pp = all_array, _ww = (unsigned int *)(_w); _pp < &(all_array[e_n*2]);)
|
|
{
|
|
S16_DECODE(_ww, _pp);
|
|
}
|
|
|
|
_w += (_ww - _w);
|
|
psum = all_array[0];
|
|
|
|
for(i=0;i<e_n;i++)
|
|
{
|
|
_p[psum] += (all_array[e_n+i]<<b);
|
|
psum += all_array[ i + 1] + 1;
|
|
}
|
|
}
|
|
return(_w);
|
|
}
|
|
|
|
|