summaryrefslogtreecommitdiff
path: root/src/bin/escpos2raster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/escpos2raster.c')
-rw-r--r--src/bin/escpos2raster.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/bin/escpos2raster.c b/src/bin/escpos2raster.c
new file mode 100644
index 0000000..e4c9708
--- /dev/null
+++ b/src/bin/escpos2raster.c
@@ -0,0 +1,80 @@
+#include <escpos/parser.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <err.h>
+
+static FILE*
+fopen_or_die(const char *path, const char *mode)
+{
+ assert(path && mode);
+
+ FILE *f;
+ if (!(f = fopen(path, mode)))
+ err(EXIT_FAILURE, "fopen(%s, %s)", path, mode);
+
+ return f;
+}
+
+struct parser {
+ struct escpos_parser parser;
+ FILE *input, *output;
+};
+
+#define container_of(ptr, type, member) ((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))
+
+size_t
+escpos_read(const struct escpos_parser *parser, void *ptr, const size_t size)
+{
+ assert(parser && ptr);
+ const struct parser *p = container_of(parser, struct parser, parser);
+ return fread(ptr, 1, size, p->input);
+}
+
+void
+escpos_write(const struct escpos_parser *parser, const uint8_t *ptr, const size_t w, const size_t h)
+{
+ assert(parser && ptr);
+ const struct parser *p = container_of(parser, struct parser, parser);
+ const uint8_t header[] = { 'P', '4', '\n' };
+ fwrite(header, 1, sizeof(header), p->output);
+ fprintf(p->output, "%zu\n", w);
+ fprintf(p->output, "%zu\n", h);
+ for (size_t y = 0; y < h; ++y) {
+ for (size_t x = 0; x < w; x += 8) {
+ uint8_t p8 = 255;
+ for (uint8_t b = 0; b < 8 && x + b < w; ++b)
+ p8 ^= (-(!!ptr[y * w + x + b]) ^ p8) & (1 << (7 - b));
+ fwrite(&p8, 1, 1, p->output);
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ {
+#define CANVAS_W 256
+#define CANVAS_H 1024
+ char window[4096];
+ uint8_t canvas_data[CANVAS_W * CANVAS_H];
+ struct parser p = {
+ .parser = {
+ .read = escpos_read,
+ .write = escpos_write,
+ .canvas = { .data = canvas_data, .w = CANVAS_W, .h = CANVAS_H },
+ .window = { .data = window, sizeof(window) },
+ },
+ .input = (argc >= 2 ? fopen_or_die(argv[1], "rb") : stdin),
+ .output = (argc >= 3 ? fopen_or_die(argv[2], "wb") : stdout),
+ };
+
+ if (!escpos_parser_parse(&p.parser, (argc >= 2 ? argv[1] : "stdin")))
+ exit(EXIT_FAILURE);
+
+ fclose(p.input);
+ fclose(p.output);
+ }
+
+ return EXIT_SUCCESS;
+}