109 lines
2.2 KiB
C
109 lines
2.2 KiB
C
// intellectual property is bullshit bgdc
|
|
|
|
#include "ascii85.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <inttypes.h>
|
|
|
|
#define ASCII85_BASE 33
|
|
|
|
static inline uint8_t divmod85(uint32_t * x)
|
|
{
|
|
uint8_t mod = *x % 85;
|
|
*x /= 85;
|
|
return mod;
|
|
}
|
|
|
|
size_t ascii85_encode(uint8_t * dest, uint8_t const * src, size_t len)
|
|
{
|
|
size_t total = 0;
|
|
|
|
while (len >= 4)
|
|
{
|
|
uint32_t n = (
|
|
((uint32_t) src[0] << 24uL) |
|
|
((uint32_t) src[1] << 16uL) |
|
|
((uint32_t) src[2] << 8uL) |
|
|
((uint32_t) src[3] << 0uL));
|
|
|
|
dest[4] = divmod85(&n) + ASCII85_BASE;
|
|
dest[3] = divmod85(&n) + ASCII85_BASE;
|
|
dest[2] = divmod85(&n) + ASCII85_BASE;
|
|
dest[1] = divmod85(&n) + ASCII85_BASE;
|
|
dest[0] = n + ASCII85_BASE; // Guaranteed < 85
|
|
|
|
src += 4;
|
|
dest += 5;
|
|
len -= 4;
|
|
total += 5;
|
|
}
|
|
|
|
if (len)
|
|
{
|
|
uint32_t n = 0;
|
|
n = (uint32_t) src[0] << 24uL;
|
|
if (len > 1) n |= ((uint32_t) src[1] << 16uL);
|
|
if (len > 2) n |= ((uint32_t) src[2] << 8uL);
|
|
if (len > 3) n |= ((uint32_t) src[3] << 0uL);
|
|
|
|
char a85[5];
|
|
a85[4] = divmod85(&n) + ASCII85_BASE;
|
|
a85[3] = divmod85(&n) + ASCII85_BASE;
|
|
a85[2] = divmod85(&n) + ASCII85_BASE;
|
|
a85[1] = divmod85(&n) + ASCII85_BASE;
|
|
a85[0] = n + ASCII85_BASE; // As above
|
|
|
|
dest[0] = a85[0];
|
|
dest[1] = a85[1];
|
|
dest[2] = (len > 1) ? a85[2] : 0;
|
|
dest[3] = (len > 2) ? a85[3] : 0;
|
|
dest[4] = 0; // if we get here we're dropping at least one
|
|
|
|
total += len + 1;
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
size_t ascii85_decode(uint8_t * dest, uint8_t const * src, size_t len)
|
|
{
|
|
size_t total = 0;
|
|
|
|
while (len >= 5)
|
|
{
|
|
uint32_t n = src[0] - ASCII85_BASE;
|
|
n = 85 * n + src[1] - ASCII85_BASE;
|
|
n = 85 * n + src[2] - ASCII85_BASE;
|
|
n = 85 * n + src[3] - ASCII85_BASE;
|
|
n = 85 * n + src[4] - ASCII85_BASE;
|
|
|
|
dest[0] = (n >> 24uL) & 0xFF;
|
|
dest[1] = (n >> 16uL) & 0xFF;
|
|
dest[2] = (n >> 8uL) & 0xFF;
|
|
dest[3] = (n >> 0uL) & 0xFF;
|
|
|
|
src += 5;
|
|
dest += 4;
|
|
len -= 5;
|
|
total += 4;
|
|
}
|
|
|
|
if (len > 1)
|
|
{
|
|
uint32_t n = src[0] - ASCII85_BASE;
|
|
n = 85 * n + src[1] - ASCII85_BASE;
|
|
n = 85 * n + (len > 2 ? src[2] : 'u') - ASCII85_BASE;
|
|
n = 85 * n + (len > 3 ? src[3] : 'u') - ASCII85_BASE;
|
|
n = 85 * n;
|
|
|
|
dest[0] = (n >> 24uL) & 0xFF;
|
|
if (len > 2) dest[1] = (n >> 16uL) & 0xFF;
|
|
if (len > 3) dest[2] = (n >> 8uL) & 0xFF;
|
|
|
|
total += len - 1;
|
|
}
|
|
|
|
return total;
|
|
}
|