Module Name:    othersrc
Committed By:   agc
Date:           Wed Mar 23 03:17:48 UTC 2011

Modified Files:
        othersrc/external/bsd/rs/dist: librs.3 main.c rs.c rs.h
        othersrc/external/bsd/rs/librs: shlib_version
        othersrc/external/bsd/rs/rs: Makefile

Log Message:
+ add code to store the encoding parameters in the generated output
+ use the encoding parameters at decode time
+ add a test for non-standard encoding values
+ update manual page to incorporate some feedback from David Young - more
to come
+ bring manual page up to date
+ bump shlib major number


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r1.2 othersrc/external/bsd/rs/dist/librs.3 \
    othersrc/external/bsd/rs/dist/rs.c othersrc/external/bsd/rs/dist/rs.h
cvs rdiff -u -r1.4 -r1.5 othersrc/external/bsd/rs/dist/main.c
cvs rdiff -u -r1.1.1.1 -r1.2 othersrc/external/bsd/rs/librs/shlib_version
cvs rdiff -u -r1.1.1.1 -r1.2 othersrc/external/bsd/rs/rs/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: othersrc/external/bsd/rs/dist/librs.3
diff -u othersrc/external/bsd/rs/dist/librs.3:1.1.1.1 othersrc/external/bsd/rs/dist/librs.3:1.2
--- othersrc/external/bsd/rs/dist/librs.3:1.1.1.1	Sat Mar 12 08:08:29 2011
+++ othersrc/external/bsd/rs/dist/librs.3	Wed Mar 23 03:17:48 2011
@@ -1,4 +1,4 @@
-.\" $NetBSD: librs.3,v 1.1.1.1 2011/03/12 08:08:29 agc Exp $
+.\" $NetBSD: librs.3,v 1.2 2011/03/23 03:17:48 agc Exp $
 .\"
 .\" Copyright (c) 2011 Alistair Crooks <[email protected]>
 .\" All rights reserved.
@@ -23,12 +23,12 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"/
-.Dd March 9, 2011
+.Dd March 22, 2011
 .Dt LIBRS 3
 .Os
 .Sh NAME
 .Nm librs
-.Nd reed-solomon erasure code library
+.Nd Reed-Solomon forward erasure code library
 .Sh LIBRARY
 .Lb librs
 .Sh SYNOPSIS
@@ -46,6 +46,14 @@
 .Fo rs_decode
 .Fa "rs_t *rs" "const void *input" "size_t insize" "uint8_t *output" "size_t outsize"
 .Fc
+.Ft ssize_t
+.Fo rs_get_header
+.Fa "rs_t *rs" "void *input" "size_t size"
+.Fc
+.Ft ssize_t
+.Fo rs_put_header
+.Fa "rs_t *rs" "const void *input" "size_t size"
+.Fc
 .Sh DESCRIPTION
 The
 .Nm
@@ -86,6 +94,30 @@
 function, the output will be split up into slices of
 256 bytes, and the final buffer may contain less than
 256 bytes.
+.Pp
+The
+.Fn rs_put_header
+function is used to store information about the encoding in
+the output that is generated. This will allow a future call
+of the
+.Fn rs_decode
+function to know the exact coding parameters in order to reconstruct
+the original data, by using the
+.Fn rs_get_header
+function.
+.Pp
+The output size from the
+.Fn rs_encode 
+function depends on the number of parity bytes, and the number of
+data bytes used.
+In addition, there is an overhead of 12 bytes to hold the
+encoding information.
+For example, a
+.Dv 28,24
+encoding will use 4 parity bytes for every 24 data bytes.
+This means that the output will be at least
+.Dv (((datasize / 6) + 1) * 7) + 12
+bytes long.
 .Sh HISTORY
 The
 .Nm
Index: othersrc/external/bsd/rs/dist/rs.c
diff -u othersrc/external/bsd/rs/dist/rs.c:1.1.1.1 othersrc/external/bsd/rs/dist/rs.c:1.2
--- othersrc/external/bsd/rs/dist/rs.c:1.1.1.1	Sat Mar 12 08:08:29 2011
+++ othersrc/external/bsd/rs/dist/rs.c	Wed Mar 23 03:17:48 2011
@@ -63,6 +63,8 @@
 #define USE_ARG(x)		/*LINTED*/(void)&(x)
 #endif
 
+#define RS_MAGIC		"rs1"
+
 /* set up the gf8 tables */
 static int
 galois_inits(const unsigned poly)
@@ -208,9 +210,9 @@
 	uint8_t	product[MAX_DEGREE * 2];
 	int	i;
 
-	poly_mult(product, rs->lambda, rs->syndrome, rs->parityc * 2);
-	poly_zero(rs->omega, rs->parityc * 2);
-	for (i = 0; i < rs->parityc; i++) {
+	poly_mult(product, rs->lambda, rs->syndrome, rs->header.parityc * 2);
+	poly_zero(rs->omega, rs->header.parityc * 2);
+	for (i = 0; i < rs->header.parityc; i++) {
 		rs->omega[i] = product[i];
 	}
 }
@@ -264,36 +266,36 @@
 	int	n;
 
 	/* initialize Gamma, the erasure locator polynomial */
-	init_gamma(rs, gamma, rs->parityc * 2);
+	init_gamma(rs, gamma, rs->header.parityc * 2);
 
 	/* initialize to z */
-	(void) memcpy(D, gamma, rs->parityc * 2);
-	poly_mul_z(D, rs->parityc * 2);
+	(void) memcpy(D, gamma, rs->header.parityc * 2);
+	poly_mul_z(D, rs->header.parityc * 2);
 
-	(void) memcpy(psi, gamma, rs->parityc * 2);
+	(void) memcpy(psi, gamma, rs->header.parityc * 2);
 	k = -1;
 
-	for (L = n = 0; n < rs->parityc; n++) {
+	for (L = n = 0; n < rs->header.parityc; n++) {
 		if ((d = compute_discrepancy(psi, rs->syndrome, L, n)) != 0) {
 			/* psi2 = psi - d*D */
-			for (i = 0; i < rs->parityc * 2; i++) {
+			for (i = 0; i < rs->header.parityc * 2; i++) {
 				psi2[i] = psi[i] ^ gfmult(d, D[i]);
 			}
 			if (L < (n - k)) {
 				L2 = n - k;
 				k = n - L;
 				/* D = poly_scale(psi, gfinv(d), rs->parityc * 2); */
-				for (i = 0; i < rs->parityc * 2; i++) {
+				for (i = 0; i < rs->header.parityc * 2; i++) {
 					D[i] = gfmult(psi[i], gfinv(d));
 				}
 				L = L2;
 			}
 			/* psi = psi2 */
-			(void) memcpy(psi, psi2, rs->parityc * 2);
+			(void) memcpy(psi, psi2, rs->header.parityc * 2);
 		}
-		poly_mul_z(D, rs->parityc * 2);
+		poly_mul_z(D, rs->header.parityc * 2);
 	}
-	(void) memcpy(rs->lambda, psi, rs->parityc * 2);
+	(void) memcpy(rs->lambda, psi, rs->header.parityc * 2);
 	compute_modified_omega(rs);
 }
 
@@ -314,7 +316,7 @@
 
 	for (rs->nerrors = 0, r = 1; r < MAX_GF8; r++) {
 		/* evaluate lambda at r */
-		for (sum = 0, k = 0; k < rs->parityc + 1; k++) {
+		for (sum = 0, k = 0; k < rs->header.parityc + 1; k++) {
 			sum ^= gfmult(gfexp[(k * r) % (MAX_GF8 - 1)], rs->lambda[k]);
 		}
 		if (sum == 0) {
@@ -373,7 +375,7 @@
 
 	Modified_Berlekamp_Massey(rs);
 	find_roots(rs);
-	if ((rs->nerrors <= rs->parityc) && rs->nerrors > 0) {
+	if ((rs->nerrors <= rs->header.parityc) && rs->nerrors > 0) {
 		/* first check for illegal error locs */
 		for (r = 0; r < rs->nerrors; r++) {
 			if (rs->errorlocs[r] >= size) {
@@ -391,7 +393,7 @@
 			/* evaluate Omega at alpha^(-i) */
 
 			num = 0;
-			for (j = 0; j < rs->parityc * 2; j++) {
+			for (j = 0; j < rs->header.parityc * 2; j++) {
 				num ^= gfmult(rs->omega[j], gfexp[((MAX_GF8 - 1 - i) * j) % (MAX_GF8 - 1)]);
 			}
 			/*
@@ -399,7 +401,7 @@
 			 * odd powers disappear
 			 */
 			denom = 0;
-			for (j = 1; j < rs->parityc * 2; j += 2) {
+			for (j = 1; j < rs->header.parityc * 2; j += 2) {
 				denom ^= gfmult(rs->lambda[j], gfexp[((MAX_GF8 - 1 - i) * (j - 1)) % (MAX_GF8 - 1)]);
 			}
 			err = gfmult(num, gfinv(denom));
@@ -423,7 +425,7 @@
 {
 	int	i;
 
-	for (i = 0; i < rs->parityc; i++) {
+	for (i = 0; i < rs->header.parityc; i++) {
 		if (rs->syndrome[i] != 0) {
 			return 1;
 		}
@@ -449,17 +451,17 @@
 
 	(void) memset(lfsr, 0x0, sizeof(lfsr));
 	for (i = 0; i < size; i++) {
-		dbyte = msg[i] ^ lfsr[rs->parityc - 1];
-		for (j = rs->parityc - 1; j > 0; j--) {
+		dbyte = msg[i] ^ lfsr[rs->header.parityc - 1];
+		for (j = rs->header.parityc - 1; j > 0; j--) {
 			lfsr[j] = lfsr[j - 1] ^ gfmult(rs->genPoly[j], dbyte);
 		}
 		lfsr[0] = gfmult(rs->genPoly[0], dbyte);
 	}
 	(void) memcpy(dst, msg, size);
-	for (i = 0; i < rs->parityc; i++) {
-		dst[size + i] = lfsr[rs->parityc - 1 - i];
+	for (i = 0; i < rs->header.parityc; i++) {
+		dst[size + i] = lfsr[rs->header.parityc - 1 - i];
 	}
-	return size + rs->parityc;
+	return size + rs->header.parityc;
 }
 
 /* decode one chunk of the input */
@@ -471,7 +473,7 @@
 	int	j;
 
 	(void) memcpy(dst, in, size);
-	for (j = 0; j < rs->parityc; j++) {
+	for (j = 0; j < rs->header.parityc; j++) {
 		for (sum = 0, i = 0; i < size; i++) {
 			sum = dst[i] ^ gfmult(gfexp[j + 1], sum);
 		}
@@ -480,7 +482,21 @@
 	if (nonzero_syndrome(rs) && !correct_errors(rs, dst, size)) {
 		return -1;
 	}
-	return size - rs->parityc;
+	return size - rs->header.parityc;
+}
+
+#define BSWAP32(x)	((((x) & 0xff) << 24) |				\
+			 (((x) & 0xff00) << 8) |			\
+			 (((x) & 0xff0000) >> 8) |			\
+			 (((x) & 0xff000000) >> 24))
+
+/* byte-swap 32 bits, if necessary, to get little-endian */
+static uint32_t
+le32(uint32_t in)
+{
+	int	indian = 1;
+
+	return (*(char *)(void *)&indian) ? in : BSWAP32(in);
 }
 
 /****************************************************************************/
@@ -502,13 +518,13 @@
 		return 0;
 	}
 	(void) memset(rs, 0x0, sizeof(*rs));
-	rs->poly = poly;
-	rs->datac = databytes;
-	rs->parityc = paritybytes;
+	rs->header.poly = poly;
+	rs->header.datac = databytes;
+	rs->header.parityc = paritybytes;
 	/* Initialize the galois field arithmetic tables */
 	galois_inits(poly);
 	/* Compute the encoder generator polynomial */
-	compute_genpoly(rs->parityc, rs->genPoly, rs->parityc * 2);
+	compute_genpoly(rs->header.parityc, rs->genPoly, rs->header.parityc * 2);
 	return 1;
 }
 
@@ -521,11 +537,11 @@
 	size_t		 incc;
 	size_t		 chunk;
 
-	if (!rs->poly) {
+	if (!rs->header.poly) {
 		rs_init(rs, RS_DEFAULT_POLYNOMIAL, RS_DEFAULT_DATA, RS_DEFAULT_PARITY);
 	}
 	for (outcc = 0, incc = 0 ; incc < size && outcc < outsize ; incc += chunk) {
-		chunk = MIN(size - incc, rs->datac);
+		chunk = MIN(size - incc, rs->header.datac);
 		outcc += encode_chunk(rs, &in[incc], chunk, &out[outcc]);
 	}
 	return (ssize_t)outcc;
@@ -541,11 +557,8 @@
 	size_t		 incc;
 	size_t		 chunk;
 
-	if (!rs->poly) {
-		rs_init(rs, RS_DEFAULT_POLYNOMIAL, RS_DEFAULT_DATA, RS_DEFAULT_PARITY);
-	}
 	for (outcc = 0, incc = 0 ; incc < size && outcc < (ssize_t)outsize ; incc += chunk) {
-		chunk = MIN(size - incc, rs->datac + rs->parityc);
+		chunk = MIN(size - incc, rs->header.datac + rs->header.parityc);
 		if ((cc = decode_chunk(rs, &in[incc], chunk, &out[outcc])) < 0) {
 			break;
 		}
@@ -553,3 +566,30 @@
 	}
 	return outcc;
 }
+
+/* get a header from an area of memory */
+ssize_t
+rs_get_header(rs_t *rs, const void *in, size_t insize)
+{
+	rs_header_t	head;
+
+	USE_ARG(insize);
+	(void) memcpy(&head, in, sizeof(head));
+	head.poly = le32(head.poly);
+	(void) memcpy(&rs->header, &head, sizeof(rs->header));
+	return sizeof(rs->header);
+}
+
+/* put a header into an area of memory */
+ssize_t
+rs_put_header(rs_t *rs, void *out, size_t outsize)
+{
+	rs_header_t	head;
+
+	USE_ARG(outsize);
+	(void) memcpy(&head, &rs->header, sizeof(head));
+	(void) snprintf(head.magic, sizeof(head.magic), "%s", RS_MAGIC);
+	head.poly = le32(head.poly);
+	(void) memcpy(out, &head, sizeof(head));
+	return sizeof(head);
+}
Index: othersrc/external/bsd/rs/dist/rs.h
diff -u othersrc/external/bsd/rs/dist/rs.h:1.1.1.1 othersrc/external/bsd/rs/dist/rs.h:1.2
--- othersrc/external/bsd/rs/dist/rs.h:1.1.1.1	Sat Mar 12 08:08:29 2011
+++ othersrc/external/bsd/rs/dist/rs.h	Wed Mar 23 03:17:48 2011
@@ -33,6 +33,15 @@
 
 #include <inttypes.h>
 
+typedef struct rs_header_t {
+	char		magic[4];		/* magic number */
+	uint32_t	poly;			/* polynomial used */
+	uint8_t		datac;			/* # of data bytes per packet */
+	uint8_t		parityc;		/* # of parity bytes per packet */
+	uint8_t		interleave;		/* interleave signature */
+	uint8_t		convolution;		/* convolution factor */
+} rs_header_t;
+
 typedef struct rs_t {
 	uint8_t		syndrome[256]; 		/* Decoder syndrome bytes */
 	uint8_t		genPoly[256 * 2];	/* generator polynomial */
@@ -44,9 +53,7 @@
 	/* error locations found using Chien's search */
 	int		nerrors;
 	uint8_t		errorlocs[256];
-	unsigned	poly;			/* polynomial */
-	uint8_t		datac;			/* # of data bytes */
-	uint8_t		parityc;		/* # of parity bytes */
+	rs_header_t	header;			/* header for transportation */
 } rs_t;
 
 enum {
@@ -61,9 +68,15 @@
 	RS_DEFAULT_PARITY	= 32
 };
 
-/* Reed Solomon encode/decode routines */
+/* initialisations */
 int rs_init(rs_t *, const unsigned, const uint8_t, const uint8_t);
+
+/* Reed Solomon encode/decode routines */
 ssize_t rs_decode(rs_t *, const void *, size_t, uint8_t *, size_t);
 ssize_t rs_encode(rs_t *, const void *, size_t, uint8_t *, size_t);
 
+/* Reed Solomon header routines */
+ssize_t rs_get_header(rs_t *, const void *, size_t);
+ssize_t rs_put_header(rs_t *, void *, size_t);
+
 #endif

Index: othersrc/external/bsd/rs/dist/main.c
diff -u othersrc/external/bsd/rs/dist/main.c:1.4 othersrc/external/bsd/rs/dist/main.c:1.5
--- othersrc/external/bsd/rs/dist/main.c:1.4	Fri Mar 18 23:59:55 2011
+++ othersrc/external/bsd/rs/dist/main.c	Wed Mar 23 03:17:48 2011
@@ -44,9 +44,9 @@
 {
 	uint8_t	 buf[256];
 	uint8_t	 out[256];
+	size_t	 readsize;
 	FILE	*fpout;
 	FILE	*fpin;
-	size_t	 readsize;
 	int	 outcc;
 	int	 cc;
 	int	 ok;
@@ -66,7 +66,23 @@
 		}
 		return 0;
 	}
-	readsize = (encoding) ? data : data + parity;
+	if (encoding) {
+		/* copy the encoding paramters to output */
+		readsize = data;
+		outcc = rs_put_header(rs, out, sizeof(out));
+		if (write(fileno(fpout), out, outcc) != outcc) {
+			(void) fprintf(stderr, "short write\n");
+			return 0;
+		}
+	} else {
+		/* read the encoding paramters from input */
+		if (read(fileno(fpin), &rs->header, sizeof(rs->header)) != sizeof(rs->header)) {
+			(void) fprintf(stderr, "short read\n");
+			return 0;
+		}
+		rs_get_header(rs, &rs->header, sizeof(rs->header));
+		readsize = rs->header.datac + rs->header.parityc;
+	}
 	for (ok = 1 ; ok && (cc = read(fileno(fpin), buf, readsize)) > 0 ; ) {
 		if (encoding) {
 			outcc = rs_encode(rs, buf, cc, out, sizeof(out));

Index: othersrc/external/bsd/rs/librs/shlib_version
diff -u othersrc/external/bsd/rs/librs/shlib_version:1.1.1.1 othersrc/external/bsd/rs/librs/shlib_version:1.2
--- othersrc/external/bsd/rs/librs/shlib_version:1.1.1.1	Sat Mar 12 08:08:29 2011
+++ othersrc/external/bsd/rs/librs/shlib_version	Wed Mar 23 03:17:48 2011
@@ -1,2 +1,2 @@
-major=0
+major=1
 minor=0

Index: othersrc/external/bsd/rs/rs/Makefile
diff -u othersrc/external/bsd/rs/rs/Makefile:1.1.1.1 othersrc/external/bsd/rs/rs/Makefile:1.2
--- othersrc/external/bsd/rs/rs/Makefile:1.1.1.1	Sat Mar 12 08:08:29 2011
+++ othersrc/external/bsd/rs/rs/Makefile	Wed Mar 23 03:17:48 2011
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.1.1.1 2011/03/12 08:08:29 agc Exp $
+# $NetBSD: Makefile,v 1.2 2011/03/23 03:17:48 agc Exp $
 
 .include <bsd.own.mk>
 
@@ -33,3 +33,7 @@
 		cmp a a3;					\
 		rm -f a a2 a3;					\
 	done
+	./${PROG} -o a2 -p 28,24 Makefile
+	./${PROG} -d -o a3 a2
+	diff Makefile a3
+	rm -f a2 a3

Reply via email to