69 lines
3.5 KiB
C
69 lines
3.5 KiB
C
/**
|
||
* 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
|