You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
3.5 KiB
68 lines
3.5 KiB
/** |
|
* Reed–Solomon: кодирование и восстановление одной пачки по известным пропускам. |
|
* rs_init задаёт n кодограмм, r проверочных и полный размер каждой кодограммы. |
|
* Первые n-r кодограмм содержат исходные данные, остальные — проверочные. |
|
* Формат: seq (8 байт, big-endian), subblock (1 байт), полезные данные. |
|
* blocks[i] всегда соответствует subblock=i; при decode NULL обозначает пропуск. |
|
* Любые n-r присутствующих кодограмм восстанавливают всю исходную пачку. |
|
* Полученные данные и заголовки должны быть проверены транспортом на повреждения. |
|
* Все входные/выходные буферы принадлежат вызывающему коду и не перекрываются. |
|
* Кодек выделяет рабочую память только при init; один контекст используют последовательно. |
|
* Неполную пачку вызывающий код дополняет нулями и отдельно сохраняет её настоящую длину. |
|
*/ |
|
#ifndef REED_SOLOMON_H |
|
#define REED_SOLOMON_H |
|
|
|
#include <stddef.h> |
|
#include <stdint.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#define RS_HEADER_SIZE 9 |
|
#define RS_MAX_BLOCK_SIZE 4096 |
|
#define RS_MAX_BLOCKS 255 |
|
|
|
enum rs_result { |
|
RS_OK = 0, |
|
RS_ERR_INVALID_ARG = -1, |
|
RS_ERR_MEMORY = -2, |
|
RS_ERR_INSUFFICIENT = -3, |
|
RS_ERR_HEADER = -4, |
|
RS_ERR_MATRIX = -5 |
|
}; |
|
|
|
struct rs_codec; |
|
|
|
/* Создать кодек: 1 <= n <= 255, 0 <= r < n, 10 <= block_size <= 4096. |
|
* ctx — выходной указатель; при ошибке *ctx=NULL. Старый контекст сначала освобождают. |
|
* Возвращает RS_OK или отрицательный rs_result. |
|
*/ |
|
int rs_init(struct rs_codec **ctx, unsigned n, unsigned r, size_t block_size); |
|
|
|
/* Освободить контекст и рабочую память; NULL допустим. */ |
|
void rs_free(struct rs_codec *ctx); |
|
|
|
/* Размер входа encode и выхода decode: (n-r)*(block_size-RS_HEADER_SIZE). |
|
* Для NULL возвращает 0 и логирует ошибку. |
|
*/ |
|
size_t rs_input_size(const struct rs_codec *ctx); |
|
|
|
/* Читать rs_input_size(ctx) байт input, записать n кодограмм с заданным seq. |
|
* blocks — n ненулевых указателей, каждый буфер содержит block_size байт. |
|
* При ошибке аргументов выходные буферы не изменяются. |
|
*/ |
|
int rs_encode(struct rs_codec *ctx, uint64_t seq, const uint8_t *input, uint8_t *const blocks[]); |
|
|
|
/* Восстановить rs_input_size(ctx) байт в output из массива n указателей blocks. |
|
* Ненулевые буферы содержат block_size байт; NULL обозначает пропуск. |
|
* Проверяет одинаковый seq и subblock=i у всех присутствующих кодограмм. |
|
* Входные буферы не изменяются. При ошибке output не изменяется. |
|
*/ |
|
int rs_decode(struct rs_codec *ctx, const uint8_t *const blocks[], uint8_t *output); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif
|
|
|