#include "brst_dcm.h" #define MAXBYTES MAX_PACKET_SIZE int nibble_decomp(uchar u[MAXBYTES],uchar c[MAXBYTES],int size); int byte_decomp(uchar u[MAXBYTES],uchar c[MAXBYTES],int size); uchar msbit(uchar xbyte); /*------------------------------------------------------------------------------ */ /* burst decompression routine */ int decompress_burst_packet(packet *uncomp,packet *comp) { int dsize; int retval; *uncomp = *comp; retval = 0; if(comp->idtype & 0x8000){ if(comp->idtype & 0x0800){ dsize = nibble_decomp(uncomp->data,comp->data, comp->dsize); retval = 1; } else{ dsize = byte_decomp(uncomp->data,comp->data, comp->dsize); retval = 2; } uncomp->dsize = dsize; uncomp->idtype &= ~0x8000; /* reset compression bit */ while(dsizedata[dsize++] = 0; } return(retval); } /*------------------------------------------------------------------------------ | byte_decomp() |------------------------------------------------------------------------------- | | PURPOSE | ------- | Perform byte decompression on burst data. | | ARGUMENTS | --------- | u output: array of uncompressed data | c input: array of compressed data | size input: number of elements in input array | | RETURN | ------ | n number of elements in output array | ------------------------------------------------------------------------------*/ int byte_decomp(uchar u[MAXBYTES], uchar c[MAXBYTES], int size) { uchar byte1; /* current raw byte */ uchar byte2; /* next raw byte */ uchar temp1; /* hold current byte */ uchar temp2; /* hold next byte */ int ibit = 7; /* current bit position */ int ibyte = 0; /* byte counter */ int n = 0; /* number of uncompressed values */ /* Check size of input array and handle special cases */ switch (size) { case 0: return(0); break; case 1: u[0] = msbit(c[0]) ? c[0] & 0x7f : 0; return(1); break; default: break; } if (size > MAXBYTES) return(0); /* Read the first 2 bytes */ byte1 = *c++; byte2 = *c++; ibyte++; /* Loop through compressed burst data */ while (ibyte < size) { /* Check size of output array */ if (n >= MAXBYTES-1) return(0); /* Read in next byte, if necessary */ if (ibit < 0) { byte2 = *c++; ibit = 7; ibyte++; } /* Check most significant bit and perform appropriate decompression */ if (msbit(byte1)) { u[n++] = (byte1 << 1) | msbit(byte2); temp1 = (byte2 << 1); temp2 = *c++; byte1 = temp1 | (temp2 >> ibit); byte2 = temp2 << (8 - ibit); ibit--; ibyte++; } else { u[n++] = 0; byte1 = (byte1 << 1) | msbit(byte2); byte2 <<= 1; ibit--; } } /* Done */ return(n); } /*------------------------------------------------------------------------------ | nibble_decomp() |------------------------------------------------------------------------------- | | PURPOSE | ------- | Perform nibble decompression on burst data. | | ARGUMENTS | --------- | u output: array of uncompressed data | c input: array of compressed data | size input: number of elements in input array | | RETURN | ------ | n number of elements in output array | ------------------------------------------------------------------------------*/ int nibble_decomp(uchar u[MAXBYTES], uchar c[MAXBYTES], int size) { uchar bit5; /* current 5 bits */ uchar bit8; /* next 8 bits */ uchar temp; /* byte holder */ int outtemp; /* output bytes from nibbles */ int nbit; /* number of bits in bit8 */ int rbit; /* bits remaining in stream */ int n = 0; /* number of uncompressed values */ int nNibs = 0; /* number of uncompressed nibbles */ /* Check size of array and handle special cases */ switch (size) { case 0: return(0); break; case 1: u[0] = msbit(c[0]) ? (c[0] >> 3) & 0x0f : 0; return(1); break; default: break; } if (size > MAXBYTES) return(0); /* Read the first byte and initialize */ bit5 = (*c) >> 3; bit8 = (*c) << 5; c++; nbit = 3; rbit = size * 8; /* Loop through compressed burst data */ while (rbit) { /* Check size of output array */ if (n >= MAXBYTES-1) return(0); /* Check most significant bit and perform appropriate decompression */ if (msbit(bit5 << 3)) { if ( nNibs % 2 ) outtemp = outtemp | bit5 & 0x0f; /* odd nibbles */ else outtemp = (bit5 & 0x0f) << 4; /* even nibbles */ nNibs ++ ; bit5 = 0x00; if (nbit < 5) { temp = *c++; bit5 = (bit8 >> 3) | (temp >> (nbit + 3)); bit8 = temp << (5 - nbit); nbit += 3; } else { bit5 = bit8 >> 3; bit8 = bit8 << 5; nbit -= 5; } rbit -= 5; } else { if ( nNibs % 2 ) outtemp = outtemp | 0; /* odd nibbles */ else outtemp = 0; /* even nibbles */ nNibs ++ ; if (nbit <= 0) { bit8 = *c++; nbit = 8; } bit5 = (bit5 << 1) | msbit(bit8); bit8 <<= 1; nbit--; rbit--; } if ( nNibs && ! (nNibs % 2) ) u[n++] = outtemp; } /* load into the output, any remaining odd nibble */ if ( nNibs % 2 ) u[n] = outtemp; /* Done */ return(n); } /*------------------------------------------------------------------------------ | msbit() |------------------------------------------------------------------------------- | | PURPOSE | ------- | Check the value of most significant bit of an unsigned character byte. | | ARGUMENTS | --------- | byte1 input: single byte value | | RETURN | ------ | Value of most significant bit. | ------------------------------------------------------------------------------*/ uchar msbit(uchar byte1) { return ((byte1 >> 7) && 0x01); }