From f98a0310e24a699e00e29d86aa26e25945615869 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 18 Apr 2020 16:30:45 +0100 Subject: [PATCH] Initial commit --- bin2csv.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ csv2bin.c | 80 ++++++++++++++++++++++++++++++++++++++ int2float.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ makefile | 33 ++++++++++++++++ normfloat.c | 85 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 402 insertions(+) create mode 100644 bin2csv.c create mode 100644 csv2bin.c create mode 100644 int2float.c create mode 100644 makefile create mode 100644 normfloat.c diff --git a/bin2csv.c b/bin2csv.c new file mode 100644 index 0000000..2c68a68 --- /dev/null +++ b/bin2csv.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include + +#define CHUNK_DEFAULT (0x1000) + +int +usage(const char* progname) +{ + fprintf(stderr, "usage: %s [-c chunk [-n]] <-s size | -u size | -f size | -d size>\n", progname); + return 1; +} + +int +main(int argc, char** argv) +{ + int optch; + int cflag = 0; + const char* carg = NULL; + int nflag = 0; + enum { INV = -1, INT, UINT, FLOAT, DOUBLE } tflag = INV; + const char* sizearg = NULL; + + while ((optch = getopt(argc, argv, "c:ns:u:f:d:h")) != -1) { + switch (optch) { + case 'c': + cflag = 1; + carg = optarg; + break; + case 'n': + nflag = cflag; + break; + case 's': + tflag = INT; + sizearg = optarg; + break; + case 'u': + tflag = UINT; + sizearg = optarg; + break; + case 'f': + tflag = FLOAT; + sizearg = optarg; + break; + case 'd': + tflag = DOUBLE; + sizearg = optarg; + break; + case 'h': + default: + return usage(*argv); + } + } + + if (tflag == INV) + return usage(*argv); + + size_t membsize = strtoull(sizearg, NULL, 10); + size_t chunk = cflag? strtoull(carg, NULL, 10) : CHUNK_DEFAULT; + + uint8_t* buffer = aligned_alloc(0x40, chunk * membsize); + size_t rd; + + if (buffer == NULL) + err(1, "malloc()"); + + while ((rd = fread(buffer, membsize, chunk, stdin))) { + for (size_t i = 0; i < rd; ++i) { + switch (tflag) { + case INT: { + int64_t v; + memcpy(&v, &buffer[i * membsize], membsize); + fprintf(stdout, "%ld,", v); + break; + } + case UINT: { + uint64_t v; + memcpy(&v, &buffer[i * membsize], membsize); + fprintf(stdout, "%lu,", v); + break; + } + case FLOAT: { + float v; + memcpy(&v, &buffer[i * membsize], membsize); + fprintf(stdout, "%f,", v); + break; + } + case DOUBLE: { + double v; + memcpy(&v, &buffer[i * membsize], membsize); + fprintf(stdout, "%lf,", v); + break; + } + case INV: + return 1; + } + } + + if (nflag) + fputs("\n", stdout); + + fflush(stdout); + } + + return 0; +} + diff --git a/csv2bin.c b/csv2bin.c new file mode 100644 index 0000000..da8f369 --- /dev/null +++ b/csv2bin.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include + +#define CHUNK_DEFAULT (0x1000) + +int +usage(const char* progname) +{ + fprintf(stderr, "usage: %s [-c chunk] <-s size | -u size | -f size | -d size>\n", progname); + return 1; +} + +int +main(int argc, char** argv) +{ + int optch; + int cflag = 0; + const char* carg = NULL; + enum { INV = -1, INT, UINT, FLOAT, DOUBLE } tflag = INV; + const char* sizearg = NULL; + + while ((optch = getopt(argc, argv, "c:s:u:f:d:h")) != -1) { + switch (optch) { + case 'c': + cflag = 1; + carg = optarg; + break; + case 's': + tflag = INT; + sizearg = optarg; + break; + case 'u': + tflag = UINT; + sizearg = optarg; + break; + case 'f': + tflag = FLOAT; + sizearg = optarg; + break; + case 'd': + tflag = FLOAT; + sizearg = optarg; + break; + case 'h': + default: + return usage(*argv); + } + } + + if (tflag == INV) + return usage(*argv); + + const char* fmt = (char*[]){ "%d,", "%u,", "%f,", "%lf," }[tflag]; + + size_t membsize = strtoull(sizearg, NULL, 10); + size_t chunk = cflag? strtoull(carg, NULL, 10) : CHUNK_DEFAULT; + + uint8_t* buffer = aligned_alloc(0x40, chunk * membsize); + + if (buffer == NULL) + err(1, "malloc()"); + + while (!feof(stdin)) { + size_t i; + + for (i = 0; i < chunk; ++i) { + if (scanf(fmt, &buffer[i * membsize]) != 1) + break; + } + + fwrite(buffer, membsize, i, stdout); + } + + return 0; +} + diff --git a/int2float.c b/int2float.c new file mode 100644 index 0000000..a8f9210 --- /dev/null +++ b/int2float.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include + +#define CHUNK_DEFAULT (0x1000) + +#define MIN(a, b) (a < b? a : b) +#define MAX(a, b) (a > b? a : b) + +int +usage(const char* progname) +{ + fprintf(stderr, "usage: %s [-c chunk] <-s size | -u size>\n", progname); + return 1; +} + +int +main(int argc, char** argv) +{ + int optch; + int cflag = 0; + const char* carg = NULL; + enum { INV = -1, INT, UINT } tflag = INV; + const char* sizearg = NULL; + + while ((optch = getopt(argc, argv, "c:s:u:h")) != -1) { + switch (optch) { + case 'c': + cflag = 1; + carg = optarg; + break; + case 's': + tflag = INT; + sizearg = optarg; + break; + case 'u': + tflag = UINT; + sizearg = optarg; + break; + case 'h': + default: + return usage(*argv); + } + } + + if (tflag == INV) + return usage(*argv); + + size_t membsize = strtoull(sizearg, NULL, 10); + size_t chunk = cflag? strtoull(carg, NULL, 10) : CHUNK_DEFAULT; + + uint8_t* intbuffer = aligned_alloc(0x40, chunk * membsize); + float* floatbuffer = aligned_alloc(0x40, chunk * sizeof(float)); + size_t rd; + + if (intbuffer == NULL || floatbuffer == NULL) + err(1, "malloc()"); + + while ((rd = fread(intbuffer, membsize, chunk, stdin))) { + for (size_t i = 0; i < rd; ++i) { + void* p = &intbuffer[i * membsize]; + switch (tflag) { + case INT: + switch (membsize) { + case 1: floatbuffer[i] = (float)*(int8_t*)p; break; + case 2: floatbuffer[i] = (float)*(int16_t*)p; break; + case 4: floatbuffer[i] = (float)*(int32_t*)p; break; + case 8: floatbuffer[i] = (float)*(int64_t*)p; break; + default: errx(1, "invalid size"); + } + break; + case UINT: + switch (membsize) { + case 1: floatbuffer[i] = (float)*(int8_t*)p; break; + case 2: floatbuffer[i] = (float)*(int16_t*)p; break; + case 4: floatbuffer[i] = (float)*(int32_t*)p; break; + case 8: floatbuffer[i] = (float)*(int64_t*)p; break; + default: errx(1, "invalid size"); + } + break; + default: + errx(1, "invalid type"); + } + } + + fwrite(floatbuffer, sizeof(float), rd, stdout); + } + + return 0; +} + diff --git a/makefile b/makefile new file mode 100644 index 0000000..5371001 --- /dev/null +++ b/makefile @@ -0,0 +1,33 @@ +.POSIX: +.PHONY: all install clean + +PREFIX=/usr/local + +TARGETS=bin2csv\ + csv2bin\ + int2float\ + normfloat + +CC=cc +CFLAGS=-Wall -Wextra -Wshadow -Wpedantic -std=c99 -O2 + +all: $(TARGETS) + +bin2csv: bin2csv.c + $(CC) $? $(CFLAGS) -o $@ + +csv2bin: csv2bin.c + $(CC) $? $(CFLAGS) -o $@ + +normfloat: normfloat.c + $(CC) $? $(CFLAGS) -o $@ + +int2float: int2float.c + $(CC) $? $(CFLAGS) -o $@ + +clean: + rm $(TARGETS) + +install: $(TARGETS) + cp $? $(PREFIX)/bin/ + diff --git a/normfloat.c b/normfloat.c new file mode 100644 index 0000000..b9951c8 --- /dev/null +++ b/normfloat.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +#define CHUNK_DEFAULT (0x1000) + +#define MIN(a, b) (a < b? a : b) +#define MAX(a, b) (a > b? a : b) + +int +usage(const char* progname) +{ + fprintf(stderr, "usage: %s [-c chunk] [-m mul] [-s start] [-e end]\n", progname); + return 1; +} + +int +main(int argc, char** argv) +{ + int optch; + int cflag = 0; + const char* carg = NULL; + int mflag = 0; + const char* marg = NULL; + int sflag = 0; + const char* sarg = NULL; + int eflag = 0; + const char* earg = NULL; + + while ((optch = getopt(argc, argv, "c:m:s:e:h")) != -1) { + switch (optch) { + case 'c': + cflag = 1; + carg = optarg; + break; + case 'm': + mflag = 1; + marg = optarg; + break; + case 's': + sflag = 1; + sarg = optarg; + break; + case 'e': + eflag = 1; + earg = optarg; + break; + case 'h': + default: + return usage(*argv); + } + } + + size_t chunk = cflag? strtoull(carg, NULL, 10) : CHUNK_DEFAULT; + float mul = mflag? strtof(marg, NULL) : 1.0f; + size_t start = sflag? strtoull(sarg, NULL, 10) : 0; + size_t end = eflag? strtoull(earg, NULL, 10) : chunk; + + float* buffer = aligned_alloc(0x40, chunk * sizeof(float)); + size_t rd; + + if (buffer == NULL) + err(1, "malloc()"); + + while ((rd = fread(buffer, sizeof(float), chunk, stdin))) { + float min = buffer[start]; + float max = buffer[start]; + + for (size_t i = start; i < MIN(rd, end); ++i) { + min = MIN(min, buffer[i]); + max = MAX(max, buffer[i]); + } + + for (size_t i = start; i < MIN(rd, end); ++i) { + buffer[i] = mul * (buffer[i] - min) / (max - min); + } + + fwrite(buffer, sizeof(float), rd, stdout); + } + + return 0; +} +