diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index b5456339..74517561 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -7,7 +7,7 @@ find_package(PNG) set(zint_COMMON_SRCS common.c library.c ps.c large.c reedsol.c gs1.c svg.c) set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c) set(zint_POSTAL_SRCS postal.c auspost.c imail.c) -set(zint_TWODIM_SRCS code16k.c blockf.c dmatrix.c dm200.c pdf417.c qr.c qrrs.c micqr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c) +set(zint_TWODIM_SRCS code16k.c blockf.c dmatrix.c dm200.c pdf417.c qr.c micqr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c) set(zint_SRCS ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS} ) if(PNG_FOUND) diff --git a/backend/Makefile b/backend/Makefile index 5dfd9a14..863657ca 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -20,15 +20,15 @@ DESTDIR := COMMON:= common.c png.c library.c ps.c large.c reedsol.c gs1.c svg.c COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o -ONEDIM:= code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c qrrs.c -ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o qrrs.o +ONEDIM:= code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c +ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o POSTAL:= postal.c auspost.c imail.c POSTAL_OBJ:= postal.o auspost.o imail.o TWODIM:= code16k.c blockf.c dmatrix.c dm200.c pdf417.c qr.c maxicode.c composite.c aztec.c micqr.c code49.c code1.c gridmtx.c TWODIM_OBJ:= code16k.o blockf.o dmatrix.o dm200.o pdf417.o qr.o maxicode.o composite.o aztec.o micqr.o code49.o code1.o gridmtx.o LIBS:= `libpng12-config --I_opts --L_opts --ldflags` -lz -lm -libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c qrrs.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c aztec.c blockf.c micqr.c gs1.c svg.c code49.c code1.c gridmtx.c +libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c aztec.c blockf.c micqr.c gs1.c svg.c code49.c code1.c gridmtx.c $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(ONEDIM) $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(POSTAL) $(CC) -Wall -fPIC $(CFLAGS) $(ZINT_VERSION) -c $(TWODIM) diff --git a/backend/Makefile.mingw b/backend/Makefile.mingw index 03de27d4..c56c603d 100644 --- a/backend/Makefile.mingw +++ b/backend/Makefile.mingw @@ -26,7 +26,7 @@ DLL:=$(APP).dll STATLIB:=lib$(APP).a COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o -ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o qrrs.o +ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o POSTAL_OBJ:= postal.o auspost.o imail.o TWODIM_OBJ:= code16k.o blockf.o dmatrix.o dm200.o pdf417.o qr.o maxicode.o composite.o aztec.o micqr.o code49.o code1.o gridmtx.o diff --git a/backend/micqr.c b/backend/micqr.c index 8356ec6a..043800aa 100644 --- a/backend/micqr.c +++ b/backend/micqr.c @@ -271,20 +271,20 @@ void versionm1(char binary_data[], unsigned char source[], int length) /* Calculate Reed-Solomon error codewords */ rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 1); + rs_init_code(ecc_codewords, 0); rs_encode(data_codewords,data_blocks,ecc_blocks); rs_free(); /* Add Reed-Solomon codewords to binary data */ for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[i] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } } return; @@ -363,20 +363,20 @@ void versionm2(char binary_data[], unsigned char source[], int length, int char_ /* Calculate Reed-Solomon error codewords */ rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 1); + rs_init_code(ecc_codewords, 0); rs_encode(data_codewords,data_blocks,ecc_blocks); rs_free(); /* Add Reed-Solomon codewords to binary data */ for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[i] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } } return; @@ -501,20 +501,20 @@ void versionm3(char binary_data[], unsigned char source[], int length, int char_ /* Calculate Reed-Solomon error codewords */ rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 1); + rs_init_code(ecc_codewords, 0); rs_encode(data_codewords,data_blocks,ecc_blocks); rs_free(); /* Add Reed-Solomon codewords to binary data */ for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[i] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } } return; @@ -613,20 +613,20 @@ void versionm4(char binary_data[], unsigned char source[], int length, int char_ /* Calculate Reed-Solomon error codewords */ rs_init_gf(0x11d); - rs_init_code(ecc_codewords, 1); + rs_init_code(ecc_codewords, 0); rs_encode(data_codewords,data_blocks,ecc_blocks); rs_free(); /* Add Reed-Solomon codewords to binary data */ for(i = 0; i < ecc_codewords; i++) { - if(ecc_blocks[i] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } - if(ecc_blocks[i] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x80) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x40) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x20) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x10) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x08) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x04) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x02) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } + if(ecc_blocks[ecc_codewords - i - 1] & 0x01) { concat(binary_data, "1"); } else { concat(binary_data, "0"); } } return; @@ -644,13 +644,15 @@ int microqr(struct zint_symbol *symbol, unsigned char source[], int length) char pattern_bit; int width, i, j, pattern_no; int sum1, sum2, evaluation[4], format, format_full, kanji; - char formatstr[16]; #ifndef _MSC_VER unsigned char local_source[length + 1]; #else unsigned char* local_source = (unsigned char*)_alloca(length + 1); #endif + for(i = 0; i < length; i++) { + local_source[i] = source[i]; + } /* Analise input data and select encoding method - zint does not attempt to optimise the symbol by switching encoding method part way through the symbol, @@ -659,7 +661,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[], int length) symbol_size = 0; for(i = 0; i < length; i++) { - if(source[i] == '\0') { + if(local_source[i] == '\0') { strcpy(symbol->errtxt, "QR Code not yet able to handle NULL characters"); return ERROR_INVALID_DATA; } @@ -906,30 +908,21 @@ int microqr(struct zint_symbol *symbol, unsigned char source[], int length) format += pattern_no; format_full = tablec1[format]; - strcpy(formatstr, ""); - if(format_full & 0x2000) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x1000) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x800) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x400) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x200) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x100) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x80) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x80) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x40) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x20) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x10) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x08) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x04) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x02) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - if(format_full & 0x01) { concat(formatstr, "1"); } else { concat(formatstr, "0"); } - - /* Add format data to symbol */ - for(i = 0; i < 8; i++) { - candidate[i + 1][8] = formatstr[i]; - } - for(i = 0; i < 7; i++) { - candidate[8][7 - i] = formatstr[i + 8]; - } + if(format_full & 0x4000) { candidate[8][1] = '1'; } + if(format_full & 0x2000) { candidate[8][2] = '1'; } + if(format_full & 0x1000) { candidate[8][3] = '1'; } + if(format_full & 0x800) { candidate[8][4] = '1'; } + if(format_full & 0x400) { candidate[8][5] = '1'; } + if(format_full & 0x200) { candidate[8][6] = '1'; } + if(format_full & 0x100) { candidate[8][7] = '1'; } + if(format_full & 0x80) { candidate[8][8] = '1'; } + if(format_full & 0x40) { candidate[7][8] = '1'; } + if(format_full & 0x20) { candidate[6][8] = '1'; } + if(format_full & 0x10) { candidate[5][8] = '1'; } + if(format_full & 0x08) { candidate[4][8] = '1'; } + if(format_full & 0x04) { candidate[3][8] = '1'; } + if(format_full & 0x02) { candidate[2][8] = '1'; } + if(format_full & 0x01) { candidate[1][8] = '1'; } /* Add timer pattern */ for(i = 0; i < width; i += 2) { diff --git a/backend/qr.c b/backend/qr.c index be87a1a7..903d7e16 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -27,7 +27,7 @@ #include #include "sjis.h" #include "qr.h" -#include "qrrs.h" +#include "reedsol.h" int in_alpha(int glyph) { /* Returns true if input glyph is in the Alphanumeric set */ @@ -506,8 +506,7 @@ void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int b int qty_long_blocks = data_cw % blocks; int qty_short_blocks = blocks - qty_long_blocks; int ecc_block_length = ecc_cw / blocks; - int i, j, length_this_block, posn, debug = 0; - RS *rs; + int i, j, length_this_block, posn, debug = 1; #ifndef _MSC_VER @@ -535,8 +534,10 @@ void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int b data_block[j] = (unsigned char) datastream[posn + j]; } - rs = init_rs(8, 0x11d, 0, 1, ecc_block_length, 255 - length_this_block - ecc_block_length); - encode_rs_char(rs, data_block, ecc_block); + rs_init_gf(0x11d); + rs_init_code(ecc_block_length, 0); + rs_encode(length_this_block, data_block, ecc_block); + rs_free(); if(debug) { printf("Block %d: ", i + 1); @@ -548,7 +549,7 @@ void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int b } printf(" // "); for(j = 0; j < ecc_block_length; j++) { - printf("%2X ", ecc_block[j]); + printf("%2X ", ecc_block[ecc_block_length - j - 1]); } printf("\n"); } @@ -562,12 +563,11 @@ void add_ecc(int fullstream[], int datastream[], int version, int data_cw, int b } for(j = 0; j < ecc_block_length; j++) { - interleaved_ecc[(j * blocks) + i] = (int) ecc_block[j]; + interleaved_ecc[(j * blocks) + i] = (int) ecc_block[ecc_block_length - j - 1]; } posn += length_this_block; } - free_rs_cache(); for(j = 0; j < data_cw; j++) { fullstream[j] = interleaved_data[j]; diff --git a/backend/qrrs.c b/backend/qrrs.c deleted file mode 100644 index e85ae20c..00000000 --- a/backend/qrrs.c +++ /dev/null @@ -1,311 +0,0 @@ -/* qrrs.c - Reed Solomon routines for QR Code - - This file pinched wholesale from libqrencode and unchanged hence - original copyright and license applies as below -*/ - -/* - * qrencode - QR Code encoder - * - * Reed solomon encoder. This code is taken from Phil Karn's libfec then - * editted and packed into a pair of .c and .h files. - * - * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q - * (libfec is released under the GNU Lesser General Public License.) - * - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "qrrs.h" - -/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs - * - */ -typedef unsigned char data_t; - - -/** - * Reed-Solomon codec control block - */ -struct _RS { - int mm; /* Bits per symbol */ - int nn; /* Symbols per block (= (1<= rs->nn) { - x -= rs->nn; - x = (x >> rs->mm) + (x & rs->nn); - } - return x; -} - - -#define MODNN(x) modnn(rs,x) - -#define MM (rs->mm) -#define NN (rs->nn) -#define ALPHA_TO (rs->alpha_to) -#define INDEX_OF (rs->index_of) -#define GENPOLY (rs->genpoly) -#define NROOTS (rs->nroots) -#define FCR (rs->fcr) -#define PRIM (rs->prim) -#define IPRIM (rs->iprim) -#define PAD (rs->pad) -#define A0 (NN) - - -/* Initialize a Reed-Solomon codec - * symsize = symbol size, bits - * gfpoly = Field generator polynomial coefficients - * fcr = first root of RS code generator polynomial, index form - * prim = primitive element to generate polynomial roots - * nroots = RS code generator polynomial degree (number of roots) - * pad = padding bytes at front of shortened block - */ -static RS *init_rs_char(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) -{ - RS *rs; - - -/* Common code for intializing a Reed-Solomon control block (char or int symbols) - * Copyright 2004 Phil Karn, KA9Q - * May be used under the terms of the GNU Lesser General Public License (LGPL) - */ -//#undef NULL -//#define NULL ((void *)0) - - int i, j, sr,root,iprim; - - rs = NULL; - /* Check parameter ranges */ - if(symsize < 0 || symsize > (int)(8*sizeof(data_t))){ - goto done; - } - - if(fcr < 0 || fcr >= (1<= (1<= (1<= ((1<mm = symsize; - rs->nn = (1<pad = pad; - - rs->alpha_to = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); - if(rs->alpha_to == NULL){ - free(rs); - rs = NULL; - goto done; - } - rs->index_of = (data_t *)malloc(sizeof(data_t)*(rs->nn+1)); - if(rs->index_of == NULL){ - free(rs->alpha_to); - free(rs); - rs = NULL; - goto done; - } - - /* Generate Galois field lookup tables */ - rs->index_of[0] = A0; /* log(zero) = -inf */ - rs->alpha_to[A0] = 0; /* alpha**-inf = 0 */ - sr = 1; - for(i=0;inn;i++){ - rs->index_of[sr] = i; - rs->alpha_to[i] = sr; - sr <<= 1; - if(sr & (1<nn; - } - if(sr != 1){ - /* field generator polynomial is not primitive! */ - free(rs->alpha_to); - free(rs->index_of); - free(rs); - rs = NULL; - goto done; - } - - /* Form RS code generator polynomial from its roots */ - rs->genpoly = (data_t *)malloc(sizeof(data_t)*(nroots+1)); - if(rs->genpoly == NULL){ - free(rs->alpha_to); - free(rs->index_of); - free(rs); - rs = NULL; - goto done; - } - rs->fcr = fcr; - rs->prim = prim; - rs->nroots = nroots; - rs->gfpoly = gfpoly; - - /* Find prim-th root of 1, used in decoding */ - for(iprim=1;(iprim % prim) != 0;iprim += rs->nn) - ; - rs->iprim = iprim / prim; - - rs->genpoly[0] = 1; - for (i = 0,root=fcr*prim; i < nroots; i++,root += prim) { - rs->genpoly[i+1] = 1; - - /* Multiply rs->genpoly[] by @**(root + x) */ - for (j = i; j > 0; j--){ - if (rs->genpoly[j] != 0) - rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)]; - else - rs->genpoly[j] = rs->genpoly[j-1]; - } - /* rs->genpoly[0] can never be zero */ - rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)]; - } - /* convert rs->genpoly[] to index form for quicker encoding */ - for (i = 0; i <= nroots; i++) - rs->genpoly[i] = rs->index_of[rs->genpoly[i]]; - done:; - - return rs; -} - -RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad) -{ - RS *rs; - - for(rs = rslist; rs != NULL; rs = rs->next) { - if(rs->pad != pad) continue; - if(rs->nroots != nroots) continue; - if(rs->mm != symsize) continue; - if(rs->gfpoly != gfpoly) continue; - if(rs->fcr != fcr) continue; - if(rs->prim != prim) continue; - - goto DONE; - } - - rs = init_rs_char(symsize, gfpoly, fcr, prim, nroots, pad); - if(rs == NULL) goto DONE; - rs->next = rslist; - rslist = rs; - -DONE: - return rs; -} - - -void free_rs_char(RS *rs) -{ - free(rs->alpha_to); - free(rs->index_of); - free(rs->genpoly); - free(rs); -} - -void free_rs_cache(void) -{ - RS *rs, *next; - - rs = rslist; - while(rs != NULL) { - next = rs->next; - free_rs_char(rs); - rs = next; - } - rslist = NULL; -} - -/* The guts of the Reed-Solomon encoder, meant to be #included - * into a function body with the following typedefs, macros and variables supplied - * according to the code parameters: - - * data_t - a typedef for the data symbol - * data_t data[] - array of NN-NROOTS-PAD and type data_t to be encoded - * data_t parity[] - an array of NROOTS and type data_t to be written with parity symbols - * NROOTS - the number of roots in the RS code generator polynomial, - * which is the same as the number of parity symbols in a block. - Integer variable or literal. - * - * NN - the total number of symbols in a RS block. Integer variable or literal. - * PAD - the number of pad symbols in a block. Integer variable or literal. - * ALPHA_TO - The address of an array of NN elements to convert Galois field - * elements in index (log) form to polynomial form. Read only. - * INDEX_OF - The address of an array of NN elements to convert Galois field - * elements in polynomial form to index (log) form. Read only. - * MODNN - a function to reduce its argument modulo NN. May be inline or a macro. - * GENPOLY - an array of NROOTS+1 elements containing the generator polynomial in index form - - * The memset() and memmove() functions are used. The appropriate header - * file declaring these functions (usually ) must be included by the calling - * program. - - * Copyright 2004, Phil Karn, KA9Q - * May be used under the terms of the GNU Lesser General Public License (LGPL) - */ - -#undef A0 -#define A0 (NN) /* Special reserved value encoding zero in index form */ - -void encode_rs_char(RS *rs, const data_t *data, data_t *parity) -{ - int i, j; - data_t feedback; - - memset(parity,0,NROOTS*sizeof(data_t)); - - for(i=0;i - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __QRRS_H__ -#define __QRRS_H__ - -/* - * General purpose RS codec, 8-bit symbols. - */ - -typedef struct _RS RS; - -/* WARNING: Thread unsafe!!! */ -extern RS *init_rs(int symsize, int gfpoly, int fcr, int prim, int nroots, int pad); -extern void encode_rs_char(RS *rs, const unsigned char *data, unsigned char *parity); -extern void free_rs_char(RS *rs); -extern void free_rs_cache(void); - -#endif /* __QRRS_H__ */