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-parse.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 lpg/libqr/code-parse.c

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

diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
new file mode 100644
index 0000000..0d3a71d
--- /dev/null
+++ b/lpg/libqr/code-parse.c
@@ -0,0 +1,12 @@
+#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,
+                               size_t       line_count)
+{
+        return 0;
+}
+
-- 
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-parse.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 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-parse.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-parse.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-parse.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-parse.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 a5c8627f3152e9604bb65fef2e71015a66c82421 Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Fri, 15 Jul 2011 14:47:28 +0900
Subject: Check return values in code-parse.c

---
 lpg/libqr/code-parse.c | 95 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 71 insertions(+), 24 deletions(-)

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

diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 7a98280..690734b 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -28,7 +28,6 @@ static int unpack_bits(int version,
                        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 */
 
         int total_words = qr_code_total_capacity(version) / 8;
@@ -36,17 +35,35 @@ static int unpack_bits(int version,
         int total_blocks;
         int i, w, block;
         struct qr_bitstream ** blocks = 0;
+        int status = -1;
 
         qr_get_rs_block_sizes(version, ec, block_count, data_length, ec_length);
         total_blocks = block_count[0] + block_count[1];
 
+        status = qr_bitstream_resize(bits_out,
+                (block_count[0] * data_length[0] +
+                 block_count[1] * data_length[1]) * 8);
+        if (status != 0)
+                goto cleanup;
+
         blocks = malloc(total_blocks * sizeof(*blocks));
-        /* XXX: check return (and below) */
+        if (blocks == NULL)
+                goto cleanup;
+
         for (i = 0; i < total_blocks; ++i)
                 blocks[i] = NULL;
 
-        for (i = 0; i < total_blocks; ++i)
+        /* Allocate temporary space for the blocks */
+        for (i = 0; i < total_blocks; ++i) {
+                int type = (i >= block_count[0]);
                 blocks[i] = qr_bitstream_create();
+                if (blocks[i] == NULL)
+                        goto cleanup;
+                status = qr_bitstream_resize(blocks[i],
+                        (data_length[type] + ec_length[type]) * 8);
+                if (status != 0)
+                        goto cleanup;
+        }
 
         /* Read in the data & EC (see spec table 19) */
 
@@ -72,11 +89,18 @@ static int unpack_bits(int version,
                 struct qr_bitstream * stream = blocks[block];
                 qr_bitstream_seek(stream, 0);
                 qr_bitstream_copy(bits_out, stream, data_length[type] * 8);
-                qr_bitstream_destroy(stream);
         }
-        free(blocks);
+        status = 0;
+
+cleanup:
+        if (blocks != NULL) {
+                for (block = 0; block < total_blocks; ++block)
+                        if (blocks[block] != NULL)
+                                qr_bitstream_destroy(blocks[block]);
+                free(blocks);
+        }
 
-        return 0;
+        return status;
 }
 
 static int read_bits(const struct qr_code * code,
@@ -88,16 +112,28 @@ static int read_bits(const struct qr_code * code,
         struct qr_bitstream * raw_bits;
         struct qr_iterator * layout;
         int w;
-        int ret;
+        int ret = -1;
 
         raw_bits = qr_bitstream_create();
+        if (raw_bits == NULL)
+                goto cleanup;
+
+        ret = qr_bitstream_resize(raw_bits, total_words * 8);
+        if (ret != 0)
+                goto cleanup;
+
         layout = qr_layout_begin((struct qr_code *) code); /* dropping const! */
+        if (layout == NULL)
+                goto cleanup;
         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);
+
+cleanup:
+        if (raw_bits != NULL)
+                qr_bitstream_destroy(raw_bits);
 
         return ret;
 }
@@ -175,11 +211,13 @@ int qr_code_parse(const void *      buffer,
                   size_t            line_count,
                   struct qr_data ** data)
 {
+        /* TODO: more informative return values for errors */
         struct qr_bitmap src_bmp;
         struct qr_code code;
         enum qr_ec_level ec;
         int mask;
         struct qr_bitstream * data_bits;
+        int status;
 
         fprintf(stderr, "parsing code bitmap %lux%lu\n", line_bits, line_count);
 
@@ -213,36 +251,45 @@ int qr_code_parse(const void *      buffer,
         fprintf(stderr, "detected ec type %d; mask %d\n", ec, mask);
 
         code.modules = qr_bitmap_clone(&src_bmp);
-        /* XXX: check return */
+        if (code.modules == NULL) {
+                status = -1;    
+                goto cleanup;
+        }
         qr_mask_apply(code.modules, mask);
 
         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;
+        if (data_bits == NULL) {
+                status = -1;
+                goto cleanup;
         }
-        */
+
+        status = read_bits(&code, ec, data_bits);
+        if (status != 0)
+                goto cleanup;
 
         *data = malloc(sizeof(*data));
-        /* XXX: check return */
+        if (*data == NULL) {
+                status = -1;
+                goto cleanup;
+        }
 
         (*data)->version = code.version;
         (*data)->ec = ec;
         (*data)->bits = data_bits;
         (*data)->offset = 0;
 
-        return 0;
+        data_bits = 0;
+        status = 0;
+
+cleanup:
+        if (data_bits)
+                qr_bitstream_destroy(data_bits);
+        if (code.modules)
+                qr_bitmap_destroy(code.modules);
+
+        return status;
 }
 
 int qr_decode_format(unsigned bits, enum qr_ec_level * ec, int * mask)
-- 
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-parse.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 bea5cbf43b7074fe59c400edaa294153d18fb325 Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Fri, 15 Jul 2011 15:12:53 +0900
Subject: Fix incorrect allocation size

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

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

diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 8e36a15..d4a2538 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -269,7 +269,7 @@ int qr_code_parse(const void *      buffer,
         if (status != 0)
                 goto cleanup;
 
-        *data = malloc(sizeof(*data));
+        *data = malloc(sizeof(**data));
         if (*data == NULL) {
                 status = -1;
                 goto cleanup;
-- 
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-parse.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 96433dc8cbc6242adc11f78590068f37f88cfc30 Mon Sep 17 00:00:00 2001
From: Leo Uino <leo@norisys.jp>
Date: Mon, 24 Dec 2012 21:47:33 +0900
Subject: Fixes thanks to Roland Illig

---
 lpg/libqr/code-parse.c  |  4 ++--
 lpg/libqr/data-create.c | 20 ++++++++++++--------
 lpg/libqr/qrparse.c     |  2 +-
 3 files changed, 15 insertions(+), 11 deletions(-)

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

diff --git a/lpg/libqr/code-parse.c b/lpg/libqr/code-parse.c
index 3fca4b2..a84df72 100644
--- a/lpg/libqr/code-parse.c
+++ b/lpg/libqr/code-parse.c
@@ -216,10 +216,10 @@ int qr_code_parse(const void *      buffer,
         struct qr_code code;
         enum qr_ec_level ec;
         int mask;
-        struct qr_bitstream * data_bits;
+        struct qr_bitstream * data_bits = NULL;
         int status;
 
-        fprintf(stderr, "parsing code bitmap %lux%lu\n", line_bits, line_count);
+        fprintf(stderr, "parsing code bitmap %lux%lu\n", (unsigned long) line_bits, (unsigned long) line_count);
 
         if (line_bits != line_count
             || line_bits < 21
diff --git a/lpg/libqr/data-create.c b/lpg/libqr/data-create.c
index 8ab127d..09d6653 100644
--- a/lpg/libqr/data-create.c
+++ b/lpg/libqr/data-create.c
@@ -19,7 +19,7 @@ static void write_type_and_length(struct qr_data *  data,
 }
 
 static struct qr_data * encode_numeric(struct qr_data * data,
-                                       const char *     input,
+                                       const unsigned char * input,
                                        size_t           length)
 {
         struct qr_bitstream * stream = data->bits;
@@ -92,7 +92,7 @@ static int get_alpha_code(char c)
 }
 
 static struct qr_data * encode_alpha(struct qr_data * data,
-                                     const char *     input,
+                                     const unsigned char * input,
                                      size_t           length)
 {
         struct qr_bitstream * stream = data->bits;
@@ -135,7 +135,7 @@ static struct qr_data * encode_alpha(struct qr_data * data,
 }
 
 static struct qr_data * encode_8bit(struct qr_data * data,
-                                    const char *     input,
+                                    const unsigned char * input,
                                     size_t           length)
 {
         struct qr_bitstream * stream = data->bits;
@@ -158,7 +158,7 @@ static struct qr_data * encode_8bit(struct qr_data * data,
 }
 
 static struct qr_data * encode_kanji(struct qr_data * data,
-                                     const char *     input,
+                                     const unsigned char * input,
                                      size_t           length)
 {
         return 0;
@@ -213,13 +213,17 @@ struct qr_data * qr_data_create(int               version,
 
                 switch (type) {
                 case QR_DATA_NUMERIC:
-                        ret = encode_numeric(data, input, length); break;
+                        ret = encode_numeric(data, (const unsigned char *) input, length);
+                        break;
                 case QR_DATA_ALPHA:
-                        ret = encode_alpha(data, input, length); break;
+                        ret = encode_alpha(data, (const unsigned char *) input, length);
+                        break;
                 case QR_DATA_8BIT:
-                        ret = encode_8bit(data, input, length); break;
+                        ret = encode_8bit(data, (const unsigned char *) input, length);
+                        break;
                 case QR_DATA_KANJI:
-                        ret = encode_kanji(data, input, length); break;
+                        ret = encode_kanji(data, (const unsigned char *) input, length);
+                        break;
                 default:
                         /* unsupported / invalid */
                         ret = 0;
diff --git a/lpg/libqr/qrparse.c b/lpg/libqr/qrparse.c
index 013066b..1b5c80e 100644
--- a/lpg/libqr/qrparse.c
+++ b/lpg/libqr/qrparse.c
@@ -49,7 +49,7 @@ int main(int argc, char ** argv)
                 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);
+                fprintf(stderr, "Data type: %s; %lu bytes\nContent: %s\n", type_str, (unsigned long) data_len, data_str);
                 free(data_str);
                 qr_data_destroy(data);
         }
-- 
cgit v1.2.3-70-g09d2