mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
212 lines
No EOL
5.7 KiB
C++
212 lines
No EOL
5.7 KiB
C++
#include "repack.h"
|
|
|
|
/*
|
|
This file contains a bunch of simple bit repacking functions,
|
|
for easy-of-use.
|
|
They are all byte-aligned, so if you do not want to be,
|
|
shifting would have to be done beforehand.
|
|
*/
|
|
|
|
int repackBytesTo10bits(uint8_t *bytes, int byte_length, uint16_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Compute how many we can repack using the "fast" way
|
|
int repack_fast = byte_length - (byte_length % 5);
|
|
int repack_slow = byte_length % 5;
|
|
|
|
// Repack what can be repacked fast
|
|
for (int i = 0; i < repack_fast; i += 5)
|
|
{
|
|
words[wpos++] = bytes[bpos + 0] << 2 | bytes[bpos + 1] >> 6;
|
|
words[wpos++] = (bytes[bpos + 1] % 64) << 4 | bytes[bpos + 2] >> 4;
|
|
words[wpos++] = (bytes[bpos + 2] % 16) << 6 | bytes[bpos + 3] >> 2;
|
|
words[wpos++] = (bytes[bpos + 3] % 4) << 8 | bytes[bpos + 4];
|
|
bpos += 5;
|
|
}
|
|
|
|
// Repack remaining using a slower method
|
|
uint16_t shifter = 0;
|
|
int inshifter = 0;
|
|
for (int i = 0; i < repack_slow; i++)
|
|
{
|
|
for (int b = 7; b >= 0; b--)
|
|
{
|
|
shifter = (shifter << 1 | ((bytes[bpos] >> b) & 1)) & 1024;
|
|
inshifter++;
|
|
if (inshifter == 10)
|
|
{
|
|
words[wpos++] = shifter;
|
|
inshifter = 0;
|
|
}
|
|
}
|
|
|
|
bpos++;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
int repackBytesTo12bits(uint8_t *bytes, int byte_length, uint16_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Compute how many we can repack using the "fast" way
|
|
int repack_fast = byte_length - (byte_length % 3);
|
|
int repack_slow = byte_length % 3;
|
|
|
|
// Repack what can be repacked fast
|
|
for (int i = 0; i < repack_fast; i += 3)
|
|
{
|
|
words[wpos++] = bytes[bpos + 0] << 4 | bytes[bpos + 1] >> 4;
|
|
words[wpos++] = (bytes[bpos + 1] & 0b1111) << 8 | bytes[bpos + 2];
|
|
bpos += 3;
|
|
}
|
|
|
|
// Repack remaining using a slower method
|
|
uint16_t shifter = 0;
|
|
int inshifter = 0;
|
|
for (int i = 0; i < repack_slow; i++)
|
|
{
|
|
for (int b = 7; b >= 0; b--)
|
|
{
|
|
shifter = (shifter << 1 | ((bytes[bpos] >> b) & 1)) & 4096;
|
|
inshifter++;
|
|
if (inshifter == 12)
|
|
{
|
|
words[wpos++] = shifter;
|
|
inshifter = 0;
|
|
}
|
|
}
|
|
|
|
bpos++;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
int repackBytesTo13bits(uint8_t *bytes, int byte_length, uint16_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Compute how many we can repack using the "fast" way
|
|
int repack_fast = byte_length - (byte_length % 13);
|
|
int repack_slow = byte_length % 13;
|
|
|
|
// Repack what can be repacked fast
|
|
for (int i = 0; i < repack_fast; i += 13)
|
|
{
|
|
words[wpos++] = bytes[bpos + 0] << 5 | bytes[bpos + 1] >> 3;
|
|
words[wpos++] = (bytes[bpos + 1] & 0b111) << 10 | bytes[bpos + 2] << 2 | bytes[bpos + 3] >> 6;
|
|
words[wpos++] = (bytes[bpos + 3] & 0b111111) << 7 | bytes[bpos + 4] >> 1;
|
|
words[wpos++] = (bytes[bpos + 4] & 0b1) << 12 | bytes[bpos + 5] << 4 | bytes[bpos + 6] >> 4;
|
|
words[wpos++] = (bytes[bpos + 6] & 0b1111) << 9 | bytes[bpos + 7] << 1 | bytes[bpos + 8] >> 7;
|
|
words[wpos++] = (bytes[bpos + 8] & 0b1111111) << 6 | bytes[bpos + 9] >> 2;
|
|
words[wpos++] = (bytes[bpos + 9] & 0b11) << 11 | bytes[bpos + 10] << 3 | bytes[bpos + 11] >> 5;
|
|
words[wpos++] = (bytes[bpos + 11] & 0b11111) << 8 | bytes[bpos + 12];
|
|
bpos += 13;
|
|
}
|
|
|
|
// Repack remaining using a slower method
|
|
uint16_t shifter = 0;
|
|
int inshifter = 0;
|
|
for (int i = 0; i < repack_slow; i++)
|
|
{
|
|
for (int b = 7; b >= 0; b--)
|
|
{
|
|
shifter = (shifter << 1 | ((bytes[bpos] >> b) & 1)) & 8192;
|
|
inshifter++;
|
|
if (inshifter == 13)
|
|
{
|
|
words[wpos++] = shifter;
|
|
inshifter = 0;
|
|
}
|
|
}
|
|
|
|
bpos++;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
int repackBytesTo16bits(uint8_t *bytes, int byte_length, uint16_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Compute how many we can repack using the "fast" way
|
|
// This also is how we will repack at all
|
|
int repack_fast = byte_length - (byte_length % 2);
|
|
|
|
// Repack what can be repacked fast
|
|
for (int i = 0; i < repack_fast; i += 2)
|
|
{
|
|
words[wpos++] = bytes[bpos + 0] << 8 | bytes[bpos + 1];
|
|
bpos += 2;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
int repackBytesTo20bits(uint8_t *bytes, int byte_length, uint32_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Repack remaining using a slower method
|
|
uint32_t shifter = 0;
|
|
int inshifter = 0;
|
|
for (int i = 0; i < byte_length; i++)
|
|
{
|
|
for (int b = 7; b >= 0; b--)
|
|
{
|
|
shifter = (shifter << 1 | ((bytes[bpos] >> b) & 1)) & 0b11111111111111111111;
|
|
inshifter++;
|
|
if (inshifter == 20)
|
|
{
|
|
words[wpos++] = shifter;
|
|
inshifter = 0;
|
|
}
|
|
}
|
|
|
|
bpos++;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
int repackBytesTo14bits(uint8_t *bytes, int byte_length, uint16_t *words)
|
|
{
|
|
int bpos = 0;
|
|
int wpos = 0;
|
|
|
|
// Repack remaining using a slower method
|
|
uint16_t shifter = 0;
|
|
int inshifter = 0;
|
|
for (int i = 0; i < byte_length; i++)
|
|
{
|
|
for (int b = 7; b >= 0; b--)
|
|
{
|
|
shifter = (shifter << 1 | ((bytes[bpos] >> b) & 1)) & 0b11111111111111;
|
|
inshifter++;
|
|
if (inshifter == 14)
|
|
{
|
|
words[wpos++] = shifter;
|
|
inshifter = 0;
|
|
}
|
|
}
|
|
|
|
bpos++;
|
|
}
|
|
|
|
return wpos;
|
|
}
|
|
|
|
void shift_array_left(uint8_t *in, int byte_length, int shift, uint8_t *out)
|
|
{
|
|
for (int i = 0; i < byte_length; i++)
|
|
out[i] = in[i + 0] << shift | in[i + 1] >> (8 - shift);
|
|
} |