Skip to content

Instantly share code, notes, and snippets.

@jkbonfield
Created May 23, 2019 19:41
Show Gist options
  • Save jkbonfield/65cd8c9d968acbe683f6f1e920c9a6a1 to your computer and use it in GitHub Desktop.
Save jkbonfield/65cd8c9d968acbe683f6f1e920c9a6a1 to your computer and use it in GitHub Desktop.
ONT signal compression
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#ifndef MAXD
#define MAXD 15
#endif
unsigned char *encode(unsigned char *data, uint64_t len, uint64_t *out_len) {
uint64_t i, j;
signed short *in = (signed short *)data;
unsigned char *out = malloc(len*2);
int p = 0;
len /= 2;
for (i = 0, j = 0; i < len; i++) {
int d = in[i]-p;
if (d >= -127 && d < 127) {
out[j++] = d;
} else {
out[j++] = -128;
d = (d<0) ? -d*2+1 : d*2;
out[j++] = d&0xff;
out[j++] = (d>>8)&0xff;
}
// Slight differences imply average with previous value to
// smooth out noise, while large differences imply a big jump
// so use this value as predictor.
if (d >= -MAXD && d <= MAXD)
p = (p + in[i])>>1;
else
p = in[i];
}
*out_len = j;
return out;
}
unsigned char *decode(unsigned char *data, uint64_t len, uint64_t *out_len) {
uint64_t i = 0, j = 0;
signed char *in = (signed char *)data;
signed short *out = malloc(len*2);
int p = 0;
while (i < len) {
int d = in[i++];
if (d == -128) {
d = (unsigned char)in[i++];
d += ((unsigned char)in[i++])<<8;
d = (d&1) ? -(d>>1) : (d>>1);
}
out[j++] = d + p;
if (d >= -MAXD && d <= MAXD)
p = (p + out[j-1])>>1;
else
p = out[j-1];
}
*out_len = j*2;
return (unsigned char *)out;
}
#define BS 1024*1024
static unsigned char *load(uint64_t *lenp) {
unsigned char *data = NULL;
uint64_t dsize = 0;
uint64_t dcurr = 0;
signed int len;
do {
if (dsize - dcurr < BS) {
dsize = dsize ? dsize * 2 : BS;
data = realloc(data, dsize);
}
len = read(0, data + dcurr, BS);
if (len > 0)
dcurr += len;
} while (len > 0);
if (len == -1) {
perror("read");
}
*lenp = dcurr;
return data;
}
int main(int argc, char **argv) {
uint64_t len;
unsigned char *in = load(&len), *out;
if (argc > 1 && strcmp(argv[1], "-d") == 0) {
out = decode(in, len, &len);
} else {
out = encode(in, len, &len);
}
if (write(1, out, len) != len)
abort();
free(in);
free(out);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment