aboutsummaryrefslogtreecommitdiff
path: root/lpg
diff options
context:
space:
mode:
authorLeo Uino <leo@norisys.jp>2011-07-14 14:31:07 +0900
committerLeo Uino <leo@norisys.jp>2011-07-14 14:31:07 +0900
commit9f4843d686bca0d75bee174d8249fbf72527b94a (patch)
treecbe61addaa9a05ba1477af91e9d69cbcd8d95fb5 /lpg
parent3af4ffd175dcaf8aaf735f3f9564da54c4f29403 (diff)
downloadpdf-simple-sign-9f4843d686bca0d75bee174d8249fbf72527b94a.tar.gz
pdf-simple-sign-9f4843d686bca0d75bee174d8249fbf72527b94a.tar.xz
pdf-simple-sign-9f4843d686bca0d75bee174d8249fbf72527b94a.zip
Move RS block size calculation to a separate function
Diffstat (limited to 'lpg')
-rw-r--r--lpg/libqr/code-common.c35
-rw-r--r--lpg/libqr/code-create.c37
-rw-r--r--lpg/libqr/code-parse.c33
-rw-r--r--lpg/libqr/constants.h2
-rw-r--r--lpg/libqr/qr/common.h11
5 files changed, 76 insertions, 42 deletions
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