diff options
Diffstat (limited to 'src/bin/escpos2raster.c')
-rw-r--r-- | src/bin/escpos2raster.c | 80 |
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; +} |