diff options
-rw-r--r-- | lpg/libqr/Makefile | 4 | ||||
-rw-r--r-- | lpg/libqr/code-common.c | 7 | ||||
-rw-r--r-- | lpg/libqr/code-common.h | 6 | ||||
-rw-r--r-- | lpg/libqr/code-create.c | 7 | ||||
-rw-r--r-- | lpg/libqr/code-layout.c | 4 | ||||
-rw-r--r-- | lpg/libqr/qr-bitmap-pbm.c | 47 | ||||
-rw-r--r-- | lpg/libqr/qr-bitmap-render.c (renamed from lpg/libqr/code-render.c) | 23 | ||||
-rw-r--r-- | lpg/libqr/qr-bitmap.c | 70 | ||||
-rw-r--r-- | lpg/libqr/qr-bitmap.h | 29 | ||||
-rw-r--r-- | lpg/libqr/qr/code.h | 8 | ||||
-rw-r--r-- | lpg/libqr/test.c | 2 |
11 files changed, 174 insertions, 33 deletions
diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile index e9783f6..1571de4 100644 --- a/lpg/libqr/Makefile +++ b/lpg/libqr/Makefile @@ -3,10 +3,12 @@ OBJECTS := bitstream.o \ code-create.o \ code-layout.o \ code-parse.o \ - code-render.o \ data-common.o \ data-create.o \ data-parse.o \ + qr-bitmap.o \ + qr-bitmap-pbm.o \ + qr-bitmap-render.o \ rs-encode.o CFLAGS := -std=c89 -pedantic -I. -Wall diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c index 25c1115..32f6492 100644 --- a/lpg/libqr/code-common.c +++ b/lpg/libqr/code-common.c @@ -2,11 +2,14 @@ #include <qr/code.h> #include "code-common.h" +#include "qr-bitmap.h" void qr_code_destroy(struct qr_code * code) { - free(code->modules); - free(code); + if (code) { + qr_bitmap_destroy(code->modules); + free(code); + } } int qr_code_width(const struct qr_code * code) diff --git a/lpg/libqr/code-common.h b/lpg/libqr/code-common.h index 17a45d7..fce8dce 100644 --- a/lpg/libqr/code-common.h +++ b/lpg/libqr/code-common.h @@ -3,11 +3,11 @@ #include <qr/code.h> #include "bitstream.h" +#include "qr-bitmap.h" struct qr_code { - int format; - unsigned char * modules; - size_t line_stride; + int format; + struct qr_bitmap * modules; }; int code_side_length(int format); diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c index a462ea3..5c0f2b7 100644 --- a/lpg/libqr/code-create.c +++ b/lpg/libqr/code-create.c @@ -29,10 +29,10 @@ static void x_dump(struct bitstream * bits) static void setpx(struct qr_code * code, int x, int y) { - size_t off = y * code->line_stride + x / CHAR_BIT; + size_t off = y * code->modules->stride + x / CHAR_BIT; unsigned char bit = 1 << (x % CHAR_BIT); - code->modules[off] |= bit; + code->modules->bits[off] |= bit; } static void draw_locator(struct qr_code * code, int x, int y) @@ -209,8 +209,7 @@ struct qr_code * qr_code_create(enum qr_ec_level ec, dim = code_side_length(data->format); code->format = data->format; - code->line_stride = dim / CHAR_BIT + ((dim % CHAR_BIT) ? 1 : 0); - code->modules = calloc(dim * code->line_stride, sizeof(unsigned char)); + code->modules = qr_bitmap_create(dim, dim, 0); if (!code->modules) goto fail; diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c index 228758a..09f29a8 100644 --- a/lpg/libqr/code-layout.c +++ b/lpg/libqr/code-layout.c @@ -36,8 +36,8 @@ static int is_data_bit(const struct qr_iterator * i) static void set_pointer(struct qr_iterator * i) { i->mask = 1 << (i->column % CHAR_BIT); - i->p = i->code->modules - + i->code->line_stride * i->row + i->p = i->code->modules->bits + + i->code->modules->stride * i->row + i->column / CHAR_BIT; } diff --git a/lpg/libqr/qr-bitmap-pbm.c b/lpg/libqr/qr-bitmap-pbm.c new file mode 100644 index 0000000..3bcddb2 --- /dev/null +++ b/lpg/libqr/qr-bitmap-pbm.c @@ -0,0 +1,47 @@ +#include <limits.h> +#include <stdio.h> +#include "qr-bitmap.h" + +int qr_bitmap_write_pbm(const char * path, + const char * comment, + const struct qr_bitmap * bmp) +{ + FILE * out; + size_t count, x, y; + + out = fopen(path, "w"); + if (!out) + return -1; + + count = 0; + + count += fputs("P1\n", out); + + if (comment) + count += fprintf(out, "# %s\n", comment); + + count += fprintf(out, "%u %u\n", + (unsigned)bmp->width, + (unsigned)bmp->height); + + for (y = 0; y < bmp->height; ++y) { + unsigned char * row = bmp->bits + y * bmp->stride; + + for (x = 0; x < bmp->width; ++x) { + int bit = row[x / CHAR_BIT] & (1 << x % CHAR_BIT); + + if (x > 0) + fputc(' ', out); + fputc(bit ? '1' : '0', out); + } + count += fputc('\n', out); + } + + if (ferror(out)) + count = -1; + + fclose(out); + + return count; +} + diff --git a/lpg/libqr/code-render.c b/lpg/libqr/qr-bitmap-render.c index cdffe24..4f6c921 100644 --- a/lpg/libqr/code-render.c +++ b/lpg/libqr/qr-bitmap-render.c @@ -1,9 +1,8 @@ #include <string.h> #include <limits.h> #include <assert.h> -#include <qr/code.h> -#include "code-common.h" +#include "qr-bitmap.h" /* CHAR_BIT | mod_bits (multi-byte) */ static void render_line_1(unsigned char * out, @@ -74,13 +73,13 @@ static void render_line_2(unsigned char * out, } } -void qr_code_render(const struct qr_code * code, - void * buffer, - size_t mod_bits, - size_t line_stride, - size_t line_repeat, - unsigned long mark, - unsigned long space) +void qr_bitmap_render(const struct qr_bitmap * bmp, + void * buffer, + size_t mod_bits, + size_t line_stride, + size_t line_repeat, + unsigned long mark, + unsigned long space) { unsigned char * out; const unsigned char * in; @@ -91,9 +90,9 @@ void qr_code_render(const struct qr_code * code, assert(!pack || (CHAR_BIT % mod_bits == 0)); assert( pack || (mod_bits % CHAR_BIT == 0)); - in = code->modules; + in = bmp->bits; out = buffer; - dim = qr_code_width(code); + dim = bmp->width; n = dim; while (n-- > 0) { @@ -112,7 +111,7 @@ void qr_code_render(const struct qr_code * code, next += line_stride; } - in += code->line_stride; + in += bmp->stride; out = next; } } diff --git a/lpg/libqr/qr-bitmap.c b/lpg/libqr/qr-bitmap.c new file mode 100644 index 0000000..e42b550 --- /dev/null +++ b/lpg/libqr/qr-bitmap.c @@ -0,0 +1,70 @@ +#include <assert.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include "qr-bitmap.h" + +struct qr_bitmap * qr_bitmap_create(int width, int height, int masked) +{ + struct qr_bitmap * out; + size_t size; + + out = malloc(sizeof(*out)); + if (!out) + goto fail; + + out->width = width; + out->height = height; + out->stride = (width / CHAR_BIT) + (width % CHAR_BIT ? 1 : 0); + + size = out->stride * height; + + out->mask = 0; + out->bits = malloc(size); + if (!out->bits) + goto fail; + memset(out->bits, 0, size); + + if (masked) { + out->mask = malloc(out->stride * width); + if (!out->mask) + goto fail; + memset(out->bits, 0xFF, size); + } + + return out; + +fail: + qr_bitmap_destroy(out); + return 0; +} + +void qr_bitmap_destroy(struct qr_bitmap * bmp) +{ + if (bmp) { + free(bmp->bits); + free(bmp->mask); + free(bmp); + } +} + +void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src) +{ + unsigned char * d, * s, * m; + size_t n; + + assert(dest->stride == src->stride); + assert(dest->height == src->height); + assert(src->mask); + + n = dest->stride * dest->height; + d = dest->bits; + s = src->bits; + m = src->mask; + + while (n--) { + *d &= ~*m; + *d++ |= *s++ & *m++; + } +} + diff --git a/lpg/libqr/qr-bitmap.h b/lpg/libqr/qr-bitmap.h new file mode 100644 index 0000000..d60049a --- /dev/null +++ b/lpg/libqr/qr-bitmap.h @@ -0,0 +1,29 @@ +#ifndef QR_BITMAP_H +#define QR_BITMAP_H + +struct qr_bitmap { + unsigned char * bits; + unsigned char * mask; + size_t stride; + size_t width, height; +}; + +struct qr_bitmap * qr_bitmap_create(int width, int height, int masked); +void qr_bitmap_destroy(struct qr_bitmap *); + +void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src); + +void qr_bitmap_render(const struct qr_bitmap * bmp, + void * buffer, + size_t mod_bits, + size_t line_stride, + size_t line_repeat, + unsigned long mark, + unsigned long space); + +int qr_bitmap_write_pbm(const char * path, + const char * comment, + const struct qr_bitmap * bmp); + +#endif + diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h index 6ae1aa9..56a9884 100644 --- a/lpg/libqr/qr/code.h +++ b/lpg/libqr/qr/code.h @@ -23,13 +23,5 @@ struct qr_code * qr_code_parse(const void * buffer, size_t line_stride, size_t line_count); -void qr_code_render(const struct qr_code * code, - void * buffer, - size_t mod_bits, - size_t line_stride, - size_t line_repeat, - unsigned long mark, - unsigned long space); - #endif diff --git a/lpg/libqr/test.c b/lpg/libqr/test.c index f51b90b..035908b 100644 --- a/lpg/libqr/test.c +++ b/lpg/libqr/test.c @@ -38,7 +38,7 @@ int main() { char buf[80*25]; int x, y; - qr_code_render(code, buf, 8, 80, 0, 1, 0); + qr_bitmap_render(code->modules, buf, 8, 80, 0, 1, 0); for (y=0;y<21;++y) { printf("\t|"); for (x=0;x<21;++x) { |