From 1349e7a3e3dc15a9ac5e571a3b941bf6883cf8bb Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Mon, 28 Sep 2009 23:40:34 +0900
Subject: apply (incorrect!) mask to generated code

---
 lpg/libqr/code-create.c | 69 ++++++++++++++++++++++++++++++++++++-------------
 lpg/libqr/code-layout.c | 52 ++++++++++++++++++++++++++++---------
 lpg/libqr/code-layout.h |  4 ++-
 lpg/libqr/qr-bitmap.c   |  2 +-
 4 files changed, 95 insertions(+), 32 deletions(-)

(limited to 'lpg')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index c6451ac..ef419d3 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -6,10 +6,15 @@
 #include "code-common.h"
 #include "code-layout.h"
 #include "data-common.h"
+#include "qr-mask.h"
 #include "rs.h"
 
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
+/* FIXME: the static functions should be in a better
+ * order, with prototypes.
+ */
+
 #include <stdio.h>
 static void x_dump(struct qr_bitstream * bits)
 {
@@ -27,44 +32,64 @@ static void x_dump(struct qr_bitstream * bits)
         printf("\n");
 }
 
-static void setpx(struct qr_code * code, int x, int y)
+static int mask_data(struct qr_code * code)
+{
+        /* XXX */
+        code->modules = qr_mask_apply(code->modules, 2);
+        return 2;
+}
+
+static void setpx(struct qr_bitmap * bmp, int x, int y)
 {
-        size_t off = y * code->modules->stride + x / CHAR_BIT;
+        size_t off = y * bmp->stride + x / CHAR_BIT;
         unsigned char bit = 1 << (x % CHAR_BIT);
 
-        code->modules->bits[off] |= bit;
+        bmp->bits[off] |= bit;
 }
 
-static void draw_locator(struct qr_code * code, int x, int y)
+static void draw_locator(struct qr_bitmap * bmp, int x, int y)
 {
         int i;
         for (i = 0; i < 6; ++i) {
-                setpx(code, x + i, y + 0);
-                setpx(code, x + 6, y + i);
-                setpx(code, x + i + 1, y + 6);
-                setpx(code, x, y + i + 1);
+                setpx(bmp, x + i, y + 0);
+                setpx(bmp, x + 6, y + i);
+                setpx(bmp, x + i + 1, y + 6);
+                setpx(bmp, x, y + i + 1);
         }
         for (i = 0; i < 9; ++i)
-                setpx(code, x + 2 + i % 3, y + 2 + i / 3);
+                setpx(bmp, x + 2 + i % 3, y + 2 + i / 3);
 }
 
-static void draw_fixed_bits(struct qr_code * code)
+static int draw_functional(struct qr_code * code,
+                           unsigned int mask)
 {
+        struct qr_bitmap * bmp;
         int dim = code_side_length(code->format);
         int i;
 
+        bmp = qr_bitmap_create(dim, dim, 0);
+        if (!bmp)
+                return -1;
+
         /* Locator pattern */
-        draw_locator(code, 0, 0);
-        draw_locator(code, 0, dim - 7);
-        draw_locator(code, dim - 7, 0);
+        draw_locator(bmp, 0, 0);
+        draw_locator(bmp, 0, dim - 7);
+        draw_locator(bmp, dim - 7, 0);
 
         /* Timing pattern */
         for (i = 8; i < dim - 8; i += 2) {
-                setpx(code, i, 6);
-                setpx(code, 6, i);
+                setpx(bmp, i, 6);
+                setpx(bmp, 6, i);
         }
 
         /* XXX: alignment pattern */
+        /* XXX: mask, format info */
+
+        qr_bitmap_merge(bmp, code->modules);
+        qr_bitmap_destroy(code->modules);
+        code->modules = bmp;
+
+        return 0;
 }
 
 static int pad_data(struct qr_bitstream * bits, size_t limit)
@@ -200,6 +225,7 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         struct qr_code * code;
         struct qr_bitstream * bits = 0;
         struct qr_iterator * layout;
+        int mask;
         size_t dim;
 
         code = malloc(sizeof(*code));
@@ -209,17 +235,17 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         dim = code_side_length(data->format);
 
         code->format = data->format;
-        code->modules = qr_bitmap_create(dim, dim, 0);
+        code->modules = qr_bitmap_create(dim, dim, 1);
 
         if (!code->modules)
                 goto fail;
 
-        draw_fixed_bits(code);
-
         bits = make_data(data->format, ec, data->bits);
         if (!bits)
                 goto fail;
 
+        qr_layout_init_mask(code);
+
         layout = qr_layout_begin(code);
         if (!layout)
                 goto fail;
@@ -229,6 +255,13 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
                 qr_layout_write(layout, qr_bitstream_read(bits, 8));
         qr_layout_end(layout);
 
+        mask = mask_data(code);
+        if (mask < 0)
+                goto fail;
+
+        if (draw_functional(code, mask) != 0)
+                goto fail;
+
 exit:
         if (bits)
                 qr_bitstream_destroy(bits);
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 09f29a8..46d2800 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -1,7 +1,10 @@
+#include <assert.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <string.h>
 #include "code-common.h"
 #include "code-layout.h"
+#include "qr-bitmap.h"
 
 struct qr_iterator {
         struct qr_code * code;
@@ -13,24 +16,49 @@ struct qr_iterator {
         unsigned char * p;
 };
 
-static int is_data_bit(const struct qr_iterator * i)
+void qr_layout_init_mask(struct qr_code * code)
 {
-        if (i->row == 6 || i->column == 6) /* timing */
-                return 0;
+        int x, y;
+        int dim = code_side_length(code->format);
+        struct qr_bitmap * bmp = code->modules;
+
+        assert(bmp->mask);
+
+        memset(bmp->mask, 0, bmp->height * bmp->stride);
+
+        /* slow and stupid, but I'm sleepy */
+        for (y = 0; y < bmp->height; ++y) {
+                unsigned char * row = bmp->mask + y * bmp->stride;
+                for (x = 0; x < bmp->width; ++x) {
+                        unsigned char bit = 1 << (x % CHAR_BIT);
+                        int off = x / CHAR_BIT;
+
+                        if (x == 6 || y == 6) /* timing */
+                                continue;
+
+                        if (x < 9 && y < 9) /* top-left */
+                                continue;
 
-        if (i->column < 9 && i->row < 9) /* top-left */
-                return 0;
+                        if (x >= dim - 8 && y < 9) /* top-right */
+                                continue;
 
-        if (i->column >= i->dim - 8 && i->row < 9) /* top-right */
-                return 0;
+                        if (x < 9 && y >= dim - 8) /* bottom-left */
+                                continue;
 
-        if (i->column < 9 && i->row >= i->dim - 8) /* bottom-left */
-                return 0;
+                        /* XXX: format data */
+                        /* XXX: alignment pattern */
 
-        /* XXX: format data */
-        /* XXX: alignment pattern */
+                        row[off] |= bit;
+                }
+        }
+}
+
+static int is_data_bit(const struct qr_iterator * i)
+{
+        unsigned char bit = 1 << (i->column % CHAR_BIT);
+        int off = (i->row * i->code->modules->stride) + (i->column / CHAR_BIT);
 
-        return 1;
+        return i->code->modules->mask[off] & bit;
 }
 
 static void set_pointer(struct qr_iterator * i)
diff --git a/lpg/libqr/code-layout.h b/lpg/libqr/code-layout.h
index 79e9730..3390548 100644
--- a/lpg/libqr/code-layout.h
+++ b/lpg/libqr/code-layout.h
@@ -3,7 +3,9 @@
 
 struct qr_iterator;
 
-struct qr_iterator * qr_layout_begin(struct qr_code *);
+void qr_layout_init_mask(struct qr_code *);
+
+struct qr_iterator * qr_layout_begin(struct qr_code * code);
 unsigned int qr_layout_read(struct qr_iterator *);
 void qr_layout_write(struct qr_iterator *, unsigned int);
 void qr_layout_end(struct qr_iterator *);
diff --git a/lpg/libqr/qr-bitmap.c b/lpg/libqr/qr-bitmap.c
index 1a5ca52..2bd0c50 100644
--- a/lpg/libqr/qr-bitmap.c
+++ b/lpg/libqr/qr-bitmap.c
@@ -29,7 +29,7 @@ struct qr_bitmap * qr_bitmap_create(int width, int height, int masked)
                 out->mask = malloc(out->stride * width);
                 if (!out->mask)
                         goto fail;
-                memset(out->bits, 0xFF, size);
+                memset(out->mask, 0xFF, size);
         }
 
         return out;
-- 
cgit v1.2.3-70-g09d2