117 lines
4.0 KiB
C++
117 lines
4.0 KiB
C++
|
#include "stdafx.h"
|
||
|
|
||
|
#include "cpuencode.h"
|
||
|
#include "print_helpers.h"
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
#if 1
|
||
|
|
||
|
// The max. codeword length for each byte symbol is 32-bits
|
||
|
|
||
|
extern "C" void cpu_vlc_encode(unsigned int *indata, unsigned int num_elements,
|
||
|
unsigned int *outdata, unsigned int *outsize,
|
||
|
unsigned int *codewords,
|
||
|
unsigned int *codewordlens) {
|
||
|
unsigned int *bitstreamPt =
|
||
|
(unsigned int *)outdata; /* Pointer to current byte */
|
||
|
*bitstreamPt = 0x00000000U;
|
||
|
unsigned int startbit = 0;
|
||
|
unsigned int totalBytes = 0;
|
||
|
|
||
|
for (unsigned int k = 0; k < num_elements; k++) {
|
||
|
unsigned int cw32 = 0;
|
||
|
unsigned int val32 = indata[k];
|
||
|
unsigned int numbits = 0;
|
||
|
unsigned int mask32;
|
||
|
|
||
|
for (unsigned int i = 0; i < 4; i++) {
|
||
|
unsigned char symbol = (unsigned char)(val32 >> (8 * (3 - i)));
|
||
|
cw32 = codewords[symbol];
|
||
|
numbits = codewordlens[symbol];
|
||
|
|
||
|
while (numbits > 0) {
|
||
|
int writebits = min(32 - startbit, numbits);
|
||
|
if (numbits == writebits)
|
||
|
mask32 = (cw32 & ((1 << numbits) - 1))
|
||
|
<< (32 - startbit -
|
||
|
numbits); // first make sure that the start of the word
|
||
|
// is clean, then shift to the left as many
|
||
|
// places as you need
|
||
|
else
|
||
|
mask32 = cw32 >>
|
||
|
(numbits - writebits); // shift out the bits that can not fit
|
||
|
*bitstreamPt = (*bitstreamPt) | mask32;
|
||
|
numbits = numbits - writebits;
|
||
|
startbit = (startbit + writebits) % 32;
|
||
|
if (startbit == 0) {
|
||
|
bitstreamPt++;
|
||
|
*bitstreamPt = 0x00000000;
|
||
|
totalBytes += 4;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
totalBytes += (startbit / 8) +
|
||
|
((startbit % 8 == 0) ? 0 : 1); // return aligned to 8-bits
|
||
|
*outsize = totalBytes;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
/// ALTERNATIVE CODER
|
||
|
/// ASSUMPTION: The max. length of 4 combined codewords can be 2x original data,
|
||
|
/// i.e. g 64 bits
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#else
|
||
|
|
||
|
extern "C" void cpu_vlc_encode(unsigned int *indata, unsigned int num_elements,
|
||
|
unsigned int *outdata, unsigned int *outsize,
|
||
|
unsigned int *codewords,
|
||
|
unsigned int *codewordlens) {
|
||
|
unsigned int *bitstreamPt =
|
||
|
(unsigned int *)outdata; /* Pointer to current byte */
|
||
|
// assume memset is done.
|
||
|
*bitstreamPt = 0x00000000U;
|
||
|
unsigned int startbit = 0;
|
||
|
unsigned int totalBytes = 0;
|
||
|
|
||
|
for (unsigned int k = 0; k < num_elements; k++) {
|
||
|
unsigned long long cw64 = 0, mask64 = 0;
|
||
|
unsigned int val32 = indata[k];
|
||
|
unsigned int numbits = 0;
|
||
|
unsigned int mask32, temp32;
|
||
|
|
||
|
for (unsigned int i = 0; i < 4; i++) {
|
||
|
unsigned char symbol = (unsigned char)(val32 >> (8 * (3 - i)));
|
||
|
cw64 = (cw64 << codewordlens[symbol]) | codewords[symbol];
|
||
|
numbits += codewordlens[symbol];
|
||
|
// if (numbits>32) printf("WARRNING! Element %d is combined into numbits =
|
||
|
// %d!!!!!!!\n", k, numbits);
|
||
|
}
|
||
|
|
||
|
while (numbits > 0) {
|
||
|
int writebits = min(32 - startbit, numbits);
|
||
|
if (numbits == writebits) {
|
||
|
temp32 = (unsigned int)cw64; //(cw64 & 0xFFFFFFFF);
|
||
|
mask32 = temp32 << (32 - startbit - numbits);
|
||
|
} else {
|
||
|
mask32 = (unsigned int)(cw64 >> (numbits - writebits));
|
||
|
cw64 = cw64 & ((1 << (numbits - writebits)) - 1);
|
||
|
}
|
||
|
*bitstreamPt = (*bitstreamPt) | mask32;
|
||
|
numbits = numbits - writebits;
|
||
|
startbit = (startbit + writebits) % 32;
|
||
|
if (startbit == 0) {
|
||
|
bitstreamPt++;
|
||
|
*bitstreamPt = 0x00000000;
|
||
|
totalBytes += 4;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
totalBytes += (startbit / 8) +
|
||
|
((startbit % 8 == 0) ? 0 : 1); // return aligned to 8-bits
|
||
|
*outsize = totalBytes;
|
||
|
}
|
||
|
#endif
|