aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lpg/libqr/Makefile4
-rw-r--r--lpg/libqr/code-common.c7
-rw-r--r--lpg/libqr/code-common.h6
-rw-r--r--lpg/libqr/code-create.c7
-rw-r--r--lpg/libqr/code-layout.c4
-rw-r--r--lpg/libqr/qr-bitmap-pbm.c47
-rw-r--r--lpg/libqr/qr-bitmap-render.c (renamed from lpg/libqr/code-render.c)23
-rw-r--r--lpg/libqr/qr-bitmap.c70
-rw-r--r--lpg/libqr/qr-bitmap.h29
-rw-r--r--lpg/libqr/qr/code.h8
-rw-r--r--lpg/libqr/test.c2
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) {