From ce330147acca10cd66c370847bdc3e824a83a0c6 Mon Sep 17 00:00:00 2001 From: Leo Howell Date: Thu, 8 Oct 2009 16:41:56 +0900 Subject: add qrgen sample app --- lpg/libqr/qr/bitmap.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lpg/libqr/qr/bitmap.h (limited to 'lpg/libqr/qr/bitmap.h') diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h new file mode 100644 index 0000000..83e82ab --- /dev/null +++ b/lpg/libqr/qr/bitmap.h @@ -0,0 +1,27 @@ +#ifndef QR_BITMAP_H +#define QR_BITMAP_H + +struct qr_bitmap { + unsigned char * bits; + unsigned char * mask; + size_t stride; + size_t width, height; +}; + +struct qr_bitmap * qr_bitmap_create(int width, int height, int masked); +void qr_bitmap_destroy(struct qr_bitmap *); + +struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap *); + +void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src); + +void qr_bitmap_render(const struct qr_bitmap * bmp, + void * buffer, + size_t mod_bits, + size_t line_stride, + size_t line_repeat, + unsigned long mark, + unsigned long space); + +#endif + -- cgit v1.2.3-70-g09d2 From 35baea42d794bec1fd5f2200f1f6f48877c5c26c Mon Sep 17 00:00:00 2001 From: Leo Uino 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/qr/bitmap.h') 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 +#include +#include +#include +#include + +#include +#include #include +#include +#include +#include + +#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 +#include +#include + +#include +#include +#include + +#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 d4abb878df167875bb66d1e0debe853cb6b88b1b Mon Sep 17 00:00:00 2001 From: Leo Uino 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/qr/bitmap.h') 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 -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 779e729ad887c1cc967731a9634a11438d56b017 Mon Sep 17 00:00:00 2001 From: Leo Uino Date: Tue, 19 Jul 2011 12:08:33 +0900 Subject: Add C++ header protectors --- lpg/libqr/qr/bitmap.h | 8 ++++++++ lpg/libqr/qr/bitstream.h | 8 ++++++++ lpg/libqr/qr/code.h | 8 ++++++++ lpg/libqr/qr/common.h | 8 ++++++++ lpg/libqr/qr/data.h | 8 ++++++++ lpg/libqr/qr/layout.h | 8 ++++++++ lpg/libqr/qr/parse.h | 8 ++++++++ lpg/libqr/qr/types.h | 8 ++++++++ lpg/libqr/qr/version.h | 8 ++++++++ 9 files changed, 72 insertions(+) (limited to 'lpg/libqr/qr/bitmap.h') diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h index d4af471..72da07f 100644 --- a/lpg/libqr/qr/bitmap.h +++ b/lpg/libqr/qr/bitmap.h @@ -1,6 +1,10 @@ #ifndef QR_BITMAP_H #define QR_BITMAP_H +#ifdef __cplusplus +extern "C" { +#endif + struct qr_bitmap { unsigned char * bits; unsigned char * mask; @@ -25,5 +29,9 @@ void qr_bitmap_render(const struct qr_bitmap * bmp, unsigned long mark, unsigned long space); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/bitstream.h b/lpg/libqr/qr/bitstream.h index 9bd8261..aa431e8 100644 --- a/lpg/libqr/qr/bitstream.h +++ b/lpg/libqr/qr/bitstream.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * Note: when writing / reading multiple bits, the * _most_ significant bits come first in the stream. @@ -45,5 +49,9 @@ int qr_bitstream_copy(struct qr_bitstream * dest, struct qr_bitstream * src, size_t count); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/code.h b/lpg/libqr/qr/code.h index e6eb47c..0f5d49c 100644 --- a/lpg/libqr/qr/code.h +++ b/lpg/libqr/qr/code.h @@ -4,6 +4,10 @@ #include #include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + struct qr_code { int version; struct qr_bitmap * modules; @@ -13,5 +17,9 @@ struct qr_code * qr_code_create(const struct qr_data * data); void qr_code_destroy(struct qr_code *); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/common.h b/lpg/libqr/qr/common.h index 640696a..b7052ad 100644 --- a/lpg/libqr/qr/common.h +++ b/lpg/libqr/qr/common.h @@ -3,6 +3,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + void qr_mask_apply(struct qr_bitmap * bmp, int mask); size_t qr_code_total_capacity(int version); @@ -20,5 +24,9 @@ void qr_get_rs_block_sizes(int version, int data_length[2], int ec_length[2]); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/data.h b/lpg/libqr/qr/data.h index f2b4b45..06600ab 100644 --- a/lpg/libqr/qr/data.h +++ b/lpg/libqr/qr/data.h @@ -4,6 +4,10 @@ #include #include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + struct qr_data { int version; /* 1 ~ 40 */ enum qr_ec_level ec; @@ -29,5 +33,9 @@ enum qr_data_type qr_parse_data(const struct qr_data * input, char ** output, size_t * length); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/layout.h b/lpg/libqr/qr/layout.h index 49bebf6..e691bdb 100644 --- a/lpg/libqr/qr/layout.h +++ b/lpg/libqr/qr/layout.h @@ -1,6 +1,10 @@ #ifndef QR_CODE_LAYOUT_H #define QR_CODE_LAYOUT_H +#ifdef __cplusplus +extern "C" { +#endif + struct qr_iterator; void qr_layout_init_mask(struct qr_code *); @@ -10,5 +14,9 @@ unsigned int qr_layout_read(struct qr_iterator *); void qr_layout_write(struct qr_iterator *, unsigned int); void qr_layout_end(struct qr_iterator *); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/parse.h b/lpg/libqr/qr/parse.h index 07a0424..0e08354 100644 --- a/lpg/libqr/qr/parse.h +++ b/lpg/libqr/qr/parse.h @@ -3,6 +3,10 @@ #include "data.h" +#ifdef __cplusplus +extern "C" { +#endif + int qr_code_parse(const void * buffer, size_t line_bits, size_t line_stride, @@ -12,5 +16,9 @@ int qr_code_parse(const void * buffer, int qr_decode_format(unsigned long bits, enum qr_ec_level * ec, int * mask); int qr_decode_version(unsigned long bits, int * version); +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/types.h b/lpg/libqr/qr/types.h index 3615e3e..ae760ab 100644 --- a/lpg/libqr/qr/types.h +++ b/lpg/libqr/qr/types.h @@ -1,6 +1,10 @@ #ifndef QR_TYPES_H #define QR_TYPES_H +#ifdef __cplusplus +extern "C" { +#endif + struct qr_data; struct qr_code; @@ -22,5 +26,9 @@ enum qr_ec_level { QR_EC_LEVEL_H = 0x2 }; +#ifdef __cplusplus +} +#endif + #endif diff --git a/lpg/libqr/qr/version.h b/lpg/libqr/qr/version.h index cd263c0..ce540f4 100644 --- a/lpg/libqr/qr/version.h +++ b/lpg/libqr/qr/version.h @@ -1,10 +1,18 @@ #ifndef QR_VERSION_H #define QR_VERSION_H +#ifdef __cplusplus +extern "C" { +#endif + #define QR_VERSION_MAJOR 0 #define QR_VERSION_MINOR 3 #define QR_VERSION "0.3" +#ifdef __cplusplus +} +#endif + #endif -- cgit v1.2.3-70-g09d2 From eaec8202df88999e3d2fbc2755113dc03172e021 Mon Sep 17 00:00:00 2001 From: Leo Uino Date: Tue, 19 Jul 2011 15:32:19 +0900 Subject: Fix bitmap renderer --- lpg/libqr/bitmap.c | 20 +++++++++++--------- lpg/libqr/qr/bitmap.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'lpg/libqr/qr/bitmap.h') diff --git a/lpg/libqr/bitmap.c b/lpg/libqr/bitmap.c index b9d3763..1c4e38b 100644 --- a/lpg/libqr/bitmap.c +++ b/lpg/libqr/bitmap.c @@ -137,11 +137,10 @@ static void render_line_2(unsigned char * out, unsigned long space) { unsigned char in_mask; - size_t n, b, step, shift; + size_t n, b, step; in_mask = 1; step = CHAR_BIT / mod_bits; - shift = CHAR_BIT - mod_bits; n = dim; while (n > 0) { @@ -156,11 +155,9 @@ static void render_line_2(unsigned char * out, ++in; } - tmp = (tmp >> mod_bits) | (v << shift); - if (--n == 0) { - tmp >>= b * mod_bits; + tmp |= v << (b * mod_bits); + if (--n == 0) break; - } }; *out++ = tmp; @@ -170,7 +167,7 @@ static void render_line_2(unsigned char * out, void qr_bitmap_render(const struct qr_bitmap * bmp, void * buffer, int mod_bits, - size_t line_stride, + ptrdiff_t line_stride, int line_repeat, unsigned long mark, unsigned long space) @@ -188,6 +185,9 @@ void qr_bitmap_render(const struct qr_bitmap * bmp, out = buffer; dim = bmp->width; + mark &= (1 << mod_bits) - 1; + space &= (1 << mod_bits) - 1; + n = dim; while (n-- > 0) { size_t rpt; @@ -200,8 +200,10 @@ void qr_bitmap_render(const struct qr_bitmap * bmp, rpt = line_repeat; next = out + line_stride; - while (rpt-- > 0) { - memcpy(next, out, line_stride); + while (--rpt > 0) { + size_t bits = dim * mod_bits; + size_t bytes = bits / CHAR_BIT + !!(bits % CHAR_BIT); + memcpy(next, out, bytes); next += line_stride; } diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h index 72da07f..57b33e0 100644 --- a/lpg/libqr/qr/bitmap.h +++ b/lpg/libqr/qr/bitmap.h @@ -24,7 +24,7 @@ void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src); void qr_bitmap_render(const struct qr_bitmap * bmp, void * buffer, int mod_bits, - size_t line_stride, + ptrdiff_t line_stride, int line_repeat, unsigned long mark, unsigned long space); -- cgit v1.2.3-70-g09d2 From 5d4815f09b8c0caf4e152bf737036eef22aaa399 Mon Sep 17 00:00:00 2001 From: Leo Uino Date: Sat, 6 Aug 2011 11:13:19 +0900 Subject: Further bitmap fixes --- lpg/libqr/bitmap.c | 8 +++++--- lpg/libqr/qr/bitmap.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'lpg/libqr/qr/bitmap.h') diff --git a/lpg/libqr/bitmap.c b/lpg/libqr/bitmap.c index 1c4e38b..246b9bd 100644 --- a/lpg/libqr/bitmap.c +++ b/lpg/libqr/bitmap.c @@ -167,7 +167,7 @@ static void render_line_2(unsigned char * out, void qr_bitmap_render(const struct qr_bitmap * bmp, void * buffer, int mod_bits, - ptrdiff_t line_stride, + long line_stride, int line_repeat, unsigned long mark, unsigned long space) @@ -185,8 +185,10 @@ void qr_bitmap_render(const struct qr_bitmap * bmp, out = buffer; dim = bmp->width; - mark &= (1 << mod_bits) - 1; - space &= (1 << mod_bits) - 1; + if (pack) { + mark &= (1 << mod_bits) - 1; + space &= (1 << mod_bits) - 1; + } n = dim; while (n-- > 0) { diff --git a/lpg/libqr/qr/bitmap.h b/lpg/libqr/qr/bitmap.h index 57b33e0..098d9c3 100644 --- a/lpg/libqr/qr/bitmap.h +++ b/lpg/libqr/qr/bitmap.h @@ -24,7 +24,7 @@ void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src); void qr_bitmap_render(const struct qr_bitmap * bmp, void * buffer, int mod_bits, - ptrdiff_t line_stride, + long line_stride, int line_repeat, unsigned long mark, unsigned long space); -- cgit v1.2.3-70-g09d2