[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