summaryrefslogtreecommitdiffstats
path: root/multimedia/munt/interleave.c
diff options
context:
space:
mode:
Diffstat (limited to 'multimedia/munt/interleave.c')
-rw-r--r--multimedia/munt/interleave.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/multimedia/munt/interleave.c b/multimedia/munt/interleave.c
new file mode 100644
index 0000000000..20b666ae12
--- /dev/null
+++ b/multimedia/munt/interleave.c
@@ -0,0 +1,93 @@
+/* interleave.c - B. Watson, April 2023, WTFPL licensed.
+
+ Given two files of the same size, creates a 3rd file whose contents are:
+
+ file 1, byte 1
+ file 2, byte 1
+ file 1, byte 2
+ file 2, byte 2
+ file 1, byte 3
+ file 2, byte 3
+ ...etc.
+
+ If file1 contains "foo" and file2 contains "bar", the output will
+ be "fboaor". The output is always twice the size of one of the
+ input files (or, the same size as both input files combined).
+
+ Output file is silently overwritten if it already exists.
+
+ Exit status is 0 for success, non-zero for failure, with a hopefully
+ useful error message.
+
+ Compile me with:
+ gcc -Wall -O2 -o interleave interleave.c
+
+ This could be done more efficiently and without an artificial file
+ size limit, but the current implementation reads everything into a
+ statically sized buffer for simpliticy.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define MAX_SIZE (1024 * 1024)
+
+unsigned char blob1[MAX_SIZE + 1], blob2[MAX_SIZE + 1], output[MAX_SIZE * 2 + 1];
+
+void die(const char *msg) {
+ if(msg)
+ fprintf(stderr, "interleave: %s\n", msg);
+ else
+ perror("interleave");
+ exit(1);
+}
+
+int read_file(const char *fname, unsigned char *dest) {
+ int bytes;
+ FILE *f = fopen(fname, "rb");
+
+ if(!f) die(NULL);
+ if( (bytes = fread(dest, 1, MAX_SIZE + 1, f)) < 1 ) die(NULL);
+ fclose(f);
+
+ /* fprintf(stderr, "read %d bytes from %s\n", bytes, fname); */
+
+ return bytes;
+}
+
+void write_output(const char *fname, int bytes) {
+ int i;
+ unsigned char *p = output;
+ FILE *f = fopen(fname, "wb");
+
+ if(!f) die(NULL);
+
+ for(i = 0; i < bytes; i++) {
+ *p++ = blob1[i];
+ *p++ = blob2[i];
+ }
+
+ if( (fwrite(output, 1, bytes * 2, f)) < (bytes * 2) ) die(NULL);
+
+ fclose(f);
+}
+
+int main(int argc, char **argv) {
+ int size1, size2;
+
+ if(argc != 4)
+ die("usage:\n\tinterleave <input1> <input2> <output>");
+
+ size1 = read_file(argv[1], blob1);
+ size2 = read_file(argv[2], blob2);
+
+ if(size1 > MAX_SIZE)
+ die("input file too big (max 1MB each)");
+ if(size1 != size2)
+ die("input files are not the same size");
+
+ write_output(argv[3], size1);
+
+ return 0;
+}