raptor_code/lib.rs
1//! [](https://github.com/ypo/raptor/actions/workflows/rust.yml)
2//! [](https://codecov.io/gh/ypo/raptor)
3//! [](https://crates.io/crates/raptor-code/)
4//!
5//! # Raptor Code
6//!
7//! A Rust library for implementing Forward Error Correction (FEC) using Raptor
8//! codes.
9//!
10//! Raptor codes are a class of FEC codes that are designed to be highly
11//! efficient in the presence of packet erasures. This library provides
12//! functionality for encoding source blocks into encoding symbols and decoding
13//! source blocks from a set of encoding symbols.
14//!
15//! This library implements on the fly Gaussian Elimination to spread decoding
16//! complexity during packets reception.
17//!
18//! # Example : Source Block Encoder/Decoder
19//!
20//! Encode and decode a source block using `raptor_code::encode_source_block`
21//! and `raptor_code::decode_source_block`
22//!
23//!
24//! ```
25//! let source_block_data: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
26//! let max_source_symbols = 4;
27//! let nb_repair = 3;
28//! let source_block_length = source_block_data.len();
29//!
30//! // Step 1 - Generate the encoding symbols (source symbols + repair symbols)
31//! let (encoding_symbols, nb_source_symbols) =
32//! raptor_code::encode_source_block(&source_block_data, max_source_symbols, nb_repair).unwrap();
33//!
34//! // Step 2 - Re-construct the source data from the encoding symbols
35//! let mut received_symbols: Vec<Option<Vec<u8>>> = encoding_symbols
36//! .into_iter()
37//! .map(|symbols| Some(symbols))
38//! .collect();
39//! // simulate encoding symbol lost
40//! received_symbols[0] = None;
41//!
42//! let reconstructed_data = raptor_code::decode_source_block(
43//! &received_symbols,
44//! nb_source_symbols as usize,
45//! source_block_length,
46//! )
47//! .unwrap();
48//!
49//! // Source data and decoded data should be identical
50//! assert!(reconstructed_data == source_block_data)
51//! ```
52//!
53//! # Example : On the fly encoder
54//!
55//! ```
56//! let source_data: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
57//! let max_source_symbols = 4;
58//! let nb_repair = 3;
59//!
60//! let mut encoder = raptor_code::SourceBlockEncoder::new(&source_data, max_source_symbols).unwrap();
61//! let n = encoder.nb_source_symbols() + nb_repair;
62//!
63//! for esi in 0..n as u32 {
64//! let encoding_symbol = encoder.fountain(esi);
65//! // TODO transfer symbol over Network
66//! // network_push_pkt(encoding_symbol);
67//! }
68//! ```
69//! # Example : On the fly decoder
70//!
71//! ```
72//! let encoding_symbol_length = 1024;
73//! let nb_source_symbols = 4; // Number of source symbols in the source block
74//! let source_block_length = encoding_symbol_length * nb_source_symbols; // Total size size of the block;
75//! let mut n = 0u32;
76//! let mut decoder = raptor_code::SourceBlockDecoder::new(nb_source_symbols);
77//!
78//! while decoder.fully_specified() == false {
79//! //TODO replace the following line with pkt received from network
80//! let (encoding_symbol, esi) = (vec![0; encoding_symbol_length],n);
81//! decoder.push_encoding_symbol(&encoding_symbol, esi);
82//! n += 1;
83//! }
84//!
85//! let source_block = decoder.decode(source_block_length as usize);
86//! ```
87//!
88//! # Credit
89//!
90//! RFC 5053 <https://www.rfc-editor.org/rfc/rfc5053.html>
91//!
92//! On the fly Gaussian Elimination for LT codes, Valerio Bioglio, Marco
93//! Grangetto, 2009
94//!
95//! Reuse ideas and concepts of [gofountain](https://github.com/google/gofountain)
96#![no_std]
97#![deny(missing_docs)]
98#![cfg_attr(test, deny(warnings))]
99
100extern crate alloc;
101
102#[cfg(any(test))]
103extern crate std;
104
105mod common;
106mod decoder;
107mod encoder;
108mod encodingsymbols;
109mod partition;
110mod raptor;
111mod sparse_matrix;
112mod tables;
113
114pub use decoder::{decode_source_block, SourceBlockDecoder};
115pub use encoder::{encode_source_block, SourceBlockEncoder};
116
117#[cfg(test)]
118mod tests {
119 pub fn init() {
120 std::env::set_var("RUST_LOG", "debug");
121 env_logger::builder().is_test(true).try_init().ok();
122 }
123}