diff --git a/backend/common.c b/backend/common.c index 6ef09dda..014cb652 100644 --- a/backend/common.c +++ b/backend/common.c @@ -30,6 +30,7 @@ SUCH DAMAGE. */ /* vim: set ts=4 sw=4 et : */ +#include #ifdef ZINT_TEST #include #endif @@ -230,6 +231,7 @@ INTERNAL void expand(struct zint_symbol *symbol, const char data[], const int le for (reader = 0; reader < length; reader++) { num = ctoi(data[reader]); + assert(num >= 0); for (i = 0; i < num; i++) { if (latch) { set_module(symbol, row, writer); diff --git a/backend/reedsol.c b/backend/reedsol.c index 67924224..6c884958 100644 --- a/backend/reedsol.c +++ b/backend/reedsol.c @@ -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 */ /* 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->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 alog = rs->alog; unsigned char *rspoly = rs->rspoly; + unsigned char *log_rspoly = rs->log_rspoly; 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) */ 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()) @@ -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 alog = rs->alog; const unsigned char *const rspoly = rs->rspoly; + const unsigned char *const log_rspoly = rs->log_rspoly; const int nsym = rs->nsym; memset(res, 0, nsym); - 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--) { - if (rspoly[k]) - res[k] = (unsigned char) (res[k - 1] ^ alog[log_m + logt[rspoly[k]]]); - else - res[k] = res[k - 1]; + if (rs->zero) { /* Poly has a zero coeff so need to check 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--) { + if (rspoly[k]) + res[k] = (unsigned char) (res[k - 1] ^ alog[log_m + log_rspoly[k]]); + 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 alog = rs->alog; const unsigned char *const rspoly = rs->rspoly; + const unsigned char *const log_rspoly = rs->log_rspoly; const int nsym = rs->nsym; memset(res, 0, sizeof(unsigned int) * nsym); - 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--) { - if (rspoly[k]) - res[k] = res[k - 1] ^ alog[log_m + logt[rspoly[k]]]; - else - res[k] = res[k - 1]; + if (rs->zero) { /* Poly has a zero coeff so need to check 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--) { + if (rspoly[k]) + res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]]; + 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) { int i, k; - const unsigned int *logt = rs_uint->logt; - const unsigned int *alog = rs_uint->alog; + const unsigned int *const logt = rs_uint->logt; + const unsigned int *const alog = rs_uint->alog; unsigned short *rspoly = rs_uint->rspoly; + unsigned int *log_rspoly = rs_uint->log_rspoly; if (logt == NULL || alog == NULL) { 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)]; 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, unsigned int *res) { int i, k; - const unsigned int *logt = rs_uint->logt; - const unsigned int *alog = rs_uint->alog; - const unsigned short *rspoly = rs_uint->rspoly; + const unsigned int *const logt = rs_uint->logt; + const unsigned int *const alog = rs_uint->alog; + const unsigned short *const rspoly = rs_uint->rspoly; + const unsigned int *const log_rspoly = rs_uint->log_rspoly; const int nsym = rs_uint->nsym; memset(res, 0, sizeof(unsigned int) * nsym); if (logt == NULL || alog == NULL) { return; } - 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--) { - if (rspoly[k]) - res[k] = res[k - 1] ^ alog[log_m + logt[rspoly[k]]]; - else - res[k] = res[k - 1]; + if (rs_uint->zero) { /* Poly has a zero coeff so need to check 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--) { + if (rspoly[k]) + res[k] = res[k - 1] ^ alog[log_m + log_rspoly[k]]; + 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; } } } diff --git a/backend/reedsol.h b/backend/reedsol.h index 400aef30..5b6163ec 100644 --- a/backend/reedsol.h +++ b/backend/reedsol.h @@ -31,8 +31,8 @@ */ /* vim: set ts=4 sw=4 et : */ -#ifndef __REEDSOL_H -#define __REEDSOL_H +#ifndef Z_REEDSOL_H +#define Z_REEDSOL_H #ifdef __cplusplus extern "C" { @@ -41,15 +41,19 @@ extern "C" { typedef struct { const unsigned char *logt; /* These are static */ const unsigned char *alog; - unsigned char rspoly[256]; - int nsym; + unsigned char rspoly[256]; /* Generated poly */ + unsigned char log_rspoly[256]; /* Logs of poly */ + int nsym; /* Degree of poly */ + int zero; /* Set if poly has a zero coeff */ } rs_t; typedef struct { unsigned int *logt; /* These are malloced */ unsigned int *alog; - unsigned short rspoly[4096]; /* 12-bit max - needs to be enlarged if > 12-bit used */ - int nsym; + unsigned short rspoly[4096]; /* Generated poly, 12-bit max - needs to be enlarged if > 12-bit used */ + 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; 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 /* __REEDSOL_H */ +#endif /* Z_REEDSOL_H */ diff --git a/backend/telepen.c b/backend/telepen.c index 710a35d7..c4fc87f1 100644 --- a/backend/telepen.c +++ b/backend/telepen.c @@ -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); /* Stop character */ - memcpy(d, TeleTable['z'], 14); - d += 14; + memcpy(d, TeleTable['z'], 12); + d += 12; 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); /* Stop character */ - memcpy(d, TeleTable['z'], 14); - d += 14; + memcpy(d, TeleTable['z'], 12); + d += 12; expand(symbol, dest, d - dest);