[MN-dev] [mndiff]: r86 - in trunk/noe: Makefile mina.c

michael subversion at mplayerhq.hu
Tue Jul 10 01:04:39 CEST 2007


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 at 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;
+}



More information about the Mndiff-dev mailing list