Mndiff-dev
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2007
- 1 participants
- 45 discussions
Author: michael
Date: Tue Jul 10 01:04:39 2007
New Revision: 86
Log:
minimalistic application using libnoe
Added:
trunk/noe/mina.c
Modified:
trunk/noe/Makefile
Modified: trunk/noe/Makefile
==============================================================================
--- trunk/noe/Makefile (original)
+++ trunk/noe/Makefile Tue Jul 10 01:04:39 2007
@@ -17,7 +17,7 @@ CFLAGS = -g -Wall -O4 $(OPTFLAGS) -I. $
%_10001.o: %.c
$(CC) $(CFLAGS) -c -DSIZE=0x10001 -o $@ $<
-all: test_100 test_101 test_10001
+all: test_100 test_101 test_10001 mina
libnoe_100.a: $(LIBOBJS:.o=_100.o)
$(AR) rc $@ $^
@@ -28,6 +28,9 @@ libnoe_101.a: $(LIBOBJS:.o=_101.o) gfft_
libnoe_10001.a: $(LIBOBJS:.o=_10001.o) gfft_10001.o
$(AR) rc $@ $^
+mina: mina.o libnoe_10001.a
+ $(CC) $(LDFLAGS) -o $@ $^
+
test: all
./test_100 ; ./test_101 ; ./test_10001
Added: trunk/noe/mina.c
==============================================================================
--- (empty file)
+++ trunk/noe/mina.c Tue Jul 10 01:04:39 2007
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <assert.h>
+
+#define SIZE 0x10001
+#include "galois.h"
+#include "rs.h"
+
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+
+static void help(){
+ printf(
+ "mina [options] <input file>\n"
+ "options:\n"
+ " e<parity size> encode\n"
+ " d decode\n"
+ " z assume large blocks of zeros are erased\n"
+ " v increase verbosity\n"
+ );
+ exit(1);
+}
+
+int64_t fsize(FILE *f){
+ int64_t i,j;
+ i=ftell(f);
+ fseek(f,0,SEEK_END);
+ j=ftell(f);
+ fseek(f,i,SEEK_SET);
+ return j;
+}
+
+/**
+ *
+ * all sizes and len in bytes
+ */
+static int read(uint8_t *buf, int64_t pos, int len, FILE *df, int64_t datasize, int64_t paddedsize, FILE *pf){
+ while(len>0){
+ int len2;
+ if(pos < datasize){
+ len2= MIN(len, datasize-pos);
+ fseek(df, pos, SEEK_SET);
+ if(fread(buf, len2, 1, df) <= 0){
+ return -1;
+ }
+ }else if(pos < paddedsize){
+ len2= paddedsize - pos;
+ memset(buf, 0, len2);
+ }else{
+ int64_t pos2= pos - paddedsize;
+ len2=len;
+ if(pf){
+ fseek(pf, pos2, SEEK_SET);
+ if(fread(buf, len2, 1, pf) <= 0){
+ return -1;
+ }
+ }else
+ memset(buf, 0, len2); //FIXME unneeded
+ }
+ pos += len2;
+ buf += len2;
+ len -= len2;
+ }
+ return 0;
+}
+
+/**
+ *
+ * all sizes and len in bytes
+ */
+static int write(uint8_t *buf, int64_t pos, int len, FILE *df, int64_t datasize, int64_t paddedsize, FILE *pf){
+ while(len>0){
+ int len2;
+ if(pos < datasize){
+ len2= MIN(len, datasize-pos);
+ if(df){
+ fseek(df, pos, SEEK_SET);
+ if(fwrite(buf, len2, 1, df) <= 0)
+ return -1;
+ }
+ }else if(pos < paddedsize){
+ len2= paddedsize - pos;
+ if(*buf) //FIXME check this at a more appropriate place and check it completely
+ return -1;
+ }else{
+ int64_t pos2= pos - paddedsize;
+ len2=len;
+ fseek(pf, pos2, SEEK_SET);
+ if(fwrite(buf, len2, 1, pf) <= 0)
+ return -1;
+ }
+ pos += len2;
+ buf += len2;
+ len -= len2;
+ }
+ return 0;
+}
+
+int main(int argc, char* argv[]){
+ FILE *df, *pf;
+ int decode=1;
+ int zero2erasure=0;
+ uint8_t buf[256];
+ int64_t datasize, paddedsize, paritysize=0;
+ int interleave, n0, n10_pos, i, j, e, i2, passes;
+ int buffersize= 256;
+ uint8_t *buffer;
+ char *tail, *s;
+ int64_t (*erasure_list)[2]= NULL;
+ int erasure_list_len=0;
+ int verbose= 0;
+
+ EXT(init)();
+
+ if(argc < 2 || argc > 3)
+ help();
+
+ if(argc==3){
+ s= argv[1];
+ for(; *s; s++){
+ switch(*s){
+ case 'd': decode=1 ; break;
+ case 'e':
+ decode=0;
+ paritysize= strtol(s+1, &tail, 0);
+ s= tail - 1;
+ break;
+ case 'z': zero2erasure=1; break;
+ case 'b':
+ buffersize= strtol(s+1, &tail, 0);
+ s= tail - 1;
+ if(buffersize <= 0){
+ perror("buffersize invalid");
+ return 3;
+ }
+ break;
+//FIXME some way to specify erasure positions on the cmd line
+ case 'v': verbose++ ; break;
+ default:
+ help();
+ }
+ }
+ }
+
+ s= argv[argc-1];
+ if(decode){
+ pf= fopen(s, "r+b");
+ if(strlen(s) >= sizeof(buf) || strlen(s) < 6)
+ return 2; //FIXME print error message and check extension
+ strcpy(buf, s);
+ buf[strlen(s) - 5]= 0;
+ df= fopen(buf, "r+b");
+ if(!pf || !df)
+ perror ("Couldn't open file");
+ paritysize= fsize(pf);
+ }else{
+ if(paritysize<=0)
+ return 3; //FIXME error message
+ df= fopen(s, "rb");
+ snprintf(buf, sizeof(buf), "%s.mina", s);
+ pf= fopen(buf, "wb");
+ if(!pf || !df)
+ perror ("Couldn't open file");
+ }
+//FIXME factorize
+
+ if((paritysize&1) || paritysize <= 0)
+ return 4; //FIXME error message
+
+ assert(SIZE == 65537);
+
+ datasize= fsize(df);
+ paddedsize= datasize + (datasize&1);
+ buffer= malloc(2*(SIZE-1)*buffersize);
+ interleave= (paddedsize + paritysize + 131071) / 131072;
+ paddedsize= interleave * 131072LL - paritysize;
+
+ if(buffersize > interleave)
+ buffersize= interleave;
+
+ passes= (paddedsize + paritysize + buffersize - 1) / buffersize;
+
+
+ n0 = (paddedsize / 2) / interleave;
+ n10_pos= (paddedsize / 2) % interleave;
+
+ if(decode && zero2erasure){
+ int64_t last=0;
+ for(i=0; i<paddedsize + paritysize; i+=131072){ //FIXME 64bit
+ read(buffer, i, 131072, df, datasize, paddedsize, pf);
+ for(i2= 0; i2<131072; i2++){ //FIXME simplify
+ if(buffer[i2] || (i2+i>=datasize && i2+i<paddedsize) /*|| (i2+i>=paddedsize+paritysize)*/){
+ if(i2+i - last > 511){
+ if(verbose)
+ fprintf(stderr, "Marking %Ld-%d as erasure due to zeros\n", last, i2+i);
+ erasure_list= realloc(erasure_list, 2*(++erasure_list_len)*sizeof(int64_t));
+ erasure_list[erasure_list_len-1][0]= last;
+ erasure_list[erasure_list_len-1][1]= i2+i;
+ }
+ last= i2+i+1;
+ }
+ }
+ }
+ }
+
+ for(i=0; i<interleave; i += buffersize){
+ for(j=0; j<SIZE-1; j++){
+ int64_t p= 2*(i+j*(int64_t)interleave);
+ if(read(buffer + 2*j*buffersize, p, 2*buffersize, df, datasize, paddedsize, decode ? pf : NULL) < 0){
+ perror("read failure\n");
+ return 8;
+ }
+ }
+ //FIXME simplify below for()
+ for(i2=i; i2<interleave && i2<i+buffersize; i2++){
+ int n= SIZE - 1;
+ int k= (i2 < n10_pos) + n0 + 1;
+ GFF4Element code[n];
+ GFF4Element parityLocator[n-k+2];
+ GFF4Element erasureLocator[n-k+2];
+ GFF4Element tPoly[n-k];
+ int erased[n-k];
+
+ parityLocator[0]= 0;
+ erasureLocator[0]= 0;
+ tPoly[0]= 0;
+
+ for(j=0; j<n; j++)
+ code[j]= (buffer[2*(j*buffersize + i2 - i) ]<<8)
+ +buffer[2*(j*buffersize + i2 - i)+1];
+
+printf("%d %d %d\n", n, k, n-k);
+ if(decode){
+ int erasedCount=0;
+
+ for(j=0; j<erasure_list_len; j++){
+ int a= ((erasure_list[j][0]+1)/2 - i2 + interleave - 1) / interleave;
+ int b= ( erasure_list[j][1] /2 - i2 + interleave - 1) / interleave;
+ for(;a<b; a++){
+ assert(!code[a]);
+ erased[erasedCount++]= a;
+ }
+ }
+
+ e= EXT(rsDecode)(code, erased, erasureLocator, erasedCount, n-k);
+ if(e<0){
+ fprintf(stderr, "reed solomon decoding error\n");
+ return 9;
+ }else if(e>0 && verbose){
+ fprintf(stderr, "corrected %d errors in slice %d of %d\n", e, i2+1, interleave);
+ }
+ }else{
+ code[k-1]=0;
+ EXT(rsEncode)(code, parityLocator, n-k);
+ }
+
+ if(EXT(rsTransform)(code, parityLocator, n-k, tPoly, k-1, !decode) < 0){
+ fprintf(stderr, "transform failure\n");
+ return 6;
+ }
+
+ for(j= decode ? 0 : k; j<n; j++){
+ buffer[2*(j*buffersize + i2 - i) ]= code[j]>>8;
+ buffer[2*(j*buffersize + i2 - i)+1]= code[j];
+ }
+ }
+ for(j=0; j<SIZE-1; j++){
+ int64_t p= 2*(i+j*(int64_t)interleave);
+ if(write(buffer + 2*j*buffersize, p, 2*buffersize, decode ? df : NULL, datasize, paddedsize, pf) < 0){
+ perror("write failure\n");
+ return 7;
+ }
+ }
+ }
+
+ //FIXME first pass check syndrom==0
+
+ return 0;
+}
1
0
Author: michael
Date: Tue Jul 10 00:59:38 2007
New Revision: 85
Log:
typo
Modified:
trunk/noe/test.c
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:59:38 2007
@@ -175,7 +175,7 @@ int main(){
data[j]= rand() & MASK;
data[tLoc] %= SIZE - 1 - n + k;
- memcpy(code, data, n*sizeof(GFF4Element));
+ memcpy(code, data, k*sizeof(GFF4Element));
{START_TIMER
EXT(rsEncode)(code, parityLocator, i);
STOP_TIMER}
1
0
Author: michael
Date: Tue Jul 10 00:58:49 2007
New Revision: 84
Log:
some error checks
Modified:
trunk/noe/rs.c
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:58:49 2007
@@ -367,6 +367,9 @@ int EXT(rsDecode)(GFF4Element *data, int
GFF4Element *errorLocator, *omega, *syn, *psi;
int error[parityCount>>1];
+ if(erasureCount > parityCount)
+ return -1;
+
syn= omegas[1];
/* kill erased symbols */
@@ -433,6 +436,8 @@ for(i=0; i<erasureCount; i++){
}
for(j=0,i=0; j<errorCount; i++){
+ if(i>=SIZE)
+ return -1;
assert(i<SIZE);
if(!errorLocator[i])
error[j++]= i ? MINUS1 - bitReverse(i) : 0;
1
0
Author: michael
Date: Tue Jul 10 00:57:06 2007
New Revision: 83
Log:
version from 2006-06-22 20:40
Modified:
trunk/noe/gfft.c
trunk/noe/rs.c
trunk/noe/rs.h
trunk/noe/test.c
Modified: trunk/noe/gfft.c
==============================================================================
--- trunk/noe/gfft.c (original)
+++ trunk/noe/gfft.c Tue Jul 10 00:57:06 2007
@@ -32,9 +32,9 @@ void noe_gfft_init(){
for(i=0; i<256; i++){
int x= i;
- x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1));
- x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2));
- x = (( x >> 4) | ((x & 0x0f) << 4));
+ x = ((x & 0xaa) >> 1) | ((x & 0x55) << 1);
+ x = ((x & 0xcc) >> 2) | ((x & 0x33) << 2);
+ x = ( x >> 4) | ( x << 4);
noe_revTable[i]= x;
}
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:57:06 2007
@@ -48,91 +48,63 @@ void EXT(getSyndrom)(GFF4Element *syn, G
syn[0]= 1;
}
-noe_RsEncoder *EXT(getRsEncoder)(int parityCount, int tLocation){
- const int dataCount= SIZE - parityCount - 1;
- noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
-
- encoder->tPoly=NULL;
-
- encoder->parityCount= parityCount;
-
- if(tLocation>=0 && tLocation<dataCount && !M){
- GFF4Element temp[SIZE - 1];
- memset(temp, 0, sizeof(temp));
- temp[tLocation]= 1;
- EXT(rsEncode)(encoder, temp);
- encoder->tPoly= memalign(16, sizeof(GFF4Element)*(parityCount));
- encoder->tLocation= tLocation;
- memcpy(encoder->tPoly, temp + dataCount, parityCount*sizeof(GFF4Element));
- }
-
- return encoder;
-}
-
-#define free(p) if(p) free(p); p=NULL;
-void EXT(freeRsEncoder)(noe_RsEncoder *encoder){
- if(!encoder) return;
-
- free(encoder->tPoly);
-
- free(encoder);
-}
-
/**
*
*/
-void EXT(rsEncode)(noe_RsEncoder *encoder, GFF4Element *data){
+void EXT(rsEncode)(GFF4Element *data, GFF4Element *parityLocator, int parityCount){
int i;
- const int parityCount= encoder->parityCount;
const int dataCount= SIZE - parityCount - 1;
- int erasureLocations[parityCount];
+ int parityLocations[parityCount];
for(i=0; i<parityCount; i++)
- erasureLocations[i]= dataCount + i;
+ parityLocations[i]= dataCount + i;
- EXT(rsDecode)(data, erasureLocations, parityCount, parityCount);
+ EXT(rsDecode)(data, parityLocations, parityLocator, parityCount, parityCount);
}
#if M==0
//FIXME avoid the noe_RsEncoder dependancy
-int EXT(rsTransform)(noe_RsEncoder *e, GFF4Element *data, int encode){
+int EXT(rsTransform)(GFF4Element *data, GFF4Element *parityLocator, int parityCount, GFF4Element *tPoly, int tLocation, int encode){
int i, j;
- const int parityCount= e->parityCount;
const int dataCount= SIZE - parityCount - 1;
- char stats[SIZE];
- GFF4Element t= data[ e->tLocation ];
+ GFF4Element temp[SIZE-1];
+ char *stats= (char*)temp;
+ GFF4Element t= data[ tLocation ];
- memset(stats, 0, sizeof(stats));
+ if(tLocation<0 || tLocation>=dataCount)
+ return -1;
+
+ if(tPoly[0]<=0){
+ memset(temp, 0, sizeof(temp));
+ temp[tLocation]= 1;
+ EXT(rsEncode)(temp, parityLocator, parityCount);
+ memcpy(tPoly, temp + dataCount, parityCount*sizeof(GFF4Element));
+ }
+
+ memset(stats, 0, SIZE);
for(i=0; i<parityCount; i++){
- GFF4Element p= diff(data[i+dataCount], prod(e->tPoly[i], t));
+ GFF4Element p= diff(data[i+dataCount], prod(tPoly[i], t));
- stats[ prod(MINUS1 - p, inv(e->tPoly[i])) ]|=1; //FIXME get rid of the neg
+ stats[ prod(MINUS1 - p, inv(tPoly[i])) ]=1; //FIXME get rid of the neg
}
if(encode){
- for(j=i=0; i<SIZE; i++){
- if(stats[i])
- continue;
- if(j == t)
- break;
- j++;
- }
+ for(j=i=0; i<SIZE && j<=t; i++)
+ j+= !stats[i];
+ i--;
if(i>=SIZE)
return -1;
}else{
- for(j=i=0; j<t; j++){
- if(stats[j])
- continue;
- i++;
- }
+ for(j=i=0; j<t; j++)
+ i+= stats[j]^1;
}
- data[ e->tLocation ]= i;
+ data[ tLocation ]= i;
t= diff(i, t);
- for(i=0; i<parityCount; i++){
- data[i+dataCount]= sum(data[i+dataCount], prod(e->tPoly[i], t));
- }
+ for(i=0; i<parityCount; i++)
+ data[i+dataCount]= sum(data[i+dataCount], prod(tPoly[i], t));
+
return 0;
}
#endif
@@ -382,11 +354,10 @@ static int rsBerlekampMassey(GFF4Element
return k;
}
-int EXT(rsDecode)(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
- int i;
+int EXT(rsDecode)(GFF4Element *data, int *erasure, GFF4Element *erasureLocator, int erasureCount, int parityCount){
+ int i, j, k;
int errorCount, gfftEval;
const int dataCount= SIZE - 1 - parityCount;
- GFF4Element erasureLocator[erasureCount + 1];
GFF4Element locator0[SIZE]; //[parityCount + 1 + 1];
GFF4Element locator1[SIZE]; //[parityCount + 1 + 1];
GFF4Element *locators[2]={locator0, locator1};
@@ -394,6 +365,7 @@ int EXT(rsDecode)(GFF4Element *data, int
GFF4Element omega1[SIZE - 1 + 1];
GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
GFF4Element *errorLocator, *omega, *syn, *psi;
+ int error[parityCount>>1];
syn= omegas[1];
@@ -413,7 +385,8 @@ int EXT(rsDecode)(GFF4Element *data, int
//FIXME check truncated symbols syndrom
if(erasureCount){
- EXT(synthPoly)(erasureLocator, erasure, erasureCount);
+ if(erasureLocator[0]<=0)
+ EXT(synthPoly)(erasureLocator, erasure, erasureCount);
EXT(partialProdPoly)(syn, erasureLocator, syn, syn[0]);
}
#if 0
@@ -450,71 +423,57 @@ for(i=0; i<erasureCount; i++){
memset(errorLocator + errorCount+2, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
errorLocator++;
EXT(gfft)(errorLocator, errorLocator, SHIFT);
- }
- if(gfftEval>1){
- memset(omega + omega[0] + 2, 0, (SIZE - omega[0] - 2)*sizeof(GFF4Element));
- memset(psi + psi [0] + 2, 0, (SIZE - psi [0] - 2)*sizeof(GFF4Element));
- omega++;
- psi++;
- EXT(gfft)(omega, omega, SHIFT);
- EXT(gfft)(psi , psi , SHIFT);
- }
-
- if(errorCount){
- for(i=0; i<SIZE-1; i++){
- int r, e;
- GFF4Element X, nom, denom;
+ if(gfftEval>1){
+ memset(omega + omega[0] + 2, 0, (SIZE - omega[0] - 2)*sizeof(GFF4Element));
+ memset(psi + psi [0] + 2, 0, (SIZE - psi [0] - 2)*sizeof(GFF4Element));
+ omega++;
+ psi++;
+ EXT(gfft)(omega, omega, SHIFT);
+ EXT(gfft)(psi , psi , SHIFT);
+ }
- if(gfftEval){ //FIXME optimize
- if(errorLocator[i])
- continue;
-
- r= i ? MINUS1 - bitReverse(i) : 0; //FIXME i=0 <->MINUS1 ?
- }else{
- if(EXT(evalPoly)(errorLocator, EXT(exp)[i]))
- continue;
-
- r= i ? MINUS1 - i : 0;
- }
-//printf("E%6d %6d\n", i, r);
+ for(j=0,i=0; j<errorCount; i++){
+ assert(i<SIZE);
+ if(!errorLocator[i])
+ error[j++]= i ? MINUS1 - bitReverse(i) : 0;
+ }
+ }else{
+ for(j=0,i=0; j<errorCount; i++){
+ assert(i<SIZE);
+ if(!EXT(evalPoly)(errorLocator, i)){
+ GFF4Element rem=errorLocator[ errorLocator[0]+1 ];
+ for(k=errorLocator[0]; k>0; k--){
+ GFF4Element temp= sum(errorLocator[k], prod(rem, i));
+ errorLocator[k]= rem;
+ rem= temp;
+ }
+ assert(rem == 0);
+ errorLocator[0]--;
- X= EXT(exp)[r];
- if(gfftEval>1){
- nom= prod(X, omega[i]);
- denom= psi[i];
- }else{
- GFF4Element invX= EXT(exp)[MINUS1 - r];
- nom= prod(X, EXT(evalPoly)(omega, invX));
- denom= EXT(evalPoly)(psi, invX);
+ error[j++]= EXT(log)[i] ? MINUS1 - EXT(log)[i] : 0;
}
-
- assert(r>=0 && r<=SIZE-2);
- e= prod(nom, inv(denom));
- if(data[r]==0 && e==MINUS1 && r < dataCount)
- return -1;
- data[r]= sum(data[r], e);
}
}
- for(i=0; i<erasureCount; i++){
- const int r= erasure[i];
- const GFF4Element X = EXT(exp)[r];
- GFF4Element nom, denom;
+ for(i=0; i<erasureCount + errorCount; i++){
+ const int r= i<erasureCount ? erasure[i] : error[i-erasureCount];
+ int e;
assert(r>=0 && r<MINUS1);
if(gfftEval>1){
int i2= bitReverse(MINUS1 - r);
- nom= prod(X, omega[i2]);
- denom= psi[i2];
+ e= r - EXT(log)[ psi[i2]];
+ if(e<0) e+= MINUS1;
+ e+= EXT(log)[omega[i2]];
}else{
- const GFF4Element invX= EXT(exp)[MINUS1 - r];
- nom= prod(X, EXT(evalPoly)(omega, invX));
- denom= EXT(evalPoly)(psi, invX);
+ GFF4Element invX= EXT(exp)[MINUS1 - r];
+ e= r - EXT(log)[EXT(evalPoly)( psi, invX)];
+ if(e<0) e+= MINUS1;
+ e+= EXT(log)[EXT(evalPoly)(omega, invX)];
}
- assert(data[r]==0);
- data[r]= prod(nom, inv(denom));
+ data[r]= sum(data[r], EXT(exp)[e]);
}
return erasureCount + errorCount;
Modified: trunk/noe/rs.h
==============================================================================
--- trunk/noe/rs.h (original)
+++ trunk/noe/rs.h Tue Jul 10 00:57:06 2007
@@ -16,27 +16,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-typedef struct noe_RsEncoder{
- int parityCount;
- int tLocation;
- GFF4Element *tPoly;
-}noe_RsEncoder;
-
/**
* gets the syndroms.
* @param src a 2^16 entry long polynom
* @param syn the syndrom polynom will be stored here
*/
void EXT(getSyndrom)(GFF4Element *syn, GFF4Element *src, int order);
-noe_RsEncoder *EXT(getRsEncoder)(int parityOrder, int tLocation);
-void EXT(freeRsEncoder)(noe_RsEncoder *encoder);
/**
*
*/
-void EXT(rsEncode)(noe_RsEncoder *encoder, GFF4Element *data);
+void EXT(rsEncode)(GFF4Element *data, GFF4Element *parityLocator, int parityCount);
-int EXT(rsDecode)(GFF4Element *data, int *erased, int erasedCount, int parityCount);
+int EXT(rsDecode)(GFF4Element *data, int *erased, GFF4Element *erassureLocator, int erasedCount, int parityCount);
#if M==0
-int EXT(rsTransform)(noe_RsEncoder *e, GFF4Element *data, int encode);
+int EXT(rsTransform)(GFF4Element *data, GFF4Element *parityLocator, int parityCount, GFF4Element *tPoly, int tLocation, int encode);
#endif
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:57:06 2007
@@ -153,6 +153,7 @@ int main(){
printf("."); fflush(stdout);
}
#endif
+#if 0
printf("\nTesting encoder");
for(i=1; i<SIZE/2; i+=i+5){
int n= SIZE - 1;
@@ -161,11 +162,13 @@ int main(){
// GFF4Element gen[i+1];
GFF4Element data[k];
GFF4Element code[n];
- noe_RsEncoder *encoder;
int pass=5;
int tLoc= rand() % k;
+ GFF4Element parityLocator[i+2];
+ GFF4Element tPoly[i];
- encoder= EXT(getRsEncoder)(i, tLoc);
+ parityLocator[0]=0;
+ tPoly[0]= 0;
for(pass=5; pass; pass--){
for(j=0; j<k; j++)
@@ -174,7 +177,7 @@ int main(){
memcpy(code, data, n*sizeof(GFF4Element));
{START_TIMER
- EXT(rsEncode)(encoder, code);
+ EXT(rsEncode)(code, parityLocator, i);
STOP_TIMER}
EXT(getSyndrom)(syn, code, i);
//FIXME check that code contains data, but its not touched so ...
@@ -186,7 +189,7 @@ STOP_TIMER}
if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
}
#if M==0
- if(EXT(rsTransform)(encoder, code, 1) < 0)
+ if(EXT(rsTransform)(code, parityLocator, i, tPoly, tLoc, 1) < 0)
printf("transform failure\n");
EXT(getSyndrom)(syn, code, i);
for(j=0; j<i; j++)
@@ -196,7 +199,7 @@ STOP_TIMER}
printf("illegal symbol detected\n");
}
- if(EXT(rsTransform)(encoder, code, 0) < 0)
+ if(EXT(rsTransform)(code, parityLocator, i, tPoly, tLoc, 0) < 0)
printf("inv-transform failure\n");
EXT(getSyndrom)(syn, code, i);
for(j=0; j<i; j++)
@@ -208,21 +211,21 @@ STOP_TIMER}
#endif
printf("."); fflush(stdout);
}
- EXT(freeRsEncoder)(encoder);
}
#endif
+#endif
printf("\nTesting decoder");
for(i=1; i<2000 && i<SIZE/2; i+=(SIZE == 0x10001 ? 100 : 10)){
int n= SIZE - 1;
int k= SIZE - 1 - i;
-// GFF4Element syn[n];
int erased[i];
+ GFF4Element erasureLocator[i+2];
GFF4Element data[k];
GFF4Element code[n];
- noe_RsEncoder *encoder;
+ GFF4Element parityLocator[i+2];
int pass=5;
- encoder= EXT(getRsEncoder)(i, 0);
+ parityLocator[0]= 0;
for(pass=5; pass; pass--){
int erasedCount, errorCount;
@@ -230,8 +233,9 @@ STOP_TIMER}
data[j]= rand() & MASK;
memcpy(code, data, n*sizeof(GFF4Element));
+ erasureLocator[0]= 0;
- EXT(rsEncode)(encoder, code);
+ EXT(rsEncode)(code, parityLocator, i);
erasedCount=0;
if(rand()&0x40){
@@ -263,7 +267,7 @@ STOP_TIMER}
}
}
//printf("erased:%d errors:%d parity:%d\n", erasedCount, errorCount, i);
- EXT(rsDecode)(code, erased, erasedCount, i);
+ EXT(rsDecode)(code, erased, erasureLocator, erasedCount, i);
// EXT(printPoly)(gen, i);
// EXT(printPoly)(syn, i-1);
@@ -276,7 +280,6 @@ STOP_TIMER}
}
printf("."); fflush(stdout);
}
- EXT(freeRsEncoder)(encoder);
}
#if 0
{
1
0
09 Jul '07
Author: michael
Date: Tue Jul 10 00:53:52 2007
New Revision: 82
Log:
version from unknown date but definitly before 2006-06-22 13:51
Modified:
trunk/noe/Makefile
trunk/noe/galois.c
trunk/noe/galois.h
trunk/noe/rs.c
trunk/noe/rs.h
trunk/noe/test.c
Modified: trunk/noe/Makefile
==============================================================================
--- trunk/noe/Makefile (original)
+++ trunk/noe/Makefile Tue Jul 10 00:53:52 2007
@@ -17,12 +17,15 @@ CFLAGS = -g -Wall -O4 $(OPTFLAGS) -I. $
%_10001.o: %.c
$(CC) $(CFLAGS) -c -DSIZE=0x10001 -o $@ $<
-all: test_100 test_101 test_10001 libnoe_101.a libnoe_10001.a
+all: test_100 test_101 test_10001
libnoe_100.a: $(LIBOBJS:.o=_100.o)
$(AR) rc $@ $^
-libnoe_1%1.a: $(LIBOBJS:.o=_1%1.o) gfft_1%1.o
+libnoe_101.a: $(LIBOBJS:.o=_101.o) gfft_101.o
+ $(AR) rc $@ $^
+
+libnoe_10001.a: $(LIBOBJS:.o=_10001.o) gfft_10001.o
$(AR) rc $@ $^
test: all
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:53:52 2007
@@ -27,24 +27,25 @@
#include "galois.h"
#include "gfft.h"
-GFF4Element EXT(exp)[SIZE];
+GFF4Element EXT(exp)[4*SIZE];
GFF4Element EXT(log)[SIZE];
void EXT(init)(){
GFF4Element ge= 1;
int i;
- for(i=0; i<SIZE; i++){
+ for(i=0; i<=(SIZE-2)*2; i++){
EXT(exp)[i]= ge;
EXT(log)[ge]= i%(SIZE-1);
#if M!=0
- assert(PRIMITIVE_ELEMENT==2);
ge+=ge;
if(ge&SIZE) ge ^= M;
#else
- ge= prod(ge, PRIMITIVE_ELEMENT);
+ ge= reduce(ge * PRIMITIVE_ELEMENT);
#endif
}
+ EXT(log)[0]= (SIZE-2)*2 + 1;
+
#if M==0
noe_gfft_init();
#endif
@@ -52,13 +53,7 @@ void EXT(init)(){
int noe_log2(unsigned int v) // from ffmpeg
{
- int n;
-
- n = 0;
- if (v & 0xffff0000) {
- v >>= 16;
- n += 16;
- }
+ int n= 0;
if (v & 0xff00) {
v >>= 8;
n += 8;
@@ -98,10 +93,8 @@ void EXT(prodPoly)(GFF4Element *dst, GFF
j = NOE_MAX(0, i - order2);
end= NOE_MIN(i, order1);
- for(; j<=end; j++){
- if(M) acc^= prod(src1[j], src2[i-j]);
- else acc+= prod(src1[j], src2[i-j]);
- }
+ for(; j<=end; j++)
+ acc ADD_OP prod(src1[j], src2[i-j]);
dst[i]= reduce(acc);
}
}else{
@@ -128,6 +121,7 @@ void EXT(prodPoly)(GFF4Element *dst, GFF
}
}
+#ifdef ALTERNATIVE_SOLVERS
void EXT(prodMatrix)(GFF4Element *d1[2], GFF4Element *d2[2], GFF4Element *s1[2], GFF4Element *s2[2]){
//FIXME improve threshold decission
if((s1[0][0] + s1[1][0] + s2[0][0] + s2[1][0]) < 64 || M/*||
@@ -195,6 +189,7 @@ void EXT(prodMatrix)(GFF4Element *d1[2],
}
}
}
+#endif
/**
* returns the first order2 coefficients of the product of the 2 polynoms.
@@ -218,10 +213,8 @@ void EXT(partialProdPoly)(GFF4Element *d
j = NOE_MAX(0, i - order2);
end= NOE_MIN(i, order1);
- for(; j<=end; j++){
- if(M) acc^= prod(src1[j], src2[i-j]);
- else acc+= prod(src1[j], src2[i-j]);
- }
+ for(; j<=end; j++)
+ acc ADD_OP prod(src1[j], src2[i-j]);
dst[i]= reduce(acc);
}
}else{
@@ -262,13 +255,11 @@ void EXT(printPoly)(GFF4Element *src){
* Evaluates the src polynom at x.
*/
GFF4Element EXT(evalPoly)(GFF4Element *src, GFF4Element x){
- unsigned int acc=0;
+ unsigned int acc=src[ src[0] + 1 ];
int j;
- for(j=src[0]+1; j>0; j--){
-//FIXME skip reduce
+ for(j=src[0]; j>0; j--)
acc = sum(prod(acc, x), src[j]);
- }
return acc;
}
@@ -283,8 +274,7 @@ void EXT(getDerivative)(GFF4Element *dst
dst[i ]= src[i+1];
}
dst[0]= i-3;
- assert(dst[0] >= 0);
- assert(dst[ dst[0]+1 ]); //FIXME this isnt guranteed but seems to be always true
+ EXT(getOrder)(dst);
#else
for(i=1; i<=src[0]; i++){
dst[i ]= prod(src[i+1], i);
@@ -296,62 +286,37 @@ void EXT(getDerivative)(GFF4Element *dst
/**
* ...
*/
-void EXT(synthPoly)(GFF4Element *dst, GFF4Element *src, int count){
- if(count<20){
- int i;
-
- SET_POLY0(dst, 1);
-
- for(i=0; i<count; i++){
- assert(src[3*i] == 1);
- EXT(prodPoly)(dst, dst, src+3*i);
- }
- }else{
- int pass, i, countLeft;
- const int passCount= noe_log2(count-1)+1;
- GFF4Element temp[2][4<<noe_log2(count-1)];
-
- assert(passCount>0);
-
- countLeft= count;
-
- // EXT(printPoly)(src, 1);
- // EXT(printPoly)(src+2, 1);
+void EXT(synthPoly)(GFF4Element *dst, int *src, int count){
+ int pass, i;
+ GFF4Element temp[2][4*count];
+ GFF4Element *temp1= count<=2 ? dst : temp[0];
- for(i=0; i<(count>>1); i++){
- EXT(prodPoly)(temp[0]+4*i, src+6*i, src+6*i+3);
+ for(i=0; i+1<count; i+=2){
+ GFF4Element a= neg(EXT(exp)[src[i+0]]);
+ GFF4Element b= neg(EXT(exp)[src[i+1]]);
+ SET_POLY2(temp1+2*i, 1, sum(a,b), prod(a,b));
}
- if(count&1){
- memcpy(temp[0]+4*i, src+6*i, 3*sizeof(GFF4Element));
- countLeft++;
+ if(i<count){
+ SET_POLY1(temp1+2*i, 1, neg(EXT(exp)[src[i+0]]));
}
- countLeft>>=1;
-
- // EXT(printPoly)(temp[0], 2);
+ count= (count+1)>>1;
- for(pass=1; countLeft>1; pass++){
+ for(pass=1; count>1; pass++){
const int step= 2<<pass;
- GFF4Element *temp1= temp[ pass&1 ];
+ GFF4Element *temp1= count<=2 ? dst : temp[ pass&1 ];
GFF4Element *temp2= temp[(pass&1)^1];
- for(i=0; i<(countLeft>>1); i++){
- EXT(prodPoly)(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step);
+ for(i=0; i+1<count; i+=2){
+ EXT(prodPoly)(temp1, temp2, temp2+step);
+ temp1 += 2*step;
+ temp2 += 2*step;
}
- if(countLeft&1){
- memcpy(temp1+2*step*i, temp2+2*step*i, step*sizeof(GFF4Element));
- countLeft++;
+ if(i<count){
+ memcpy(temp1, temp2, step*sizeof(GFF4Element));
}
- countLeft>>=1;
+ count= (count+1)>>1;
}
-
- assert(pass==passCount);
-
- // EXT(printPoly)(temp[0], count);
-
- memcpy(dst, temp[(pass&1)^1], (count+2)*sizeof(GFF4Element));
- // EXT(printPoly)(dst, count);
- }
}
void EXT(getOrder)(GFF4Element *src){
@@ -359,6 +324,7 @@ void EXT(getOrder)(GFF4Element *src){
src[0]--;
}
+#ifdef ALTERNATIVE_SOLVERS
/**
* ...
* Note: rem can be identical to nom
@@ -475,3 +441,4 @@ void EXT(scaledSumPoly)(GFF4Element *dst
EXT(getOrder)(dst-1); //FIXME we need this due to src2= 0
}
}
+#endif
Modified: trunk/noe/galois.h
==============================================================================
--- trunk/noe/galois.h (original)
+++ trunk/noe/galois.h Tue Jul 10 00:53:52 2007
@@ -21,16 +21,19 @@
#define SHIFT 8
#define M 0x11D
#define EXT(name) noe_ ## name ## _100
+#define ADD_OP ^=
#elif SIZE == 0x10001
#define PRIMITIVE_ELEMENT 3
#define SHIFT 16
#define M 0
#define EXT(name) name ## _10001
+#define ADD_OP +=
#elif SIZE == 0x101
#define PRIMITIVE_ELEMENT 3
#define SHIFT 8
#define M 0
#define EXT(name) noe_ ## name ## _101
+#define ADD_OP +=
#else
#error wrong SIZE
#endif
@@ -40,7 +43,7 @@
typedef unsigned int GFF4Element;
-extern GFF4Element EXT(exp)[SIZE];
+extern GFF4Element EXT(exp)[4*SIZE];
extern GFF4Element EXT(log)[SIZE];
void EXT(prodPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
@@ -49,13 +52,17 @@ void EXT(init)();
void EXT(printPoly)(GFF4Element *src);
void EXT(getDerivative)(GFF4Element *dst, GFF4Element *src);
GFF4Element EXT(evalPoly)(GFF4Element *src, GFF4Element x);
-void EXT(synthPoly)(GFF4Element *dst, GFF4Element *src, int count);
+void EXT(synthPoly)(GFF4Element *dst, int *src, int count);
+#ifdef ALTERNATIVE_SOLVERS
void EXT(divPoly)(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom);
void EXT(diffPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
void EXT(sumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
+#endif
void EXT(getOrder)(GFF4Element *src);
+#ifdef ALTERNATIVE_SOLVERS
void EXT(scaledSumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s);
void EXT(prodMatrix)(GFF4Element *d1[2], GFF4Element *d2[2], GFF4Element *s1[2], GFF4Element *s2[2]);
+#endif
int noe_log2(unsigned int v);
static inline GFF4Element reduce(GFF4Element a){
@@ -67,30 +74,12 @@ static inline GFF4Element reduce(GFF4Ele
}
static inline GFF4Element prod(GFF4Element a, GFF4Element b){
-#if M!=0
- if(a==0 || b==0) return 0;
- a= EXT(log)[a] + EXT(log)[b];
- if(a>=SIZE) a-= SIZE-1;
- return EXT(exp)[a];
-#else
-//printf("%d %d\n", a,b);
-#if 0
- uint64_t x= ((uint64_t)a)*b;
- return reduce(x + (x>>32));
+#if M!=0 || SIZE < 0x500
+ return EXT(exp)[EXT(log)[a] + EXT(log)[b]];
#else
if(a==MINUS1) return -b + ((((int)-b)>>31)&SIZE);
else return reduce(a*b);
#endif
-#endif
-}
-
-static inline GFF4Element sum(GFF4Element a, GFF4Element b){
-#if M!=0
- return a^b;
-#else
- a += b - SIZE;
- return a + ((((int)a)>>31)&SIZE);
-#endif
}
static inline GFF4Element diff(GFF4Element a, GFF4Element b){
@@ -108,11 +97,14 @@ static inline GFF4Element diff(GFF4Eleme
#define neg(a) (SIZE - (a))
#endif
+#define sum(a,b) diff(a,neg(b))
+
static inline GFF4Element inv(GFF4Element a){
assert(a!=0);
- return EXT(exp)[MINUS1 - EXT(log)[a]];
+ return (EXT(exp)+MINUS1)[- EXT(log)[a]];
}
#define SET_POLY0(dst, coeff0) (dst)[0]=0; (dst)[1]=coeff0;
#define SET_POLY1(dst, coeff0, coeff1) (dst)[0]=1; (dst)[1]=coeff0; (dst)[2]=coeff1;
+#define SET_POLY2(dst, coeff0, coeff1, coeff2) (dst)[0]=2; (dst)[1]=coeff0; (dst)[2]=coeff1; (dst)[3]=coeff2;
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:53:52 2007
@@ -31,90 +31,49 @@
#undef NDEBUG
#include <assert.h>
-/**
- *
- */
-void EXT(getRsGenerator)(GFF4Element *dst, int first, int order){
- int i;
- GFF4Element factor[3*order];
-
- for(i=0; i<order; i++){
- SET_POLY1(factor+3*i, neg(EXT(exp)[ first + i ]), 1);
- }
-
- EXT(synthPoly)(dst, factor, order);
-}
-
void EXT(getSyndrom)(GFF4Element *syn, GFF4Element *src, int order){
*syn++= order;
-#if M==0
- EXT(gfft)(syn, src, SHIFT);
- EXT(permute)(syn, syn, order+1);
-#else
-{
- int i;
- int bak= src[-1];
- src[-1]= SIZE-2;
- for(i=0; i<order; i++){
- syn[i+1]= EXT(evalPoly)(src-1, EXT(exp)[1 + i]);
+ if(order>6 && !M){
+ EXT(gfft)(syn, src, SHIFT);
+ EXT(permute)(syn, syn, order+1);
+ }else{
+ int i;
+ for(i=1; i<=order; i++){
+ int bak= src[-1];
+ src[-1]= SIZE-2;
+ syn[i]= EXT(evalPoly)(src-1, EXT(exp)[i]);
+ src[-1]= bak;
+ }
}
- src[-1]= bak;
-}
-#endif
syn[0]= 1;
}
-#if 1
-noe_RsEncoder *EXT(getRsEncoder)(int parityCount){
+
+noe_RsEncoder *EXT(getRsEncoder)(int parityCount, int tLocation){
const int dataCount= SIZE - parityCount - 1;
- int i;
- GFF4Element *locator, *factor;
- GFF4Element locatorDerivative[parityCount+1];
noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
- GFF4Element locationFactor[3*parityCount];
- locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+2));
- factor= encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount );
+ encoder->tPoly=NULL;
encoder->parityCount= parityCount;
-
- for(i=0; i<parityCount; i++){
- SET_POLY1(locationFactor+3*i, 1, neg(EXT(exp)[dataCount + i]));
- }
- EXT(synthPoly)(locator, locationFactor, parityCount);
-#if 0
-for(i=0; i<parityCount; i++){
- if(EXT(evalPoly)(locator, inv(EXT(exp)[dataCount + i]))){
- printf("Internal Error 1\n");
- }
-}
-if(!EXT(evalPoly)(locator, inv(EXT(exp)[dataCount - 1])))
- printf("Internal Error 2\n");
-#endif
- EXT(getDerivative)(locatorDerivative, locator);
- assert(locatorDerivative[0] == parityCount-1);
- for(i=0; i<parityCount; i++){
- GFF4Element X= EXT(exp)[dataCount + i];
- GFF4Element invX= EXT(exp)[MINUS1 - (dataCount + i)];
- GFF4Element denom;
-
- assert(X == inv(invX));
-
- denom= EXT(evalPoly)(locatorDerivative, invX); //FIXME do in freq domain if parityCount>1000
- factor[i]= prod(X, inv(denom));
+ if(tLocation>=0 && tLocation<dataCount && !M){
+ GFF4Element temp[SIZE - 1];
+ memset(temp, 0, sizeof(temp));
+ temp[tLocation]= 1;
+ EXT(rsEncode)(encoder, temp);
+ encoder->tPoly= memalign(16, sizeof(GFF4Element)*(parityCount));
+ encoder->tLocation= tLocation;
+ memcpy(encoder->tPoly, temp + dataCount, parityCount*sizeof(GFF4Element));
}
return encoder;
}
+#define free(p) if(p) free(p); p=NULL;
void EXT(freeRsEncoder)(noe_RsEncoder *encoder){
if(!encoder) return;
- if(encoder->parityLocator) free(encoder->parityLocator);
- encoder->parityLocator= NULL;
-
- if(encoder->parityFactor) free(encoder->parityFactor);
- encoder->parityFactor= NULL;
+ free(encoder->tPoly);
free(encoder);
}
@@ -126,39 +85,59 @@ void EXT(rsEncode)(noe_RsEncoder *encode
int i;
const int parityCount= encoder->parityCount;
const int dataCount= SIZE - parityCount - 1;
- GFF4Element syn[SIZE];
- GFF4Element omega[SIZE];
- GFF4Element *locator= encoder->parityLocator;
- GFF4Element *factor= encoder->parityFactor;
+ int erasureLocations[parityCount];
- memset(data + dataCount, 0, parityCount*sizeof(GFF4Element));
-
- EXT(getSyndrom)(syn, data, parityCount);
+ for(i=0; i<parityCount; i++)
+ erasureLocations[i]= dataCount + i;
- EXT(partialProdPoly)(omega, locator, syn, syn[0]);
+ EXT(rsDecode)(data, erasureLocations, parityCount, parityCount);
+}
- if(parityCount < 1000 || M){
- for(i=0; i<parityCount; i++){
- GFF4Element invX= EXT(exp)[MINUS1 - (dataCount + i)];
-
- GFF4Element parity= prod(EXT(evalPoly)(omega, invX), factor[i]);
-
- data[dataCount + i]= parity;
+#if M==0
+//FIXME avoid the noe_RsEncoder dependancy
+int EXT(rsTransform)(noe_RsEncoder *e, GFF4Element *data, int encode){
+ int i, j;
+ const int parityCount= e->parityCount;
+ const int dataCount= SIZE - parityCount - 1;
+ char stats[SIZE];
+ GFF4Element t= data[ e->tLocation ];
+
+ memset(stats, 0, sizeof(stats));
+
+ for(i=0; i<parityCount; i++){
+ GFF4Element p= diff(data[i+dataCount], prod(e->tPoly[i], t));
+
+ stats[ prod(MINUS1 - p, inv(e->tPoly[i])) ]|=1; //FIXME get rid of the neg
+ }
+
+ if(encode){
+ for(j=i=0; i<SIZE; i++){
+ if(stats[i])
+ continue;
+ if(j == t)
+ break;
+ j++;
}
+ if(i>=SIZE)
+ return -1;
}else{
- memset(omega + parityCount + 1 + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
- EXT(gfft)(omega+1, omega+1, SHIFT);
- for(i=0; i<parityCount; i++){
- int index= SIZE - dataCount - i - 1;
-
- GFF4Element parity= prod(omega[bitReverse(index)+1], factor[i]);
-
- data[dataCount + i]= parity;
+ for(j=i=0; j<t; j++){
+ if(stats[j])
+ continue;
+ i++;
}
}
+ data[ e->tLocation ]= i;
+ t= diff(i, t);
+
+ for(i=0; i<parityCount; i++){
+ data[i+dataCount]= sum(data[i+dataCount], prod(e->tPoly[i], t));
+ }
+ return 0;
}
#endif
+#ifdef ALTERNATIVE_SOLVERS
#define XCHG(a,b) {void *tmp= a; a= b; b= tmp;}
static void hgcd(GFF4Element *ma[2], GFF4Element *mb[2], GFF4Element *a, GFF4Element *b, int len){
@@ -221,7 +200,7 @@ static void hgcd(GFF4Element *ma[2], GFF
SET_POLY0(mb[1], 1);
for(;;){
- GFF4Element q= SIZE - prod(a[ a[0]+1 ], inv(b[ b[0]+1 ]));
+ GFF4Element q= neg(prod(a[ a[0]+1 ], inv(b[ b[0]+1 ])));
int s= a[0] - b[0];
assert(s >= 0);
@@ -333,6 +312,7 @@ static int rsEuclid(GFF4Element *locator
EXT(diffPoly)(locator[di], locator[di], quot);
}
}
+#endif
/**
* ...
@@ -354,13 +334,9 @@ static int rsBerlekampMassey(GFF4Element
for(k=1+erasureCount; k<=parityCount; k++){
const int k2= k - erasureCount;
GFF4Element delta= syn[k];
-
for(j=1; j<=Lix[-1]; j++)
-#if M!=0
- delta^= prod(Lix[j], syn[k-j]);
-#else
- delta+= prod(Lix[j], syn[k-j]);
-#endif
+ delta ADD_OP prod(Lix[j], syn[k-j]);
+
delta= reduce(delta);
if(delta){
@@ -369,18 +345,22 @@ static int rsBerlekampMassey(GFF4Element
for(j=Tshift; j<=Tix[-1]; j++)
Lix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
}else{
- //Lix[-1] >= Tshift-1 has always been true during tests
//Tshift == 2 true in >99% of the cases
if(Tshift == 2 && Lix[-1]>0){
for(j=Tix[-1]; j>Lix[-1]; j--)
Tix[j]= prod(factor, Tix[j-2]);
for(; j>=2; j--)
Tix[j]= sum(Lix[j], prod(factor, Tix[j-2]));
- }else{
- for(j=Tix[-1]; j>NOE_MAX(Lix[-1], Tshift-1); j--)
+ }else if(Lix[-1] >= Tshift-1){
+ for(j=Tix[-1]; j>Lix[-1]; j--)
Tix[j]= prod(factor, Tix[j-Tshift]);
for(; j>=Tshift; j--)
Tix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
+ }else{
+ for(j=Tix[-1]; j>=Tshift; j--)
+ Tix[j]= prod(factor, Tix[j-Tshift]);
+ for(; j>Lix[-1]; j--)
+ Tix[j]= 0;
}
for(; j>0; j--)
Tix[j]= Lix[j];
@@ -404,53 +384,49 @@ static int rsBerlekampMassey(GFF4Element
int EXT(rsDecode)(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
int i;
- int errorCount, gfftEval, phantomErrorCount;
+ int errorCount, gfftEval;
const int dataCount= SIZE - 1 - parityCount;
GFF4Element erasureLocator[erasureCount + 1];
- GFF4Element erasureSynthSrc[erasureCount*3 + 1];
GFF4Element locator0[SIZE]; //[parityCount + 1 + 1];
GFF4Element locator1[SIZE]; //[parityCount + 1 + 1];
GFF4Element *locators[2]={locator0, locator1};
GFF4Element omega0[SIZE - 1 + 1];
GFF4Element omega1[SIZE - 1 + 1];
GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
- GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
+ GFF4Element *errorLocator, *omega, *syn, *psi;
syn= omegas[1];
/* kill erased symbols */
for(i=0; i<erasureCount; i++){
-//printf("%d\n", erasure[i]);
data[ erasure[i] ]=0;
}
EXT(getSyndrom)(syn, data, parityCount);
+
for(i=1; i<=parityCount; i++){
if(syn[i+1]) break;
}
if(i>parityCount)
return 0;
- phantomErrorCount=0;
//FIXME check truncated symbols syndrom
- for(i=0; i<erasureCount; i++){
- SET_POLY1(erasureSynthSrc + 3*i, 1, neg(EXT(exp)[erasure[i]]));
+ if(erasureCount){
+ EXT(synthPoly)(erasureLocator, erasure, erasureCount);
+ EXT(partialProdPoly)(syn, erasureLocator, syn, syn[0]);
}
- EXT(synthPoly)(erasureLocator, erasureSynthSrc, erasureCount);
-// EXT(printPoly)(erasureLocator, erasureCount);
-#if 1
+#if 0
for(i=0; i<erasureCount; i++){
int eval= EXT(evalPoly)(erasureLocator, inv(EXT(exp)[erasure[i]]));
assert( eval==0);
}
#endif
- EXT(partialProdPoly)(syn, erasureLocator, syn, syn[0]);
-START_TIMER
+//START_TIMER
i= rsBerlekampMassey(locators, omegas, parityCount, erasureCount);
// i= rsEuclid(locators, omegas, parityCount, erasureCount);
// i= rsSchoenhage(locators, omegas, parityCount, erasureCount);
-STOP_TIMER
+//STOP_TIMER
//printf("errorCount %d \n", errorCount);
if(i<0) return -1;
@@ -458,20 +434,23 @@ STOP_TIMER
omega= omegas[i];
errorLocator= locators[i];
- fErrorLocator= omegas[1-i]; //reuse some unused space
psi= locators[1-i]; //reuse some unused space
- gfftEval= (errorCount>20) + (errorCount>1024); //FIXME finetune thresholds
- if(M) gfftEval=0;
- if(gfftEval){
- memcpy(fErrorLocator, errorLocator+1, (errorCount+1)*sizeof(GFF4Element));
- memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
- EXT(gfft)(fErrorLocator, fErrorLocator, SHIFT);
- }
+ if(M) gfftEval= 0;
+ else if(errorCount + erasureCount>1024) gfftEval= 2;
+ else gfftEval= errorCount>20;
- EXT(prodPoly)(psi, errorLocator, erasureLocator);
+ if(erasureCount)
+ EXT(prodPoly)(psi, errorLocator, erasureLocator);
+ else
+ memcpy(psi, errorLocator, (errorLocator[0]+2)*sizeof(GFF4Element));
EXT(getDerivative)(psi, psi);
+ if(gfftEval){
+ memset(errorLocator + errorCount+2, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
+ errorLocator++;
+ EXT(gfft)(errorLocator, errorLocator, SHIFT);
+ }
if(gfftEval>1){
memset(omega + omega[0] + 2, 0, (SIZE - omega[0] - 2)*sizeof(GFF4Element));
memset(psi + psi [0] + 2, 0, (SIZE - psi [0] - 2)*sizeof(GFF4Element));
@@ -487,7 +466,7 @@ STOP_TIMER
GFF4Element X, nom, denom;
if(gfftEval){ //FIXME optimize
- if(fErrorLocator[i])
+ if(errorLocator[i])
continue;
r= i ? MINUS1 - bitReverse(i) : 0; //FIXME i=0 <->MINUS1 ?
@@ -511,12 +490,8 @@ STOP_TIMER
assert(r>=0 && r<=SIZE-2);
e= prod(nom, inv(denom));
- if(data[r]==0 && e==MINUS1){
- if(r < dataCount)
- return -1;
- else
- phantomErrorCount++;
- }
+ if(data[r]==0 && e==MINUS1 && r < dataCount)
+ return -1;
data[r]= sum(data[r], e);
}
}
@@ -542,6 +517,6 @@ STOP_TIMER
data[r]= prod(nom, inv(denom));
}
- return erasureCount + errorCount - phantomErrorCount;
+ return erasureCount + errorCount;
}
Modified: trunk/noe/rs.h
==============================================================================
--- trunk/noe/rs.h (original)
+++ trunk/noe/rs.h Tue Jul 10 00:53:52 2007
@@ -18,19 +18,17 @@
typedef struct noe_RsEncoder{
int parityCount;
- GFF4Element *parityLocator;
- GFF4Element *parityFactor;
+ int tLocation;
+ GFF4Element *tPoly;
}noe_RsEncoder;
-void EXT(getRsGenerator)(GFF4Element *dst, int first, int order);
-
/**
* gets the syndroms.
* @param src a 2^16 entry long polynom
* @param syn the syndrom polynom will be stored here
*/
void EXT(getSyndrom)(GFF4Element *syn, GFF4Element *src, int order);
-noe_RsEncoder *EXT(getRsEncoder)(int parityOrder);
+noe_RsEncoder *EXT(getRsEncoder)(int parityOrder, int tLocation);
void EXT(freeRsEncoder)(noe_RsEncoder *encoder);
/**
@@ -39,3 +37,6 @@ void EXT(freeRsEncoder)(noe_RsEncoder *e
void EXT(rsEncode)(noe_RsEncoder *encoder, GFF4Element *data);
int EXT(rsDecode)(GFF4Element *data, int *erased, int erasedCount, int parityCount);
+#if M==0
+int EXT(rsTransform)(noe_RsEncoder *e, GFF4Element *data, int encode);
+#endif
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:53:52 2007
@@ -124,6 +124,7 @@ int main(){
#if 1
srand (31415);
+#if 0 // only func using getRsGenerator so droped with it
printf("\nTesting generator polynoms");
for(i=1; i<100; i+=5){
int n= SIZE - 1;
@@ -151,9 +152,9 @@ int main(){
}
printf("."); fflush(stdout);
}
-
+#endif
printf("\nTesting encoder");
- for(i=1; i<1000 && i<SIZE/2; i+=i+5){
+ for(i=1; i<SIZE/2; i+=i+5){
int n= SIZE - 1;
int k= SIZE - 1 - i;
GFF4Element syn[n+1];
@@ -162,17 +163,19 @@ int main(){
GFF4Element code[n];
noe_RsEncoder *encoder;
int pass=5;
+ int tLoc= rand() % k;
- encoder= EXT(getRsEncoder)(i);
+ encoder= EXT(getRsEncoder)(i, tLoc);
for(pass=5; pass; pass--){
for(j=0; j<k; j++)
data[j]= rand() & MASK;
+ data[tLoc] %= SIZE - 1 - n + k;
memcpy(code, data, n*sizeof(GFF4Element));
-
+{START_TIMER
EXT(rsEncode)(encoder, code);
-
+STOP_TIMER}
EXT(getSyndrom)(syn, code, i);
//FIXME check that code contains data, but its not touched so ...
@@ -182,6 +185,27 @@ int main(){
for(j=0; j<i; j++){
if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
}
+#if M==0
+ if(EXT(rsTransform)(encoder, code, 1) < 0)
+ printf("transform failure\n");
+ EXT(getSyndrom)(syn, code, i);
+ for(j=0; j<i; j++)
+ if(syn[j+1+1]) printf("FAILT generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
+ for(j=0; j<n; j++){
+ if(code[j] == MINUS1)
+ printf("illegal symbol detected\n");
+ }
+
+ if(EXT(rsTransform)(encoder, code, 0) < 0)
+ printf("inv-transform failure\n");
+ EXT(getSyndrom)(syn, code, i);
+ for(j=0; j<i; j++)
+ if(syn[j+1+1]) printf("FAILTT generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
+ for(j=0; j<k; j++){
+ if(data[j] != code[j])
+ printf("data changed\n");
+ }
+#endif
printf("."); fflush(stdout);
}
EXT(freeRsEncoder)(encoder);
@@ -192,13 +216,13 @@ int main(){
int n= SIZE - 1;
int k= SIZE - 1 - i;
// GFF4Element syn[n];
- GFF4Element erased[i];
+ int erased[i];
GFF4Element data[k];
GFF4Element code[n];
noe_RsEncoder *encoder;
int pass=5;
- encoder= EXT(getRsEncoder)(i);
+ encoder= EXT(getRsEncoder)(i, 0);
for(pass=5; pass; pass--){
int erasedCount, errorCount;
@@ -281,53 +305,6 @@ int main(){
}
#endif
printf("\n");
-return 0;
- printf("Testing erasure decoding\n");
- for(i=1; i<20; i++){
- int n= SIZE - 1;
- int k= SIZE - 1 - i;
- GFF4Element syn[n+1];
- GFF4Element gen[i+1+1];
- GFF4Element data[k+1];
- GFF4Element code[n+1];
- GFF4Element locator[i+1+1];
- GFF4Element omega[2*i+1];
-
- data[0]= k-1;
- for(j=0; j<k; j++)
- data[j+1]= rand() & MASK;
-
- EXT(getRsGenerator)(gen, 1, i);
- EXT(prodPoly)(code, gen, data);
- assert(code[0]==n);
-
- locator[0] = 0;
- locator[1] = 1;
- for(j=0; j<i; j++){
- int index;
- GFF4Element locationFactor[3];
-
- if((rand()&7)==0 && j) continue;
-
- index= rand()%MASK;
- SET_POLY1(locationFactor, 1, inv(EXT(exp)[index]));
- EXT(prodPoly)(locator, locator, locationFactor);
-
- code[index] = 0;
- }
-
- EXT(getSyndrom)(syn, code+1, i);
- EXT(prodPoly)(omega, syn, locator);
-// EXT(getDeriative)(locator, locator, locatorOrder);
-
-
-// EXT(printPoly)(gen, i);
-// EXT(printPoly)(syn, i-1);
-
- for(j=0; j<i; j++){
- if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
- }
- }
return 0;
}
1
0
[mndiff]: r81 - in trunk/noe: Makefile galois.c galois.h gfft.c gfft.h noe.c noe_internal.h rs.c rs.h rw.h test.c
by michael 09 Jul '07
by michael 09 Jul '07
09 Jul '07
Author: michael
Date: Tue Jul 10 00:48:14 2007
New Revision: 81
Log:
version from unknown date but definitly before 2006-06-20 13:05
Modified:
trunk/noe/Makefile
trunk/noe/galois.c
trunk/noe/galois.h
trunk/noe/gfft.c
trunk/noe/gfft.h
trunk/noe/noe.c
trunk/noe/noe_internal.h
trunk/noe/rs.c
trunk/noe/rs.h
trunk/noe/rw.h
trunk/noe/test.c
Modified: trunk/noe/Makefile
==============================================================================
--- trunk/noe/Makefile (original)
+++ trunk/noe/Makefile Tue Jul 10 00:48:14 2007
@@ -1,15 +1,35 @@
-OBJS = test.o galois.o rs.o gfft.o rw.o filerw.o
-SRCS = $(OBJS:.o=.c) $(ASM_OBJS:.o=.s)
+LIBOBJS = galois.o rs.o
+OBJS = rw.o filerw.o noe.o
+LIBSRCS = $(LIBOBJS:.o=.c) $(ASM_LIBOBJS:.o=.s)
+SRCS = $(OBJS:.o=.c)
CFLAGS = -g -Wall -O4 $(OPTFLAGS) -I. $(EXTRA_INC)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
-all: test
+%_100.o: %.c
+ $(CC) $(CFLAGS) -c -DSIZE=0x100 -o $@ $<
-test: $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $(OBJS)
+%_101.o: %.c
+ $(CC) $(CFLAGS) -c -DSIZE=0x101 -o $@ $<
+
+%_10001.o: %.c
+ $(CC) $(CFLAGS) -c -DSIZE=0x10001 -o $@ $<
+
+all: test_100 test_101 test_10001 libnoe_101.a libnoe_10001.a
+
+libnoe_100.a: $(LIBOBJS:.o=_100.o)
+ $(AR) rc $@ $^
+
+libnoe_1%1.a: $(LIBOBJS:.o=_1%1.o) gfft_1%1.o
+ $(AR) rc $@ $^
+
+test: all
+ ./test_100 ; ./test_101 ; ./test_10001
+
+test_%: test_%.o libnoe_%.a
+ $(CC) $(LDFLAGS) -o $@ $^
clean:
rm -f *.o *.a *~
@@ -17,4 +37,4 @@ clean:
dep: depend
depend:
- $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend
+ $(CC) -MM $(CFLAGS) $(LIBSRCS) $(SRCS) 1>.depend
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:48:14 2007
@@ -27,43 +27,71 @@
#include "galois.h"
#include "gfft.h"
-GFF4Element noe_exp[SIZE];
-GFF4Element noe_log[SIZE];
+GFF4Element EXT(exp)[SIZE];
+GFF4Element EXT(log)[SIZE];
-void noe_init(){
+void EXT(init)(){
GFF4Element ge= 1;
int i;
for(i=0; i<SIZE; i++){
- noe_exp[i]= ge;
- noe_log[ge]= i;
+ EXT(exp)[i]= ge;
+ EXT(log)[ge]= i%(SIZE-1);
+#if M!=0
+ assert(PRIMITIVE_ELEMENT==2);
+ ge+=ge;
+ if(ge&SIZE) ge ^= M;
+#else
ge= prod(ge, PRIMITIVE_ELEMENT);
+#endif
}
-
- noe_log[0]= 0xFFFF;
- noe_log[1]= 0;
-
+#if M==0
noe_gfft_init();
+#endif
}
+
+int noe_log2(unsigned int v) // from ffmpeg
+{
+ int n;
+
+ n = 0;
+ if (v & 0xffff0000) {
+ v >>= 16;
+ n += 16;
+ }
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ if (v & 0xf0) {
+ v >>= 4;
+ n += 4;
+ }
+ if (v & 0xc) {
+ v >>= 2;
+ n += 2;
+ }
+ if (v & 0x2) {
+ n++;
+ }
+ return n;
+}
+
/**
* ...
*/
-void noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+void EXT(prodPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
const int order1= *src1++;
const int order2= *src2++;
int order= order1 + order2;
int i;
- if((order1==0 && src1[0]==0) ||
- (order2==0 && src2[0]==0)){
- SET_POLY0(dst, 0);
- return;
- }
-
*dst++= order;
- if(order1*order2 <= (order1+order2)*64){
- for(i=order; i>=0; i--){
+ if(order1*order2 <= (order1+order2)*64 || M){
+ dst[order]= prod(src1[order1], src2[order2]);
+ if(!dst[order]) dst[-1]=0; //special case for zero polynoms
+ for(i=order-1; i>=0; i--){
unsigned int acc=0;
int j, end;
@@ -71,7 +99,8 @@ void noe_prodPoly(GFF4Element *dst, GFF4
end= NOE_MIN(i, order1);
for(; j<=end; j++){
- acc+= prod(src1[j], src2[i-j]);
+ if(M) acc^= prod(src1[j], src2[i-j]);
+ else acc+= prod(src1[j], src2[i-j]);
}
dst[i]= reduce(acc);
}
@@ -87,23 +116,91 @@ void noe_prodPoly(GFF4Element *dst, GFF4
memcpy(temp[1], src2, sizeof(GFF4Element)*(order2+1));
memset(temp[1] + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
- noe_gfft(temp[0], temp[0], logSize);
- noe_gfft(temp[1], temp[1], logSize);
+ EXT(gfft)(temp[0], temp[0], logSize);
+ EXT(gfft)(temp[1], temp[1], logSize);
for(i=0; i<size; i++){
temp[0][i]= prod(prod(temp[0][i], temp[1][i]), scale);
}
- noe_igfft(temp[0], temp[0], logSize);
+ EXT(igfft)(temp[0], temp[0], logSize);
memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
}
}
+void EXT(prodMatrix)(GFF4Element *d1[2], GFF4Element *d2[2], GFF4Element *s1[2], GFF4Element *s2[2]){
+//FIXME improve threshold decission
+ if((s1[0][0] + s1[1][0] + s2[0][0] + s2[1][0]) < 64 || M/*||
+ d1[0][0]==0 || d1[1][0]==0 || d2[0][0]==0 || d2[1][0]==0 ||
+ s1[0][0]==0 || s1[1][0]==0 || s2[0][0]==0 || s2[1][0]==0*/){
+ GFF4Element t1[SIZE]; //FIXME size
+ GFF4Element t2[SIZE]; //FIXME size
+
+ EXT(prodPoly)(t1 , d1[0], s2[0]);
+ EXT(prodPoly)(d1[0], d1[0], s1[0]);
+ EXT(prodPoly)(t2 , d2[0], s1[1]);
+ EXT(prodPoly)(d2[0], d2[0], s2[1]);
+ EXT(sumPoly)(d1[0], d1[0], t2);
+ EXT(sumPoly)(d2[0], d2[0], t1);
+
+ EXT(prodPoly)(t1 , d1[1], s2[0]);
+ EXT(prodPoly)(d1[1], d1[1], s1[0]);
+ EXT(prodPoly)(t2 , d2[1], s1[1]);
+ EXT(prodPoly)(d2[1], d2[1], s2[1]);
+ EXT(sumPoly)(d1[1], d1[1], t2);
+ EXT(sumPoly)(d2[1], d2[1], t1);
+ }else{
+ int i;
+ int max_order= NOE_MAX( NOE_MAX( NOE_MAX(d1[0][0] + s2[0][0], d1[0][0] + s1[0][0]),
+ NOE_MAX(d2[0][0] + s2[1][0], d2[0][0] + s1[1][0]) ),
+ NOE_MAX( NOE_MAX(d1[1][0] + s2[0][0], d1[1][0] + s1[0][0]),
+ NOE_MAX(d2[1][0] + s2[1][0], d2[1][0] + s1[1][0]) ));
+
+ const int logSize= noe_log2(max_order)+1;
+ const int size= 1<<logSize;
+ const GFF4Element scale= inv(size);
+
+ s1[0]++; s1[1]++; s2[0]++; s2[1]++;
+ d1[0]++; d1[1]++; d2[0]++; d2[1]++;
+
+ for(i=0; i<2; i++){
+ memset(s1[i] + s1[i][-1] + 1, 0, sizeof(GFF4Element)*(size - s1[i][-1] - 1));
+ memset(s2[i] + s2[i][-1] + 1, 0, sizeof(GFF4Element)*(size - s2[i][-1] - 1));
+ memset(d1[i] + d1[i][-1] + 1, 0, sizeof(GFF4Element)*(size - d1[i][-1] - 1));
+ memset(d2[i] + d2[i][-1] + 1, 0, sizeof(GFF4Element)*(size - d2[i][-1] - 1));
+ EXT(gfft)(s1[i], s1[i], logSize);
+ EXT(gfft)(s2[i], s2[i], logSize);
+ EXT(gfft)(d1[i], d1[i], logSize);
+ EXT(gfft)(d2[i], d2[i], logSize);
+ }
+
+ for(i=0; i<size; i++){
+ int d1t= d1[0][i];
+ d1[0][i]= prod(sum(prod(d1t, s1[0][i]), prod(d2[0][i], s1[1][i])), scale);
+ d2[0][i]= prod(sum(prod(d1t, s2[0][i]), prod(d2[0][i], s2[1][i])), scale);
+ }
+ for(i=0; i<size; i++){
+ int d1t= d1[1][i];
+ d1[1][i]= prod(sum(prod(d1t, s1[0][i]), prod(d2[1][i], s1[1][i])), scale);
+ d2[1][i]= prod(sum(prod(d1t, s2[0][i]), prod(d2[1][i], s2[1][i])), scale);
+ }
+
+ for(i=0; i<2; i++){
+ EXT(igfft)(d1[i], d1[i], logSize);
+ EXT(igfft)(d2[i], d2[i], logSize);
+ *(--d1[i])= max_order;
+ *(--d2[i])= max_order;
+ EXT(getOrder)(d1[i]);
+ EXT(getOrder)(d2[i]);
+ }
+ }
+}
+
/**
* returns the first order2 coefficients of the product of the 2 polynoms.
* Note dst must be at least 2^log2(order1+order2) big FIXME benchmark if its worth it
*/
-void noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order){
+void EXT(partialProdPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order){
int order1= *src1++;
int order2= *src2++;
int i;
@@ -113,7 +210,7 @@ void noe_partialProdPoly(GFF4Element *ds
if(order < order1) order1= order;
if(order < order2) order2= order;
- if(order1*order2 <= (order1+order2)*64){
+ if(order1*order2 <= (order1+order2)*64 || M){
for(i=order; i>=0; i--){
unsigned int acc=0;
int j, end;
@@ -122,12 +219,13 @@ void noe_partialProdPoly(GFF4Element *ds
end= NOE_MIN(i, order1);
for(; j<=end; j++){
- acc+= prod(src1[j], src2[i-j]);
+ if(M) acc^= prod(src1[j], src2[i-j]);
+ else acc+= prod(src1[j], src2[i-j]);
}
dst[i]= reduce(acc);
}
}else{
- const int logSize= noe_log2(order1+order2)+1;
+ const int logSize= noe_log2(order2 + order1)+1;
const int size= 1<<logSize;
GFF4Element temp[size]; //FIXME is this fast?
const GFF4Element scale= inv(size);
@@ -138,20 +236,20 @@ void noe_partialProdPoly(GFF4Element *ds
memcpy(dst, src1, sizeof(GFF4Element)*(order1+1));
memset(dst + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
- noe_gfft(dst, dst, logSize);
- noe_gfft(temp, temp, logSize);
+ EXT(gfft)(dst, dst, logSize);
+ EXT(gfft)(temp, temp, logSize);
for(i=0; i<size; i++){
dst[i]= prod(prod(dst[i], temp[i]), scale);
}
- noe_igfft(dst, dst, logSize);
+ EXT(igfft)(dst, dst, logSize);
}
- noe_getOrder(dst-1);
+ EXT(getOrder)(dst-1);
}
-void noe_printPoly(GFF4Element *src){
+void EXT(printPoly)(GFF4Element *src){
int i;
for(i=src[0]+1; i>0; i--){
@@ -163,30 +261,42 @@ void noe_printPoly(GFF4Element *src){
/**
* Evaluates the src polynom at x.
*/
-GFF4Element noe_evalPoly(GFF4Element *src, GFF4Element x){
+GFF4Element EXT(evalPoly)(GFF4Element *src, GFF4Element x){
unsigned int acc=0;
int j;
for(j=src[0]+1; j>0; j--){
+//FIXME skip reduce
acc = sum(prod(acc, x), src[j]);
}
return acc;
}
-void noe_getDerivative(GFF4Element *dst, GFF4Element *src){
+void EXT(getDerivative)(GFF4Element *dst, GFF4Element *src){
int i;
+#if M!=0
+ dst[1]= src[2];
+ for(i=3; i<=src[0]; i+=2){
+ dst[i-1]= 0;
+ dst[i ]= src[i+1];
+ }
+ dst[0]= i-3;
+ assert(dst[0] >= 0);
+ assert(dst[ dst[0]+1 ]); //FIXME this isnt guranteed but seems to be always true
+#else
for(i=1; i<=src[0]; i++){
dst[i ]= prod(src[i+1], i);
}
dst[0]= src[0]-1;
+#endif
}
/**
* ...
*/
-void noe_synthPoly(GFF4Element *dst, GFF4Element *src, int count){
+void EXT(synthPoly)(GFF4Element *dst, GFF4Element *src, int count){
if(count<20){
int i;
@@ -194,7 +304,7 @@ void noe_synthPoly(GFF4Element *dst, GFF
for(i=0; i<count; i++){
assert(src[3*i] == 1);
- noe_prodPoly(dst, dst, src+3*i);
+ EXT(prodPoly)(dst, dst, src+3*i);
}
}else{
int pass, i, countLeft;
@@ -205,11 +315,11 @@ void noe_synthPoly(GFF4Element *dst, GFF
countLeft= count;
- // noe_printPoly(src, 1);
- // noe_printPoly(src+2, 1);
+ // EXT(printPoly)(src, 1);
+ // EXT(printPoly)(src+2, 1);
for(i=0; i<(count>>1); i++){
- noe_prodPoly(temp[0]+4*i, src+6*i, src+6*i+3);
+ EXT(prodPoly)(temp[0]+4*i, src+6*i, src+6*i+3);
}
if(count&1){
memcpy(temp[0]+4*i, src+6*i, 3*sizeof(GFF4Element));
@@ -217,7 +327,7 @@ void noe_synthPoly(GFF4Element *dst, GFF
}
countLeft>>=1;
- // noe_printPoly(temp[0], 2);
+ // EXT(printPoly)(temp[0], 2);
for(pass=1; countLeft>1; pass++){
const int step= 2<<pass;
@@ -225,7 +335,7 @@ void noe_synthPoly(GFF4Element *dst, GFF
GFF4Element *temp2= temp[(pass&1)^1];
for(i=0; i<(countLeft>>1); i++){
- noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step);
+ EXT(prodPoly)(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step);
}
if(countLeft&1){
@@ -237,14 +347,14 @@ void noe_synthPoly(GFF4Element *dst, GFF
assert(pass==passCount);
- // noe_printPoly(temp[0], count);
+ // EXT(printPoly)(temp[0], count);
memcpy(dst, temp[(pass&1)^1], (count+2)*sizeof(GFF4Element));
- // noe_printPoly(dst, count);
+ // EXT(printPoly)(dst, count);
}
}
-void noe_getOrder(GFF4Element *src){
+void EXT(getOrder)(GFF4Element *src){
while(src[0] && src[ src[0] + 1 ]==0)
src[0]--;
}
@@ -253,7 +363,7 @@ void noe_getOrder(GFF4Element *src){
* ...
* Note: rem can be identical to nom
*/
-void noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom){
+void EXT(divPoly)(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom){
const int nomOrder= *nom++;
const int denomOrder= *denom++;
int i;
@@ -279,16 +389,16 @@ void noe_divPoly(GFF4Element *quot, GFF4
for(i=0; i<=denomOrder; i++){ //FIXME optimize
const int remIndex= i + remOrder - denomOrder;
- rem[remIndex]= sum(rem[remIndex], SIZE - prod(scale, denom[i]));
+ rem[remIndex]= diff(rem[remIndex], prod(scale, denom[i])); //FIXME skip reduce
}
quot[remOrder - denomOrder]= scale;
}
- noe_getOrder(rem-1);
+ EXT(getOrder)(rem-1);
}
-void noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+void EXT(diffPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
const int order1= *src1++;
const int order2= *src2++;
int i;
@@ -297,24 +407,24 @@ void noe_diffPoly(GFF4Element *dst, GFF4
*dst++= order1;
for(i=0; i<=minOrder; i++){
- dst[i]= sum(src1[i], SIZE - src2[i]);
+ dst[i]= diff(src1[i], src2[i]);
}
if(order1==order2){
- noe_getOrder(dst-1);
+ EXT(getOrder)(dst-1);
}else{
if(dst!=src1)
memcpy(dst+i, src1+i, (i-1-order1)*sizeof(GFF4Element));
for(; i<=order2; i++){
- dst[i]= SIZE - src2[i];
+ dst[i]= neg(src2[i]);
}
dst[-1]= NOE_MAX(order1, order2);
}
}
-void noe_sumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+void EXT(sumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
const int order1= *src1++;
const int order2= *src2++;
int i;
@@ -327,7 +437,7 @@ void noe_sumPoly(GFF4Element *dst, GFF4E
}
if(order1==order2){
- noe_getOrder(dst-1);
+ EXT(getOrder)(dst-1);
}else if(order1 < order2){
dst[-1]= order2;
if(dst!=src2)
@@ -338,7 +448,7 @@ void noe_sumPoly(GFF4Element *dst, GFF4E
}
}
-void noe_scaledSumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s){
+void EXT(scaledSumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s){
const int order1= *src1++;
const int order2= *src2++; //FIXME +s
int i;
@@ -352,7 +462,7 @@ void noe_scaledSumPoly(GFF4Element *dst,
dst[i]= sum(src1[i], prod(src2[i-s], f));
if(order1==order2 + s){
- noe_getOrder(dst-1);
+ EXT(getOrder)(dst-1);
}else{
if(dst!=src1)
memcpy(dst+i, src1+i, (order1+1-i)*sizeof(GFF4Element));
@@ -362,6 +472,6 @@ void noe_scaledSumPoly(GFF4Element *dst,
}
dst[-1]= NOE_MAX(order1, order2+s);
- noe_getOrder(dst-1); //FIXME we need this due to src2= 0
+ EXT(getOrder)(dst-1); //FIXME we need this due to src2= 0
}
}
Modified: trunk/noe/galois.h
==============================================================================
--- trunk/noe/galois.h (original)
+++ trunk/noe/galois.h Tue Jul 10 00:48:14 2007
@@ -16,48 +16,103 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#if SIZE == 0x100
+#define PRIMITIVE_ELEMENT 2
+#define SHIFT 8
+#define M 0x11D
+#define EXT(name) noe_ ## name ## _100
+#elif SIZE == 0x10001
#define PRIMITIVE_ELEMENT 3
-#define SIZE 0x10001
+#define SHIFT 16
+#define M 0
+#define EXT(name) name ## _10001
+#elif SIZE == 0x101
+#define PRIMITIVE_ELEMENT 3
+#define SHIFT 8
+#define M 0
+#define EXT(name) noe_ ## name ## _101
+#else
+#error wrong SIZE
+#endif
+
+#define MINUS1 (SIZE-1)
+#define MASK ((1<<SHIFT)-1)
typedef unsigned int GFF4Element;
-extern GFF4Element noe_exp[SIZE];
-extern GFF4Element noe_log[SIZE];
+extern GFF4Element EXT(exp)[SIZE];
+extern GFF4Element EXT(log)[SIZE];
-int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
-int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
-void noe_init();
-void noe_printPoly(GFF4Element *src, int order);
-int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order);
-GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x);
-void noe_synthPoly(GFF4Element *dst, GFF4Element *src, int count);
-int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder);
-int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
-int noe_getOrder(GFF4Element *src, int maxOrder);
+void EXT(prodPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
+void EXT(partialProdPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order);
+void EXT(init)();
+void EXT(printPoly)(GFF4Element *src);
+void EXT(getDerivative)(GFF4Element *dst, GFF4Element *src);
+GFF4Element EXT(evalPoly)(GFF4Element *src, GFF4Element x);
+void EXT(synthPoly)(GFF4Element *dst, GFF4Element *src, int count);
+void EXT(divPoly)(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom);
+void EXT(diffPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
+void EXT(sumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2);
+void EXT(getOrder)(GFF4Element *src);
+void EXT(scaledSumPoly)(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s);
+void EXT(prodMatrix)(GFF4Element *d1[2], GFF4Element *d2[2], GFF4Element *s1[2], GFF4Element *s2[2]);
+int noe_log2(unsigned int v);
static inline GFF4Element reduce(GFF4Element a){
- a = (a&0xFFFF) - (a>>16);
- a += (((int)a)>>31)&0x10001;
-
+#if M==0
+ a = (a&MASK) - (a>>SHIFT);
+ a += (((int)a)>>31)&SIZE;
+#endif
return a;
}
static inline GFF4Element prod(GFF4Element a, GFF4Element b){
+#if M!=0
+ if(a==0 || b==0) return 0;
+ a= EXT(log)[a] + EXT(log)[b];
+ if(a>=SIZE) a-= SIZE-1;
+ return EXT(exp)[a];
+#else
//printf("%d %d\n", a,b);
- if((a&b)==0x10000) return 1;
- else return reduce(a*b);
+#if 0
+ uint64_t x= ((uint64_t)a)*b;
+ return reduce(x + (x>>32));
+#else
+ if(a==MINUS1) return -b + ((((int)-b)>>31)&SIZE);
+ else return reduce(a*b);
+#endif
+#endif
}
static inline GFF4Element sum(GFF4Element a, GFF4Element b){
-
- a += b - 0x10001;
- a += (((int)a)>>31)&0x10001;
-
- return a;
+#if M!=0
+ return a^b;
+#else
+ a += b - SIZE;
+ return a + ((((int)a)>>31)&SIZE);
+#endif
}
+static inline GFF4Element diff(GFF4Element a, GFF4Element b){
+#if M!=0
+ return a^b;
+#else
+ a -= b;
+ return a + ((((int)a)>>31)&SIZE);
+#endif
+}
+
+#if M!=0
+#define neg(a) (a)
+#else
+#define neg(a) (SIZE - (a))
+#endif
+
static inline GFF4Element inv(GFF4Element a){
assert(a!=0);
- return noe_exp[SIZE - 1 - noe_log[a]];
+ return EXT(exp)[MINUS1 - EXT(log)[a]];
}
+
+#define SET_POLY0(dst, coeff0) (dst)[0]=0; (dst)[1]=coeff0;
+#define SET_POLY1(dst, coeff0, coeff1) (dst)[0]=1; (dst)[1]=coeff0; (dst)[2]=coeff1;
Modified: trunk/noe/gfft.c
==============================================================================
--- trunk/noe/gfft.c (original)
+++ trunk/noe/gfft.c Tue Jul 10 00:48:14 2007
@@ -40,39 +40,12 @@ void noe_gfft_init(){
}
}
-int noe_log2(unsigned int v) // from ffmpeg
-{
- int n;
-
- n = 0;
- if (v & 0xffff0000) {
- v >>= 16;
- n += 16;
- }
- if (v & 0xff00) {
- v >>= 8;
- n += 8;
- }
- if (v & 0xf0) {
- v >>= 4;
- n += 4;
- }
- if (v & 0xc) {
- v >>= 2;
- n += 2;
- }
- if (v & 0x2) {
- n++;
- }
- return n;
-}
-
-void noe_permute(GFF4Element *dst, GFF4Element *src, int outCount){
+void EXT(permute)(GFF4Element *dst, GFF4Element *src, int outCount){
int i;
if(dst==src){
for(i=1; i<outCount; i++){
- const int r= noe_bitReverse(i);
+ const int r= bitReverse(i);
unsigned int t;
if(r<=i) continue;
t= dst[i];
@@ -81,7 +54,7 @@ void noe_permute(GFF4Element *dst, GFF4E
}
}else{
for(i=0; i<outCount; i++){
- dst[i]= src[noe_bitReverse(i)];
+ dst[i]= src[bitReverse(i)];
}
}
}
@@ -97,12 +70,12 @@ static inline void fft2(GFF4Element *p){
static inline void fft4(GFF4Element *p){
unsigned int a,b,c,d;
- d= p[0] + SIZE*0x8000ULL;
+ d= p[0] + SIZE*(SIZE/2ULL);
a= d +p[2];
b= p[1]+p[3];
c= d -p[2];
- d= (p[3] - p[1])<<8 /*(p[1] - p[3])*noe_exp[16384]*/;
+ d= (p[3] - p[1])<<(SHIFT/2) /*(p[1] - p[3])*noe_exp[16384]*/;
p[0]= reduce(a+b);
p[1]= reduce(a-b);
@@ -128,17 +101,17 @@ static inline void fft8(GFF4Element *p){
a= p[1];
b= p[5];
p[1]= a+b;
- p[5]= reduce(SIZE*0x8000ULL + ((a-b)<<12))/*(a-b)*noe_exp[8192]*/;
+ p[5]= reduce(SIZE*(SIZE/2ULL) + ((a-b)<<(SHIFT*3/4)))/*(a-b)*noe_exp[8192]*/;
a= p[2];
b= p[6];
p[2]= a+b;
- p[6]= (b-a)<<8 /*(a-b)*noe_exp[16384]*/;
+ p[6]= (b-a)<<(SHIFT/2) /*(a-b)*noe_exp[16384]*/;
a= p[3];
b= p[7];
p[3]= a+b;
- p[7]= (a-b)<<4/*(a-b)*noe_exp[3*8192]*/;
+ p[7]= (a-b)<<(SHIFT/4)/*(a-b)*noe_exp[3*8192]*/;
fft4(p);
fft4(p+4);
@@ -148,7 +121,7 @@ static void fft16(GFF4Element *p){
int n;
for(n=0; n<8; n++){
- const unsigned int w= noe_exp[ n<<12 ];
+ const unsigned int w= EXT(exp)[ n<<(SHIFT-4) ];
const unsigned int a= p[n ];
const unsigned int b= p[n + 8];
@@ -165,7 +138,7 @@ static void fftn(GFF4Element *p, int log
const int size= 1<<(logSize-1);
for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int w= EXT(exp)[ n<<(SHIFT-logSize) ];
const unsigned int a= p[n ];
const unsigned int b= p[n + size];
@@ -187,7 +160,7 @@ static void fftn2(GFF4Element *p, GFF4El
const int size= 1<<(logSize-1);
for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int w= EXT(exp)[ n<<(SHIFT-logSize) ];
const unsigned int a= src[n ];
const unsigned int b= src[n + size];
@@ -225,7 +198,7 @@ static void ifftn(GFF4Element *p, int lo
}
for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ (1<<16) - (n<<(16-logSize)) ];
+ const unsigned int w= EXT(exp)[ MINUS1 - (n<<(SHIFT-logSize)) ];
const unsigned int a= p[n ];
const unsigned int b= prod(p[n + size], w);
@@ -235,7 +208,7 @@ static void ifftn(GFF4Element *p, int lo
}
-void noe_gfft(GFF4Element *dst, GFF4Element *src, int logSize){
+void EXT(gfft)(GFF4Element *dst, GFF4Element *src, int logSize){
// int i, j, pass;
//printf("%X %X\n", noe_exp[4096], noe_exp[3*4096]);
@@ -258,7 +231,7 @@ void noe_gfft(GFF4Element *dst, GFF4Elem
const int bot= top + np;
for(n=0; n<np; n++){
- const unsigned int w= noe_exp[ n<<pass ];
+ const unsigned int w= EXT(exp)[ n<<pass ];
const unsigned int a= dst[top + n];
const unsigned int b= dst[bot + n];
@@ -279,7 +252,7 @@ STOP_TIMER}
#endif
}
-void noe_igfft(GFF4Element *dst, GFF4Element *src, int logSize){
+void EXT(igfft)(GFF4Element *dst, GFF4Element *src, int logSize){
assert(logSize>=5);
if(src!=dst)
Modified: trunk/noe/gfft.h
==============================================================================
--- trunk/noe/gfft.h (original)
+++ trunk/noe/gfft.h Tue Jul 10 00:48:14 2007
@@ -17,14 +17,17 @@
*/
void noe_gfft_init();
-void noe_gfft(GFF4Element *dst, GFF4Element *src, int size);
-void noe_igfft(GFF4Element *dst, GFF4Element *src, int size);
-void noe_permute(GFF4Element *dst, GFF4Element *src, int outCount);
-int noe_log2(unsigned int v);
+void EXT(gfft)(GFF4Element *dst, GFF4Element *src, int size);
+void EXT(igfft)(GFF4Element *dst, GFF4Element *src, int size);
+void EXT(permute)(GFF4Element *dst, GFF4Element *src, int outCount);
extern uint8_t noe_revTable[256];
-static inline unsigned int noe_bitReverse(unsigned int x){
+static inline unsigned int bitReverse(unsigned int x){
+#if SHIFT==16
return (noe_revTable[x&255]<<8) | (noe_revTable[x>>8]);
+#else
+ return noe_revTable[x];
+#endif
}
Modified: trunk/noe/noe.c
==============================================================================
--- trunk/noe/noe.c (original)
+++ trunk/noe/noe.c Tue Jul 10 00:48:14 2007
@@ -146,7 +146,7 @@ static int decode_header(NoeContext *n,
code[k+i]= get_c(&bs, 2);
}
- if(noe_rsDecode(code, erased, erasedCount, HEADER_PARITY_LENGTH) < 0)
+ if(EXT(rsDecode)(code, erased, erasedCount, HEADER_PARITY_LENGTH) < 0)
return -1;
for(i=HEADER_DATA_LENGTH; i<k; i++){
@@ -158,8 +158,8 @@ static int decode_header(NoeContext *n,
return -2;
}
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // EXT(printPoly)(gen, i);
+ // EXT(printPoly)(syn, i-1);
for(i=0; 2*i<HEADER_DATA_LENGTH; i++){
buffer[2*i+0]= code[ i] >> 8;
@@ -388,7 +388,7 @@ static int correct(NoeContext *n, noe_Rw
code[cw_id - first_cw][cw_pos]= 256*buffer[pos] + buffer[pos+1];
}
}
- if(noe_rsDecode(code, NULL/*erased*/, erasedCount, n->parityCount) < 0)
+ if(EXT(rsDecode)(code, NULL/*erased*/, erasedCount, n->parityCount) < 0)
uncorrectable++;
// write data
Modified: trunk/noe/noe_internal.h
==============================================================================
--- trunk/noe/noe_internal.h (original)
+++ trunk/noe/noe_internal.h Tue Jul 10 00:48:14 2007
@@ -39,12 +39,12 @@ uint64_t tstart= rdtsc();\
#define STOP_TIMER \
tend= rdtsc();\
-if(tcount<2 || tend - tstart < 4*tsum/tcount){\
+if(tcount<2 || tend - tstart < 16*tsum/tcount){\
tsum+= tend - tstart;\
tcount++;\
}else\
tskip_count++;\
-if(256*256*256*64%tcount==0){\
+if(256*256*256*64%(tskip_count+tcount)==0){\
fprintf(stderr, "%Ld dezicycles, %d runs, %d skips\n", tsum*10/tcount, tcount, tskip_count);\
fflush(stderr);\
}
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:48:14 2007
@@ -34,31 +34,37 @@
/**
*
*/
-void noe_getRsGenerator(GFF4Element *dst, int first, int order){
+void EXT(getRsGenerator)(GFF4Element *dst, int first, int order){
int i;
GFF4Element factor[3*order];
for(i=0; i<order; i++){
- SET_POLY1(factor+3*i, SIZE - noe_exp[ first + i ], 1);
+ SET_POLY1(factor+3*i, neg(EXT(exp)[ first + i ]), 1);
}
- noe_synthPoly(dst, factor, order);
+ EXT(synthPoly)(dst, factor, order);
}
-void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order){
+void EXT(getSyndrom)(GFF4Element *syn, GFF4Element *src, int order){
*syn++= order;
- noe_gfft(syn, src, 16);
- noe_permute(syn, syn, order+1);
-
- syn[0]= 1;
-#if 0
+#if M==0
+ EXT(gfft)(syn, src, SHIFT);
+ EXT(permute)(syn, syn, order+1);
+#else
+{
+ int i;
+ int bak= src[-1];
+ src[-1]= SIZE-2;
for(i=0; i<order; i++){
- syn[i+1]= noe_evalPoly(src, SIZE-2, noe_exp[1 + i]);
+ syn[i+1]= EXT(evalPoly)(src-1, EXT(exp)[1 + i]);
}
+ src[-1]= bak;
+}
#endif
+ syn[0]= 1;
}
#if 1
-noe_RsEncoder *noe_getRsEncoder(int parityCount){
+noe_RsEncoder *EXT(getRsEncoder)(int parityCount){
const int dataCount= SIZE - parityCount - 1;
int i;
GFF4Element *locator, *factor;
@@ -72,36 +78,36 @@ noe_RsEncoder *noe_getRsEncoder(int pari
encoder->parityCount= parityCount;
for(i=0; i<parityCount; i++){
- SET_POLY1(locationFactor+3*i, 1, SIZE - noe_exp[dataCount + i]);
+ SET_POLY1(locationFactor+3*i, 1, neg(EXT(exp)[dataCount + i]));
}
- noe_synthPoly(locator, locationFactor, parityCount);
+ EXT(synthPoly)(locator, locationFactor, parityCount);
#if 0
for(i=0; i<parityCount; i++){
- if(noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount + i]))){
+ if(EXT(evalPoly)(locator, inv(EXT(exp)[dataCount + i]))){
printf("Internal Error 1\n");
}
}
-if(!noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount - 1])))
+if(!EXT(evalPoly)(locator, inv(EXT(exp)[dataCount - 1])))
printf("Internal Error 2\n");
#endif
- noe_getDerivative(locatorDerivative, locator);
+ EXT(getDerivative)(locatorDerivative, locator);
assert(locatorDerivative[0] == parityCount-1);
for(i=0; i<parityCount; i++){
- GFF4Element X= noe_exp[dataCount + i];
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+ GFF4Element X= EXT(exp)[dataCount + i];
+ GFF4Element invX= EXT(exp)[MINUS1 - (dataCount + i)];
GFF4Element denom;
assert(X == inv(invX));
- denom= noe_evalPoly(locatorDerivative, invX); //FIXME do in freq domain if parityCount>1000
- factor[i]= prod(SIZE - X, inv(denom));
+ denom= EXT(evalPoly)(locatorDerivative, invX); //FIXME do in freq domain if parityCount>1000
+ factor[i]= prod(X, inv(denom));
}
return encoder;
}
-void noe_freeRsEncoder(noe_RsEncoder *encoder){
+void EXT(freeRsEncoder)(noe_RsEncoder *encoder){
if(!encoder) return;
if(encoder->parityLocator) free(encoder->parityLocator);
@@ -116,7 +122,7 @@ void noe_freeRsEncoder(noe_RsEncoder *en
/**
*
*/
-void noe_rsEncode(noe_RsEncoder *encoder, GFF4Element *data){
+void EXT(rsEncode)(noe_RsEncoder *encoder, GFF4Element *data){
int i;
const int parityCount= encoder->parityCount;
const int dataCount= SIZE - parityCount - 1;
@@ -127,47 +133,35 @@ void noe_rsEncode(noe_RsEncoder *encoder
memset(data + dataCount, 0, parityCount*sizeof(GFF4Element));
- noe_getSyndrom(syn, data, parityCount);
+ EXT(getSyndrom)(syn, data, parityCount);
- noe_partialProdPoly(omega, locator, syn, syn[0]);
-
- if(parityCount < 1000){
+ EXT(partialProdPoly)(omega, locator, syn, syn[0]);
+
+ if(parityCount < 1000 || M){
for(i=0; i<parityCount; i++){
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+ GFF4Element invX= EXT(exp)[MINUS1 - (dataCount + i)];
- GFF4Element parity= prod(noe_evalPoly(omega, invX), factor[i]);
+ GFF4Element parity= prod(EXT(evalPoly)(omega, invX), factor[i]);
- data[dataCount + i]= SIZE - parity;
+ data[dataCount + i]= parity;
}
}else{
-//START_TIMER
-#if 0
- for(i=0; i<parityCount; i++){
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
-
- GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
-
- data[dataCount + i]= SIZE - parity;
- }
-#else
memset(omega + parityCount + 1 + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
- noe_gfft(omega+1, omega+1, 16);
+ EXT(gfft)(omega+1, omega+1, SHIFT);
for(i=0; i<parityCount; i++){
int index= SIZE - dataCount - i - 1;
- GFF4Element parity= prod(omega[noe_bitReverse(index)+1], factor[i]);
+ GFF4Element parity= prod(omega[bitReverse(index)+1], factor[i]);
- data[dataCount + i]= SIZE - parity;
+ data[dataCount + i]= parity;
}
-#endif
-//STOP_TIMER
}
}
#endif
#define XCHG(a,b) {void *tmp= a; a= b; b= tmp;}
-static void lehmer(GFF4Element *ma[2], GFF4Element *mb[2], GFF4Element *a, GFF4Element *b, int len){
+static void hgcd(GFF4Element *ma[2], GFF4Element *mb[2], GFF4Element *a, GFF4Element *b, int len){
int j;
int end= a[0] + b[0] - len;
assert(a[0] >= b[0]);
@@ -189,19 +183,20 @@ static void lehmer(GFF4Element *ma[2], G
max= a[0] - a_tmp[0];
memcpy(a_tmp+1, a+1+a[0]-a_tmp[0], (a_tmp[0]+1)*sizeof(GFF4Element));
memcpy(b_tmp+1, b+1+b[0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
- lehmer(ma, mb, a_tmp, b_tmp, len2);
+ hgcd(ma, mb, a_tmp, b_tmp, len2);
max+= NOE_MAX(a_tmp[0], b_tmp[0]);
- noe_partialProdPoly(a_tmp, b, ma[1], max);
- noe_partialProdPoly(b_tmp, a, mb[0], max);
- noe_partialProdPoly(a , a, ma[0], max);
- noe_partialProdPoly(b , b, mb[1], max);
- noe_sumPoly(a, a, a_tmp);
- noe_sumPoly(b, b, b_tmp);
+ EXT(partialProdPoly)(a_tmp, b, ma[1], max);
+ EXT(partialProdPoly)(b_tmp, a, mb[0], max);
+ EXT(partialProdPoly)(a , a, ma[0], max);
+ EXT(partialProdPoly)(b , b, mb[1], max);
+ EXT(sumPoly)(a, a, a_tmp);
+ EXT(sumPoly)(b, b, b_tmp);
len2= a[0] + b[0] - end;
//printf("Mid %d %d %d len2=%d\n", level, a[0], b[0], len2);
- if(len2 == 0)
+
+ if(len2 == 0 || a[ a[0] + 1 ]==0)
return;
assert(len2>0);
@@ -215,23 +210,10 @@ static void lehmer(GFF4Element *ma[2], G
j= b[0] + 1 - len2;
a[j]= a[0] - j;
b[j]= b[0] - j;
- lehmer(ma2, mb2, a + j, b + j, len2);
+ hgcd(ma2, mb2, a + j, b + j, len2);
//printf("End %d %d %d\n", level, a[0], b[0]);
-
- noe_prodPoly(a_tmp, ma[0], mb2[0]);
- noe_prodPoly(ma[0], ma[0], ma2[0]);
- noe_prodPoly(b_tmp, mb[0], ma2[1]);
- noe_prodPoly(mb[0], mb[0], mb2[1]);
- noe_sumPoly(ma[0], ma[0], b_tmp);
- noe_sumPoly(mb[0], mb[0], a_tmp);
-
- noe_prodPoly(a_tmp, ma[1], mb2[0]);
- noe_prodPoly(ma[1], ma[1], ma2[0]);
- noe_prodPoly(b_tmp, mb[1], ma2[1]);
- noe_prodPoly(mb[1], mb[1], mb2[1]);
- noe_sumPoly(ma[1], ma[1], b_tmp);
- noe_sumPoly(mb[1], mb[1], a_tmp);
+ EXT(prodMatrix)(ma, mb, ma2, mb2);
}else{
SET_POLY0(ma[0], 1);
SET_POLY0(ma[1], 0);
@@ -251,13 +233,12 @@ static void lehmer(GFF4Element *ma[2], G
}
a[0]--;
- noe_scaledSumPoly(ma[0], ma[0], mb[0], q, s);
- noe_scaledSumPoly(ma[1], ma[1], mb[1], q, s);
+ EXT(scaledSumPoly)(ma[0], ma[0], mb[0], q, s);
+ EXT(scaledSumPoly)(ma[1], ma[1], mb[1], q, s);
- noe_getOrder(a);
- if(a[0] + b[0] <= end)
+ EXT(getOrder)(a);
+ if(a[0] + b[0] <= end || a[a[0] + 1]==0)
return;
- assert(a[0]!=0 || a[1]!=0);
if(a[0] < b[0]){
XCHG(a,b)
@@ -267,7 +248,7 @@ static void lehmer(GFF4Element *ma[2], G
}
}
-int noe_rsEuclid2(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+static int rsSchoenhage(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
int i;
GFF4Element quot[parityCount+2]; //FIXME size ok?
@@ -292,7 +273,7 @@ int noe_rsEuclid2(GFF4Element *locator[2
if(2*omega[si][0] <= parityCount + erasureCount)
return si;
- if(len > omega[si][0]+1) len=omega[si][0]+1;
+ assert(len <= omega[si][0]+1);
if(len>128 && omega[si][0]/2 < len) len= omega[si][0]/2;
assert(omega[si][ omega[si][0]+1 ]);
@@ -303,22 +284,22 @@ int noe_rsEuclid2(GFF4Element *locator[2
memcpy(b_tmp+1, omega[si]+1+omega[si][0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
assert(b_tmp[ b_tmp[0]+1 ]);
//printf("In 0 %d %d\n", omega[di][0], omega[si][0]);
- lehmer(ma, mb, a_tmp, b_tmp, len);
+ hgcd(ma, mb, a_tmp, b_tmp, len);
max= omega[si][0] - (len-1) + NOE_MAX(a_tmp[0], b_tmp[0]);
- noe_partialProdPoly(a_tmp, omega[si], ma[1], max);
- noe_partialProdPoly(b_tmp, omega[di], mb[0], max);
- noe_partialProdPoly(omega[di], omega[di], ma[0], max);
- noe_partialProdPoly(omega[si], omega[si], mb[1], max);
- noe_sumPoly(omega[di], omega[di], a_tmp);
- noe_sumPoly(omega[si], omega[si], b_tmp);
+ EXT(partialProdPoly)(a_tmp, omega[si], ma[1], max);
+ EXT(partialProdPoly)(b_tmp, omega[di], mb[0], max);
+ EXT(partialProdPoly)(omega[di], omega[di], ma[0], max);
+ EXT(partialProdPoly)(omega[si], omega[si], mb[1], max);
+ EXT(sumPoly)(omega[di], omega[di], a_tmp);
+ EXT(sumPoly)(omega[si], omega[si], b_tmp);
- noe_prodPoly(a_tmp, locator[si], ma[1]);
- noe_prodPoly(b_tmp, locator[di], mb[0]);
- noe_prodPoly(locator[di], locator[di], ma[0]);
- noe_prodPoly(locator[si], locator[si], mb[1]);
- noe_sumPoly(locator[di], locator[di], a_tmp);
- noe_sumPoly(locator[si], locator[si], b_tmp);
+ EXT(prodPoly)(a_tmp, locator[si], ma[1]);
+ EXT(prodPoly)(b_tmp, locator[di], mb[0]);
+ EXT(prodPoly)(locator[di], locator[di], ma[0]);
+ EXT(prodPoly)(locator[si], locator[si], mb[1]);
+ EXT(sumPoly)(locator[di], locator[di], a_tmp);
+ EXT(sumPoly)(locator[si], locator[si], b_tmp);
if(omega[si][0] < omega[di][0])
i++;
@@ -329,7 +310,7 @@ int noe_rsEuclid2(GFF4Element *locator[2
* ...
* @param omega must be parityCount+2 big
*/
-int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+static int rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
int i;
GFF4Element quot[parityCount+2]; //FIXME size ok?
@@ -346,10 +327,10 @@ int noe_rsEuclid(GFF4Element *locator[2]
if(2*omega[si][0] <= parityCount + erasureCount)
return si;
- noe_divPoly(quot, omega[di], omega[di], omega[si]);
+ EXT(divPoly)(quot, omega[di], omega[di], omega[si]);
- noe_prodPoly(quot, quot, locator[si]);
- noe_diffPoly(locator[di], locator[di], quot);
+ EXT(prodPoly)(quot, quot, locator[si]);
+ EXT(diffPoly)(locator[di], locator[di], quot);
}
}
@@ -357,10 +338,10 @@ int noe_rsEuclid(GFF4Element *locator[2]
* ...
* @param omega must be parityCount+2 big
*/
-int noe_rsBerlekampMassey(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+static int rsBerlekampMassey(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
GFF4Element *syn= omega[1]+1; //yeah maybe we should clean this ...
int k, j;
- GFF4Element oldDelta=0x10000;
+ GFF4Element oldDelta=MINUS1;
GFF4Element *Tix= locator[0]+1;
GFF4Element *Lix= locator[1]+1;
GFF4Element *temp;
@@ -375,7 +356,11 @@ int noe_rsBerlekampMassey(GFF4Element *l
GFF4Element delta= syn[k];
for(j=1; j<=Lix[-1]; j++)
+#if M!=0
+ delta^= prod(Lix[j], syn[k-j]);
+#else
delta+= prod(Lix[j], syn[k-j]);
+#endif
delta= reduce(delta);
if(delta){
@@ -401,7 +386,7 @@ int noe_rsBerlekampMassey(GFF4Element *l
Tix[j]= Lix[j];
Tshift=0;
temp= Tix; Tix= Lix; Lix= temp;
- oldDelta= SIZE - inv(delta);
+ oldDelta= neg(inv(delta));
Lix[-1]= k2 - Tix[-1];
}
}
@@ -412,19 +397,19 @@ int noe_rsBerlekampMassey(GFF4Element *l
assert(Lix[0]==1);
k= Tix-1 == locator[0];
- noe_partialProdPoly(omega[k], Lix-1, syn-1, syn[-1]);
+ EXT(partialProdPoly)(omega[k], Lix-1, syn-1, syn[-1]);
return k;
}
-int noe_rsDecode(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
+int EXT(rsDecode)(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
int i;
int errorCount, gfftEval, phantomErrorCount;
const int dataCount= SIZE - 1 - parityCount;
GFF4Element erasureLocator[erasureCount + 1];
GFF4Element erasureSynthSrc[erasureCount*3 + 1];
- GFF4Element locator0[parityCount + 1 + 1];
- GFF4Element locator1[parityCount + 1 + 1];
+ GFF4Element locator0[SIZE]; //[parityCount + 1 + 1];
+ GFF4Element locator1[SIZE]; //[parityCount + 1 + 1];
GFF4Element *locators[2]={locator0, locator1};
GFF4Element omega0[SIZE - 1 + 1];
GFF4Element omega1[SIZE - 1 + 1];
@@ -439,7 +424,7 @@ int noe_rsDecode(GFF4Element *data, int
data[ erasure[i] ]=0;
}
- noe_getSyndrom(syn, data, parityCount);
+ EXT(getSyndrom)(syn, data, parityCount);
for(i=1; i<=parityCount; i++){
if(syn[i+1]) break;
}
@@ -450,20 +435,21 @@ int noe_rsDecode(GFF4Element *data, int
//FIXME check truncated symbols syndrom
for(i=0; i<erasureCount; i++){
- SET_POLY1(erasureSynthSrc + 3*i, 1, SIZE - noe_exp[erasure[i]]);
+ SET_POLY1(erasureSynthSrc + 3*i, 1, neg(EXT(exp)[erasure[i]]));
}
- noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
-// noe_printPoly(erasureLocator, erasureCount);
-#if 0
+ EXT(synthPoly)(erasureLocator, erasureSynthSrc, erasureCount);
+// EXT(printPoly)(erasureLocator, erasureCount);
+#if 1
for(i=0; i<erasureCount; i++){
- int eval= noe_evalPoly(erasureLocator, erasureCount, inv(noe_exp[erasure[i]]));
+ int eval= EXT(evalPoly)(erasureLocator, inv(EXT(exp)[erasure[i]]));
assert( eval==0);
}
#endif
- noe_partialProdPoly(syn, erasureLocator, syn, syn[0]);
+ EXT(partialProdPoly)(syn, erasureLocator, syn, syn[0]);
START_TIMER
-// i= noe_rsBerlekampMassey(locators, omegas, parityCount, erasureCount);
- i= noe_rsEuclid2(locators, omegas, parityCount, erasureCount);
+ i= rsBerlekampMassey(locators, omegas, parityCount, erasureCount);
+// i= rsEuclid(locators, omegas, parityCount, erasureCount);
+// i= rsSchoenhage(locators, omegas, parityCount, erasureCount);
STOP_TIMER
//printf("errorCount %d \n", errorCount);
@@ -475,42 +461,57 @@ STOP_TIMER
fErrorLocator= omegas[1-i]; //reuse some unused space
psi= locators[1-i]; //reuse some unused space
- gfftEval= errorCount>20;
- if(gfftEval && errorCount){
+ gfftEval= (errorCount>20) + (errorCount>1024); //FIXME finetune thresholds
+ if(M) gfftEval=0;
+ if(gfftEval){
memcpy(fErrorLocator, errorLocator+1, (errorCount+1)*sizeof(GFF4Element));
memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
- noe_gfft(fErrorLocator, fErrorLocator, 16);
+ EXT(gfft)(fErrorLocator, fErrorLocator, SHIFT);
}
- noe_prodPoly(psi, errorLocator, erasureLocator);
- noe_getDerivative(psi, psi);
+ EXT(prodPoly)(psi, errorLocator, erasureLocator);
+ EXT(getDerivative)(psi, psi);
+
+ if(gfftEval>1){
+ memset(omega + omega[0] + 2, 0, (SIZE - omega[0] - 2)*sizeof(GFF4Element));
+ memset(psi + psi [0] + 2, 0, (SIZE - psi [0] - 2)*sizeof(GFF4Element));
+ omega++;
+ psi++;
+ EXT(gfft)(omega, omega, SHIFT);
+ EXT(gfft)(psi , psi , SHIFT);
+ }
if(errorCount){
for(i=0; i<SIZE-1; i++){
int r, e;
- GFF4Element X, invX, nom, denom;
+ GFF4Element X, nom, denom;
if(gfftEval){ //FIXME optimize
if(fErrorLocator[i])
continue;
- r= (- noe_bitReverse(i))&0xFFFF;
+ r= i ? MINUS1 - bitReverse(i) : 0; //FIXME i=0 <->MINUS1 ?
}else{
- if(noe_evalPoly(errorLocator, noe_exp[i]))
+ if(EXT(evalPoly)(errorLocator, EXT(exp)[i]))
continue;
- r= (-i)&0xFFFF;
+ r= i ? MINUS1 - i : 0;
}
//printf("E%6d %6d\n", i, r);
- X = noe_exp[r];
- invX= noe_exp[SIZE - r - 1];
- nom= prod(X, noe_evalPoly(omega, invX));
- denom= noe_evalPoly(psi, invX);
+ X= EXT(exp)[r];
+ if(gfftEval>1){
+ nom= prod(X, omega[i]);
+ denom= psi[i];
+ }else{
+ GFF4Element invX= EXT(exp)[MINUS1 - r];
+ nom= prod(X, EXT(evalPoly)(omega, invX));
+ denom= EXT(evalPoly)(psi, invX);
+ }
assert(r>=0 && r<=SIZE-2);
e= prod(nom, inv(denom));
- if(data[r]==0 && e==0x10000){
+ if(data[r]==0 && e==MINUS1){
if(r < dataCount)
return -1;
else
@@ -522,15 +523,20 @@ STOP_TIMER
for(i=0; i<erasureCount; i++){
const int r= erasure[i];
- const GFF4Element X = noe_exp[r];
- const GFF4Element invX= noe_exp[SIZE - r - 1];
+ const GFF4Element X = EXT(exp)[r];
GFF4Element nom, denom;
- assert(r>=0 && r<0x10000);
- assert(prod(X, invX)==1);
+ assert(r>=0 && r<MINUS1);
- nom= prod(X, noe_evalPoly(omega, invX));
- denom= noe_evalPoly(psi, invX);
+ if(gfftEval>1){
+ int i2= bitReverse(MINUS1 - r);
+ nom= prod(X, omega[i2]);
+ denom= psi[i2];
+ }else{
+ const GFF4Element invX= EXT(exp)[MINUS1 - r];
+ nom= prod(X, EXT(evalPoly)(omega, invX));
+ denom= EXT(evalPoly)(psi, invX);
+ }
assert(data[r]==0);
data[r]= prod(nom, inv(denom));
Modified: trunk/noe/rs.h
==============================================================================
--- trunk/noe/rs.h (original)
+++ trunk/noe/rs.h Tue Jul 10 00:48:14 2007
@@ -22,20 +22,20 @@ typedef struct noe_RsEncoder{
GFF4Element *parityFactor;
}noe_RsEncoder;
-void noe_getRsGenerator(GFF4Element *dst, int first, int order);
+void EXT(getRsGenerator)(GFF4Element *dst, int first, int order);
/**
* gets the syndroms.
* @param src a 2^16 entry long polynom
* @param syn the syndrom polynom will be stored here
*/
-void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order);
-noe_RsEncoder *noe_getRsEncoder(int parityOrder);
-void noe_freeRsEncoder(noe_RsEncoder *encoder);
+void EXT(getSyndrom)(GFF4Element *syn, GFF4Element *src, int order);
+noe_RsEncoder *EXT(getRsEncoder)(int parityOrder);
+void EXT(freeRsEncoder)(noe_RsEncoder *encoder);
/**
*
*/
-void noe_rsEncode(noe_RsEncoder *encoder, GFF4Element *data);
+void EXT(rsEncode)(noe_RsEncoder *encoder, GFF4Element *data);
-int noe_rsDecode(GFF4Element *data, int *erased, int erasedCount, int parityCount);
+int EXT(rsDecode)(GFF4Element *data, int *erased, int erasedCount, int parityCount);
Modified: trunk/noe/rw.h
==============================================================================
--- trunk/noe/rw.h (original)
+++ trunk/noe/rw.h Tue Jul 10 00:48:14 2007
@@ -19,9 +19,6 @@
#define RW_SIZE (1<<18)
typedef struct noe_RwContext{
- uint8_t buffer[RW_SIZE];
- uint64_t pos;
- int flush;
uint64_t size;
/**
@@ -40,5 +37,3 @@ typedef struct noe_Map{
uint64_t len;
}noe_Map;
-uint64_t noe_read(noe_RwContext *c, uint64_t pos, int len);
-void noe_write(noe_RwContext *c, uint64_t pos, int len, uint64_t v);
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:48:14 2007
@@ -55,11 +55,11 @@ int main(){
int i, j;
GFF4Element bp=1;
- noe_init();
+ EXT(init)();
- printf("Testing GF(65537)\n");
+ printf("Testing GF(%d)\n", SIZE);
for(i=0; i<SIZE-1; i++){
- if((bp==1 || bp==0) && i>0){
+ if(bp==0 || (bp==1 && i>0) || bp >= SIZE){
printf("FAIL %d %d\n", i, bp);
break;
}
@@ -86,7 +86,7 @@ int main(){
}
#endif
srand (31415);
-#if 0
+ if(!M){
printf("Testing GFFT");
for(i=1; i<20; i++){
int n= SIZE - 1;
@@ -95,32 +95,33 @@ int main(){
int acc=0;
for(j=0; j<n; j++)
- code[j]= rand() % 0x10001;
+ code[j]= rand() % SIZE;
- noe_gfft(syn, code, 16);
+ EXT(gfft)(syn, code, SHIFT);
for(j=0; j<n; j++){
acc+= syn[j];
acc*=2*j+1;
}
- if(gfftChecksums[i-1] != acc)
+ if(gfftChecksums[i-1] != acc && SHIFT == 16)
printf("FAIL: 0x%08X != 0x%08X\n", gfftChecksums[i-1], acc);
- noe_igfft(syn, syn, 16);
+ EXT(igfft)(syn, syn, SHIFT);
for(j=0; j<n; j++){
- syn[j]= prod(syn[j], inv(1<<16));
+ syn[j]= prod(syn[j], inv(MINUS1));
}
for(j=0; j<n; j++){
if(syn[j] != code[j]) printf("IGFFT missmatch at %d %X!=%X\n", j, syn[j], code[j]);
}
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
+// EXT(printPoly)(gen, i);
+// EXT(printPoly)(syn, i-1);
printf("."); fflush(stdout);
}
-
+ }
+#if 1
srand (31415);
printf("\nTesting generator polynoms");
@@ -134,16 +135,16 @@ int main(){
data[0]= k-1;
for(j=0; j<k; j++)
- data[j+1]= rand() & 0xFFFF;
+ data[j+1]= rand() & MASK;
- noe_getRsGenerator(gen, 1, i);
- noe_prodPoly(code, gen, data);
+ EXT(getRsGenerator)(gen, 1, i);
+ EXT(prodPoly)(code, gen, data);
assert(code[0]==n-1);
- noe_getSyndrom(syn, code+1, i);
+ EXT(getSyndrom)(syn, code+1, i);
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
+// EXT(printPoly)(gen, i);
+// EXT(printPoly)(syn, i-1);
for(j=0; j<i; j++){
if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
@@ -152,7 +153,7 @@ int main(){
}
printf("\nTesting encoder");
- for(i=1; i<1000; i+=200){
+ for(i=1; i<1000 && i<SIZE/2; i+=i+5){
int n= SIZE - 1;
int k= SIZE - 1 - i;
GFF4Element syn[n+1];
@@ -162,32 +163,32 @@ int main(){
noe_RsEncoder *encoder;
int pass=5;
- encoder= noe_getRsEncoder(i);
+ encoder= EXT(getRsEncoder)(i);
for(pass=5; pass; pass--){
for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ data[j]= rand() & MASK;
memcpy(code, data, n*sizeof(GFF4Element));
- noe_rsEncode(encoder, code);
+ EXT(rsEncode)(encoder, code);
- noe_getSyndrom(syn, code, i);
+ EXT(getSyndrom)(syn, code, i);
//FIXME check that code contains data, but its not touched so ...
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // EXT(printPoly)(gen, i);
+ // EXT(printPoly)(syn, i-1);
for(j=0; j<i; j++){
if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
}
printf("."); fflush(stdout);
}
- noe_freeRsEncoder(encoder);
+ EXT(freeRsEncoder)(encoder);
}
#endif
printf("\nTesting decoder");
- for(i=1; i<5000; i+=100){
+ for(i=1; i<2000 && i<SIZE/2; i+=(SIZE == 0x10001 ? 100 : 10)){
int n= SIZE - 1;
int k= SIZE - 1 - i;
// GFF4Element syn[n];
@@ -197,16 +198,16 @@ int main(){
noe_RsEncoder *encoder;
int pass=5;
- encoder= noe_getRsEncoder(i);
+ encoder= EXT(getRsEncoder)(i);
for(pass=5; pass; pass--){
int erasedCount, errorCount;
for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ data[j]= rand() & MASK;
memcpy(code, data, n*sizeof(GFF4Element));
- noe_rsEncode(encoder, code);
+ EXT(rsEncode)(encoder, code);
erasedCount=0;
if(rand()&0x40){
@@ -214,15 +215,15 @@ int main(){
for(j=0; j<erasedCount; j++){
int e=-1;
- while(e==-1 || code[e]==0x10000) e=rand()%n;
+ while(e==-1 || code[e]==MINUS1) e=rand()%n;
erased[j]= e;
- code[ e ]= 0x10000;
+ code[ e ]= MINUS1;
}
for(j=0; j<erasedCount; j++){
int e= erased[j];
- code[ e ]= rand()%0xFFFF;
+ code[ e ]= rand()&MASK;
}
}
errorCount=0;
@@ -232,16 +233,16 @@ int main(){
errorCount= (rand() % max)+1;
for(j=0; j<errorCount; j++){
int pos= rand()%n;
- code[pos] = rand()%0xFFFF;
+ code[pos] = rand()&MASK;
// printf("P%6d\n", pos);
}
}
}
//printf("erased:%d errors:%d parity:%d\n", erasedCount, errorCount, i);
- noe_rsDecode(code, erased, erasedCount, i);
+ EXT(rsDecode)(code, erased, erasedCount, i);
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // EXT(printPoly)(gen, i);
+ // EXT(printPoly)(syn, i-1);
for(j=0; j<k; j++){
if(data[j]!=code[j]){
@@ -251,7 +252,7 @@ int main(){
}
printf("."); fflush(stdout);
}
- noe_freeRsEncoder(encoder);
+ EXT(freeRsEncoder)(encoder);
}
#if 0
{
@@ -294,10 +295,10 @@ return 0;
data[0]= k-1;
for(j=0; j<k; j++)
- data[j+1]= rand() & 0xFFFF;
+ data[j+1]= rand() & MASK;
- noe_getRsGenerator(gen, 1, i);
- noe_prodPoly(code, gen, data);
+ EXT(getRsGenerator)(gen, 1, i);
+ EXT(prodPoly)(code, gen, data);
assert(code[0]==n);
locator[0] = 0;
@@ -308,20 +309,20 @@ return 0;
if((rand()&7)==0 && j) continue;
- index= rand()%0xFFFF;
- SET_POLY1(locationFactor, 1, inv(noe_exp[index]));
- noe_prodPoly(locator, locator, locationFactor);
+ index= rand()%MASK;
+ SET_POLY1(locationFactor, 1, inv(EXT(exp)[index]));
+ EXT(prodPoly)(locator, locator, locationFactor);
code[index] = 0;
}
- noe_getSyndrom(syn, code+1, i);
- noe_prodPoly(omega, syn, locator);
-// noe_getDeriative(locator, locator, locatorOrder);
+ EXT(getSyndrom)(syn, code+1, i);
+ EXT(prodPoly)(omega, syn, locator);
+// EXT(getDeriative)(locator, locator, locatorOrder);
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
+// EXT(printPoly)(gen, i);
+// EXT(printPoly)(syn, i-1);
for(j=0; j<i; j++){
if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
1
0
09 Jul '07
Author: michael
Date: Tue Jul 10 00:42:52 2007
New Revision: 80
Log:
version from unknown date but definitly before 2006-06-16 20:48
Modified:
trunk/noe/filerw.c
trunk/noe/galois.c
trunk/noe/noe.c
trunk/noe/rs.c
trunk/noe/rw.c
trunk/noe/test.c
Modified: trunk/noe/filerw.c
==============================================================================
--- trunk/noe/filerw.c (original)
+++ trunk/noe/filerw.c Tue Jul 10 00:42:52 2007
@@ -45,7 +45,10 @@ static int fileIO(noe_RwContext *c, uint
uint64_t currentLen= pos - p->end[i];
if(currentLen > len) currentLen= len;
if(currentLen <= 0) return -1;
-
+
+ if(fseek(p->file[i], pos - (i ? p->end[i-1] : 0), SEEK_SET))
+ return -1;
+
if(write)
e= fwrite(data, currentLen, 1, p->file[i]);
else
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:42:52 2007
@@ -48,11 +48,21 @@ void noe_init(){
/**
* ...
*/
-int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+void noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+ const int order1= *src1++;
+ const int order2= *src2++;
int order= order1 + order2;
int i;
- if(order1*order2 < (order1+order2)*64){
+ if((order1==0 && src1[0]==0) ||
+ (order2==0 && src2[0]==0)){
+ SET_POLY0(dst, 0);
+ return;
+ }
+
+ *dst++= order;
+
+ if(order1*order2 <= (order1+order2)*64){
for(i=order; i>=0; i--){
unsigned int acc=0;
int j, end;
@@ -87,19 +97,23 @@ int noe_prodPoly(GFF4Element *dst, GFF4E
noe_igfft(temp[0], temp[0], logSize);
memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
}
-
- return order;
}
/**
* returns the first order2 coefficients of the product of the 2 polynoms.
* Note dst must be at least 2^log2(order1+order2) big FIXME benchmark if its worth it
*/
-int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
- const int order= order2;
+void noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order){
+ int order1= *src1++;
+ int order2= *src2++;
int i;
-
- if(order1*order2 < (order1+order2)*64){
+
+ *dst++= order;
+
+ if(order < order1) order1= order;
+ if(order < order2) order2= order;
+
+ if(order1*order2 <= (order1+order2)*64){
for(i=order; i>=0; i--){
unsigned int acc=0;
int j, end;
@@ -113,7 +127,7 @@ int noe_partialProdPoly(GFF4Element *dst
dst[i]= reduce(acc);
}
}else{
- const int logSize= noe_log2(order2 + order1)+1;
+ const int logSize= noe_log2(order1+order2)+1;
const int size= 1<<logSize;
GFF4Element temp[size]; //FIXME is this fast?
const GFF4Element scale= inv(size);
@@ -134,14 +148,14 @@ int noe_partialProdPoly(GFF4Element *dst
noe_igfft(dst, dst, logSize);
}
- return order;
+ noe_getOrder(dst-1);
}
-void noe_printPoly(GFF4Element *src, int order){
+void noe_printPoly(GFF4Element *src){
int i;
- for(i=order; i>=0; i--){
- printf(" + %X*x^%d", src[i], i);
+ for(i=src[0]+1; i>0; i--){
+ printf(" + %X*x^%d", src[i], i-1);
}
printf("\n");
}
@@ -149,25 +163,24 @@ void noe_printPoly(GFF4Element *src, int
/**
* Evaluates the src polynom at x.
*/
-GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x){
+GFF4Element noe_evalPoly(GFF4Element *src, GFF4Element x){
unsigned int acc=0;
int j;
- for(j=order; j>=0; j--){
+ for(j=src[0]+1; j>0; j--){
acc = sum(prod(acc, x), src[j]);
}
return acc;
}
-int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order){
+void noe_getDerivative(GFF4Element *dst, GFF4Element *src){
int i;
-
- for(i=0; i<order; i++){
- dst[i ]= prod(src[i+1], i+1);
- }
- return order-1;
+ for(i=1; i<=src[0]; i++){
+ dst[i ]= prod(src[i+1], i);
+ }
+ dst[0]= src[0]-1;
}
/**
@@ -177,10 +190,11 @@ void noe_synthPoly(GFF4Element *dst, GFF
if(count<20){
int i;
- dst[0]= 1;
+ SET_POLY0(dst, 1);
for(i=0; i<count; i++){
- noe_prodPoly(dst, dst, src+2*i, i, 1);
+ assert(src[3*i] == 1);
+ noe_prodPoly(dst, dst, src+3*i);
}
}else{
int pass, i, countLeft;
@@ -195,11 +209,10 @@ void noe_synthPoly(GFF4Element *dst, GFF
// noe_printPoly(src+2, 1);
for(i=0; i<(count>>1); i++){
- noe_prodPoly(temp[0]+4*i, src+4*i, src+4*i+2, 1, 1);
+ noe_prodPoly(temp[0]+4*i, src+6*i, src+6*i+3);
}
if(count&1){
- memcpy(temp[0]+4*i, src+4*i, 2*sizeof(GFF4Element));
- temp[0][4*i+2]= 0;
+ memcpy(temp[0]+4*i, src+6*i, 3*sizeof(GFF4Element));
countLeft++;
}
countLeft>>=1;
@@ -212,13 +225,11 @@ void noe_synthPoly(GFF4Element *dst, GFF
GFF4Element *temp2= temp[(pass&1)^1];
for(i=0; i<(countLeft>>1); i++){
- noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step, step>>1, step>>1);
+ noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step);
}
if(countLeft&1){
- int len= (step>>1) + 1;
- memcpy(temp1+2*step*i , temp2+2*step*i, len*sizeof(GFF4Element));
- memset(temp1+2*step*i + len , 0, step*sizeof(GFF4Element));
+ memcpy(temp1+2*step*i, temp2+2*step*i, step*sizeof(GFF4Element));
countLeft++;
}
countLeft>>=1;
@@ -228,31 +239,34 @@ void noe_synthPoly(GFF4Element *dst, GFF
// noe_printPoly(temp[0], count);
- memcpy(dst, temp[(pass&1)^1], (count+1)*sizeof(GFF4Element));
+ memcpy(dst, temp[(pass&1)^1], (count+2)*sizeof(GFF4Element));
// noe_printPoly(dst, count);
}
}
-int noe_getOrder(GFF4Element *src, int maxOrder){
- while(maxOrder && src[maxOrder]==0)
- maxOrder--;
-
- return maxOrder;
+void noe_getOrder(GFF4Element *src){
+ while(src[0] && src[ src[0] + 1 ]==0)
+ src[0]--;
}
/**
* ...
* Note: rem can be identical to nom
*/
-int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder){
+void noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom){
+ const int nomOrder= *nom++;
+ const int denomOrder= *denom++;
int i;
int remOrder= nomOrder;
- int quotOrder= 0;
+
+ *rem++= nomOrder;
+ *quot++= remOrder - denomOrder;
if(rem != nom)
memcpy(rem, nom, (nomOrder+1)*sizeof(GFF4Element));
- denomOrder= noe_getOrder(denom, denomOrder);
+ assert( nom[ nomOrder]);
+ assert(denom[denomOrder]);
quot[0]=0;
@@ -269,34 +283,85 @@ int noe_divPoly(GFF4Element *quot, GFF4E
}
quot[remOrder - denomOrder]= scale;
- if(quotOrder==0)
- quotOrder= remOrder - denomOrder;
}
-
- return noe_getOrder(rem, remOrder);
+
+ noe_getOrder(rem-1);
}
-int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+void noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+ const int order1= *src1++;
+ const int order2= *src2++;
int i;
int minOrder= NOE_MIN(order1, order2);
+ *dst++= order1;
+
for(i=0; i<=minOrder; i++){
dst[i]= sum(src1[i], SIZE - src2[i]);
}
if(order1==order2){
- return noe_getOrder(dst, order1);
+ noe_getOrder(dst-1);
}else{
- if(dst!=src1){
- for(; i<=order1; i++){
- dst[i]= src1[i];
- }
- }
+ if(dst!=src1)
+ memcpy(dst+i, src1+i, (i-1-order1)*sizeof(GFF4Element));
for(; i<=order2; i++){
dst[i]= SIZE - src2[i];
}
- return NOE_MAX(order1, order2);;
+ dst[-1]= NOE_MAX(order1, order2);
+ }
+}
+
+void noe_sumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2){
+ const int order1= *src1++;
+ const int order2= *src2++;
+ int i;
+ int minOrder= NOE_MIN(order1, order2);
+
+ *dst++= order1;
+
+ for(i=0; i<=minOrder; i++){
+ dst[i]= sum(src1[i], src2[i]);
+ }
+
+ if(order1==order2){
+ noe_getOrder(dst-1);
+ }else if(order1 < order2){
+ dst[-1]= order2;
+ if(dst!=src2)
+ memcpy(dst+i, src2+i, (order2 - order1)*sizeof(GFF4Element));
+ }else{
+ if(dst!=src1)
+ memcpy(dst+i, src1+i, (order1 - order2)*sizeof(GFF4Element));
+ }
+}
+
+void noe_scaledSumPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, GFF4Element f, int s){
+ const int order1= *src1++;
+ const int order2= *src2++; //FIXME +s
+ int i;
+ int minOrder= NOE_MIN(order1, order2+s);
+
+ *dst++= order1;
+
+ for(i=0; i<s; i++)
+ dst[i]= src1[i];
+ for( ; i<=minOrder; i++)
+ dst[i]= sum(src1[i], prod(src2[i-s], f));
+
+ if(order1==order2 + s){
+ noe_getOrder(dst-1);
+ }else{
+ if(dst!=src1)
+ memcpy(dst+i, src1+i, (order1+1-i)*sizeof(GFF4Element));
+
+ for(; i<=order2+s; i++){
+ dst[i]= prod(src2[i-s], f);
+ }
+
+ dst[-1]= NOE_MAX(order1, order2+s);
+ noe_getOrder(dst-1); //FIXME we need this due to src2= 0
}
}
Modified: trunk/noe/noe.c
==============================================================================
--- trunk/noe/noe.c (original)
+++ trunk/noe/noe.c Tue Jul 10 00:42:52 2007
@@ -46,6 +46,9 @@ typedef struct NoeContext{
int dataSize;
int fileIdThreshold;
int version;
+ int interleave;
+ int parity_per_header; ///< number of parity symbols (16bit) per header
+ int cw_per_pass;
// uint8_t header[HEADER_LENGTH];
int header[HEADER_LENGTH][256];
uint32_t *fingerprint;
@@ -113,12 +116,12 @@ static int decode_header(NoeContext *n,
const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
GFF4Element erased[HEADER_PARITY_LENGTH];
GFF4Element code[nn];
- int i,j;
+ int i,j,dataword_size, file_parity_size;
for(j=0; j<8; j++){
buffer[j] = startcode[j];
}
-
+
for(i=12; i<HEADER_DATA_LENGTH; i++){
int best=0;
int bestScore=0;
@@ -137,7 +140,7 @@ static int decode_header(NoeContext *n,
memset(code, 0, sizeof(GFF4Element)*nn);
for(i=0; 2*i<HEADER_DATA_LENGTH; i++){
- code[i ]= get_c(&bs, 2);
+ code[i ]= get_c(&bs, 2); //FIXME change to 1
}
for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
code[k+i]= get_c(&bs, 2);
@@ -186,6 +189,11 @@ static int decode_header(NoeContext *n,
n->fingerprintCount= get_c(&bs, 2);
n->dataSize= get_c(&bs, 8);
+ dataword_size= 2*(65535 - n->parityCount);
+ n->interleave= (n->dataSize + dataword_size - 1)/dataword_size;
+ file_parity_size= n->interleave * n->parityCount;
+ n->parity_per_header= (file_parity_size + n->headerCount - 1)/n->headerCount;
+
for(i=12; i<HEADER_DATA_LENGTH; i++){
n->header[i][ buffer[i] ]= INT_MAX/2;
}
@@ -199,14 +207,13 @@ static int decode_header(NoeContext *n,
* @return -1 if not found
*/
static int find_and_decode_global_header(NoeContext *n, noe_RwContext *rw){
- int length= BUFFER_LENGTH;
uint64_t i;
- uint8_t buffer[length];
+ uint8_t buffer[BUFFER_LENGTH];
- for(i=rw->size; i>=0; i-= length - HEADER_LENGTH){
+ for(i=rw->size; i>=0; i-= BUFFER_LENGTH - HEADER_LENGTH){
+ int length= MIN(BUFFER_LENGTH, i);
int pos;
- if(i < length) length= i;
rw->io(rw, buffer, i - length, length, 0);
for(pos=0; ; pos++){
@@ -222,7 +229,6 @@ static int find_and_decode_global_header
if( decode_header(n, buffer + pos) >= 0)
return 0;
}
- length= BUFFER_LENGTH;
}
return -1;
@@ -247,7 +253,7 @@ static int decode_fingerprints(NoeContex
const int index= n->seqNum + i*n->headerCount;
const int expectedChecksum= getChecksum(c, index);
- if(expectedChecksum == checksum){
+ if(expectedChecksum == checksum && !n->fingerprintOk[index]){
n->fingerprintOk[index]= 1;
n->fingerprint[index]= c;
n->fingerprintOk_count++;
@@ -261,19 +267,18 @@ static int decode_fingerprints(NoeContex
* @return -1 if not found
*/
static int find_and_decode_packets(NoeContext *n, noe_RwContext *rw){
- int length= BUFFER_LENGTH;
const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
uint64_t i;
- uint8_t buffer[length];
+ uint8_t buffer[BUFFER_LENGTH];
n->fingerprint = malloc(n->fingerprintCount*n->headerCount * sizeof(int));
n->fingerprintOk= malloc(n->fingerprintCount*n->headerCount);
memset(n->fingerprintOk, 0, n->fingerprintCount*n->headerCount);
- for(i=rw->size; i>=0; i-= length - packetLength){
+ for(i=rw->size; i>=0; i-= BUFFER_LENGTH - packetLength){
+ int length= MIN(BUFFER_LENGTH, i);
int pos;
- if(i < length) length= i;
rw->io(rw, buffer, i - length, length, 0);
for(pos=0; ; pos++){
@@ -287,9 +292,8 @@ static int find_and_decode_packets(NoeCo
decode_fingerprints(n, buffer + pos, length - pos);
}
- length= BUFFER_LENGTH;
- if(n->fingerprintOk_count >= n->fingerprintCount*n->headerCount*15/16)
+ if(n->fingerprintOk_count >= n->fingerprintCount*n->headerCount*15/16) //FIXME
break;
}
@@ -300,7 +304,7 @@ static int match_fingerprints(NoeContext
int length= BUFFER_LENGTH;
// const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
uint64_t i;
- uint8_t buffer[length];
+ uint8_t buffer[BUFFER_LENGTH];
for(i=0; i<n->fingerprintCount*n->headerCount; i++){
if(!n->fingerprintOk[i])
@@ -322,4 +326,81 @@ static int match_fingerprints(NoeContext
// setup remap table
}
-//decode data into another file
+//reorder data based on fingerprint matches
+
+static int correct(NoeContext *n, noe_RwContext *out, noe_RwContext *in){
+ uint8_t buffer[BUFFER_LENGTH];
+ int passes, pass, i;
+ const int nn= SIZE - 1;
+// const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
+ GFF4Element erased[/*HEADER_PARITY_LENGTH*/nn];
+ const int erasedCount=0;
+ GFF4Element (*code)[nn];
+ const int packet_size= HEADER_LENGTH + 5*n->fingerprintCount + 2*n->parity_per_header;
+ int uncorrectable=0;
+
+ assert(2*packet_size <= BUFFER_LENGTH);
+
+ n->cw_per_pass= 32; //4mb storege
+
+ code= malloc(n->cw_per_pass*nn*sizeof(GFF4Element));
+ passes= (n->interleave + n->cw_per_pass - 1) / n->cw_per_pass;
+
+ for(pass=0; pass<passes; pass++){
+ int first_cw= n->interleave* pass / passes;
+ int next_cw= n->interleave*(pass+1) / passes;
+
+ memset(code, 0, n->cw_per_pass*nn*sizeof(GFF4Element));
+
+ for(i=0; i<in->size; i+= BUFFER_LENGTH - packet_size){
+ int length= MIN(BUFFER_LENGTH, in->size - i);
+ int pos;
+
+ in->io(in, buffer, i, length, 0);
+
+ for(pos=0; ; pos++){
+ int j;
+ pos += find_header(n, buffer + pos, length - pos);
+ if(pos + packet_size > length) break;
+
+ if( decode_header(n, buffer + pos) < 0 )
+ continue;
+ pos += HEADER_LENGTH + 5*n->fingerprintCount;
+
+ for(j=0; j<n->parity_per_header; pos+=2, j++){
+ int j2= j + n->seqNum*n->parity_per_header;
+ int cw_id = j2 % n->interleave;//FIXME optimize
+ int cw_pos= j2 / n->interleave;
+ if(cw_id < first_cw || cw_id >= next_cw)
+ continue;
+ code[cw_id - first_cw][cw_pos]= 256*buffer[pos] + buffer[pos+1];
+ }
+ }
+
+ assert(i%2==0);
+ for(pos=0; pos<length; pos+=2){
+ int cw_id = ((i+pos)/2) % n->interleave; //FIXME optimize
+ int cw_pos= ((i+pos)/2) / n->interleave; //FIXME optimize
+ if(i+pos >= n->dataSize)
+ break;
+ if(cw_id < first_cw || cw_id >= next_cw)
+ continue;
+ code[cw_id - first_cw][cw_pos]= 256*buffer[pos] + buffer[pos+1];
+ }
+ }
+ if(noe_rsDecode(code, NULL/*erased*/, erasedCount, n->parityCount) < 0)
+ uncorrectable++;
+
+// write data
+ }
+
+ av_free(code);
+ return uncorrectable;
+}
+
+//main
+
+//encode mainheader
+//encode fingerprints
+//encoder parity
+
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:42:52 2007
@@ -28,25 +28,25 @@
#include "gfft.h"
+#undef NDEBUG
+#include <assert.h>
+
/**
*
*/
void noe_getRsGenerator(GFF4Element *dst, int first, int order){
int i;
- GFF4Element factor[2*order];
-
- factor[0]= SIZE - noe_exp[first];
- factor[1]= 1;
+ GFF4Element factor[3*order];
- for(i=1; i<order; i++){
- factor[2*i+0]= prod(factor[2*i-2], PRIMITIVE_ELEMENT);
- factor[2*i+1]= 1;
+ for(i=0; i<order; i++){
+ SET_POLY1(factor+3*i, SIZE - noe_exp[ first + i ], 1);
}
noe_synthPoly(dst, factor, order);
}
void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order){
+ *syn++= order;
noe_gfft(syn, src, 16);
noe_permute(syn, syn, order+1);
@@ -62,22 +62,19 @@ noe_RsEncoder *noe_getRsEncoder(int pari
const int dataCount= SIZE - parityCount - 1;
int i;
GFF4Element *locator, *factor;
- GFF4Element locatorDerivative[parityCount];
+ GFF4Element locatorDerivative[parityCount+1];
noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
+ GFF4Element locationFactor[3*parityCount];
- locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+1));
+ locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+2));
factor= encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount );
encoder->parityCount= parityCount;
- locator[0]= 1;
for(i=0; i<parityCount; i++){
- GFF4Element locationFactor[2];
-
- locationFactor[0] = 1;
- locationFactor[1] = SIZE - noe_exp[dataCount + i];
- noe_prodPoly(locator, locator, locationFactor, i, 1); //FIXME use synthPoly
+ SET_POLY1(locationFactor+3*i, 1, SIZE - noe_exp[dataCount + i]);
}
+ noe_synthPoly(locator, locationFactor, parityCount);
#if 0
for(i=0; i<parityCount; i++){
if(noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount + i]))){
@@ -87,8 +84,8 @@ for(i=0; i<parityCount; i++){
if(!noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount - 1])))
printf("Internal Error 2\n");
#endif
- i= noe_getDerivative(locatorDerivative, locator, parityCount);
- assert(i==parityCount-1);
+ noe_getDerivative(locatorDerivative, locator);
+ assert(locatorDerivative[0] == parityCount-1);
for(i=0; i<parityCount; i++){
GFF4Element X= noe_exp[dataCount + i];
@@ -97,7 +94,7 @@ if(!noe_evalPoly(locator, parityCount, i
assert(X == inv(invX));
- denom= noe_evalPoly(locatorDerivative, parityCount-1, invX); //FIXME do in freq domain if parityCount>1000
+ denom= noe_evalPoly(locatorDerivative, invX); //FIXME do in freq domain if parityCount>1000
factor[i]= prod(SIZE - X, inv(denom));
}
@@ -123,8 +120,8 @@ void noe_rsEncode(noe_RsEncoder *encoder
int i;
const int parityCount= encoder->parityCount;
const int dataCount= SIZE - parityCount - 1;
- GFF4Element syn[SIZE - 1];
- GFF4Element omega[SIZE - 1];
+ GFF4Element syn[SIZE];
+ GFF4Element omega[SIZE];
GFF4Element *locator= encoder->parityLocator;
GFF4Element *factor= encoder->parityFactor;
@@ -132,13 +129,13 @@ void noe_rsEncode(noe_RsEncoder *encoder
noe_getSyndrom(syn, data, parityCount);
- noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
+ noe_partialProdPoly(omega, locator, syn, syn[0]);
if(parityCount < 1000){
for(i=0; i<parityCount; i++){
GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
- GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+ GFF4Element parity= prod(noe_evalPoly(omega, invX), factor[i]);
data[dataCount + i]= SIZE - parity;
}
@@ -153,12 +150,12 @@ void noe_rsEncode(noe_RsEncoder *encoder
data[dataCount + i]= SIZE - parity;
}
#else
- memset(omega + parityCount + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
- noe_gfft(omega, omega, 16);
+ memset(omega + parityCount + 1 + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
+ noe_gfft(omega+1, omega+1, 16);
for(i=0; i<parityCount; i++){
int index= SIZE - dataCount - i - 1;
- GFF4Element parity= prod(omega[noe_bitReverse(index)], factor[i]);
+ GFF4Element parity= prod(omega[noe_bitReverse(index)+1], factor[i]);
data[dataCount + i]= SIZE - parity;
}
@@ -168,66 +165,269 @@ void noe_rsEncode(noe_RsEncoder *encoder
}
#endif
+#define XCHG(a,b) {void *tmp= a; a= b; b= tmp;}
+
+static void lehmer(GFF4Element *ma[2], GFF4Element *mb[2], GFF4Element *a, GFF4Element *b, int len){
+ int j;
+ int end= a[0] + b[0] - len;
+ assert(a[0] >= b[0]);
+
+// assert(len);
+//printf("In %d %d %d len=%d\n", level, a[0], b[0], len);
+ if(len > 256){
+ int max;
+ int len2= len>>1;
+ GFF4Element a_tmp[4*len];
+ GFF4Element b_tmp[4*len];
+ GFF4Element m2[4][2*len];
+ GFF4Element *ma2[2]= {m2[0], m2[1]};
+ GFF4Element *mb2[2]= {m2[2], m2[3]};
+ assert(len-1 <= a[0]);
+ assert(len-1 <= b[0]);
+ a_tmp[0]= a[0] - b[0] + len2-1;
+ b_tmp[0]= len2-1;
+ max= a[0] - a_tmp[0];
+ memcpy(a_tmp+1, a+1+a[0]-a_tmp[0], (a_tmp[0]+1)*sizeof(GFF4Element));
+ memcpy(b_tmp+1, b+1+b[0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
+ lehmer(ma, mb, a_tmp, b_tmp, len2);
+
+ max+= NOE_MAX(a_tmp[0], b_tmp[0]);
+
+ noe_partialProdPoly(a_tmp, b, ma[1], max);
+ noe_partialProdPoly(b_tmp, a, mb[0], max);
+ noe_partialProdPoly(a , a, ma[0], max);
+ noe_partialProdPoly(b , b, mb[1], max);
+ noe_sumPoly(a, a, a_tmp);
+ noe_sumPoly(b, b, b_tmp);
+ len2= a[0] + b[0] - end;
+//printf("Mid %d %d %d len2=%d\n", level, a[0], b[0], len2);
+ if(len2 == 0)
+ return;
+
+ assert(len2>0);
+ assert(len2 <= a[0]+1);
+ assert(len2 <= b[0]+1);
+
+ if(a[0] < b[0]){
+ XCHG(a,b);
+ XCHG(ma,mb);
+ }
+ j= b[0] + 1 - len2;
+ a[j]= a[0] - j;
+ b[j]= b[0] - j;
+ lehmer(ma2, mb2, a + j, b + j, len2);
+
+//printf("End %d %d %d\n", level, a[0], b[0]);
+
+ noe_prodPoly(a_tmp, ma[0], mb2[0]);
+ noe_prodPoly(ma[0], ma[0], ma2[0]);
+ noe_prodPoly(b_tmp, mb[0], ma2[1]);
+ noe_prodPoly(mb[0], mb[0], mb2[1]);
+ noe_sumPoly(ma[0], ma[0], b_tmp);
+ noe_sumPoly(mb[0], mb[0], a_tmp);
+
+ noe_prodPoly(a_tmp, ma[1], mb2[0]);
+ noe_prodPoly(ma[1], ma[1], ma2[0]);
+ noe_prodPoly(b_tmp, mb[1], ma2[1]);
+ noe_prodPoly(mb[1], mb[1], mb2[1]);
+ noe_sumPoly(ma[1], ma[1], b_tmp);
+ noe_sumPoly(mb[1], mb[1], a_tmp);
+ }else{
+ SET_POLY0(ma[0], 1);
+ SET_POLY0(ma[1], 0);
+ SET_POLY0(mb[0], 0);
+ SET_POLY0(mb[1], 1);
+
+ for(;;){
+ GFF4Element q= SIZE - prod(a[ a[0]+1 ], inv(b[ b[0]+1 ]));
+ int s= a[0] - b[0];
+
+ assert(s >= 0);
+ assert(a[ a[0]+1 ]);
+ assert(b[ b[0]+1 ]);
+
+ for(j=end - b[0] + 2; j<=a[0]; j++){
+ a[ j ] = sum(a[ j ], prod(q, b[ j-s ]));
+ }
+ a[0]--;
+
+ noe_scaledSumPoly(ma[0], ma[0], mb[0], q, s);
+ noe_scaledSumPoly(ma[1], ma[1], mb[1], q, s);
+
+ noe_getOrder(a);
+ if(a[0] + b[0] <= end)
+ return;
+ assert(a[0]!=0 || a[1]!=0);
+
+ if(a[0] < b[0]){
+ XCHG(a,b)
+ XCHG(ma,mb)
+ }
+ }
+ }
+}
+
+int noe_rsEuclid2(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+ int i;
+ GFF4Element quot[parityCount+2]; //FIXME size ok?
+
+ omega[0][0]= parityCount+1;
+ memset(omega[0]+1, 0, (parityCount+1)*sizeof(GFF4Element));
+ omega[0][parityCount+1+1]= 1;
+ SET_POLY0(locator[0], 0);
+ SET_POLY0(locator[1], 1);
+
+ for(i=0; 1; i++){
+ GFF4Element a_tmp[SIZE];
+ GFF4Element b_tmp[SIZE];
+ GFF4Element m[4][SIZE];
+ GFF4Element *ma[2]= {m[0], m[1]};
+ GFF4Element *mb[2]= {m[2], m[3]};
+ int max;
+
+ const int di= i&1;
+ const int si= 1-di;
+ int len= 2*omega[si][0] - parityCount - erasureCount;
+//printf("%d %d\n", omega[si][0], omega[di][0]);
+ if(2*omega[si][0] <= parityCount + erasureCount)
+ return si;
+
+ if(len > omega[si][0]+1) len=omega[si][0]+1;
+ if(len>128 && omega[si][0]/2 < len) len= omega[si][0]/2;
+
+ assert(omega[si][ omega[si][0]+1 ]);
+
+ a_tmp[0]= omega[di][0] - omega[si][0] + len-1;
+ b_tmp[0]= len-1;
+ memcpy(a_tmp+1, omega[di]+1+omega[di][0]-a_tmp[0], (a_tmp[0]+1)*sizeof(GFF4Element));
+ memcpy(b_tmp+1, omega[si]+1+omega[si][0]-b_tmp[0], (b_tmp[0]+1)*sizeof(GFF4Element));
+ assert(b_tmp[ b_tmp[0]+1 ]);
+//printf("In 0 %d %d\n", omega[di][0], omega[si][0]);
+ lehmer(ma, mb, a_tmp, b_tmp, len);
+ max= omega[si][0] - (len-1) + NOE_MAX(a_tmp[0], b_tmp[0]);
+
+ noe_partialProdPoly(a_tmp, omega[si], ma[1], max);
+ noe_partialProdPoly(b_tmp, omega[di], mb[0], max);
+ noe_partialProdPoly(omega[di], omega[di], ma[0], max);
+ noe_partialProdPoly(omega[si], omega[si], mb[1], max);
+ noe_sumPoly(omega[di], omega[di], a_tmp);
+ noe_sumPoly(omega[si], omega[si], b_tmp);
+
+ noe_prodPoly(a_tmp, locator[si], ma[1]);
+ noe_prodPoly(b_tmp, locator[di], mb[0]);
+ noe_prodPoly(locator[di], locator[di], ma[0]);
+ noe_prodPoly(locator[si], locator[si], mb[1]);
+ noe_sumPoly(locator[di], locator[di], a_tmp);
+ noe_sumPoly(locator[si], locator[si], b_tmp);
+
+ if(omega[si][0] < omega[di][0])
+ i++;
+ }
+}
+
/**
* ...
* @param omega must be parityCount+2 big
*/
-int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount, int *locatorOrderP, int *omegaOrderP){
- int i, quotOrder;
- int locatorOrder[2]= {0,0};
- int omegaOrder[2]= {parityCount+1, -1};
+int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+ int i;
GFF4Element quot[parityCount+2]; //FIXME size ok?
- memset(omega[0], 0, (parityCount+1)*sizeof(GFF4Element));
- omega[0][parityCount+1]= 1;
- locator[0][0]=0;
- locator[1][0]=1;
- omegaOrder[1]= noe_getOrder(omega[1], parityCount);
+ omega[0][0]= parityCount+1;
+ memset(omega[0]+1, 0, (parityCount+1)*sizeof(GFF4Element));
+ omega[0][parityCount+1+1]= 1;
+ SET_POLY0(locator[0], 0);
+ SET_POLY0(locator[1], 1);
for(i=0; 1; i++){
const int di= i&1;
const int si= 1-di;
-#ifdef DEBUG_EUCLID
-printf("Locator0:");noe_printPoly(locator[di], locatorOrder[di]);
-printf("Omega0:");noe_printPoly(omega[di], omegaOrder[di]);
-printf("Locator1:");noe_printPoly(locator[si], locatorOrder[si]);
-printf("Omega1:");noe_printPoly(omega[si], omegaOrder[si]);
-#endif
- if(2*omegaOrder[si] <= parityCount + erasureCount)
- break;
- quotOrder= omegaOrder[di] - omegaOrder[si];
+ if(2*omega[si][0] <= parityCount + erasureCount)
+ return si;
- omegaOrder[di]= noe_divPoly(quot, omega[di], omega[di], omega[si], omegaOrder[di], omegaOrder[si]);
+ noe_divPoly(quot, omega[di], omega[di], omega[si]);
- quotOrder= noe_prodPoly(quot, quot, locator[si], quotOrder, locatorOrder[si]);
- locatorOrder[di]= noe_diffPoly(locator[di], locator[di], quot, locatorOrder[di], quotOrder);
-#ifdef DEBUG_EUCLID
-printf("quot:");noe_printPoly(quot, quotOrder);
-printf("Locator:");noe_printPoly(locator[di], locatorOrder[di]);
-printf("Omega:");noe_printPoly(omega[di], omegaOrder[di]);
-#endif
+ noe_prodPoly(quot, quot, locator[si]);
+ noe_diffPoly(locator[di], locator[di], quot);
}
+}
- i++;
-
- *locatorOrderP= locatorOrder[i&1];
- *omegaOrderP= omegaOrder[i&1];
+/**
+ * ...
+ * @param omega must be parityCount+2 big
+ */
+int noe_rsBerlekampMassey(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount){
+ GFF4Element *syn= omega[1]+1; //yeah maybe we should clean this ...
+ int k, j;
+ GFF4Element oldDelta=0x10000;
+ GFF4Element *Tix= locator[0]+1;
+ GFF4Element *Lix= locator[1]+1;
+ GFF4Element *temp;
+ int Tshift= 1;
- return i&1;
+ Tix[-1]=1;
+ Tix[ 0]=1;
+ SET_POLY0(Lix-1, 1);
+
+ for(k=1+erasureCount; k<=parityCount; k++){
+ const int k2= k - erasureCount;
+ GFF4Element delta= syn[k];
+
+ for(j=1; j<=Lix[-1]; j++)
+ delta+= prod(Lix[j], syn[k-j]);
+ delta= reduce(delta);
+
+ if(delta){
+ GFF4Element factor= prod(delta, oldDelta);
+ if(Lix[-1] >= k2 - Lix[-1]){
+ for(j=Tshift; j<=Tix[-1]; j++)
+ Lix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
+ }else{
+ //Lix[-1] >= Tshift-1 has always been true during tests
+ //Tshift == 2 true in >99% of the cases
+ if(Tshift == 2 && Lix[-1]>0){
+ for(j=Tix[-1]; j>Lix[-1]; j--)
+ Tix[j]= prod(factor, Tix[j-2]);
+ for(; j>=2; j--)
+ Tix[j]= sum(Lix[j], prod(factor, Tix[j-2]));
+ }else{
+ for(j=Tix[-1]; j>NOE_MAX(Lix[-1], Tshift-1); j--)
+ Tix[j]= prod(factor, Tix[j-Tshift]);
+ for(; j>=Tshift; j--)
+ Tix[j]= sum(Lix[j], prod(factor, Tix[j-Tshift]));
+ }
+ for(; j>0; j--)
+ Tix[j]= Lix[j];
+ Tshift=0;
+ temp= Tix; Tix= Lix; Lix= temp;
+ oldDelta= SIZE - inv(delta);
+ Lix[-1]= k2 - Tix[-1];
+ }
+ }
+ Tix[-1]++;
+ Tshift++;
+ }
+
+ assert(Lix[0]==1);
+
+ k= Tix-1 == locator[0];
+ noe_partialProdPoly(omega[k], Lix-1, syn-1, syn[-1]);
+
+ return k;
}
int noe_rsDecode(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
int i;
- int errorCount, psiOrder, gfftEval, omegaOrder, phantomErrorCount;
+ int errorCount, gfftEval, phantomErrorCount;
const int dataCount= SIZE - 1 - parityCount;
GFF4Element erasureLocator[erasureCount + 1];
- GFF4Element erasureSynthSrc[erasureCount*2 + 1];
- GFF4Element locator0[parityCount + 1];
- GFF4Element locator1[parityCount + 1];
+ GFF4Element erasureSynthSrc[erasureCount*3 + 1];
+ GFF4Element locator0[parityCount + 1 + 1];
+ GFF4Element locator1[parityCount + 1 + 1];
GFF4Element *locators[2]={locator0, locator1};
- GFF4Element omega0[SIZE - 1];
- GFF4Element omega1[SIZE - 1];
+ GFF4Element omega0[SIZE - 1 + 1];
+ GFF4Element omega1[SIZE - 1 + 1];
GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
@@ -241,7 +441,7 @@ int noe_rsDecode(GFF4Element *data, int
noe_getSyndrom(syn, data, parityCount);
for(i=1; i<=parityCount; i++){
- if(syn[i]) break;
+ if(syn[i+1]) break;
}
if(i>parityCount)
return 0;
@@ -250,8 +450,7 @@ int noe_rsDecode(GFF4Element *data, int
//FIXME check truncated symbols syndrom
for(i=0; i<erasureCount; i++){
- erasureSynthSrc[2*i + 0] = 1;
- erasureSynthSrc[2*i + 1] = SIZE - noe_exp[erasure[i]];
+ SET_POLY1(erasureSynthSrc + 3*i, 1, SIZE - noe_exp[erasure[i]]);
}
noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
// noe_printPoly(erasureLocator, erasureCount);
@@ -261,13 +460,15 @@ for(i=0; i<erasureCount; i++){
assert( eval==0);
}
#endif
- noe_partialProdPoly(syn, erasureLocator, syn, erasureCount, parityCount);
-
-
- i= noe_rsEuclid(locators, omegas, parityCount, erasureCount, &errorCount, &omegaOrder);
+ noe_partialProdPoly(syn, erasureLocator, syn, syn[0]);
+START_TIMER
+// i= noe_rsBerlekampMassey(locators, omegas, parityCount, erasureCount);
+ i= noe_rsEuclid2(locators, omegas, parityCount, erasureCount);
+STOP_TIMER
//printf("errorCount %d \n", errorCount);
if(i<0) return -1;
+ errorCount= locators[i][0];
omega= omegas[i];
errorLocator= locators[i];
@@ -276,13 +477,13 @@ for(i=0; i<erasureCount; i++){
gfftEval= errorCount>20;
if(gfftEval && errorCount){
- memcpy(fErrorLocator, errorLocator, (errorCount+1)*sizeof(GFF4Element));
+ memcpy(fErrorLocator, errorLocator+1, (errorCount+1)*sizeof(GFF4Element));
memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
noe_gfft(fErrorLocator, fErrorLocator, 16);
}
- psiOrder= noe_prodPoly(psi, errorLocator, erasureLocator, errorCount, erasureCount);
- psiOrder= noe_getDerivative(psi, psi, psiOrder);
+ noe_prodPoly(psi, errorLocator, erasureLocator);
+ noe_getDerivative(psi, psi);
if(errorCount){
for(i=0; i<SIZE-1; i++){
@@ -295,7 +496,7 @@ for(i=0; i<erasureCount; i++){
r= (- noe_bitReverse(i))&0xFFFF;
}else{
- if(noe_evalPoly(errorLocator, errorCount, noe_exp[i]))
+ if(noe_evalPoly(errorLocator, noe_exp[i]))
continue;
r= (-i)&0xFFFF;
@@ -304,8 +505,8 @@ for(i=0; i<erasureCount; i++){
X = noe_exp[r];
invX= noe_exp[SIZE - r - 1];
- nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
- denom= noe_evalPoly(psi, psiOrder, invX);
+ nom= prod(X, noe_evalPoly(omega, invX));
+ denom= noe_evalPoly(psi, invX);
assert(r>=0 && r<=SIZE-2);
e= prod(nom, inv(denom));
@@ -328,8 +529,8 @@ for(i=0; i<erasureCount; i++){
assert(r>=0 && r<0x10000);
assert(prod(X, invX)==1);
- nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
- denom= noe_evalPoly(psi, psiOrder, invX);
+ nom= prod(X, noe_evalPoly(omega, invX));
+ denom= noe_evalPoly(psi, invX);
assert(data[r]==0);
data[r]= prod(nom, inv(denom));
Modified: trunk/noe/rw.c
==============================================================================
--- trunk/noe/rw.c (original)
+++ trunk/noe/rw.c Tue Jul 10 00:42:52 2007
@@ -19,7 +19,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
#include "rw.h"
@@ -82,44 +81,3 @@ noe_RwContext *noe_getRemapRwContext(noe
return c;
}
-
-static void update_buf(noe_RwContext *c, uint64_t pos, int len){
- assert(len>0 && len<=64);
-// assert(pos < 8*c->size);
-
- if(pos<8*c->pos || pos + len > 8*c->pos + 8*RW_SIZE){
- if(c->flush){
- c->io(c, c->buffer, c->pos, RW_SIZE, 1);
- c->flush=0;
- }
- c->pos= pos/8 - RW_SIZE/2;
- if(c->pos<0) c->pos=0;
- //FIXME memmove the old to avoid redundant io
- c->io(c, c->buffer, c->pos, RW_SIZE, 0);
- }
-}
-
-uint64_t noe_read(noe_RwContext *c, uint64_t pos, int len){
- int i;
- uint64_t v=0;
-
- update_buf(c, pos, len);
-
- for(i=0; i<len; i++){
- v += v + (c->buffer[(pos+i)/8 - c->pos] >> (8-((pos+i)&7)));
- }
- return v;
-}
-
-void noe_write(noe_RwContext *c, uint64_t pos, int len, uint64_t v){
- int i;
-
- update_buf(c, pos, len);
-
- for(i=0; i<len; i++){
- int bit= (v>>(len-i))&1;
- c->buffer[(pos+i)/8 - c->pos] &= ~(1 <<(8-((pos+i)&7)));
- c->buffer[(pos+i)/8 - c->pos] |= (bit<<(8-((pos+i)&7)));
- }
- c->flush=1;
-}
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:42:52 2007
@@ -86,7 +86,7 @@ int main(){
}
#endif
srand (31415);
-
+#if 0
printf("Testing GFFT");
for(i=1; i<20; i++){
int n= SIZE - 1;
@@ -127,25 +127,26 @@ int main(){
for(i=1; i<100; i+=5){
int n= SIZE - 1;
int k= SIZE - 1 - i;
- GFF4Element syn[n];
- GFF4Element gen[i+1];
- GFF4Element data[k];
- GFF4Element code[n];
-
+ GFF4Element syn[n+1];
+ GFF4Element gen[i+1+1];
+ GFF4Element data[k+1];
+ GFF4Element code[n+1];
+
+ data[0]= k-1;
for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ data[j+1]= rand() & 0xFFFF;
noe_getRsGenerator(gen, 1, i);
- j=noe_prodPoly(code, gen, data, i, k-1);
- assert(j==n-1);
+ noe_prodPoly(code, gen, data);
+ assert(code[0]==n-1);
- noe_getSyndrom(syn, code, i);
+ noe_getSyndrom(syn, code+1, i);
// noe_printPoly(gen, i);
// noe_printPoly(syn, i-1);
for(j=0; j<i; j++){
- if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+ if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
}
printf("."); fflush(stdout);
}
@@ -154,7 +155,7 @@ int main(){
for(i=1; i<1000; i+=200){
int n= SIZE - 1;
int k= SIZE - 1 - i;
- GFF4Element syn[n];
+ GFF4Element syn[n+1];
// GFF4Element gen[i+1];
GFF4Element data[k];
GFF4Element code[n];
@@ -178,15 +179,15 @@ int main(){
// noe_printPoly(syn, i-1);
for(j=0; j<i; j++){
- if(syn[j+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
+ if(syn[j+1+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
}
printf("."); fflush(stdout);
}
noe_freeRsEncoder(encoder);
}
-
+#endif
printf("\nTesting decoder");
- for(i=1; i<2000; i+=100){
+ for(i=1; i<5000; i+=100){
int n= SIZE - 1;
int k= SIZE - 1 - i;
// GFF4Element syn[n];
@@ -280,44 +281,42 @@ int main(){
#endif
printf("\n");
return 0;
-
printf("Testing erasure decoding\n");
for(i=1; i<20; i++){
int n= SIZE - 1;
int k= SIZE - 1 - i;
- GFF4Element syn[n];
- GFF4Element gen[i+1];
- GFF4Element data[k];
- GFF4Element code[n];
- GFF4Element locator[i+1];
- GFF4Element omega[2*i];
+ GFF4Element syn[n+1];
+ GFF4Element gen[i+1+1];
+ GFF4Element data[k+1];
+ GFF4Element code[n+1];
+ GFF4Element locator[i+1+1];
+ GFF4Element omega[2*i+1];
- int locatorOrder=0;
-
+ data[0]= k-1;
for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ data[j+1]= rand() & 0xFFFF;
noe_getRsGenerator(gen, 1, i);
- j=noe_prodPoly(code, gen, data, i, k);
- assert(j==n);
+ noe_prodPoly(code, gen, data);
+ assert(code[0]==n);
- locator[0] = 1;
+ locator[0] = 0;
+ locator[1] = 1;
for(j=0; j<i; j++){
int index;
- GFF4Element locationFactor[2];
+ GFF4Element locationFactor[3];
if((rand()&7)==0 && j) continue;
index= rand()%0xFFFF;
- locationFactor[0] = 1;
- locationFactor[1] = inv(noe_exp[index]);
- locatorOrder= noe_prodPoly(locator, locator, locationFactor, j, 1);
+ SET_POLY1(locationFactor, 1, inv(noe_exp[index]));
+ noe_prodPoly(locator, locator, locationFactor);
code[index] = 0;
}
- noe_getSyndrom(syn, code, i);
- noe_prodPoly(omega, syn, locator, i-1, locatorOrder);
+ noe_getSyndrom(syn, code+1, i);
+ noe_prodPoly(omega, syn, locator);
// noe_getDeriative(locator, locator, locatorOrder);
@@ -325,8 +324,9 @@ return 0;
// noe_printPoly(syn, i-1);
for(j=0; j<i; j++){
- if(syn[j]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+ if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
}
}
+
return 0;
}
1
0
[mndiff]: r79 - in trunk/noe: bytestream.h filerw.c filerw.h galois.c galois.h gfft.c gfft.h noe.c noe_internal.h rs.c rs.h rw.c rw.h test.c
by michael 09 Jul '07
by michael 09 Jul '07
09 Jul '07
Author: michael
Date: Tue Jul 10 00:37:39 2007
New Revision: 79
Log:
version from unknown date, probably 2005 or 2006
this mostly reindents the code, and seems to loose the 2003 copyright on some files
Modified:
trunk/noe/bytestream.h
trunk/noe/filerw.c
trunk/noe/filerw.h
trunk/noe/galois.c
trunk/noe/galois.h
trunk/noe/gfft.c
trunk/noe/gfft.h
trunk/noe/noe.c
trunk/noe/noe_internal.h
trunk/noe/rs.c
trunk/noe/rs.h
trunk/noe/rw.c
trunk/noe/rw.h
trunk/noe/test.c
Modified: trunk/noe/bytestream.h
==============================================================================
--- trunk/noe/bytestream.h (original)
+++ trunk/noe/bytestream.h Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003-2005 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,138 +16,26 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-typedef struct ByteStream{
- uint8_t *buf;
- uint8_t *buf_ptr;
-// int length;
- uint8_t *buf_end;
-}ByteStream;
-
-static inline void initByteStream(ByteStream *bc, uint8_t *buf, int length){
- bc->buf=
- bc->buf_ptr= buf;
-// bc->length= length;
- bc->buf_end= bc->buf + length;
-}
-
-static inline int spaceLeft(ByteStream *bc){
-// return bc->length - ((int)(bc->buf_ptr - bc->buf));
- return ((int)(bc->buf_end - bc->buf_ptr));
-}
-
-/**
- *
- * @return <0 if an error occured
- */
-static inline uint64_t get_v(ByteStream *bc){
- uint64_t val= 0;
-
- for(; spaceLeft(bc) > 0; ){
- int tmp= *(bc->buf_ptr++);
- if(tmp&0x80)
- val= (val<<7) + tmp - 0x80;
- else
- return (val<<7) + tmp;
- }
-
- return -1;
-}
-
-/**
- *
- * @return <0 if an error occured
- */
-static inline int put_v(ByteStream *bc, uint64_t val){
- int i;
-
- if(spaceLeft(bc) < 9) return -1; //FIXME
-
- val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
- for(i=7; ; i+=7){
- if(val>>i == 0) break;
- }
-
- for(i-=7; i>0; i-=7){
- *(bc->buf_ptr++)= 0x80 | (val>>i);
- }
- *(bc->buf_ptr++)= val&0x7F;
-
- return 0;
-}
-
-/**
- *
- */
-static inline uint64_t get_c(ByteStream *bc, int length){
- uint64_t val= 0;
-
- for(i=length-1; i>=0; i--){
- val |= (*(bc->buf_ptr++)) << (8*i) ;
- }
- return val;
-}
-
-/**
- *
- */
-static inline void put_c(ByteStream *bc, uint64_t val, int length){
- int i;
-
- for(i=length-1; i>=0; i--){
- *(bc->buf_ptr++)= val >> (i*8);
- }
-}
-
/**
*
- * @return <0 if an error occured
*/
-static inline int get_buffer(ByteStream *bc, uint8_t *dst, int length){
- int i;
-
- if(length > spaceLeft(bc) || length<0) return -1;
-
- for(i=0; i<length; i++){
- dst[i]= *(bc->buf_ptr++);
- }
-
- return 0;
-}
-
-/**
- *
- * @return <0 if an error occured
- */
-static inline int put_buffer(ByteStream *bc, uint8_t *src, int length){
- int i;
-
- if(length > spaceLeft(bc)) return -1;
-
- for(i=0; i<length; i++){
- *(bc->buf_ptr++)= src[i];
- }
+static inline uint64_t get_c(uint8_t **buf_ptr, int length){
+ uint64_t val= 0;
+ int i;
- return 0;
+ for(i=length-1; i>=0; i--){
+ val |= (*((*buf_ptr)++)) << (8*i) ;
+ }
+ return val;
}
-#if 1 // just do a *_v() *_buffer()
/**
*
- * @return <0 if an error occured
*/
-static inline int get_b(ByteStream *bc, uint8_t *dst, int max_length){
- const int length= get_v(bc);
- if(length > max_length) return -1;
-
- return get_buffer(bc, dst, length);
-}
+static inline void put_c(uint8_t **buf_ptr, uint64_t val, int length){
+ int i;
-/**
- *
- * @return <0 if an error occured
- */
-static inline int put_b(ByteStream *bc, uint8_t *src, int length){
- put_v(bc, length);
- return put_buffer(bc, src, length);
+ for(i=length-1; i>=0; i--){
+ *((*buf_ptr)++)= val >> (i*8);
+ }
}
-#endif
\ No newline at end of file
Modified: trunk/noe/filerw.c
==============================================================================
--- trunk/noe/filerw.c (original)
+++ trunk/noe/filerw.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003-2005 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,84 +25,84 @@
#include "filerw.h"
static uint64_t fsize(FILE *f){
- uint64_t cur= ftell(f);
- uint64_t size;
-
- fseek(f, 0, SEEK_END); //FIXME 64bit stuff?
- size= ftell(f);
- fseek(f, cur, SEEK_SET);
-
- return size;
+ uint64_t cur= ftell(f);
+ uint64_t size;
+
+ fseek(f, 0, SEEK_END); //FIXME 64bit stuff?
+ size= ftell(f);
+ fseek(f, cur, SEEK_SET);
+
+ return size;
}
static int fileIO(noe_RwContext *c, uint8_t *data, uint64_t pos, int len, int write){
- int i;
- noe_FileRwContext *p= (noe_FileRwContext *)c;
+ int i;
+ noe_FileRwContext *p= (noe_FileRwContext *)c;
- for(i=0; i<p->fileCount; i++){
- if(p->end[i] > pos){
- int e;
- uint64_t currentLen= pos - p->end[i];
- if(currentLen > len) currentLen= len;
- if(currentLen <= 0) return -1;
-
- if(write)
- e= fwrite(data, currentLen, 1, p->file[i]);
- else
- e= fread(data, currentLen, 1, p->file[i]);
- if(e!=1) return -1;
-
- len -= currentLen;
- data+= currentLen;
- pos += currentLen;
- if(len==0) return 0;
- }
- }
- return -1;
+ for(i=0; i<p->fileCount; i++){
+ if(p->end[i] > pos){
+ int e;
+ uint64_t currentLen= pos - p->end[i];
+ if(currentLen > len) currentLen= len;
+ if(currentLen <= 0) return -1;
+
+ if(write)
+ e= fwrite(data, currentLen, 1, p->file[i]);
+ else
+ e= fread(data, currentLen, 1, p->file[i]);
+ if(e!=1) return -1;
+
+ len -= currentLen;
+ data+= currentLen;
+ pos += currentLen;
+ if(len==0) return 0;
+ }
+ }
+ return -1;
}
static void fileUninit(noe_RwContext *c){
- int i;
- noe_FileRwContext *p= (noe_FileRwContext *)c;
+ int i;
+ noe_FileRwContext *p= (noe_FileRwContext *)c;
- if(c==NULL) return;
+ if(c==NULL) return;
- for(i=0; i<p->fileCount; i++){
- fclose(p->file[i]);
- }
- free(p->file);
- free(p->end);
- memset(p, 0, sizeof(noe_FileRwContext));
- free(p);
+ for(i=0; i<p->fileCount; i++){
+ fclose(p->file[i]);
+ }
+ free(p->file);
+ free(p->end);
+ memset(p, 0, sizeof(noe_FileRwContext));
+ free(p);
}
noe_RwContext *noe_getFileRwContext(char **fileNames, int fileCount, char *access){
- int i;
- uint64_t pos;
- noe_FileRwContext *p= malloc(sizeof(noe_FileRwContext));
- noe_RwContext *c= (noe_RwContext *)p;
+ int i;
+ uint64_t pos;
+ noe_FileRwContext *p= malloc(sizeof(noe_FileRwContext));
+ noe_RwContext *c= (noe_RwContext *)p;
- c->parent= NULL;
+ c->parent= NULL;
- p->file= malloc(sizeof(FILE)*fileCount);
- p->end= malloc(sizeof(uint64_t)*fileCount);
+ p->file= malloc(sizeof(FILE)*fileCount);
+ p->end= malloc(sizeof(uint64_t)*fileCount);
- c->io= fileIO;
- c->uninit= fileUninit;
+ c->io= fileIO;
+ c->uninit= fileUninit;
- pos=0;
- for(i=0; i<fileCount; i++){
- p->file[i]= fopen(fileNames[i], access);
- if(p->file[i]==NULL) goto fail;
-
- pos+= fsize(p->file[i]);
- p->end[i]= pos;
- }
- p->size= pos;
-
- return c;
+ pos=0;
+ for(i=0; i<fileCount; i++){
+ p->file[i]= fopen(fileNames[i], access);
+ if(p->file[i]==NULL) goto fail;
- fail:
- fileUninit(c);
- return NULL;
+ pos+= fsize(p->file[i]);
+ p->end[i]= pos;
+ }
+ c->size= p->end[i-1];
+
+ return c;
+
+fail:
+ fileUninit(c);
+ return NULL;
}
Modified: trunk/noe/filerw.h
==============================================================================
--- trunk/noe/filerw.h (original)
+++ trunk/noe/filerw.h Tue Jul 10 00:37:39 2007
@@ -17,14 +17,14 @@
*/
typedef struct noe_FileRwContext{
- noe_RwContext rw;
- FILE **file;
+ noe_RwContext rw;
+ FILE **file;
- /**
- * end of the ith file.
- */
- uint64_t *end;
- int fileCount;
+ /**
+ * end of the ith file.
+ */
+ uint64_t *end;
+ int fileCount;
}noe_FileRwContext;
//FIXME move to .c if this is the only thing here
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,64 +31,64 @@ GFF4Element noe_exp[SIZE];
GFF4Element noe_log[SIZE];
void noe_init(){
- GFF4Element ge= 1;
- int i;
-
- for(i=0; i<SIZE; i++){
- noe_exp[i]= ge;
- noe_log[ge]= i;
- ge= prod(ge, PRIMITIVE_ELEMENT);
- }
-
- noe_log[0]= 0xFFFF;
- noe_log[1]= 0;
-
- noe_gfft_init();
+ GFF4Element ge= 1;
+ int i;
+
+ for(i=0; i<SIZE; i++){
+ noe_exp[i]= ge;
+ noe_log[ge]= i;
+ ge= prod(ge, PRIMITIVE_ELEMENT);
+ }
+
+ noe_log[0]= 0xFFFF;
+ noe_log[1]= 0;
+
+ noe_gfft_init();
}
/**
* ...
*/
int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
- int order= order1 + order2;
- int i;
+ int order= order1 + order2;
+ int i;
- if(order1*order2 < (order1+order2)*64){
- for(i=order; i>=0; i--){
- unsigned int acc=0;
- int j, end;
+ if(order1*order2 < (order1+order2)*64){
+ for(i=order; i>=0; i--){
+ unsigned int acc=0;
+ int j, end;
- j = NOE_MAX(0, i - order2);
- end= NOE_MIN(i, order1);
+ j = NOE_MAX(0, i - order2);
+ end= NOE_MIN(i, order1);
- for(; j<=end; j++){
- acc+= prod(src1[j], src2[i-j]);
- }
- dst[i]= reduce(acc);
- }
- }else{
- const int logSize= noe_log2(order2 + order1)+1;
- const int size= 1<<logSize;
- GFF4Element temp[2][size]; //FIXME is this fast?
- const GFF4Element scale= inv(size);
+ for(; j<=end; j++){
+ acc+= prod(src1[j], src2[i-j]);
+ }
+ dst[i]= reduce(acc);
+ }
+ }else{
+ const int logSize= noe_log2(order2 + order1)+1;
+ const int size= 1<<logSize;
+ GFF4Element temp[2][size]; //FIXME is this fast?
+ const GFF4Element scale= inv(size);
- //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
- memcpy(temp[0], src1, sizeof(GFF4Element)*(order1+1));
- memset(temp[0] + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
- memcpy(temp[1], src2, sizeof(GFF4Element)*(order2+1));
- memset(temp[1] + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
+ //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
+ memcpy(temp[0], src1, sizeof(GFF4Element)*(order1+1));
+ memset(temp[0] + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
+ memcpy(temp[1], src2, sizeof(GFF4Element)*(order2+1));
+ memset(temp[1] + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
- noe_gfft(temp[0], temp[0], logSize);
- noe_gfft(temp[1], temp[1], logSize);
-
- for(i=0; i<size; i++){
- temp[0][i]= prod(prod(temp[0][i], temp[1][i]), scale);
- }
+ noe_gfft(temp[0], temp[0], logSize);
+ noe_gfft(temp[1], temp[1], logSize);
+
+ for(i=0; i<size; i++){
+ temp[0][i]= prod(prod(temp[0][i], temp[1][i]), scale);
+ }
- noe_igfft(temp[0], temp[0], logSize);
- memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
- }
+ noe_igfft(temp[0], temp[0], logSize);
+ memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
+ }
- return order;
+ return order;
}
/**
@@ -96,148 +96,148 @@ int noe_prodPoly(GFF4Element *dst, GFF4E
* Note dst must be at least 2^log2(order1+order2) big FIXME benchmark if its worth it
*/
int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
- const int order= order2;
- int i;
-
- if(order1*order2 < (order1+order2)*64){
- for(i=order; i>=0; i--){
- unsigned int acc=0;
- int j, end;
+ const int order= order2;
+ int i;
+
+ if(order1*order2 < (order1+order2)*64){
+ for(i=order; i>=0; i--){
+ unsigned int acc=0;
+ int j, end;
- j = NOE_MAX(0, i - order2);
- end= NOE_MIN(i, order1);
+ j = NOE_MAX(0, i - order2);
+ end= NOE_MIN(i, order1);
- for(; j<=end; j++){
- acc+= prod(src1[j], src2[i-j]);
- }
- dst[i]= reduce(acc);
- }
- }else{
- const int logSize= noe_log2(order2 + order1)+1;
- const int size= 1<<logSize;
- GFF4Element temp[size]; //FIXME is this fast?
- const GFF4Element scale= inv(size);
+ for(; j<=end; j++){
+ acc+= prod(src1[j], src2[i-j]);
+ }
+ dst[i]= reduce(acc);
+ }
+ }else{
+ const int logSize= noe_log2(order2 + order1)+1;
+ const int size= 1<<logSize;
+ GFF4Element temp[size]; //FIXME is this fast?
+ const GFF4Element scale= inv(size);
- //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
- memcpy(temp, src2, sizeof(GFF4Element)*(order2+1));
- memset(temp + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
- memcpy(dst, src1, sizeof(GFF4Element)*(order1+1));
- memset(dst + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
+ //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
+ memcpy(temp, src2, sizeof(GFF4Element)*(order2+1));
+ memset(temp + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
+ memcpy(dst, src1, sizeof(GFF4Element)*(order1+1));
+ memset(dst + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
- noe_gfft(dst, dst, logSize);
- noe_gfft(temp, temp, logSize);
-
- for(i=0; i<size; i++){
- dst[i]= prod(prod(dst[i], temp[i]), scale);
- }
+ noe_gfft(dst, dst, logSize);
+ noe_gfft(temp, temp, logSize);
+
+ for(i=0; i<size; i++){
+ dst[i]= prod(prod(dst[i], temp[i]), scale);
+ }
- noe_igfft(dst, dst, logSize);
- }
+ noe_igfft(dst, dst, logSize);
+ }
- return order;
+ return order;
}
void noe_printPoly(GFF4Element *src, int order){
- int i;
-
- for(i=order; i>=0; i--){
- printf(" + %X*x^%d", src[i], i);
- }
- printf("\n");
+ int i;
+
+ for(i=order; i>=0; i--){
+ printf(" + %X*x^%d", src[i], i);
+ }
+ printf("\n");
}
/**
* Evaluates the src polynom at x.
*/
GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x){
- unsigned int acc=0;
- int j;
+ unsigned int acc=0;
+ int j;
- for(j=order; j>=0; j--){
- acc = sum(prod(acc, x), src[j]);
- }
+ for(j=order; j>=0; j--){
+ acc = sum(prod(acc, x), src[j]);
+ }
- return acc;
+ return acc;
}
int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order){
- int i;
-
- for(i=0; i<order; i++){
- dst[i ]= prod(src[i+1], i+1);
- }
+ int i;
+
+ for(i=0; i<order; i++){
+ dst[i ]= prod(src[i+1], i+1);
+ }
- return order-1;
+ return order-1;
}
/**
* ...
*/
void noe_synthPoly(GFF4Element *dst, GFF4Element *src, int count){
- if(count<20){
- int i;
+ if(count<20){
+ int i;
- dst[0]= 1;
+ dst[0]= 1;
- for(i=0; i<count; i++){
- noe_prodPoly(dst, dst, src+2*i, i, 1);
- }
- }else{
- int pass, i, countLeft;
- const int passCount= noe_log2(count-1)+1;
- GFF4Element temp[2][4<<noe_log2(count-1)];
+ for(i=0; i<count; i++){
+ noe_prodPoly(dst, dst, src+2*i, i, 1);
+ }
+ }else{
+ int pass, i, countLeft;
+ const int passCount= noe_log2(count-1)+1;
+ GFF4Element temp[2][4<<noe_log2(count-1)];
- assert(passCount>0);
+ assert(passCount>0);
- countLeft= count;
+ countLeft= count;
- // noe_printPoly(src, 1);
- // noe_printPoly(src+2, 1);
+ // noe_printPoly(src, 1);
+ // noe_printPoly(src+2, 1);
- for(i=0; i<(count>>1); i++){
- noe_prodPoly(temp[0]+4*i, src+4*i, src+4*i+2, 1, 1);
- }
- if(count&1){
- memcpy(temp[0]+4*i, src+4*i, 2*sizeof(GFF4Element));
- temp[0][4*i+2]= 0;
- countLeft++;
- }
- countLeft>>=1;
+ for(i=0; i<(count>>1); i++){
+ noe_prodPoly(temp[0]+4*i, src+4*i, src+4*i+2, 1, 1);
+ }
+ if(count&1){
+ memcpy(temp[0]+4*i, src+4*i, 2*sizeof(GFF4Element));
+ temp[0][4*i+2]= 0;
+ countLeft++;
+ }
+ countLeft>>=1;
- // noe_printPoly(temp[0], 2);
+ // noe_printPoly(temp[0], 2);
- for(pass=1; countLeft>1; pass++){
- const int step= 2<<pass;
- GFF4Element *temp1= temp[ pass&1 ];
- GFF4Element *temp2= temp[(pass&1)^1];
+ for(pass=1; countLeft>1; pass++){
+ const int step= 2<<pass;
+ GFF4Element *temp1= temp[ pass&1 ];
+ GFF4Element *temp2= temp[(pass&1)^1];
- for(i=0; i<(countLeft>>1); i++){
- noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step, step>>1, step>>1);
- }
+ for(i=0; i<(countLeft>>1); i++){
+ noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step, step>>1, step>>1);
+ }
- if(countLeft&1){
- int len= (step>>1) + 1;
- memcpy(temp1+2*step*i , temp2+2*step*i, len*sizeof(GFF4Element));
- memset(temp1+2*step*i + len , 0, step*sizeof(GFF4Element));
- countLeft++;
- }
- countLeft>>=1;
- }
+ if(countLeft&1){
+ int len= (step>>1) + 1;
+ memcpy(temp1+2*step*i , temp2+2*step*i, len*sizeof(GFF4Element));
+ memset(temp1+2*step*i + len , 0, step*sizeof(GFF4Element));
+ countLeft++;
+ }
+ countLeft>>=1;
+ }
- assert(pass==passCount);
+ assert(pass==passCount);
- // noe_printPoly(temp[0], count);
+ // noe_printPoly(temp[0], count);
- memcpy(dst, temp[(pass&1)^1], (count+1)*sizeof(GFF4Element));
- // noe_printPoly(dst, count);
- }
+ memcpy(dst, temp[(pass&1)^1], (count+1)*sizeof(GFF4Element));
+ // noe_printPoly(dst, count);
+ }
}
int noe_getOrder(GFF4Element *src, int maxOrder){
- while(maxOrder && src[maxOrder]==0)
- maxOrder--;
+ while(maxOrder && src[maxOrder]==0)
+ maxOrder--;
- return maxOrder;
+ return maxOrder;
}
/**
@@ -245,58 +245,58 @@ int noe_getOrder(GFF4Element *src, int m
* Note: rem can be identical to nom
*/
int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder){
- int i;
- int remOrder= nomOrder;
- int quotOrder= 0;
+ int i;
+ int remOrder= nomOrder;
+ int quotOrder= 0;
- if(rem != nom)
- memcpy(rem, nom, (nomOrder+1)*sizeof(GFF4Element));
+ if(rem != nom)
+ memcpy(rem, nom, (nomOrder+1)*sizeof(GFF4Element));
- denomOrder= noe_getOrder(denom, denomOrder);
+ denomOrder= noe_getOrder(denom, denomOrder);
- quot[0]=0;
+ quot[0]=0;
- for(; remOrder >= denomOrder; remOrder--){
- GFF4Element scale;
+ for(; remOrder >= denomOrder; remOrder--){
+ GFF4Element scale;
- if(rem[remOrder]==0) continue;
+ if(rem[remOrder]==0) continue;
- scale= prod(rem[remOrder], inv(denom[denomOrder]));
+ scale= prod(rem[remOrder], inv(denom[denomOrder]));
- for(i=0; i<=denomOrder; i++){ //FIXME optimize
- const int remIndex= i + remOrder - denomOrder;
- rem[remIndex]= sum(rem[remIndex], SIZE - prod(scale, denom[i]));
- }
+ for(i=0; i<=denomOrder; i++){ //FIXME optimize
+ const int remIndex= i + remOrder - denomOrder;
+ rem[remIndex]= sum(rem[remIndex], SIZE - prod(scale, denom[i]));
+ }
- quot[remOrder - denomOrder]= scale;
- if(quotOrder==0)
- quotOrder= remOrder - denomOrder;
- }
-
- return noe_getOrder(rem, remOrder);
+ quot[remOrder - denomOrder]= scale;
+ if(quotOrder==0)
+ quotOrder= remOrder - denomOrder;
+ }
+
+ return noe_getOrder(rem, remOrder);
}
int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
- int i;
- int minOrder= NOE_MIN(order1, order2);
+ int i;
+ int minOrder= NOE_MIN(order1, order2);
- for(i=0; i<=minOrder; i++){
- dst[i]= sum(src1[i], SIZE - src2[i]);
- }
-
- if(order1==order2){
- return noe_getOrder(dst, order1);
- }else{
- if(dst!=src1){
- for(; i<=order1; i++){
- dst[i]= src1[i];
- }
- }
+ for(i=0; i<=minOrder; i++){
+ dst[i]= sum(src1[i], SIZE - src2[i]);
+ }
+
+ if(order1==order2){
+ return noe_getOrder(dst, order1);
+ }else{
+ if(dst!=src1){
+ for(; i<=order1; i++){
+ dst[i]= src1[i];
+ }
+ }
- for(; i<=order2; i++){
- dst[i]= SIZE - src2[i];
- }
+ for(; i<=order2; i++){
+ dst[i]= SIZE - src2[i];
+ }
- return NOE_MAX(order1, order2);;
- }
+ return NOE_MAX(order1, order2);;
+ }
}
Modified: trunk/noe/galois.h
==============================================================================
--- trunk/noe/galois.h (original)
+++ trunk/noe/galois.h Tue Jul 10 00:37:39 2007
@@ -36,28 +36,28 @@ int noe_diffPoly(GFF4Element *dst, GFF4E
int noe_getOrder(GFF4Element *src, int maxOrder);
static inline GFF4Element reduce(GFF4Element a){
- a = (a&0xFFFF) - (a>>16);
- a += (((int)a)>>31)&0x10001;
-
- return a;
+ a = (a&0xFFFF) - (a>>16);
+ a += (((int)a)>>31)&0x10001;
+
+ return a;
}
static inline GFF4Element prod(GFF4Element a, GFF4Element b){
//printf("%d %d\n", a,b);
- if((a&b)==0x10000) return 1;
- else return reduce(a*b);
+ if((a&b)==0x10000) return 1;
+ else return reduce(a*b);
}
static inline GFF4Element sum(GFF4Element a, GFF4Element b){
-
- a += b - 0x10001;
- a += (((int)a)>>31)&0x10001;
-
- return a;
+
+ a += b - 0x10001;
+ a += (((int)a)>>31)&0x10001;
+
+ return a;
}
static inline GFF4Element inv(GFF4Element a){
- assert(a!=0);
+ assert(a!=0);
- return noe_exp[SIZE - 1 - noe_log[a]];
+ return noe_exp[SIZE - 1 - noe_log[a]];
}
Modified: trunk/noe/gfft.c
==============================================================================
--- trunk/noe/gfft.c (original)
+++ trunk/noe/gfft.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,16 +28,16 @@
uint8_t noe_revTable[256];
void noe_gfft_init(){
- int i;
-
- for(i=0; i<256; i++){
- int x= i;
- x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1));
- x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2));
- x = (( x >> 4) | ((x & 0x0f) << 4));
-
- noe_revTable[i]= x;
- }
+ int i;
+
+ for(i=0; i<256; i++){
+ int x= i;
+ x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1));
+ x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2));
+ x = (( x >> 4) | ((x & 0x0f) << 4));
+
+ noe_revTable[i]= x;
+ }
}
int noe_log2(unsigned int v) // from ffmpeg
@@ -68,46 +68,46 @@ int noe_log2(unsigned int v) // from ffm
}
void noe_permute(GFF4Element *dst, GFF4Element *src, int outCount){
- int i;
+ int i;
- if(dst==src){
- for(i=1; i<outCount; i++){
- const int r= noe_bitReverse(i);
- unsigned int t;
- if(r<=i) continue;
- t= dst[i];
- dst[i]= dst[r];
- dst[r]= t;
- }
- }else{
- for(i=0; i<outCount; i++){
- dst[i]= src[noe_bitReverse(i)];
- }
- }
+ if(dst==src){
+ for(i=1; i<outCount; i++){
+ const int r= noe_bitReverse(i);
+ unsigned int t;
+ if(r<=i) continue;
+ t= dst[i];
+ dst[i]= dst[r];
+ dst[r]= t;
+ }
+ }else{
+ for(i=0; i<outCount; i++){
+ dst[i]= src[noe_bitReverse(i)];
+ }
+ }
}
static inline void fft2(GFF4Element *p){
- const unsigned int a= p[0];
- const unsigned int b= p[1];
-
- p[0]= sum(a, b);
- p[1]= sum(a, SIZE - b);
+ const unsigned int a= p[0];
+ const unsigned int b= p[1];
+
+ p[0]= sum(a, b);
+ p[1]= sum(a, SIZE - b);
}
static inline void fft4(GFF4Element *p){
- unsigned int a,b,c,d;
+ unsigned int a,b,c,d;
- d= p[0] + SIZE*0x8000ULL;
-
- a= d +p[2];
- b= p[1]+p[3];
- c= d -p[2];
- d= (p[3] - p[1])<<8 /*(p[1] - p[3])*noe_exp[16384]*/;
+ d= p[0] + SIZE*0x8000ULL;
+
+ a= d +p[2];
+ b= p[1]+p[3];
+ c= d -p[2];
+ d= (p[3] - p[1])<<8 /*(p[1] - p[3])*noe_exp[16384]*/;
- p[0]= reduce(a+b);
- p[1]= reduce(a-b);
- p[2]= reduce(c+d);
- p[3]= reduce(c-d);
+ p[0]= reduce(a+b);
+ p[1]= reduce(a-b);
+ p[2]= reduce(c+d);
+ p[3]= reduce(c-d);
}
/*
@@ -118,172 +118,172 @@ aWi + bWiWn
(a - bWn)WiW2i
*/
static inline void fft8(GFF4Element *p){
- unsigned int a,b;
+ unsigned int a,b;
- a= p[0];
- b= p[4];
- p[0]= a+b;
- p[4]= a-b;
+ a= p[0];
+ b= p[4];
+ p[0]= a+b;
+ p[4]= a-b;
- a= p[1];
- b= p[5];
- p[1]= a+b;
- p[5]= reduce(SIZE*0x8000ULL + ((a-b)<<12))/*(a-b)*noe_exp[8192]*/;
+ a= p[1];
+ b= p[5];
+ p[1]= a+b;
+ p[5]= reduce(SIZE*0x8000ULL + ((a-b)<<12))/*(a-b)*noe_exp[8192]*/;
- a= p[2];
- b= p[6];
- p[2]= a+b;
- p[6]= (b-a)<<8 /*(a-b)*noe_exp[16384]*/;
+ a= p[2];
+ b= p[6];
+ p[2]= a+b;
+ p[6]= (b-a)<<8 /*(a-b)*noe_exp[16384]*/;
- a= p[3];
- b= p[7];
- p[3]= a+b;
- p[7]= (a-b)<<4/*(a-b)*noe_exp[3*8192]*/;
+ a= p[3];
+ b= p[7];
+ p[3]= a+b;
+ p[7]= (a-b)<<4/*(a-b)*noe_exp[3*8192]*/;
- fft4(p);
- fft4(p+4);
+ fft4(p);
+ fft4(p+4);
}
static void fft16(GFF4Element *p){
- int n;
+ int n;
- for(n=0; n<8; n++){
- const unsigned int w= noe_exp[ n<<12 ];
- const unsigned int a= p[n ];
- const unsigned int b= p[n + 8];
+ for(n=0; n<8; n++){
+ const unsigned int w= noe_exp[ n<<12 ];
+ const unsigned int a= p[n ];
+ const unsigned int b= p[n + 8];
- p[n ]= sum(a, b);
- p[n + 8]= reduce(sum(a, SIZE - b)*w);
- }
+ p[n ]= sum(a, b);
+ p[n + 8]= reduce(sum(a, SIZE - b)*w);
+ }
- fft8(p);
- fft8(p+8);
+ fft8(p);
+ fft8(p+8);
}
static void fftn(GFF4Element *p, int logSize){
- int n;
- const int size= 1<<(logSize-1);
+ int n;
+ const int size= 1<<(logSize-1);
- for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ n<<(16-logSize) ];
- const unsigned int a= p[n ];
- const unsigned int b= p[n + size];
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int a= p[n ];
+ const unsigned int b= p[n + size];
- p[n ]= sum(a, b);
- p[n + size]= reduce(sum(a, SIZE - b)*w);
- }
-
- if(logSize==5){
- fft16(p);
- fft16(p+16);
- }else{
- fftn(p, logSize-1);
- fftn(p+size, logSize-1);
- }
+ p[n ]= sum(a, b);
+ p[n + size]= reduce(sum(a, SIZE - b)*w);
+ }
+
+ if(logSize==5){
+ fft16(p);
+ fft16(p+16);
+ }else{
+ fftn(p, logSize-1);
+ fftn(p+size, logSize-1);
+ }
}
static void fftn2(GFF4Element *p, GFF4Element *src, int logSize){
- int n;
- const int size= 1<<(logSize-1);
+ int n;
+ const int size= 1<<(logSize-1);
- for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ n<<(16-logSize) ];
- const unsigned int a= src[n ];
- const unsigned int b= src[n + size];
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int a= src[n ];
+ const unsigned int b= src[n + size];
- p[n ]= sum(a, b);
- p[n + size]= reduce(sum(a, SIZE - b)*w);
- }
-
- if(logSize==5){
- fft16(p);
- fft16(p+16);
- }else{
- fftn(p, logSize-1);
- fftn(p+size, logSize-1);
- }
+ p[n ]= sum(a, b);
+ p[n + size]= reduce(sum(a, SIZE - b)*w);
+ }
+
+ if(logSize==5){
+ fft16(p);
+ fft16(p+16);
+ }else{
+ fftn(p, logSize-1);
+ fftn(p+size, logSize-1);
+ }
}
static inline void ifft2(GFF4Element *p){
- const unsigned int a= p[0];
- const unsigned int b= p[1];
-
- p[0]= sum(a, b);
- p[1]= sum(a, SIZE - b);
+ const unsigned int a= p[0];
+ const unsigned int b= p[1];
+
+ p[0]= sum(a, b);
+ p[1]= sum(a, SIZE - b);
}
static void ifftn(GFF4Element *p, int logSize){
- int n;
- const int size= 1<<(logSize-1);
+ int n;
+ const int size= 1<<(logSize-1);
- if(logSize==2){
- ifft2(p);
- ifft2(p+2);
- }else{
- ifftn(p, logSize-1);
- ifftn(p+size, logSize-1);
- }
-
- for(n=0; n<size; n++){
- const unsigned int w= noe_exp[ (1<<16) - (n<<(16-logSize)) ];
- const unsigned int a= p[n ];
- const unsigned int b= prod(p[n + size], w);
+ if(logSize==2){
+ ifft2(p);
+ ifft2(p+2);
+ }else{
+ ifftn(p, logSize-1);
+ ifftn(p+size, logSize-1);
+ }
+
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ (1<<16) - (n<<(16-logSize)) ];
+ const unsigned int a= p[n ];
+ const unsigned int b= prod(p[n + size], w);
- p[n ]= sum(a, b);
- p[n + size]= sum(a, SIZE - b);
- }
-
+ p[n ]= sum(a, b);
+ p[n + size]= sum(a, SIZE - b);
+ }
+
}
void noe_gfft(GFF4Element *dst, GFF4Element *src, int logSize){
-// int i, j, pass;
+// int i, j, pass;
//printf("%X %X\n", noe_exp[4096], noe_exp[3*4096]);
- assert(logSize>=5);
+ assert(logSize>=5);
- if(src==dst)
- fftn(dst, logSize);
- else
- fftn2(dst, src, logSize);
+ if(src==dst)
+ fftn(dst, logSize);
+ else
+ fftn2(dst, src, logSize);
#if 0
- memcpy(dst, src, sizeof(GFF4Element)<<logSize);
- for(pass=0; pass<12; pass++){
- int block;
- const int np= 1<<(16-pass-1);
- const int blockCount= 1<<pass;
-
- for(block=0; block<blockCount; block++){
- int n;
- const int top= block*np<<1;
- const int bot= top + np;
-
- for(n=0; n<np; n++){
- const unsigned int w= noe_exp[ n<<pass ];
- const unsigned int a= dst[top + n];
- const unsigned int b= dst[bot + n];
-
- dst[top + n]= sum(a, b);
- dst[bot + n]= prod(sum(a, SIZE - b), w);
- }
- }
- }
+ memcpy(dst, src, sizeof(GFF4Element)<<logSize);
+ for(pass=0; pass<12; pass++){
+ int block;
+ const int np= 1<<(16-pass-1);
+ const int blockCount= 1<<pass;
+
+ for(block=0; block<blockCount; block++){
+ int n;
+ const int top= block*np<<1;
+ const int bot= top + np;
+
+ for(n=0; n<np; n++){
+ const unsigned int w= noe_exp[ n<<pass ];
+ const unsigned int a= dst[top + n];
+ const unsigned int b= dst[bot + n];
+
+ dst[top + n]= sum(a, b);
+ dst[bot + n]= prod(sum(a, SIZE - b), w);
+ }
+ }
+ }
- {
- int block;
- for(block=0; block<4096; block++){
+ {
+ int block;
+ for(block=0; block<4096; block++){
{START_TIMER
- fft16(dst + block*16);
+ fft16(dst + block*16);
STOP_TIMER}
- }
- }
+ }
+ }
#endif
}
void noe_igfft(GFF4Element *dst, GFF4Element *src, int logSize){
- assert(logSize>=5);
+ assert(logSize>=5);
- if(src!=dst)
- memcpy(dst, src, sizeof(GFF4Element)<<logSize);
+ if(src!=dst)
+ memcpy(dst, src, sizeof(GFF4Element)<<logSize);
- ifftn(dst, logSize);
+ ifftn(dst, logSize);
}
Modified: trunk/noe/gfft.h
==============================================================================
--- trunk/noe/gfft.h (original)
+++ trunk/noe/gfft.h Tue Jul 10 00:37:39 2007
@@ -25,6 +25,6 @@ int noe_log2(unsigned int v);
extern uint8_t noe_revTable[256];
static inline unsigned int noe_bitReverse(unsigned int x){
- return (noe_revTable[x&255]<<8) | (noe_revTable[x>>8]);
+ return (noe_revTable[x&255]<<8) | (noe_revTable[x>>8]);
}
Modified: trunk/noe/noe.c
==============================================================================
--- trunk/noe/noe.c (original)
+++ trunk/noe/noe.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003-2005 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,26 +17,40 @@
*/
#include <inttypes.h>
-
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include "galois.h"
+#include "rs.h"
+#include "rw.h"
+#include "bytestream.h"
+
static const uint8_t startcode[8]={0xAB, 0x2C, 0xE2, 0x47, 0x15, 'N', 'O', 'E'};
//#define STARTCODE (0xAB2CE24715000000ULL + ('N'<<16) + ('O'<<8) + 'E')
#define STARTCODE_THRESHOLD 6
-#define HEADER_PARITY_LENGTH 26
-#define HEADER_LENGTH (38 + HEADER_PARITY_LENGTH)
+#define HEADER_PARITY_LENGTH 16
+#define HEADER_DATA_LENGTH 34
+#define HEADER_LENGTH (HEADER_DATA_LENGTH + HEADER_PARITY_LENGTH)
+#define HEADER_THRESHOLD (HEADER_LENGTH/2) //50
#define BUFFER_LENGTH 262144
+#define HASH_BITS 32
typedef struct NoeContext{
- int debug;
- int fileId;
- int fileChecksum;
- int fileIdThreshold;
- int seqNum;
- int headerCount;
- int parityCount;
- int fingerprintCount;
- int flags;
- int dataSize;
- int header[HEADER_LENGTH][256];
+ int debug;
+ int fileChecksum;
+ int seqNum;
+ int headerCount;
+ int parityCount;
+ int fingerprintCount;
+ int flags;
+ int dataSize;
+ int fileIdThreshold;
+ int version;
+// uint8_t header[HEADER_LENGTH];
+ int header[HEADER_LENGTH][256];
+ uint32_t *fingerprint;
+ uint8_t *fingerprintOk;
+ int fingerprintOk_count;
}NoeContext;
const static uint8_t parity[256]={
@@ -59,127 +73,124 @@ const static uint8_t parity[256]={
};
/**
- *
+ * searches for a header.
* @return length if not found
*/
-static uint64_t find_header(NoeContext *n, uint8_t *buffer, uint64_t length){
- int i;
+static int find_header(NoeContext *n, uint8_t *buffer, int length){
+ int i;
- for(i=0; i + HEADER_LENGTH < length; i++){
- int j;
- int score=8;
+ for(i=0; i + HEADER_LENGTH < length; i++){
+ int j;
+ int score=8;
- for(j=0; j<8; j++){
- if(buffer[i + j] != startcode[j]){
- score--;
- if(score < STARTCODE_THRESHOLD) break;
- }
- }
- if(score < STARTCODE_THRESHOLD) continue;
+ for(j=0; j<8; j++){
+ if(buffer[i + j] != startcode[j])
+ score--;
+ }
+ if(score < STARTCODE_THRESHOLD) continue;
- score=8;
- for(j=0; j<4; j++){ //FIXME cleaner?
- if(buffer[i + 12 + j] != ((n->fileChecksum >> (24 - 8*j)) & 0xFF))
- score--;
- }
- for(j=0; j<4; j++){
- if(buffer[i + 16+ j] != ((n->fileId >> (24 - 8*j)) & 0xFF))
- score--;
- }
- if(score < n->fileIdThreshold) continue;
+ score+=4;
+ for(j=0; j<4; j++){
+ if(buffer[i + 12 + j] != ((n->fileChecksum >> (24 - 8*j)) & 0xFF))
+ score--;
+ }
+/* for(j=0; j<4; j++){
+ if(buffer[i + 16+ j] != ((n->fileId >> (24 - 8*j)) & 0xFF))
+ score--;
+ }*/
+ if(score < n->fileIdThreshold) continue;
- return i;
- }
+ return i;
+ }
- return length;
+ return length;
}
static int decode_header(NoeContext *n, uint8_t *buffer){
- ByteStream bc;
- int erasedCount=0; //FIXME
- const int n= SIZE - 1;
- const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
- GFF4Element erased[HEADER_PARITY_LENGTH];
- GFF4Element code[n];
- int i,j;
+ uint8_t *bs;
+ int erasedCount=0; //FIXME
+ const int nn= SIZE - 1;
+ const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
+ GFF4Element erased[HEADER_PARITY_LENGTH];
+ GFF4Element code[nn];
+ int i,j;
- for(j=0; j<8; j++){
- buffer[j] = startcode[j];
- }
-
- for(i=12; i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
- int best=0;
- int bestScore=0;
+ for(j=0; j<8; j++){
+ buffer[j] = startcode[j];
+ }
+
+ for(i=12; i<HEADER_DATA_LENGTH; i++){
+ int best=0;
+ int bestScore=0;
- for(j=0; j<256; j++){
- const int score= n->header[i][j];
- if(score > bestScore){
- bestScore= score;
- best= j;
- }
- }
- buffer[i]= best; //FIXME dont modify it / load into code directly
- }
+ for(j=0; j<256; j++){
+ const int score= n->header[i][j];
+ if(score > bestScore){
+ bestScore= score;
+ best= j;
+ }
+ }
+ buffer[i]= best; //FIXME dont modify it / load into code directly
+ }
- initByteStream(&bc, buffer, HEADER_LENGTH);
+ bs= buffer;
- memset(code, 0, sizeof(GFF4Element)*n);
- for(i=0; 2*i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
- code[i ]= get_c(bc, 2);
- }
- for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
- code[k+i]= get_c(bc, 2);
- }
+ memset(code, 0, sizeof(GFF4Element)*nn);
+ for(i=0; 2*i<HEADER_DATA_LENGTH; i++){
+ code[i ]= get_c(&bs, 2);
+ }
+ for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
+ code[k+i]= get_c(&bs, 2);
+ }
- if(noe_rsDecode(code, erased, erasedCount, HEADER_PARITY_LENGTH) < 0)
- return -1;
+ if(noe_rsDecode(code, erased, erasedCount, HEADER_PARITY_LENGTH) < 0)
+ return -1;
- for(i=HEADER_LENGTH - HEADER_PARITY_LENGTH; i<k; i++){
- if(code[i] != 0)
- return -2;
- }
- for(i=0; i<8; i++){
- if(buffer[i] != startcode[i])
- return -2;
- }
+ for(i=HEADER_DATA_LENGTH; i<k; i++){
+ if(code[i] != 0)
+ return -2;
+ }
+ for(i=0; i<8; i++){
+ if(buffer[i] != startcode[i])
+ return -2;
+ }
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // noe_printPoly(gen, i);
+ // noe_printPoly(syn, i-1);
- for(i=0; 2*i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
- buffer[2*i+0]= code[ i] >> 8;
- buffer[2*i+1]= code[ i];
- }
- for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
- const int j= i + (HEADER_LENGTH - HEADER_PARITY_LENGTH)/2;
- buffer[2*j+0]= code[k+i] >> 8;
- buffer[2*j+1]= code[k+i];
- }
+ for(i=0; 2*i<HEADER_DATA_LENGTH; i++){
+ buffer[2*i+0]= code[ i] >> 8;
+ buffer[2*i+1]= code[ i];
+ }
+ for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
+ const int j= i + HEADER_DATA_LENGTH/2;
+ buffer[2*j+0]= code[k+i] >> 8;
+ buffer[2*j+1]= code[k+i];
+ }
- initByteStream(&bc, buffer, HEADER_LENGTH);
+ bs= buffer;
- get_c(bc, 8);
- n->seqNum= get_c(bc, 4);
- n->fileChecksum= get_c(bc, 4);
- n->fileId= get_c(bc, 4);
- n->version= get_c(bc, 1);
- if(n->version > 0)
- return -3;
+ get_c(&bs, 8);
+ n->seqNum= get_c(&bs, 4);
+ n->fileChecksum= get_c(&bs, 4);
+ n->version= get_c(&bs, 1);
+ if(n->version > 0)
+ return -3;
- n->flags= get_c(bc, 1);
- n->headerCount= get_c(bc, 4);
- if(n->seqNum >= n->headerCount)
- return -2;
+ n->flags= get_c(&bs, 1);
+ n->headerCount= get_c(&bs, 4);
+ if(n->seqNum >= n->headerCount)
+ return -2;
- n->parityCount= get_c(bc, 2);
- n->fingerprintCount= get_c(bc, 2);
- n->dataSize= get_c(bc, 8);
+ n->parityCount= get_c(&bs, 2);
+ n->fingerprintCount= get_c(&bs, 2);
+ n->dataSize= get_c(&bs, 8);
- for(i=12; i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
- n->header[i][ buffer[i] ]= INT_MAX/2;
- }
+ for(i=12; i<HEADER_DATA_LENGTH; i++){
+ n->header[i][ buffer[i] ]= INT_MAX/2;
+ }
- return n->seqNum;
+ return n->seqNum;
}
@@ -188,57 +199,61 @@ static int decode_header(NoeContext *n,
* @return -1 if not found
*/
static int find_and_decode_global_header(NoeContext *n, noe_RwContext *rw){
- int length= BUFFER_LENGTH
- uint64_t i;
- uint8_t buffer[length];
+ int length= BUFFER_LENGTH;
+ uint64_t i;
+ uint8_t buffer[length];
- for(i=rw->size; i>=0; i-= length - HEADER_LENGTH){
- int pos;
+ for(i=rw->size; i>=0; i-= length - HEADER_LENGTH){
+ int pos;
- if(i < length) length= i;
- rw->io(rw, buffer, i - length, length, 0);
+ if(i < length) length= i;
+ rw->io(rw, buffer, i - length, length, 0);
- for(pos=0; ; pos++){
- int j;
- pos += find_header(n, buffer + pos, length - pos);
- if(pos >= length) break;
+ for(pos=0; ; pos++){
+ int j;
+ pos += find_header(n, buffer + pos, length - pos);
+ if(pos >= length) break;
- for(j=0; j<HEADER_LENGTH; j++){ //FIXME bitwise histogram?
- const int c= buffer[pos + j]
- n->header[j][c]++;
- }
+ for(j=0; j<HEADER_LENGTH; j++){ //FIXME bitwise histogram?
+ const int c= buffer[pos + j];
+ n->header[j][c]++;
+ }
- if( decode_header(n, buffer + pos) >= 0)
- return 0;
- }
- length= BUFFER_LENGTH;
- }
+ if( decode_header(n, buffer + pos) >= 0)
+ return 0;
+ }
+ length= BUFFER_LENGTH;
+ }
- return -1;
+ return -1;
}
static inline int getChecksum(unsigned int fingerprint, unsigned int pos){
- return (fingerprint ^ pos) % 251;
+ return (fingerprint ^ pos) % 251;
}
static int decode_fingerprints(NoeContext *n, uint8_t *buffer, int length){
- int i, count;
- ByteStream bc;
+ int i, count;
+ uint8_t *bs;;
- count= MIN(n->fingerprintCount, length/5);
+ count= n->fingerprintCount;
+ if(count > length/5)
+ count= length/5;
- initByteStream(&bc, buffer, 5*count);
- for(i=0; i<count; i++){
- const unsigned int c= get_c(bc, 4);
- const int checksum= get_c(bc, 1);
- const int index= n->seqNum + i*n->headerCount;
- const int expectedChecksum= getChecksum(c, index);
+ bs= buffer;
+ for(i=0; i<count; i++){
+ const unsigned int c= get_c(&bs, 4);
+ const int checksum= get_c(&bs, 1);
+ const int index= n->seqNum + i*n->headerCount;
+ const int expectedChecksum= getChecksum(c, index);
- if(expectedChecksum == checksum){
- n->fingerprintOk[index]= 1;
- n->fingerprint[index]= c;
- }//FIXME resync
- }
+ if(expectedChecksum == checksum){
+ n->fingerprintOk[index]= 1;
+ n->fingerprint[index]= c;
+ n->fingerprintOk_count++;
+ }//FIXME resync
+ }
+ return 0;
}
/**
@@ -246,36 +261,65 @@ static int decode_fingerprints(NoeContex
* @return -1 if not found
*/
static int find_and_decode_packets(NoeContext *n, noe_RwContext *rw){
- int length= BUFFER_LENGTH
- const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
- uint64_t i;
- uint8_t buffer[length];
+ int length= BUFFER_LENGTH;
+ const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
+ uint64_t i;
+ uint8_t buffer[length];
- n->fingerprint = malloc(n->fingerprintCount*n->headerCount * sizeof(int));
- n->fingerprintOk= malloc(n->fingerprintCount*n->headerCount);
- memset(n->fingerprintOk, 0, n->fingerprintCount*n->headerCount);
+ n->fingerprint = malloc(n->fingerprintCount*n->headerCount * sizeof(int));
+ n->fingerprintOk= malloc(n->fingerprintCount*n->headerCount);
+ memset(n->fingerprintOk, 0, n->fingerprintCount*n->headerCount);
- for(i=rw->size; i>=0; i-= length - packetLength){
- int pos;
+ for(i=rw->size; i>=0; i-= length - packetLength){
+ int pos;
- if(i < length) length= i;
- rw->io(rw, buffer, i - length, length, 0);
+ if(i < length) length= i;
+ rw->io(rw, buffer, i - length, length, 0);
- for(pos=0; ; pos++){
- int j;
- pos += find_header(n, buffer + pos, length - pos);
- if(pos >= length) break;
+ for(pos=0; ; pos++){
+ int j;
+ pos += find_header(n, buffer + pos, length - pos);
+ if(pos >= length) break;
- if( decode_header(n, buffer + pos) < 0 )
- continue;
- pos += HEADER_LENGTH;
+ if( decode_header(n, buffer + pos) < 0 )
+ continue;
+ pos += HEADER_LENGTH;
- decode_fingerprints(n, buffer + pos, length - pos);
- }
- length= BUFFER_LENGTH;
-
- //FIXME detect if enough packets
- }
+ decode_fingerprints(n, buffer + pos, length - pos);
+ }
+ length= BUFFER_LENGTH;
- return -1;
+ if(n->fingerprintOk_count >= n->fingerprintCount*n->headerCount*15/16)
+ break;
+ }
+
+ return 0;
+}
+
+static int match_fingerprints(NoeContext *n, noe_RwContext *rw){
+ int length= BUFFER_LENGTH;
+// const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
+ uint64_t i;
+ uint8_t buffer[length];
+
+ for(i=0; i<n->fingerprintCount*n->headerCount; i++){
+ if(!n->fingerprintOk[i])
+ continue;
+
+ }
+
+ for(i=0; i<rw->size; i+= length - HASH_BITS/8){
+ int pos;
+
+ rw->io(rw, buffer, i, length, 0);
+
+ for(pos=0; ; pos++){
+ }
+ }
+
+// remove certainly false matches (where better match exists)
+
+// setup remap table
}
+
+//decode data into another file
Modified: trunk/noe/noe_internal.h
==============================================================================
--- trunk/noe/noe_internal.h (original)
+++ trunk/noe/noe_internal.h Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,12 +21,12 @@
static inline long long rdtsc()
{
- long long l;
- asm volatile( "rdtsc\n\t"
- : "=A" (l)
- );
-// printf("%d\n", int(l/1000));
- return l;
+ long long l;
+ asm volatile( "rdtsc\n\t"
+ : "=A" (l)
+ );
+// printf("%d\n", int(l/1000));
+ return l;
}
#define START_TIMER \
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,139 +32,139 @@
*
*/
void noe_getRsGenerator(GFF4Element *dst, int first, int order){
- int i;
- GFF4Element factor[2*order];
+ int i;
+ GFF4Element factor[2*order];
- factor[0]= SIZE - noe_exp[first];
- factor[1]= 1;
+ factor[0]= SIZE - noe_exp[first];
+ factor[1]= 1;
- for(i=1; i<order; i++){
- factor[2*i+0]= prod(factor[2*i-2], PRIMITIVE_ELEMENT);
- factor[2*i+1]= 1;
- }
-
- noe_synthPoly(dst, factor, order);
+ for(i=1; i<order; i++){
+ factor[2*i+0]= prod(factor[2*i-2], PRIMITIVE_ELEMENT);
+ factor[2*i+1]= 1;
+ }
+
+ noe_synthPoly(dst, factor, order);
}
-void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int first, int order){
- noe_gfft(syn, src, 16);
- noe_permute(syn, syn, order+1);
+void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order){
+ noe_gfft(syn, src, 16);
+ noe_permute(syn, syn, order+1);
- syn[0]= 1;
+ syn[0]= 1;
#if 0
- for(i=0; i<order; i++){
- syn[i+1]= noe_evalPoly(src, SIZE-2, noe_exp[first + i]);
- }
+ for(i=0; i<order; i++){
+ syn[i+1]= noe_evalPoly(src, SIZE-2, noe_exp[1 + i]);
+ }
#endif
}
#if 1
noe_RsEncoder *noe_getRsEncoder(int parityCount){
- const int dataCount= SIZE - parityCount - 1;
- int i;
- GFF4Element *locator, *factor;
- GFF4Element locatorDerivative[parityCount];
- noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
-
- locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+1));
- factor= encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount );
+ const int dataCount= SIZE - parityCount - 1;
+ int i;
+ GFF4Element *locator, *factor;
+ GFF4Element locatorDerivative[parityCount];
+ noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
+
+ locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+1));
+ factor= encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount );
- encoder->parityCount= parityCount;
-
- locator[0]= 1;
- for(i=0; i<parityCount; i++){
- GFF4Element locationFactor[2];
-
- locationFactor[0] = 1;
- locationFactor[1] = SIZE - noe_exp[dataCount + i];
- noe_prodPoly(locator, locator, locationFactor, i, 1); //FIXME use synthPoly
- }
+ encoder->parityCount= parityCount;
+
+ locator[0]= 1;
+ for(i=0; i<parityCount; i++){
+ GFF4Element locationFactor[2];
+
+ locationFactor[0] = 1;
+ locationFactor[1] = SIZE - noe_exp[dataCount + i];
+ noe_prodPoly(locator, locator, locationFactor, i, 1); //FIXME use synthPoly
+ }
#if 0
for(i=0; i<parityCount; i++){
- if(noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount + i]))){
- printf("Internal Error 1\n");
- }
+ if(noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount + i]))){
+ printf("Internal Error 1\n");
+ }
}
if(!noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount - 1])))
- printf("Internal Error 2\n");
+ printf("Internal Error 2\n");
#endif
- i= noe_getDerivative(locatorDerivative, locator, parityCount);
- assert(i==parityCount-1);
+ i= noe_getDerivative(locatorDerivative, locator, parityCount);
+ assert(i==parityCount-1);
- for(i=0; i<parityCount; i++){
- GFF4Element X= noe_exp[dataCount + i];
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
- GFF4Element denom;
-
- assert(X == inv(invX));
+ for(i=0; i<parityCount; i++){
+ GFF4Element X= noe_exp[dataCount + i];
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+ GFF4Element denom;
+
+ assert(X == inv(invX));
- denom= noe_evalPoly(locatorDerivative, parityCount-1, invX); //FIXME do in freq domain if parityCount>1000
- factor[i]= prod(SIZE - X, inv(denom));
- }
-
- return encoder;
+ denom= noe_evalPoly(locatorDerivative, parityCount-1, invX); //FIXME do in freq domain if parityCount>1000
+ factor[i]= prod(SIZE - X, inv(denom));
+ }
+
+ return encoder;
}
void noe_freeRsEncoder(noe_RsEncoder *encoder){
- if(!encoder) return;
-
- if(encoder->parityLocator) free(encoder->parityLocator);
- encoder->parityLocator= NULL;
-
- if(encoder->parityFactor) free(encoder->parityFactor);
- encoder->parityFactor= NULL;
+ if(!encoder) return;
+
+ if(encoder->parityLocator) free(encoder->parityLocator);
+ encoder->parityLocator= NULL;
+
+ if(encoder->parityFactor) free(encoder->parityFactor);
+ encoder->parityFactor= NULL;
- free(encoder);
+ free(encoder);
}
/**
*
*/
void noe_rsEncode(noe_RsEncoder *encoder, GFF4Element *data){
- int i;
- const int parityCount= encoder->parityCount;
- const int dataCount= SIZE - parityCount - 1;
- GFF4Element syn[SIZE - 1];
- GFF4Element omega[SIZE - 1];
- GFF4Element *locator= encoder->parityLocator;
- GFF4Element *factor= encoder->parityFactor;
+ int i;
+ const int parityCount= encoder->parityCount;
+ const int dataCount= SIZE - parityCount - 1;
+ GFF4Element syn[SIZE - 1];
+ GFF4Element omega[SIZE - 1];
+ GFF4Element *locator= encoder->parityLocator;
+ GFF4Element *factor= encoder->parityFactor;
- memset(data + dataCount, 0, parityCount*sizeof(GFF4Element));
-
- noe_getSyndrom(syn, data, 1, parityCount);
+ memset(data + dataCount, 0, parityCount*sizeof(GFF4Element));
+
+ noe_getSyndrom(syn, data, parityCount);
- noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
-
- if(parityCount < 1000){
- for(i=0; i<parityCount; i++){
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
-
- GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
-
- data[dataCount + i]= SIZE - parity;
- }
- }else{
+ noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
+
+ if(parityCount < 1000){
+ for(i=0; i<parityCount; i++){
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+
+ GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+
+ data[dataCount + i]= SIZE - parity;
+ }
+ }else{
//START_TIMER
#if 0
- for(i=0; i<parityCount; i++){
- GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
-
- GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
-
- data[dataCount + i]= SIZE - parity;
- }
+ for(i=0; i<parityCount; i++){
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+
+ GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+
+ data[dataCount + i]= SIZE - parity;
+ }
#else
- memset(omega + parityCount + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
- noe_gfft(omega, omega, 16);
- for(i=0; i<parityCount; i++){
- int index= SIZE - dataCount - i - 1;
-
- GFF4Element parity= prod(omega[noe_bitReverse(index)], factor[i]);
-
- data[dataCount + i]= SIZE - parity;
- }
+ memset(omega + parityCount + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
+ noe_gfft(omega, omega, 16);
+ for(i=0; i<parityCount; i++){
+ int index= SIZE - dataCount - i - 1;
+
+ GFF4Element parity= prod(omega[noe_bitReverse(index)], factor[i]);
+
+ data[dataCount + i]= SIZE - parity;
+ }
#endif
//STOP_TIMER
- }
+ }
}
#endif
@@ -173,168 +173,168 @@ void noe_rsEncode(noe_RsEncoder *encoder
* @param omega must be parityCount+2 big
*/
int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount, int *locatorOrderP, int *omegaOrderP){
- int i, quotOrder;
- int locatorOrder[2]= {0,0};
- int omegaOrder[2]= {parityCount+1, -1};
- GFF4Element quot[parityCount+2]; //FIXME size ok?
+ int i, quotOrder;
+ int locatorOrder[2]= {0,0};
+ int omegaOrder[2]= {parityCount+1, -1};
+ GFF4Element quot[parityCount+2]; //FIXME size ok?
- memset(omega[0], 0, (parityCount+1)*sizeof(GFF4Element));
- omega[0][parityCount+1]= 1;
- locator[0][0]=0;
- locator[1][0]=1;
- omegaOrder[1]= noe_getOrder(omega[1], parityCount);
-
- for(i=0; 1; i++){
- const int di= i&1;
- const int si= 1-di;
+ memset(omega[0], 0, (parityCount+1)*sizeof(GFF4Element));
+ omega[0][parityCount+1]= 1;
+ locator[0][0]=0;
+ locator[1][0]=1;
+ omegaOrder[1]= noe_getOrder(omega[1], parityCount);
+
+ for(i=0; 1; i++){
+ const int di= i&1;
+ const int si= 1-di;
#ifdef DEBUG_EUCLID
printf("Locator0:");noe_printPoly(locator[di], locatorOrder[di]);
printf("Omega0:");noe_printPoly(omega[di], omegaOrder[di]);
printf("Locator1:");noe_printPoly(locator[si], locatorOrder[si]);
printf("Omega1:");noe_printPoly(omega[si], omegaOrder[si]);
#endif
- if(2*omegaOrder[si] <= parityCount + erasureCount)
- break;
+ if(2*omegaOrder[si] <= parityCount + erasureCount)
+ break;
- quotOrder= omegaOrder[di] - omegaOrder[si];
+ quotOrder= omegaOrder[di] - omegaOrder[si];
- omegaOrder[di]= noe_divPoly(quot, omega[di], omega[di], omega[si], omegaOrder[di], omegaOrder[si]);
+ omegaOrder[di]= noe_divPoly(quot, omega[di], omega[di], omega[si], omegaOrder[di], omegaOrder[si]);
- quotOrder= noe_prodPoly(quot, quot, locator[si], quotOrder, locatorOrder[si]);
- locatorOrder[di]= noe_diffPoly(locator[di], locator[di], quot, locatorOrder[di], quotOrder);
+ quotOrder= noe_prodPoly(quot, quot, locator[si], quotOrder, locatorOrder[si]);
+ locatorOrder[di]= noe_diffPoly(locator[di], locator[di], quot, locatorOrder[di], quotOrder);
#ifdef DEBUG_EUCLID
printf("quot:");noe_printPoly(quot, quotOrder);
printf("Locator:");noe_printPoly(locator[di], locatorOrder[di]);
printf("Omega:");noe_printPoly(omega[di], omegaOrder[di]);
#endif
- }
+ }
- i++;
-
- *locatorOrderP= locatorOrder[i&1];
- *omegaOrderP= omegaOrder[i&1];
+ i++;
+
+ *locatorOrderP= locatorOrder[i&1];
+ *omegaOrderP= omegaOrder[i&1];
- return i&1;
+ return i&1;
}
int noe_rsDecode(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
- int i;
- int errorCount, psiOrder, gfftEval, omegaOrder, phantomErrorCount;
- const int dataCount= SIZE - 1 - parityCount;
- GFF4Element erasureLocator[erasureCount + 1];
- GFF4Element erasureSynthSrc[erasureCount*2 + 1];
- GFF4Element locator0[parityCount + 1];
- GFF4Element locator1[parityCount + 1];
- GFF4Element *locators[2]={locator0, locator1};
- GFF4Element omega0[SIZE - 1];
- GFF4Element omega1[SIZE - 1];
- GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
- GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
+ int i;
+ int errorCount, psiOrder, gfftEval, omegaOrder, phantomErrorCount;
+ const int dataCount= SIZE - 1 - parityCount;
+ GFF4Element erasureLocator[erasureCount + 1];
+ GFF4Element erasureSynthSrc[erasureCount*2 + 1];
+ GFF4Element locator0[parityCount + 1];
+ GFF4Element locator1[parityCount + 1];
+ GFF4Element *locators[2]={locator0, locator1};
+ GFF4Element omega0[SIZE - 1];
+ GFF4Element omega1[SIZE - 1];
+ GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
+ GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
- syn= omegas[1];
-
- /* kill erased symbols */
- for(i=0; i<erasureCount; i++){
+ syn= omegas[1];
+
+ /* kill erased symbols */
+ for(i=0; i<erasureCount; i++){
//printf("%d\n", erasure[i]);
- data[ erasure[i] ]=0;
- }
+ data[ erasure[i] ]=0;
+ }
- noe_getSyndrom(syn, data, 1, parityCount);
- for(i=1; i<=parityCount; i++){
- if(syn[i]) break;
- }
- if(i>parityCount)
- return 0;
+ noe_getSyndrom(syn, data, parityCount);
+ for(i=1; i<=parityCount; i++){
+ if(syn[i]) break;
+ }
+ if(i>parityCount)
+ return 0;
- phantomErrorCount=0;
- //FIXME check truncated symbols syndrom
+ phantomErrorCount=0;
+ //FIXME check truncated symbols syndrom
- for(i=0; i<erasureCount; i++){
- erasureSynthSrc[2*i + 0] = 1;
- erasureSynthSrc[2*i + 1] = SIZE - noe_exp[erasure[i]];
- }
- noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
-// noe_printPoly(erasureLocator, erasureCount);
+ for(i=0; i<erasureCount; i++){
+ erasureSynthSrc[2*i + 0] = 1;
+ erasureSynthSrc[2*i + 1] = SIZE - noe_exp[erasure[i]];
+ }
+ noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
+// noe_printPoly(erasureLocator, erasureCount);
#if 0
for(i=0; i<erasureCount; i++){
- int eval= noe_evalPoly(erasureLocator, erasureCount, inv(noe_exp[erasure[i]]));
- assert( eval==0);
+ int eval= noe_evalPoly(erasureLocator, erasureCount, inv(noe_exp[erasure[i]]));
+ assert( eval==0);
}
#endif
- noe_partialProdPoly(syn, erasureLocator, syn, erasureCount, parityCount);
+ noe_partialProdPoly(syn, erasureLocator, syn, erasureCount, parityCount);
- i= noe_rsEuclid(locators, omegas, parityCount, erasureCount, &errorCount, &omegaOrder);
+ i= noe_rsEuclid(locators, omegas, parityCount, erasureCount, &errorCount, &omegaOrder);
//printf("errorCount %d \n", errorCount);
- if(i<0) return -1;
+ if(i<0) return -1;
- omega= omegas[i];
- errorLocator= locators[i];
- fErrorLocator= omegas[1-i]; //reuse some unused space
- psi= locators[1-i]; //reuse some unused space
+ omega= omegas[i];
+ errorLocator= locators[i];
+ fErrorLocator= omegas[1-i]; //reuse some unused space
+ psi= locators[1-i]; //reuse some unused space
- gfftEval= errorCount>20;
- if(gfftEval && errorCount){
- memcpy(fErrorLocator, errorLocator, (errorCount+1)*sizeof(GFF4Element));
- memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
- noe_gfft(fErrorLocator, fErrorLocator, 16);
- }
+ gfftEval= errorCount>20;
+ if(gfftEval && errorCount){
+ memcpy(fErrorLocator, errorLocator, (errorCount+1)*sizeof(GFF4Element));
+ memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
+ noe_gfft(fErrorLocator, fErrorLocator, 16);
+ }
- psiOrder= noe_prodPoly(psi, errorLocator, erasureLocator, errorCount, erasureCount);
- psiOrder= noe_getDerivative(psi, psi, psiOrder);
+ psiOrder= noe_prodPoly(psi, errorLocator, erasureLocator, errorCount, erasureCount);
+ psiOrder= noe_getDerivative(psi, psi, psiOrder);
- if(errorCount){
- for(i=0; i<SIZE-1; i++){
- int r, e;
- GFF4Element X, invX, nom, denom;
+ if(errorCount){
+ for(i=0; i<SIZE-1; i++){
+ int r, e;
+ GFF4Element X, invX, nom, denom;
- if(gfftEval){ //FIXME optimize
- if(fErrorLocator[i])
- continue;
-
- r= (- noe_bitReverse(i))&0xFFFF;
- }else{
- if(noe_evalPoly(errorLocator, errorCount, noe_exp[i]))
- continue;
-
- r= (-i)&0xFFFF;
- }
+ if(gfftEval){ //FIXME optimize
+ if(fErrorLocator[i])
+ continue;
+
+ r= (- noe_bitReverse(i))&0xFFFF;
+ }else{
+ if(noe_evalPoly(errorLocator, errorCount, noe_exp[i]))
+ continue;
+
+ r= (-i)&0xFFFF;
+ }
//printf("E%6d %6d\n", i, r);
- X = noe_exp[r];
- invX= noe_exp[SIZE - r - 1];
- nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
- denom= noe_evalPoly(psi, psiOrder, invX);
+ X = noe_exp[r];
+ invX= noe_exp[SIZE - r - 1];
+ nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
+ denom= noe_evalPoly(psi, psiOrder, invX);
- assert(r>=0 && r<=SIZE-2);
- e= prod(nom, inv(denom));
- if(data[r]==0 && e==0x10000){
- if(r < dataCount)
- return -1;
- else
- phantomErrorCount++;
- }
- data[r]= sum(data[r], e);
- }
- }
+ assert(r>=0 && r<=SIZE-2);
+ e= prod(nom, inv(denom));
+ if(data[r]==0 && e==0x10000){
+ if(r < dataCount)
+ return -1;
+ else
+ phantomErrorCount++;
+ }
+ data[r]= sum(data[r], e);
+ }
+ }
- for(i=0; i<erasureCount; i++){
- const int r= erasure[i];
- const GFF4Element X = noe_exp[r];
- const GFF4Element invX= noe_exp[SIZE - r - 1];
- GFF4Element nom, denom;
+ for(i=0; i<erasureCount; i++){
+ const int r= erasure[i];
+ const GFF4Element X = noe_exp[r];
+ const GFF4Element invX= noe_exp[SIZE - r - 1];
+ GFF4Element nom, denom;
- assert(r>=0 && r<0x10000);
- assert(prod(X, invX)==1);
-
- nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
- denom= noe_evalPoly(psi, psiOrder, invX);
+ assert(r>=0 && r<0x10000);
+ assert(prod(X, invX)==1);
+
+ nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
+ denom= noe_evalPoly(psi, psiOrder, invX);
- assert(data[r]==0);
- data[r]= prod(nom, inv(denom));
- }
+ assert(data[r]==0);
+ data[r]= prod(nom, inv(denom));
+ }
- return erasureCount + errorCount - phantomErrorCount;
+ return erasureCount + errorCount - phantomErrorCount;
}
Modified: trunk/noe/rs.h
==============================================================================
--- trunk/noe/rs.h (original)
+++ trunk/noe/rs.h Tue Jul 10 00:37:39 2007
@@ -17,9 +17,9 @@
*/
typedef struct noe_RsEncoder{
- int parityCount;
- GFF4Element *parityLocator;
- GFF4Element *parityFactor;
+ int parityCount;
+ GFF4Element *parityLocator;
+ GFF4Element *parityFactor;
}noe_RsEncoder;
void noe_getRsGenerator(GFF4Element *dst, int first, int order);
@@ -29,7 +29,7 @@ void noe_getRsGenerator(GFF4Element *dst
* @param src a 2^16 entry long polynom
* @param syn the syndrom polynom will be stored here
*/
-void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int first, int order);
+void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int order);
noe_RsEncoder *noe_getRsEncoder(int parityOrder);
void noe_freeRsEncoder(noe_RsEncoder *encoder);
Modified: trunk/noe/rw.c
==============================================================================
--- trunk/noe/rw.c (original)
+++ trunk/noe/rw.c Tue Jul 10 00:37:39 2007
@@ -19,65 +19,107 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "rw.h"
typedef struct noe_RemapRwContext{
- noe_RwContext rw;
- noe_Map *map;
- int count;
+ noe_RwContext rw;
+ noe_Map *map;
+ int count;
}noe_RemapRwContext;
static int remapIO(noe_RwContext *c, uint8_t *data, uint64_t pos, int len, int write){
- int i;
- noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
- noe_RwContext *parent= c->parent;
+ int i;
+ noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
+ noe_RwContext *parent= c->parent;
- //FIXME do binary search or cache last
+ //FIXME do binary search or cache last
- for(i=0; i<p->count; i++){
- if(pos < p->map[i].src + p->map[i].len){
- const uint64_t diff= p->map[i].dst - p->map[i].src;
- uint64_t currentLen= p->map[i].src + p->map[i].len - pos;
- if(currentLen > len) currentLen= len;
+ for(i=0; i<p->count; i++){
+ if(pos < p->map[i].src + p->map[i].len){
+ const uint64_t diff= p->map[i].dst - p->map[i].src;
+ uint64_t currentLen= p->map[i].src + p->map[i].len - pos;
+ if(currentLen > len) currentLen= len;
- parent->io(parent, data, pos + diff, currentLen, write);
-
- data+= currentLen;
- pos+= currentLen;
- len-= currentLen;
- if(len == 0) return 0;
- }
- }
+ parent->io(parent, data, pos + diff, currentLen, write);
+
+ data+= currentLen;
+ pos+= currentLen;
+ len-= currentLen;
+ if(len == 0) return 0;
+ }
+ }
- return -1;
+ return -1;
}
static void remapUninit(noe_RwContext *c){
- noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
+ noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
- if(c==NULL) return;
+ if(c==NULL) return;
- free(p->map);
- memset(p, 0, sizeof(noe_RemapRwContext));
- free(p);
+ free(p->map);
+ memset(p, 0, sizeof(noe_RemapRwContext));
+ free(p);
}
noe_RwContext *noe_getRemapRwContext(noe_RwContext *parent, noe_Map *map, int count){
- noe_RemapRwContext *p= malloc(sizeof(noe_RemapRwContext));
- noe_RwContext *c= (noe_RwContext*)p;
+ noe_RemapRwContext *p= malloc(sizeof(noe_RemapRwContext));
+ noe_RwContext *c= (noe_RwContext*)p;
- c->parent= parent;
+ c->parent= parent;
- p->map= malloc(sizeof(noe_Map)*count);
- memcpy(p->map, map, sizeof(noe_Map)*count);
- p->count= count;
-
- //FIXME sort map
+ p->map= malloc(sizeof(noe_Map)*count);
+ memcpy(p->map, map, sizeof(noe_Map)*count);
+ p->count= count;
+
+ //FIXME sort map
- c->io= remapIO;
- c->uninit= remapUninit;
+ c->io= remapIO;
+ c->uninit= remapUninit;
- return c;
+ return c;
+}
+
+static void update_buf(noe_RwContext *c, uint64_t pos, int len){
+ assert(len>0 && len<=64);
+// assert(pos < 8*c->size);
+
+ if(pos<8*c->pos || pos + len > 8*c->pos + 8*RW_SIZE){
+ if(c->flush){
+ c->io(c, c->buffer, c->pos, RW_SIZE, 1);
+ c->flush=0;
+ }
+ c->pos= pos/8 - RW_SIZE/2;
+ if(c->pos<0) c->pos=0;
+ //FIXME memmove the old to avoid redundant io
+ c->io(c, c->buffer, c->pos, RW_SIZE, 0);
+ }
+}
+
+uint64_t noe_read(noe_RwContext *c, uint64_t pos, int len){
+ int i;
+ uint64_t v=0;
+
+ update_buf(c, pos, len);
+
+ for(i=0; i<len; i++){
+ v += v + (c->buffer[(pos+i)/8 - c->pos] >> (8-((pos+i)&7)));
+ }
+ return v;
+}
+
+void noe_write(noe_RwContext *c, uint64_t pos, int len, uint64_t v){
+ int i;
+
+ update_buf(c, pos, len);
+
+ for(i=0; i<len; i++){
+ int bit= (v>>(len-i))&1;
+ c->buffer[(pos+i)/8 - c->pos] &= ~(1 <<(8-((pos+i)&7)));
+ c->buffer[(pos+i)/8 - c->pos] |= (bit<<(8-((pos+i)&7)));
+ }
+ c->flush=1;
}
Modified: trunk/noe/rw.h
==============================================================================
--- trunk/noe/rw.h (original)
+++ trunk/noe/rw.h Tue Jul 10 00:37:39 2007
@@ -15,23 +15,30 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+
+#define RW_SIZE (1<<18)
+
typedef struct noe_RwContext{
- uint64_t size;
+ uint8_t buffer[RW_SIZE];
+ uint64_t pos;
+ int flush;
+ uint64_t size;
- /**
- * reads or writes some data.
- * @returns <0 if an error occured
- */
- int (*io )(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len, int write);
+ /**
+ * reads or writes some data.
+ * @returns <0 if an error occured
+ */
+ int (*io )(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len, int write);
- void (*uninit)(struct noe_RwContext *context);
- struct noe_RwContext *parent;
+ void (*uninit)(struct noe_RwContext *context);
+ struct noe_RwContext *parent;
}noe_RwContext;
typedef struct noe_Map{
- uint64_t src;
- uint64_t dst;
- uint64_t len;
+ uint64_t src;
+ uint64_t dst;
+ uint64_t len;
}noe_Map;
+uint64_t noe_read(noe_RwContext *c, uint64_t pos, int len);
+void noe_write(noe_RwContext *c, uint64_t pos, int len, uint64_t v);
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:37:39 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,280 +52,281 @@ static const unsigned int gfftChecksums[
};
int main(){
- int i, j;
- GFF4Element bp=1;
+ int i, j;
+ GFF4Element bp=1;
- noe_init();
+ noe_init();
- printf("Testing GF(65537)\n");
- for(i=0; i<SIZE-1; i++){
- if((bp==1 || bp==0) && i>0){
- printf("FAIL %d %d\n", i, bp);
- break;
- }
- bp= prod(bp, PRIMITIVE_ELEMENT);
- }
- if(bp!=1) printf("FAILED to reach 1\n");
-
- printf("Testing inverse\n");
- bp=1;
- for(i=1; i<SIZE; i++){
- if(prod(bp, inv(bp)) != 1){
- printf("FAIL %X %X\n", (int)bp, (int)inv(bp));
- break;
- }
- bp= prod(bp, PRIMITIVE_ELEMENT);
- }
+ printf("Testing GF(65537)\n");
+ for(i=0; i<SIZE-1; i++){
+ if((bp==1 || bp==0) && i>0){
+ printf("FAIL %d %d\n", i, bp);
+ break;
+ }
+ bp= prod(bp, PRIMITIVE_ELEMENT);
+ }
+ if(bp!=1) printf("FAILED to reach 1\n");
+
+ printf("Testing inverse\n");
+ bp=1;
+ for(i=1; i<SIZE; i++){
+ if(prod(bp, inv(bp)) != 1){
+ printf("FAIL %X %X\n", (int)bp, (int)inv(bp));
+ break;
+ }
+ bp= prod(bp, PRIMITIVE_ELEMENT);
+ }
#if 0
- printf("Experiment");
- for(i=0; i<(1<<30); i++){
- unsigned int a= reduce(i*0xFF01);
- unsigned int b= reduce(reduce(i)*0xFF01);
-
- if(a!=b) printf("%X %X %X %X\n", i, reduce(i), i*0xFF01, reduce(i)*0xFF01);
- }
+ printf("Experiment");
+ for(i=0; i<(1<<30); i++){
+ unsigned int a= reduce(i*0xFF01);
+ unsigned int b= reduce(reduce(i)*0xFF01);
+
+ if(a!=b) printf("%X %X %X %X\n", i, reduce(i), i*0xFF01, reduce(i)*0xFF01);
+ }
#endif
- srand (31415);
+ srand (31415);
- printf("Testing GFFT");
- for(i=1; i<20; i++){
- int n= SIZE - 1;
- GFF4Element syn[n];
- GFF4Element code[n];
- int acc=0;
-
- for(j=0; j<n; j++)
- code[j]= rand() % 0x10001;
+ printf("Testing GFFT");
+ for(i=1; i<20; i++){
+ int n= SIZE - 1;
+ GFF4Element syn[n];
+ GFF4Element code[n];
+ int acc=0;
+
+ for(j=0; j<n; j++)
+ code[j]= rand() % 0x10001;
- noe_gfft(syn, code, 16);
-
- for(j=0; j<n; j++){
- acc+= syn[j];
- acc*=2*j+1;
- }
- if(gfftChecksums[i-1] != acc)
- printf("FAIL: 0x%08X != 0x%08X\n", gfftChecksums[i-1], acc);
-
- noe_igfft(syn, syn, 16);
- for(j=0; j<n; j++){
- syn[j]= prod(syn[j], inv(1<<16));
- }
-
- for(j=0; j<n; j++){
- if(syn[j] != code[j]) printf("IGFFT missmatch at %d %X!=%X\n", j, syn[j], code[j]);
- }
-
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
-
- printf("."); fflush(stdout);
- }
-
- srand (31415);
+ noe_gfft(syn, code, 16);
+
+ for(j=0; j<n; j++){
+ acc+= syn[j];
+ acc*=2*j+1;
+ }
+ if(gfftChecksums[i-1] != acc)
+ printf("FAIL: 0x%08X != 0x%08X\n", gfftChecksums[i-1], acc);
+
+ noe_igfft(syn, syn, 16);
+ for(j=0; j<n; j++){
+ syn[j]= prod(syn[j], inv(1<<16));
+ }
+
+ for(j=0; j<n; j++){
+ if(syn[j] != code[j]) printf("IGFFT missmatch at %d %X!=%X\n", j, syn[j], code[j]);
+ }
+
+// noe_printPoly(gen, i);
+// noe_printPoly(syn, i-1);
+
+ printf("."); fflush(stdout);
+ }
+
+ srand (31415);
- printf("\nTesting generator polynoms");
- for(i=1; i<100; i+=5){
- int n= SIZE - 1;
- int k= SIZE - 1 - i;
- GFF4Element syn[n];
- GFF4Element gen[i+1];
- GFF4Element data[k];
- GFF4Element code[n];
-
- for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
-
- noe_getRsGenerator(gen, 1, i);
- j=noe_prodPoly(code, gen, data, i, k-1);
- assert(j==n-1);
-
- noe_getSyndrom(syn, code, 1, i);
-
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
-
- for(j=0; j<i; j++){
- if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
- }
- printf("."); fflush(stdout);
- }
+ printf("\nTesting generator polynoms");
+ for(i=1; i<100; i+=5){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+ GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
+
+ for(j=0; j<k; j++)
+ data[j]= rand() & 0xFFFF;
+
+ noe_getRsGenerator(gen, 1, i);
+ j=noe_prodPoly(code, gen, data, i, k-1);
+ assert(j==n-1);
+
+ noe_getSyndrom(syn, code, i);
+
+// noe_printPoly(gen, i);
+// noe_printPoly(syn, i-1);
+
+ for(j=0; j<i; j++){
+ if(syn[j+1]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+ }
+ printf("."); fflush(stdout);
+ }
- printf("\nTesting encoder");
- for(i=1; i<1000; i+=200){
- int n= SIZE - 1;
- int k= SIZE - 1 - i;
- GFF4Element syn[n];
-// GFF4Element gen[i+1];
- GFF4Element data[k];
- GFF4Element code[n];
- noe_RsEncoder *encoder;
- int pass=5;
+ printf("\nTesting encoder");
+ for(i=1; i<1000; i+=200){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+// GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
+ noe_RsEncoder *encoder;
+ int pass=5;
- encoder= noe_getRsEncoder(i);
+ encoder= noe_getRsEncoder(i);
- for(pass=5; pass; pass--){
- for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ for(pass=5; pass; pass--){
+ for(j=0; j<k; j++)
+ data[j]= rand() & 0xFFFF;
- memcpy(code, data, n*sizeof(GFF4Element));
+ memcpy(code, data, n*sizeof(GFF4Element));
- noe_rsEncode(encoder, code);
+ noe_rsEncode(encoder, code);
- noe_getSyndrom(syn, code, 1, i);
- //FIXME check that code contains data, but its not touched so ...
+ noe_getSyndrom(syn, code, i);
+ //FIXME check that code contains data, but its not touched so ...
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // noe_printPoly(gen, i);
+ // noe_printPoly(syn, i-1);
- for(j=0; j<i; j++){
- if(syn[j+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
- }
- printf("."); fflush(stdout);
- }
- noe_freeRsEncoder(encoder);
- }
-
- printf("\nTesting decoder");
- for(i=1; i<2000; i+=100){
- int n= SIZE - 1;
- int k= SIZE - 1 - i;
-// GFF4Element syn[n];
- GFF4Element erased[i];
- GFF4Element data[k];
- GFF4Element code[n];
- noe_RsEncoder *encoder;
- int pass=5;
+ for(j=0; j<i; j++){
+ if(syn[j+1]) printf("FAIL generator:%d coefficient:%d is %X\n", i, j, syn[j+1]);
+ }
+ printf("."); fflush(stdout);
+ }
+ noe_freeRsEncoder(encoder);
+ }
+
+ printf("\nTesting decoder");
+ for(i=1; i<2000; i+=100){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+// GFF4Element syn[n];
+ GFF4Element erased[i];
+ GFF4Element data[k];
+ GFF4Element code[n];
+ noe_RsEncoder *encoder;
+ int pass=5;
- encoder= noe_getRsEncoder(i);
+ encoder= noe_getRsEncoder(i);
- for(pass=5; pass; pass--){
- int erasedCount, errorCount;
- for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
+ for(pass=5; pass; pass--){
+ int erasedCount, errorCount;
+ for(j=0; j<k; j++)
+ data[j]= rand() & 0xFFFF;
- memcpy(code, data, n*sizeof(GFF4Element));
+ memcpy(code, data, n*sizeof(GFF4Element));
- noe_rsEncode(encoder, code);
-
- erasedCount=0;
- if(rand()&0x40){
- erasedCount= (rand()%i)+1;
- for(j=0; j<erasedCount; j++){
- int e=-1;
-
- while(e==-1 || code[e]==0x10000) e=rand()%n;
+ noe_rsEncode(encoder, code);
+
+ erasedCount=0;
+ if(rand()&0x40){
+ erasedCount= (rand()%i)+1;
+ for(j=0; j<erasedCount; j++){
+ int e=-1;
+
+ while(e==-1 || code[e]==0x10000) e=rand()%n;
- erased[j]= e;
- code[ e ]= 0x10000;
- }
- for(j=0; j<erasedCount; j++){
- int e= erased[j];
+ erased[j]= e;
+ code[ e ]= 0x10000;
+ }
+ for(j=0; j<erasedCount; j++){
+ int e= erased[j];
- code[ e ]= rand()%0xFFFF;
- }
- }
- errorCount=0;
- if(erasedCount==0 || (rand()&0x40)){
- int max= (i - erasedCount)/2;
- if(max){
- errorCount= (rand() % max)+1;
- for(j=0; j<errorCount; j++){
- int pos= rand()%n;
- code[pos] = rand()%0xFFFF;
-// printf("P%6d\n", pos);
- }
- }
- }
+ code[ e ]= rand()%0xFFFF;
+ }
+ }
+ errorCount=0;
+ if(erasedCount==0 || (rand()&0x40)){
+ int max= (i - erasedCount)/2;
+ if(max){
+ errorCount= (rand() % max)+1;
+ for(j=0; j<errorCount; j++){
+ int pos= rand()%n;
+ code[pos] = rand()%0xFFFF;
+// printf("P%6d\n", pos);
+ }
+ }
+ }
//printf("erased:%d errors:%d parity:%d\n", erasedCount, errorCount, i);
- noe_rsDecode(code, erased, erasedCount, i);
+ noe_rsDecode(code, erased, erasedCount, i);
- // noe_printPoly(gen, i);
- // noe_printPoly(syn, i-1);
+ // noe_printPoly(gen, i);
+ // noe_printPoly(syn, i-1);
- for(j=0; j<k; j++){
- if(data[j]!=code[j]){
- printf("FAIL at:%d is %X %X\n", j, data[j], code[j]);
- break;
- }
- }
- printf("."); fflush(stdout);
- }
- noe_freeRsEncoder(encoder);
- }
- {
- uint8_t buffer[20000];
- uint32_t val[2000];
- ByteStream bs;
+ for(j=0; j<k; j++){
+ if(data[j]!=code[j]){
+ printf("FAIL at:%d is %X %X\n", j, data[j], code[j]);
+ break;
+ }
+ }
+ printf("."); fflush(stdout);
+ }
+ noe_freeRsEncoder(encoder);
+ }
+#if 0
+ {
+ uint8_t buffer[20000];
+ uint32_t val[2000];
+ ByteStream bs;
- printf("\nTesting v coder");
-
- initByteStream(&bs, buffer, 20000);
- for(i=0; i<2000; i++){
- int len= rand()%32;
- val[i] = rand() % (1<<len);
- put_v(&bs, val[i]);
- if(i%100 == 0) printf(".");
- }
+ printf("\nTesting v coder");
+
+ initByteStream(&bs, buffer, 20000);
+ for(i=0; i<2000; i++){
+ int len= rand()%32;
+ val[i] = rand() % (1<<len);
+ put_v(&bs, val[i]);
+ if(i%100 == 0) printf(".");
+ }
- initByteStream(&bs, buffer, 20000);
- for(i=0; i<2000; i++){
- if(val[i] != get_v(&bs)){
- printf("FAIL\n");
- break;
- }
- if(i%100 == 0) printf(".");
- }
- }
-
- printf("\n");
+ initByteStream(&bs, buffer, 20000);
+ for(i=0; i<2000; i++){
+ if(val[i] != get_v(&bs)){
+ printf("FAIL\n");
+ break;
+ }
+ if(i%100 == 0) printf(".");
+ }
+ }
+#endif
+ printf("\n");
return 0;
-
- printf("Testing erasure decoding\n");
- for(i=1; i<20; i++){
- int n= SIZE - 1;
- int k= SIZE - 1 - i;
- GFF4Element syn[n];
- GFF4Element gen[i+1];
- GFF4Element data[k];
- GFF4Element code[n];
- GFF4Element locator[i+1];
- GFF4Element omega[2*i];
+
+ printf("Testing erasure decoding\n");
+ for(i=1; i<20; i++){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+ GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
+ GFF4Element locator[i+1];
+ GFF4Element omega[2*i];
- int locatorOrder=0;
-
- for(j=0; j<k; j++)
- data[j]= rand() & 0xFFFF;
-
- noe_getRsGenerator(gen, 1, i);
- j=noe_prodPoly(code, gen, data, i, k);
- assert(j==n);
-
- locator[0] = 1;
- for(j=0; j<i; j++){
- int index;
- GFF4Element locationFactor[2];
-
- if((rand()&7)==0 && j) continue;
-
- index= rand()%0xFFFF;
- locationFactor[0] = 1;
- locationFactor[1] = inv(noe_exp[index]);
- locatorOrder= noe_prodPoly(locator, locator, locationFactor, j, 1);
-
- code[index] += rand()&0xFFFF;
- }
-
- noe_getSyndrom(syn, code, 1, i);
- noe_prodPoly(omega, syn, locator, i-1, locatorOrder);
-// noe_getDeriative(locator, locator, locatorOrder);
-
+ int locatorOrder=0;
+
+ for(j=0; j<k; j++)
+ data[j]= rand() & 0xFFFF;
+
+ noe_getRsGenerator(gen, 1, i);
+ j=noe_prodPoly(code, gen, data, i, k);
+ assert(j==n);
+
+ locator[0] = 1;
+ for(j=0; j<i; j++){
+ int index;
+ GFF4Element locationFactor[2];
+
+ if((rand()&7)==0 && j) continue;
+
+ index= rand()%0xFFFF;
+ locationFactor[0] = 1;
+ locationFactor[1] = inv(noe_exp[index]);
+ locatorOrder= noe_prodPoly(locator, locator, locationFactor, j, 1);
+
+ code[index] = 0;
+ }
+
+ noe_getSyndrom(syn, code, i);
+ noe_prodPoly(omega, syn, locator, i-1, locatorOrder);
+// noe_getDeriative(locator, locator, locatorOrder);
+
-// noe_printPoly(gen, i);
-// noe_printPoly(syn, i-1);
-
- for(j=0; j<i; j++){
- if(syn[j]) printf("FAIL generator:%d coefficient:%d\n", i, j);
- }
- }
- return 0;
+// noe_printPoly(gen, i);
+// noe_printPoly(syn, i-1);
+
+ for(j=0; j<i; j++){
+ if(syn[j]) printf("FAIL generator:%d coefficient:%d\n", i, j);
+ }
+ }
+ return 0;
}
1
0
[mndiff]: r78 - in trunk/noe: bytestream.h filerw.c filerw.h galois.c gfft.c noe.c noe_internal.h rs.c rw.c rw.h test.c
by michael 09 Jul '07
by michael 09 Jul '07
09 Jul '07
Author: michael
Date: Tue Jul 10 00:20:07 2007
New Revision: 78
Log:
version from 2003-09-24 00:02
Added:
trunk/noe/bytestream.h
trunk/noe/noe.c
Modified:
trunk/noe/filerw.c
trunk/noe/filerw.h
trunk/noe/galois.c
trunk/noe/gfft.c
trunk/noe/noe_internal.h
trunk/noe/rs.c
trunk/noe/rw.c
trunk/noe/rw.h
trunk/noe/test.c
Added: trunk/noe/bytestream.h
==============================================================================
--- (empty file)
+++ trunk/noe/bytestream.h Tue Jul 10 00:20:07 2007
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+typedef struct ByteStream{
+ uint8_t *buf;
+ uint8_t *buf_ptr;
+// int length;
+ uint8_t *buf_end;
+}ByteStream;
+
+static inline void initByteStream(ByteStream *bc, uint8_t *buf, int length){
+ bc->buf=
+ bc->buf_ptr= buf;
+// bc->length= length;
+ bc->buf_end= bc->buf + length;
+}
+
+static inline int spaceLeft(ByteStream *bc){
+// return bc->length - ((int)(bc->buf_ptr - bc->buf));
+ return ((int)(bc->buf_end - bc->buf_ptr));
+}
+
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline uint64_t get_v(ByteStream *bc){
+ uint64_t val= 0;
+
+ for(; spaceLeft(bc) > 0; ){
+ int tmp= *(bc->buf_ptr++);
+ if(tmp&0x80)
+ val= (val<<7) + tmp - 0x80;
+ else
+ return (val<<7) + tmp;
+ }
+
+ return -1;
+}
+
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline int put_v(ByteStream *bc, uint64_t val){
+ int i;
+
+ if(spaceLeft(bc) < 9) return -1; //FIXME
+
+ val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
+ for(i=7; ; i+=7){
+ if(val>>i == 0) break;
+ }
+
+ for(i-=7; i>0; i-=7){
+ *(bc->buf_ptr++)= 0x80 | (val>>i);
+ }
+ *(bc->buf_ptr++)= val&0x7F;
+
+ return 0;
+}
+
+/**
+ *
+ */
+static inline uint64_t get_c(ByteStream *bc, int length){
+ uint64_t val= 0;
+
+ for(i=length-1; i>=0; i--){
+ val |= (*(bc->buf_ptr++)) << (8*i) ;
+ }
+ return val;
+}
+
+/**
+ *
+ */
+static inline void put_c(ByteStream *bc, uint64_t val, int length){
+ int i;
+
+ for(i=length-1; i>=0; i--){
+ *(bc->buf_ptr++)= val >> (i*8);
+ }
+}
+
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline int get_buffer(ByteStream *bc, uint8_t *dst, int length){
+ int i;
+
+ if(length > spaceLeft(bc) || length<0) return -1;
+
+ for(i=0; i<length; i++){
+ dst[i]= *(bc->buf_ptr++);
+ }
+
+ return 0;
+}
+
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline int put_buffer(ByteStream *bc, uint8_t *src, int length){
+ int i;
+
+ if(length > spaceLeft(bc)) return -1;
+
+ for(i=0; i<length; i++){
+ *(bc->buf_ptr++)= src[i];
+ }
+
+ return 0;
+}
+
+#if 1 // just do a *_v() *_buffer()
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline int get_b(ByteStream *bc, uint8_t *dst, int max_length){
+ const int length= get_v(bc);
+ if(length > max_length) return -1;
+
+ return get_buffer(bc, dst, length);
+}
+
+/**
+ *
+ * @return <0 if an error occured
+ */
+static inline int put_b(ByteStream *bc, uint8_t *src, int length){
+ put_v(bc, length);
+ return put_buffer(bc, src, length);
+}
+#endif
\ No newline at end of file
Modified: trunk/noe/filerw.c
==============================================================================
--- trunk/noe/filerw.c (original)
+++ trunk/noe/filerw.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "rw.h"
#include "filerw.h"
@@ -34,18 +35,21 @@ static uint64_t fsize(FILE *f){
return size;
}
-static int fileRead(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
+static int fileIO(noe_RwContext *c, uint8_t *data, uint64_t pos, int len, int write){
int i;
- noe_FileRwContext *p= (noe_FileRwContext *)c->priv;
+ noe_FileRwContext *p= (noe_FileRwContext *)c;
for(i=0; i<p->fileCount; i++){
- if(p->offset[i] > pos){
+ if(p->end[i] > pos){
int e;
- uint64_t currentLen= pos - p->offset[i];
+ uint64_t currentLen= pos - p->end[i];
if(currentLen > len) currentLen= len;
if(currentLen <= 0) return -1;
- e= fread(data, currentLen, 1, p->file[i]);
+ if(write)
+ e= fwrite(data, currentLen, 1, p->file[i]);
+ else
+ e= fread(data, currentLen, 1, p->file[i]);
if(e!=1) return -1;
len -= currentLen;
@@ -57,51 +61,48 @@ static int fileRead(noe_RwContext *c, ui
return -1;
}
-static int fileWrite(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
- return -1;
-}
-
static void fileUninit(noe_RwContext *c){
int i;
- noe_FileRwContext *p;
+ noe_FileRwContext *p= (noe_FileRwContext *)c;
if(c==NULL) return;
- p = (noe_FileRwContext *)c->priv;
-
for(i=0; i<p->fileCount; i++){
fclose(p->file[i]);
}
free(p->file);
- free(p->offset);
+ free(p->end);
+ memset(p, 0, sizeof(noe_FileRwContext));
free(p);
- free(c);
}
noe_RwContext *noe_getFileRwContext(char **fileNames, int fileCount, char *access){
int i;
uint64_t pos;
- noe_RwContext *c= malloc(sizeof(noe_RwContext));
noe_FileRwContext *p= malloc(sizeof(noe_FileRwContext));
+ noe_RwContext *c= (noe_RwContext *)p;
- c->priv= p;
c->parent= NULL;
p->file= malloc(sizeof(FILE)*fileCount);
- p->offset= malloc(sizeof(uint64_t)*fileCount);
+ p->end= malloc(sizeof(uint64_t)*fileCount);
- c->read= fileRead;
- c->write= fileWrite;
+ c->io= fileIO;
c->uninit= fileUninit;
pos=0;
for(i=0; i<fileCount; i++){
p->file[i]= fopen(fileNames[i], access);
- if(p->file[i]==NULL) return NULL;
+ if(p->file[i]==NULL) goto fail;
pos+= fsize(p->file[i]);
- p->offset[i]= pos;
+ p->end[i]= pos;
}
+ p->size= pos;
return c;
+
+ fail:
+ fileUninit(c);
+ return NULL;
}
Modified: trunk/noe/filerw.h
==============================================================================
--- trunk/noe/filerw.h (original)
+++ trunk/noe/filerw.h Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,9 +17,14 @@
*/
typedef struct noe_FileRwContext{
+ noe_RwContext rw;
FILE **file;
- uint64_t *offset;
+
+ /**
+ * end of the ith file.
+ */
+ uint64_t *end;
int fileCount;
}noe_FileRwContext;
-//FIXME move to .c if this is the only thing here
\ No newline at end of file
+//FIXME move to .c if this is the only thing here
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
#include <inttypes.h>
#include <assert.h>
#include <stdio.h>
+#include <string.h>
#include "noe_internal.h"
#include "galois.h"
Modified: trunk/noe/gfft.c
==============================================================================
--- trunk/noe/gfft.c (original)
+++ trunk/noe/gfft.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
#include <inttypes.h>
#include <assert.h>
#include <stdio.h>
+#include <string.h>
#include "noe_internal.h"
#include "galois.h"
Added: trunk/noe/noe.c
==============================================================================
--- (empty file)
+++ trunk/noe/noe.c Tue Jul 10 00:20:07 2007
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <inttypes.h>
+
+static const uint8_t startcode[8]={0xAB, 0x2C, 0xE2, 0x47, 0x15, 'N', 'O', 'E'};
+//#define STARTCODE (0xAB2CE24715000000ULL + ('N'<<16) + ('O'<<8) + 'E')
+#define STARTCODE_THRESHOLD 6
+#define HEADER_PARITY_LENGTH 26
+#define HEADER_LENGTH (38 + HEADER_PARITY_LENGTH)
+#define BUFFER_LENGTH 262144
+
+typedef struct NoeContext{
+ int debug;
+ int fileId;
+ int fileChecksum;
+ int fileIdThreshold;
+ int seqNum;
+ int headerCount;
+ int parityCount;
+ int fingerprintCount;
+ int flags;
+ int dataSize;
+ int header[HEADER_LENGTH][256];
+}NoeContext;
+
+const static uint8_t parity[256]={
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
+0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
+};
+
+/**
+ *
+ * @return length if not found
+ */
+static uint64_t find_header(NoeContext *n, uint8_t *buffer, uint64_t length){
+ int i;
+
+ for(i=0; i + HEADER_LENGTH < length; i++){
+ int j;
+ int score=8;
+
+ for(j=0; j<8; j++){
+ if(buffer[i + j] != startcode[j]){
+ score--;
+ if(score < STARTCODE_THRESHOLD) break;
+ }
+ }
+ if(score < STARTCODE_THRESHOLD) continue;
+
+ score=8;
+ for(j=0; j<4; j++){ //FIXME cleaner?
+ if(buffer[i + 12 + j] != ((n->fileChecksum >> (24 - 8*j)) & 0xFF))
+ score--;
+ }
+ for(j=0; j<4; j++){
+ if(buffer[i + 16+ j] != ((n->fileId >> (24 - 8*j)) & 0xFF))
+ score--;
+ }
+ if(score < n->fileIdThreshold) continue;
+
+ return i;
+ }
+
+ return length;
+}
+
+static int decode_header(NoeContext *n, uint8_t *buffer){
+ ByteStream bc;
+ int erasedCount=0; //FIXME
+ const int n= SIZE - 1;
+ const int k= SIZE - 1 - HEADER_PARITY_LENGTH;
+ GFF4Element erased[HEADER_PARITY_LENGTH];
+ GFF4Element code[n];
+ int i,j;
+
+ for(j=0; j<8; j++){
+ buffer[j] = startcode[j];
+ }
+
+ for(i=12; i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
+ int best=0;
+ int bestScore=0;
+
+ for(j=0; j<256; j++){
+ const int score= n->header[i][j];
+ if(score > bestScore){
+ bestScore= score;
+ best= j;
+ }
+ }
+ buffer[i]= best; //FIXME dont modify it / load into code directly
+ }
+
+ initByteStream(&bc, buffer, HEADER_LENGTH);
+
+ memset(code, 0, sizeof(GFF4Element)*n);
+ for(i=0; 2*i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
+ code[i ]= get_c(bc, 2);
+ }
+ for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
+ code[k+i]= get_c(bc, 2);
+ }
+
+ if(noe_rsDecode(code, erased, erasedCount, HEADER_PARITY_LENGTH) < 0)
+ return -1;
+
+ for(i=HEADER_LENGTH - HEADER_PARITY_LENGTH; i<k; i++){
+ if(code[i] != 0)
+ return -2;
+ }
+ for(i=0; i<8; i++){
+ if(buffer[i] != startcode[i])
+ return -2;
+ }
+
+ // noe_printPoly(gen, i);
+ // noe_printPoly(syn, i-1);
+
+ for(i=0; 2*i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
+ buffer[2*i+0]= code[ i] >> 8;
+ buffer[2*i+1]= code[ i];
+ }
+ for(i=0; 2*i<HEADER_PARITY_LENGTH; i++){
+ const int j= i + (HEADER_LENGTH - HEADER_PARITY_LENGTH)/2;
+ buffer[2*j+0]= code[k+i] >> 8;
+ buffer[2*j+1]= code[k+i];
+ }
+
+ initByteStream(&bc, buffer, HEADER_LENGTH);
+
+ get_c(bc, 8);
+ n->seqNum= get_c(bc, 4);
+ n->fileChecksum= get_c(bc, 4);
+ n->fileId= get_c(bc, 4);
+ n->version= get_c(bc, 1);
+ if(n->version > 0)
+ return -3;
+
+ n->flags= get_c(bc, 1);
+ n->headerCount= get_c(bc, 4);
+ if(n->seqNum >= n->headerCount)
+ return -2;
+
+ n->parityCount= get_c(bc, 2);
+ n->fingerprintCount= get_c(bc, 2);
+ n->dataSize= get_c(bc, 8);
+
+ for(i=12; i<HEADER_LENGTH - HEADER_PARITY_LENGTH; i++){
+ n->header[i][ buffer[i] ]= INT_MAX/2;
+ }
+
+ return n->seqNum;
+}
+
+
+/**
+ *
+ * @return -1 if not found
+ */
+static int find_and_decode_global_header(NoeContext *n, noe_RwContext *rw){
+ int length= BUFFER_LENGTH
+ uint64_t i;
+ uint8_t buffer[length];
+
+ for(i=rw->size; i>=0; i-= length - HEADER_LENGTH){
+ int pos;
+
+ if(i < length) length= i;
+ rw->io(rw, buffer, i - length, length, 0);
+
+ for(pos=0; ; pos++){
+ int j;
+ pos += find_header(n, buffer + pos, length - pos);
+ if(pos >= length) break;
+
+ for(j=0; j<HEADER_LENGTH; j++){ //FIXME bitwise histogram?
+ const int c= buffer[pos + j]
+ n->header[j][c]++;
+ }
+
+ if( decode_header(n, buffer + pos) >= 0)
+ return 0;
+ }
+ length= BUFFER_LENGTH;
+ }
+
+ return -1;
+}
+
+static inline int getChecksum(unsigned int fingerprint, unsigned int pos){
+ return (fingerprint ^ pos) % 251;
+}
+
+static int decode_fingerprints(NoeContext *n, uint8_t *buffer, int length){
+ int i, count;
+ ByteStream bc;
+
+ count= MIN(n->fingerprintCount, length/5);
+
+ initByteStream(&bc, buffer, 5*count);
+ for(i=0; i<count; i++){
+ const unsigned int c= get_c(bc, 4);
+ const int checksum= get_c(bc, 1);
+ const int index= n->seqNum + i*n->headerCount;
+ const int expectedChecksum= getChecksum(c, index);
+
+ if(expectedChecksum == checksum){
+ n->fingerprintOk[index]= 1;
+ n->fingerprint[index]= c;
+ }//FIXME resync
+ }
+}
+
+/**
+ *
+ * @return -1 if not found
+ */
+static int find_and_decode_packets(NoeContext *n, noe_RwContext *rw){
+ int length= BUFFER_LENGTH
+ const int packetLength= HEADER_LENGTH + 5*n->fingerprintCount;
+ uint64_t i;
+ uint8_t buffer[length];
+
+ n->fingerprint = malloc(n->fingerprintCount*n->headerCount * sizeof(int));
+ n->fingerprintOk= malloc(n->fingerprintCount*n->headerCount);
+ memset(n->fingerprintOk, 0, n->fingerprintCount*n->headerCount);
+
+ for(i=rw->size; i>=0; i-= length - packetLength){
+ int pos;
+
+ if(i < length) length= i;
+ rw->io(rw, buffer, i - length, length, 0);
+
+ for(pos=0; ; pos++){
+ int j;
+ pos += find_header(n, buffer + pos, length - pos);
+ if(pos >= length) break;
+
+ if( decode_header(n, buffer + pos) < 0 )
+ continue;
+ pos += HEADER_LENGTH;
+
+ decode_fingerprints(n, buffer + pos, length - pos);
+ }
+ length= BUFFER_LENGTH;
+
+ //FIXME detect if enough packets
+ }
+
+ return -1;
+}
Modified: trunk/noe/noe_internal.h
==============================================================================
--- trunk/noe/noe_internal.h (original)
+++ trunk/noe/noe_internal.h Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,4 +47,6 @@ if(tcount<2 || tend - tstart < 4*tsum/tc
if(256*256*256*64%tcount==0){\
fprintf(stderr, "%Ld dezicycles, %d runs, %d skips\n", tsum*10/tcount, tcount, tskip_count);\
fflush(stderr);\
-}
\ No newline at end of file
+}
+
+
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <assert.h>
#include <malloc.h>
#include <stdio.h>
+#include <string.h>
#include "noe_internal.h"
#include "galois.h"
Modified: trunk/noe/rw.c
==============================================================================
--- trunk/noe/rw.c (original)
+++ trunk/noe/rw.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,24 +17,21 @@
*/
#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
#include "rw.h"
-typedef struct noe_Map{
- uint64_t src;
- uint64_t dst;
- uint64_t len;
-}noe_Map;
-
typedef struct noe_RemapRwContext{
- Map *map;
+ noe_RwContext rw;
+ noe_Map *map;
int count;
}noe_RemapRwContext;
-static int noe_remapRead(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
+static int remapIO(noe_RwContext *c, uint8_t *data, uint64_t pos, int len, int write){
int i;
- noe_RemapRwContext *p= (noe_RemapRwContext *)c->priv;
+ noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
noe_RwContext *parent= c->parent;
//FIXME do binary search or cache last
@@ -45,7 +42,7 @@ static int noe_remapRead(noe_RwContext *
uint64_t currentLen= p->map[i].src + p->map[i].len - pos;
if(currentLen > len) currentLen= len;
- parent->read(parent, data, pos + diff, currentLen);
+ parent->io(parent, data, pos + diff, currentLen, write);
data+= currentLen;
pos+= currentLen;
@@ -58,35 +55,28 @@ static int noe_remapRead(noe_RwContext *
}
static void remapUninit(noe_RwContext *c){
- int i;
- noe_RemapRwContext *p;
+ noe_RemapRwContext * const p= (noe_RemapRwContext *)c;
if(c==NULL) return;
- p = (noe_RemapRwContext *)c->priv;
-
free(p->map);
+ memset(p, 0, sizeof(noe_RemapRwContext));
free(p);
- free(c);
}
-noe_RwContext *noe_getRemapRwContext(noe_RwContext *parent, uint64_t *map, int count){
- int i;
- uint64_t pos;
- noe_RwContext *c= malloc(sizeof(noe_RwContext));
+noe_RwContext *noe_getRemapRwContext(noe_RwContext *parent, noe_Map *map, int count){
noe_RemapRwContext *p= malloc(sizeof(noe_RemapRwContext));
+ noe_RwContext *c= (noe_RwContext*)p;
- c->priv= p;
c->parent= parent;
p->map= malloc(sizeof(noe_Map)*count);
memcpy(p->map, map, sizeof(noe_Map)*count);
p->count= count;
- //FIXME sort map ?
+ //FIXME sort map
- c->read= remapRead;
- c->write= remapWrite;
+ c->io= remapIO;
c->uninit= remapUninit;
return c;
Modified: trunk/noe/rw.h
==============================================================================
--- trunk/noe/rw.h (original)
+++ trunk/noe/rw.h Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,9 +17,21 @@
*/
typedef struct noe_RwContext{
- int (*read )(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len);
- int (*write)(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len);
+ uint64_t size;
+
+ /**
+ * reads or writes some data.
+ * @returns <0 if an error occured
+ */
+ int (*io )(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len, int write);
+
void (*uninit)(struct noe_RwContext *context);
struct noe_RwContext *parent;
- void *priv;
-}noe_RwContext;
\ No newline at end of file
+}noe_RwContext;
+
+typedef struct noe_Map{
+ uint64_t src;
+ uint64_t dst;
+ uint64_t len;
+}noe_Map;
+
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:20:07 2007
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ * Copyright (C) 2003 Michael Niedermayer <michaelni(a)gmx.at>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,11 +21,13 @@
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
+#include <string.h>
#include "noe_internal.h"
#include "galois.h"
#include "gfft.h"
#include "rs.h"
+#include "bytestream.h"
static const unsigned int gfftChecksums[20]={
0xFCB3E495,
@@ -187,7 +189,7 @@ int main(){
for(i=1; i<2000; i+=100){
int n= SIZE - 1;
int k= SIZE - 1 - i;
- GFF4Element syn[n];
+// GFF4Element syn[n];
GFF4Element erased[i];
GFF4Element data[k];
GFF4Element code[n];
@@ -250,7 +252,32 @@ int main(){
}
noe_freeRsEncoder(encoder);
}
+ {
+ uint8_t buffer[20000];
+ uint32_t val[2000];
+ ByteStream bs;
+ printf("\nTesting v coder");
+
+ initByteStream(&bs, buffer, 20000);
+ for(i=0; i<2000; i++){
+ int len= rand()%32;
+ val[i] = rand() % (1<<len);
+ put_v(&bs, val[i]);
+ if(i%100 == 0) printf(".");
+ }
+
+ initByteStream(&bs, buffer, 20000);
+ for(i=0; i<2000; i++){
+ if(val[i] != get_v(&bs)){
+ printf("FAIL\n");
+ break;
+ }
+ if(i%100 == 0) printf(".");
+ }
+ }
+
+ printf("\n");
return 0;
printf("Testing erasure decoding\n");
1
0
[mndiff]: r77 - in trunk/noe: Makefile filerw.c filerw.h galois.c galois.h gfft.c gfft.h noe_internal.h rs.c rs.h rw.c rw.h test.c
by michael 09 Jul '07
by michael 09 Jul '07
09 Jul '07
Author: michael
Date: Tue Jul 10 00:15:17 2007
New Revision: 77
Log:
version from 2002-11-26 13:12
Added:
trunk/noe/filerw.c
trunk/noe/filerw.h
trunk/noe/gfft.c
trunk/noe/gfft.h
trunk/noe/rw.c
trunk/noe/rw.h
Modified:
trunk/noe/Makefile
trunk/noe/galois.c
trunk/noe/galois.h
trunk/noe/noe_internal.h
trunk/noe/rs.c
trunk/noe/rs.h
trunk/noe/test.c
Modified: trunk/noe/Makefile
==============================================================================
--- trunk/noe/Makefile (original)
+++ trunk/noe/Makefile Tue Jul 10 00:15:17 2007
@@ -1,4 +1,4 @@
-OBJS = test.o galois.o rs.o
+OBJS = test.o galois.o rs.o gfft.o rw.o filerw.o
SRCS = $(OBJS:.o=.c) $(ASM_OBJS:.o=.s)
CFLAGS = -g -Wall -O4 $(OPTFLAGS) -I. $(EXTRA_INC)
Added: trunk/noe/filerw.c
==============================================================================
--- (empty file)
+++ trunk/noe/filerw.c Tue Jul 10 00:15:17 2007
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "rw.h"
+#include "filerw.h"
+
+static uint64_t fsize(FILE *f){
+ uint64_t cur= ftell(f);
+ uint64_t size;
+
+ fseek(f, 0, SEEK_END); //FIXME 64bit stuff?
+ size= ftell(f);
+ fseek(f, cur, SEEK_SET);
+
+ return size;
+}
+
+static int fileRead(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
+ int i;
+ noe_FileRwContext *p= (noe_FileRwContext *)c->priv;
+
+ for(i=0; i<p->fileCount; i++){
+ if(p->offset[i] > pos){
+ int e;
+ uint64_t currentLen= pos - p->offset[i];
+ if(currentLen > len) currentLen= len;
+ if(currentLen <= 0) return -1;
+
+ e= fread(data, currentLen, 1, p->file[i]);
+ if(e!=1) return -1;
+
+ len -= currentLen;
+ data+= currentLen;
+ pos += currentLen;
+ if(len==0) return 0;
+ }
+ }
+ return -1;
+}
+
+static int fileWrite(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
+ return -1;
+}
+
+static void fileUninit(noe_RwContext *c){
+ int i;
+ noe_FileRwContext *p;
+
+ if(c==NULL) return;
+
+ p = (noe_FileRwContext *)c->priv;
+
+ for(i=0; i<p->fileCount; i++){
+ fclose(p->file[i]);
+ }
+ free(p->file);
+ free(p->offset);
+ free(p);
+ free(c);
+}
+
+noe_RwContext *noe_getFileRwContext(char **fileNames, int fileCount, char *access){
+ int i;
+ uint64_t pos;
+ noe_RwContext *c= malloc(sizeof(noe_RwContext));
+ noe_FileRwContext *p= malloc(sizeof(noe_FileRwContext));
+
+ c->priv= p;
+ c->parent= NULL;
+
+ p->file= malloc(sizeof(FILE)*fileCount);
+ p->offset= malloc(sizeof(uint64_t)*fileCount);
+
+ c->read= fileRead;
+ c->write= fileWrite;
+ c->uninit= fileUninit;
+
+ pos=0;
+ for(i=0; i<fileCount; i++){
+ p->file[i]= fopen(fileNames[i], access);
+ if(p->file[i]==NULL) return NULL;
+
+ pos+= fsize(p->file[i]);
+ p->offset[i]= pos;
+ }
+
+ return c;
+}
Added: trunk/noe/filerw.h
==============================================================================
--- (empty file)
+++ trunk/noe/filerw.h Tue Jul 10 00:15:17 2007
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+typedef struct noe_FileRwContext{
+ FILE **file;
+ uint64_t *offset;
+ int fileCount;
+}noe_FileRwContext;
+
+//FIXME move to .c if this is the only thing here
\ No newline at end of file
Modified: trunk/noe/galois.c
==============================================================================
--- trunk/noe/galois.c (original)
+++ trunk/noe/galois.c Tue Jul 10 00:15:17 2007
@@ -16,58 +16,75 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+//FIXME try to use 16bit table with check in noe_log/exp()
+
#include <inttypes.h>
#include <assert.h>
#include <stdio.h>
#include "noe_internal.h"
#include "galois.h"
+#include "gfft.h"
-GF2h16Element noe_exp[65536];
-GF2h16Element noe_log[65536];
-uint32_t noe_mod[256];
+GFF4Element noe_exp[SIZE];
+GFF4Element noe_log[SIZE];
void noe_init(){
- GF2h16Element ge= 1;
+ GFF4Element ge= 1;
int i;
- for(i=0; i<256; i++){
- noe_mod[i]= gf2poly_mod(i<<16, PRIMITIVE_POLYNOM);
- noe_mod[i]^= i<<16;
- }
-
for(i=0; i<SIZE; i++){
noe_exp[i]= ge;
noe_log[ge]= i;
- ge= gf2poly_mod(ge+ge, PRIMITIVE_POLYNOM);
+ ge= prod(ge, PRIMITIVE_ELEMENT);
}
noe_log[0]= 0xFFFF;
noe_log[1]= 0;
+
+ noe_gfft_init();
}
+/**
+ * ...
+ */
+int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+ int order= order1 + order2;
+ int i;
-//int zech_log(GaloisField gf, GF2Polynom b){
-//}
+ if(order1*order2 < (order1+order2)*64){
+ for(i=order; i>=0; i--){
+ unsigned int acc=0;
+ int j, end;
-void noe_gfft(GF2h16Element *src, GF2h16Element *dst){
+ j = NOE_MAX(0, i - order2);
+ end= NOE_MIN(i, order1);
-}
+ for(; j<=end; j++){
+ acc+= prod(src1[j], src2[i-j]);
+ }
+ dst[i]= reduce(acc);
+ }
+ }else{
+ const int logSize= noe_log2(order2 + order1)+1;
+ const int size= 1<<logSize;
+ GFF4Element temp[2][size]; //FIXME is this fast?
+ const GFF4Element scale= inv(size);
-int noe_prodPoly(GF2h16Element *dst, GF2h16Element *src1, GF2h16Element *src2, int order1, int order2){
- int order= order1 + order2;
- int i;
-
- for(i=order; i>=0; i--){
- int acc=0;
- int j, end;
-
- j = NOE_MAX(0, i - order2);
- end= NOE_MIN(i, order1);
+ //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
+ memcpy(temp[0], src1, sizeof(GFF4Element)*(order1+1));
+ memset(temp[0] + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
+ memcpy(temp[1], src2, sizeof(GFF4Element)*(order2+1));
+ memset(temp[1] + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
- for(; j<=end; j++){
- acc^= prod(src1[j], src2[i-j]);
+ noe_gfft(temp[0], temp[0], logSize);
+ noe_gfft(temp[1], temp[1], logSize);
+
+ for(i=0; i<size; i++){
+ temp[0][i]= prod(prod(temp[0][i], temp[1][i]), scale);
}
- dst[i]= acc;
+
+ noe_igfft(temp[0], temp[0], logSize);
+ memcpy(dst, temp[0], sizeof(GFF4Element)*(order+1));
}
return order;
@@ -75,28 +92,51 @@ int noe_prodPoly(GF2h16Element *dst, GF2
/**
* returns the first order2 coefficients of the product of the 2 polynoms.
+ * Note dst must be at least 2^log2(order1+order2) big FIXME benchmark if its worth it
*/
-int noe_partialProdPoly(GF2h16Element *dst, GF2h16Element *src1, GF2h16Element *src2, int order1, int order2){
+int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
const int order= order2;
int i;
- for(i=order; i>=0; i--){
- int acc=0;
- int j, end;
-
- j = NOE_MAX(0, i - order2);
- end= NOE_MIN(i, order1);
+ if(order1*order2 < (order1+order2)*64){
+ for(i=order; i>=0; i--){
+ unsigned int acc=0;
+ int j, end;
- for(; j<=end; j++){
- acc^= prod(src1[j], src2[i-j]);
+ j = NOE_MAX(0, i - order2);
+ end= NOE_MIN(i, order1);
+
+ for(; j<=end; j++){
+ acc+= prod(src1[j], src2[i-j]);
+ }
+ dst[i]= reduce(acc);
}
- dst[i]= acc;
+ }else{
+ const int logSize= noe_log2(order2 + order1)+1;
+ const int size= 1<<logSize;
+ GFF4Element temp[size]; //FIXME is this fast?
+ const GFF4Element scale= inv(size);
+
+ //FIXME avoid mem* (but note the memcpy/set only takes 2% of the prodPoly time)
+ memcpy(temp, src2, sizeof(GFF4Element)*(order2+1));
+ memset(temp + order2 + 1, 0, sizeof(GFF4Element)*(size - order2 - 1));
+ memcpy(dst, src1, sizeof(GFF4Element)*(order1+1));
+ memset(dst + order1 + 1, 0, sizeof(GFF4Element)*(size - order1 - 1));
+
+ noe_gfft(dst, dst, logSize);
+ noe_gfft(temp, temp, logSize);
+
+ for(i=0; i<size; i++){
+ dst[i]= prod(prod(dst[i], temp[i]), scale);
+ }
+
+ noe_igfft(dst, dst, logSize);
}
return order;
}
-void noe_printPoly(GF2h16Element *src, int order){
+void noe_printPoly(GFF4Element *src, int order){
int i;
for(i=order; i>=0; i--){
@@ -108,59 +148,154 @@ void noe_printPoly(GF2h16Element *src, i
/**
* Evaluates the src polynom at x.
*/
-GF2h16Element noe_evalPoly(GF2h16Element *src, int order, GF2h16Element x){
- int acc=0;
+GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x){
+ unsigned int acc=0;
int j;
for(j=order; j>=0; j--){
- acc = prod(acc, x) ^ src[j];
+ acc = sum(prod(acc, x), src[j]);
}
return acc;
}
-void noe_getDerivative(GF2h16Element *dst, GF2h16Element *src, int order){
+int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order){
int i;
- for(i=0; i<order-1; i+=2){
- dst[i ]= src[i+1];
- dst[i+1]= 0;
+ for(i=0; i<order; i++){
+ dst[i ]= prod(src[i+1], i+1);
}
- if(i<order)
- dst[i ]= src[i+1];
+
+ return order-1;
}
-static inline int rev(int x){
- x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1));
- x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2));
- x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4));
- x = (( x >> 8) | ((x & 0x00ff) << 8));
- return(x);
+/**
+ * ...
+ */
+void noe_synthPoly(GFF4Element *dst, GFF4Element *src, int count){
+ if(count<20){
+ int i;
+
+ dst[0]= 1;
+
+ for(i=0; i<count; i++){
+ noe_prodPoly(dst, dst, src+2*i, i, 1);
+ }
+ }else{
+ int pass, i, countLeft;
+ const int passCount= noe_log2(count-1)+1;
+ GFF4Element temp[2][4<<noe_log2(count-1)];
+
+ assert(passCount>0);
+
+ countLeft= count;
+
+ // noe_printPoly(src, 1);
+ // noe_printPoly(src+2, 1);
+
+ for(i=0; i<(count>>1); i++){
+ noe_prodPoly(temp[0]+4*i, src+4*i, src+4*i+2, 1, 1);
+ }
+ if(count&1){
+ memcpy(temp[0]+4*i, src+4*i, 2*sizeof(GFF4Element));
+ temp[0][4*i+2]= 0;
+ countLeft++;
+ }
+ countLeft>>=1;
+
+ // noe_printPoly(temp[0], 2);
+
+ for(pass=1; countLeft>1; pass++){
+ const int step= 2<<pass;
+ GFF4Element *temp1= temp[ pass&1 ];
+ GFF4Element *temp2= temp[(pass&1)^1];
+
+ for(i=0; i<(countLeft>>1); i++){
+ noe_prodPoly(temp1+2*step*i, temp2+2*step*i, temp2+2*step*i+step, step>>1, step>>1);
+ }
+
+ if(countLeft&1){
+ int len= (step>>1) + 1;
+ memcpy(temp1+2*step*i , temp2+2*step*i, len*sizeof(GFF4Element));
+ memset(temp1+2*step*i + len , 0, step*sizeof(GFF4Element));
+ countLeft++;
+ }
+ countLeft>>=1;
+ }
+
+ assert(pass==passCount);
+
+ // noe_printPoly(temp[0], count);
+
+ memcpy(dst, temp[(pass&1)^1], (count+1)*sizeof(GFF4Element));
+ // noe_printPoly(dst, count);
+ }
}
-void noe_gfft_dit2(GF2h16Element *dst, GF2h16Element *src){
- int i, j, pass;
-
- for(i=0; i<SIZE; i++){
- dst[i]= src[rev(i)];
+int noe_getOrder(GFF4Element *src, int maxOrder){
+ while(maxOrder && src[maxOrder]==0)
+ maxOrder--;
+
+ return maxOrder;
+}
+
+/**
+ * ...
+ * Note: rem can be identical to nom
+ */
+int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder){
+ int i;
+ int remOrder= nomOrder;
+ int quotOrder= 0;
+
+ if(rem != nom)
+ memcpy(rem, nom, (nomOrder+1)*sizeof(GFF4Element));
+
+ denomOrder= noe_getOrder(denom, denomOrder);
+
+ quot[0]=0;
+
+ for(; remOrder >= denomOrder; remOrder--){
+ GFF4Element scale;
+
+ if(rem[remOrder]==0) continue;
+
+ scale= prod(rem[remOrder], inv(denom[denomOrder]));
+
+ for(i=0; i<=denomOrder; i++){ //FIXME optimize
+ const int remIndex= i + remOrder - denomOrder;
+ rem[remIndex]= sum(rem[remIndex], SIZE - prod(scale, denom[i]));
+ }
+
+ quot[remOrder - denomOrder]= scale;
+ if(quotOrder==0)
+ quotOrder= remOrder - denomOrder;
}
+
+ return noe_getOrder(rem, remOrder);
+}
- for(pass=0; pass<EXPONENT; pass++){
- int block;
- const int np= 1<<pass;
- const int blockCount= 1<<(EXPONENT-pass-1);
-
- for(block=0; block<blockCount; block++){
- int n;
- const int top= block*np<<1;
- const int bot= top + np;
-
- for(n=0; n<np; n++){
- int a= dst[top + n];
- int b= dst[bot + n];
-
- dst[top + n]= a^b;
+int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2){
+ int i;
+ int minOrder= NOE_MIN(order1, order2);
+
+ for(i=0; i<=minOrder; i++){
+ dst[i]= sum(src1[i], SIZE - src2[i]);
+ }
+
+ if(order1==order2){
+ return noe_getOrder(dst, order1);
+ }else{
+ if(dst!=src1){
+ for(; i<=order1; i++){
+ dst[i]= src1[i];
}
}
+
+ for(; i<=order2; i++){
+ dst[i]= SIZE - src2[i];
+ }
+
+ return NOE_MAX(order1, order2);;
}
}
Modified: trunk/noe/galois.h
==============================================================================
--- trunk/noe/galois.h (original)
+++ trunk/noe/galois.h Tue Jul 10 00:15:17 2007
@@ -16,113 +16,48 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define PRIMITIVE_ELEMENT 2
-#define PRIMITIVE_POLYNOM 0x0001002D
-#define EXPONENT 16
-#define SIZE (1<<EXPONENT)
-
-typedef uint16_t GF2h16Element;
+#define PRIMITIVE_ELEMENT 3
+#define SIZE 0x10001
-typedef uint32_t GF2Polynom;
+typedef unsigned int GFF4Element;
-extern GF2h16Element noe_exp[65536];
-extern GF2h16Element noe_log[65536];
-extern uint32_t noe_mod[256];
+extern GFF4Element noe_exp[SIZE];
+extern GFF4Element noe_log[SIZE];
-int noe_prodPoly(GF2h16Element *dst, GF2h16Element *src1, GF2h16Element *src2, int order1, int order2);
-int noe_partialProdPoly(GF2h16Element *dst, GF2h16Element *src1, GF2h16Element *src2, int order1, int order2);
+int noe_prodPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
+int noe_partialProdPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
void noe_init();
-void noe_printPoly(GF2h16Element *src, int order);
-void noe_getDerivative(GF2h16Element *dst, GF2h16Element *src, int order);
-GF2h16Element noe_evalPoly(GF2h16Element *src, int order, GF2h16Element x);
-
+void noe_printPoly(GFF4Element *src, int order);
+int noe_getDerivative(GFF4Element *dst, GFF4Element *src, int order);
+GFF4Element noe_evalPoly(GFF4Element *src, int order, GFF4Element x);
+void noe_synthPoly(GFF4Element *dst, GFF4Element *src, int count);
+int noe_divPoly(GFF4Element *quot, GFF4Element *rem, GFF4Element *nom, GFF4Element *denom, int nomOrder, int denomOrder);
+int noe_diffPoly(GFF4Element *dst, GFF4Element *src1, GFF4Element *src2, int order1, int order2);
+int noe_getOrder(GFF4Element *src, int maxOrder);
-static inline GF2Polynom gf2poly_prod(GF2Polynom a, GF2Polynom b){
- int i;
- unsigned int ret=0;
-#if 0
- if(a&1) ret^=b;
- b+=b;
- if(a&2) ret^=b;
- b+=b;
- if(a&4) ret^=b;
- b+=b;
- if(a&8) ret^=b;
- b+=b;
- if(a&16) ret^=b;
- b+=b;
- if(a&32) ret^=b;
- b+=b;
- if(a&64) ret^=b;
- b+=b;
- if(a&128) ret^=b;
- b+=b;
- if(a&256) ret^=b;
- b+=b;
- if(a&512) ret^=b;
- b+=b;
- if(a&1024) ret^=b;
- b+=b;
- if(a&2048) ret^=b;
- b+=b;
- if(a&4096) ret^=b;
- b+=b;
- if(a&8192) ret^=b;
- b+=b;
- if(a&16384) ret^=b;
- b+=b;
- if(a&32768) ret^=b;
- return ret;
-#elif 1
- unsigned int tmp[4];
- tmp[0]= 0;
- tmp[1]= b;
- tmp[2]= b + b;
- tmp[3]= (b + b) ^ b;
+static inline GFF4Element reduce(GFF4Element a){
+ a = (a&0xFFFF) - (a>>16);
+ a += (((int)a)>>31)&0x10001;
- ret ^= tmp[a&3] ; a>>=2;
- ret ^= tmp[a&3]<<2 ; a>>=2;
- ret ^= tmp[a&3]<<4 ; a>>=2;
- ret ^= tmp[a&3]<<6 ; a>>=2;
- ret ^= tmp[a&3]<<8 ; a>>=2;
- ret ^= tmp[a&3]<<10; a>>=2;
- ret ^= tmp[a&3]<<12; a>>=2;
- ret ^= tmp[a&3]<<14;
- return ret;
-#else
- if(a==0 || b==0) return 0;
- ret= noe_log[a] + noe_log[b];
- if(ret >= 0xFFFF) ret-= 0xFFFF;
- return noe_exp[ret];
-#endif
+ return a;
}
-static inline GF2Polynom gf2poly_mod(GF2Polynom a, GF2Polynom b){
- int i;
+static inline GFF4Element prod(GFF4Element a, GFF4Element b){
+//printf("%d %d\n", a,b);
+ if((a&b)==0x10000) return 1;
+ else return reduce(a*b);
+}
- b<<= EXPONENT - 1;
+static inline GFF4Element sum(GFF4Element a, GFF4Element b){
- for(i=0; i<EXPONENT; i++){
- if((a^b) < a) a^=b;
- b>>=1;
- }
+ a += b - 0x10001;
+ a += (((int)a)>>31)&0x10001;
return a;
}
-static inline GF2Polynom gf2poly_mod_m(GF2Polynom a){
- a ^= noe_mod[a>>24]<<8;
- a ^= noe_mod[a>>16];
-
- return a;
-}
-
-static inline GF2h16Element prod(GF2h16Element a, GF2h16Element b){
- return gf2poly_mod_m(gf2poly_prod(a, b));
-}
-
-static inline GF2h16Element inv(GF2h16Element a){
+static inline GFF4Element inv(GFF4Element a){
assert(a!=0);
- return noe_exp[(1<<EXPONENT) - 1 - noe_log[a]];
+ return noe_exp[SIZE - 1 - noe_log[a]];
}
Added: trunk/noe/gfft.c
==============================================================================
--- (empty file)
+++ trunk/noe/gfft.c Tue Jul 10 00:15:17 2007
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <inttypes.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "noe_internal.h"
+#include "galois.h"
+#include "gfft.h"
+
+uint8_t noe_revTable[256];
+
+void noe_gfft_init(){
+ int i;
+
+ for(i=0; i<256; i++){
+ int x= i;
+ x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1));
+ x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2));
+ x = (( x >> 4) | ((x & 0x0f) << 4));
+
+ noe_revTable[i]= x;
+ }
+}
+
+int noe_log2(unsigned int v) // from ffmpeg
+{
+ int n;
+
+ n = 0;
+ if (v & 0xffff0000) {
+ v >>= 16;
+ n += 16;
+ }
+ if (v & 0xff00) {
+ v >>= 8;
+ n += 8;
+ }
+ if (v & 0xf0) {
+ v >>= 4;
+ n += 4;
+ }
+ if (v & 0xc) {
+ v >>= 2;
+ n += 2;
+ }
+ if (v & 0x2) {
+ n++;
+ }
+ return n;
+}
+
+void noe_permute(GFF4Element *dst, GFF4Element *src, int outCount){
+ int i;
+
+ if(dst==src){
+ for(i=1; i<outCount; i++){
+ const int r= noe_bitReverse(i);
+ unsigned int t;
+ if(r<=i) continue;
+ t= dst[i];
+ dst[i]= dst[r];
+ dst[r]= t;
+ }
+ }else{
+ for(i=0; i<outCount; i++){
+ dst[i]= src[noe_bitReverse(i)];
+ }
+ }
+}
+
+static inline void fft2(GFF4Element *p){
+ const unsigned int a= p[0];
+ const unsigned int b= p[1];
+
+ p[0]= sum(a, b);
+ p[1]= sum(a, SIZE - b);
+}
+
+static inline void fft4(GFF4Element *p){
+ unsigned int a,b,c,d;
+
+ d= p[0] + SIZE*0x8000ULL;
+
+ a= d +p[2];
+ b= p[1]+p[3];
+ c= d -p[2];
+ d= (p[3] - p[1])<<8 /*(p[1] - p[3])*noe_exp[16384]*/;
+
+ p[0]= reduce(a+b);
+ p[1]= reduce(a-b);
+ p[2]= reduce(c+d);
+ p[3]= reduce(c-d);
+}
+
+/*
+aWi + bWiWn
+(aWi - bWiWn)W2i
+
+(a + bWn)Wi
+(a - bWn)WiW2i
+*/
+static inline void fft8(GFF4Element *p){
+ unsigned int a,b;
+
+ a= p[0];
+ b= p[4];
+ p[0]= a+b;
+ p[4]= a-b;
+
+ a= p[1];
+ b= p[5];
+ p[1]= a+b;
+ p[5]= reduce(SIZE*0x8000ULL + ((a-b)<<12))/*(a-b)*noe_exp[8192]*/;
+
+ a= p[2];
+ b= p[6];
+ p[2]= a+b;
+ p[6]= (b-a)<<8 /*(a-b)*noe_exp[16384]*/;
+
+ a= p[3];
+ b= p[7];
+ p[3]= a+b;
+ p[7]= (a-b)<<4/*(a-b)*noe_exp[3*8192]*/;
+
+ fft4(p);
+ fft4(p+4);
+}
+
+static void fft16(GFF4Element *p){
+ int n;
+
+ for(n=0; n<8; n++){
+ const unsigned int w= noe_exp[ n<<12 ];
+ const unsigned int a= p[n ];
+ const unsigned int b= p[n + 8];
+
+ p[n ]= sum(a, b);
+ p[n + 8]= reduce(sum(a, SIZE - b)*w);
+ }
+
+ fft8(p);
+ fft8(p+8);
+}
+
+static void fftn(GFF4Element *p, int logSize){
+ int n;
+ const int size= 1<<(logSize-1);
+
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int a= p[n ];
+ const unsigned int b= p[n + size];
+
+ p[n ]= sum(a, b);
+ p[n + size]= reduce(sum(a, SIZE - b)*w);
+ }
+
+ if(logSize==5){
+ fft16(p);
+ fft16(p+16);
+ }else{
+ fftn(p, logSize-1);
+ fftn(p+size, logSize-1);
+ }
+}
+
+static void fftn2(GFF4Element *p, GFF4Element *src, int logSize){
+ int n;
+ const int size= 1<<(logSize-1);
+
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ n<<(16-logSize) ];
+ const unsigned int a= src[n ];
+ const unsigned int b= src[n + size];
+
+ p[n ]= sum(a, b);
+ p[n + size]= reduce(sum(a, SIZE - b)*w);
+ }
+
+ if(logSize==5){
+ fft16(p);
+ fft16(p+16);
+ }else{
+ fftn(p, logSize-1);
+ fftn(p+size, logSize-1);
+ }
+}
+
+static inline void ifft2(GFF4Element *p){
+ const unsigned int a= p[0];
+ const unsigned int b= p[1];
+
+ p[0]= sum(a, b);
+ p[1]= sum(a, SIZE - b);
+}
+
+static void ifftn(GFF4Element *p, int logSize){
+ int n;
+ const int size= 1<<(logSize-1);
+
+ if(logSize==2){
+ ifft2(p);
+ ifft2(p+2);
+ }else{
+ ifftn(p, logSize-1);
+ ifftn(p+size, logSize-1);
+ }
+
+ for(n=0; n<size; n++){
+ const unsigned int w= noe_exp[ (1<<16) - (n<<(16-logSize)) ];
+ const unsigned int a= p[n ];
+ const unsigned int b= prod(p[n + size], w);
+
+ p[n ]= sum(a, b);
+ p[n + size]= sum(a, SIZE - b);
+ }
+
+}
+
+void noe_gfft(GFF4Element *dst, GFF4Element *src, int logSize){
+// int i, j, pass;
+//printf("%X %X\n", noe_exp[4096], noe_exp[3*4096]);
+
+ assert(logSize>=5);
+
+ if(src==dst)
+ fftn(dst, logSize);
+ else
+ fftn2(dst, src, logSize);
+#if 0
+ memcpy(dst, src, sizeof(GFF4Element)<<logSize);
+ for(pass=0; pass<12; pass++){
+ int block;
+ const int np= 1<<(16-pass-1);
+ const int blockCount= 1<<pass;
+
+ for(block=0; block<blockCount; block++){
+ int n;
+ const int top= block*np<<1;
+ const int bot= top + np;
+
+ for(n=0; n<np; n++){
+ const unsigned int w= noe_exp[ n<<pass ];
+ const unsigned int a= dst[top + n];
+ const unsigned int b= dst[bot + n];
+
+ dst[top + n]= sum(a, b);
+ dst[bot + n]= prod(sum(a, SIZE - b), w);
+ }
+ }
+ }
+
+ {
+ int block;
+ for(block=0; block<4096; block++){
+{START_TIMER
+ fft16(dst + block*16);
+STOP_TIMER}
+ }
+ }
+#endif
+}
+
+void noe_igfft(GFF4Element *dst, GFF4Element *src, int logSize){
+ assert(logSize>=5);
+
+ if(src!=dst)
+ memcpy(dst, src, sizeof(GFF4Element)<<logSize);
+
+ ifftn(dst, logSize);
+}
Added: trunk/noe/gfft.h
==============================================================================
--- (empty file)
+++ trunk/noe/gfft.h Tue Jul 10 00:15:17 2007
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void noe_gfft_init();
+void noe_gfft(GFF4Element *dst, GFF4Element *src, int size);
+void noe_igfft(GFF4Element *dst, GFF4Element *src, int size);
+void noe_permute(GFF4Element *dst, GFF4Element *src, int outCount);
+int noe_log2(unsigned int v);
+
+extern uint8_t noe_revTable[256];
+
+static inline unsigned int noe_bitReverse(unsigned int x){
+ return (noe_revTable[x&255]<<8) | (noe_revTable[x>>8]);
+}
+
Modified: trunk/noe/noe_internal.h
==============================================================================
--- trunk/noe/noe_internal.h (original)
+++ trunk/noe/noe_internal.h Tue Jul 10 00:15:17 2007
@@ -18,3 +18,33 @@
#define NOE_MAX(a,b) ((a) > (b) ? (a) : (b))
#define NOE_MIN(a,b) ((a) > (b) ? (b) : (a))
+
+static inline long long rdtsc()
+{
+ long long l;
+ asm volatile( "rdtsc\n\t"
+ : "=A" (l)
+ );
+// printf("%d\n", int(l/1000));
+ return l;
+}
+
+#define START_TIMER \
+static uint64_t tsum=0;\
+static int tcount=0;\
+static int tskip_count=0;\
+uint64_t tend;\
+uint64_t tstart= rdtsc();\
+
+
+#define STOP_TIMER \
+tend= rdtsc();\
+if(tcount<2 || tend - tstart < 4*tsum/tcount){\
+ tsum+= tend - tstart;\
+ tcount++;\
+}else\
+ tskip_count++;\
+if(256*256*256*64%tcount==0){\
+ fprintf(stderr, "%Ld dezicycles, %d runs, %d skips\n", tsum*10/tcount, tcount, tskip_count);\
+ fflush(stderr);\
+}
\ No newline at end of file
Modified: trunk/noe/rs.c
==============================================================================
--- trunk/noe/rs.c (original)
+++ trunk/noe/rs.c Tue Jul 10 00:15:17 2007
@@ -19,61 +19,63 @@
#include <inttypes.h>
#include <assert.h>
#include <malloc.h>
+#include <stdio.h>
#include "noe_internal.h"
#include "galois.h"
#include "rs.h"
+#include "gfft.h"
+
/**
*
*/
-void noe_getRsGenerator(GF2h16Element *dst, int first, int order){
- GF2h16Element factor[2];
+void noe_getRsGenerator(GFF4Element *dst, int first, int order){
int i;
-
- dst[0]= 1;
-
- factor[0]= noe_exp[first];
- factor[1]= 1;
+ GFF4Element factor[2*order];
- for(i=0; i<order; i++){
- int j;
+ factor[0]= SIZE - noe_exp[first];
+ factor[1]= 1;
- noe_prodPoly(dst, dst, factor, i, 1);
- factor[0]= prod(factor[0], PRIMITIVE_ELEMENT);
+ for(i=1; i<order; i++){
+ factor[2*i+0]= prod(factor[2*i-2], PRIMITIVE_ELEMENT);
+ factor[2*i+1]= 1;
}
+
+ noe_synthPoly(dst, factor, order);
}
-void noe_getSyndrom(GF2h16Element *syn, GF2h16Element *src, int first, int order){
- int i;
- //FIXME use GFFT if order is large
+void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int first, int order){
+ noe_gfft(syn, src, 16);
+ noe_permute(syn, syn, order+1);
syn[0]= 1;
-
+#if 0
for(i=0; i<order; i++){
- syn[i+1]= noe_evalPoly(src, (1<<EXPONENT)-2, noe_exp[first + i]);
+ syn[i+1]= noe_evalPoly(src, SIZE-2, noe_exp[first + i]);
}
+#endif
}
#if 1
noe_RsEncoder *noe_getRsEncoder(int parityCount){
- const int dataCount= (1<<EXPONENT) - parityCount - 1;
+ const int dataCount= SIZE - parityCount - 1;
int i;
- GF2h16Element *locator, *factor;
- GF2h16Element locatorDerivative[parityCount];
+ GFF4Element *locator, *factor;
+ GFF4Element locatorDerivative[parityCount];
noe_RsEncoder *encoder= memalign(16, sizeof(noe_RsEncoder));
- locator= encoder->parityLocator= memalign(16, sizeof(GF2h16Element)*(parityCount+1));
- factor= encoder->parityFactor = memalign(16, sizeof(GF2h16Element)* parityCount );
+ locator= encoder->parityLocator= memalign(16, sizeof(GFF4Element)*(parityCount+1));
+ factor= encoder->parityFactor = memalign(16, sizeof(GFF4Element)* parityCount );
encoder->parityCount= parityCount;
locator[0]= 1;
for(i=0; i<parityCount; i++){
- GF2h16Element locationFactor[2];
+ GFF4Element locationFactor[2];
locationFactor[0] = 1;
- locationFactor[1] = noe_exp[dataCount + i];
- noe_prodPoly(locator, locator, locationFactor, i, 1);
+ locationFactor[1] = SIZE - noe_exp[dataCount + i];
+ noe_prodPoly(locator, locator, locationFactor, i, 1); //FIXME use synthPoly
}
#if 0
for(i=0; i<parityCount; i++){
@@ -84,17 +86,18 @@ for(i=0; i<parityCount; i++){
if(!noe_evalPoly(locator, parityCount, inv(noe_exp[dataCount - 1])))
printf("Internal Error 2\n");
#endif
- noe_getDerivative(locatorDerivative, locator, parityCount);
+ i= noe_getDerivative(locatorDerivative, locator, parityCount);
+ assert(i==parityCount-1);
for(i=0; i<parityCount; i++){
- GF2h16Element X= noe_exp[dataCount + i];
- GF2h16Element invX= noe_exp[(1<<EXPONENT) - dataCount - i - 1];
- GF2h16Element denom;
+ GFF4Element X= noe_exp[dataCount + i];
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+ GFF4Element denom;
assert(X == inv(invX));
- denom= noe_evalPoly(locatorDerivative, parityCount-1, invX);
- factor[i]= prod(X, inv(denom));
+ denom= noe_evalPoly(locatorDerivative, parityCount-1, invX); //FIXME do in freq domain if parityCount>1000
+ factor[i]= prod(SIZE - X, inv(denom));
}
return encoder;
@@ -115,35 +118,222 @@ void noe_freeRsEncoder(noe_RsEncoder *en
/**
*
*/
-void noe_rsEncode(noe_RsEncoder *encoder, GF2h16Element *data){
+void noe_rsEncode(noe_RsEncoder *encoder, GFF4Element *data){
int i;
const int parityCount= encoder->parityCount;
- const int dataCount= (1<<EXPONENT) - parityCount - 1;
- GF2h16Element syn[parityCount+1];
- GF2h16Element omega[2*parityCount+1];
- GF2h16Element *locator= encoder->parityLocator;
- GF2h16Element *factor= encoder->parityFactor;
+ const int dataCount= SIZE - parityCount - 1;
+ GFF4Element syn[SIZE - 1];
+ GFF4Element omega[SIZE - 1];
+ GFF4Element *locator= encoder->parityLocator;
+ GFF4Element *factor= encoder->parityFactor;
- memset(data + dataCount, 0, parityCount*sizeof(GF2h16Element));
+ memset(data + dataCount, 0, parityCount*sizeof(GFF4Element));
noe_getSyndrom(syn, data, 1, parityCount);
- if(parityCount < 1000 || 1){
- noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
-
+ noe_partialProdPoly(omega, locator, syn, parityCount, parityCount);
+
+ if(parityCount < 1000){
for(i=0; i<parityCount; i++){
- GF2h16Element invX= noe_exp[(1<<EXPONENT) - dataCount - i - 1];
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
- GF2h16Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+ GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
- data[dataCount + i]= parity;
+ data[dataCount + i]= SIZE - parity;
}
}else{
- //FIXME freq domain encoding
+//START_TIMER
+#if 0
+ for(i=0; i<parityCount; i++){
+ GFF4Element invX= noe_exp[SIZE - dataCount - i - 1];
+
+ GFF4Element parity= prod(noe_evalPoly(omega, parityCount, invX), factor[i]);
+
+ data[dataCount + i]= SIZE - parity;
+ }
+#else
+ memset(omega + parityCount + 1, 0, (SIZE - 2 - parityCount)*sizeof(GFF4Element));
+ noe_gfft(omega, omega, 16);
+ for(i=0; i<parityCount; i++){
+ int index= SIZE - dataCount - i - 1;
+
+ GFF4Element parity= prod(omega[noe_bitReverse(index)], factor[i]);
+
+ data[dataCount + i]= SIZE - parity;
+ }
+#endif
+//STOP_TIMER
+ }
+}
+#endif
+
+/**
+ * ...
+ * @param omega must be parityCount+2 big
+ */
+int noe_rsEuclid(GFF4Element *locator[2], GFF4Element *omega[2], int parityCount, int erasureCount, int *locatorOrderP, int *omegaOrderP){
+ int i, quotOrder;
+ int locatorOrder[2]= {0,0};
+ int omegaOrder[2]= {parityCount+1, -1};
+ GFF4Element quot[parityCount+2]; //FIXME size ok?
+
+ memset(omega[0], 0, (parityCount+1)*sizeof(GFF4Element));
+ omega[0][parityCount+1]= 1;
+ locator[0][0]=0;
+ locator[1][0]=1;
+ omegaOrder[1]= noe_getOrder(omega[1], parityCount);
+
+ for(i=0; 1; i++){
+ const int di= i&1;
+ const int si= 1-di;
+#ifdef DEBUG_EUCLID
+printf("Locator0:");noe_printPoly(locator[di], locatorOrder[di]);
+printf("Omega0:");noe_printPoly(omega[di], omegaOrder[di]);
+printf("Locator1:");noe_printPoly(locator[si], locatorOrder[si]);
+printf("Omega1:");noe_printPoly(omega[si], omegaOrder[si]);
+#endif
+ if(2*omegaOrder[si] <= parityCount + erasureCount)
+ break;
+
+ quotOrder= omegaOrder[di] - omegaOrder[si];
+
+ omegaOrder[di]= noe_divPoly(quot, omega[di], omega[di], omega[si], omegaOrder[di], omegaOrder[si]);
+
+ quotOrder= noe_prodPoly(quot, quot, locator[si], quotOrder, locatorOrder[si]);
+ locatorOrder[di]= noe_diffPoly(locator[di], locator[di], quot, locatorOrder[di], quotOrder);
+#ifdef DEBUG_EUCLID
+printf("quot:");noe_printPoly(quot, quotOrder);
+printf("Locator:");noe_printPoly(locator[di], locatorOrder[di]);
+printf("Omega:");noe_printPoly(omega[di], omegaOrder[di]);
+#endif
}
+
+ i++;
+
+ *locatorOrderP= locatorOrder[i&1];
+ *omegaOrderP= omegaOrder[i&1];
+
+ return i&1;
+}
+
+int noe_rsDecode(GFF4Element *data, int *erasure, int erasureCount, int parityCount){
+ int i;
+ int errorCount, psiOrder, gfftEval, omegaOrder, phantomErrorCount;
+ const int dataCount= SIZE - 1 - parityCount;
+ GFF4Element erasureLocator[erasureCount + 1];
+ GFF4Element erasureSynthSrc[erasureCount*2 + 1];
+ GFF4Element locator0[parityCount + 1];
+ GFF4Element locator1[parityCount + 1];
+ GFF4Element *locators[2]={locator0, locator1};
+ GFF4Element omega0[SIZE - 1];
+ GFF4Element omega1[SIZE - 1];
+ GFF4Element *omegas[2]={omega0, omega1}; //FIXME clean this shit up
+ GFF4Element *fErrorLocator, *errorLocator, *omega, *syn, *psi;
+
+ syn= omegas[1];
+ /* kill erased symbols */
+ for(i=0; i<erasureCount; i++){
+//printf("%d\n", erasure[i]);
+ data[ erasure[i] ]=0;
+ }
+
+ noe_getSyndrom(syn, data, 1, parityCount);
+ for(i=1; i<=parityCount; i++){
+ if(syn[i]) break;
+ }
+ if(i>parityCount)
+ return 0;
+
+ phantomErrorCount=0;
+ //FIXME check truncated symbols syndrom
+
+ for(i=0; i<erasureCount; i++){
+ erasureSynthSrc[2*i + 0] = 1;
+ erasureSynthSrc[2*i + 1] = SIZE - noe_exp[erasure[i]];
+ }
+ noe_synthPoly(erasureLocator, erasureSynthSrc, erasureCount);
+// noe_printPoly(erasureLocator, erasureCount);
+#if 0
+for(i=0; i<erasureCount; i++){
+ int eval= noe_evalPoly(erasureLocator, erasureCount, inv(noe_exp[erasure[i]]));
+ assert( eval==0);
}
#endif
+ noe_partialProdPoly(syn, erasureLocator, syn, erasureCount, parityCount);
+ i= noe_rsEuclid(locators, omegas, parityCount, erasureCount, &errorCount, &omegaOrder);
+//printf("errorCount %d \n", errorCount);
+
+ if(i<0) return -1;
+
+ omega= omegas[i];
+ errorLocator= locators[i];
+ fErrorLocator= omegas[1-i]; //reuse some unused space
+ psi= locators[1-i]; //reuse some unused space
+
+ gfftEval= errorCount>20;
+ if(gfftEval && errorCount){
+ memcpy(fErrorLocator, errorLocator, (errorCount+1)*sizeof(GFF4Element));
+ memset(fErrorLocator + errorCount+1, 0, (SIZE - errorCount-2)*sizeof(GFF4Element));
+ noe_gfft(fErrorLocator, fErrorLocator, 16);
+ }
+
+ psiOrder= noe_prodPoly(psi, errorLocator, erasureLocator, errorCount, erasureCount);
+ psiOrder= noe_getDerivative(psi, psi, psiOrder);
+
+ if(errorCount){
+ for(i=0; i<SIZE-1; i++){
+ int r, e;
+ GFF4Element X, invX, nom, denom;
+
+ if(gfftEval){ //FIXME optimize
+ if(fErrorLocator[i])
+ continue;
+
+ r= (- noe_bitReverse(i))&0xFFFF;
+ }else{
+ if(noe_evalPoly(errorLocator, errorCount, noe_exp[i]))
+ continue;
+
+ r= (-i)&0xFFFF;
+ }
+//printf("E%6d %6d\n", i, r);
+
+ X = noe_exp[r];
+ invX= noe_exp[SIZE - r - 1];
+ nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
+ denom= noe_evalPoly(psi, psiOrder, invX);
+
+ assert(r>=0 && r<=SIZE-2);
+ e= prod(nom, inv(denom));
+ if(data[r]==0 && e==0x10000){
+ if(r < dataCount)
+ return -1;
+ else
+ phantomErrorCount++;
+ }
+ data[r]= sum(data[r], e);
+ }
+ }
+
+ for(i=0; i<erasureCount; i++){
+ const int r= erasure[i];
+ const GFF4Element X = noe_exp[r];
+ const GFF4Element invX= noe_exp[SIZE - r - 1];
+ GFF4Element nom, denom;
+
+ assert(r>=0 && r<0x10000);
+ assert(prod(X, invX)==1);
+
+ nom= prod(X, noe_evalPoly(omega, omegaOrder, invX));
+ denom= noe_evalPoly(psi, psiOrder, invX);
+
+ assert(data[r]==0);
+ data[r]= prod(nom, inv(denom));
+ }
+
+ return erasureCount + errorCount - phantomErrorCount;
+}
Modified: trunk/noe/rs.h
==============================================================================
--- trunk/noe/rs.h (original)
+++ trunk/noe/rs.h Tue Jul 10 00:15:17 2007
@@ -15,25 +15,27 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+
typedef struct noe_RsEncoder{
int parityCount;
- GF2h16Element *parityLocator;
- GF2h16Element *parityFactor;
+ GFF4Element *parityLocator;
+ GFF4Element *parityFactor;
}noe_RsEncoder;
-void noe_getRsGenerator(GF2h16Element *dst, int first, int order);
+void noe_getRsGenerator(GFF4Element *dst, int first, int order);
/**
* gets the syndroms.
* @param src a 2^16 entry long polynom
* @param syn the syndrom polynom will be stored here
*/
-void noe_getSyndrom(GF2h16Element *syn, GF2h16Element *src, int first, int order);
+void noe_getSyndrom(GFF4Element *syn, GFF4Element *src, int first, int order);
noe_RsEncoder *noe_getRsEncoder(int parityOrder);
void noe_freeRsEncoder(noe_RsEncoder *encoder);
/**
*
*/
-void noe_rsEncode(noe_RsEncoder *encoder, GF2h16Element *data);
+void noe_rsEncode(noe_RsEncoder *encoder, GFF4Element *data);
+
+int noe_rsDecode(GFF4Element *data, int *erased, int erasedCount, int parityCount);
Added: trunk/noe/rw.c
==============================================================================
--- (empty file)
+++ trunk/noe/rw.c Tue Jul 10 00:15:17 2007
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <inttypes.h>
+
+#include "rw.h"
+
+typedef struct noe_Map{
+ uint64_t src;
+ uint64_t dst;
+ uint64_t len;
+}noe_Map;
+
+typedef struct noe_RemapRwContext{
+ Map *map;
+ int count;
+}noe_RemapRwContext;
+
+
+static int noe_remapRead(noe_RwContext *c, uint8_t *data, uint64_t pos, int len){
+ int i;
+ noe_RemapRwContext *p= (noe_RemapRwContext *)c->priv;
+ noe_RwContext *parent= c->parent;
+
+ //FIXME do binary search or cache last
+
+ for(i=0; i<p->count; i++){
+ if(pos < p->map[i].src + p->map[i].len){
+ const uint64_t diff= p->map[i].dst - p->map[i].src;
+ uint64_t currentLen= p->map[i].src + p->map[i].len - pos;
+ if(currentLen > len) currentLen= len;
+
+ parent->read(parent, data, pos + diff, currentLen);
+
+ data+= currentLen;
+ pos+= currentLen;
+ len-= currentLen;
+ if(len == 0) return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void remapUninit(noe_RwContext *c){
+ int i;
+ noe_RemapRwContext *p;
+
+ if(c==NULL) return;
+
+ p = (noe_RemapRwContext *)c->priv;
+
+ free(p->map);
+ free(p);
+ free(c);
+}
+
+noe_RwContext *noe_getRemapRwContext(noe_RwContext *parent, uint64_t *map, int count){
+ int i;
+ uint64_t pos;
+ noe_RwContext *c= malloc(sizeof(noe_RwContext));
+ noe_RemapRwContext *p= malloc(sizeof(noe_RemapRwContext));
+
+ c->priv= p;
+ c->parent= parent;
+
+ p->map= malloc(sizeof(noe_Map)*count);
+ memcpy(p->map, map, sizeof(noe_Map)*count);
+ p->count= count;
+
+ //FIXME sort map ?
+
+ c->read= remapRead;
+ c->write= remapWrite;
+ c->uninit= remapUninit;
+
+ return c;
+}
Added: trunk/noe/rw.h
==============================================================================
--- (empty file)
+++ trunk/noe/rw.h Tue Jul 10 00:15:17 2007
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni(a)gmx.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+typedef struct noe_RwContext{
+ int (*read )(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len);
+ int (*write)(struct noe_RwContext *context, uint8_t *data, uint64_t pos, int len);
+ void (*uninit)(struct noe_RwContext *context);
+ struct noe_RwContext *parent;
+ void *priv;
+}noe_RwContext;
\ No newline at end of file
Modified: trunk/noe/test.c
==============================================================================
--- trunk/noe/test.c (original)
+++ trunk/noe/test.c Tue Jul 10 00:15:17 2007
@@ -24,18 +24,41 @@
#include "noe_internal.h"
#include "galois.h"
+#include "gfft.h"
#include "rs.h"
-main(){
+static const unsigned int gfftChecksums[20]={
+0xFCB3E495,
+0x5704AC39,
+0x07F19DC4,
+0xE8E3A16F,
+0xD3FDE16D,
+0xB2F03FC5,
+0xB42E9BB6,
+0x1281C15E,
+0x4F1C1BA2,
+0x0EA4927A,
+0x2E0EBEC7,
+0x2D80F238,
+0x6D40B8AB,
+0x3EF87629,
+0xD1649F79,
+0x24A3D9E4,
+0x4EDC2FE4,
+0xF24C2F4F,
+0x1BFE26C9,
+};
+
+int main(){
int i, j;
- GF2Polynom bp=1;
+ GFF4Element bp=1;
noe_init();
- printf("Testing GF(2^%d)\n", EXPONENT);
- for(i=0; i<(1<<EXPONENT)-1; i++){
+ printf("Testing GF(65537)\n");
+ for(i=0; i<SIZE-1; i++){
if((bp==1 || bp==0) && i>0){
- printf("FAIL\n");
+ printf("FAIL %d %d\n", i, bp);
break;
}
bp= prod(bp, PRIMITIVE_ELEMENT);
@@ -44,24 +67,68 @@ main(){
printf("Testing inverse\n");
bp=1;
- for(i=1; i<(1<<EXPONENT); i++){
+ for(i=1; i<SIZE; i++){
if(prod(bp, inv(bp)) != 1){
printf("FAIL %X %X\n", (int)bp, (int)inv(bp));
break;
}
bp= prod(bp, PRIMITIVE_ELEMENT);
}
+#if 0
+ printf("Experiment");
+ for(i=0; i<(1<<30); i++){
+ unsigned int a= reduce(i*0xFF01);
+ unsigned int b= reduce(reduce(i)*0xFF01);
+
+ if(a!=b) printf("%X %X %X %X\n", i, reduce(i), i*0xFF01, reduce(i)*0xFF01);
+ }
+#endif
+ srand (31415);
- srand (time (0));
-
- printf("Testing generator polynoms");
+ printf("Testing GFFT");
for(i=1; i<20; i++){
- int n= (1<<EXPONENT) - 1;
- int k= (1<<EXPONENT) - 1 - i;
- GF2h16Element syn[i+1];
- GF2h16Element gen[i+1];
- GF2h16Element data[k];
- GF2h16Element code[n];
+ int n= SIZE - 1;
+ GFF4Element syn[n];
+ GFF4Element code[n];
+ int acc=0;
+
+ for(j=0; j<n; j++)
+ code[j]= rand() % 0x10001;
+
+ noe_gfft(syn, code, 16);
+
+ for(j=0; j<n; j++){
+ acc+= syn[j];
+ acc*=2*j+1;
+ }
+ if(gfftChecksums[i-1] != acc)
+ printf("FAIL: 0x%08X != 0x%08X\n", gfftChecksums[i-1], acc);
+
+ noe_igfft(syn, syn, 16);
+ for(j=0; j<n; j++){
+ syn[j]= prod(syn[j], inv(1<<16));
+ }
+
+ for(j=0; j<n; j++){
+ if(syn[j] != code[j]) printf("IGFFT missmatch at %d %X!=%X\n", j, syn[j], code[j]);
+ }
+
+// noe_printPoly(gen, i);
+// noe_printPoly(syn, i-1);
+
+ printf("."); fflush(stdout);
+ }
+
+ srand (31415);
+
+ printf("\nTesting generator polynoms");
+ for(i=1; i<100; i+=5){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+ GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
for(j=0; j<k; j++)
data[j]= rand() & 0xFFFF;
@@ -82,13 +149,13 @@ main(){
}
printf("\nTesting encoder");
- for(i=1; i<50; i+=10){
- int n= (1<<EXPONENT) - 1;
- int k= (1<<EXPONENT) - 1 - i;
- GF2h16Element syn[i+1];
- GF2h16Element gen[i+1];
- GF2h16Element data[k];
- GF2h16Element code[n];
+ for(i=1; i<1000; i+=200){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+// GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
noe_RsEncoder *encoder;
int pass=5;
@@ -98,7 +165,7 @@ main(){
for(j=0; j<k; j++)
data[j]= rand() & 0xFFFF;
- memcpy(code, data, n*sizeof(GF2h16Element));
+ memcpy(code, data, n*sizeof(GFF4Element));
noe_rsEncode(encoder, code);
@@ -115,19 +182,87 @@ main(){
}
noe_freeRsEncoder(encoder);
}
+
+ printf("\nTesting decoder");
+ for(i=1; i<2000; i+=100){
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+ GFF4Element erased[i];
+ GFF4Element data[k];
+ GFF4Element code[n];
+ noe_RsEncoder *encoder;
+ int pass=5;
+
+ encoder= noe_getRsEncoder(i);
+
+ for(pass=5; pass; pass--){
+ int erasedCount, errorCount;
+ for(j=0; j<k; j++)
+ data[j]= rand() & 0xFFFF;
+
+ memcpy(code, data, n*sizeof(GFF4Element));
+
+ noe_rsEncode(encoder, code);
+
+ erasedCount=0;
+ if(rand()&0x40){
+ erasedCount= (rand()%i)+1;
+ for(j=0; j<erasedCount; j++){
+ int e=-1;
+
+ while(e==-1 || code[e]==0x10000) e=rand()%n;
+
+ erased[j]= e;
+ code[ e ]= 0x10000;
+ }
+ for(j=0; j<erasedCount; j++){
+ int e= erased[j];
+
+ code[ e ]= rand()%0xFFFF;
+ }
+ }
+ errorCount=0;
+ if(erasedCount==0 || (rand()&0x40)){
+ int max= (i - erasedCount)/2;
+ if(max){
+ errorCount= (rand() % max)+1;
+ for(j=0; j<errorCount; j++){
+ int pos= rand()%n;
+ code[pos] = rand()%0xFFFF;
+// printf("P%6d\n", pos);
+ }
+ }
+ }
+//printf("erased:%d errors:%d parity:%d\n", erasedCount, errorCount, i);
+ noe_rsDecode(code, erased, erasedCount, i);
+
+ // noe_printPoly(gen, i);
+ // noe_printPoly(syn, i-1);
+
+ for(j=0; j<k; j++){
+ if(data[j]!=code[j]){
+ printf("FAIL at:%d is %X %X\n", j, data[j], code[j]);
+ break;
+ }
+ }
+ printf("."); fflush(stdout);
+ }
+ noe_freeRsEncoder(encoder);
+ }
return 0;
printf("Testing erasure decoding\n");
for(i=1; i<20; i++){
- int n= (1<<EXPONENT) - 1;
- int k= (1<<EXPONENT) - 1 - i;
- GF2h16Element syn[i+1];
- GF2h16Element gen[i+1];
- GF2h16Element data[k];
- GF2h16Element code[n];
- GF2h16Element locator[i+1];
- GF2h16Element omega[2*i];
+ int n= SIZE - 1;
+ int k= SIZE - 1 - i;
+ GFF4Element syn[n];
+ GFF4Element gen[i+1];
+ GFF4Element data[k];
+ GFF4Element code[n];
+ GFF4Element locator[i+1];
+ GFF4Element omega[2*i];
int locatorOrder=0;
@@ -141,7 +276,7 @@ return 0;
locator[0] = 1;
for(j=0; j<i; j++){
int index;
- GF2h16Element locationFactor[2];
+ GFF4Element locationFactor[2];
if((rand()&7)==0 && j) continue;
@@ -153,8 +288,6 @@ return 0;
code[index] += rand()&0xFFFF;
}
- syn[0] ^= 1;
-
noe_getSyndrom(syn, code, 1, i);
noe_prodPoly(omega, syn, locator, i-1, locatorOrder);
// noe_getDeriative(locator, locator, locatorOrder);
1
0