mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
TELEPEN: fix stop length (14 -> 12)
reedsol.c: some performance gain by stashing generated poly logs and pre-checking if has a zero coeff to avoid inner loop branch
This commit is contained in:
parent
7e3d0f2405
commit
21d015a84a
@ -30,6 +30,7 @@
|
|||||||
SUCH DAMAGE.
|
SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* vim: set ts=4 sw=4 et : */
|
/* vim: set ts=4 sw=4 et : */
|
||||||
|
#include <assert.h>
|
||||||
#ifdef ZINT_TEST
|
#ifdef ZINT_TEST
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
@ -230,6 +231,7 @@ INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int le
|
|||||||
|
|
||||||
for (reader = 0; reader < length; reader++) {
|
for (reader = 0; reader < length; reader++) {
|
||||||
num = ctoi(data[reader]);
|
num = ctoi(data[reader]);
|
||||||
|
assert(num >= 0);
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
if (latch) {
|
if (latch) {
|
||||||
set_module(symbol, row, writer);
|
set_module(symbol, row, writer);
|
||||||
|
@ -91,7 +91,7 @@ INTERNAL void rs_init_gf(rs_t *rs, const unsigned int prime_poly) {
|
|||||||
|
|
||||||
/* Using bits 9-6 as hash to save a few cycles */
|
/* Using bits 9-6 as hash to save a few cycles */
|
||||||
/* Alter this hash or just iterate if new prime poly added that doesn't fit */
|
/* Alter this hash or just iterate if new prime poly added that doesn't fit */
|
||||||
unsigned int hash = prime_poly >> 5;
|
const unsigned int hash = prime_poly >> 5;
|
||||||
|
|
||||||
rs->logt = data[hash].logt;
|
rs->logt = data[hash].logt;
|
||||||
rs->alog = data[hash].alog;
|
rs->alog = data[hash].alog;
|
||||||
@ -109,6 +109,7 @@ INTERNAL void rs_init_code(rs_t *rs, const int nsym, int index) {
|
|||||||
const unsigned char *const logt = rs->logt;
|
const unsigned char *const logt = rs->logt;
|
||||||
const unsigned char *const alog = rs->alog;
|
const unsigned char *const alog = rs->alog;
|
||||||
unsigned char *rspoly = rs->rspoly;
|
unsigned char *rspoly = rs->rspoly;
|
||||||
|
unsigned char *log_rspoly = rs->log_rspoly;
|
||||||
|
|
||||||
rs->nsym = nsym;
|
rs->nsym = nsym;
|
||||||
|
|
||||||
@ -123,6 +124,13 @@ INTERNAL void rs_init_code(rs_t *rs, const int nsym, int index) {
|
|||||||
rspoly[0] = alog[logt[rspoly[0]] + index]; /* 2**(i + (i+1) + ... + index) */
|
rspoly[0] = alog[logt[rspoly[0]] + index]; /* 2**(i + (i+1) + ... + index) */
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set logs of poly and check if have zero coeffs */
|
||||||
|
rs->zero = 0;
|
||||||
|
for (i = 0; i <= nsym; i++) {
|
||||||
|
log_rspoly[i] = logt[rspoly[i]]; /* For simplicity allow log of 0 */
|
||||||
|
rs->zero |= rspoly[i] == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rs_encode(&rs, datalen, data, res) generates nsym Reed-Solomon codes (nsym as given in rs_init_code())
|
/* rs_encode(&rs, datalen, data, res) generates nsym Reed-Solomon codes (nsym as given in rs_init_code())
|
||||||
@ -132,23 +140,40 @@ INTERNAL void rs_encode(const rs_t *rs, const int datalen, const unsigned char *
|
|||||||
const unsigned char *const logt = rs->logt;
|
const unsigned char *const logt = rs->logt;
|
||||||
const unsigned char *const alog = rs->alog;
|
const unsigned char *const alog = rs->alog;
|
||||||
const unsigned char *const rspoly = rs->rspoly;
|
const unsigned char *const rspoly = rs->rspoly;
|
||||||
|
const unsigned char *const log_rspoly = rs->log_rspoly;
|
||||||
const int nsym = rs->nsym;
|
const int nsym = rs->nsym;
|
||||||
|
|
||||||
memset(res, 0, nsym);
|
memset(res, 0, nsym);
|
||||||
for (i = 0; i < datalen; i++) {
|
if (rs->zero) { /* Poly has a zero coeff so need to check in inner loop */
|
||||||
const unsigned int m = res[nsym - 1] ^ data[i];
|
for (i = 0; i < datalen; i++) {
|
||||||
if (m) {
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
const unsigned int log_m = logt[m];
|
if (m) {
|
||||||
for (k = nsym - 1; k > 0; k--) {
|
const unsigned int log_m = logt[m];
|
||||||
if (rspoly[k])
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
res[k] = (unsigned char) (res[k - 1] ^ alog[log_m + logt[rspoly[k]]]);
|
if (rspoly[k])
|
||||||
else
|
res[k] = (unsigned char) (res[k - 1] ^ alog[log_m + log_rspoly[k]]);
|
||||||
res[k] = res[k - 1];
|
else
|
||||||
|
res[k] = res[k - 1];
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, nsym - 1);
|
||||||
|
res[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { /* Avoid a branch in inner loop */
|
||||||
|
for (i = 0; i < datalen; i++) {
|
||||||
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
|
if (m) {
|
||||||
|
const unsigned int log_m = logt[m];
|
||||||
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
|
res[k] = (unsigned char) (res[k - 1] ^ alog[log_m + log_rspoly[k]]);
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, nsym - 1);
|
||||||
|
res[0] = 0;
|
||||||
}
|
}
|
||||||
res[0] = alog[log_m + logt[rspoly[0]]]; /* rspoly[0] can't be zero */
|
|
||||||
} else {
|
|
||||||
memmove(res + 1, res, nsym - 1);
|
|
||||||
res[0] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,23 +185,40 @@ INTERNAL void rs_encode_uint(const rs_t *rs, const int datalen, const unsigned i
|
|||||||
const unsigned char *const logt = rs->logt;
|
const unsigned char *const logt = rs->logt;
|
||||||
const unsigned char *const alog = rs->alog;
|
const unsigned char *const alog = rs->alog;
|
||||||
const unsigned char *const rspoly = rs->rspoly;
|
const unsigned char *const rspoly = rs->rspoly;
|
||||||
|
const unsigned char *const log_rspoly = rs->log_rspoly;
|
||||||
const int nsym = rs->nsym;
|
const int nsym = rs->nsym;
|
||||||
|
|
||||||
memset(res, 0, sizeof(unsigned int) * nsym);
|
memset(res, 0, sizeof(unsigned int) * nsym);
|
||||||
for (i = 0; i < datalen; i++) {
|
if (rs->zero) { /* Poly has a zero coeff so need to check in inner loop */
|
||||||
const unsigned int m = res[nsym - 1] ^ data[i];
|
for (i = 0; i < datalen; i++) {
|
||||||
if (m) {
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
const unsigned int log_m = logt[m];
|
if (m) {
|
||||||
for (k = nsym - 1; k > 0; k--) {
|
const unsigned int log_m = logt[m];
|
||||||
if (rspoly[k])
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
res[k] = res[k - 1] ^ alog[log_m + logt[rspoly[k]]];
|
if (rspoly[k])
|
||||||
else
|
res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]];
|
||||||
res[k] = res[k - 1];
|
else
|
||||||
|
res[k] = res[k - 1];
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
||||||
|
res[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { /* Avoid a branch in inner loop */
|
||||||
|
for (i = 0; i < datalen; i++) {
|
||||||
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
|
if (m) {
|
||||||
|
const unsigned int log_m = logt[m];
|
||||||
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
|
res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]];
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
||||||
|
res[0] = 0;
|
||||||
}
|
}
|
||||||
res[0] = alog[log_m + logt[rspoly[0]]];
|
|
||||||
} else {
|
|
||||||
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
|
||||||
res[0] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,9 +265,10 @@ INTERNAL int rs_uint_init_gf(rs_uint_t *rs_uint, const unsigned int prime_poly,
|
|||||||
|
|
||||||
INTERNAL void rs_uint_init_code(rs_uint_t *rs_uint, const int nsym, int index) {
|
INTERNAL void rs_uint_init_code(rs_uint_t *rs_uint, const int nsym, int index) {
|
||||||
int i, k;
|
int i, k;
|
||||||
const unsigned int *logt = rs_uint->logt;
|
const unsigned int *const logt = rs_uint->logt;
|
||||||
const unsigned int *alog = rs_uint->alog;
|
const unsigned int *const alog = rs_uint->alog;
|
||||||
unsigned short *rspoly = rs_uint->rspoly;
|
unsigned short *rspoly = rs_uint->rspoly;
|
||||||
|
unsigned int *log_rspoly = rs_uint->log_rspoly;
|
||||||
|
|
||||||
if (logt == NULL || alog == NULL) {
|
if (logt == NULL || alog == NULL) {
|
||||||
return;
|
return;
|
||||||
@ -243,34 +286,58 @@ INTERNAL void rs_uint_init_code(rs_uint_t *rs_uint, const int nsym, int index) {
|
|||||||
rspoly[0] = alog[(logt[rspoly[0]] + index)];
|
rspoly[0] = alog[(logt[rspoly[0]] + index)];
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set logs of poly and check if have zero coeffs */
|
||||||
|
rs_uint->zero = 0;
|
||||||
|
for (i = 0; i <= nsym; i++) {
|
||||||
|
log_rspoly[i] = logt[rspoly[i]]; /* For simplicity allow log of 0 */
|
||||||
|
rs_uint->zero |= rspoly[i] == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void rs_uint_encode(const rs_uint_t *rs_uint, const int datalen, const unsigned int *data,
|
INTERNAL void rs_uint_encode(const rs_uint_t *rs_uint, const int datalen, const unsigned int *data,
|
||||||
unsigned int *res) {
|
unsigned int *res) {
|
||||||
int i, k;
|
int i, k;
|
||||||
const unsigned int *logt = rs_uint->logt;
|
const unsigned int *const logt = rs_uint->logt;
|
||||||
const unsigned int *alog = rs_uint->alog;
|
const unsigned int *const alog = rs_uint->alog;
|
||||||
const unsigned short *rspoly = rs_uint->rspoly;
|
const unsigned short *const rspoly = rs_uint->rspoly;
|
||||||
|
const unsigned int *const log_rspoly = rs_uint->log_rspoly;
|
||||||
const int nsym = rs_uint->nsym;
|
const int nsym = rs_uint->nsym;
|
||||||
|
|
||||||
memset(res, 0, sizeof(unsigned int) * nsym);
|
memset(res, 0, sizeof(unsigned int) * nsym);
|
||||||
if (logt == NULL || alog == NULL) {
|
if (logt == NULL || alog == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i = 0; i < datalen; i++) {
|
if (rs_uint->zero) { /* Poly has a zero coeff so need to check in inner loop */
|
||||||
const unsigned int m = res[nsym - 1] ^ data[i];
|
for (i = 0; i < datalen; i++) {
|
||||||
if (m) {
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
const unsigned int log_m = logt[m];
|
if (m) {
|
||||||
for (k = nsym - 1; k > 0; k--) {
|
const unsigned int log_m = logt[m];
|
||||||
if (rspoly[k])
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
res[k] = res[k - 1] ^ alog[log_m + logt[rspoly[k]]];
|
if (rspoly[k])
|
||||||
else
|
res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]];
|
||||||
res[k] = res[k - 1];
|
else
|
||||||
|
res[k] = res[k - 1];
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
||||||
|
res[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { /* Avoid a branch in inner loop */
|
||||||
|
for (i = 0; i < datalen; i++) {
|
||||||
|
const unsigned int m = res[nsym - 1] ^ data[i];
|
||||||
|
if (m) {
|
||||||
|
const unsigned int log_m = logt[m];
|
||||||
|
for (k = nsym - 1; k > 0; k--) {
|
||||||
|
res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]];
|
||||||
|
}
|
||||||
|
res[0] = alog[log_m + log_rspoly[0]];
|
||||||
|
} else {
|
||||||
|
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
||||||
|
res[0] = 0;
|
||||||
}
|
}
|
||||||
res[0] = alog[log_m + logt[rspoly[0]]];
|
|
||||||
} else {
|
|
||||||
memmove(res + 1, res, sizeof(unsigned int) * (nsym - 1));
|
|
||||||
res[0] = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
*/
|
*/
|
||||||
/* vim: set ts=4 sw=4 et : */
|
/* vim: set ts=4 sw=4 et : */
|
||||||
|
|
||||||
#ifndef __REEDSOL_H
|
#ifndef Z_REEDSOL_H
|
||||||
#define __REEDSOL_H
|
#define Z_REEDSOL_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -41,15 +41,19 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
const unsigned char *logt; /* These are static */
|
const unsigned char *logt; /* These are static */
|
||||||
const unsigned char *alog;
|
const unsigned char *alog;
|
||||||
unsigned char rspoly[256];
|
unsigned char rspoly[256]; /* Generated poly */
|
||||||
int nsym;
|
unsigned char log_rspoly[256]; /* Logs of poly */
|
||||||
|
int nsym; /* Degree of poly */
|
||||||
|
int zero; /* Set if poly has a zero coeff */
|
||||||
} rs_t;
|
} rs_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int *logt; /* These are malloced */
|
unsigned int *logt; /* These are malloced */
|
||||||
unsigned int *alog;
|
unsigned int *alog;
|
||||||
unsigned short rspoly[4096]; /* 12-bit max - needs to be enlarged if > 12-bit used */
|
unsigned short rspoly[4096]; /* Generated poly, 12-bit max - needs to be enlarged if > 12-bit used */
|
||||||
int nsym;
|
unsigned int log_rspoly[4096]; /* Logs of poly */
|
||||||
|
int nsym; /* Degree of poly */
|
||||||
|
int zero; /* Set if poly has a zero coeff */
|
||||||
} rs_uint_t;
|
} rs_uint_t;
|
||||||
|
|
||||||
INTERNAL void rs_init_gf(rs_t *rs, const unsigned int prime_poly);
|
INTERNAL void rs_init_gf(rs_t *rs, const unsigned int prime_poly);
|
||||||
@ -68,4 +72,4 @@ INTERNAL void rs_uint_free(rs_uint_t *rs_uint);
|
|||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif /* __REEDSOL_H */
|
#endif /* Z_REEDSOL_H */
|
||||||
|
@ -125,8 +125,8 @@ INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], int src
|
|||||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
||||||
|
|
||||||
/* Stop character */
|
/* Stop character */
|
||||||
memcpy(d, TeleTable['z'], 14);
|
memcpy(d, TeleTable['z'], 12);
|
||||||
d += 14;
|
d += 12;
|
||||||
|
|
||||||
expand(symbol, dest, d - dest);
|
expand(symbol, dest, d - dest);
|
||||||
|
|
||||||
@ -210,8 +210,8 @@ INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], int
|
|||||||
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
if (symbol->debug & ZINT_DEBUG_PRINT) printf("Check digit: %d\n", check_digit);
|
||||||
|
|
||||||
/* Stop character */
|
/* Stop character */
|
||||||
memcpy(d, TeleTable['z'], 14);
|
memcpy(d, TeleTable['z'], 12);
|
||||||
d += 14;
|
d += 12;
|
||||||
|
|
||||||
expand(symbol, dest, d - dest);
|
expand(symbol, dest, d - dest);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user