From ef01767c732629b7eff7d1601e76a1bac58f5bfd Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sat, 5 Sep 2009 09:33:22 +0900
Subject: The story so far

---
 lpg/libqr/code-create.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)
 create mode 100644 lpg/libqr/code-create.c

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
new file mode 100644
index 0000000..d09c2fe
--- /dev/null
+++ b/lpg/libqr/code-create.c
@@ -0,0 +1,121 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
+#include <qr/code.h>
+
+#include "code-common.h"
+#include "data-common.h"
+
+#define MIN(a, b) ((b) < (a) ? (b) : (a))
+
+#include <stdio.h>
+static void x_dump(struct bitstream * bits)
+{
+        size_t i, n;
+
+        bitstream_seek(bits, 0);
+        n = bitstream_size(bits);
+        for (i = 0; i < n; ++i) {
+                printf("%d", bitstream_read(bits, 1));
+                if (i % 8 == 7)
+                        printf(" ");
+                if ((i+1) % (7 * 8) == 0)
+                        printf("\n");
+        }
+        printf("\n");
+}
+
+static int add_ecc(struct bitstream * bits, int format, enum qr_ec_level ec)
+{
+        puts("Before ecc:");
+        x_dump(bits);
+
+        return -1;
+}
+
+static int pad_data(struct bitstream * bits, size_t limit)
+{
+        /* This function is not very nice. Sorry. */
+
+        size_t count, n;
+
+        assert(bitstream_size(bits) <= limit);
+
+        if (bitstream_resize(bits, limit) != 0)
+                return -1;
+
+        n = bitstream_size(bits);
+        bitstream_seek(bits, n);
+        count = limit - n;
+
+        /* First append the terminator (0000) if possible,
+         * and pad with zeros up to an 8-bit boundary
+         */
+        n = (n + 4) % 8;
+        if (n != 0)
+                n = 8 - n;
+        n = MIN(count, n + 4);
+        bitstream_write(bits, 0, n);
+        count -= n;
+
+        assert(count % 8 == 0); /* since data codewords are 8 bits */
+
+        /* Finally pad with the repeating sequence 11101100 00010001 */
+        while (count >= 16) {
+                bitstream_write(bits, 0xEC11, 16);
+                count -= 16;
+        }
+        if (count > 0) {
+                assert(count == 8);
+                bitstream_write(bits, 0xEC, 8);
+        }
+
+        return 0;
+}
+
+static struct bitstream * make_data(int                format,
+                                    enum qr_ec_level   ec,
+                                    struct bitstream * data)
+{
+        size_t data_bits = 16 * 8 /*XXX*/;
+        struct bitstream * out;
+
+        out = bitstream_copy(data);
+        if (!out)
+                return 0;
+
+        if (pad_data(out, data_bits) != 0)
+                goto fail;
+
+        if (add_ecc(out, format, ec) != 0)
+                goto fail;
+
+        return out;
+fail:
+        bitstream_destroy(out);
+        return 0;
+}
+
+struct qr_code * qr_code_create(enum qr_ec_level       ec,
+                                const struct qr_data * data)
+{
+        struct qr_code * code;
+        struct bitstream * ecdata;
+
+        code = malloc(sizeof(*code));
+        if (!code)
+                return 0;
+
+        code->format = data->format;
+        ecdata = make_data(data->format, ec, data->bits);
+
+        if (!ecdata) {
+                free(code);
+                return 0;
+        }
+
+        /* TODO: allocate bitmap; layout */
+
+        return 0;
+}
+
-- 
cgit v1.2.3-70-g09d2


From 55d8ac4768d03001b746ce0af0ad0e15031e4041 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Tue, 15 Sep 2009 07:56:20 +0900
Subject: RS encode (not working yet)

---
 lpg/libqr/Makefile      |  3 ++-
 lpg/libqr/code-create.c | 11 ++++++++++-
 lpg/libqr/rs-encode.c   | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/rs.h          |  9 +++++++++
 lpg/libqr/test.c        |  1 +
 5 files changed, 69 insertions(+), 2 deletions(-)
 create mode 100644 lpg/libqr/rs-encode.c
 create mode 100644 lpg/libqr/rs.h

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index e36b09f..1f34caf 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -5,7 +5,8 @@ OBJECTS :=      bitstream.o     \
                 code-render.o   \
                 data-common.o   \
                 data-create.o   \
-                data-parse.o
+                data-parse.o	\
+                rs-encode.o
 
 CFLAGS := -std=c89 -pedantic -I. -Wall
 CFLAGS += -g
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index d09c2fe..484dbe3 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -5,6 +5,7 @@
 
 #include "code-common.h"
 #include "data-common.h"
+#include "rs.h"
 
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
@@ -29,7 +30,15 @@ static int add_ecc(struct bitstream * bits, int format, enum qr_ec_level ec)
 {
         puts("Before ecc:");
         x_dump(bits);
-
+        {
+                const int g[10] = { 251, 67, 61, 118, 70, 64, 94, 32, 45 };
+                int rs_words = 10; /* 1-M */
+                struct bitstream * rs;
+
+                rs = rs_generate_words(rs_words, g, bits);
+                puts("ecc part:");
+                x_dump(rs);
+        }
         return -1;
 }
 
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
new file mode 100644
index 0000000..ec99c6b
--- /dev/null
+++ b/lpg/libqr/rs-encode.c
@@ -0,0 +1,47 @@
+#include <assert.h>
+#include <stdlib.h>
+#include "bitstream.h"
+#include "rs.h"
+
+struct bitstream * rs_generate_words(int k, const int * coeff, struct bitstream * data)
+{
+        struct bitstream * ec = 0;
+        unsigned int * b = 0;
+        size_t n, i, dlen;
+
+        dlen = bitstream_size(data);
+        assert(dlen % 8 == 0);
+        dlen /= 8;
+
+        ec = bitstream_create();
+        if (!ec)
+                return 0;
+
+        if (bitstream_resize(ec, k * 8) != 0)
+                goto fail;
+
+        b = calloc(k, sizeof(*b));
+        if (!b)
+                goto fail;
+
+        /* First, prepare the registers (b) with data bits. Note that
+         * the registers are in reverse of the normal order
+         */
+        bitstream_seek(data, 0);
+        for (n = 0; n < dlen; ++n) {
+                unsigned int x = b[0] + bitstream_read(data, 8);
+                for (i = 0; i < k-1; ++i)
+                        b[i] = b[i+1] + coeff[(k-1) - i] * x;
+                b[k-1] = coeff[0] * x;
+        }
+
+        /* Read off the registers */
+        bitstream_pack(ec, b, k, 8);
+
+        free(b);
+        return ec;
+fail:
+        bitstream_destroy(ec);
+        return 0;
+}
+
diff --git a/lpg/libqr/rs.h b/lpg/libqr/rs.h
new file mode 100644
index 0000000..98e3aa0
--- /dev/null
+++ b/lpg/libqr/rs.h
@@ -0,0 +1,9 @@
+#ifndef RS_H
+#define RS_H
+
+#include "bitstream.h"
+
+struct bitstream * rs_generate_words(int k, const int * coeff, struct bitstream * data);
+
+#endif
+
diff --git a/lpg/libqr/test.c b/lpg/libqr/test.c
index 76d0b97..ec77bfe 100644
--- a/lpg/libqr/test.c
+++ b/lpg/libqr/test.c
@@ -5,6 +5,7 @@
 #include <qr/data.h>
 
 #include "bitstream.h"
+#include "code-common.h"
 
 int main() {
 
-- 
cgit v1.2.3-70-g09d2


From 69b03a15eb048c05b31a5cc6128c27acc77c1dd5 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Tue, 15 Sep 2009 19:03:26 +0900
Subject: Figure out how to encode RS

---
 lpg/libqr/code-create.c |  4 +--
 lpg/libqr/rs-encode.c   | 76 ++++++++++++++++++++++++++++++++++++++++---------
 lpg/libqr/rs.h          |  2 +-
 3 files changed, 66 insertions(+), 16 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 484dbe3..389dcd5 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -31,13 +31,13 @@ static int add_ecc(struct bitstream * bits, int format, enum qr_ec_level ec)
         puts("Before ecc:");
         x_dump(bits);
         {
-                const int g[10] = { 251, 67, 61, 118, 70, 64, 94, 32, 45 };
                 int rs_words = 10; /* 1-M */
                 struct bitstream * rs;
 
-                rs = rs_generate_words(rs_words, g, bits);
+                rs = rs_generate_words(rs_words, bits);
                 puts("ecc part:");
                 x_dump(rs);
+                bitstream_destroy(rs);
         }
         return -1;
 }
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
index ec99c6b..ea54d77 100644
--- a/lpg/libqr/rs-encode.c
+++ b/lpg/libqr/rs-encode.c
@@ -3,11 +3,56 @@
 #include "bitstream.h"
 #include "rs.h"
 
-struct bitstream * rs_generate_words(int k, const int * coeff, struct bitstream * data)
+static unsigned int gf_mult(unsigned int a, unsigned int b)
+{
+        /* Reduce modulo x^8 + x^4 + x^3 + x^2 + 1
+         * using the peasant's algorithm
+         */
+        const unsigned int m = 0x11D;
+        unsigned int x = 0;
+        int i;
+
+        for (i = 0; i < 8; ++i) {
+                x ^= (b & 0x1) ? a : 0;
+                a = (a << 1) ^ ((a & 0x80) ? m : 0);
+                b >>= 1;
+        }
+
+        return x & 0xFF;
+}
+
+static unsigned int * make_generator(int k)
+{
+        unsigned int * g;
+        unsigned int a;
+        int i, j;
+
+        g = calloc(k, sizeof(*g));
+        if (!g)
+                return 0;
+
+        g[0] = 1; /* Start with g(x) = 1 */
+        a = 1;    /* 2^0 = 1 */
+
+        for (i = 0; i < k; ++i) {
+                /* Multiply our poly g(x) by (x + 2^i) */
+                for (j = k - 1; j > 0; --j)
+                        g[j] = gf_mult(g[j], a) ^ g[j-1];
+                g[0] = gf_mult(g[0], a);
+
+                a = gf_mult(a, 2);
+        }
+
+        return g;
+}
+
+struct bitstream * rs_generate_words(int n, struct bitstream * data)
 {
         struct bitstream * ec = 0;
         unsigned int * b = 0;
-        size_t n, i, dlen;
+        unsigned int * g;
+        size_t dlen;
+        int i, r;
 
         dlen = bitstream_size(data);
         assert(dlen % 8 == 0);
@@ -17,30 +62,35 @@ struct bitstream * rs_generate_words(int k, const int * coeff, struct bitstream
         if (!ec)
                 return 0;
 
-        if (bitstream_resize(ec, k * 8) != 0)
+        if (bitstream_resize(ec, n * 8) != 0)
                 goto fail;
 
-        b = calloc(k, sizeof(*b));
+        b = calloc(n, sizeof(*b));
         if (!b)
                 goto fail;
 
-        /* First, prepare the registers (b) with data bits. Note that
-         * the registers are in reverse of the normal order
-         */
+        g = make_generator(n);
+        if (!g)
+                goto fail;
+
+        /* First, prepare the registers (b) with data bits */
         bitstream_seek(data, 0);
-        for (n = 0; n < dlen; ++n) {
-                unsigned int x = b[0] + bitstream_read(data, 8);
-                for (i = 0; i < k-1; ++i)
-                        b[i] = b[i+1] + coeff[(k-1) - i] * x;
-                b[k-1] = coeff[0] * x;
+        for (i = 0; i < dlen; ++i) {
+                unsigned int x = b[n-1] ^ bitstream_read(data, 8);
+                for (r = n-1; r > 0; --r)
+                        b[r] = b[r-1] ^ gf_mult(g[r], x);
+                b[0] = gf_mult(g[0], x);
         }
 
         /* Read off the registers */
-        bitstream_pack(ec, b, k, 8);
+        for (r = 0; r < n; ++r)
+                bitstream_write(ec, b[(n-1)-r], 8);
 
+        free(g);
         free(b);
         return ec;
 fail:
+        free(b);
         bitstream_destroy(ec);
         return 0;
 }
diff --git a/lpg/libqr/rs.h b/lpg/libqr/rs.h
index 98e3aa0..48b1f01 100644
--- a/lpg/libqr/rs.h
+++ b/lpg/libqr/rs.h
@@ -3,7 +3,7 @@
 
 #include "bitstream.h"
 
-struct bitstream * rs_generate_words(int k, const int * coeff, struct bitstream * data);
+struct bitstream * rs_generate_words(int n, struct bitstream * data);
 
 #endif
 
-- 
cgit v1.2.3-70-g09d2


From 64a96442629b720b2e2b1cc3997ee3dbc6a71b90 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sat, 26 Sep 2009 11:45:30 +0900
Subject: get ready for multiple RS blocks

---
 lpg/libqr/code-create.c | 94 +++++++++++++++++++++++++++++++++++++------------
 lpg/libqr/rs-encode.c   | 12 +++----
 lpg/libqr/rs.h          |  4 ++-
 3 files changed, 80 insertions(+), 30 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 389dcd5..9ed59de 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -26,22 +26,6 @@ static void x_dump(struct bitstream * bits)
         printf("\n");
 }
 
-static int add_ecc(struct bitstream * bits, int format, enum qr_ec_level ec)
-{
-        puts("Before ecc:");
-        x_dump(bits);
-        {
-                int rs_words = 10; /* 1-M */
-                struct bitstream * rs;
-
-                rs = rs_generate_words(rs_words, bits);
-                puts("ecc part:");
-                x_dump(rs);
-                bitstream_destroy(rs);
-        }
-        return -1;
-}
-
 static int pad_data(struct bitstream * bits, size_t limit)
 {
         /* This function is not very nice. Sorry. */
@@ -86,23 +70,87 @@ static struct bitstream * make_data(int                format,
                                     enum qr_ec_level   ec,
                                     struct bitstream * data)
 {
-        size_t data_bits = 16 * 8 /*XXX*/;
-        struct bitstream * out;
-
-        out = bitstream_copy(data);
+        const size_t total_bits = code_total_capacity(format);
+        const size_t total_words = total_bits / 8;
+        size_t block_count, data_words, rs_words;
+        size_t i;
+        struct bitstream * dcopy = 0;
+        struct bitstream * out = 0;
+        struct bitstream ** blocks = 0;
+
+        /* Set up the output stream */
+        out = bitstream_create();
         if (!out)
                 return 0;
 
-        if (pad_data(out, data_bits) != 0)
+        if (bitstream_resize(out, total_bits) != 0)
                 goto fail;
 
-        if (add_ecc(out, format, ec) != 0)
+        /**
+         * XXX: For our test case (1-M) there is only one RS block.
+         * This is not the case for most other formats, so we'll
+         * have to deal with this eventually.
+         */
+        block_count = 1;
+        data_words = 16;
+        rs_words = 10;
+        assert(data_words + rs_words == total_words);
+
+        /* Make a copy of the data and pad it */
+        dcopy = bitstream_copy(data);
+        if (!dcopy)
+                goto fail;
+
+        if (pad_data(dcopy, data_words * 8) != 0)
                 goto fail;
 
+        puts("Pad data:");
+        x_dump(dcopy);
+
+        /* Make space for the RS blocks */
+        blocks = calloc(block_count, sizeof(*blocks));
+        if (!blocks)
+                goto fail;
+
+        /* Generate RS codewords */
+        bitstream_seek(dcopy, 0);
+        puts("Generate RS blocks:");
+        for (i = 0; i < block_count; ++i) {
+                /* XXX: some blocks may be longer */
+                blocks[i] = rs_generate_words(dcopy, data_words, rs_words);
+                if (!blocks[i]) {
+                        while (i--)
+                                bitstream_destroy(blocks[i]);
+                        free(blocks);
+                        blocks = 0;
+                        goto fail;
+                }
+                x_dump(blocks[i]);
+        }
+
+        /* Finally, write everything out in the correct order */
+        /* XXX: need to handle multiple blocks */
+        bitstream_cat(out, dcopy);
+        bitstream_cat(out, blocks[0]);
+        bitstream_write(out, 0, total_bits - total_words * 8);
+
+        puts("Final bitstream:");
+        x_dump(out);
+exit:
+        if (blocks) {
+                while (block_count--)
+                       bitstream_destroy(blocks[block_count]);
+                free(blocks);
+        }
+        if (dcopy)
+                bitstream_destroy(dcopy);
+
         return out;
+
 fail:
         bitstream_destroy(out);
-        return 0;
+        out = 0;
+        goto exit;
 }
 
 struct qr_code * qr_code_create(enum qr_ec_level       ec,
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
index ea54d77..1e6c6bf 100644
--- a/lpg/libqr/rs-encode.c
+++ b/lpg/libqr/rs-encode.c
@@ -46,17 +46,17 @@ static unsigned int * make_generator(int k)
         return g;
 }
 
-struct bitstream * rs_generate_words(int n, struct bitstream * data)
+struct bitstream * rs_generate_words(struct bitstream * data,
+                                     size_t data_words,
+                                     size_t rs_words)
 {
         struct bitstream * ec = 0;
         unsigned int * b = 0;
         unsigned int * g;
-        size_t dlen;
+        size_t n = rs_words;
         int i, r;
 
-        dlen = bitstream_size(data);
-        assert(dlen % 8 == 0);
-        dlen /= 8;
+        assert(bitstream_remaining(data) >= data_words * 8);
 
         ec = bitstream_create();
         if (!ec)
@@ -75,7 +75,7 @@ struct bitstream * rs_generate_words(int n, struct bitstream * data)
 
         /* First, prepare the registers (b) with data bits */
         bitstream_seek(data, 0);
-        for (i = 0; i < dlen; ++i) {
+        for (i = 0; i < data_words; ++i) {
                 unsigned int x = b[n-1] ^ bitstream_read(data, 8);
                 for (r = n-1; r > 0; --r)
                         b[r] = b[r-1] ^ gf_mult(g[r], x);
diff --git a/lpg/libqr/rs.h b/lpg/libqr/rs.h
index 48b1f01..e640044 100644
--- a/lpg/libqr/rs.h
+++ b/lpg/libqr/rs.h
@@ -3,7 +3,9 @@
 
 #include "bitstream.h"
 
-struct bitstream * rs_generate_words(int n, struct bitstream * data);
+struct bitstream * rs_generate_words(struct bitstream * data,
+                                     size_t data_words,
+                                     size_t rs_words);
 
 #endif
 
-- 
cgit v1.2.3-70-g09d2


From 28849b589dcd933b2527d9f231ce6668ed7d19fa Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sat, 26 Sep 2009 16:08:27 +0900
Subject: (partially) layout code

---
 lpg/libqr/Makefile      |   1 +
 lpg/libqr/code-create.c |  82 +++++++++++++++++++++++++++----
 lpg/libqr/code-layout.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/code-layout.h |  12 +++++
 lpg/libqr/test.c        |  15 ++++++
 5 files changed, 227 insertions(+), 8 deletions(-)
 create mode 100644 lpg/libqr/code-layout.c
 create mode 100644 lpg/libqr/code-layout.h

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index 1f34caf..e9783f6 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -1,6 +1,7 @@
 OBJECTS :=      bitstream.o     \
                 code-common.o   \
                 code-create.o   \
+                code-layout.o   \
                 code-parse.o    \
                 code-render.o   \
                 data-common.o   \
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 9ed59de..a462ea3 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -4,6 +4,7 @@
 #include <qr/code.h>
 
 #include "code-common.h"
+#include "code-layout.h"
 #include "data-common.h"
 #include "rs.h"
 
@@ -26,6 +27,46 @@ static void x_dump(struct bitstream * bits)
         printf("\n");
 }
 
+static void setpx(struct qr_code * code, int x, int y)
+{
+        size_t off = y * code->line_stride + x / CHAR_BIT;
+        unsigned char bit = 1 << (x % CHAR_BIT);
+
+        code->modules[off] |= bit;
+}
+
+static void draw_locator(struct qr_code * code, 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);
+        }
+        for (i = 0; i < 9; ++i)
+                setpx(code, x + 2 + i % 3, y + 2 + i / 3);
+}
+
+static void draw_fixed_bits(struct qr_code * code)
+{
+        int dim = code_side_length(code->format);
+        int i;
+
+        /* Locator pattern */
+        draw_locator(code, 0, 0);
+        draw_locator(code, 0, dim - 7);
+        draw_locator(code, dim - 7, 0);
+
+        /* Timing pattern */
+        for (i = 8; i < dim - 8; i += 2) {
+                setpx(code, i, 6);
+                setpx(code, 6, i);
+        }
+
+        /* XXX: alignment pattern */
+}
+
 static int pad_data(struct bitstream * bits, size_t limit)
 {
         /* This function is not very nice. Sorry. */
@@ -157,22 +198,47 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
                                 const struct qr_data * data)
 {
         struct qr_code * code;
-        struct bitstream * ecdata;
+        struct bitstream * bits = 0;
+        struct qr_iterator * layout;
+        size_t dim;
 
         code = malloc(sizeof(*code));
         if (!code)
                 return 0;
 
+        dim = code_side_length(data->format);
+
         code->format = data->format;
-        ecdata = make_data(data->format, ec, data->bits);
+        code->line_stride = dim / CHAR_BIT + ((dim % CHAR_BIT) ? 1 : 0);
+        code->modules = calloc(dim * code->line_stride, sizeof(unsigned char));
 
-        if (!ecdata) {
-                free(code);
-                return 0;
-        }
+        if (!code->modules)
+                goto fail;
 
-        /* TODO: allocate bitmap; layout */
+        draw_fixed_bits(code);
 
-        return 0;
+        bits = make_data(data->format, ec, data->bits);
+        if (!bits)
+                goto fail;
+
+        layout = qr_layout_begin(code);
+        if (!layout)
+                goto fail;
+
+        bitstream_seek(bits, 0);
+        while (bitstream_remaining(bits) >= 8)
+                qr_layout_write(layout, bitstream_read(bits, 8));
+        qr_layout_end(layout);
+
+exit:
+        if (bits)
+                bitstream_destroy(bits);
+
+        return code;
+
+fail:
+        qr_code_destroy(code);
+        code = 0;
+        goto exit;
 }
 
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
new file mode 100644
index 0000000..228758a
--- /dev/null
+++ b/lpg/libqr/code-layout.c
@@ -0,0 +1,125 @@
+#include <limits.h>
+#include <stdlib.h>
+#include "code-common.h"
+#include "code-layout.h"
+
+struct qr_iterator {
+        struct qr_code * code;
+        int dim;
+        int column;
+        int row;
+        int up;
+        int mask;
+        unsigned char * p;
+};
+
+static int is_data_bit(const struct qr_iterator * i)
+{
+        if (i->row == 6 || i->column == 6) /* timing */
+                return 0;
+
+        if (i->column < 9 && i->row < 9) /* top-left */
+                return 0;
+
+        if (i->column >= i->dim - 8 && i->row < 9) /* top-right */
+                return 0;
+
+        if (i->column < 9 && i->row >= i->dim - 8) /* bottom-left */
+                return 0;
+
+        /* XXX: format data */
+        /* XXX: alignment pattern */
+
+        return 1;
+}
+
+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->column / CHAR_BIT;
+}
+
+static void advance(struct qr_iterator * i)
+{
+        do {
+                /* This XOR is to account for the vertical strip of
+                 * timing bits in column 6 which displaces everything.
+                 */
+                if ((i->column < 6) ^ !(i->column % 2)) {
+                        /* Right-hand part or at left edge */
+                        i->column -= 1;
+                } else {
+                        /* Left-hand part */
+                        i->column += 1;
+
+                        if (( i->up && i->row == 0) ||
+                            (!i->up && i->row == i->dim - 1)) {
+                                /* Hit the top / bottom */
+                                i->column -= 2;
+                                i->up = !i->up;
+                        } else {
+                                i->row += i->up ? -1 : 1;
+                        }
+                }
+
+                if (i->column < 0)
+                        continue; /* don't go off left edge */
+
+                /* Check for one-past-end */
+                if (i->column == 0 && i->row >= i->dim - 8)
+                        break;
+
+        } while (!is_data_bit(i));
+
+        set_pointer(i);
+}
+
+struct qr_iterator * qr_layout_begin(struct qr_code * code)
+{
+        struct qr_iterator * i;
+
+        i = malloc(sizeof(*i));
+        if (i) {
+                i->dim = code_side_length(code->format);
+                i->code = code;
+                i->column = i->dim - 1;
+                i->row = i->dim - 1;
+                i->up = 1;
+                set_pointer(i);
+        }
+
+        return i;
+}
+
+void qr_layout_end(struct qr_iterator * i)
+{
+        free(i);
+}
+
+unsigned int qr_layout_read(struct qr_iterator * i)
+{
+        unsigned int x = 0;
+        int b;
+
+        for (b = 0; b < 8; ++b) {
+                x |= (*i->p & i->mask) ? 1 : 0;
+                advance(i);
+                x <<= 1;
+        }
+
+        return x;
+}
+
+void qr_layout_write(struct qr_iterator * i, unsigned int x)
+{
+        int b;
+
+        for (b = 0; b < 8; ++b) {
+                *i->p |= (x & 0x80) ? i->mask : 0;
+                advance(i);
+                x <<= 1;
+        }
+}
+
diff --git a/lpg/libqr/code-layout.h b/lpg/libqr/code-layout.h
new file mode 100644
index 0000000..79e9730
--- /dev/null
+++ b/lpg/libqr/code-layout.h
@@ -0,0 +1,12 @@
+#ifndef CODE_LAYOUT_H
+#define CODE_LAYOUT_H
+
+struct qr_iterator;
+
+struct qr_iterator * qr_layout_begin(struct qr_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 *);
+
+#endif
+
diff --git a/lpg/libqr/test.c b/lpg/libqr/test.c
index ec77bfe..f51b90b 100644
--- a/lpg/libqr/test.c
+++ b/lpg/libqr/test.c
@@ -33,6 +33,21 @@ int main() {
 
         printf("Code width %d\n", qr_code_width(code));
 
+        {
+                /* Hack: render the code using ANSI terminal art */
+                char buf[80*25];
+                int x, y;
+
+                qr_code_render(code, buf, 8, 80, 0, 1, 0);
+                for (y=0;y<21;++y) {
+                        printf("\t|");
+                        for (x=0;x<21;++x) {
+                                printf("%s  ", buf[y*80+x]?"\033[7m":"\033[0m");
+                        }
+                        printf("\033[0m|\n");
+                }
+        }
+
 	return 0;
 }
 
-- 
cgit v1.2.3-70-g09d2


From 559eb9633e1f97d70112f02538ae5e9a0e46f4d5 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sun, 27 Sep 2009 16:31:03 +0900
Subject: bitmap handling routines

---
 lpg/libqr/Makefile           |   4 +-
 lpg/libqr/code-common.c      |   7 ++-
 lpg/libqr/code-common.h      |   6 +--
 lpg/libqr/code-create.c      |   7 ++-
 lpg/libqr/code-layout.c      |   4 +-
 lpg/libqr/code-render.c      | 119 -------------------------------------------
 lpg/libqr/qr-bitmap-pbm.c    |  47 +++++++++++++++++
 lpg/libqr/qr-bitmap-render.c | 118 ++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/qr-bitmap.c        |  70 +++++++++++++++++++++++++
 lpg/libqr/qr-bitmap.h        |  29 +++++++++++
 lpg/libqr/qr/code.h          |   8 ---
 lpg/libqr/test.c             |   2 +-
 12 files changed, 281 insertions(+), 140 deletions(-)
 delete mode 100644 lpg/libqr/code-render.c
 create mode 100644 lpg/libqr/qr-bitmap-pbm.c
 create mode 100644 lpg/libqr/qr-bitmap-render.c
 create mode 100644 lpg/libqr/qr-bitmap.c
 create mode 100644 lpg/libqr/qr-bitmap.h

(limited to 'lpg/libqr/code-create.c')

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/code-render.c b/lpg/libqr/code-render.c
deleted file mode 100644
index cdffe24..0000000
--- a/lpg/libqr/code-render.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <string.h>
-#include <limits.h>
-#include <assert.h>
-#include <qr/code.h>
-
-#include "code-common.h"
-
-/* CHAR_BIT | mod_bits  (multi-byte) */
-static void render_line_1(unsigned char *       out,
-                          const unsigned char * in,
-                          size_t                mod_bits,
-                          size_t                dim,
-                          unsigned long         mark,
-                          unsigned long         space)
-{
-        unsigned char in_mask;
-        size_t n, b;
-
-        in_mask = 1;
-        n = dim;
-
-        while (n-- > 0) {
-                unsigned long v = (*in & in_mask) ? mark : space;
-
-                if ((in_mask <<= 1) == 0) {
-                        in_mask = 1;
-                        ++in;
-                }
-
-                b = mod_bits / CHAR_BIT;
-                while (b-- > 0) {
-                        *out++ = (unsigned char) v;
-                        v >>= CHAR_BIT;
-                }
-        }
-}
-
-/* mod_bits | CHAR_BIT  (packed) */
-static void render_line_2(unsigned char *       out,
-                          const unsigned char * in,
-                          size_t                mod_bits,
-                          size_t                dim,
-                          unsigned long         mark,
-                          unsigned long         space)
-{
-        unsigned char in_mask;
-        size_t n, b, step, shift;
-
-        in_mask = 1;
-        step = CHAR_BIT / mod_bits;
-        shift = CHAR_BIT - mod_bits;
-        n = dim;
-
-        while (n > 0) {
-                unsigned char tmp = 0;
-
-                b = step;
-                while (b-- > 0) {
-                        unsigned long v = (*in & in_mask) ? mark : space;
-
-                        if ((in_mask <<= 1) == 0) {
-                                in_mask = 1;
-                                ++in;
-                        }
-
-                        tmp = (tmp >> mod_bits) | (v << shift);
-                        if (--n == 0) {
-                                tmp >>= b * mod_bits;
-                                break;
-                        }
-                };
-
-                *out++ = tmp;
-        }
-}
-
-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)
-{
-        unsigned char * out;
-        const unsigned char * in;
-        size_t n, dim;
-        int pack;
-
-        pack = (mod_bits < CHAR_BIT);
-        assert(!pack || (CHAR_BIT % mod_bits == 0));
-        assert( pack || (mod_bits % CHAR_BIT == 0));
-
-        in = code->modules;
-        out = buffer;
-        dim = qr_code_width(code);
-
-        n = dim;
-        while (n-- > 0) {
-                size_t rpt;
-                unsigned char * next;
-
-                if (pack)
-                        render_line_2(out, in, mod_bits, dim, mark, space);
-                else
-                        render_line_1(out, in, mod_bits, dim, mark, space);
-
-                rpt = line_repeat;
-                next = out + line_stride;
-                while (rpt-- > 0) {
-                        memcpy(next, out, line_stride);
-                        next += line_stride;
-                }
-
-                in += code->line_stride;
-                out = next;
-        }
-}
-
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/qr-bitmap-render.c b/lpg/libqr/qr-bitmap-render.c
new file mode 100644
index 0000000..4f6c921
--- /dev/null
+++ b/lpg/libqr/qr-bitmap-render.c
@@ -0,0 +1,118 @@
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#include "qr-bitmap.h"
+
+/* CHAR_BIT | mod_bits  (multi-byte) */
+static void render_line_1(unsigned char *       out,
+                          const unsigned char * in,
+                          size_t                mod_bits,
+                          size_t                dim,
+                          unsigned long         mark,
+                          unsigned long         space)
+{
+        unsigned char in_mask;
+        size_t n, b;
+
+        in_mask = 1;
+        n = dim;
+
+        while (n-- > 0) {
+                unsigned long v = (*in & in_mask) ? mark : space;
+
+                if ((in_mask <<= 1) == 0) {
+                        in_mask = 1;
+                        ++in;
+                }
+
+                b = mod_bits / CHAR_BIT;
+                while (b-- > 0) {
+                        *out++ = (unsigned char) v;
+                        v >>= CHAR_BIT;
+                }
+        }
+}
+
+/* mod_bits | CHAR_BIT  (packed) */
+static void render_line_2(unsigned char *       out,
+                          const unsigned char * in,
+                          size_t                mod_bits,
+                          size_t                dim,
+                          unsigned long         mark,
+                          unsigned long         space)
+{
+        unsigned char in_mask;
+        size_t n, b, step, shift;
+
+        in_mask = 1;
+        step = CHAR_BIT / mod_bits;
+        shift = CHAR_BIT - mod_bits;
+        n = dim;
+
+        while (n > 0) {
+                unsigned char tmp = 0;
+
+                b = step;
+                while (b-- > 0) {
+                        unsigned long v = (*in & in_mask) ? mark : space;
+
+                        if ((in_mask <<= 1) == 0) {
+                                in_mask = 1;
+                                ++in;
+                        }
+
+                        tmp = (tmp >> mod_bits) | (v << shift);
+                        if (--n == 0) {
+                                tmp >>= b * mod_bits;
+                                break;
+                        }
+                };
+
+                *out++ = tmp;
+        }
+}
+
+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;
+        size_t n, dim;
+        int pack;
+
+        pack = (mod_bits < CHAR_BIT);
+        assert(!pack || (CHAR_BIT % mod_bits == 0));
+        assert( pack || (mod_bits % CHAR_BIT == 0));
+
+        in = bmp->bits;
+        out = buffer;
+        dim = bmp->width;
+
+        n = dim;
+        while (n-- > 0) {
+                size_t rpt;
+                unsigned char * next;
+
+                if (pack)
+                        render_line_2(out, in, mod_bits, dim, mark, space);
+                else
+                        render_line_1(out, in, mod_bits, dim, mark, space);
+
+                rpt = line_repeat;
+                next = out + line_stride;
+                while (rpt-- > 0) {
+                        memcpy(next, out, line_stride);
+                        next += 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) {
-- 
cgit v1.2.3-70-g09d2


From 388507a61df32c0bddf7e61c5da013c3f29d32d4 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sun, 27 Sep 2009 16:53:16 +0900
Subject: bitstream -> qr_bitstream

---
 lpg/libqr/Makefile       |   4 +-
 lpg/libqr/bitstream.c    | 232 -----------------------------------------------
 lpg/libqr/bitstream.h    |  44 ---------
 lpg/libqr/code-common.h  |   2 +-
 lpg/libqr/code-create.c  |  66 +++++++-------
 lpg/libqr/data-common.c  |   4 +-
 lpg/libqr/data-common.h  |   4 +-
 lpg/libqr/data-create.c  |  38 ++++----
 lpg/libqr/data-parse.c   |  52 +++++------
 lpg/libqr/qr-bitstream.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/qr-bitstream.h |  44 +++++++++
 lpg/libqr/rs-encode.c    |  20 ++--
 lpg/libqr/rs.h           |   4 +-
 lpg/libqr/test.c         |   2 +-
 14 files changed, 374 insertions(+), 374 deletions(-)
 delete mode 100644 lpg/libqr/bitstream.c
 delete mode 100644 lpg/libqr/bitstream.h
 create mode 100644 lpg/libqr/qr-bitstream.c
 create mode 100644 lpg/libqr/qr-bitstream.h

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index 1571de4..49f89d4 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -1,5 +1,4 @@
-OBJECTS :=      bitstream.o     \
-                code-common.o   \
+OBJECTS :=      code-common.o           \
                 code-create.o   \
                 code-layout.o   \
                 code-parse.o    \
@@ -9,6 +8,7 @@ OBJECTS :=      bitstream.o     \
                 qr-bitmap.o             \
                 qr-bitmap-pbm.o         \
                 qr-bitmap-render.o      \
+                qr-bitstream.o          \
                 rs-encode.o
 
 CFLAGS := -std=c89 -pedantic -I. -Wall
diff --git a/lpg/libqr/bitstream.c b/lpg/libqr/bitstream.c
deleted file mode 100644
index fd58ea3..0000000
--- a/lpg/libqr/bitstream.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/**
- * It would perhaps be more sensible just to store the bits
- * as an array of char or similar, but this way is more fun.
- * This is a pretty inefficient implementation, althought I
- * suspect that won't be a problem.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <assert.h>
-
-#include "bitstream.h"
-
-#define MAX(a, b) ((a) < (b) ? (b) : (a))
-#define MIN(a, b) ((a) > (b) ? (b) : (a))
-
-struct bitstream {
-        size_t pos;    /* bits */
-        size_t count;  /* bits */
-        size_t bufsiz; /* bytes */
-        unsigned char * buffer;
-};
-
-static size_t bits_to_bytes(size_t bits)
-{
-        return (bits / CHAR_BIT) + (bits % CHAR_BIT != 0);
-}
-
-static int ensure_available(struct bitstream * stream, size_t bits)
-{
-        size_t need_bits = stream->pos + bits;
-        size_t need_bytes = need_bits / CHAR_BIT + ((need_bits % CHAR_BIT) ? 0 : 1);
-        size_t newsize;
-
-        if (stream->bufsiz >= need_bytes)
-                return 0;
-
-        newsize = MAX(stream->bufsiz, 100);
-        while (newsize < need_bytes)
-                newsize *= 2;
-
-        return bitstream_resize(stream, newsize);
-}
-
-struct bitstream * bitstream_create(void)
-{
-        struct bitstream * obj;
-
-        obj = malloc(sizeof(*obj));
-
-        if (obj) {
-                obj->pos    = 0;
-                obj->count  = 0;
-                obj->bufsiz = 0;
-                obj->buffer = 0;
-        }
-
-        return obj;
-}
-
-int bitstream_resize(struct bitstream * stream, size_t bits)
-{
-        size_t newsize;
-        void * newbuf;
-
-        newsize = bits_to_bytes(bits);
-        newbuf = realloc(stream->buffer, newsize);
-
-        if (newbuf) {
-                stream->bufsiz = newsize;
-                stream->buffer = newbuf;
-        }
-
-        return newbuf ? 0 : -1;
-}
-
-void bitstream_destroy(struct bitstream * stream)
-{
-        free(stream->buffer);
-        free(stream);
-}
-
-struct bitstream * bitstream_copy(const struct bitstream * src)
-{
-        struct bitstream * ret;
-
-        ret = bitstream_create();
-        if (!ret)
-                return 0;
-
-        if (bitstream_resize(ret, src->count) != 0) {
-                free(ret);
-                return 0;
-        }
-
-        ret->pos   = src->pos;
-        ret->count = src->count;
-        memcpy(ret->buffer, src->buffer, src->bufsiz);
-
-        return ret;
-}
-
-void bitstream_seek(struct bitstream * stream, size_t pos)
-{
-        assert(pos <= stream->count);
-        stream->pos = pos;
-}
-
-size_t bitstream_tell(const struct bitstream * stream)
-{
-        return stream->pos;
-}
-
-size_t bitstream_remaining(const struct bitstream * stream)
-{
-        return stream->count - stream->pos;
-}
-
-size_t bitstream_size(const struct bitstream * stream)
-{
-        return stream->count;
-}
-
-unsigned int bitstream_read(struct bitstream * stream, size_t bits)
-{
-        unsigned int result = 0;
-        unsigned char * byte;
-        size_t bitnum;
-
-        assert(bitstream_remaining(stream) >= bits);
-
-        byte = stream->buffer + (stream->pos / CHAR_BIT);
-        bitnum = stream->pos % CHAR_BIT;
-
-        stream->pos += bits;
-
-        while (bits-- > 0) {
-                int bit = (*byte >> bitnum++) & 0x1;
-                result = (result << 1) | bit;
-                if (bitnum == CHAR_BIT) {
-                        bitnum = 0;
-                        ++byte;
-                }                
-        }
-
-        return result;
-}
-
-void bitstream_unpack(struct bitstream * stream,
-                      unsigned int *     result,
-                      size_t             count,
-                      size_t             bitsize)
-{
-        assert(bitstream_remaining(stream) >= (count * bitsize));
-
-        while (count--)
-                *(result++) = bitstream_read(stream, bitsize);
-}
-
-int bitstream_write(struct bitstream * stream,
-                    unsigned int       value,
-                    size_t             bits)
-{
-        unsigned char * byte;
-        size_t bitnum;
-
-        if (ensure_available(stream, bits) != 0)
-                return -1;
-
-        byte = stream->buffer + (stream->pos / CHAR_BIT);
-        bitnum = stream->pos % CHAR_BIT;
-
-        stream->pos += bits;
-        stream->count = stream->pos; /* truncate */
-
-        while (bits-- > 0) {
-                int bit = (value >> bits) & 0x1;
-                unsigned char mask = 1 << bitnum++;
-                *byte = (*byte & ~mask) | (bit ? mask : 0);
-                if (bitnum == CHAR_BIT) {
-                        bitnum = 0;
-                        ++byte;
-                }
-        }
-
-        return 0;
-}
-
-int bitstream_pack(struct bitstream *   stream,
-                   const unsigned int * values,
-                   size_t               count,
-                   size_t               bitsize)
-{
-        if (ensure_available(stream, count * bitsize) != 0)
-                return -1;
-
-        while (count--)
-                bitstream_write(stream, *(values++), bitsize);
-
-        return 0;
-}
-
-int bitstream_cat(struct bitstream * dest, const struct bitstream * src)
-{
-        size_t count = bitstream_size(src);
-        size_t srcpos;
-
-        if (ensure_available(dest, count) != 0)
-                return -1;
-
-        srcpos = bitstream_tell(src);
-        bitstream_seek((struct bitstream *)src, 0);
-
-        /* uint must be at least 16 bits */
-        for (; count >= 16; count -= 16)
-                bitstream_write(
-                        dest,
-                        bitstream_read((struct bitstream *)src, 16),
-                        16);
-
-        if (count > 0)
-                bitstream_write(
-                        dest,
-                        bitstream_read((struct bitstream *)src, count),
-                        count);
-
-        bitstream_seek((struct bitstream *)src, srcpos);
-
-        return 0;
-}
-
diff --git a/lpg/libqr/bitstream.h b/lpg/libqr/bitstream.h
deleted file mode 100644
index 12412bc..0000000
--- a/lpg/libqr/bitstream.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef QR_BITSTREAM_H
-#define QR_BITSTREAM_H
-
-#include <stddef.h>
-
-/**
- * Note: when writing / reading multiple bits, the
- * _most_ significant bits come first in the stream.
- * (That is, the order you would naturally write the
- * number in binary)
- */
-
-struct bitstream;
-
-struct bitstream * bitstream_create(void);
-int                bitstream_resize(struct bitstream *, size_t bits);
-void               bitstream_destroy(struct bitstream *);
-struct bitstream * bitstream_copy(const struct bitstream *);
-
-void bitstream_seek(struct bitstream *, size_t pos);
-size_t bitstream_tell(const struct bitstream *);
-size_t bitstream_remaining(const struct bitstream *);
-size_t bitstream_size(const struct bitstream *);
-
-unsigned int bitstream_read(struct bitstream *, size_t bits);
-
-void bitstream_unpack(struct bitstream *,
-                      unsigned int * result,
-                      size_t         count,
-                      size_t         bitsize);
-
-int bitstream_write(struct bitstream *,
-                    unsigned int value,
-                    size_t       bits);
-
-int bitstream_pack(struct bitstream *,
-                   const unsigned int * values,
-                   size_t               count,
-                   size_t               bitsize);
-
-int bitstream_cat(struct bitstream *, const struct bitstream * src);
-
-#endif
-
diff --git a/lpg/libqr/code-common.h b/lpg/libqr/code-common.h
index fce8dce..cf96217 100644
--- a/lpg/libqr/code-common.h
+++ b/lpg/libqr/code-common.h
@@ -2,7 +2,7 @@
 #define CODE_COMMON_H
 
 #include <qr/code.h>
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "qr-bitmap.h"
 
 struct qr_code {
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 5c0f2b7..c6451ac 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -11,14 +11,14 @@
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
 #include <stdio.h>
-static void x_dump(struct bitstream * bits)
+static void x_dump(struct qr_bitstream * bits)
 {
         size_t i, n;
 
-        bitstream_seek(bits, 0);
-        n = bitstream_size(bits);
+        qr_bitstream_seek(bits, 0);
+        n = qr_bitstream_size(bits);
         for (i = 0; i < n; ++i) {
-                printf("%d", bitstream_read(bits, 1));
+                printf("%d", qr_bitstream_read(bits, 1));
                 if (i % 8 == 7)
                         printf(" ");
                 if ((i+1) % (7 * 8) == 0)
@@ -67,19 +67,19 @@ static void draw_fixed_bits(struct qr_code * code)
         /* XXX: alignment pattern */
 }
 
-static int pad_data(struct bitstream * bits, size_t limit)
+static int pad_data(struct qr_bitstream * bits, size_t limit)
 {
         /* This function is not very nice. Sorry. */
 
         size_t count, n;
 
-        assert(bitstream_size(bits) <= limit);
+        assert(qr_bitstream_size(bits) <= limit);
 
-        if (bitstream_resize(bits, limit) != 0)
+        if (qr_bitstream_resize(bits, limit) != 0)
                 return -1;
 
-        n = bitstream_size(bits);
-        bitstream_seek(bits, n);
+        n = qr_bitstream_size(bits);
+        qr_bitstream_seek(bits, n);
         count = limit - n;
 
         /* First append the terminator (0000) if possible,
@@ -89,42 +89,42 @@ static int pad_data(struct bitstream * bits, size_t limit)
         if (n != 0)
                 n = 8 - n;
         n = MIN(count, n + 4);
-        bitstream_write(bits, 0, n);
+        qr_bitstream_write(bits, 0, n);
         count -= n;
 
         assert(count % 8 == 0); /* since data codewords are 8 bits */
 
         /* Finally pad with the repeating sequence 11101100 00010001 */
         while (count >= 16) {
-                bitstream_write(bits, 0xEC11, 16);
+                qr_bitstream_write(bits, 0xEC11, 16);
                 count -= 16;
         }
         if (count > 0) {
                 assert(count == 8);
-                bitstream_write(bits, 0xEC, 8);
+                qr_bitstream_write(bits, 0xEC, 8);
         }
 
         return 0;
 }
 
-static struct bitstream * make_data(int                format,
+static struct qr_bitstream * make_data(int                format,
                                     enum qr_ec_level   ec,
-                                    struct bitstream * data)
+                                    struct qr_bitstream * data)
 {
         const size_t total_bits = code_total_capacity(format);
         const size_t total_words = total_bits / 8;
         size_t block_count, data_words, rs_words;
         size_t i;
-        struct bitstream * dcopy = 0;
-        struct bitstream * out = 0;
-        struct bitstream ** blocks = 0;
+        struct qr_bitstream * dcopy = 0;
+        struct qr_bitstream * out = 0;
+        struct qr_bitstream ** blocks = 0;
 
         /* Set up the output stream */
-        out = bitstream_create();
+        out = qr_bitstream_create();
         if (!out)
                 return 0;
 
-        if (bitstream_resize(out, total_bits) != 0)
+        if (qr_bitstream_resize(out, total_bits) != 0)
                 goto fail;
 
         /**
@@ -138,7 +138,7 @@ static struct bitstream * make_data(int                format,
         assert(data_words + rs_words == total_words);
 
         /* Make a copy of the data and pad it */
-        dcopy = bitstream_copy(data);
+        dcopy = qr_bitstream_copy(data);
         if (!dcopy)
                 goto fail;
 
@@ -154,14 +154,14 @@ static struct bitstream * make_data(int                format,
                 goto fail;
 
         /* Generate RS codewords */
-        bitstream_seek(dcopy, 0);
+        qr_bitstream_seek(dcopy, 0);
         puts("Generate RS blocks:");
         for (i = 0; i < block_count; ++i) {
                 /* XXX: some blocks may be longer */
                 blocks[i] = rs_generate_words(dcopy, data_words, rs_words);
                 if (!blocks[i]) {
                         while (i--)
-                                bitstream_destroy(blocks[i]);
+                                qr_bitstream_destroy(blocks[i]);
                         free(blocks);
                         blocks = 0;
                         goto fail;
@@ -171,25 +171,25 @@ static struct bitstream * make_data(int                format,
 
         /* Finally, write everything out in the correct order */
         /* XXX: need to handle multiple blocks */
-        bitstream_cat(out, dcopy);
-        bitstream_cat(out, blocks[0]);
-        bitstream_write(out, 0, total_bits - total_words * 8);
+        qr_bitstream_cat(out, dcopy);
+        qr_bitstream_cat(out, blocks[0]);
+        qr_bitstream_write(out, 0, total_bits - total_words * 8);
 
         puts("Final bitstream:");
         x_dump(out);
 exit:
         if (blocks) {
                 while (block_count--)
-                       bitstream_destroy(blocks[block_count]);
+                       qr_bitstream_destroy(blocks[block_count]);
                 free(blocks);
         }
         if (dcopy)
-                bitstream_destroy(dcopy);
+                qr_bitstream_destroy(dcopy);
 
         return out;
 
 fail:
-        bitstream_destroy(out);
+        qr_bitstream_destroy(out);
         out = 0;
         goto exit;
 }
@@ -198,7 +198,7 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
                                 const struct qr_data * data)
 {
         struct qr_code * code;
-        struct bitstream * bits = 0;
+        struct qr_bitstream * bits = 0;
         struct qr_iterator * layout;
         size_t dim;
 
@@ -224,14 +224,14 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         if (!layout)
                 goto fail;
 
-        bitstream_seek(bits, 0);
-        while (bitstream_remaining(bits) >= 8)
-                qr_layout_write(layout, bitstream_read(bits, 8));
+        qr_bitstream_seek(bits, 0);
+        while (qr_bitstream_remaining(bits) >= 8)
+                qr_layout_write(layout, qr_bitstream_read(bits, 8));
         qr_layout_end(layout);
 
 exit:
         if (bits)
-                bitstream_destroy(bits);
+                qr_bitstream_destroy(bits);
 
         return code;
 
diff --git a/lpg/libqr/data-common.c b/lpg/libqr/data-common.c
index 123e5c4..c64527a 100644
--- a/lpg/libqr/data-common.c
+++ b/lpg/libqr/data-common.c
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 #include <qr/data.h>
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "data-common.h"
 
 const enum qr_data_type QR_TYPE_CODES[16] = {
@@ -25,7 +25,7 @@ const enum qr_data_type QR_TYPE_CODES[16] = {
 
 void qr_free_data(struct qr_data * data)
 {
-        bitstream_destroy(data->bits);
+        qr_bitstream_destroy(data->bits);
         free(data);
 }
 
diff --git a/lpg/libqr/data-common.h b/lpg/libqr/data-common.h
index d5f6e45..1522b09 100644
--- a/lpg/libqr/data-common.h
+++ b/lpg/libqr/data-common.h
@@ -3,11 +3,11 @@
 
 #include <qr/data.h>
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 
 struct qr_data {
         int                format; /* 1 ~ 40 */
-        struct bitstream * bits;
+        struct qr_bitstream * bits;
         size_t             offset;
 };
 
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index 2910997..a918413 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -9,15 +9,15 @@
 #include <stdlib.h>
 #include <qr/data.h>
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "data-common.h"
 
 static void write_type_and_length(struct qr_data *  data,
                                   enum qr_data_type type,
                                   size_t            length)
 {
-        (void)bitstream_write(data->bits, QR_TYPE_CODES[type], 4);
-        (void)bitstream_write(data->bits, length,
+        (void)qr_bitstream_write(data->bits, QR_TYPE_CODES[type], 4);
+        (void)qr_bitstream_write(data->bits, length,
                 get_size_field_length(data->format, type));
 }
 
@@ -25,7 +25,7 @@ static struct qr_data * encode_numeric(struct qr_data * data,
                                        const char *     input,
                                        size_t           length)
 {
-        struct bitstream * stream = data->bits;
+        struct qr_bitstream * stream = data->bits;
         size_t bits;
 
         bits = 4 + get_size_field_length(data->format, QR_DATA_NUMERIC)
@@ -37,8 +37,8 @@ static struct qr_data * encode_numeric(struct qr_data * data,
                 bits += 7;
 
         stream = data->bits;
-        if (bitstream_resize(stream,
-                        bitstream_size(stream) + bits) != 0)
+        if (qr_bitstream_resize(stream,
+                        qr_bitstream_size(stream) + bits) != 0)
                 return 0;
 
         write_type_and_length(data, QR_DATA_NUMERIC, length);
@@ -54,7 +54,7 @@ static struct qr_data * encode_numeric(struct qr_data * data,
                 x = (input[0] - '0') * 100
                   + (input[1] - '0') * 10
                   + (input[2] - '0');
-                bitstream_write(stream, x, 10);
+                qr_bitstream_write(stream, x, 10);
                 input += 3;
         }
 
@@ -72,7 +72,7 @@ static struct qr_data * encode_numeric(struct qr_data * data,
                         x = x * 10 + (*input - '0');
                 }
 
-                bitstream_write(stream, x, length == 2 ? 7 : 4);
+                qr_bitstream_write(stream, x, length == 2 ? 7 : 4);
         }
 
         return data;
@@ -103,7 +103,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
                                      const char *     input,
                                      size_t           length)
 {
-        struct bitstream * stream = data->bits;
+        struct qr_bitstream * stream = data->bits;
         size_t bits;
 
         bits = 4 + get_size_field_length(data->format, QR_DATA_ALPHA)
@@ -111,8 +111,8 @@ static struct qr_data * encode_alpha(struct qr_data * data,
                  + 6 * (length % 2);
 
         stream = data->bits;
-        if (bitstream_resize(stream,
-                        bitstream_size(stream) + bits) != 0)
+        if (qr_bitstream_resize(stream,
+                        qr_bitstream_size(stream) + bits) != 0)
                 return 0;
 
         write_type_and_length(data, QR_DATA_ALPHA, length);
@@ -128,7 +128,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
                         return 0;
 
                 x = c1 * 45 + c2;
-                bitstream_write(stream, x, 11);
+                qr_bitstream_write(stream, x, 11);
         }
 
         if (length > 0) {
@@ -137,7 +137,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
                 if (c < 0)
                         return 0;
 
-                bitstream_write(stream, c, 6);
+                qr_bitstream_write(stream, c, 6);
         }
 
         return data;
@@ -147,21 +147,21 @@ static struct qr_data * encode_8bit(struct qr_data * data,
                                     const char *     input,
                                     size_t           length)
 {
-        struct bitstream * stream = data->bits;
+        struct qr_bitstream * stream = data->bits;
         size_t bits;
 
         bits = 4 + get_size_field_length(data->format, QR_DATA_8BIT)
                  + 8 * length;
 
         stream = data->bits;
-        if (bitstream_resize(stream,
-                        bitstream_size(stream) + bits) != 0)
+        if (qr_bitstream_resize(stream,
+                        qr_bitstream_size(stream) + bits) != 0)
                 return 0;
 
         write_type_and_length(data, QR_DATA_8BIT, length);
 
         while (length--)
-                bitstream_write(stream, *input++, 8);
+                qr_bitstream_write(stream, *input++, 8);
 
         return data;
 }
@@ -188,7 +188,7 @@ struct qr_data * qr_create_data(int               format,
                 return 0;
 
         data->format = format;
-        data->bits   = bitstream_create();
+        data->bits   = qr_bitstream_create();
         data->offset = 0;
 
         if (data->bits) {
@@ -210,7 +210,7 @@ struct qr_data * qr_create_data(int               format,
                 }
 
                 if (!ret) {
-                        bitstream_destroy(data->bits);
+                        qr_bitstream_destroy(data->bits);
                         free(data);
                 }
 
diff --git a/lpg/libqr/data-parse.c b/lpg/libqr/data-parse.c
index 9129ed7..d497bdf 100644
--- a/lpg/libqr/data-parse.c
+++ b/lpg/libqr/data-parse.c
@@ -3,18 +3,18 @@
 #include <stdlib.h>
 #include <qr/data.h>
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "data-common.h"
 
-static enum qr_data_type read_data_type(struct bitstream * stream)
+static enum qr_data_type read_data_type(struct qr_bitstream * stream)
 {
         const size_t length = 4;
         unsigned int type;
 
-        if (bitstream_remaining(stream) < length)
+        if (qr_bitstream_remaining(stream) < length)
                 return QR_DATA_INVALID;
 
-        type = bitstream_read(stream, length);
+        type = qr_bitstream_read(stream, length);
         assert(type < 16);
 
         return QR_TYPE_CODES[type];
@@ -24,7 +24,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
                                        char **                output,
                                        size_t *               length)
 {
-        struct bitstream * stream;
+        struct qr_bitstream * stream;
         size_t field_len, bits;
 	unsigned int digits;
 	unsigned int chunk;
@@ -34,10 +34,10 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
         buffer = 0;
 
         field_len = get_size_field_length(data->format, QR_DATA_NUMERIC);
-        if (bitstream_remaining(stream) < field_len)
+        if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
-	digits = bitstream_read(stream, field_len);
+	digits = qr_bitstream_read(stream, field_len);
 
 	bits = (digits / 3) * 10;
 	if (digits % 3 == 1)
@@ -45,7 +45,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
 	else if (digits % 3 == 2)
 		bits += 7;
 
-	if (bitstream_remaining(stream) < bits)
+	if (qr_bitstream_remaining(stream) < bits)
 		goto invalid;
 
 	buffer = malloc(digits + 1);
@@ -55,7 +55,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
 	p = buffer;
 
 	for (; bits >= 10; bits -= 10) {
-		chunk = bitstream_read(stream, 10);
+		chunk = qr_bitstream_read(stream, 10);
                 if (chunk >= 1000)
                         goto invalid;
 		sprintf(p, "%03u", chunk);
@@ -63,7 +63,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
 	}
 
         if (bits > 0) {
-                chunk = bitstream_read(stream, bits);
+                chunk = qr_bitstream_read(stream, bits);
                 if (chunk >= (bits >= 7 ? 100 : 10))
                         goto invalid;
                 sprintf(p, "%0*u", bits >= 7 ? 2 : 1, chunk);
@@ -84,7 +84,7 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
 {
         static const char charset[45] =
                 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
-        struct bitstream * stream;
+        struct qr_bitstream * stream;
         size_t field_len, bits;
 	unsigned int chars;
 	unsigned int chunk;
@@ -94,16 +94,16 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
         buffer = 0;
 
         field_len = get_size_field_length(data->format, QR_DATA_ALPHA);
-        if (bitstream_remaining(stream) < field_len)
+        if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
-	chars = bitstream_read(stream, field_len);
+	chars = qr_bitstream_read(stream, field_len);
 
 	bits = (chars / 2) * 11;
 	if (chars % 2 == 1)
 		bits += 6;
 
-	if (bitstream_remaining(stream) < bits)
+	if (qr_bitstream_remaining(stream) < bits)
 		goto invalid;
 
 	buffer = malloc(chars + 1);
@@ -114,7 +114,7 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
 
 	for (; bits >= 11; bits -= 11) {
                 unsigned int c1, c2;
-		chunk = bitstream_read(stream, 11);
+		chunk = qr_bitstream_read(stream, 11);
                 c1 = chunk / 45;
                 c2 = chunk % 45;
                 if (c1 >= 45)
@@ -124,7 +124,7 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
 	}
 
         if (bits > 0) {
-                chunk = bitstream_read(stream, bits);
+                chunk = qr_bitstream_read(stream, bits);
                 if (chunk >= 45)
                         goto invalid;
                 *p = charset[chunk];
@@ -143,7 +143,7 @@ static enum qr_data_type parse_8bit(const struct qr_data * data,
                                     char **                output,
                                     size_t *               length)
 {
-        struct bitstream * stream;
+        struct qr_bitstream * stream;
         size_t field_len;
 	unsigned int bytes;
 	char * p;
@@ -151,12 +151,12 @@ static enum qr_data_type parse_8bit(const struct qr_data * data,
         stream = data->bits;
 
         field_len = get_size_field_length(data->format, QR_DATA_8BIT);
-        if (bitstream_remaining(stream) < field_len)
+        if (qr_bitstream_remaining(stream) < field_len)
                 return QR_DATA_INVALID;
 
-	bytes = bitstream_read(stream, field_len);
+	bytes = qr_bitstream_read(stream, field_len);
 
-	if (bitstream_remaining(stream) < bytes * 8)
+	if (qr_bitstream_remaining(stream) < bytes * 8)
 		return QR_DATA_INVALID;
 
 	*output = malloc(bytes + 1);
@@ -167,7 +167,7 @@ static enum qr_data_type parse_8bit(const struct qr_data * data,
         *length = bytes;
 
         while (bytes-- > 0)
-                *p++ = bitstream_read(stream, 8);
+                *p++ = qr_bitstream_read(stream, 8);
 
         *p = '\0';
 
@@ -183,7 +183,7 @@ static enum qr_data_type parse_kanji(const struct qr_data * data,
 
 enum qr_data_type qr_get_data_type(const struct qr_data * data)
 {
-        bitstream_seek(data->bits, data->offset);
+        qr_bitstream_seek(data->bits, data->offset);
         return read_data_type(data->bits);
 }
 
@@ -192,7 +192,7 @@ int qr_get_data_length(const struct qr_data * data)
         size_t field_len;
         enum qr_data_type type;
 
-        bitstream_seek(data->bits, data->offset);
+        qr_bitstream_seek(data->bits, data->offset);
 
         type = read_data_type(data->bits);
 
@@ -208,17 +208,17 @@ int qr_get_data_length(const struct qr_data * data)
                 return -1;
         }
 
-        if (bitstream_remaining(data->bits) < field_len)
+        if (qr_bitstream_remaining(data->bits) < field_len)
                 return -1;
 
-        return (int) bitstream_read(data->bits, field_len);
+        return (int) qr_bitstream_read(data->bits, field_len);
 }
 
 enum qr_data_type qr_parse_data(const struct qr_data * input,
                                 char **                output,
                                 size_t *               length)
 {
-        bitstream_seek(input->bits, input->offset);
+        qr_bitstream_seek(input->bits, input->offset);
 
         switch (read_data_type(input->bits)) {
         case QR_DATA_NUMERIC:
diff --git a/lpg/libqr/qr-bitstream.c b/lpg/libqr/qr-bitstream.c
new file mode 100644
index 0000000..3df2549
--- /dev/null
+++ b/lpg/libqr/qr-bitstream.c
@@ -0,0 +1,232 @@
+/**
+ * It would perhaps be more sensible just to store the bits
+ * as an array of char or similar, but this way is more fun.
+ * This is a pretty inefficient implementation, althought I
+ * suspect that won't be a problem.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#include "qr-bitstream.h"
+
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+struct qr_bitstream {
+        size_t pos;    /* bits */
+        size_t count;  /* bits */
+        size_t bufsiz; /* bytes */
+        unsigned char * buffer;
+};
+
+static size_t bits_to_bytes(size_t bits)
+{
+        return (bits / CHAR_BIT) + (bits % CHAR_BIT != 0);
+}
+
+static int ensure_available(struct qr_bitstream * stream, size_t bits)
+{
+        size_t need_bits = stream->pos + bits;
+        size_t need_bytes = need_bits / CHAR_BIT + ((need_bits % CHAR_BIT) ? 0 : 1);
+        size_t newsize;
+
+        if (stream->bufsiz >= need_bytes)
+                return 0;
+
+        newsize = MAX(stream->bufsiz, 100);
+        while (newsize < need_bytes)
+                newsize *= 2;
+
+        return qr_bitstream_resize(stream, newsize);
+}
+
+struct qr_bitstream * qr_bitstream_create(void)
+{
+        struct qr_bitstream * obj;
+
+        obj = malloc(sizeof(*obj));
+
+        if (obj) {
+                obj->pos    = 0;
+                obj->count  = 0;
+                obj->bufsiz = 0;
+                obj->buffer = 0;
+        }
+
+        return obj;
+}
+
+int qr_bitstream_resize(struct qr_bitstream * stream, size_t bits)
+{
+        size_t newsize;
+        void * newbuf;
+
+        newsize = bits_to_bytes(bits);
+        newbuf = realloc(stream->buffer, newsize);
+
+        if (newbuf) {
+                stream->bufsiz = newsize;
+                stream->buffer = newbuf;
+        }
+
+        return newbuf ? 0 : -1;
+}
+
+void qr_bitstream_destroy(struct qr_bitstream * stream)
+{
+        free(stream->buffer);
+        free(stream);
+}
+
+struct qr_bitstream * qr_bitstream_copy(const struct qr_bitstream * src)
+{
+        struct qr_bitstream * ret;
+
+        ret = qr_bitstream_create();
+        if (!ret)
+                return 0;
+
+        if (qr_bitstream_resize(ret, src->count) != 0) {
+                free(ret);
+                return 0;
+        }
+
+        ret->pos   = src->pos;
+        ret->count = src->count;
+        memcpy(ret->buffer, src->buffer, src->bufsiz);
+
+        return ret;
+}
+
+void qr_bitstream_seek(struct qr_bitstream * stream, size_t pos)
+{
+        assert(pos <= stream->count);
+        stream->pos = pos;
+}
+
+size_t qr_bitstream_tell(const struct qr_bitstream * stream)
+{
+        return stream->pos;
+}
+
+size_t qr_bitstream_remaining(const struct qr_bitstream * stream)
+{
+        return stream->count - stream->pos;
+}
+
+size_t qr_bitstream_size(const struct qr_bitstream * stream)
+{
+        return stream->count;
+}
+
+unsigned int qr_bitstream_read(struct qr_bitstream * stream, size_t bits)
+{
+        unsigned int result = 0;
+        unsigned char * byte;
+        size_t bitnum;
+
+        assert(qr_bitstream_remaining(stream) >= bits);
+
+        byte = stream->buffer + (stream->pos / CHAR_BIT);
+        bitnum = stream->pos % CHAR_BIT;
+
+        stream->pos += bits;
+
+        while (bits-- > 0) {
+                int bit = (*byte >> bitnum++) & 0x1;
+                result = (result << 1) | bit;
+                if (bitnum == CHAR_BIT) {
+                        bitnum = 0;
+                        ++byte;
+                }                
+        }
+
+        return result;
+}
+
+void qr_bitstream_unpack(struct qr_bitstream * stream,
+                      unsigned int *     result,
+                      size_t             count,
+                      size_t             bitsize)
+{
+        assert(qr_bitstream_remaining(stream) >= (count * bitsize));
+
+        while (count--)
+                *(result++) = qr_bitstream_read(stream, bitsize);
+}
+
+int qr_bitstream_write(struct qr_bitstream * stream,
+                    unsigned int       value,
+                    size_t             bits)
+{
+        unsigned char * byte;
+        size_t bitnum;
+
+        if (ensure_available(stream, bits) != 0)
+                return -1;
+
+        byte = stream->buffer + (stream->pos / CHAR_BIT);
+        bitnum = stream->pos % CHAR_BIT;
+
+        stream->pos += bits;
+        stream->count = stream->pos; /* truncate */
+
+        while (bits-- > 0) {
+                int bit = (value >> bits) & 0x1;
+                unsigned char mask = 1 << bitnum++;
+                *byte = (*byte & ~mask) | (bit ? mask : 0);
+                if (bitnum == CHAR_BIT) {
+                        bitnum = 0;
+                        ++byte;
+                }
+        }
+
+        return 0;
+}
+
+int qr_bitstream_pack(struct qr_bitstream *   stream,
+                   const unsigned int * values,
+                   size_t               count,
+                   size_t               bitsize)
+{
+        if (ensure_available(stream, count * bitsize) != 0)
+                return -1;
+
+        while (count--)
+                qr_bitstream_write(stream, *(values++), bitsize);
+
+        return 0;
+}
+
+int qr_bitstream_cat(struct qr_bitstream * dest, const struct qr_bitstream * src)
+{
+        size_t count = qr_bitstream_size(src);
+        size_t srcpos;
+
+        if (ensure_available(dest, count) != 0)
+                return -1;
+
+        srcpos = qr_bitstream_tell(src);
+        qr_bitstream_seek((struct qr_bitstream *)src, 0);
+
+        /* uint must be at least 16 bits */
+        for (; count >= 16; count -= 16)
+                qr_bitstream_write(
+                        dest,
+                        qr_bitstream_read((struct qr_bitstream *)src, 16),
+                        16);
+
+        if (count > 0)
+                qr_bitstream_write(
+                        dest,
+                        qr_bitstream_read((struct qr_bitstream *)src, count),
+                        count);
+
+        qr_bitstream_seek((struct qr_bitstream *)src, srcpos);
+
+        return 0;
+}
+
diff --git a/lpg/libqr/qr-bitstream.h b/lpg/libqr/qr-bitstream.h
new file mode 100644
index 0000000..298e53b
--- /dev/null
+++ b/lpg/libqr/qr-bitstream.h
@@ -0,0 +1,44 @@
+#ifndef QR_BITSTREAM_H
+#define QR_BITSTREAM_H
+
+#include <stddef.h>
+
+/**
+ * Note: when writing / reading multiple bits, the
+ * _most_ significant bits come first in the stream.
+ * (That is, the order you would naturally write the
+ * number in binary)
+ */
+
+struct qr_bitstream;
+
+struct qr_bitstream * qr_bitstream_create(void);
+int                qr_bitstream_resize(struct qr_bitstream *, size_t bits);
+void               qr_bitstream_destroy(struct qr_bitstream *);
+struct qr_bitstream * qr_bitstream_copy(const struct qr_bitstream *);
+
+void qr_bitstream_seek(struct qr_bitstream *, size_t pos);
+size_t qr_bitstream_tell(const struct qr_bitstream *);
+size_t qr_bitstream_remaining(const struct qr_bitstream *);
+size_t qr_bitstream_size(const struct qr_bitstream *);
+
+unsigned int qr_bitstream_read(struct qr_bitstream *, size_t bits);
+
+void qr_bitstream_unpack(struct qr_bitstream *,
+                      unsigned int * result,
+                      size_t         count,
+                      size_t         bitsize);
+
+int qr_bitstream_write(struct qr_bitstream *,
+                    unsigned int value,
+                    size_t       bits);
+
+int qr_bitstream_pack(struct qr_bitstream *,
+                   const unsigned int * values,
+                   size_t               count,
+                   size_t               bitsize);
+
+int qr_bitstream_cat(struct qr_bitstream *, const struct qr_bitstream * src);
+
+#endif
+
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
index 1e6c6bf..42b404f 100644
--- a/lpg/libqr/rs-encode.c
+++ b/lpg/libqr/rs-encode.c
@@ -1,6 +1,6 @@
 #include <assert.h>
 #include <stdlib.h>
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "rs.h"
 
 static unsigned int gf_mult(unsigned int a, unsigned int b)
@@ -46,23 +46,23 @@ static unsigned int * make_generator(int k)
         return g;
 }
 
-struct bitstream * rs_generate_words(struct bitstream * data,
+struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
                                      size_t data_words,
                                      size_t rs_words)
 {
-        struct bitstream * ec = 0;
+        struct qr_bitstream * ec = 0;
         unsigned int * b = 0;
         unsigned int * g;
         size_t n = rs_words;
         int i, r;
 
-        assert(bitstream_remaining(data) >= data_words * 8);
+        assert(qr_bitstream_remaining(data) >= data_words * 8);
 
-        ec = bitstream_create();
+        ec = qr_bitstream_create();
         if (!ec)
                 return 0;
 
-        if (bitstream_resize(ec, n * 8) != 0)
+        if (qr_bitstream_resize(ec, n * 8) != 0)
                 goto fail;
 
         b = calloc(n, sizeof(*b));
@@ -74,9 +74,9 @@ struct bitstream * rs_generate_words(struct bitstream * data,
                 goto fail;
 
         /* First, prepare the registers (b) with data bits */
-        bitstream_seek(data, 0);
+        qr_bitstream_seek(data, 0);
         for (i = 0; i < data_words; ++i) {
-                unsigned int x = b[n-1] ^ bitstream_read(data, 8);
+                unsigned int x = b[n-1] ^ qr_bitstream_read(data, 8);
                 for (r = n-1; r > 0; --r)
                         b[r] = b[r-1] ^ gf_mult(g[r], x);
                 b[0] = gf_mult(g[0], x);
@@ -84,14 +84,14 @@ struct bitstream * rs_generate_words(struct bitstream * data,
 
         /* Read off the registers */
         for (r = 0; r < n; ++r)
-                bitstream_write(ec, b[(n-1)-r], 8);
+                qr_bitstream_write(ec, b[(n-1)-r], 8);
 
         free(g);
         free(b);
         return ec;
 fail:
         free(b);
-        bitstream_destroy(ec);
+        qr_bitstream_destroy(ec);
         return 0;
 }
 
diff --git a/lpg/libqr/rs.h b/lpg/libqr/rs.h
index e640044..c87d852 100644
--- a/lpg/libqr/rs.h
+++ b/lpg/libqr/rs.h
@@ -1,9 +1,9 @@
 #ifndef RS_H
 #define RS_H
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 
-struct bitstream * rs_generate_words(struct bitstream * data,
+struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
                                      size_t data_words,
                                      size_t rs_words);
 
diff --git a/lpg/libqr/test.c b/lpg/libqr/test.c
index 035908b..4e288af 100644
--- a/lpg/libqr/test.c
+++ b/lpg/libqr/test.c
@@ -4,7 +4,7 @@
 #include <qr/code.h>
 #include <qr/data.h>
 
-#include "bitstream.h"
+#include "qr-bitstream.h"
 #include "code-common.h"
 
 int main() {
-- 
cgit v1.2.3-70-g09d2


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/libqr/code-create.c')

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


From 27ed9a6bb8e101f1eee5a953e9985f4d631a4aa9 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sun, 4 Oct 2009 14:35:01 +0900
Subject: Auto-select mask

---
 lpg/libqr/code-create.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 199 insertions(+), 7 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index ef419d3..5582a30 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -11,6 +11,15 @@
 
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
+static int mask_data(struct qr_code * code);
+static int score_mask(const struct qr_bitmap * bmp);
+static int score_runs(const struct qr_bitmap * bmp, int base);
+static int count_2blocks(const struct qr_bitmap * bmp);
+static int count_locators(const struct qr_bitmap * bmp);
+static int calc_bw_balance(const struct qr_bitmap * bmp);
+static int get_px(const struct qr_bitmap * bmp, int x, int y);
+static int get_mask(const struct qr_bitmap * bmp, int x, int y);
+
 /* FIXME: the static functions should be in a better
  * order, with prototypes.
  */
@@ -32,13 +41,6 @@ static void x_dump(struct qr_bitstream * bits)
         printf("\n");
 }
 
-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 * bmp->stride + x / CHAR_BIT;
@@ -274,3 +276,193 @@ fail:
         goto exit;
 }
 
+static int mask_data(struct qr_code * code)
+{
+        struct qr_bitmap * mask, * test;
+        int selected, score;
+        int i, best;
+
+        mask = 0;
+
+        /* Generate bitmap for each mask and evaluate */
+        for (i = 0; i < 8; ++i) {
+                test = qr_mask_apply(code->modules, i);
+                if (!test) {
+                        qr_bitmap_destroy(mask);
+                        return -1;
+                }
+                score = score_mask(test);
+                printf("mask %d scored %d\n", i, score);
+                if (!mask || score < best) {
+                        best = score;
+                        selected = i;
+                        qr_bitmap_destroy(mask);
+                        mask = test;
+                } else {
+                        qr_bitmap_destroy(test);
+                }
+        }
+        printf("Selected mask %d (%d)\n", selected, best);
+
+        qr_bitmap_destroy(code->modules);
+        code->modules = mask;
+
+        return selected;
+}
+
+static int score_mask(const struct qr_bitmap * bmp)
+{
+        const int N[4] = { 3, 3, 40, 10 };
+        int score = 0;
+
+        score += score_runs(bmp, N[0]);
+        score += N[1] * count_2blocks(bmp);
+        score += N[2] * count_locators(bmp);
+        score += N[3] * ((abs(calc_bw_balance(bmp) - 50) + 4) / 5);
+
+        return score;
+}
+
+static int score_runs(const struct qr_bitmap * bmp, int base)
+{
+        /* Runs of 5+n bits -> N[0] + i */
+        int x, y, flip;
+        int score = 0;
+        int count, last;
+
+        for (flip = 0; flip <= 1; ++flip) {
+                for (y = 0; y < bmp->height; ++y) {
+                        count = 0;
+                        for (x = 0; x < bmp->width; ++x) {
+                                int mask, bit;
+                                if (flip) {
+                                        mask = get_mask(bmp, y, x);
+                                        bit = get_mask(bmp, y, x);
+                                } else {
+                                        mask = get_mask(bmp, x, y);
+                                        bit = get_px(bmp, x, y);
+                                }
+
+                                if (mask &&
+                                    (count == 0 || !!bit == !!last)) {
+                                        ++count;
+                                        last = bit;
+                                } else {
+                                        if (count >= 5)
+                                                score += base + count - 5;
+                                        count = 0;
+                                }
+                        }
+                }
+        }
+
+        return score;
+}
+
+static int count_2blocks(const struct qr_bitmap * bmp)
+{
+        /* Count the number of 2x2 blocks (on or off) */
+        int x, y;
+        int count = 0;
+
+        /* Slow and stupid */
+        for (y = 0; y < bmp->height - 1; ++y) {
+                for (x = 0; x < bmp->width - 1; ++x) {
+                        if (get_mask(bmp, x, y) &&
+                            get_mask(bmp, x+1, y) &&
+                            get_mask(bmp, x, y+1) &&
+                            get_mask(bmp, x+1, y+1)) {
+                                int v[4];
+                                v[0] = get_px(bmp, x, y);
+                                v[1] = get_px(bmp, x+1, y);
+                                v[2] = get_px(bmp, x, y+1);
+                                v[3] = get_px(bmp, x+1, y+1);
+                                if (!(v[0] || v[1] || v[2] || v[3]) ||
+                                     (v[0] && v[1] && v[2] && v[3])) {
+                                        ++count;
+                                }
+                        }
+                }
+        }
+
+        return count;
+}
+
+static int count_locators(const struct qr_bitmap * bmp)
+{
+        /* 1:1:3:1:1 patterns -> N[2] */
+        int x, y, flip;
+        int count = 0;
+
+        for (flip = 0; flip <= 1; ++flip) {
+                for (y = 0; y < bmp->height - 7; ++y) {
+                        for (x = 0; x < bmp->width - 7; ++x) {
+                                int bits[7];
+                                int i;
+
+                                for (i = 0; i < 7; ++i)
+                                        if (!(flip ? get_mask(bmp, y, x+i) : get_mask(bmp, x+i, y)))
+                                                continue;
+
+                                for (i = 0; i < 7; ++i)
+                                        bits[i] = flip ? get_px(bmp, y, x+i) : get_px(bmp, x+i, y);
+
+                                if (!bits[0])
+                                        for (i = 0; i < 7; ++i)
+                                                bits[i] = !bits[i];
+
+                                if ( bits[0] && !bits[1] &&  bits[2] &&
+                                     bits[3] &&  bits[4] && !bits[5] &&
+                                     bits[6])
+                                        ++count;
+                        }
+                }
+        }
+
+        return count;
+}
+
+static int calc_bw_balance(const struct qr_bitmap * bmp)
+{
+        /* Calculate the proportion (in percent) of "on" bits */
+        int x, y;
+        unsigned char bit;
+        long on, total;
+
+        assert(bmp->mask); /* we only need this case */
+
+        on = total = 0;
+        for (y = 0; y < bmp->height; ++y) {
+                size_t off = y * bmp->stride;
+                unsigned char * bits = bmp->bits + off;
+                unsigned char * mask = bmp->mask + off;
+
+                for (x = 0; x < bmp->width / CHAR_BIT; ++x, ++bits, ++mask) {
+                        for (bit = 1; bit; bit <<= 1) {
+                                int m = *mask & bit;
+
+                                total += !!m;
+                                on += !!(*bits & m);
+                        }
+                }
+        }
+
+        return (on * 100) / total;
+}
+
+static int get_px(const struct qr_bitmap * bmp, int x, int y)
+{
+        size_t off = y * bmp->stride + x / CHAR_BIT;
+        unsigned char bit = 1 << (x % CHAR_BIT);
+
+        return bmp->bits[off] & bit;
+}
+
+static int get_mask(const struct qr_bitmap * bmp, int x, int y)
+{
+        size_t off = y * bmp->stride + x / CHAR_BIT;
+        unsigned char bit = 1 << (x % CHAR_BIT);
+
+        return bmp->mask[off] & bit;
+}
+
-- 
cgit v1.2.3-70-g09d2


From ad59de83b7f82cb812d23ac2bb948ac32fe0ac71 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Thu, 8 Oct 2009 12:18:31 +0900
Subject: Render ec level, mask info bits

---
 lpg/libqr/code-create.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++-
 lpg/libqr/qr/code.h     |   8 ++--
 2 files changed, 102 insertions(+), 6 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 5582a30..9ce46f7 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -19,6 +19,12 @@ static int count_locators(const struct qr_bitmap * bmp);
 static int calc_bw_balance(const struct qr_bitmap * bmp);
 static int get_px(const struct qr_bitmap * bmp, int x, int y);
 static int get_mask(const struct qr_bitmap * bmp, int x, int y);
+static int draw_format(struct qr_bitmap * bmp,
+                        struct qr_code * code,
+                        enum qr_ec_level ec,
+                        int mask);
+static int calc_format_bits(enum qr_ec_level ec, int mask);
+static unsigned long gal_residue(unsigned long a, unsigned long m);
 
 /* FIXME: the static functions should be in a better
  * order, with prototypes.
@@ -63,6 +69,7 @@ static void draw_locator(struct qr_bitmap * bmp, int x, int y)
 }
 
 static int draw_functional(struct qr_code * code,
+                           enum qr_ec_level ec,
                            unsigned int mask)
 {
         struct qr_bitmap * bmp;
@@ -85,8 +92,13 @@ static int draw_functional(struct qr_code * code,
         }
 
         /* XXX: alignment pattern */
-        /* XXX: mask, format info */
 
+        /* Format info */
+        setpx(bmp, 8, dim - 8);
+        if (draw_format(bmp, code, ec, mask) != 0)
+                return -1;
+
+        /* Merge data */
         qr_bitmap_merge(bmp, code->modules);
         qr_bitmap_destroy(code->modules);
         code->modules = bmp;
@@ -261,7 +273,7 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         if (mask < 0)
                 goto fail;
 
-        if (draw_functional(code, mask) != 0)
+        if (draw_functional(code, ec, mask) != 0)
                 goto fail;
 
 exit:
@@ -466,3 +478,87 @@ static int get_mask(const struct qr_bitmap * bmp, int x, int y)
         return bmp->mask[off] & bit;
 }
 
+static int draw_format(struct qr_bitmap * bmp,
+                        struct qr_code * code,
+                        enum qr_ec_level ec,
+                        int mask)
+{
+        int i;
+        size_t dim;
+        long bits;
+
+        dim = bmp->width;
+
+        bits = calc_format_bits(ec, mask);
+        if (bits < 0)
+                return -1;
+
+        for (i = 0; i < 8; ++i) {
+                if (bits & 0x1) {
+                        setpx(bmp, 8, i);
+                        setpx(bmp, dim - 1 - i, 8);
+                }
+                bits >>= 1;
+        }
+
+        for (i = 0; i < 7; ++i) {
+                if (bits & 0x1) {
+                        setpx(bmp, 8, dim - 7 + i);
+                        setpx(bmp, 6 - i + (i == 0), 8);
+                }
+                bits >>= 1;
+        }
+
+        /* XXX: size info for 7~40 */
+
+        return 0;
+}
+
+static int calc_format_bits(enum qr_ec_level ec, int mask)
+{
+        int bits;
+
+        bits = (ec & 0x3) << 3 | (mask & 0x7);
+
+        /* Compute (15, 5) BCH code with
+         *   G(x) = x^10 + x^8 + x^5 + x^4 + x^2 + x + 1
+         */
+
+        bits <<= 15 - 5;
+        bits |= (unsigned int)gal_residue(bits, 0x537);
+
+        /* XOR mask: 101 0100 0001 0010 */
+        bits ^= 0x5412;
+
+        return bits;
+}
+
+/* Calculate the residue of a modulo m */
+static unsigned long gal_residue(unsigned long a,
+                                   unsigned long m)
+{
+        unsigned long o = 1;
+        int n = 1;
+
+        /* Find one past the highest bit of the modulus */
+        while (m & ~(o - 1))
+                o <<= 1;
+
+        /* Find the highest n such that O(m * x^n) <= O(a) */
+        while (a & ~(o - 1)) {
+                o <<= 1;
+                ++n;
+        }
+
+        /* For each n, try to reduce a by (m * x^n) */
+        while (n--) {
+                o >>= 1;
+
+                /* o is the highest bit of (m * x^n) */
+                if (a & o)
+                        a ^= m << n;
+        }
+
+        return a;
+}
+
diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h
index 56a9884..dba0040 100644
--- a/lpg/libqr/qr/code.h
+++ b/lpg/libqr/qr/code.h
@@ -5,10 +5,10 @@
 #include "types.h"
 
 enum qr_ec_level {
-        QR_EC_LEVEL_L,
-        QR_EC_LEVEL_M,
-        QR_EC_LEVEL_Q,
-        QR_EC_LEVEL_H
+        QR_EC_LEVEL_L = 0x1,
+        QR_EC_LEVEL_M = 0x0,
+        QR_EC_LEVEL_Q = 0x3,
+        QR_EC_LEVEL_H = 0x2
 };
 
 struct qr_code * qr_code_create(enum qr_ec_level       ec,
-- 
cgit v1.2.3-70-g09d2


From 62e8a6f2ad89be06c7e649c0fc4c564ecad2d070 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Thu, 8 Oct 2009 14:38:37 +0900
Subject: code format --> version

---
 lpg/libqr/code-common.c | 15 +++++----------
 lpg/libqr/code-common.h |  6 ++----
 lpg/libqr/code-create.c | 17 ++++++++---------
 lpg/libqr/code-layout.c |  4 ++--
 lpg/libqr/data-common.c |  6 +++---
 lpg/libqr/data-common.h |  4 ++--
 lpg/libqr/data-create.c | 14 +++++++-------
 lpg/libqr/data-parse.c  |  8 ++++----
 8 files changed, 33 insertions(+), 41 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index 32f6492..dc2a8f0 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -14,26 +14,21 @@ void qr_code_destroy(struct qr_code * code)
 
 int qr_code_width(const struct qr_code * code)
 {
-        return code_side_length(code->format);
+        return code->version * 4 + 17;
 }
 
-int code_side_length(int format)
+size_t code_total_capacity(int version)
 {
-        return format * 4 + 17;
-}
-
-size_t code_total_capacity(int format)
-{
-	int side = format * 4 + 17;
+	int side = version * 4 + 17;
 
-	int alignment_side = format > 1 ? (format / 7) + 2 : 0;
+	int alignment_side = version > 1 ? (version / 7) + 2 : 0;
 
 	int alignment_count = alignment_side >= 2 ?
 		alignment_side * alignment_side - 3 : 0;
 
 	int locator_bits = 8*8*3;
 
-	int format_bits = 8*4 - 1 + (format >= 7 ? 6*3*2 : 0);
+	int format_bits = 8*4 - 1 + (version >= 7 ? 6*3*2 : 0);
 
 	int timing_bits = 2 * (side - 8*2 -
 		(alignment_side > 2 ? (alignment_side - 2) * 5 : 0));
diff --git a/lpg/libqr/code-common.h b/lpg/libqr/code-common.h
index cf96217..11538d8 100644
--- a/lpg/libqr/code-common.h
+++ b/lpg/libqr/code-common.h
@@ -6,13 +6,11 @@
 #include "qr-bitmap.h"
 
 struct qr_code {
-        int                format;
+        int                version;
         struct qr_bitmap * modules;
 };
 
-int code_side_length(int format);
-
-size_t code_total_capacity(int format);
+size_t code_total_capacity(int version);
 
 #endif
 
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 9ce46f7..6c56f45 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -73,7 +73,7 @@ static int draw_functional(struct qr_code * code,
                            unsigned int mask)
 {
         struct qr_bitmap * bmp;
-        int dim = code_side_length(code->format);
+        int dim = qr_code_width(code);
         int i;
 
         bmp = qr_bitmap_create(dim, dim, 0);
@@ -146,11 +146,11 @@ static int pad_data(struct qr_bitstream * bits, size_t limit)
         return 0;
 }
 
-static struct qr_bitstream * make_data(int                format,
-                                    enum qr_ec_level   ec,
-                                    struct qr_bitstream * data)
+static struct qr_bitstream * make_data(int version,
+                                       enum qr_ec_level   ec,
+                                       struct qr_bitstream * data)
 {
-        const size_t total_bits = code_total_capacity(format);
+        const size_t total_bits = code_total_capacity(version);
         const size_t total_words = total_bits / 8;
         size_t block_count, data_words, rs_words;
         size_t i;
@@ -246,15 +246,14 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         if (!code)
                 return 0;
 
-        dim = code_side_length(data->format);
-
-        code->format = data->format;
+        code->version = data->version;
+        dim = qr_code_width(code);
         code->modules = qr_bitmap_create(dim, dim, 1);
 
         if (!code->modules)
                 goto fail;
 
-        bits = make_data(data->format, ec, data->bits);
+        bits = make_data(data->version, ec, data->bits);
         if (!bits)
                 goto fail;
 
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 46d2800..4be3871 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -19,7 +19,7 @@ struct qr_iterator {
 void qr_layout_init_mask(struct qr_code * code)
 {
         int x, y;
-        int dim = code_side_length(code->format);
+        int dim = qr_code_width(code);
         struct qr_bitmap * bmp = code->modules;
 
         assert(bmp->mask);
@@ -110,7 +110,7 @@ struct qr_iterator * qr_layout_begin(struct qr_code * code)
 
         i = malloc(sizeof(*i));
         if (i) {
-                i->dim = code_side_length(code->format);
+                i->dim = qr_code_width(code);
                 i->code = code;
                 i->column = i->dim - 1;
                 i->row = i->dim - 1;
diff --git a/lpg/libqr/data-common.c b/lpg/libqr/data-common.c
index c64527a..ac2f198 100644
--- a/lpg/libqr/data-common.c
+++ b/lpg/libqr/data-common.c
@@ -29,7 +29,7 @@ void qr_free_data(struct qr_data * data)
         free(data);
 }
 
-size_t get_size_field_length(int format, enum qr_data_type type)
+size_t get_size_field_length(int version, enum qr_data_type type)
 {
         static const size_t QR_SIZE_LENGTHS[3][4] = {
                 { 10,  9,  8,  8 },
@@ -46,9 +46,9 @@ size_t get_size_field_length(int format, enum qr_data_type type)
         default:                return 0;
         }
 
-        if (format < 10)
+        if (version < 10)
                 row = 0;
-        else if (format < 27)
+        else if (version < 27)
                 row = 1;
         else
                 row = 2;
diff --git a/lpg/libqr/data-common.h b/lpg/libqr/data-common.h
index 1522b09..bc2b381 100644
--- a/lpg/libqr/data-common.h
+++ b/lpg/libqr/data-common.h
@@ -6,14 +6,14 @@
 #include "qr-bitstream.h"
 
 struct qr_data {
-        int                format; /* 1 ~ 40 */
+        int                version; /* 1 ~ 40 */
         struct qr_bitstream * bits;
         size_t             offset;
 };
 
 extern const enum qr_data_type QR_TYPE_CODES[16];
 
-size_t get_size_field_length(int format, enum qr_data_type);
+size_t get_size_field_length(int version, enum qr_data_type);
 
 #endif
 
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index a918413..2c2737f 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -18,7 +18,7 @@ static void write_type_and_length(struct qr_data *  data,
 {
         (void)qr_bitstream_write(data->bits, QR_TYPE_CODES[type], 4);
         (void)qr_bitstream_write(data->bits, length,
-                get_size_field_length(data->format, type));
+                get_size_field_length(data->version, type));
 }
 
 static struct qr_data * encode_numeric(struct qr_data * data,
@@ -28,7 +28,7 @@ static struct qr_data * encode_numeric(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->format, QR_DATA_NUMERIC)
+        bits = 4 + get_size_field_length(data->version, QR_DATA_NUMERIC)
                  + 10 * (length / 3);
 
         if (length % 3 == 1)
@@ -106,7 +106,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->format, QR_DATA_ALPHA)
+        bits = 4 + get_size_field_length(data->version, QR_DATA_ALPHA)
                  + 11 * (length / 2)
                  + 6 * (length % 2);
 
@@ -150,7 +150,7 @@ static struct qr_data * encode_8bit(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->format, QR_DATA_8BIT)
+        bits = 4 + get_size_field_length(data->version, QR_DATA_8BIT)
                  + 8 * length;
 
         stream = data->bits;
@@ -173,21 +173,21 @@ static struct qr_data * encode_kanji(struct qr_data * data,
         return 0;
 }
 
-struct qr_data * qr_create_data(int               format,
+struct qr_data * qr_create_data(int               version,
                                 enum qr_data_type type,
                                 const char *      input,
                                 size_t            length)
 {
         struct qr_data * data;
 
-        if (format < 1 || format > 40)
+        if (version < 1 || version > 40)
                 return 0;
 
         data = malloc(sizeof(*data));
         if (!data)
                 return 0;
 
-        data->format = format;
+        data->version = version;
         data->bits   = qr_bitstream_create();
         data->offset = 0;
 
diff --git a/lpg/libqr/data-parse.c b/lpg/libqr/data-parse.c
index d497bdf..4868cd2 100644
--- a/lpg/libqr/data-parse.c
+++ b/lpg/libqr/data-parse.c
@@ -33,7 +33,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
         stream = data->bits;
         buffer = 0;
 
-        field_len = get_size_field_length(data->format, QR_DATA_NUMERIC);
+        field_len = get_size_field_length(data->version, QR_DATA_NUMERIC);
         if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
@@ -93,7 +93,7 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
         stream = data->bits;
         buffer = 0;
 
-        field_len = get_size_field_length(data->format, QR_DATA_ALPHA);
+        field_len = get_size_field_length(data->version, QR_DATA_ALPHA);
         if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
@@ -150,7 +150,7 @@ static enum qr_data_type parse_8bit(const struct qr_data * data,
 
         stream = data->bits;
 
-        field_len = get_size_field_length(data->format, QR_DATA_8BIT);
+        field_len = get_size_field_length(data->version, QR_DATA_8BIT);
         if (qr_bitstream_remaining(stream) < field_len)
                 return QR_DATA_INVALID;
 
@@ -201,7 +201,7 @@ int qr_get_data_length(const struct qr_data * data)
         case QR_DATA_ALPHA:
         case QR_DATA_8BIT:
         case QR_DATA_KANJI:
-                field_len = get_size_field_length(data->format, type);
+                field_len = get_size_field_length(data->version, type);
                 break;
         default:
                 /* unsupported / invalid */
-- 
cgit v1.2.3-70-g09d2


From 6359bfddcc5868093418784fa2e972581ebd82b6 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Thu, 8 Oct 2009 14:48:28 +0900
Subject: render version bits

---
 lpg/libqr/code-create.c | 29 ++++++++++++++++++++++++++++-
 lpg/libqr/code-layout.c |  9 ++++++++-
 2 files changed, 36 insertions(+), 2 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 6c56f45..9936981 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -24,6 +24,7 @@ static int draw_format(struct qr_bitmap * bmp,
                         enum qr_ec_level ec,
                         int mask);
 static int calc_format_bits(enum qr_ec_level ec, int mask);
+static long calc_version_bits(int version);
 static unsigned long gal_residue(unsigned long a, unsigned long m);
 
 /* FIXME: the static functions should be in a better
@@ -508,7 +509,18 @@ static int draw_format(struct qr_bitmap * bmp,
                 bits >>= 1;
         }
 
-        /* XXX: size info for 7~40 */
+        if (code->version >= 7) {
+                bits = calc_version_bits(code->version);
+
+                for (i = 0; i < 18; ++i) {
+                        if (bits & 0x1) {
+                                int a = i % 3, b = i / 3;
+                                setpx(bmp, dim - 11 + a, b);
+                                setpx(bmp, b, dim - 11 + a);
+                        }
+                        bits >>= 1;
+                }
+        }
 
         return 0;
 }
@@ -532,6 +544,21 @@ static int calc_format_bits(enum qr_ec_level ec, int mask)
         return bits;
 }
 
+static long calc_version_bits(int version)
+{
+        long bits;
+
+        bits = version & 0x3F;
+
+        /* (18, 6) BCH code
+         *   G(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
+         */
+        bits <<= 18 - 6;
+        bits |= gal_residue(bits, 0x1F25);
+
+        return bits;
+}
+
 /* Calculate the residue of a modulo m */
 static unsigned long gal_residue(unsigned long a,
                                    unsigned long m)
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 4be3871..ed01112 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -45,7 +45,14 @@ void qr_layout_init_mask(struct qr_code * code)
                         if (x < 9 && y >= dim - 8) /* bottom-left */
                                 continue;
 
-                        /* XXX: format data */
+                        /* version info */
+                        if (code->version >= 7) {
+                                if (y < 6 && x >= dim - 11)
+                                        continue;
+                                if (x < 6 && y >= dim - 11)
+                                        continue;
+                        }
+
                         /* XXX: alignment pattern */
 
                         row[off] |= bit;
-- 
cgit v1.2.3-70-g09d2


From 5d9157331d8dd08010790bc9d17053bac279f524 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Thu, 8 Oct 2009 16:48:51 +0900
Subject: debug output to stderr

---
 lpg/libqr/code-create.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 9936981..2e0a0b2 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -39,13 +39,13 @@ static void x_dump(struct qr_bitstream * bits)
         qr_bitstream_seek(bits, 0);
         n = qr_bitstream_size(bits);
         for (i = 0; i < n; ++i) {
-                printf("%d", qr_bitstream_read(bits, 1));
+                fprintf(stderr, "%d", qr_bitstream_read(bits, 1));
                 if (i % 8 == 7)
-                        printf(" ");
+                        fputc(' ', stderr);
                 if ((i+1) % (7 * 8) == 0)
-                        printf("\n");
+                        fputc('\n', stderr);
         }
-        printf("\n");
+        fputc('\n', stderr);
 }
 
 static void setpx(struct qr_bitmap * bmp, int x, int y)
@@ -185,7 +185,7 @@ static struct qr_bitstream * make_data(int version,
         if (pad_data(dcopy, data_words * 8) != 0)
                 goto fail;
 
-        puts("Pad data:");
+        fputs("Pad data:\n", stderr);
         x_dump(dcopy);
 
         /* Make space for the RS blocks */
@@ -195,7 +195,7 @@ static struct qr_bitstream * make_data(int version,
 
         /* Generate RS codewords */
         qr_bitstream_seek(dcopy, 0);
-        puts("Generate RS blocks:");
+        fputs("Generate RS blocks:\n", stderr);
         for (i = 0; i < block_count; ++i) {
                 /* XXX: some blocks may be longer */
                 blocks[i] = rs_generate_words(dcopy, data_words, rs_words);
@@ -215,7 +215,7 @@ static struct qr_bitstream * make_data(int version,
         qr_bitstream_cat(out, blocks[0]);
         qr_bitstream_write(out, 0, total_bits - total_words * 8);
 
-        puts("Final bitstream:");
+        fputs("Final bitstream:\n", stderr);
         x_dump(out);
 exit:
         if (blocks) {
@@ -304,7 +304,7 @@ static int mask_data(struct qr_code * code)
                         return -1;
                 }
                 score = score_mask(test);
-                printf("mask %d scored %d\n", i, score);
+                fprintf(stderr, "mask %d scored %d\n", i, score);
                 if (!mask || score < best) {
                         best = score;
                         selected = i;
@@ -314,7 +314,7 @@ static int mask_data(struct qr_code * code)
                         qr_bitmap_destroy(test);
                 }
         }
-        printf("Selected mask %d (%d)\n", selected, best);
+        fprintf(stderr, "Selected mask %d (%d)\n", selected, best);
 
         qr_bitmap_destroy(code->modules);
         code->modules = mask;
-- 
cgit v1.2.3-70-g09d2


From 4eee8658be637fde410f429e69e86b034cd39185 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sun, 1 Nov 2009 22:54:33 +0900
Subject: support for multiple ec blocks

---
 lpg/libqr/Makefile       |  3 +-
 lpg/libqr/capacity.c     | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/code-create.c  | 49 +++++++++++++++------------
 lpg/libqr/qr-bitstream.c | 18 ++++++++--
 lpg/libqr/qr-bitstream.h |  6 +++-
 5 files changed, 138 insertions(+), 26 deletions(-)
 create mode 100644 lpg/libqr/capacity.c

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index 19e8791..3a6af6f 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -1,4 +1,5 @@
-OBJECTS :=      code-common.o           \
+OBJECTS :=      capacity.o              \
+                code-common.o           \
                 code-create.o           \
                 code-layout.o           \
                 code-parse.o            \
diff --git a/lpg/libqr/capacity.c b/lpg/libqr/capacity.c
new file mode 100644
index 0000000..4b513af
--- /dev/null
+++ b/lpg/libqr/capacity.c
@@ -0,0 +1,88 @@
+/* FIXME: don't like big tables of data */
+
+const int QR_DATA_WORD_COUNT[40][4] = {
+          19,   16,   13,    9,
+          34,   28,   22,   16,
+          55,   44,   34,   26,
+          80,   64,   48,   36,
+         108,   86,   62,   46,
+         136,  108,   76,   60,
+         156,  124,   88,   66,
+         194,  154,  110,   86,
+         232,  182,  132,  100,
+         274,  216,  154,  122,
+         324,  254,  180,  140,
+         370,  290,  206,  158,
+         428,  334,  244,  180,
+         461,  365,  261,  197,
+         523,  415,  295,  223,
+         589,  453,  325,  253,
+         647,  507,  367,  283,
+         721,  563,  397,  313,
+         795,  627,  445,  341,
+         861,  669,  485,  385,
+         932,  714,  512,  406,
+        1006,  782,  568,  442,
+        1094,  860,  614,  464,
+        1174,  914,  664,  514,
+        1276, 1000,  718,  538,
+        1370, 1062,  754,  596,
+        1468, 1128,  808,  628,
+        1531, 1193,  871,  661,
+        1631, 1267,  911,  701,
+        1735, 1373,  985,  745,
+        1845, 1455, 1033,  793,
+        1955, 1541, 1115,  845,
+        2071, 1631, 1171,  901,
+        2191, 1725, 1231,  961,
+        2306, 1812, 1286,  986,
+        2434, 1914, 1351, 1054,
+        2566, 1992, 1426, 1096,
+        2812, 2216, 1582, 1222,
+        2956, 2334, 1666, 1276
+};
+
+/* I'm sure we can calculate these values */
+const int QR_RS_BLOCK_COUNT[40][4][2] = {
+         1,  0,  1,  0,  1,  0,  1,  0, /*  1 */
+         1,  0,  1,  0,  1,  0,  1,  0, /*  2 */
+         1,  0,  1,  0,  2,  0,  2,  0, /*  3 */
+         1,  0,  2,  0,  2,  0,  4,  0, /*  4 */
+         1,  0,  2,  0,  2,  0,  2,  0,
+         2,  0,  4,  0,  4,  0,  4,  0,
+         2,  0,  4,  0,  2,  4,  4,  1,
+         2,  0,  2,  2,  4,  2,  4,  2, /*  8 */
+         2,  0,  3,  2,  4,  4,  4,  4,
+         2,  2,  4,  1,  6,  2,  6,  2,
+         4,  0,  1,  4,  4,  4,  3,  8,
+         2,  2,  6,  2,  4,  6,  7,  4,
+         4,  0,  8,  1,  8,  4, 12,  4,
+         3,  1,  4,  5, 11,  5, 11,  5, /* 14 */
+         5,  1,  5,  5,  5,  7, 11,  7,
+         5,  1,  7,  3, 15,  2,  3, 13,
+         1,  5, 10,  1,  1, 15,  2, 17,
+         5,  1,  9,  4, 17,  1,  2, 19,
+         3,  4,  3, 11, 17,  4,  9, 16, /* 19 */
+         3,  5,  3, 13, 15,  5, 15, 10,
+         4,  4, 17,  0, 17,  6, 19,  6,
+         2,  7, 17,  0,  7, 16, 34,  0,
+         4,  5,  4, 14, 11, 14, 16, 14,
+         6,  4,  6, 14, 11, 16, 30,  2,
+         8,  4,  8, 13,  7, 22, 22, 13, /* 25 */
+        10,  2, 19,  4, 28,  6, 33,  4,
+         8,  4, 22,  3,  8, 26, 12, 28,
+         3, 10,  3, 23,  4, 31, 11, 31,
+         7,  7, 21,  7,  1, 37, 19, 26,
+         5, 10, 19, 10, 15, 25, 23, 25, /* 30 */
+        13,  3,  2, 29, 42,  1, 23, 28,
+        17,  0, 10, 23, 10, 35, 19, 35,
+        17,  1, 14, 21, 29, 19, 11, 46,
+        13,  6, 14, 23, 44,  7, 59,  1,
+        12,  7, 12, 26, 39, 14, 22, 41, /* 35 */
+         6, 14,  6, 34, 46, 10,  2, 64,
+        17,  4, 29, 14, 49, 10, 24, 46,
+         4, 18, 13, 32, 48, 14, 42, 32,
+        20,  4, 40,  7, 43, 22, 10, 67,
+        19,  6, 18, 31, 34, 34, 20, 61 /* 40 */
+};
+
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 2e0a0b2..36ebb24 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -11,6 +11,9 @@
 
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
+extern const int QR_DATA_WORD_COUNT[40][4];
+extern const int QR_RS_BLOCK_COUNT[40][4][2];
+
 static int mask_data(struct qr_code * code);
 static int score_mask(const struct qr_bitmap * bmp);
 static int score_runs(const struct qr_bitmap * bmp, int base);
@@ -153,7 +156,8 @@ static struct qr_bitstream * make_data(int version,
 {
         const size_t total_bits = code_total_capacity(version);
         const size_t total_words = total_bits / 8;
-        size_t block_count, data_words, rs_words;
+        const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
+        size_t total_blocks, block_count[2], data_words, rs_words;
         size_t i;
         struct qr_bitstream * dcopy = 0;
         struct qr_bitstream * out = 0;
@@ -167,38 +171,38 @@ static struct qr_bitstream * make_data(int version,
         if (qr_bitstream_resize(out, total_bits) != 0)
                 goto fail;
 
-        /**
-         * XXX: For our test case (1-M) there is only one RS block.
-         * This is not the case for most other formats, so we'll
-         * have to deal with this eventually.
-         */
-        block_count = 1;
-        data_words = 16;
-        rs_words = 10;
-        assert(data_words + rs_words == total_words);
+        /* XXX: 14-M will be incorrect */
+        block_count[0] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][0];
+        block_count[1] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][1];
+        total_blocks = block_count[0] + block_count[1];
+        data_words = total_data / total_blocks;
+        rs_words = total_words / total_blocks - data_words;
+        assert((data_words + rs_words) * block_count[0] +
+               (data_words + rs_words + 1) * block_count[1] == total_words);
 
         /* Make a copy of the data and pad it */
-        dcopy = qr_bitstream_copy(data);
+        dcopy = qr_bitstream_dup(data);
         if (!dcopy)
                 goto fail;
 
-        if (pad_data(dcopy, data_words * 8) != 0)
+        if (pad_data(dcopy, total_data * 8) != 0)
                 goto fail;
 
         fputs("Pad data:\n", stderr);
         x_dump(dcopy);
 
         /* Make space for the RS blocks */
-        blocks = calloc(block_count, sizeof(*blocks));
+        blocks = calloc(total_blocks, sizeof(*blocks));
         if (!blocks)
                 goto fail;
 
         /* Generate RS codewords */
         qr_bitstream_seek(dcopy, 0);
         fputs("Generate RS blocks:\n", stderr);
-        for (i = 0; i < block_count; ++i) {
-                /* XXX: some blocks may be longer */
-                blocks[i] = rs_generate_words(dcopy, data_words, rs_words);
+        for (i = 0; i < total_blocks; ++i) {
+                size_t dw = data_words + (i >= block_count[0]);
+
+                blocks[i] = rs_generate_words(dcopy, dw, rs_words);
                 if (!blocks[i]) {
                         while (i--)
                                 qr_bitstream_destroy(blocks[i]);
@@ -210,17 +214,20 @@ static struct qr_bitstream * make_data(int version,
         }
 
         /* Finally, write everything out in the correct order */
-        /* XXX: need to handle multiple blocks */
-        qr_bitstream_cat(out, dcopy);
-        qr_bitstream_cat(out, blocks[0]);
+        qr_bitstream_seek(dcopy, 0);
+        for (i = 0; i < total_blocks; ++i) {
+                size_t dw = data_words + (i >= block_count[0]);
+                qr_bitstream_copy(out, dcopy, dw * 8);
+                qr_bitstream_cat(out, blocks[i]);
+        }
         qr_bitstream_write(out, 0, total_bits - total_words * 8);
 
         fputs("Final bitstream:\n", stderr);
         x_dump(out);
 exit:
         if (blocks) {
-                while (block_count--)
-                       qr_bitstream_destroy(blocks[block_count]);
+                while (total_blocks--)
+                       qr_bitstream_destroy(blocks[total_blocks]);
                 free(blocks);
         }
         if (dcopy)
diff --git a/lpg/libqr/qr-bitstream.c b/lpg/libqr/qr-bitstream.c
index b223f4c..c752cde 100644
--- a/lpg/libqr/qr-bitstream.c
+++ b/lpg/libqr/qr-bitstream.c
@@ -80,7 +80,7 @@ void qr_bitstream_destroy(struct qr_bitstream * stream)
         free(stream);
 }
 
-struct qr_bitstream * qr_bitstream_copy(const struct qr_bitstream * src)
+struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream * src)
 {
         struct qr_bitstream * ret;
 
@@ -210,6 +210,20 @@ int qr_bitstream_cat(struct qr_bitstream * dest, const struct qr_bitstream * src
 
         srcpos = qr_bitstream_tell(src);
         qr_bitstream_seek((struct qr_bitstream *)src, 0);
+        qr_bitstream_copy(dest, (struct qr_bitstream *)src, count);
+        qr_bitstream_seek((struct qr_bitstream *)src, srcpos);
+
+        return 0;
+}
+
+int qr_bitstream_copy(struct qr_bitstream * dest,
+                      struct qr_bitstream * src,
+                      size_t count)
+{
+        if (qr_bitstream_remaining(src) < count)
+                return -1;
+        if (ensure_available(dest, count) != 0)
+                return -1;
 
         /* uint must be at least 16 bits */
         for (; count >= 16; count -= 16)
@@ -224,8 +238,6 @@ int qr_bitstream_cat(struct qr_bitstream * dest, const struct qr_bitstream * src
                         qr_bitstream_read((struct qr_bitstream *)src, count),
                         count);
 
-        qr_bitstream_seek((struct qr_bitstream *)src, srcpos);
-
         return 0;
 }
 
diff --git a/lpg/libqr/qr-bitstream.h b/lpg/libqr/qr-bitstream.h
index 298e53b..cf20694 100644
--- a/lpg/libqr/qr-bitstream.h
+++ b/lpg/libqr/qr-bitstream.h
@@ -15,7 +15,7 @@ struct qr_bitstream;
 struct qr_bitstream * qr_bitstream_create(void);
 int                qr_bitstream_resize(struct qr_bitstream *, size_t bits);
 void               qr_bitstream_destroy(struct qr_bitstream *);
-struct qr_bitstream * qr_bitstream_copy(const struct qr_bitstream *);
+struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream *);
 
 void qr_bitstream_seek(struct qr_bitstream *, size_t pos);
 size_t qr_bitstream_tell(const struct qr_bitstream *);
@@ -40,5 +40,9 @@ int qr_bitstream_pack(struct qr_bitstream *,
 
 int qr_bitstream_cat(struct qr_bitstream *, const struct qr_bitstream * src);
 
+int qr_bitstream_copy(struct qr_bitstream * dest,
+                      struct qr_bitstream * src,
+                      size_t count);
+
 #endif
 
-- 
cgit v1.2.3-70-g09d2


From 688c1b52ed356d024ba2e72ba52f7da64b7d74ed Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Tue, 3 Nov 2009 00:12:30 +0900
Subject: generate alignment pattern

---
 lpg/libqr/TODO          |  2 --
 lpg/libqr/code-common.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/code-common.h |  2 ++
 lpg/libqr/code-create.c | 23 ++++++++++++++++++++++-
 lpg/libqr/code-layout.c | 27 +++++++++++++++++++++++++--
 5 files changed, 92 insertions(+), 5 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/TODO b/lpg/libqr/TODO
index 6efa259..eb35da8 100644
--- a/lpg/libqr/TODO
+++ b/lpg/libqr/TODO
@@ -1,5 +1,3 @@
-* Get sample generated OK
-* Fix generation for all sizes (alignment pattern)
 * Auto-sizing for data
 * Sample app
 * Merge some files
diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index 150dfc5..7c3c119 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -38,3 +38,46 @@ size_t code_total_capacity(int version)
 	return side * side - function_bits;
 }
 
+const int QR_ALIGNMENT_LOCATION[40][7] = {
+        {  0,  0,  0,  0,  0,  0,  0 }, /*  1 */
+        {  6, 18,  0,  0,  0,  0,  0 }, /*  2 */
+        {  6, 22,  0,  0,  0,  0,  0 }, /*  3 */
+        {  6, 26,  0,  0,  0,  0,  0 }, /*  4 */
+        {  6, 30,  0,  0,  0,  0,  0 }, /*  5 */
+        {  6, 34,  0,  0,  0,  0,  0 }, /*  6 */
+        {  6, 22, 38,  0,  0,  0,  0 }, /*  7 */
+        {  6, 24, 42,  0,  0,  0,  0 }, /*  8 */
+        {  6, 26, 46,  0,  0,  0,  0 }, /*  9 */
+        {  6, 28, 50,  0,  0,  0,  0 }, /* 10 */
+        {  6, 30, 54,  0,  0,  0,  0 }, /* 11 */
+        {  6, 32, 58,  0,  0,  0,  0 }, /* 12 */
+        {  6, 34, 62,  0,  0,  0,  0 }, /* 13 */
+        {  6, 26, 46, 66,  0,  0,  0 }, /* 14 */
+        {  6, 26, 48, 70,  0,  0,  0 }, /* 15 */
+        {  6, 26, 50, 74,  0,  0,  0 }, /* 16 */
+        {  6, 30, 54, 78,  0,  0,  0 }, /* 17 */
+        {  6, 30, 56, 82,  0,  0,  0 }, /* 18 */
+        {  6, 30, 58, 86,  0,  0,  0 }, /* 19 */
+        {  6, 34, 62, 90,  0,  0,  0 }, /* 20 */
+        {  6, 28, 50, 72, 94,  0,  0 }, /* 21 */
+        {  6, 26, 50, 74, 98,  0,  0 }, /* 22 */
+        {  6, 30, 54, 78,102,  0,  0 }, /* 23 */
+        {  6, 28, 54, 80,106,  0,  0 }, /* 24 */
+        {  6, 32, 58, 84,110,  0,  0 }, /* 25 */
+        {  6, 30, 58, 86,114,  0,  0 }, /* 26 */
+        {  6, 34, 62, 90,118,  0,  0 }, /* 27 */
+        {  6, 26, 50, 74, 98,122,  0 }, /* 28 */
+        {  6, 30, 54, 78,102,126,  0 }, /* 29 */
+        {  6, 26, 52, 78,104,130,  0 }, /* 30 */
+        {  6, 30, 56, 82,108,134,  0 }, /* 31 */
+        {  6, 34, 60, 86,112,138,  0 }, /* 32 */
+        {  6, 30, 58, 86,114,142,  0 }, /* 33 */
+        {  6, 34, 62, 90,118,146,  0 }, /* 34 */
+        {  6, 30, 54, 78,102,126,150 }, /* 35 */
+        {  6, 24, 50, 76,102,128,154 }, /* 36 */
+        {  6, 28, 54, 80,106,132,158 }, /* 37 */
+        {  6, 32, 58, 84,110,136,162 }, /* 38 */
+        {  6, 26, 54, 82,110,138,166 }, /* 39 */
+        {  6, 30, 58, 86,114,142,170 }, /* 40 */
+};
+
diff --git a/lpg/libqr/code-common.h b/lpg/libqr/code-common.h
index 0459708..9900e4e 100644
--- a/lpg/libqr/code-common.h
+++ b/lpg/libqr/code-common.h
@@ -12,5 +12,7 @@ struct qr_code {
 
 size_t code_total_capacity(int version);
 
+extern const int QR_ALIGNMENT_LOCATION[40][7];
+
 #endif
 
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 36ebb24..ae23acc 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -79,6 +79,8 @@ static int draw_functional(struct qr_code * code,
         struct qr_bitmap * bmp;
         int dim = qr_code_width(code);
         int i;
+        int x, y;
+        int am_side;
 
         bmp = qr_bitmap_create(dim, dim, 0);
         if (!bmp)
@@ -95,7 +97,26 @@ static int draw_functional(struct qr_code * code,
                 setpx(bmp, 6, i);
         }
 
-        /* XXX: alignment pattern */
+        /* Alignment pattern */
+        am_side = code->version > 1 ? (code->version / 7) + 2 : 0;
+        for (y = 0; y < am_side; ++y) {
+                const int * am_pos = QR_ALIGNMENT_LOCATION[code->version - 1];
+
+                for (x = 0; x < am_side; ++x) {
+                        if ((x == 0 && y == 0) ||
+                            (x == 0 && y == am_side - 1) ||
+                            (x == am_side - 1 && y == 0))
+                                continue;
+
+                        for (i = -2; i < 2; ++i) {
+                                setpx(bmp, am_pos[x] + i, am_pos[y] - 2);
+                                setpx(bmp, am_pos[x] + 2, am_pos[y] + i);
+                                setpx(bmp, am_pos[x] - i, am_pos[y] + 2);
+                                setpx(bmp, am_pos[x] - 2, am_pos[y] - i);
+                        }
+                        setpx(bmp, am_pos[x], am_pos[y]);
+                }
+        }
 
         /* Format info */
         setpx(bmp, 8, dim - 8);
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 54947d1..2a90124 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -21,6 +21,8 @@ void qr_layout_init_mask(struct qr_code * code)
         int x, y;
         int dim = qr_code_width(code);
         struct qr_bitmap * bmp = code->modules;
+        const int * am_pos = QR_ALIGNMENT_LOCATION[code->version - 1];
+        int am_side;
 
         assert(bmp->mask);
 
@@ -53,11 +55,32 @@ void qr_layout_init_mask(struct qr_code * code)
                                         continue;
                         }
 
-                        /* XXX: alignment pattern */
-
                         row[off] |= bit;
                 }
         }
+
+        /* Alignment pattern */
+        am_side = code->version > 1 ? (code->version / 7) + 2 : 0;
+        for (y = 0; y < am_side; ++y) {
+                for (x = 0; x < am_side; ++x) {
+                        int i, j;
+
+                        if ((x == 0 && y == 0) ||
+                            (x == 0 && y == am_side - 1) ||
+                            (x == am_side - 1 && y == 0))
+                                continue;
+
+                        for (j = -2; j <= 2; ++j) {
+                                unsigned char * row = bmp->mask + (am_pos[y]+j) * bmp->stride;
+                                for (i = -2; i <= 2; ++i) {
+                                        unsigned char bit = 1 << ((am_pos[x]+i) % CHAR_BIT);
+                                        int off = (am_pos[x]+i) / CHAR_BIT;
+
+                                        row[off] &= ~bit;
+                                }
+                        }
+                }
+        }
 }
 
 static int is_data_bit(const struct qr_iterator * i)
-- 
cgit v1.2.3-70-g09d2


From cca340e1b1017f1f565c5c53920e450d75164d51 Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Tue, 3 Nov 2009 15:29:45 +0900
Subject: Fix the output block order

---
 lpg/libqr/code-create.c | 24 ++++++++++++++++++------
 lpg/libqr/rs-encode.c   |  1 -
 2 files changed, 18 insertions(+), 7 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index ae23acc..1a38967 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -179,7 +179,7 @@ static struct qr_bitstream * make_data(int version,
         const size_t total_words = total_bits / 8;
         const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
         size_t total_blocks, block_count[2], data_words, rs_words;
-        size_t i;
+        size_t i, w;
         struct qr_bitstream * dcopy = 0;
         struct qr_bitstream * out = 0;
         struct qr_bitstream ** blocks = 0;
@@ -235,12 +235,24 @@ static struct qr_bitstream * make_data(int version,
         }
 
         /* Finally, write everything out in the correct order */
-        qr_bitstream_seek(dcopy, 0);
-        for (i = 0; i < total_blocks; ++i) {
-                size_t dw = data_words + (i >= block_count[0]);
-                qr_bitstream_copy(out, dcopy, dw * 8);
-                qr_bitstream_cat(out, blocks[i]);
+        for (w = 0; w < data_words + 1; ++w) {
+                for (i = (w == data_words ? block_count[0] : 0); i < total_blocks; ++i) {
+                        size_t di = w + (i < block_count[0] ?
+                                i * data_words :
+                                i * (data_words + 1) - block_count[0]);
+
+                        qr_bitstream_seek(dcopy, di * 8);
+                        qr_bitstream_write(out,
+                                qr_bitstream_read(dcopy, 8), 8);
+                }
         }
+        for (i = 0; i < total_blocks; ++i)
+                qr_bitstream_seek(blocks[i], 0);
+        for (w = 0; w < rs_words; ++w)
+                for (i = 0; i < total_blocks; ++i)
+                        qr_bitstream_write(out,
+                                qr_bitstream_read(blocks[i], 8), 8);
+
         qr_bitstream_write(out, 0, total_bits - total_words * 8);
 
         fputs("Final bitstream:\n", stderr);
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
index 42b404f..a8ecc73 100644
--- a/lpg/libqr/rs-encode.c
+++ b/lpg/libqr/rs-encode.c
@@ -74,7 +74,6 @@ struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
                 goto fail;
 
         /* First, prepare the registers (b) with data bits */
-        qr_bitstream_seek(data, 0);
         for (i = 0; i < data_words; ++i) {
                 unsigned int x = b[n-1] ^ qr_bitstream_read(data, 8);
                 for (r = n-1; r > 0; --r)
-- 
cgit v1.2.3-70-g09d2


From 682c2c553b7083645dd5147cdf3ff8650f08a0fd Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sat, 14 Nov 2009 18:13:58 +0900
Subject: Store ec level in qr_data struct

---
 lpg/libqr/code-create.c |  7 +++----
 lpg/libqr/data-common.h |  1 +
 lpg/libqr/data-create.c |  3 ++-
 lpg/libqr/qr/code.h     | 10 +---------
 lpg/libqr/qr/data.h     |  8 ++++++++
 lpg/libqr/qrgen.c       |  4 ++--
 6 files changed, 17 insertions(+), 16 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 1a38967..f8ef7b9 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -274,8 +274,7 @@ fail:
         goto exit;
 }
 
-struct qr_code * qr_code_create(enum qr_ec_level       ec,
-                                const struct qr_data * data)
+struct qr_code * qr_code_create(const struct qr_data * data)
 {
         struct qr_code * code;
         struct qr_bitstream * bits = 0;
@@ -294,7 +293,7 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         if (!code->modules)
                 goto fail;
 
-        bits = make_data(data->version, ec, data->bits);
+        bits = make_data(data->version, data->ec, data->bits);
         if (!bits)
                 goto fail;
 
@@ -313,7 +312,7 @@ struct qr_code * qr_code_create(enum qr_ec_level       ec,
         if (mask < 0)
                 goto fail;
 
-        if (draw_functional(code, ec, mask) != 0)
+        if (draw_functional(code, data->ec, mask) != 0)
                 goto fail;
 
 exit:
diff --git a/lpg/libqr/data-common.h b/lpg/libqr/data-common.h
index bc2b381..420b3b2 100644
--- a/lpg/libqr/data-common.h
+++ b/lpg/libqr/data-common.h
@@ -7,6 +7,7 @@
 
 struct qr_data {
         int                version; /* 1 ~ 40 */
+        enum qr_ec_level      ec;
         struct qr_bitstream * bits;
         size_t             offset;
 };
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index 2c2737f..27c6d4b 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -3,7 +3,6 @@
  */
 
 /** XXX: check that the data will fit! **/
-/** NOTE: should store ec type in qr_data **/
 
 #include <ctype.h>
 #include <stdlib.h>
@@ -174,6 +173,7 @@ static struct qr_data * encode_kanji(struct qr_data * data,
 }
 
 struct qr_data * qr_create_data(int               version,
+                                enum qr_ec_level  ec,
                                 enum qr_data_type type,
                                 const char *      input,
                                 size_t            length)
@@ -188,6 +188,7 @@ struct qr_data * qr_create_data(int               version,
                 return 0;
 
         data->version = version;
+        data->ec      = ec;
         data->bits   = qr_bitstream_create();
         data->offset = 0;
 
diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h
index dba0040..3c14c1f 100644
--- a/lpg/libqr/qr/code.h
+++ b/lpg/libqr/qr/code.h
@@ -4,15 +4,7 @@
 #include <stddef.h>
 #include "types.h"
 
-enum qr_ec_level {
-        QR_EC_LEVEL_L = 0x1,
-        QR_EC_LEVEL_M = 0x0,
-        QR_EC_LEVEL_Q = 0x3,
-        QR_EC_LEVEL_H = 0x2
-};
-
-struct qr_code * qr_code_create(enum qr_ec_level       ec,
-                                const struct qr_data * data);
+struct qr_code * qr_code_create(const struct qr_data * data);
 
 void qr_code_destroy(struct qr_code *);
 
diff --git a/lpg/libqr/qr/data.h b/lpg/libqr/qr/data.h
index 5fbdded..39494f4 100644
--- a/lpg/libqr/qr/data.h
+++ b/lpg/libqr/qr/data.h
@@ -15,7 +15,15 @@ enum qr_data_type {
         QR_DATA_FNC1    =  9
 };
 
+enum qr_ec_level {
+        QR_EC_LEVEL_L = 0x1,
+        QR_EC_LEVEL_M = 0x0,
+        QR_EC_LEVEL_Q = 0x3,
+        QR_EC_LEVEL_H = 0x2
+};
+
 struct qr_data * qr_create_data(int               format, /* 1 ~ 40 */
+                                enum qr_ec_level  ec,
                                 enum qr_data_type type,
                                 const char *      input,
                                 size_t            length);
diff --git a/lpg/libqr/qrgen.c b/lpg/libqr/qrgen.c
index aee6166..d1aae68 100644
--- a/lpg/libqr/qrgen.c
+++ b/lpg/libqr/qrgen.c
@@ -31,7 +31,7 @@ struct qr_code * create(int               version,
 
         len = strlen(input);
 
-        data = qr_create_data(version, dtype, input, len);
+        data = qr_create_data(version, ec, dtype, input, len);
 
         if (!data) {
                 /* BUG: this could also indicate OOM or
@@ -41,7 +41,7 @@ struct qr_code * create(int               version,
                 exit(1);
         }
 
-        code = qr_code_create(ec, data);
+        code = qr_code_create(data);
 
         if (!code) {
                 perror("Failed to create code");
-- 
cgit v1.2.3-70-g09d2


From c2e4639d2ebefbeb7f8b7e1826ae2391c6876a5a Mon Sep 17 00:00:00 2001
From: Leo Howell <leo@lwh.jp>
Date: Sat, 14 Nov 2009 20:24:57 +0900
Subject: Merge some files

---
 lpg/libqr/Makefile           |  10 +-
 lpg/libqr/TODO               |   1 -
 lpg/libqr/bitmap.c           | 202 +++++++++++++++++++++++++++++++++++
 lpg/libqr/bitstream.c        | 243 +++++++++++++++++++++++++++++++++++++++++++
 lpg/libqr/capacity.c         |  88 ----------------
 lpg/libqr/code-common.c      |  89 ++++++++--------
 lpg/libqr/code-common.h      |  18 ----
 lpg/libqr/code-create.c      |  56 ++--------
 lpg/libqr/code-layout.c      |   6 +-
 lpg/libqr/code-layout.h      |  14 ---
 lpg/libqr/code-parse.c       |   2 -
 lpg/libqr/constants.c        | 151 +++++++++++++++++++++++++++
 lpg/libqr/constants.h        |  12 +++
 lpg/libqr/data-common.c      |  26 +----
 lpg/libqr/data-common.h      |  22 ----
 lpg/libqr/data-create.c      |  20 ++--
 lpg/libqr/data-parse.c       |  16 +--
 lpg/libqr/galois.c           | 126 ++++++++++++++++++++++
 lpg/libqr/galois.h           |  12 +++
 lpg/libqr/qr-bitmap-render.c | 118 ---------------------
 lpg/libqr/qr-bitmap.c        |  89 ----------------
 lpg/libqr/qr-bitstream.c     | 243 -------------------------------------------
 lpg/libqr/qr-bitstream.h     |  48 ---------
 lpg/libqr/qr-mask.c          |  46 --------
 lpg/libqr/qr-mask.h          |  10 --
 lpg/libqr/qr/bitstream.h     |  48 +++++++++
 lpg/libqr/qr/code.h          |  10 ++
 lpg/libqr/qr/data.h          |  13 ++-
 lpg/libqr/qr/layout.h        |  14 +++
 lpg/libqr/qrgen.c            |  11 +-
 lpg/libqr/rs-encode.c        |  96 -----------------
 lpg/libqr/rs.h               |  11 --
 32 files changed, 916 insertions(+), 955 deletions(-)
 create mode 100644 lpg/libqr/bitmap.c
 create mode 100644 lpg/libqr/bitstream.c
 delete mode 100644 lpg/libqr/capacity.c
 delete mode 100644 lpg/libqr/code-common.h
 delete mode 100644 lpg/libqr/code-layout.h
 create mode 100644 lpg/libqr/constants.c
 create mode 100644 lpg/libqr/constants.h
 delete mode 100644 lpg/libqr/data-common.h
 create mode 100644 lpg/libqr/galois.c
 create mode 100644 lpg/libqr/galois.h
 delete mode 100644 lpg/libqr/qr-bitmap-render.c
 delete mode 100644 lpg/libqr/qr-bitmap.c
 delete mode 100644 lpg/libqr/qr-bitstream.c
 delete mode 100644 lpg/libqr/qr-bitstream.h
 delete mode 100644 lpg/libqr/qr-mask.c
 delete mode 100644 lpg/libqr/qr-mask.h
 create mode 100644 lpg/libqr/qr/bitstream.h
 create mode 100644 lpg/libqr/qr/layout.h
 delete mode 100644 lpg/libqr/rs-encode.c
 delete mode 100644 lpg/libqr/rs.h

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index 3a6af6f..a82372f 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -1,4 +1,6 @@
-OBJECTS :=      capacity.o              \
+OBJECTS :=      bitmap.o                \
+                bitstream.o             \
+                constants.o             \
                 code-common.o           \
                 code-create.o           \
                 code-layout.o           \
@@ -6,11 +8,7 @@ OBJECTS :=      capacity.o              \
                 data-common.o           \
                 data-create.o           \
                 data-parse.o            \
-                qr-bitmap.o             \
-                qr-bitmap-render.o      \
-                qr-bitstream.o          \
-                qr-mask.o               \
-                rs-encode.o
+                galois.o
 
 CFLAGS := -std=c89 -pedantic -I. -Wall
 CFLAGS += -g
diff --git a/lpg/libqr/TODO b/lpg/libqr/TODO
index 219ca83..3cd0583 100644
--- a/lpg/libqr/TODO
+++ b/lpg/libqr/TODO
@@ -1,4 +1,3 @@
-* Merge some files
 * Fix XXX, TODO
 * Tidy code
 * RELEASE v0.1
diff --git a/lpg/libqr/bitmap.c b/lpg/libqr/bitmap.c
new file mode 100644
index 0000000..3394784
--- /dev/null
+++ b/lpg/libqr/bitmap.c
@@ -0,0 +1,202 @@
+#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->mask, 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);
+        }
+}
+
+struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap * src)
+{
+        struct qr_bitmap * bmp;
+        size_t size;
+
+        bmp = qr_bitmap_create(src->width, src->height, !!src->mask);
+        if (!bmp)
+                return 0;
+
+        assert(bmp->stride == src->stride);
+
+        size = bmp->width * bmp->stride;
+        memcpy(bmp->bits, src->bits, size);
+        if (bmp->mask)
+                memcpy(bmp->mask, src->mask, size);
+
+        return 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++;
+        }
+}
+
+/* CHAR_BIT | mod_bits  (multi-byte) */
+static void render_line_1(unsigned char *       out,
+                          const unsigned char * in,
+                          size_t                mod_bits,
+                          size_t                dim,
+                          unsigned long         mark,
+                          unsigned long         space)
+{
+        unsigned char in_mask;
+        size_t n, b;
+
+        in_mask = 1;
+        n = dim;
+
+        while (n-- > 0) {
+                unsigned long v = (*in & in_mask) ? mark : space;
+
+                if ((in_mask <<= 1) == 0) {
+                        in_mask = 1;
+                        ++in;
+                }
+
+                b = mod_bits / CHAR_BIT;
+                while (b-- > 0) {
+                        *out++ = (unsigned char) v;
+                        v >>= CHAR_BIT;
+                }
+        }
+}
+
+/* mod_bits | CHAR_BIT  (packed) */
+static void render_line_2(unsigned char *       out,
+                          const unsigned char * in,
+                          size_t                mod_bits,
+                          size_t                dim,
+                          unsigned long         mark,
+                          unsigned long         space)
+{
+        unsigned char in_mask;
+        size_t n, b, step, shift;
+
+        in_mask = 1;
+        step = CHAR_BIT / mod_bits;
+        shift = CHAR_BIT - mod_bits;
+        n = dim;
+
+        while (n > 0) {
+                unsigned char tmp = 0;
+
+                b = step;
+                while (b-- > 0) {
+                        unsigned long v = (*in & in_mask) ? mark : space;
+
+                        if ((in_mask <<= 1) == 0) {
+                                in_mask = 1;
+                                ++in;
+                        }
+
+                        tmp = (tmp >> mod_bits) | (v << shift);
+                        if (--n == 0) {
+                                tmp >>= b * mod_bits;
+                                break;
+                        }
+                };
+
+                *out++ = tmp;
+        }
+}
+
+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;
+        size_t n, dim;
+        int pack;
+
+        pack = (mod_bits < CHAR_BIT);
+        assert(!pack || (CHAR_BIT % mod_bits == 0));
+        assert( pack || (mod_bits % CHAR_BIT == 0));
+
+        in = bmp->bits;
+        out = buffer;
+        dim = bmp->width;
+
+        n = dim;
+        while (n-- > 0) {
+                size_t rpt;
+                unsigned char * next;
+
+                if (pack)
+                        render_line_2(out, in, mod_bits, dim, mark, space);
+                else
+                        render_line_1(out, in, mod_bits, dim, mark, space);
+
+                rpt = line_repeat;
+                next = out + line_stride;
+                while (rpt-- > 0) {
+                        memcpy(next, out, line_stride);
+                        next += line_stride;
+                }
+
+                in += bmp->stride;
+                out = next;
+        }
+}
+
diff --git a/lpg/libqr/bitstream.c b/lpg/libqr/bitstream.c
new file mode 100644
index 0000000..cf5a9d4
--- /dev/null
+++ b/lpg/libqr/bitstream.c
@@ -0,0 +1,243 @@
+/**
+ * It would perhaps be more sensible just to store the bits
+ * as an array of char or similar, but this way is more fun.
+ * This is a pretty inefficient implementation, althought I
+ * suspect that won't be a problem.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+
+#include <qr/bitstream.h>
+
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+struct qr_bitstream {
+        size_t pos;    /* bits */
+        size_t count;  /* bits */
+        size_t bufsiz; /* bytes */
+        unsigned char * buffer;
+};
+
+static size_t bits_to_bytes(size_t bits)
+{
+        return (bits / CHAR_BIT) + (bits % CHAR_BIT != 0);
+}
+
+static int ensure_available(struct qr_bitstream * stream, size_t bits)
+{
+        size_t need_bits = stream->pos + bits;
+        size_t newsize;
+
+        if (stream->bufsiz * CHAR_BIT >= need_bits)
+                return 0;
+
+        newsize = MAX(stream->bufsiz, 100) * CHAR_BIT;
+        while (newsize < need_bits)
+                newsize *= 2;
+
+        return qr_bitstream_resize(stream, newsize);
+}
+
+struct qr_bitstream * qr_bitstream_create(void)
+{
+        struct qr_bitstream * obj;
+
+        obj = malloc(sizeof(*obj));
+
+        if (obj) {
+                obj->pos    = 0;
+                obj->count  = 0;
+                obj->bufsiz = 0;
+                obj->buffer = 0;
+        }
+
+        return obj;
+}
+
+int qr_bitstream_resize(struct qr_bitstream * stream, size_t bits)
+{
+        size_t newsize;
+        void * newbuf;
+
+        newsize = bits_to_bytes(bits);
+        newbuf = realloc(stream->buffer, newsize);
+
+        if (newbuf) {
+                stream->bufsiz = newsize;
+                stream->buffer = newbuf;
+        }
+
+        return newbuf ? 0 : -1;
+}
+
+void qr_bitstream_destroy(struct qr_bitstream * stream)
+{
+        free(stream->buffer);
+        free(stream);
+}
+
+struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream * src)
+{
+        struct qr_bitstream * ret;
+
+        ret = qr_bitstream_create();
+        if (!ret)
+                return 0;
+
+        if (qr_bitstream_resize(ret, src->count) != 0) {
+                free(ret);
+                return 0;
+        }
+
+        ret->pos   = src->pos;
+        ret->count = src->count;
+        memcpy(ret->buffer, src->buffer, src->bufsiz);
+
+        return ret;
+}
+
+void qr_bitstream_seek(struct qr_bitstream * stream, size_t pos)
+{
+        assert(pos <= stream->count);
+        stream->pos = pos;
+}
+
+size_t qr_bitstream_tell(const struct qr_bitstream * stream)
+{
+        return stream->pos;
+}
+
+size_t qr_bitstream_remaining(const struct qr_bitstream * stream)
+{
+        return stream->count - stream->pos;
+}
+
+size_t qr_bitstream_size(const struct qr_bitstream * stream)
+{
+        return stream->count;
+}
+
+unsigned int qr_bitstream_read(struct qr_bitstream * stream, size_t bits)
+{
+        unsigned int result = 0;
+        unsigned char * byte;
+        size_t bitnum;
+
+        assert(qr_bitstream_remaining(stream) >= bits);
+
+        byte = stream->buffer + (stream->pos / CHAR_BIT);
+        bitnum = stream->pos % CHAR_BIT;
+
+        stream->pos += bits;
+
+        while (bits-- > 0) {
+                int bit = (*byte >> bitnum++) & 0x1;
+                result = (result << 1) | bit;
+                if (bitnum == CHAR_BIT) {
+                        bitnum = 0;
+                        ++byte;
+                }                
+        }
+
+        return result;
+}
+
+void qr_bitstream_unpack(struct qr_bitstream * stream,
+                      unsigned int *     result,
+                      size_t             count,
+                      size_t             bitsize)
+{
+        assert(qr_bitstream_remaining(stream) >= (count * bitsize));
+
+        while (count--)
+                *(result++) = qr_bitstream_read(stream, bitsize);
+}
+
+int qr_bitstream_write(struct qr_bitstream * stream,
+                    unsigned int       value,
+                    size_t             bits)
+{
+        unsigned char * byte;
+        size_t bitnum;
+
+        if (ensure_available(stream, bits) != 0)
+                return -1;
+
+        byte = stream->buffer + (stream->pos / CHAR_BIT);
+        bitnum = stream->pos % CHAR_BIT;
+
+        stream->pos += bits;
+        stream->count = stream->pos; /* truncate */
+
+        while (bits-- > 0) {
+                int bit = (value >> bits) & 0x1;
+                unsigned char mask = 1 << bitnum++;
+                *byte = (*byte & ~mask) | (bit ? mask : 0);
+                if (bitnum == CHAR_BIT) {
+                        bitnum = 0;
+                        ++byte;
+                }
+        }
+
+        return 0;
+}
+
+int qr_bitstream_pack(struct qr_bitstream *   stream,
+                   const unsigned int * values,
+                   size_t               count,
+                   size_t               bitsize)
+{
+        if (ensure_available(stream, count * bitsize) != 0)
+                return -1;
+
+        while (count--)
+                qr_bitstream_write(stream, *(values++), bitsize);
+
+        return 0;
+}
+
+int qr_bitstream_cat(struct qr_bitstream * dest, const struct qr_bitstream * src)
+{
+        size_t count = qr_bitstream_size(src);
+        size_t srcpos;
+
+        if (ensure_available(dest, count) != 0)
+                return -1;
+
+        srcpos = qr_bitstream_tell(src);
+        qr_bitstream_seek((struct qr_bitstream *)src, 0);
+        qr_bitstream_copy(dest, (struct qr_bitstream *)src, count);
+        qr_bitstream_seek((struct qr_bitstream *)src, srcpos);
+
+        return 0;
+}
+
+int qr_bitstream_copy(struct qr_bitstream * dest,
+                      struct qr_bitstream * src,
+                      size_t count)
+{
+        if (qr_bitstream_remaining(src) < count)
+                return -1;
+        if (ensure_available(dest, count) != 0)
+                return -1;
+
+        /* uint must be at least 16 bits */
+        for (; count >= 16; count -= 16)
+                qr_bitstream_write(
+                        dest,
+                        qr_bitstream_read((struct qr_bitstream *)src, 16),
+                        16);
+
+        if (count > 0)
+                qr_bitstream_write(
+                        dest,
+                        qr_bitstream_read((struct qr_bitstream *)src, count),
+                        count);
+
+        return 0;
+}
+
diff --git a/lpg/libqr/capacity.c b/lpg/libqr/capacity.c
deleted file mode 100644
index 4b513af..0000000
--- a/lpg/libqr/capacity.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* FIXME: don't like big tables of data */
-
-const int QR_DATA_WORD_COUNT[40][4] = {
-          19,   16,   13,    9,
-          34,   28,   22,   16,
-          55,   44,   34,   26,
-          80,   64,   48,   36,
-         108,   86,   62,   46,
-         136,  108,   76,   60,
-         156,  124,   88,   66,
-         194,  154,  110,   86,
-         232,  182,  132,  100,
-         274,  216,  154,  122,
-         324,  254,  180,  140,
-         370,  290,  206,  158,
-         428,  334,  244,  180,
-         461,  365,  261,  197,
-         523,  415,  295,  223,
-         589,  453,  325,  253,
-         647,  507,  367,  283,
-         721,  563,  397,  313,
-         795,  627,  445,  341,
-         861,  669,  485,  385,
-         932,  714,  512,  406,
-        1006,  782,  568,  442,
-        1094,  860,  614,  464,
-        1174,  914,  664,  514,
-        1276, 1000,  718,  538,
-        1370, 1062,  754,  596,
-        1468, 1128,  808,  628,
-        1531, 1193,  871,  661,
-        1631, 1267,  911,  701,
-        1735, 1373,  985,  745,
-        1845, 1455, 1033,  793,
-        1955, 1541, 1115,  845,
-        2071, 1631, 1171,  901,
-        2191, 1725, 1231,  961,
-        2306, 1812, 1286,  986,
-        2434, 1914, 1351, 1054,
-        2566, 1992, 1426, 1096,
-        2812, 2216, 1582, 1222,
-        2956, 2334, 1666, 1276
-};
-
-/* I'm sure we can calculate these values */
-const int QR_RS_BLOCK_COUNT[40][4][2] = {
-         1,  0,  1,  0,  1,  0,  1,  0, /*  1 */
-         1,  0,  1,  0,  1,  0,  1,  0, /*  2 */
-         1,  0,  1,  0,  2,  0,  2,  0, /*  3 */
-         1,  0,  2,  0,  2,  0,  4,  0, /*  4 */
-         1,  0,  2,  0,  2,  0,  2,  0,
-         2,  0,  4,  0,  4,  0,  4,  0,
-         2,  0,  4,  0,  2,  4,  4,  1,
-         2,  0,  2,  2,  4,  2,  4,  2, /*  8 */
-         2,  0,  3,  2,  4,  4,  4,  4,
-         2,  2,  4,  1,  6,  2,  6,  2,
-         4,  0,  1,  4,  4,  4,  3,  8,
-         2,  2,  6,  2,  4,  6,  7,  4,
-         4,  0,  8,  1,  8,  4, 12,  4,
-         3,  1,  4,  5, 11,  5, 11,  5, /* 14 */
-         5,  1,  5,  5,  5,  7, 11,  7,
-         5,  1,  7,  3, 15,  2,  3, 13,
-         1,  5, 10,  1,  1, 15,  2, 17,
-         5,  1,  9,  4, 17,  1,  2, 19,
-         3,  4,  3, 11, 17,  4,  9, 16, /* 19 */
-         3,  5,  3, 13, 15,  5, 15, 10,
-         4,  4, 17,  0, 17,  6, 19,  6,
-         2,  7, 17,  0,  7, 16, 34,  0,
-         4,  5,  4, 14, 11, 14, 16, 14,
-         6,  4,  6, 14, 11, 16, 30,  2,
-         8,  4,  8, 13,  7, 22, 22, 13, /* 25 */
-        10,  2, 19,  4, 28,  6, 33,  4,
-         8,  4, 22,  3,  8, 26, 12, 28,
-         3, 10,  3, 23,  4, 31, 11, 31,
-         7,  7, 21,  7,  1, 37, 19, 26,
-         5, 10, 19, 10, 15, 25, 23, 25, /* 30 */
-        13,  3,  2, 29, 42,  1, 23, 28,
-        17,  0, 10, 23, 10, 35, 19, 35,
-        17,  1, 14, 21, 29, 19, 11, 46,
-        13,  6, 14, 23, 44,  7, 59,  1,
-        12,  7, 12, 26, 39, 14, 22, 41, /* 35 */
-         6, 14,  6, 34, 46, 10,  2, 64,
-        17,  4, 29, 14, 49, 10, 24, 46,
-         4, 18, 13, 32, 48, 14, 42, 32,
-        20,  4, 40,  7, 43, 22, 10, 67,
-        19,  6, 18, 31, 34, 34, 20, 61 /* 40 */
-};
-
diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index 7c3c119..bc6621a 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -1,7 +1,10 @@
+#include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
+
 #include <qr/code.h>
 #include <qr/bitmap.h>
-#include "code-common.h"
+#include <qr/bitstream.h>
 
 void qr_code_destroy(struct qr_code * code)
 {
@@ -16,7 +19,7 @@ int qr_code_width(const struct qr_code * code)
         return code->version * 4 + 17;
 }
 
-size_t code_total_capacity(int version)
+size_t qr_code_total_capacity(int version)
 {
 	int side = version * 4 + 17;
 
@@ -38,46 +41,44 @@ size_t code_total_capacity(int version)
 	return side * side - function_bits;
 }
 
-const int QR_ALIGNMENT_LOCATION[40][7] = {
-        {  0,  0,  0,  0,  0,  0,  0 }, /*  1 */
-        {  6, 18,  0,  0,  0,  0,  0 }, /*  2 */
-        {  6, 22,  0,  0,  0,  0,  0 }, /*  3 */
-        {  6, 26,  0,  0,  0,  0,  0 }, /*  4 */
-        {  6, 30,  0,  0,  0,  0,  0 }, /*  5 */
-        {  6, 34,  0,  0,  0,  0,  0 }, /*  6 */
-        {  6, 22, 38,  0,  0,  0,  0 }, /*  7 */
-        {  6, 24, 42,  0,  0,  0,  0 }, /*  8 */
-        {  6, 26, 46,  0,  0,  0,  0 }, /*  9 */
-        {  6, 28, 50,  0,  0,  0,  0 }, /* 10 */
-        {  6, 30, 54,  0,  0,  0,  0 }, /* 11 */
-        {  6, 32, 58,  0,  0,  0,  0 }, /* 12 */
-        {  6, 34, 62,  0,  0,  0,  0 }, /* 13 */
-        {  6, 26, 46, 66,  0,  0,  0 }, /* 14 */
-        {  6, 26, 48, 70,  0,  0,  0 }, /* 15 */
-        {  6, 26, 50, 74,  0,  0,  0 }, /* 16 */
-        {  6, 30, 54, 78,  0,  0,  0 }, /* 17 */
-        {  6, 30, 56, 82,  0,  0,  0 }, /* 18 */
-        {  6, 30, 58, 86,  0,  0,  0 }, /* 19 */
-        {  6, 34, 62, 90,  0,  0,  0 }, /* 20 */
-        {  6, 28, 50, 72, 94,  0,  0 }, /* 21 */
-        {  6, 26, 50, 74, 98,  0,  0 }, /* 22 */
-        {  6, 30, 54, 78,102,  0,  0 }, /* 23 */
-        {  6, 28, 54, 80,106,  0,  0 }, /* 24 */
-        {  6, 32, 58, 84,110,  0,  0 }, /* 25 */
-        {  6, 30, 58, 86,114,  0,  0 }, /* 26 */
-        {  6, 34, 62, 90,118,  0,  0 }, /* 27 */
-        {  6, 26, 50, 74, 98,122,  0 }, /* 28 */
-        {  6, 30, 54, 78,102,126,  0 }, /* 29 */
-        {  6, 26, 52, 78,104,130,  0 }, /* 30 */
-        {  6, 30, 56, 82,108,134,  0 }, /* 31 */
-        {  6, 34, 60, 86,112,138,  0 }, /* 32 */
-        {  6, 30, 58, 86,114,142,  0 }, /* 33 */
-        {  6, 34, 62, 90,118,146,  0 }, /* 34 */
-        {  6, 30, 54, 78,102,126,150 }, /* 35 */
-        {  6, 24, 50, 76,102,128,154 }, /* 36 */
-        {  6, 28, 54, 80,106,132,158 }, /* 37 */
-        {  6, 32, 58, 84,110,136,162 }, /* 38 */
-        {  6, 26, 54, 82,110,138,166 }, /* 39 */
-        {  6, 30, 58, 86,114,142,170 }, /* 40 */
-};
+struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
+                                 unsigned int mask)
+{
+        struct qr_bitmap * bmp;
+        int i, j;
+
+        if (mask & ~0x7)
+                return 0;
+
+        bmp = qr_bitmap_clone(orig);
+        if (!bmp)
+                return 0;
+
+        /* Slow version for now; we can optimize later */
+
+        for (i = 0; i < bmp->height; ++i) {
+                unsigned char * p = bmp->bits + i * bmp->stride;
+
+                for (j = 0; j < bmp->width; ++j) {
+                        int bit = j % CHAR_BIT;
+                        size_t off = j / CHAR_BIT;
+                        int t;
+
+                        switch (mask) {
+                        case 0: t = (i + j) % 2; break;
+                        case 1: t = i % 2; break;
+                        case 2: t = j % 3; break;
+                        case 3: t = (i + j) % 3; break;
+                        case 4: t = (i/2 + j/3) % 2; break;
+                        case 5: t = ((i*j) % 2) + ((i*j) % 3); break;
+                        case 6: t = (((i*j) % 2) + ((i*j) % 3)) % 2; break;
+                        case 7: t = (((i*j) % 3) + ((i+j) % 2)) % 2; break;
+                        }
+
+                        p[off] ^= (t == 0) << bit;
+                }
+        }
+
+        return bmp;
+}
 
diff --git a/lpg/libqr/code-common.h b/lpg/libqr/code-common.h
deleted file mode 100644
index 9900e4e..0000000
--- a/lpg/libqr/code-common.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef CODE_COMMON_H
-#define CODE_COMMON_H
-
-#include <qr/code.h>
-#include <qr/bitmap.h>
-#include "qr-bitstream.h"
-
-struct qr_code {
-        int                version;
-        struct qr_bitmap * modules;
-};
-
-size_t code_total_capacity(int version);
-
-extern const int QR_ALIGNMENT_LOCATION[40][7];
-
-#endif
-
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index f8ef7b9..0882b88 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -1,19 +1,17 @@
 #include <stdlib.h>
 #include <limits.h>
 #include <assert.h>
-#include <qr/code.h>
 
-#include "code-common.h"
-#include "code-layout.h"
-#include "data-common.h"
-#include "qr-mask.h"
-#include "rs.h"
+#include <qr/bitmap.h>
+#include <qr/bitstream.h>
+#include <qr/code.h>
+#include <qr/data.h>
+#include <qr/layout.h>
+#include "constants.h"
+#include "galois.h"
 
 #define MIN(a, b) ((b) < (a) ? (b) : (a))
 
-extern const int QR_DATA_WORD_COUNT[40][4];
-extern const int QR_RS_BLOCK_COUNT[40][4][2];
-
 static int mask_data(struct qr_code * code);
 static int score_mask(const struct qr_bitmap * bmp);
 static int score_runs(const struct qr_bitmap * bmp, int base);
@@ -28,11 +26,6 @@ static int draw_format(struct qr_bitmap * bmp,
                         int mask);
 static int calc_format_bits(enum qr_ec_level ec, int mask);
 static long calc_version_bits(int version);
-static unsigned long gal_residue(unsigned long a, unsigned long m);
-
-/* FIXME: the static functions should be in a better
- * order, with prototypes.
- */
 
 #include <stdio.h>
 static void x_dump(struct qr_bitstream * bits)
@@ -175,7 +168,7 @@ static struct qr_bitstream * make_data(int version,
                                        enum qr_ec_level   ec,
                                        struct qr_bitstream * data)
 {
-        const size_t total_bits = code_total_capacity(version);
+        const size_t total_bits = qr_code_total_capacity(version);
         const size_t total_words = total_bits / 8;
         const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
         size_t total_blocks, block_count[2], data_words, rs_words;
@@ -575,7 +568,7 @@ static int calc_format_bits(enum qr_ec_level ec, int mask)
          */
 
         bits <<= 15 - 5;
-        bits |= (unsigned int)gal_residue(bits, 0x537);
+        bits |= (unsigned int)gf_residue(bits, 0x537);
 
         /* XOR mask: 101 0100 0001 0010 */
         bits ^= 0x5412;
@@ -593,37 +586,8 @@ static long calc_version_bits(int version)
          *   G(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
          */
         bits <<= 18 - 6;
-        bits |= gal_residue(bits, 0x1F25);
+        bits |= gf_residue(bits, 0x1F25);
 
         return bits;
 }
 
-/* Calculate the residue of a modulo m */
-static unsigned long gal_residue(unsigned long a,
-                                   unsigned long m)
-{
-        unsigned long o = 1;
-        int n = 1;
-
-        /* Find one past the highest bit of the modulus */
-        while (m & ~(o - 1))
-                o <<= 1;
-
-        /* Find the highest n such that O(m * x^n) <= O(a) */
-        while (a & ~(o - 1)) {
-                o <<= 1;
-                ++n;
-        }
-
-        /* For each n, try to reduce a by (m * x^n) */
-        while (n--) {
-                o >>= 1;
-
-                /* o is the highest bit of (m * x^n) */
-                if (a & o)
-                        a ^= m << n;
-        }
-
-        return a;
-}
-
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 2a90124..68a1a0e 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -2,9 +2,11 @@
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+
 #include <qr/bitmap.h>
-#include "code-common.h"
-#include "code-layout.h"
+#include <qr/code.h>
+#include <qr/layout.h>
+#include "constants.h"
 
 struct qr_iterator {
         struct qr_code * code;
diff --git a/lpg/libqr/code-layout.h b/lpg/libqr/code-layout.h
deleted file mode 100644
index 3390548..0000000
--- a/lpg/libqr/code-layout.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef CODE_LAYOUT_H
-#define CODE_LAYOUT_H
-
-struct qr_iterator;
-
-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 *);
-
-#endif
-
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 0d3a71d..a794cdc 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -1,7 +1,5 @@
 #include <qr/code.h>
 
-#include "code-common.h"
-
 struct qr_code * qr_code_parse(const void * buffer,
                                size_t       line_bits,
                                size_t       line_stride,
diff --git a/lpg/libqr/constants.c b/lpg/libqr/constants.c
new file mode 100644
index 0000000..86f08ff
--- /dev/null
+++ b/lpg/libqr/constants.c
@@ -0,0 +1,151 @@
+#include "constants.h"
+
+/* FIXME: don't like big tables of data */
+
+const int QR_ALIGNMENT_LOCATION[40][7] = {
+        {  0,  0,  0,  0,  0,  0,  0 }, /*  1 */
+        {  6, 18,  0,  0,  0,  0,  0 }, /*  2 */
+        {  6, 22,  0,  0,  0,  0,  0 }, /*  3 */
+        {  6, 26,  0,  0,  0,  0,  0 }, /*  4 */
+        {  6, 30,  0,  0,  0,  0,  0 }, /*  5 */
+        {  6, 34,  0,  0,  0,  0,  0 }, /*  6 */
+        {  6, 22, 38,  0,  0,  0,  0 }, /*  7 */
+        {  6, 24, 42,  0,  0,  0,  0 }, /*  8 */
+        {  6, 26, 46,  0,  0,  0,  0 }, /*  9 */
+        {  6, 28, 50,  0,  0,  0,  0 }, /* 10 */
+        {  6, 30, 54,  0,  0,  0,  0 }, /* 11 */
+        {  6, 32, 58,  0,  0,  0,  0 }, /* 12 */
+        {  6, 34, 62,  0,  0,  0,  0 }, /* 13 */
+        {  6, 26, 46, 66,  0,  0,  0 }, /* 14 */
+        {  6, 26, 48, 70,  0,  0,  0 }, /* 15 */
+        {  6, 26, 50, 74,  0,  0,  0 }, /* 16 */
+        {  6, 30, 54, 78,  0,  0,  0 }, /* 17 */
+        {  6, 30, 56, 82,  0,  0,  0 }, /* 18 */
+        {  6, 30, 58, 86,  0,  0,  0 }, /* 19 */
+        {  6, 34, 62, 90,  0,  0,  0 }, /* 20 */
+        {  6, 28, 50, 72, 94,  0,  0 }, /* 21 */
+        {  6, 26, 50, 74, 98,  0,  0 }, /* 22 */
+        {  6, 30, 54, 78,102,  0,  0 }, /* 23 */
+        {  6, 28, 54, 80,106,  0,  0 }, /* 24 */
+        {  6, 32, 58, 84,110,  0,  0 }, /* 25 */
+        {  6, 30, 58, 86,114,  0,  0 }, /* 26 */
+        {  6, 34, 62, 90,118,  0,  0 }, /* 27 */
+        {  6, 26, 50, 74, 98,122,  0 }, /* 28 */
+        {  6, 30, 54, 78,102,126,  0 }, /* 29 */
+        {  6, 26, 52, 78,104,130,  0 }, /* 30 */
+        {  6, 30, 56, 82,108,134,  0 }, /* 31 */
+        {  6, 34, 60, 86,112,138,  0 }, /* 32 */
+        {  6, 30, 58, 86,114,142,  0 }, /* 33 */
+        {  6, 34, 62, 90,118,146,  0 }, /* 34 */
+        {  6, 30, 54, 78,102,126,150 }, /* 35 */
+        {  6, 24, 50, 76,102,128,154 }, /* 36 */
+        {  6, 28, 54, 80,106,132,158 }, /* 37 */
+        {  6, 32, 58, 84,110,136,162 }, /* 38 */
+        {  6, 26, 54, 82,110,138,166 }, /* 39 */
+        {  6, 30, 58, 86,114,142,170 }, /* 40 */
+};
+
+const int QR_DATA_WORD_COUNT[40][4] = {
+        {   19,   16,   13,    9 },
+        {   34,   28,   22,   16 },
+        {   55,   44,   34,   26 },
+        {   80,   64,   48,   36 },
+        {  108,   86,   62,   46 },
+        {  136,  108,   76,   60 },
+        {  156,  124,   88,   66 },
+        {  194,  154,  110,   86 },
+        {  232,  182,  132,  100 },
+        {  274,  216,  154,  122 },
+        {  324,  254,  180,  140 },
+        {  370,  290,  206,  158 },
+        {  428,  334,  244,  180 },
+        {  461,  365,  261,  197 },
+        {  523,  415,  295,  223 },
+        {  589,  453,  325,  253 },
+        {  647,  507,  367,  283 },
+        {  721,  563,  397,  313 },
+        {  795,  627,  445,  341 },
+        {  861,  669,  485,  385 },
+        {  932,  714,  512,  406 },
+        { 1006,  782,  568,  442 },
+        { 1094,  860,  614,  464 },
+        { 1174,  914,  664,  514 },
+        { 1276, 1000,  718,  538 },
+        { 1370, 1062,  754,  596 },
+        { 1468, 1128,  808,  628 },
+        { 1531, 1193,  871,  661 },
+        { 1631, 1267,  911,  701 },
+        { 1735, 1373,  985,  745 },
+        { 1845, 1455, 1033,  793 },
+        { 1955, 1541, 1115,  845 },
+        { 2071, 1631, 1171,  901 },
+        { 2191, 1725, 1231,  961 },
+        { 2306, 1812, 1286,  986 },
+        { 2434, 1914, 1351, 1054 },
+        { 2566, 1992, 1426, 1096 },
+        { 2812, 2216, 1582, 1222 },
+        { 2956, 2334, 1666, 1276 }
+};
+
+const int QR_RS_BLOCK_COUNT[40][4][2] = {
+        {  1,  0,  1,  0,  1,  0,  1,  0 }, /*  1 */
+        {  1,  0,  1,  0,  1,  0,  1,  0 }, /*  2 */
+        {  1,  0,  1,  0,  2,  0,  2,  0 }, /*  3 */
+        {  1,  0,  2,  0,  2,  0,  4,  0 }, /*  4 */
+        {  1,  0,  2,  0,  2,  0,  2,  0 }, /*  5 */
+        {  2,  0,  4,  0,  4,  0,  4,  0 }, /*  6 */
+        {  2,  0,  4,  0,  2,  4,  4,  1 }, /*  7 */
+        {  2,  0,  2,  2,  4,  2,  4,  2 }, /*  8 */
+        {  2,  0,  3,  2,  4,  4,  4,  4 }, /*  9 */
+        {  2,  2,  4,  1,  6,  2,  6,  2 }, /* 10 */
+        {  4,  0,  1,  4,  4,  4,  3,  8 }, /* 11 */
+        {  2,  2,  6,  2,  4,  6,  7,  4 }, /* 12 */
+        {  4,  0,  8,  1,  8,  4, 12,  4 }, /* 13 */
+        {  3,  1,  4,  5, 11,  5, 11,  5 }, /* 14 */
+        {  5,  1,  5,  5,  5,  7, 11,  7 }, /* 15 */
+        {  5,  1,  7,  3, 15,  2,  3, 13 }, /* 16 */
+        {  1,  5, 10,  1,  1, 15,  2, 17 }, /* 17 */
+        {  5,  1,  9,  4, 17,  1,  2, 19 }, /* 18 */
+        {  3,  4,  3, 11, 17,  4,  9, 16 }, /* 19 */
+        {  3,  5,  3, 13, 15,  5, 15, 10 }, /* 20 */
+        {  4,  4, 17,  0, 17,  6, 19,  6 }, /* 21 */
+        {  2,  7, 17,  0,  7, 16, 34,  0 }, /* 22 */
+        {  4,  5,  4, 14, 11, 14, 16, 14 }, /* 23 */
+        {  6,  4,  6, 14, 11, 16, 30,  2 }, /* 24 */
+        {  8,  4,  8, 13,  7, 22, 22, 13 }, /* 25 */
+        { 10,  2, 19,  4, 28,  6, 33,  4 }, /* 26 */
+        {  8,  4, 22,  3,  8, 26, 12, 28 }, /* 27 */
+        {  3, 10,  3, 23,  4, 31, 11, 31 }, /* 28 */
+        {  7,  7, 21,  7,  1, 37, 19, 26 }, /* 29 */
+        {  5, 10, 19, 10, 15, 25, 23, 25 }, /* 30 */
+        { 13,  3,  2, 29, 42,  1, 23, 28 }, /* 31 */
+        { 17,  0, 10, 23, 10, 35, 19, 35 }, /* 32 */
+        { 17,  1, 14, 21, 29, 19, 11, 46 }, /* 33 */
+        { 13,  6, 14, 23, 44,  7, 59,  1 }, /* 34 */
+        { 12,  7, 12, 26, 39, 14, 22, 41 }, /* 35 */
+        {  6, 14,  6, 34, 46, 10,  2, 64 }, /* 36 */
+        { 17,  4, 29, 14, 49, 10, 24, 46 }, /* 37 */
+        {  4, 18, 13, 32, 48, 14, 42, 32 }, /* 38 */
+        { 20,  4, 40,  7, 43, 22, 10, 67 }, /* 39 */
+        { 19,  6, 18, 31, 34, 34, 20, 61 }  /* 40 */
+};
+
+const enum qr_data_type QR_TYPE_CODES[16] = {
+        QR_DATA_INVALID,        /* 0000 */
+        QR_DATA_NUMERIC,        /* 0001 */
+        QR_DATA_ALPHA,          /* 0010 */
+        QR_DATA_MIXED,          /* 0011 */
+        QR_DATA_8BIT,           /* 0100 */
+        QR_DATA_FNC1,           /* 0101 */
+        QR_DATA_INVALID,        /* 0110 */
+        QR_DATA_ECI,            /* 0111 */
+        QR_DATA_KANJI,          /* 1000 */
+        QR_DATA_FNC1,           /* 1001 */
+        QR_DATA_INVALID,        /* 1010 */
+        QR_DATA_INVALID,        /* 1011 */
+        QR_DATA_INVALID,        /* 1100 */
+        QR_DATA_INVALID,        /* 1101 */
+        QR_DATA_INVALID,        /* 1110 */
+        QR_DATA_INVALID,        /* 1111 */
+};
+
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
new file mode 100644
index 0000000..15aa515
--- /dev/null
+++ b/lpg/libqr/constants.h
@@ -0,0 +1,12 @@
+#ifndef QR_CONSTANTS_H
+#define QR_CONSTANTS_H
+
+#include <qr/data.h>
+
+extern const int QR_ALIGNMENT_LOCATION[40][7];
+extern const int QR_DATA_WORD_COUNT[40][4];
+extern const int QR_RS_BLOCK_COUNT[40][4][2];
+extern const enum qr_data_type QR_TYPE_CODES[16];
+
+#endif
+
diff --git a/lpg/libqr/data-common.c b/lpg/libqr/data-common.c
index ac2f198..8a05f4a 100644
--- a/lpg/libqr/data-common.c
+++ b/lpg/libqr/data-common.c
@@ -1,27 +1,7 @@
 #include <stdlib.h>
-#include <qr/data.h>
-
-#include "qr-bitstream.h"
-#include "data-common.h"
 
-const enum qr_data_type QR_TYPE_CODES[16] = {
-        QR_DATA_INVALID,        /* 0000 */
-        QR_DATA_NUMERIC,        /* 0001 */
-        QR_DATA_ALPHA,          /* 0010 */
-        QR_DATA_MIXED,          /* 0011 */
-        QR_DATA_8BIT,           /* 0100 */
-        QR_DATA_FNC1,           /* 0101 */
-        QR_DATA_INVALID,        /* 0110 */
-        QR_DATA_ECI,            /* 0111 */
-        QR_DATA_KANJI,          /* 1000 */
-        QR_DATA_FNC1,           /* 1001 */
-        QR_DATA_INVALID,        /* 1010 */
-        QR_DATA_INVALID,        /* 1011 */
-        QR_DATA_INVALID,        /* 1100 */
-        QR_DATA_INVALID,        /* 1101 */
-        QR_DATA_INVALID,        /* 1110 */
-        QR_DATA_INVALID,        /* 1111 */
-};
+#include <qr/bitstream.h>
+#include <qr/data.h>
 
 void qr_free_data(struct qr_data * data)
 {
@@ -29,7 +9,7 @@ void qr_free_data(struct qr_data * data)
         free(data);
 }
 
-size_t get_size_field_length(int version, enum qr_data_type type)
+size_t qr_data_size_field_length(int version, enum qr_data_type type)
 {
         static const size_t QR_SIZE_LENGTHS[3][4] = {
                 { 10,  9,  8,  8 },
diff --git a/lpg/libqr/data-common.h b/lpg/libqr/data-common.h
deleted file mode 100644
index 054d349..0000000
--- a/lpg/libqr/data-common.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef DATA_COMMON_H
-#define DATA_COMMON_H
-
-#include <qr/data.h>
-
-#include "qr-bitstream.h"
-
-struct qr_data {
-        int                version; /* 1 ~ 40 */
-        enum qr_ec_level      ec;
-        struct qr_bitstream * bits;
-        size_t             offset;
-};
-
-extern const enum qr_data_type QR_TYPE_CODES[16];
-
-size_t get_size_field_length(int version, enum qr_data_type);
-
-size_t qr_data_dpart_length(enum qr_data_type type, size_t nchars);
-
-#endif
-
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index 37556c6..9d6c384 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -2,16 +2,12 @@
  * Not "pure" C - only works with ASCII
  */
 
-/** XXX: check that the data will fit! **/
-
 #include <ctype.h>
 #include <stdlib.h>
-#include <qr/data.h>
 
-#include "qr-bitstream.h"
-#include "data-common.h"
-
-extern const int QR_DATA_WORD_COUNT[40][4];
+#include <qr/bitstream.h>
+#include <qr/data.h>
+#include "constants.h"
 
 static void write_type_and_length(struct qr_data *  data,
                                   enum qr_data_type type,
@@ -19,7 +15,7 @@ static void write_type_and_length(struct qr_data *  data,
 {
         (void)qr_bitstream_write(data->bits, QR_TYPE_CODES[type], 4);
         (void)qr_bitstream_write(data->bits, length,
-                get_size_field_length(data->version, type));
+                qr_data_size_field_length(data->version, type));
 }
 
 static struct qr_data * encode_numeric(struct qr_data * data,
@@ -29,7 +25,7 @@ static struct qr_data * encode_numeric(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->version, QR_DATA_NUMERIC)
+        bits = 4 + qr_data_size_field_length(data->version, QR_DATA_NUMERIC)
                  + qr_data_dpart_length(QR_DATA_NUMERIC, length);
 
         stream = data->bits;
@@ -102,7 +98,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->version, QR_DATA_ALPHA)
+        bits = 4 + qr_data_size_field_length(data->version, QR_DATA_ALPHA)
                  + qr_data_dpart_length(QR_DATA_ALPHA, length);
 
         stream = data->bits;
@@ -145,7 +141,7 @@ static struct qr_data * encode_8bit(struct qr_data * data,
         struct qr_bitstream * stream = data->bits;
         size_t bits;
 
-        bits = 4 + get_size_field_length(data->version, QR_DATA_8BIT)
+        bits = 4 + qr_data_size_field_length(data->version, QR_DATA_8BIT)
                  + qr_data_dpart_length(QR_DATA_8BIT, length);
 
         stream = data->bits;
@@ -178,7 +174,7 @@ static int calc_min_version(enum qr_data_type type,
         dbits = qr_data_dpart_length(type, length);
 
         for (version = 1; version <= 40; ++version) {
-                if (4 + dbits + get_size_field_length(version, type)
+                if (4 + dbits + qr_data_size_field_length(version, type)
                     < 8 * QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1])
                         return version;
         }
diff --git a/lpg/libqr/data-parse.c b/lpg/libqr/data-parse.c
index 4868cd2..801aa66 100644
--- a/lpg/libqr/data-parse.c
+++ b/lpg/libqr/data-parse.c
@@ -1,10 +1,10 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <qr/data.h>
 
-#include "qr-bitstream.h"
-#include "data-common.h"
+#include <qr/bitstream.h>
+#include <qr/data.h>
+#include "constants.h"
 
 static enum qr_data_type read_data_type(struct qr_bitstream * stream)
 {
@@ -33,7 +33,7 @@ static enum qr_data_type parse_numeric(const struct qr_data * data,
         stream = data->bits;
         buffer = 0;
 
-        field_len = get_size_field_length(data->version, QR_DATA_NUMERIC);
+        field_len = qr_data_size_field_length(data->version, QR_DATA_NUMERIC);
         if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
@@ -93,7 +93,7 @@ static enum qr_data_type parse_alpha(const struct qr_data * data,
         stream = data->bits;
         buffer = 0;
 
-        field_len = get_size_field_length(data->version, QR_DATA_ALPHA);
+        field_len = qr_data_size_field_length(data->version, QR_DATA_ALPHA);
         if (qr_bitstream_remaining(stream) < field_len)
                 goto invalid;
 
@@ -150,7 +150,7 @@ static enum qr_data_type parse_8bit(const struct qr_data * data,
 
         stream = data->bits;
 
-        field_len = get_size_field_length(data->version, QR_DATA_8BIT);
+        field_len = qr_data_size_field_length(data->version, QR_DATA_8BIT);
         if (qr_bitstream_remaining(stream) < field_len)
                 return QR_DATA_INVALID;
 
@@ -181,7 +181,7 @@ static enum qr_data_type parse_kanji(const struct qr_data * data,
         return QR_DATA_INVALID;
 }
 
-enum qr_data_type qr_get_data_type(const struct qr_data * data)
+enum qr_data_type qr_data_type(const struct qr_data * data)
 {
         qr_bitstream_seek(data->bits, data->offset);
         return read_data_type(data->bits);
@@ -201,7 +201,7 @@ int qr_get_data_length(const struct qr_data * data)
         case QR_DATA_ALPHA:
         case QR_DATA_8BIT:
         case QR_DATA_KANJI:
-                field_len = get_size_field_length(data->version, type);
+                field_len = qr_data_size_field_length(data->version, type);
                 break;
         default:
                 /* unsupported / invalid */
diff --git a/lpg/libqr/galois.c b/lpg/libqr/galois.c
new file mode 100644
index 0000000..e21ce22
--- /dev/null
+++ b/lpg/libqr/galois.c
@@ -0,0 +1,126 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <qr/bitstream.h>
+#include "galois.h"
+
+/* Calculate the residue of a modulo m */
+unsigned long gf_residue(unsigned long a,
+                         unsigned long m)
+{
+        unsigned long o = 1;
+        int n = 1;
+
+        /* Find one past the highest bit of the modulus */
+        while (m & ~(o - 1))
+                o <<= 1;
+
+        /* Find the highest n such that O(m * x^n) <= O(a) */
+        while (a & ~(o - 1)) {
+                o <<= 1;
+                ++n;
+        }
+
+        /* For each n, try to reduce a by (m * x^n) */
+        while (n--) {
+                o >>= 1;
+
+                /* o is the highest bit of (m * x^n) */
+                if (a & o)
+                        a ^= m << n;
+        }
+
+        return a;
+}
+
+static unsigned int gf_mult(unsigned int a, unsigned int b)
+{
+        /* Reduce modulo x^8 + x^4 + x^3 + x^2 + 1
+         * using the peasant's algorithm
+         */
+        const unsigned int m = 0x11D;
+        unsigned int x = 0;
+        int i;
+
+        for (i = 0; i < 8; ++i) {
+                x ^= (b & 0x1) ? a : 0;
+                a = (a << 1) ^ ((a & 0x80) ? m : 0);
+                b >>= 1;
+        }
+
+        return x & 0xFF;
+}
+
+static unsigned int * make_generator(int k)
+{
+        unsigned int * g;
+        unsigned int a;
+        int i, j;
+
+        g = calloc(k, sizeof(*g));
+        if (!g)
+                return 0;
+
+        g[0] = 1; /* Start with g(x) = 1 */
+        a = 1;    /* 2^0 = 1 */
+
+        for (i = 0; i < k; ++i) {
+                /* Multiply our poly g(x) by (x + 2^i) */
+                for (j = k - 1; j > 0; --j)
+                        g[j] = gf_mult(g[j], a) ^ g[j-1];
+                g[0] = gf_mult(g[0], a);
+
+                a = gf_mult(a, 2);
+        }
+
+        return g;
+}
+
+struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
+                                     size_t data_words,
+                                     size_t rs_words)
+{
+        struct qr_bitstream * ec = 0;
+        unsigned int * b = 0;
+        unsigned int * g;
+        size_t n = rs_words;
+        int i, r;
+
+        assert(qr_bitstream_remaining(data) >= data_words * 8);
+
+        ec = qr_bitstream_create();
+        if (!ec)
+                return 0;
+
+        if (qr_bitstream_resize(ec, n * 8) != 0)
+                goto fail;
+
+        b = calloc(n, sizeof(*b));
+        if (!b)
+                goto fail;
+
+        g = make_generator(n);
+        if (!g)
+                goto fail;
+
+        /* First, prepare the registers (b) with data bits */
+        for (i = 0; i < data_words; ++i) {
+                unsigned int x = b[n-1] ^ qr_bitstream_read(data, 8);
+                for (r = n-1; r > 0; --r)
+                        b[r] = b[r-1] ^ gf_mult(g[r], x);
+                b[0] = gf_mult(g[0], x);
+        }
+
+        /* Read off the registers */
+        for (r = 0; r < n; ++r)
+                qr_bitstream_write(ec, b[(n-1)-r], 8);
+
+        free(g);
+        free(b);
+        return ec;
+fail:
+        free(b);
+        qr_bitstream_destroy(ec);
+        return 0;
+}
+
diff --git a/lpg/libqr/galois.h b/lpg/libqr/galois.h
new file mode 100644
index 0000000..1adeb88
--- /dev/null
+++ b/lpg/libqr/galois.h
@@ -0,0 +1,12 @@
+#ifndef QR_GALOIS_H
+#define QR_GALOIS_H
+
+unsigned long gf_residue(unsigned long a,
+                         unsigned long m);
+
+struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
+                                     size_t data_words,
+                                     size_t rs_words);
+
+#endif
+
diff --git a/lpg/libqr/qr-bitmap-render.c b/lpg/libqr/qr-bitmap-render.c
deleted file mode 100644
index 197e947..0000000
--- a/lpg/libqr/qr-bitmap-render.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include <string.h>
-#include <limits.h>
-#include <assert.h>
-
-#include <qr/bitmap.h>
-
-/* CHAR_BIT | mod_bits  (multi-byte) */
-static void render_line_1(unsigned char *       out,
-                          const unsigned char * in,
-                          size_t                mod_bits,
-                          size_t                dim,
-                          unsigned long         mark,
-                          unsigned long         space)
-{
-        unsigned char in_mask;
-        size_t n, b;
-
-        in_mask = 1;
-        n = dim;
-
-        while (n-- > 0) {
-                unsigned long v = (*in & in_mask) ? mark : space;
-
-                if ((in_mask <<= 1) == 0) {
-                        in_mask = 1;
-                        ++in;
-                }
-
-                b = mod_bits / CHAR_BIT;
-                while (b-- > 0) {
-                        *out++ = (unsigned char) v;
-                        v >>= CHAR_BIT;
-                }
-        }
-}
-
-/* mod_bits | CHAR_BIT  (packed) */
-static void render_line_2(unsigned char *       out,
-                          const unsigned char * in,
-                          size_t                mod_bits,
-                          size_t                dim,
-                          unsigned long         mark,
-                          unsigned long         space)
-{
-        unsigned char in_mask;
-        size_t n, b, step, shift;
-
-        in_mask = 1;
-        step = CHAR_BIT / mod_bits;
-        shift = CHAR_BIT - mod_bits;
-        n = dim;
-
-        while (n > 0) {
-                unsigned char tmp = 0;
-
-                b = step;
-                while (b-- > 0) {
-                        unsigned long v = (*in & in_mask) ? mark : space;
-
-                        if ((in_mask <<= 1) == 0) {
-                                in_mask = 1;
-                                ++in;
-                        }
-
-                        tmp = (tmp >> mod_bits) | (v << shift);
-                        if (--n == 0) {
-                                tmp >>= b * mod_bits;
-                                break;
-                        }
-                };
-
-                *out++ = tmp;
-        }
-}
-
-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;
-        size_t n, dim;
-        int pack;
-
-        pack = (mod_bits < CHAR_BIT);
-        assert(!pack || (CHAR_BIT % mod_bits == 0));
-        assert( pack || (mod_bits % CHAR_BIT == 0));
-
-        in = bmp->bits;
-        out = buffer;
-        dim = bmp->width;
-
-        n = dim;
-        while (n-- > 0) {
-                size_t rpt;
-                unsigned char * next;
-
-                if (pack)
-                        render_line_2(out, in, mod_bits, dim, mark, space);
-                else
-                        render_line_1(out, in, mod_bits, dim, mark, space);
-
-                rpt = line_repeat;
-                next = out + line_stride;
-                while (rpt-- > 0) {
-                        memcpy(next, out, line_stride);
-                        next += line_stride;
-                }
-
-                in += bmp->stride;
-                out = next;
-        }
-}
-
diff --git a/lpg/libqr/qr-bitmap.c b/lpg/libqr/qr-bitmap.c
deleted file mode 100644
index 7d2d900..0000000
--- a/lpg/libqr/qr-bitmap.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#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->mask, 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);
-        }
-}
-
-struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap * src)
-{
-        struct qr_bitmap * bmp;
-        size_t size;
-
-        bmp = qr_bitmap_create(src->width, src->height, !!src->mask);
-        if (!bmp)
-                return 0;
-
-        assert(bmp->stride == src->stride);
-
-        size = bmp->width * bmp->stride;
-        memcpy(bmp->bits, src->bits, size);
-        if (bmp->mask)
-                memcpy(bmp->mask, src->mask, size);
-
-        return 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-bitstream.c b/lpg/libqr/qr-bitstream.c
deleted file mode 100644
index c752cde..0000000
--- a/lpg/libqr/qr-bitstream.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * It would perhaps be more sensible just to store the bits
- * as an array of char or similar, but this way is more fun.
- * This is a pretty inefficient implementation, althought I
- * suspect that won't be a problem.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <assert.h>
-
-#include "qr-bitstream.h"
-
-#define MAX(a, b) ((a) < (b) ? (b) : (a))
-#define MIN(a, b) ((a) > (b) ? (b) : (a))
-
-struct qr_bitstream {
-        size_t pos;    /* bits */
-        size_t count;  /* bits */
-        size_t bufsiz; /* bytes */
-        unsigned char * buffer;
-};
-
-static size_t bits_to_bytes(size_t bits)
-{
-        return (bits / CHAR_BIT) + (bits % CHAR_BIT != 0);
-}
-
-static int ensure_available(struct qr_bitstream * stream, size_t bits)
-{
-        size_t need_bits = stream->pos + bits;
-        size_t newsize;
-
-        if (stream->bufsiz * CHAR_BIT >= need_bits)
-                return 0;
-
-        newsize = MAX(stream->bufsiz, 100) * CHAR_BIT;
-        while (newsize < need_bits)
-                newsize *= 2;
-
-        return qr_bitstream_resize(stream, newsize);
-}
-
-struct qr_bitstream * qr_bitstream_create(void)
-{
-        struct qr_bitstream * obj;
-
-        obj = malloc(sizeof(*obj));
-
-        if (obj) {
-                obj->pos    = 0;
-                obj->count  = 0;
-                obj->bufsiz = 0;
-                obj->buffer = 0;
-        }
-
-        return obj;
-}
-
-int qr_bitstream_resize(struct qr_bitstream * stream, size_t bits)
-{
-        size_t newsize;
-        void * newbuf;
-
-        newsize = bits_to_bytes(bits);
-        newbuf = realloc(stream->buffer, newsize);
-
-        if (newbuf) {
-                stream->bufsiz = newsize;
-                stream->buffer = newbuf;
-        }
-
-        return newbuf ? 0 : -1;
-}
-
-void qr_bitstream_destroy(struct qr_bitstream * stream)
-{
-        free(stream->buffer);
-        free(stream);
-}
-
-struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream * src)
-{
-        struct qr_bitstream * ret;
-
-        ret = qr_bitstream_create();
-        if (!ret)
-                return 0;
-
-        if (qr_bitstream_resize(ret, src->count) != 0) {
-                free(ret);
-                return 0;
-        }
-
-        ret->pos   = src->pos;
-        ret->count = src->count;
-        memcpy(ret->buffer, src->buffer, src->bufsiz);
-
-        return ret;
-}
-
-void qr_bitstream_seek(struct qr_bitstream * stream, size_t pos)
-{
-        assert(pos <= stream->count);
-        stream->pos = pos;
-}
-
-size_t qr_bitstream_tell(const struct qr_bitstream * stream)
-{
-        return stream->pos;
-}
-
-size_t qr_bitstream_remaining(const struct qr_bitstream * stream)
-{
-        return stream->count - stream->pos;
-}
-
-size_t qr_bitstream_size(const struct qr_bitstream * stream)
-{
-        return stream->count;
-}
-
-unsigned int qr_bitstream_read(struct qr_bitstream * stream, size_t bits)
-{
-        unsigned int result = 0;
-        unsigned char * byte;
-        size_t bitnum;
-
-        assert(qr_bitstream_remaining(stream) >= bits);
-
-        byte = stream->buffer + (stream->pos / CHAR_BIT);
-        bitnum = stream->pos % CHAR_BIT;
-
-        stream->pos += bits;
-
-        while (bits-- > 0) {
-                int bit = (*byte >> bitnum++) & 0x1;
-                result = (result << 1) | bit;
-                if (bitnum == CHAR_BIT) {
-                        bitnum = 0;
-                        ++byte;
-                }                
-        }
-
-        return result;
-}
-
-void qr_bitstream_unpack(struct qr_bitstream * stream,
-                      unsigned int *     result,
-                      size_t             count,
-                      size_t             bitsize)
-{
-        assert(qr_bitstream_remaining(stream) >= (count * bitsize));
-
-        while (count--)
-                *(result++) = qr_bitstream_read(stream, bitsize);
-}
-
-int qr_bitstream_write(struct qr_bitstream * stream,
-                    unsigned int       value,
-                    size_t             bits)
-{
-        unsigned char * byte;
-        size_t bitnum;
-
-        if (ensure_available(stream, bits) != 0)
-                return -1;
-
-        byte = stream->buffer + (stream->pos / CHAR_BIT);
-        bitnum = stream->pos % CHAR_BIT;
-
-        stream->pos += bits;
-        stream->count = stream->pos; /* truncate */
-
-        while (bits-- > 0) {
-                int bit = (value >> bits) & 0x1;
-                unsigned char mask = 1 << bitnum++;
-                *byte = (*byte & ~mask) | (bit ? mask : 0);
-                if (bitnum == CHAR_BIT) {
-                        bitnum = 0;
-                        ++byte;
-                }
-        }
-
-        return 0;
-}
-
-int qr_bitstream_pack(struct qr_bitstream *   stream,
-                   const unsigned int * values,
-                   size_t               count,
-                   size_t               bitsize)
-{
-        if (ensure_available(stream, count * bitsize) != 0)
-                return -1;
-
-        while (count--)
-                qr_bitstream_write(stream, *(values++), bitsize);
-
-        return 0;
-}
-
-int qr_bitstream_cat(struct qr_bitstream * dest, const struct qr_bitstream * src)
-{
-        size_t count = qr_bitstream_size(src);
-        size_t srcpos;
-
-        if (ensure_available(dest, count) != 0)
-                return -1;
-
-        srcpos = qr_bitstream_tell(src);
-        qr_bitstream_seek((struct qr_bitstream *)src, 0);
-        qr_bitstream_copy(dest, (struct qr_bitstream *)src, count);
-        qr_bitstream_seek((struct qr_bitstream *)src, srcpos);
-
-        return 0;
-}
-
-int qr_bitstream_copy(struct qr_bitstream * dest,
-                      struct qr_bitstream * src,
-                      size_t count)
-{
-        if (qr_bitstream_remaining(src) < count)
-                return -1;
-        if (ensure_available(dest, count) != 0)
-                return -1;
-
-        /* uint must be at least 16 bits */
-        for (; count >= 16; count -= 16)
-                qr_bitstream_write(
-                        dest,
-                        qr_bitstream_read((struct qr_bitstream *)src, 16),
-                        16);
-
-        if (count > 0)
-                qr_bitstream_write(
-                        dest,
-                        qr_bitstream_read((struct qr_bitstream *)src, count),
-                        count);
-
-        return 0;
-}
-
diff --git a/lpg/libqr/qr-bitstream.h b/lpg/libqr/qr-bitstream.h
deleted file mode 100644
index cf20694..0000000
--- a/lpg/libqr/qr-bitstream.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef QR_BITSTREAM_H
-#define QR_BITSTREAM_H
-
-#include <stddef.h>
-
-/**
- * Note: when writing / reading multiple bits, the
- * _most_ significant bits come first in the stream.
- * (That is, the order you would naturally write the
- * number in binary)
- */
-
-struct qr_bitstream;
-
-struct qr_bitstream * qr_bitstream_create(void);
-int                qr_bitstream_resize(struct qr_bitstream *, size_t bits);
-void               qr_bitstream_destroy(struct qr_bitstream *);
-struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream *);
-
-void qr_bitstream_seek(struct qr_bitstream *, size_t pos);
-size_t qr_bitstream_tell(const struct qr_bitstream *);
-size_t qr_bitstream_remaining(const struct qr_bitstream *);
-size_t qr_bitstream_size(const struct qr_bitstream *);
-
-unsigned int qr_bitstream_read(struct qr_bitstream *, size_t bits);
-
-void qr_bitstream_unpack(struct qr_bitstream *,
-                      unsigned int * result,
-                      size_t         count,
-                      size_t         bitsize);
-
-int qr_bitstream_write(struct qr_bitstream *,
-                    unsigned int value,
-                    size_t       bits);
-
-int qr_bitstream_pack(struct qr_bitstream *,
-                   const unsigned int * values,
-                   size_t               count,
-                   size_t               bitsize);
-
-int qr_bitstream_cat(struct qr_bitstream *, const struct qr_bitstream * src);
-
-int qr_bitstream_copy(struct qr_bitstream * dest,
-                      struct qr_bitstream * src,
-                      size_t count);
-
-#endif
-
diff --git a/lpg/libqr/qr-mask.c b/lpg/libqr/qr-mask.c
deleted file mode 100644
index 7ff78a4..0000000
--- a/lpg/libqr/qr-mask.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <limits.h>
-#include <stdlib.h>
-#include <qr/bitmap.h>
-#include "qr-mask.h"
-
-struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
-                                 unsigned int mask)
-{
-        struct qr_bitmap * bmp;
-        int i, j;
-
-        if (mask & ~0x7)
-                return 0;
-
-        bmp = qr_bitmap_clone(orig);
-        if (!bmp)
-                return 0;
-
-        /* Slow version for now; we can optimize later */
-
-        for (i = 0; i < bmp->height; ++i) {
-                unsigned char * p = bmp->bits + i * bmp->stride;
-
-                for (j = 0; j < bmp->width; ++j) {
-                        int bit = j % CHAR_BIT;
-                        size_t off = j / CHAR_BIT;
-                        int t;
-
-                        switch (mask) {
-                        case 0: t = (i + j) % 2; break;
-                        case 1: t = i % 2; break;
-                        case 2: t = j % 3; break;
-                        case 3: t = (i + j) % 3; break;
-                        case 4: t = (i/2 + j/3) % 2; break;
-                        case 5: t = ((i*j) % 2) + ((i*j) % 3); break;
-                        case 6: t = (((i*j) % 2) + ((i*j) % 3)) % 2; break;
-                        case 7: t = (((i*j) % 3) + ((i+j) % 2)) % 2; break;
-                        }
-
-                        p[off] ^= (t == 0) << bit;
-                }
-        }
-
-        return bmp;
-}
-
diff --git a/lpg/libqr/qr-mask.h b/lpg/libqr/qr-mask.h
deleted file mode 100644
index eb254af..0000000
--- a/lpg/libqr/qr-mask.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef QR_MASK_H
-#define QR_MASK_H
-
-#include <qr/bitmap.h>
-
-struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
-                                 unsigned int mask);
-
-#endif
-
diff --git a/lpg/libqr/qr/bitstream.h b/lpg/libqr/qr/bitstream.h
new file mode 100644
index 0000000..cf20694
--- /dev/null
+++ b/lpg/libqr/qr/bitstream.h
@@ -0,0 +1,48 @@
+#ifndef QR_BITSTREAM_H
+#define QR_BITSTREAM_H
+
+#include <stddef.h>
+
+/**
+ * Note: when writing / reading multiple bits, the
+ * _most_ significant bits come first in the stream.
+ * (That is, the order you would naturally write the
+ * number in binary)
+ */
+
+struct qr_bitstream;
+
+struct qr_bitstream * qr_bitstream_create(void);
+int                qr_bitstream_resize(struct qr_bitstream *, size_t bits);
+void               qr_bitstream_destroy(struct qr_bitstream *);
+struct qr_bitstream * qr_bitstream_dup(const struct qr_bitstream *);
+
+void qr_bitstream_seek(struct qr_bitstream *, size_t pos);
+size_t qr_bitstream_tell(const struct qr_bitstream *);
+size_t qr_bitstream_remaining(const struct qr_bitstream *);
+size_t qr_bitstream_size(const struct qr_bitstream *);
+
+unsigned int qr_bitstream_read(struct qr_bitstream *, size_t bits);
+
+void qr_bitstream_unpack(struct qr_bitstream *,
+                      unsigned int * result,
+                      size_t         count,
+                      size_t         bitsize);
+
+int qr_bitstream_write(struct qr_bitstream *,
+                    unsigned int value,
+                    size_t       bits);
+
+int qr_bitstream_pack(struct qr_bitstream *,
+                   const unsigned int * values,
+                   size_t               count,
+                   size_t               bitsize);
+
+int qr_bitstream_cat(struct qr_bitstream *, const struct qr_bitstream * src);
+
+int qr_bitstream_copy(struct qr_bitstream * dest,
+                      struct qr_bitstream * src,
+                      size_t count);
+
+#endif
+
diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h
index 3c14c1f..ac3c363 100644
--- a/lpg/libqr/qr/code.h
+++ b/lpg/libqr/qr/code.h
@@ -4,16 +4,26 @@
 #include <stddef.h>
 #include "types.h"
 
+struct qr_code {
+        int                version;
+        struct qr_bitmap * modules;
+};
+
 struct qr_code * qr_code_create(const struct qr_data * data);
 
 void qr_code_destroy(struct qr_code *);
 
 int qr_code_width(const struct qr_code *);
 
+size_t qr_code_total_capacity(int version);
+
 struct qr_code * qr_code_parse(const void * buffer,
                                size_t       line_bits,
                                size_t       line_stride,
                                size_t       line_count);
 
+struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
+                                 unsigned int mask);
+
 #endif
 
diff --git a/lpg/libqr/qr/data.h b/lpg/libqr/qr/data.h
index 34b6968..a3bb309 100644
--- a/lpg/libqr/qr/data.h
+++ b/lpg/libqr/qr/data.h
@@ -22,6 +22,13 @@ enum qr_ec_level {
         QR_EC_LEVEL_H = 0x2
 };
 
+struct qr_data {
+        int                   version; /* 1 ~ 40 */
+        enum qr_ec_level      ec;
+        struct qr_bitstream * bits;
+        size_t                offset;
+};
+
 struct qr_data * qr_create_data(int               format, /* 1 ~ 40; 0=auto */
                                 enum qr_ec_level  ec,
                                 enum qr_data_type type,
@@ -30,9 +37,11 @@ struct qr_data * qr_create_data(int               format, /* 1 ~ 40; 0=auto */
 
 void qr_free_data(struct qr_data *);
 
-enum qr_data_type qr_get_data_type(const struct qr_data *);
+enum qr_data_type qr_data_type(const struct qr_data *);
 
-int qr_get_data_length(const struct qr_data *);
+size_t qr_data_length(const struct qr_data *);
+size_t qr_data_size_field_length(int version, enum qr_data_type);
+size_t qr_data_dpart_length(enum qr_data_type type, size_t nchars);
 
 enum qr_data_type qr_parse_data(const struct qr_data * input,
                                 char **                output,
diff --git a/lpg/libqr/qr/layout.h b/lpg/libqr/qr/layout.h
new file mode 100644
index 0000000..49bebf6
--- /dev/null
+++ b/lpg/libqr/qr/layout.h
@@ -0,0 +1,14 @@
+#ifndef QR_CODE_LAYOUT_H
+#define QR_CODE_LAYOUT_H
+
+struct qr_iterator;
+
+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 *);
+
+#endif
+
diff --git a/lpg/libqr/qrgen.c b/lpg/libqr/qrgen.c
index 1309596..ad53125 100644
--- a/lpg/libqr/qrgen.c
+++ b/lpg/libqr/qrgen.c
@@ -1,17 +1,16 @@
+#include <assert.h>
 #include <ctype.h>
+#include <getopt.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
-#include <limits.h>
-#include <getopt.h>
+
 #include <qr/bitmap.h>
+#include <qr/bitstream.h>
 #include <qr/code.h>
 #include <qr/data.h>
 
-#include "qr-bitstream.h"
-#include "code-common.h"
-
 struct config {
         int               version;
         enum qr_ec_level  ec;
diff --git a/lpg/libqr/rs-encode.c b/lpg/libqr/rs-encode.c
deleted file mode 100644
index a8ecc73..0000000
--- a/lpg/libqr/rs-encode.c
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include "qr-bitstream.h"
-#include "rs.h"
-
-static unsigned int gf_mult(unsigned int a, unsigned int b)
-{
-        /* Reduce modulo x^8 + x^4 + x^3 + x^2 + 1
-         * using the peasant's algorithm
-         */
-        const unsigned int m = 0x11D;
-        unsigned int x = 0;
-        int i;
-
-        for (i = 0; i < 8; ++i) {
-                x ^= (b & 0x1) ? a : 0;
-                a = (a << 1) ^ ((a & 0x80) ? m : 0);
-                b >>= 1;
-        }
-
-        return x & 0xFF;
-}
-
-static unsigned int * make_generator(int k)
-{
-        unsigned int * g;
-        unsigned int a;
-        int i, j;
-
-        g = calloc(k, sizeof(*g));
-        if (!g)
-                return 0;
-
-        g[0] = 1; /* Start with g(x) = 1 */
-        a = 1;    /* 2^0 = 1 */
-
-        for (i = 0; i < k; ++i) {
-                /* Multiply our poly g(x) by (x + 2^i) */
-                for (j = k - 1; j > 0; --j)
-                        g[j] = gf_mult(g[j], a) ^ g[j-1];
-                g[0] = gf_mult(g[0], a);
-
-                a = gf_mult(a, 2);
-        }
-
-        return g;
-}
-
-struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
-                                     size_t data_words,
-                                     size_t rs_words)
-{
-        struct qr_bitstream * ec = 0;
-        unsigned int * b = 0;
-        unsigned int * g;
-        size_t n = rs_words;
-        int i, r;
-
-        assert(qr_bitstream_remaining(data) >= data_words * 8);
-
-        ec = qr_bitstream_create();
-        if (!ec)
-                return 0;
-
-        if (qr_bitstream_resize(ec, n * 8) != 0)
-                goto fail;
-
-        b = calloc(n, sizeof(*b));
-        if (!b)
-                goto fail;
-
-        g = make_generator(n);
-        if (!g)
-                goto fail;
-
-        /* First, prepare the registers (b) with data bits */
-        for (i = 0; i < data_words; ++i) {
-                unsigned int x = b[n-1] ^ qr_bitstream_read(data, 8);
-                for (r = n-1; r > 0; --r)
-                        b[r] = b[r-1] ^ gf_mult(g[r], x);
-                b[0] = gf_mult(g[0], x);
-        }
-
-        /* Read off the registers */
-        for (r = 0; r < n; ++r)
-                qr_bitstream_write(ec, b[(n-1)-r], 8);
-
-        free(g);
-        free(b);
-        return ec;
-fail:
-        free(b);
-        qr_bitstream_destroy(ec);
-        return 0;
-}
-
diff --git a/lpg/libqr/rs.h b/lpg/libqr/rs.h
deleted file mode 100644
index c87d852..0000000
--- a/lpg/libqr/rs.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef RS_H
-#define RS_H
-
-#include "qr-bitstream.h"
-
-struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
-                                     size_t data_words,
-                                     size_t rs_words);
-
-#endif
-
-- 
cgit v1.2.3-70-g09d2


From 2280c632f390b6e6a682a38d9abee9f08e41db02 Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Wed, 13 Jul 2011 17:39:25 +0900
Subject: Fix incorrect layout of format info

---
 lpg/libqr/code-create.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 0882b88..b0db1c9 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -527,7 +527,7 @@ static int draw_format(struct qr_bitmap * bmp,
 
         for (i = 0; i < 8; ++i) {
                 if (bits & 0x1) {
-                        setpx(bmp, 8, i);
+                        setpx(bmp, 8, i + (i > 5));
                         setpx(bmp, dim - 1 - i, 8);
                 }
                 bits >>= 1;
-- 
cgit v1.2.3-70-g09d2


From 35baea42d794bec1fd5f2200f1f6f48877c5c26c Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Thu, 14 Jul 2011 11:06:47 +0900
Subject: First attempt at parsing

---
 lpg/libqr/Makefile      |   5 +-
 lpg/libqr/bitmap.c      |  10 ++
 lpg/libqr/code-create.c |   1 +
 lpg/libqr/code-layout.c |   6 +-
 lpg/libqr/code-parse.c  | 312 +++++++++++++++++++++++++++++++++++++++++++++++-
 lpg/libqr/constants.h   |   1 +
 lpg/libqr/data-parse.c  |   3 +
 lpg/libqr/qr/bitmap.h   |   2 +
 lpg/libqr/qr/code.h     |   5 -
 lpg/libqr/qr/parse.h    |  16 +++
 lpg/libqr/qrparse.c     |  59 +++++++++
 lpg/libqr/testqr.xbm    |  19 +++
 12 files changed, 427 insertions(+), 12 deletions(-)
 create mode 100644 lpg/libqr/qr/parse.h
 create mode 100644 lpg/libqr/qrparse.c
 create mode 100644 lpg/libqr/testqr.xbm

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index a82372f..fa6cf04 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -14,7 +14,7 @@ CFLAGS := -std=c89 -pedantic -I. -Wall
 CFLAGS += -g
 #CFLAGS += -O3 -DNDEBUG
 
-all : libqr qrgen
+all : libqr qrgen qrparse
 
 $(OBJECTS) : $(wildcard *.h qr/*.h)
 
@@ -23,6 +23,9 @@ libqr : libqr.a($(OBJECTS))
 qrgen : libqr qrgen.c
 	$(CC) $(CFLAGS) -o qrgen qrgen.c libqr.a
 
+qrparse : libqr qrparse.c
+	$(CC) $(CFLAGS) -o qrparse qrparse.c libqr.a
+
 .PHONY : clean
 clean:
 	$(RM) qr/*~ *~ *.o *.a *.so qrgen
diff --git a/lpg/libqr/bitmap.c b/lpg/libqr/bitmap.c
index 3394784..759aeca 100644
--- a/lpg/libqr/bitmap.c
+++ b/lpg/libqr/bitmap.c
@@ -49,6 +49,16 @@ void qr_bitmap_destroy(struct qr_bitmap * bmp)
         }
 }
 
+int qr_bitmap_add_mask(struct qr_bitmap * bmp)
+{
+        size_t size = bmp->stride * bmp->width;
+        bmp->mask = malloc(size);
+        if (!bmp->mask)
+                return -1;
+        memset(bmp->mask, 0xFF, size);
+        return 0;
+}
+
 struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap * src)
 {
         struct qr_bitmap * bmp;
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index b0db1c9..155ffa3 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -588,6 +588,7 @@ static long calc_version_bits(int version)
         bits <<= 18 - 6;
         bits |= gf_residue(bits, 0x1F25);
 
+fprintf(stderr, "version bits: %lx\n", bits);
         return bits;
 }
 
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 68a1a0e..04b6ca6 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -26,6 +26,9 @@ void qr_layout_init_mask(struct qr_code * code)
         const int * am_pos = QR_ALIGNMENT_LOCATION[code->version - 1];
         int am_side;
 
+        if (!bmp->mask)
+                qr_bitmap_add_mask(bmp);
+
         assert(bmp->mask);
 
         memset(bmp->mask, 0, bmp->height * bmp->stride);
@@ -164,9 +167,8 @@ unsigned int qr_layout_read(struct qr_iterator * i)
         int b;
 
         for (b = 0; b < 8; ++b) {
-                x |= (*i->p & i->mask) ? 1 : 0;
+                x = (x << 1) | ((*i->p & i->mask) ? 1 : 0);
                 advance(i);
-                x <<= 1;
         }
 
         return x;
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index a794cdc..50d621c 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -1,10 +1,314 @@
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <qr/bitmap.h>
+#include <qr/bitstream.h>
 #include <qr/code.h>
+#include <qr/data.h>
+#include <qr/layout.h>
+#include <qr/parse.h>
+
+#include "constants.h"
+#include "galois.h"
+
+/* XXX: duplicated */
+static int get_px(const struct qr_bitmap * bmp, int x, int y)
+{
+        size_t off = y * bmp->stride + x / CHAR_BIT;
+        unsigned char bit = 1 << (x % CHAR_BIT);
+
+        return bmp->bits[off] & bit;
+}
+
+static int unpack_bits(int version,
+                       enum qr_ec_level ec,
+                       struct qr_bitstream * raw_bits,
+                       struct qr_bitstream * bits_out)
+{
+        /* FIXME: less math here (get the values from a common helper fn) */
+        /* FIXME: more comments to explain the algorithm */
+
+        const size_t total_bits = qr_code_total_capacity(version);
+        const size_t total_words = total_bits / 8;
+        const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
+        int total_blocks, block_count[2], row_length[2], data_words, rs_words;
+        int i, w, block;
+        struct qr_bitstream ** blocks = 0;
+
+        /* copied from make_data */
+        block_count[0] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][0];
+        block_count[1] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][1];
+        total_blocks = block_count[0] + block_count[1];
+        data_words = total_data / total_blocks;
+        rs_words = total_words / total_blocks - data_words;
+        assert((data_words + rs_words) * block_count[0] +
+               (data_words + rs_words + 1) * block_count[1] == total_words);
+
+        blocks = calloc(total_blocks, sizeof(*blocks));
+        /* XXX: check return (and below) */
+
+        for (i = 0; i < total_blocks; ++i)
+                blocks[i] = qr_bitstream_create();
+
+        /* Read in the data & EC (see spec table 19) */
+
+        qr_bitstream_seek(raw_bits, 0);
+
+        /* XXX: 14-M will be incorrect */
+        row_length[0] = data_words;
+        row_length[1] = block_count[1] > 0 ? (total_data - row_length[0] * block_count[0]) / block_count[1] : 0;
+
+        fprintf(stderr, "block counts %d and %d\n", block_count[0], block_count[1]);
+        fprintf(stderr, "row lengths %d and %d\n", row_length[0], row_length[1]);
+
+        block = 0;
+        for (w = 0; w < total_words; ++w) {
+                if (block == 0 && w / total_blocks == row_length[0] && block_count[1] != 0) {
+                        /* Skip the short blocks, if there are any */
+                        block += block_count[0];
+                }
+                qr_bitstream_write(blocks[block], qr_bitstream_read(raw_bits, 8), 8);
+                block = (block + 1) % total_blocks;
+        }
+
+        /* XXX: apply ec */
+
+        for (block = 0; block < total_blocks; ++block) {
+                struct qr_bitstream * stream = blocks[block];
+                qr_bitstream_seek(stream, 0);
+                for (w = 0; w < row_length[block >= block_count[0]]; ++w)
+                        qr_bitstream_write(bits_out,
+                                           qr_bitstream_read(stream, 8),
+                                           8);
+                qr_bitstream_destroy(stream);
+        }
+        free(blocks);
+
+        return 0;
+}
 
-struct qr_code * qr_code_parse(const void * buffer,
-                               size_t       line_bits,
-                               size_t       line_stride,
-                               size_t       line_count)
+static int read_bits(const struct qr_code * code,
+                     enum qr_ec_level ec,
+                     struct qr_bitstream * data_bits)
 {
+        const size_t total_bits = qr_code_total_capacity(code->version);
+        const size_t total_words = total_bits / 8;
+        struct qr_bitstream * raw_bits;
+        struct qr_iterator * layout;
+        int w;
+        int ret;
+
+        raw_bits = qr_bitstream_create();
+        layout = qr_layout_begin((struct qr_code *) code); /* dropping const! */
+        for (w = 0; w < total_words; ++w)
+                qr_bitstream_write(raw_bits, qr_layout_read(layout), 8);
+        qr_layout_end(layout);
+
+        ret = unpack_bits(code->version, ec, raw_bits, data_bits);
+        qr_bitstream_destroy(raw_bits);
+
+        return ret;
+}
+
+static int read_format(const struct qr_bitmap * bmp, enum qr_ec_level * ec, int * mask)
+{
+        int dim;
+        int i;
+        unsigned bits1, bits2;
+        enum qr_ec_level ec1, ec2;
+        int mask1, mask2;
+        int err1, err2;
+
+        dim = bmp->width;
+        bits1 = bits2 = 0;
+
+        for (i = 14; i >= 8; --i) {
+                bits1 = (bits1 << 1) | !!get_px(bmp, 14 - i + (i <= 8), 8);
+                bits2 = (bits2 << 1) | !!get_px(bmp, 8, dim - 1 - (14 - i));
+        }
+
+        for (; i >= 0; --i) {
+                bits1 = (bits1 << 1) | !!get_px(bmp, 8, i + (i >= 6));
+                bits2 = (bits2 << 1) | !!get_px(bmp, dim - 1 - i, 8);
+        }
+
+        fprintf(stderr, "read format bits %x / %x\n", bits1, bits2);
+
+        err1 = qr_decode_format(bits1, &ec1, &mask1);
+        err2 = qr_decode_format(bits2, &ec2, &mask2);
+
+        if (err1 < 0 && err2 < 0)
+                return -1;
+
+        if (err1 < err2)
+                *ec = ec1, *mask = mask1;
+        else
+                *ec = ec2, *mask = mask2;
+
         return 0;
 }
 
+static int read_version(const struct qr_bitmap * bmp)
+{
+        int dim;
+        int i;
+        unsigned long bits1, bits2;
+        int ver1, ver2;
+        int err1, err2;
+
+        dim = bmp->width;
+        bits1 = bits2 = 0;
+
+        for (i = 17; i >= 0; --i) {
+                bits1 = (bits1 << 1) | !!get_px(bmp, i / 3, dim - 11 + (i % 3));
+                bits2 = (bits2 << 1) | !!get_px(bmp, dim - 11 + (i % 3), i / 3);
+        }
+
+        fprintf(stderr, "read version bits %lx / %lx\n", bits1, bits2);
+
+        err1 = qr_decode_version(bits1, &ver1);
+        err2 = qr_decode_version(bits2, &ver2);
+
+        fprintf(stderr, "got versions %d[%d] / %d[%d]\n", ver1, err1, ver2, err2);
+
+        if (err1 < 0 && err2 < 0)
+                return -1;
+
+        return err1 < err2 ? ver1 : ver2;
+}
+
+int qr_code_parse(const void *      buffer,
+                  size_t            line_bits,
+                  size_t            line_stride,
+                  size_t            line_count,
+                  struct qr_data ** data)
+{
+        struct qr_bitmap src_bmp;
+        struct qr_code code;
+        enum qr_ec_level ec;
+        int mask;
+        struct qr_bitstream * data_bits;
+
+        fprintf(stderr, "parsing code bitmap %lux%lu\n", line_bits, line_count);
+
+        if (line_bits != line_count
+            || line_bits < 21
+            || (line_bits - 17) % 4 != 0) {
+                /* Invalid size */
+                fprintf(stderr, "Invalid size\n");
+                return -1;
+        }
+
+        code.version = (line_bits - 17) / 4;
+        fprintf(stderr, "assuming version %d\n", code.version);
+
+        src_bmp.bits = (unsigned char *) buffer; /* dropping const! */
+        src_bmp.mask = NULL;
+        src_bmp.stride = line_stride;
+        src_bmp.width = line_bits;
+        src_bmp.height = line_count;
+
+        if (code.version >= 7 && read_version(&src_bmp) != code.version) {
+                fprintf(stderr, "Invalid version info\n");
+                return -1;
+        }
+
+        if (read_format(&src_bmp, &ec, &mask) != 0) {
+                fprintf(stderr, "Failed to read format\n");
+                return -1;
+        }
+
+        fprintf(stderr, "detected ec type %d; mask %d\n", ec, mask);
+
+        code.modules = qr_mask_apply(&src_bmp, mask);
+        if (code.modules == NULL) {
+                fprintf(stderr, "failed to apply mask\n");
+                return -1;
+        }
+
+        qr_layout_init_mask(&code);
+
+        data_bits = qr_bitstream_create();
+        /* XXX: check return */
+
+        read_bits(&code, ec, data_bits);
+        /* XXX: check return */
+
+        /*
+        {
+                fprintf(stderr, "decoding failed\n");
+                qr_bitmap_destroy(code.modules);
+                qr_bitstream_destroy(bits);
+                *data = NULL;
+                return -1;
+        }
+        */
+
+        *data = malloc(sizeof(*data));
+        /* XXX: check return */
+
+        (*data)->version = code.version;
+        (*data)->ec = ec;
+        (*data)->bits = data_bits;
+        (*data)->offset = 0;
+
+        return 0;
+}
+
+int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask)
+{
+        bits ^= 0x5412;
+
+        /* TODO: check and fix errors */
+
+        bits >>= 10;
+        *mask = bits & 7;
+        *ec = bits >> 3;
+
+        return 0;
+}
+
+int qr_decode_version(unsigned long bits, int * version)
+{
+        int v, errors;
+        unsigned long version_bits;
+        int best_err, best_version;
+
+        if (bits != (bits & 0x3FFFF))
+                fprintf(stderr, "WARNING: excess version bits");
+
+        best_err = 18;
+
+        for (v = 7; v <= 40; ++v) {
+                /* FIXME: cache these values */
+                /* see calc_version_bits() */
+                version_bits = v;
+                version_bits <<= 12;
+                version_bits |= gf_residue(version_bits, 0x1F25);
+
+                /* count errors */
+                errors = 0;
+                version_bits ^= bits;
+                while (version_bits != 0) {
+                        if ((version_bits & 1) == 1)
+                                ++errors;
+                        version_bits >>= 1;
+                }
+
+                if (errors < best_err) {
+                        best_version = v;
+                        best_err = errors;
+                }
+
+                if (errors == 0) /* can we do better than this? */
+                        break;
+        }
+
+        *version = best_version;
+
+        return best_err;
+}
+
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index 15aa515..2c19e97 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -5,6 +5,7 @@
 
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
+/* See spec table 18 (also table 19 for application) */
 extern const int QR_RS_BLOCK_COUNT[40][4][2];
 extern const enum qr_data_type QR_TYPE_CODES[16];
 
diff --git a/lpg/libqr/data-parse.c b/lpg/libqr/data-parse.c
index 801aa66..d641c47 100644
--- a/lpg/libqr/data-parse.c
+++ b/lpg/libqr/data-parse.c
@@ -220,6 +220,9 @@ enum qr_data_type qr_parse_data(const struct qr_data * input,
 {
         qr_bitstream_seek(input->bits, input->offset);
 
+        *output = NULL;
+        *length = 0;
+
         switch (read_data_type(input->bits)) {
         case QR_DATA_NUMERIC:
                 return parse_numeric(input, output, length);
diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h
index 83e82ab..36c56b3 100644
--- a/lpg/libqr/qr/bitmap.h
+++ b/lpg/libqr/qr/bitmap.h
@@ -11,6 +11,8 @@ struct qr_bitmap {
 struct qr_bitmap * qr_bitmap_create(int width, int height, int masked);
 void qr_bitmap_destroy(struct qr_bitmap *);
 
+int qr_bitmap_add_mask(struct qr_bitmap *);
+
 struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap *);
 
 void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src);
diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h
index ac3c363..2392467 100644
--- a/lpg/libqr/qr/code.h
+++ b/lpg/libqr/qr/code.h
@@ -17,11 +17,6 @@ int qr_code_width(const struct qr_code *);
 
 size_t qr_code_total_capacity(int version);
 
-struct qr_code * qr_code_parse(const void * buffer,
-                               size_t       line_bits,
-                               size_t       line_stride,
-                               size_t       line_count);
-
 struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
                                  unsigned int mask);
 
diff --git a/lpg/libqr/qr/parse.h b/lpg/libqr/qr/parse.h
new file mode 100644
index 0000000..d7b8c4e
--- /dev/null
+++ b/lpg/libqr/qr/parse.h
@@ -0,0 +1,16 @@
+#ifndef QR_PARSE_H
+#define QR_PARSE_H
+
+#include "data.h"
+
+int qr_code_parse(const void *      buffer,
+                  size_t            line_bits,
+                  size_t            line_stride,
+                  size_t            line_count,
+                  struct qr_data ** data);
+
+int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask);
+int qr_decode_version(unsigned long bits, int * version);
+
+#endif
+
diff --git a/lpg/libqr/qrparse.c b/lpg/libqr/qrparse.c
new file mode 100644
index 0000000..4a9312f
--- /dev/null
+++ b/lpg/libqr/qrparse.c
@@ -0,0 +1,59 @@
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qr/code.h>
+#include <qr/data.h>
+#include <qr/parse.h>
+
+#include "testqr.xbm"
+
+int main(int argc, char ** argv)
+{
+        struct qr_data * data;
+        int ret;
+
+        ret = qr_code_parse(testqr_bits,
+                            testqr_width,
+                            (testqr_width + CHAR_BIT - 1) / CHAR_BIT,
+                            testqr_height,
+                            &data);
+
+        fprintf(stderr, "qr_code_parse returned %d\n", ret);
+
+        if (ret == 0) {
+                const char * ec_str, * type_str;
+                char * data_str;
+                size_t data_len;
+                enum qr_data_type data_type;
+
+                fprintf(stderr, "version = %d\n", data->version);
+                switch (data->ec) {
+                case QR_EC_LEVEL_L: ec_str = "L"; break;
+                case QR_EC_LEVEL_M: ec_str = "M"; break;
+                case QR_EC_LEVEL_Q: ec_str = "Q"; break;
+                case QR_EC_LEVEL_H: ec_str = "H"; break;
+                default: ec_str = "(unknown)"; break;
+                }
+                fprintf(stderr, "EC level %s\n", ec_str);
+
+                data_type = qr_parse_data(data, &data_str, &data_len);
+                switch (data_type) {
+                case QR_DATA_INVALID: type_str = "(invalid)"; break;
+                case QR_DATA_ECI: type_str = "ECI"; break;
+                case QR_DATA_NUMERIC: type_str = "numeric"; break;
+                case QR_DATA_ALPHA: type_str = "alpha"; break;
+                case QR_DATA_8BIT: type_str = "8-bit"; break;
+                case QR_DATA_KANJI: type_str = "kanji"; break;
+                case QR_DATA_MIXED: type_str = "mixed"; break;
+                case QR_DATA_FNC1: type_str = "FNC1"; break;
+                default: type_str = "(unknown)"; break;
+                }
+                fprintf(stderr, "Data type: %s; %lu bytes\nContent: %s\n", type_str, data_len, data_str);
+                free(data_str);
+                qr_free_data(data);
+        }
+
+        return 0;
+}
+
diff --git a/lpg/libqr/testqr.xbm b/lpg/libqr/testqr.xbm
new file mode 100644
index 0000000..ca2966f
--- /dev/null
+++ b/lpg/libqr/testqr.xbm
@@ -0,0 +1,19 @@
+#define testqr_width 37
+#define testqr_height 37
+static unsigned char testqr_bits[] = {
+  0x7F, 0x63, 0xFB, 0xDA, 0x1F, 0x41, 0xD7, 0xAD, 0x55, 0x10, 0x5D, 0x3D, 
+  0xE9, 0x5E, 0x17, 0x5D, 0xC6, 0xB5, 0x43, 0x17, 0x5D, 0x41, 0x61, 0x52, 
+  0x17, 0x41, 0x76, 0xC9, 0x46, 0x10, 0x7F, 0x55, 0x55, 0xD5, 0x1F, 0x00, 
+  0x98, 0x47, 0x05, 0x00, 0xF9, 0x99, 0xE0, 0x36, 0x1D, 0x24, 0x01, 0x07, 
+  0xC7, 0x0A, 0x60, 0xBC, 0xB9, 0x44, 0x16, 0x81, 0x21, 0x9D, 0x8D, 0x1B, 
+  0xCF, 0x8E, 0x83, 0x51, 0x16, 0xA2, 0x1B, 0xFD, 0x3A, 0x1B, 0xEB, 0x3B, 
+  0x1D, 0x5B, 0x17, 0xA9, 0xF6, 0x70, 0xF8, 0x1F, 0xC1, 0x68, 0x66, 0xFD, 
+  0x1D, 0xB3, 0x07, 0xC2, 0x54, 0x04, 0xD8, 0x0C, 0x4F, 0x4D, 0x15, 0x11, 
+  0xA1, 0x99, 0xA2, 0x11, 0x60, 0x65, 0xCC, 0x49, 0x05, 0x1D, 0x1F, 0xC3, 
+  0x8E, 0x15, 0x64, 0xED, 0xB9, 0x9A, 0x02, 0x90, 0x03, 0x1D, 0xAA, 0x0D, 
+  0x45, 0xD8, 0x72, 0x92, 0x01, 0x83, 0x53, 0x6E, 0x55, 0x06, 0xC7, 0xC4, 
+  0x02, 0xB4, 0x1B, 0x19, 0x24, 0x0F, 0x8D, 0x12, 0xE5, 0xAA, 0xAA, 0xF3, 
+  0x03, 0x00, 0x5F, 0x66, 0x11, 0x11, 0x7F, 0x73, 0x8F, 0x57, 0x1B, 0x41, 
+  0x8D, 0x39, 0x1B, 0x19, 0x5D, 0x3B, 0x3D, 0xFB, 0x13, 0x5D, 0x03, 0x70, 
+  0x62, 0x1C, 0x5D, 0x6A, 0x46, 0x37, 0x19, 0x41, 0xDA, 0x62, 0xF8, 0x1D, 
+  0x7F, 0x7B, 0x3E, 0x58, 0x14, };
-- 
cgit v1.2.3-70-g09d2


From 3af4ffd175dcaf8aaf735f3f9564da54c4f29403 Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Thu, 14 Jul 2011 11:36:58 +0900
Subject: Create common header

---
 lpg/libqr/code-create.c |  1 +
 lpg/libqr/code-layout.c |  1 +
 lpg/libqr/code-parse.c  |  2 +-
 lpg/libqr/constants.h   |  2 +-
 lpg/libqr/qr/code.h     |  7 -------
 lpg/libqr/qr/common.h   | 14 ++++++++++++++
 lpg/libqr/qr/data.h     | 18 ------------------
 lpg/libqr/qr/types.h    | 18 ++++++++++++++++++
 8 files changed, 36 insertions(+), 27 deletions(-)
 create mode 100644 lpg/libqr/qr/common.h

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 155ffa3..1da7845 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -5,6 +5,7 @@
 #include <qr/bitmap.h>
 #include <qr/bitstream.h>
 #include <qr/code.h>
+#include <qr/common.h>
 #include <qr/data.h>
 #include <qr/layout.h>
 #include "constants.h"
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 04b6ca6..97cf3af 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -5,6 +5,7 @@
 
 #include <qr/bitmap.h>
 #include <qr/code.h>
+#include <qr/common.h>
 #include <qr/layout.h>
 #include "constants.h"
 
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 50d621c..f84dcfe 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -7,7 +7,7 @@
 #include <qr/bitmap.h>
 #include <qr/bitstream.h>
 #include <qr/code.h>
-#include <qr/data.h>
+#include <qr/common.h>
 #include <qr/layout.h>
 #include <qr/parse.h>
 
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index 2c19e97..5ae9256 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -1,7 +1,7 @@
 #ifndef QR_CONSTANTS_H
 #define QR_CONSTANTS_H
 
-#include <qr/data.h>
+#include <qr/types.h>
 
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h
index 2392467..e6eb47c 100644
--- a/lpg/libqr/qr/code.h
+++ b/lpg/libqr/qr/code.h
@@ -13,12 +13,5 @@ struct qr_code * qr_code_create(const struct qr_data * data);
 
 void qr_code_destroy(struct qr_code *);
 
-int qr_code_width(const struct qr_code *);
-
-size_t qr_code_total_capacity(int version);
-
-struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
-                                 unsigned int mask);
-
 #endif
 
diff --git a/lpg/libqr/qr/common.h b/lpg/libqr/qr/common.h
new file mode 100644
index 0000000..9caf3e0
--- /dev/null
+++ b/lpg/libqr/qr/common.h
@@ -0,0 +1,14 @@
+#ifndef QR_COMMON_H
+#define QR_COMMON_H
+
+#include <qr/types.h>
+
+struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
+                                 unsigned int mask);
+
+size_t qr_code_total_capacity(int version);
+
+int qr_code_width(const struct qr_code *);
+
+#endif
+
diff --git a/lpg/libqr/qr/data.h b/lpg/libqr/qr/data.h
index a3bb309..3cc665a 100644
--- a/lpg/libqr/qr/data.h
+++ b/lpg/libqr/qr/data.h
@@ -4,24 +4,6 @@
 #include <stddef.h>
 #include "types.h"
 
-enum qr_data_type {
-        QR_DATA_INVALID = -1,
-        QR_DATA_ECI     =  7,
-        QR_DATA_NUMERIC =  1,
-        QR_DATA_ALPHA   =  2,
-        QR_DATA_8BIT    =  4,
-        QR_DATA_KANJI   =  8, /* JIS X 0208 */
-        QR_DATA_MIXED   =  3,
-        QR_DATA_FNC1    =  9
-};
-
-enum qr_ec_level {
-        QR_EC_LEVEL_L = 0x1,
-        QR_EC_LEVEL_M = 0x0,
-        QR_EC_LEVEL_Q = 0x3,
-        QR_EC_LEVEL_H = 0x2
-};
-
 struct qr_data {
         int                   version; /* 1 ~ 40 */
         enum qr_ec_level      ec;
diff --git a/lpg/libqr/qr/types.h b/lpg/libqr/qr/types.h
index bb44cde..3615e3e 100644
--- a/lpg/libqr/qr/types.h
+++ b/lpg/libqr/qr/types.h
@@ -4,5 +4,23 @@
 struct qr_data;
 struct qr_code;
 
+enum qr_data_type {
+        QR_DATA_INVALID = -1,
+        QR_DATA_ECI     =  7,
+        QR_DATA_NUMERIC =  1,
+        QR_DATA_ALPHA   =  2,
+        QR_DATA_8BIT    =  4,
+        QR_DATA_KANJI   =  8, /* JIS X 0208 */
+        QR_DATA_MIXED   =  3,
+        QR_DATA_FNC1    =  9
+};
+
+enum qr_ec_level {
+        QR_EC_LEVEL_L = 0x1,
+        QR_EC_LEVEL_M = 0x0,
+        QR_EC_LEVEL_Q = 0x3,
+        QR_EC_LEVEL_H = 0x2
+};
+
 #endif
 
-- 
cgit v1.2.3-70-g09d2


From 9f4843d686bca0d75bee174d8249fbf72527b94a Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Thu, 14 Jul 2011 14:31:07 +0900
Subject: Move RS block size calculation to a separate function

---
 lpg/libqr/code-common.c | 35 ++++++++++++++++++++++++++++++++++-
 lpg/libqr/code-create.c | 37 +++++++++++++++++++------------------
 lpg/libqr/code-parse.c  | 33 +++++++++++----------------------
 lpg/libqr/constants.h   |  2 +-
 lpg/libqr/qr/common.h   | 11 +++++++++++
 5 files changed, 76 insertions(+), 42 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index a0b8fcc..422f2ac 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -2,9 +2,11 @@
 #include <limits.h>
 #include <stdlib.h>
 
-#include <qr/code.h>
 #include <qr/bitmap.h>
 #include <qr/bitstream.h>
+#include <qr/code.h>
+#include <qr/common.h>
+#include "constants.h"
 
 void qr_code_destroy(struct qr_code * code)
 {
@@ -41,6 +43,37 @@ size_t qr_code_total_capacity(int version)
 	return side * side - function_bits;
 }
 
+void qr_get_rs_block_sizes(int version,
+                           enum qr_ec_level ec,
+                           int block_count[2],
+                           int data_length[2],
+                           int ec_length[2])
+{
+        /* FIXME: rather than using a big static table, better to
+         * calculate these values.
+         */
+        int total_words = qr_code_total_capacity(version) / 8;
+        int data_words = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
+        int ec_words = total_words - data_words;
+        int total_blocks;
+
+        block_count[0] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][0];
+        block_count[1] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][1];
+        total_blocks = block_count[0] + block_count[1];
+
+        data_length[0] = data_words / total_blocks;
+        data_length[1] = data_length[0] + 1;
+
+        assert(data_length[0] * block_count[0] +
+               data_length[1] * block_count[1] == data_words);
+
+        ec_length[0] = ec_length[1] = ec_words / total_blocks;
+
+        assert(ec_length[0] * block_count[0] +
+               ec_length[1] * block_count[1] == ec_words);
+        assert(data_words + ec_words == total_words);
+}
+
 struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
                                  unsigned int mask)
 {
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 1da7845..680b405 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -172,7 +172,8 @@ static struct qr_bitstream * make_data(int version,
         const size_t total_bits = qr_code_total_capacity(version);
         const size_t total_words = total_bits / 8;
         const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
-        size_t total_blocks, block_count[2], data_words, rs_words;
+        int block_count[2], data_length[2], ec_length[2];
+        int total_blocks;
         size_t i, w;
         struct qr_bitstream * dcopy = 0;
         struct qr_bitstream * out = 0;
@@ -186,14 +187,8 @@ static struct qr_bitstream * make_data(int version,
         if (qr_bitstream_resize(out, total_bits) != 0)
                 goto fail;
 
-        /* XXX: 14-M will be incorrect */
-        block_count[0] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][0];
-        block_count[1] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][1];
+        qr_get_rs_block_sizes(version, ec, block_count, data_length, ec_length);
         total_blocks = block_count[0] + block_count[1];
-        data_words = total_data / total_blocks;
-        rs_words = total_words / total_blocks - data_words;
-        assert((data_words + rs_words) * block_count[0] +
-               (data_words + rs_words + 1) * block_count[1] == total_words);
 
         /* Make a copy of the data and pad it */
         dcopy = qr_bitstream_dup(data);
@@ -207,17 +202,20 @@ static struct qr_bitstream * make_data(int version,
         x_dump(dcopy);
 
         /* Make space for the RS blocks */
-        blocks = calloc(total_blocks, sizeof(*blocks));
+        blocks = malloc(total_blocks * sizeof(*blocks));
         if (!blocks)
                 goto fail;
+        for (i = 0; i < total_blocks; ++i)
+                blocks[i] = NULL;
 
         /* Generate RS codewords */
         qr_bitstream_seek(dcopy, 0);
         fputs("Generate RS blocks:\n", stderr);
         for (i = 0; i < total_blocks; ++i) {
-                size_t dw = data_words + (i >= block_count[0]);
-
-                blocks[i] = rs_generate_words(dcopy, dw, rs_words);
+                int type = (i >= block_count[0]);
+                blocks[i] = rs_generate_words(dcopy,
+                                              data_length[type],
+                                              ec_length[type]);
                 if (!blocks[i]) {
                         while (i--)
                                 qr_bitstream_destroy(blocks[i]);
@@ -229,11 +227,13 @@ static struct qr_bitstream * make_data(int version,
         }
 
         /* Finally, write everything out in the correct order */
-        for (w = 0; w < data_words + 1; ++w) {
-                for (i = (w == data_words ? block_count[0] : 0); i < total_blocks; ++i) {
-                        size_t di = w + (i < block_count[0] ?
-                                i * data_words :
-                                i * (data_words + 1) - block_count[0]);
+        assert(block_count[1] == 0 || data_length[1] >= data_length[0]);
+        for (w = 0; w < data_length[block_count[1] ? 1 : 0]; ++w) {
+                for (i = (w >= data_length[0] ? block_count[0] : 0); i < total_blocks; ++i) {
+                        long di = w + i * data_length[0]
+                                + (i > block_count[0] ?
+                                        (i - block_count[0]) * (data_length[1] - data_length[0])
+                                        : 0);
 
                         qr_bitstream_seek(dcopy, di * 8);
                         qr_bitstream_write(out,
@@ -242,7 +242,8 @@ static struct qr_bitstream * make_data(int version,
         }
         for (i = 0; i < total_blocks; ++i)
                 qr_bitstream_seek(blocks[i], 0);
-        for (w = 0; w < rs_words; ++w)
+        assert(block_count[1] == 0 || ec_length[1] == ec_length[0]);
+        for (w = 0; w < ec_length[0]; ++w)
                 for (i = 0; i < total_blocks; ++i)
                         qr_bitstream_write(out,
                                 qr_bitstream_read(blocks[i], 8), 8);
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index f84dcfe..29d96bb 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -31,24 +31,19 @@ static int unpack_bits(int version,
         /* FIXME: less math here (get the values from a common helper fn) */
         /* FIXME: more comments to explain the algorithm */
 
-        const size_t total_bits = qr_code_total_capacity(version);
-        const size_t total_words = total_bits / 8;
-        const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
-        int total_blocks, block_count[2], row_length[2], data_words, rs_words;
+        int total_words = qr_code_total_capacity(version) / 8;
+        int block_count[2], data_length[2], ec_length[2];
+        int total_blocks;
         int i, w, block;
         struct qr_bitstream ** blocks = 0;
 
-        /* copied from make_data */
-        block_count[0] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][0];
-        block_count[1] = QR_RS_BLOCK_COUNT[version - 1][ec ^ 0x1][1];
+        qr_get_rs_block_sizes(version, ec, block_count, data_length, ec_length);
         total_blocks = block_count[0] + block_count[1];
-        data_words = total_data / total_blocks;
-        rs_words = total_words / total_blocks - data_words;
-        assert((data_words + rs_words) * block_count[0] +
-               (data_words + rs_words + 1) * block_count[1] == total_words);
 
-        blocks = calloc(total_blocks, sizeof(*blocks));
+        blocks = malloc(total_blocks * sizeof(*blocks));
         /* XXX: check return (and below) */
+        for (i = 0; i < total_blocks; ++i)
+                blocks[i] = NULL;
 
         for (i = 0; i < total_blocks; ++i)
                 blocks[i] = qr_bitstream_create();
@@ -57,16 +52,12 @@ static int unpack_bits(int version,
 
         qr_bitstream_seek(raw_bits, 0);
 
-        /* XXX: 14-M will be incorrect */
-        row_length[0] = data_words;
-        row_length[1] = block_count[1] > 0 ? (total_data - row_length[0] * block_count[0]) / block_count[1] : 0;
-
         fprintf(stderr, "block counts %d and %d\n", block_count[0], block_count[1]);
-        fprintf(stderr, "row lengths %d and %d\n", row_length[0], row_length[1]);
+        fprintf(stderr, "row lengths %d and %d\n", data_length[0], data_length[1]);
 
         block = 0;
         for (w = 0; w < total_words; ++w) {
-                if (block == 0 && w / total_blocks == row_length[0] && block_count[1] != 0) {
+                if (block == 0 && w / total_blocks >= data_length[0] && block_count[1] != 0) {
                         /* Skip the short blocks, if there are any */
                         block += block_count[0];
                 }
@@ -77,12 +68,10 @@ static int unpack_bits(int version,
         /* XXX: apply ec */
 
         for (block = 0; block < total_blocks; ++block) {
+                int type = (block >= block_count[0]);
                 struct qr_bitstream * stream = blocks[block];
                 qr_bitstream_seek(stream, 0);
-                for (w = 0; w < row_length[block >= block_count[0]]; ++w)
-                        qr_bitstream_write(bits_out,
-                                           qr_bitstream_read(stream, 8),
-                                           8);
+                qr_bitstream_copy(bits_out, stream, data_length[type] * 8);
                 qr_bitstream_destroy(stream);
         }
         free(blocks);
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index 5ae9256..fbfadc8 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -5,7 +5,7 @@
 
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
-/* See spec table 18 (also table 19 for application) */
+/* See qr_get_rs_block_sizes() */
 extern const int QR_RS_BLOCK_COUNT[40][4][2];
 extern const enum qr_data_type QR_TYPE_CODES[16];
 
diff --git a/lpg/libqr/qr/common.h b/lpg/libqr/qr/common.h
index 9caf3e0..f2bd127 100644
--- a/lpg/libqr/qr/common.h
+++ b/lpg/libqr/qr/common.h
@@ -10,5 +10,16 @@ size_t qr_code_total_capacity(int version);
 
 int qr_code_width(const struct qr_code *);
 
+/* See table 19 of the spec for the layout of EC data. There are at
+ * most two different block lengths, so the total number of data+ec
+ * blocks is the sum of block_count[]. The total number of 8-bit
+ * words in each kind of block is data_length + ec_length.
+ */
+void qr_get_rs_block_sizes(int version,
+                           enum qr_ec_level ec,
+                           int block_count[2],
+                           int data_length[2],
+                           int ec_length[2]);
+
 #endif
 
-- 
cgit v1.2.3-70-g09d2


From 4670274ec303082e0fb86ff3be1ea4170a17662f Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Fri, 15 Jul 2011 14:20:41 +0900
Subject: qr_mask_apply() works in-place

---
 lpg/libqr/code-common.c | 14 +++-----------
 lpg/libqr/code-create.c |  3 ++-
 lpg/libqr/code-parse.c  |  8 +++-----
 lpg/libqr/qr/common.h   |  3 +--
 4 files changed, 9 insertions(+), 19 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index 422f2ac..1cb1745 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -74,18 +74,12 @@ void qr_get_rs_block_sizes(int version,
         assert(data_words + ec_words == total_words);
 }
 
-struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
-                                 unsigned int mask)
+void qr_mask_apply(struct qr_bitmap * bmp, int mask)
 {
-        struct qr_bitmap * bmp;
         int i, j;
 
-        if (mask > 7)
-                return 0;
-
-        bmp = qr_bitmap_clone(orig);
-        if (!bmp)
-                return 0;
+        assert((mask & 0x7) == mask);
+        mask &= 0x7;
 
         /* Slow version for now; we can optimize later */
 
@@ -111,7 +105,5 @@ struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
                         p[off] ^= (t == 0) << bit;
                 }
         }
-
-        return bmp;
 }
 
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index 680b405..f29778f 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -332,11 +332,12 @@ static int mask_data(struct qr_code * code)
 
         /* Generate bitmap for each mask and evaluate */
         for (i = 0; i < 8; ++i) {
-                test = qr_mask_apply(code->modules, i);
+                test = qr_bitmap_clone(code->modules);
                 if (!test) {
                         qr_bitmap_destroy(mask);
                         return -1;
                 }
+                qr_mask_apply(test, i);
                 score = score_mask(test);
                 fprintf(stderr, "mask %d scored %d\n", i, score);
                 if (!mask || score < best) {
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 29d96bb..7a98280 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -212,11 +212,9 @@ int qr_code_parse(const void *      buffer,
 
         fprintf(stderr, "detected ec type %d; mask %d\n", ec, mask);
 
-        code.modules = qr_mask_apply(&src_bmp, mask);
-        if (code.modules == NULL) {
-                fprintf(stderr, "failed to apply mask\n");
-                return -1;
-        }
+        code.modules = qr_bitmap_clone(&src_bmp);
+        /* XXX: check return */
+        qr_mask_apply(code.modules, mask);
 
         qr_layout_init_mask(&code);
 
diff --git a/lpg/libqr/qr/common.h b/lpg/libqr/qr/common.h
index f2bd127..640696a 100644
--- a/lpg/libqr/qr/common.h
+++ b/lpg/libqr/qr/common.h
@@ -3,8 +3,7 @@
 
 #include <qr/types.h>
 
-struct qr_bitmap * qr_mask_apply(const struct qr_bitmap * orig,
-                                 unsigned int mask);
+void qr_mask_apply(struct qr_bitmap * bmp, int mask);
 
 size_t qr_code_total_capacity(int version);
 
-- 
cgit v1.2.3-70-g09d2


From f7133a8a56650a2e5cefc66b6d9b87809a890b2e Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Fri, 15 Jul 2011 14:57:03 +0900
Subject: Remove (a few) magic numbers

---
 lpg/libqr/code-create.c | 33 +++++++++++++--------------------
 lpg/libqr/code-layout.c |  4 ++--
 lpg/libqr/code-parse.c  | 20 ++++++++++----------
 lpg/libqr/constants.h   | 16 ++++++++++++++++
 4 files changed, 41 insertions(+), 32 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index f29778f..d00a41f 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -170,7 +170,6 @@ static struct qr_bitstream * make_data(int version,
                                        struct qr_bitstream * data)
 {
         const size_t total_bits = qr_code_total_capacity(version);
-        const size_t total_words = total_bits / 8;
         const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
         int block_count[2], data_length[2], ec_length[2];
         int total_blocks;
@@ -195,7 +194,7 @@ static struct qr_bitstream * make_data(int version,
         if (!dcopy)
                 goto fail;
 
-        if (pad_data(dcopy, total_data * 8) != 0)
+        if (pad_data(dcopy, total_data * QR_WORD_BITS) != 0)
                 goto fail;
 
         fputs("Pad data:\n", stderr);
@@ -235,9 +234,8 @@ static struct qr_bitstream * make_data(int version,
                                         (i - block_count[0]) * (data_length[1] - data_length[0])
                                         : 0);
 
-                        qr_bitstream_seek(dcopy, di * 8);
-                        qr_bitstream_write(out,
-                                qr_bitstream_read(dcopy, 8), 8);
+                        qr_bitstream_seek(dcopy, di * QR_WORD_BITS);
+                        qr_bitstream_copy(out, dcopy, QR_WORD_BITS);
                 }
         }
         for (i = 0; i < total_blocks; ++i)
@@ -245,10 +243,9 @@ static struct qr_bitstream * make_data(int version,
         assert(block_count[1] == 0 || ec_length[1] == ec_length[0]);
         for (w = 0; w < ec_length[0]; ++w)
                 for (i = 0; i < total_blocks; ++i)
-                        qr_bitstream_write(out,
-                                qr_bitstream_read(blocks[i], 8), 8);
+                        qr_bitstream_copy(out, blocks[i], QR_WORD_BITS);
 
-        qr_bitstream_write(out, 0, total_bits - total_words * 8);
+        qr_bitstream_write(out, 0, total_bits % QR_WORD_BITS);
 
         fputs("Final bitstream:\n", stderr);
         x_dump(out);
@@ -299,8 +296,8 @@ struct qr_code * qr_code_create(const struct qr_data * data)
                 goto fail;
 
         qr_bitstream_seek(bits, 0);
-        while (qr_bitstream_remaining(bits) >= 8)
-                qr_layout_write(layout, qr_bitstream_read(bits, 8));
+        while (qr_bitstream_remaining(bits) >= QR_WORD_BITS)
+                qr_layout_write(layout, qr_bitstream_read(bits, QR_WORD_BITS));
         qr_layout_end(layout);
 
         mask = mask_data(code);
@@ -566,15 +563,12 @@ static int calc_format_bits(enum qr_ec_level ec, int mask)
 
         bits = (ec & 0x3) << 3 | (mask & 0x7);
 
-        /* Compute (15, 5) BCH code with
-         *   G(x) = x^10 + x^8 + x^5 + x^4 + x^2 + x + 1
-         */
+        /* Compute (15, 5) BCH code */
 
         bits <<= 15 - 5;
-        bits |= (unsigned int)gf_residue(bits, 0x537);
+        bits |= (unsigned int)gf_residue(bits, QR_FORMAT_POLY);
 
-        /* XOR mask: 101 0100 0001 0010 */
-        bits ^= 0x5412;
+        bits ^= QR_FORMAT_MASK;
 
         return bits;
 }
@@ -585,11 +579,10 @@ static long calc_version_bits(int version)
 
         bits = version & 0x3F;
 
-        /* (18, 6) BCH code
-         *   G(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
-         */
+        /* (18, 6) BCH code */
+
         bits <<= 18 - 6;
-        bits |= gf_residue(bits, 0x1F25);
+        bits |= gf_residue(bits, QR_VERSION_POLY);
 
 fprintf(stderr, "version bits: %lx\n", bits);
         return bits;
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 97cf3af..8b4522d 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -167,7 +167,7 @@ unsigned int qr_layout_read(struct qr_iterator * i)
         unsigned int x = 0;
         int b;
 
-        for (b = 0; b < 8; ++b) {
+        for (b = 0; b < QR_WORD_BITS; ++b) {
                 x = (x << 1) | ((*i->p & i->mask) ? 1 : 0);
                 advance(i);
         }
@@ -179,7 +179,7 @@ void qr_layout_write(struct qr_iterator * i, unsigned int x)
 {
         int b;
 
-        for (b = 0; b < 8; ++b) {
+        for (b = 0; b < QR_WORD_BITS; ++b) {
                 *i->p |= (x & 0x80) ? i->mask : 0;
                 advance(i);
                 x <<= 1;
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 690734b..8e36a15 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -30,7 +30,7 @@ static int unpack_bits(int version,
 {
         /* FIXME: more comments to explain the algorithm */
 
-        int total_words = qr_code_total_capacity(version) / 8;
+        int total_words = qr_code_total_capacity(version) / QR_WORD_BITS;
         int block_count[2], data_length[2], ec_length[2];
         int total_blocks;
         int i, w, block;
@@ -42,7 +42,7 @@ static int unpack_bits(int version,
 
         status = qr_bitstream_resize(bits_out,
                 (block_count[0] * data_length[0] +
-                 block_count[1] * data_length[1]) * 8);
+                 block_count[1] * data_length[1]) * QR_WORD_BITS);
         if (status != 0)
                 goto cleanup;
 
@@ -60,7 +60,7 @@ static int unpack_bits(int version,
                 if (blocks[i] == NULL)
                         goto cleanup;
                 status = qr_bitstream_resize(blocks[i],
-                        (data_length[type] + ec_length[type]) * 8);
+                        (data_length[type] + ec_length[type]) * QR_WORD_BITS);
                 if (status != 0)
                         goto cleanup;
         }
@@ -78,7 +78,7 @@ static int unpack_bits(int version,
                         /* Skip the short blocks, if there are any */
                         block += block_count[0];
                 }
-                qr_bitstream_write(blocks[block], qr_bitstream_read(raw_bits, 8), 8);
+                qr_bitstream_copy(blocks[block], raw_bits, QR_WORD_BITS);
                 block = (block + 1) % total_blocks;
         }
 
@@ -88,7 +88,7 @@ static int unpack_bits(int version,
                 int type = (block >= block_count[0]);
                 struct qr_bitstream * stream = blocks[block];
                 qr_bitstream_seek(stream, 0);
-                qr_bitstream_copy(bits_out, stream, data_length[type] * 8);
+                qr_bitstream_copy(bits_out, stream, data_length[type] * QR_WORD_BITS);
         }
         status = 0;
 
@@ -108,7 +108,7 @@ static int read_bits(const struct qr_code * code,
                      struct qr_bitstream * data_bits)
 {
         const size_t total_bits = qr_code_total_capacity(code->version);
-        const size_t total_words = total_bits / 8;
+        const size_t total_words = total_bits / QR_WORD_BITS;
         struct qr_bitstream * raw_bits;
         struct qr_iterator * layout;
         int w;
@@ -118,7 +118,7 @@ static int read_bits(const struct qr_code * code,
         if (raw_bits == NULL)
                 goto cleanup;
 
-        ret = qr_bitstream_resize(raw_bits, total_words * 8);
+        ret = qr_bitstream_resize(raw_bits, total_words * QR_WORD_BITS);
         if (ret != 0)
                 goto cleanup;
 
@@ -126,7 +126,7 @@ static int read_bits(const struct qr_code * code,
         if (layout == NULL)
                 goto cleanup;
         for (w = 0; w < total_words; ++w)
-                qr_bitstream_write(raw_bits, qr_layout_read(layout), 8);
+                qr_bitstream_write(raw_bits, qr_layout_read(layout), QR_WORD_BITS);
         qr_layout_end(layout);
 
         ret = unpack_bits(code->version, ec, raw_bits, data_bits);
@@ -294,7 +294,7 @@ cleanup:
 
 int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask)
 {
-        bits ^= 0x5412;
+        bits ^= QR_FORMAT_MASK;
 
         /* TODO: check and fix errors */
 
@@ -321,7 +321,7 @@ int qr_decode_version(unsigned long bits, int * version)
                 /* see calc_version_bits() */
                 version_bits = v;
                 version_bits <<= 12;
-                version_bits |= gf_residue(version_bits, 0x1F25);
+                version_bits |= gf_residue(version_bits, QR_VERSION_POLY);
 
                 /* count errors */
                 errors = 0;
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index fbfadc8..e6cfa3c 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -3,6 +3,22 @@
 
 #include <qr/types.h>
 
+/* XOR mask for format data: 101 0100 0001 0010 */
+#define QR_FORMAT_MASK (0x5412)
+
+/* Format info EC polynomial
+ * G(x) = x^10 + x^8 + x^5 + x^4 + x^2 + x + 1
+ */
+#define QR_FORMAT_POLY (0x537)
+
+/* Version info EC polynomial
+ * G(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
+ */
+#define QR_VERSION_POLY (0x1F25)
+
+/* A QR-code word is always 8 bits, but CHAR_BIT might not be */
+#define QR_WORD_BITS (8)
+
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
 /* See qr_get_rs_block_sizes() */
-- 
cgit v1.2.3-70-g09d2


From a3234f7d7e36ad7d1bad6a85b868b05addf40e9b Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Sun, 17 Jul 2011 09:45:26 +0900
Subject: Tweak some types

---
 lpg/libqr/code-create.c | 13 ++++++-------
 lpg/libqr/constants.h   |  8 ++++----
 2 files changed, 10 insertions(+), 11 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index d00a41f..cf04eb7 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -25,8 +25,8 @@ static int draw_format(struct qr_bitmap * bmp,
                         struct qr_code * code,
                         enum qr_ec_level ec,
                         int mask);
-static int calc_format_bits(enum qr_ec_level ec, int mask);
-static long calc_version_bits(int version);
+static unsigned int calc_format_bits(enum qr_ec_level ec, int mask);
+static unsigned long calc_version_bits(int version);
 
 #include <stdio.h>
 static void x_dump(struct qr_bitstream * bits)
@@ -557,9 +557,9 @@ static int draw_format(struct qr_bitmap * bmp,
         return 0;
 }
 
-static int calc_format_bits(enum qr_ec_level ec, int mask)
+static unsigned int calc_format_bits(enum qr_ec_level ec, int mask)
 {
-        int bits;
+        unsigned int bits;
 
         bits = (ec & 0x3) << 3 | (mask & 0x7);
 
@@ -573,9 +573,9 @@ static int calc_format_bits(enum qr_ec_level ec, int mask)
         return bits;
 }
 
-static long calc_version_bits(int version)
+static unsigned long calc_version_bits(int version)
 {
-        long bits;
+        unsigned long bits;
 
         bits = version & 0x3F;
 
@@ -584,7 +584,6 @@ static long calc_version_bits(int version)
         bits <<= 18 - 6;
         bits |= gf_residue(bits, QR_VERSION_POLY);
 
-fprintf(stderr, "version bits: %lx\n", bits);
         return bits;
 }
 
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index e6cfa3c..c13ae5a 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -4,20 +4,20 @@
 #include <qr/types.h>
 
 /* XOR mask for format data: 101 0100 0001 0010 */
-#define QR_FORMAT_MASK (0x5412)
+static const unsigned int QR_FORMAT_MASK = 0x5412;
 
 /* Format info EC polynomial
  * G(x) = x^10 + x^8 + x^5 + x^4 + x^2 + x + 1
  */
-#define QR_FORMAT_POLY (0x537)
+static const unsigned int QR_FORMAT_POLY = 0x537;
 
 /* Version info EC polynomial
  * G(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
  */
-#define QR_VERSION_POLY (0x1F25)
+static const unsigned int QR_VERSION_POLY = 0x1F25;
 
 /* A QR-code word is always 8 bits, but CHAR_BIT might not be */
-#define QR_WORD_BITS (8)
+static const unsigned int QR_WORD_BITS = 8;
 
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
-- 
cgit v1.2.3-70-g09d2


From d4abb878df167875bb66d1e0debe853cb6b88b1b Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Tue, 19 Jul 2011 12:04:15 +0900
Subject: Fix some types

---
 lpg/libqr/bitmap.c       |  6 +++---
 lpg/libqr/bitstream.c    | 14 +++++++-------
 lpg/libqr/code-common.c  |  2 +-
 lpg/libqr/code-create.c  | 16 +++++++++-------
 lpg/libqr/code-layout.c  |  6 +++---
 lpg/libqr/code-parse.c   |  4 ++--
 lpg/libqr/constants.h    |  2 +-
 lpg/libqr/data-create.c  |  2 +-
 lpg/libqr/galois.c       |  2 +-
 lpg/libqr/qr/bitmap.h    |  6 +++---
 lpg/libqr/qr/bitstream.h | 10 +++++-----
 lpg/libqr/qr/parse.h     |  2 +-
 lpg/libqr/qrgen.c        |  2 +-
 13 files changed, 38 insertions(+), 36 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/bitmap.c b/lpg/libqr/bitmap.c
index 759aeca..b9d3763 100644
--- a/lpg/libqr/bitmap.c
+++ b/lpg/libqr/bitmap.c
@@ -5,7 +5,7 @@
 
 #include <qr/bitmap.h>
 
-struct qr_bitmap * qr_bitmap_create(int width, int height, int masked)
+struct qr_bitmap * qr_bitmap_create(size_t width, size_t height, int masked)
 {
         struct qr_bitmap * out;
         size_t size;
@@ -169,9 +169,9 @@ static void render_line_2(unsigned char *       out,
 
 void qr_bitmap_render(const struct qr_bitmap * bmp,
                       void *                   buffer,
-                      size_t                   mod_bits,
+                      int                      mod_bits,
                       size_t                   line_stride,
-                      size_t                   line_repeat,
+                      int                      line_repeat,
                       unsigned long            mark,
                       unsigned long            space)
 {
diff --git a/lpg/libqr/bitstream.c b/lpg/libqr/bitstream.c
index cf5a9d4..cc8a1ae 100644
--- a/lpg/libqr/bitstream.c
+++ b/lpg/libqr/bitstream.c
@@ -121,13 +121,13 @@ size_t qr_bitstream_size(const struct qr_bitstream * stream)
         return stream->count;
 }
 
-unsigned int qr_bitstream_read(struct qr_bitstream * stream, size_t bits)
+unsigned long qr_bitstream_read(struct qr_bitstream * stream, int bits)
 {
-        unsigned int result = 0;
+        unsigned long result = 0;
         unsigned char * byte;
         size_t bitnum;
 
-        assert(qr_bitstream_remaining(stream) >= bits);
+        assert(qr_bitstream_remaining(stream) >= (size_t) bits);
 
         byte = stream->buffer + (stream->pos / CHAR_BIT);
         bitnum = stream->pos % CHAR_BIT;
@@ -149,7 +149,7 @@ unsigned int qr_bitstream_read(struct qr_bitstream * stream, size_t bits)
 void qr_bitstream_unpack(struct qr_bitstream * stream,
                       unsigned int *     result,
                       size_t             count,
-                      size_t             bitsize)
+                      int                bitsize)
 {
         assert(qr_bitstream_remaining(stream) >= (count * bitsize));
 
@@ -158,8 +158,8 @@ void qr_bitstream_unpack(struct qr_bitstream * stream,
 }
 
 int qr_bitstream_write(struct qr_bitstream * stream,
-                    unsigned int       value,
-                    size_t             bits)
+                    unsigned long      value,
+                    int                bits)
 {
         unsigned char * byte;
         size_t bitnum;
@@ -189,7 +189,7 @@ int qr_bitstream_write(struct qr_bitstream * stream,
 int qr_bitstream_pack(struct qr_bitstream *   stream,
                    const unsigned int * values,
                    size_t               count,
-                   size_t               bitsize)
+                   int                  bitsize)
 {
         if (ensure_available(stream, count * bitsize) != 0)
                 return -1;
diff --git a/lpg/libqr/code-common.c b/lpg/libqr/code-common.c
index 1cb1745..babaf86 100644
--- a/lpg/libqr/code-common.c
+++ b/lpg/libqr/code-common.c
@@ -76,7 +76,7 @@ void qr_get_rs_block_sizes(int version,
 
 void qr_mask_apply(struct qr_bitmap * bmp, int mask)
 {
-        int i, j;
+        size_t i, j;
 
         assert((mask & 0x7) == mask);
         mask &= 0x7;
diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index cf04eb7..f9d86a7 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -36,7 +36,7 @@ static void x_dump(struct qr_bitstream * bits)
         qr_bitstream_seek(bits, 0);
         n = qr_bitstream_size(bits);
         for (i = 0; i < n; ++i) {
-                fprintf(stderr, "%d", qr_bitstream_read(bits, 1));
+                fprintf(stderr, "%d", (int) qr_bitstream_read(bits, 1));
                 if (i % 8 == 7)
                         fputc(' ', stderr);
                 if ((i+1) % (7 * 8) == 0)
@@ -173,7 +173,7 @@ static struct qr_bitstream * make_data(int version,
         const size_t total_data = QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1];
         int block_count[2], data_length[2], ec_length[2];
         int total_blocks;
-        size_t i, w;
+        int i, w;
         struct qr_bitstream * dcopy = 0;
         struct qr_bitstream * out = 0;
         struct qr_bitstream ** blocks = 0;
@@ -296,7 +296,7 @@ struct qr_code * qr_code_create(const struct qr_data * data)
                 goto fail;
 
         qr_bitstream_seek(bits, 0);
-        while (qr_bitstream_remaining(bits) >= QR_WORD_BITS)
+        while (qr_bitstream_remaining(bits) >= (size_t) QR_WORD_BITS)
                 qr_layout_write(layout, qr_bitstream_read(bits, QR_WORD_BITS));
         qr_layout_end(layout);
 
@@ -370,7 +370,8 @@ static int score_mask(const struct qr_bitmap * bmp)
 static int score_runs(const struct qr_bitmap * bmp, int base)
 {
         /* Runs of 5+n bits -> N[0] + i */
-        int x, y, flip;
+        size_t x, y;
+        int flip;
         int score = 0;
         int count, last;
 
@@ -406,7 +407,7 @@ static int score_runs(const struct qr_bitmap * bmp, int base)
 static int count_2blocks(const struct qr_bitmap * bmp)
 {
         /* Count the number of 2x2 blocks (on or off) */
-        int x, y;
+        size_t x, y;
         int count = 0;
 
         /* Slow and stupid */
@@ -435,7 +436,8 @@ static int count_2blocks(const struct qr_bitmap * bmp)
 static int count_locators(const struct qr_bitmap * bmp)
 {
         /* 1:1:3:1:1 patterns -> N[2] */
-        int x, y, flip;
+        size_t x, y;
+        int flip;
         int count = 0;
 
         for (flip = 0; flip <= 1; ++flip) {
@@ -469,7 +471,7 @@ static int count_locators(const struct qr_bitmap * bmp)
 static int calc_bw_balance(const struct qr_bitmap * bmp)
 {
         /* Calculate the proportion (in percent) of "on" bits */
-        int x, y;
+        size_t x, y;
         unsigned char bit;
         long on, total;
 
diff --git a/lpg/libqr/code-layout.c b/lpg/libqr/code-layout.c
index 8b4522d..fe8caa7 100644
--- a/lpg/libqr/code-layout.c
+++ b/lpg/libqr/code-layout.c
@@ -21,11 +21,11 @@ struct qr_iterator {
 
 void qr_layout_init_mask(struct qr_code * code)
 {
-        int x, y;
-        int dim = qr_code_width(code);
+        size_t x, y;
+        size_t dim = qr_code_width(code);
         struct qr_bitmap * bmp = code->modules;
         const int * am_pos = QR_ALIGNMENT_LOCATION[code->version - 1];
-        int am_side;
+        size_t am_side;
 
         if (!bmp->mask)
                 qr_bitmap_add_mask(bmp);
diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index d4a2538..3fca4b2 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -111,7 +111,7 @@ static int read_bits(const struct qr_code * code,
         const size_t total_words = total_bits / QR_WORD_BITS;
         struct qr_bitstream * raw_bits;
         struct qr_iterator * layout;
-        int w;
+        size_t w;
         int ret = -1;
 
         raw_bits = qr_bitstream_create();
@@ -292,7 +292,7 @@ cleanup:
         return status;
 }
 
-int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask)
+int qr_decode_format(unsigned long bits, enum qr_ec_level * ec, int * mask)
 {
         bits ^= QR_FORMAT_MASK;
 
diff --git a/lpg/libqr/constants.h b/lpg/libqr/constants.h
index c13ae5a..b1f7493 100644
--- a/lpg/libqr/constants.h
+++ b/lpg/libqr/constants.h
@@ -17,7 +17,7 @@ static const unsigned int QR_FORMAT_POLY = 0x537;
 static const unsigned int QR_VERSION_POLY = 0x1F25;
 
 /* A QR-code word is always 8 bits, but CHAR_BIT might not be */
-static const unsigned int QR_WORD_BITS = 8;
+static const int QR_WORD_BITS = 8;
 
 extern const int QR_ALIGNMENT_LOCATION[40][7];
 extern const int QR_DATA_WORD_COUNT[40][4];
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index 9d6c384..6437bc1 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -175,7 +175,7 @@ static int calc_min_version(enum qr_data_type type,
 
         for (version = 1; version <= 40; ++version) {
                 if (4 + dbits + qr_data_size_field_length(version, type)
-                    < 8 * QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1])
+                    < 8 * (size_t) QR_DATA_WORD_COUNT[version - 1][ec ^ 0x1])
                         return version;
         }
 
diff --git a/lpg/libqr/galois.c b/lpg/libqr/galois.c
index f0aadfd..decefb0 100644
--- a/lpg/libqr/galois.c
+++ b/lpg/libqr/galois.c
@@ -83,7 +83,7 @@ struct qr_bitstream * rs_generate_words(struct qr_bitstream * data,
         unsigned int * b = 0;
         unsigned int * g;
         size_t n = rs_words;
-        int i, r;
+        size_t i, r;
 
         assert(qr_bitstream_remaining(data) >= data_words * 8);
 
diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h
index 36c56b3..d4af471 100644
--- a/lpg/libqr/qr/bitmap.h
+++ b/lpg/libqr/qr/bitmap.h
@@ -8,7 +8,7 @@ struct qr_bitmap {
         size_t width, height;
 };
 
-struct qr_bitmap * qr_bitmap_create(int width, int height, int masked);
+struct qr_bitmap * qr_bitmap_create(size_t width, size_t height, int masked);
 void qr_bitmap_destroy(struct qr_bitmap *);
 
 int qr_bitmap_add_mask(struct qr_bitmap *);
@@ -19,9 +19,9 @@ 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,
+                      int                      mod_bits,
                       size_t                   line_stride,
-                      size_t                   line_repeat,
+                      int                      line_repeat,
                       unsigned long            mark,
                       unsigned long            space);
 
diff --git a/lpg/libqr/qr/bitstream.h b/lpg/libqr/qr/bitstream.h
index 5ca6b41..9bd8261 100644
--- a/lpg/libqr/qr/bitstream.h
+++ b/lpg/libqr/qr/bitstream.h
@@ -22,21 +22,21 @@ size_t qr_bitstream_tell(const struct qr_bitstream *);
 size_t qr_bitstream_remaining(const struct qr_bitstream *);
 size_t qr_bitstream_size(const struct qr_bitstream *);
 
-unsigned int qr_bitstream_read(struct qr_bitstream *, size_t bits);
+unsigned long qr_bitstream_read(struct qr_bitstream *, int bits);
 
 void qr_bitstream_unpack(struct qr_bitstream *,
                          unsigned int * result,
                          size_t         count,
-                         size_t         bitsize);
+                         int            bitsize);
 
 int qr_bitstream_write(struct qr_bitstream *,
-                       unsigned int value,
-                       size_t       bits);
+                       unsigned long value,
+                       int bits);
 
 int qr_bitstream_pack(struct qr_bitstream *,
                       const unsigned int * values,
                       size_t               count,
-                      size_t               bitsize);
+                      int                  bitsize);
 
 int qr_bitstream_cat(struct qr_bitstream *,
                      const struct qr_bitstream * src);
diff --git a/lpg/libqr/qr/parse.h b/lpg/libqr/qr/parse.h
index d7b8c4e..07a0424 100644
--- a/lpg/libqr/qr/parse.h
+++ b/lpg/libqr/qr/parse.h
@@ -9,7 +9,7 @@ int qr_code_parse(const void *      buffer,
                   size_t            line_count,
                   struct qr_data ** data);
 
-int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask);
+int qr_decode_format(unsigned long bits, enum qr_ec_level * ec, int * mask);
 int qr_decode_version(unsigned long bits, int * version);
 
 #endif
diff --git a/lpg/libqr/qrgen.c b/lpg/libqr/qrgen.c
index 6098231..3007011 100644
--- a/lpg/libqr/qrgen.c
+++ b/lpg/libqr/qrgen.c
@@ -100,7 +100,7 @@ void output_ansi(const struct qr_bitmap * bmp)
         };
 
         unsigned char * line;
-        int x, y;
+        size_t x, y;
 
         line = bmp->bits;
 
-- 
cgit v1.2.3-70-g09d2


From a2683d2ecbd9dadf115fe2143c17ef8a14b86eda Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Tue, 19 Jul 2011 13:04:24 +0900
Subject: Remove debug noise

---
 lpg/libqr/code-create.c | 26 --------------------------
 1 file changed, 26 deletions(-)

(limited to 'lpg/libqr/code-create.c')

diff --git a/lpg/libqr/code-create.c b/lpg/libqr/code-create.c
index f9d86a7..f64e42d 100644
--- a/lpg/libqr/code-create.c
+++ b/lpg/libqr/code-create.c
@@ -28,23 +28,6 @@ static int draw_format(struct qr_bitmap * bmp,
 static unsigned int calc_format_bits(enum qr_ec_level ec, int mask);
 static unsigned long calc_version_bits(int version);
 
-#include <stdio.h>
-static void x_dump(struct qr_bitstream * bits)
-{
-        size_t i, n;
-
-        qr_bitstream_seek(bits, 0);
-        n = qr_bitstream_size(bits);
-        for (i = 0; i < n; ++i) {
-                fprintf(stderr, "%d", (int) qr_bitstream_read(bits, 1));
-                if (i % 8 == 7)
-                        fputc(' ', stderr);
-                if ((i+1) % (7 * 8) == 0)
-                        fputc('\n', stderr);
-        }
-        fputc('\n', stderr);
-}
-
 static void setpx(struct qr_bitmap * bmp, int x, int y)
 {
         size_t off = y * bmp->stride + x / CHAR_BIT;
@@ -197,9 +180,6 @@ static struct qr_bitstream * make_data(int version,
         if (pad_data(dcopy, total_data * QR_WORD_BITS) != 0)
                 goto fail;
 
-        fputs("Pad data:\n", stderr);
-        x_dump(dcopy);
-
         /* Make space for the RS blocks */
         blocks = malloc(total_blocks * sizeof(*blocks));
         if (!blocks)
@@ -209,7 +189,6 @@ static struct qr_bitstream * make_data(int version,
 
         /* Generate RS codewords */
         qr_bitstream_seek(dcopy, 0);
-        fputs("Generate RS blocks:\n", stderr);
         for (i = 0; i < total_blocks; ++i) {
                 int type = (i >= block_count[0]);
                 blocks[i] = rs_generate_words(dcopy,
@@ -222,7 +201,6 @@ static struct qr_bitstream * make_data(int version,
                         blocks = 0;
                         goto fail;
                 }
-                x_dump(blocks[i]);
         }
 
         /* Finally, write everything out in the correct order */
@@ -247,8 +225,6 @@ static struct qr_bitstream * make_data(int version,
 
         qr_bitstream_write(out, 0, total_bits % QR_WORD_BITS);
 
-        fputs("Final bitstream:\n", stderr);
-        x_dump(out);
 exit:
         if (blocks) {
                 while (total_blocks--)
@@ -336,7 +312,6 @@ static int mask_data(struct qr_code * code)
                 }
                 qr_mask_apply(test, i);
                 score = score_mask(test);
-                fprintf(stderr, "mask %d scored %d\n", i, score);
                 if (!mask || score < best) {
                         best = score;
                         selected = i;
@@ -346,7 +321,6 @@ static int mask_data(struct qr_code * code)
                         qr_bitmap_destroy(test);
                 }
         }
-        fprintf(stderr, "Selected mask %d (%d)\n", selected, best);
 
         qr_bitmap_destroy(code->modules);
         code->modules = mask;
-- 
cgit v1.2.3-70-g09d2