LCOV - code coverage report
Current view: top level - src - poporon.c (source / functions) Coverage Total Hit
Test: poporon Coverage Report Lines: 83.8 % 173 145
Test Date: 2026-03-07 15:16:43 Functions: 100.0 % 19 19
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * libpoporon - poporon.c
       3              :  *
       4              :  * This file is part of libpoporon.
       5              :  *
       6              :  * SPDX-License-Identifier: BSD-3-Clause
       7              :  */
       8              : 
       9              : #include <poporon.h>
      10              : 
      11              : #include "internal/common.h"
      12              : #include "internal/config.h"
      13              : #include "internal/ldpc.h"
      14              : #include "internal/rs.h"
      15              : 
      16           10 : static inline poporon_t *poporon_create_rs_internal(const poporon_config_t *cfg)
      17              : {
      18              :     poporon_t *pprn;
      19              :     poporon_rs_t *rs;
      20              : 
      21           10 :     if (cfg->params.rs.primitive_element == 0) {
      22            0 :         return NULL;
      23              :     }
      24              : 
      25           10 :     rs = poporon_rs_create(cfg->params.rs.symbol_size, cfg->params.rs.generator_polynomial,
      26           10 :                            cfg->params.rs.first_consecutive_root, cfg->params.rs.primitive_element,
      27           10 :                            cfg->params.rs.num_roots);
      28           10 :     if (!rs) {
      29            0 :         return NULL;
      30              :     }
      31              : 
      32           10 :     pprn = (poporon_t *)pcalloc(1, sizeof(poporon_t));
      33           10 :     if (!pprn) {
      34            0 :         poporon_rs_destroy(rs);
      35            0 :         return NULL;
      36              :     }
      37              : 
      38           10 :     pprn->fec_type = PPLN_FEC_RS;
      39           10 :     pprn->ctx.rs.rs = rs;
      40           10 :     pprn->ctx.rs.erasure = cfg->params.rs.erasure;
      41           10 :     pprn->ctx.rs.ext_syndrome = cfg->params.rs.syndrome;
      42           10 :     pprn->ctx.rs.last_corrected = 0;
      43              : 
      44           10 :     return pprn;
      45              : }
      46              : 
      47           12 : static inline poporon_t *poporon_create_ldpc_internal(const poporon_config_t *cfg)
      48              : {
      49              :     poporon_t *pprn;
      50              :     poporon_ldpc_params_t ldpc_params;
      51              :     poporon_ldpc_t *ldpc;
      52              : 
      53           12 :     ldpc_params.matrix_type = cfg->params.ldpc.matrix_type;
      54           12 :     ldpc_params.column_weight = cfg->params.ldpc.column_weight;
      55           12 :     ldpc_params.use_inner_interleave = cfg->params.ldpc.use_inner_interleave;
      56           12 :     ldpc_params.use_outer_interleave = cfg->params.ldpc.use_outer_interleave;
      57           12 :     ldpc_params.interleave_depth = cfg->params.ldpc.interleave_depth;
      58           12 :     ldpc_params.lifting_factor = cfg->params.ldpc.lifting_factor;
      59           12 :     ldpc_params.seed = cfg->params.ldpc.seed;
      60              : 
      61           12 :     ldpc = poporon_ldpc_create(cfg->params.ldpc.block_size, cfg->params.ldpc.rate, &ldpc_params);
      62           12 :     if (!ldpc) {
      63            0 :         return NULL;
      64              :     }
      65              : 
      66           12 :     pprn = (poporon_t *)pcalloc(1, sizeof(poporon_t));
      67           12 :     if (!pprn) {
      68            0 :         poporon_ldpc_destroy(ldpc);
      69            0 :         return NULL;
      70              :     }
      71              : 
      72           12 :     pprn->fec_type = PPLN_FEC_LDPC;
      73           12 :     pprn->ctx.ldpc.ldpc = ldpc;
      74           12 :     pprn->ctx.ldpc.soft_llr = cfg->params.ldpc.soft_llr;
      75           12 :     pprn->ctx.ldpc.soft_llr_size = cfg->params.ldpc.soft_llr_size;
      76           12 :     pprn->ctx.ldpc.use_soft_decode = cfg->params.ldpc.use_soft_decode;
      77           12 :     pprn->ctx.ldpc.max_iterations = cfg->params.ldpc.max_iterations;
      78           12 :     pprn->ctx.ldpc.last_iterations = 0;
      79              : 
      80           12 :     return pprn;
      81              : }
      82              : 
      83            2 : static inline poporon_t *poporon_create_bch_internal(const poporon_config_t *cfg)
      84              : {
      85              :     poporon_t *pprn;
      86              :     poporon_bch_t *bch;
      87              : 
      88            2 :     bch = poporon_bch_create(cfg->params.bch.symbol_size, cfg->params.bch.generator_polynomial,
      89            2 :                              cfg->params.bch.correction_capability);
      90            2 :     if (!bch) {
      91            0 :         return NULL;
      92              :     }
      93              : 
      94            2 :     pprn = (poporon_t *)pcalloc(1, sizeof(poporon_t));
      95            2 :     if (!pprn) {
      96            0 :         poporon_bch_destroy(bch);
      97            0 :         return NULL;
      98              :     }
      99              : 
     100            2 :     pprn->fec_type = PPLN_FEC_BCH;
     101            2 :     pprn->ctx.bch.bch = bch;
     102            2 :     pprn->ctx.bch.last_num_errors = 0;
     103              : 
     104            2 :     return pprn;
     105              : }
     106              : 
     107           26 : extern poporon_t *poporon_create(const poporon_config_t *config)
     108              : {
     109           26 :     if (!config) {
     110            2 :         return NULL;
     111              :     }
     112              : 
     113           24 :     switch (config->fec_type) {
     114           10 :     case PPLN_FEC_RS:
     115           10 :         return poporon_create_rs_internal(config);
     116           12 :     case PPLN_FEC_LDPC:
     117           12 :         return poporon_create_ldpc_internal(config);
     118            2 :     case PPLN_FEC_BCH:
     119            2 :         return poporon_create_bch_internal(config);
     120            0 :     default:
     121            0 :         return NULL;
     122              :     }
     123              : }
     124              : 
     125           25 : extern void poporon_destroy(poporon_t *pprn)
     126              : {
     127           25 :     if (!pprn) {
     128            1 :         return;
     129              :     }
     130              : 
     131           24 :     switch (pprn->fec_type) {
     132           10 :     case PPLN_FEC_RS:
     133           10 :         poporon_rs_destroy(pprn->ctx.rs.rs);
     134           10 :         break;
     135           12 :     case PPLN_FEC_LDPC:
     136           12 :         poporon_ldpc_destroy(pprn->ctx.ldpc.ldpc);
     137           12 :         break;
     138            2 :     case PPLN_FEC_BCH:
     139            2 :         poporon_bch_destroy(pprn->ctx.bch.bch);
     140            2 :         break;
     141            0 :     case PPLN_FEC_UNKNOWN:
     142              :     default:
     143            0 :         break;
     144              :     }
     145              : 
     146           24 :     pfree(pprn);
     147              : 
     148           24 :     return;
     149              : }
     150              : 
     151           10 : extern poporon_config_t *poporon_rs_config_create(uint8_t symbol_size, uint16_t generator_polynomial,
     152              :                                                   uint16_t first_consecutive_root, uint16_t primitive_element,
     153              :                                                   uint8_t num_roots, poporon_erasure_t *erasure, uint16_t *syndrome)
     154              : {
     155           10 :     poporon_config_t *config = (poporon_config_t *)pcalloc(1, sizeof(poporon_config_t));
     156           10 :     if (!config) {
     157            0 :         return NULL;
     158              :     }
     159              : 
     160           10 :     config->fec_type = PPLN_FEC_RS;
     161           10 :     config->params.rs.symbol_size = symbol_size;
     162           10 :     config->params.rs.generator_polynomial = generator_polynomial;
     163           10 :     config->params.rs.first_consecutive_root = first_consecutive_root;
     164           10 :     config->params.rs.primitive_element = primitive_element;
     165           10 :     config->params.rs.num_roots = num_roots;
     166           10 :     config->params.rs.erasure = erasure;
     167           10 :     config->params.rs.syndrome = syndrome;
     168              : 
     169           10 :     return config;
     170              : }
     171              : 
     172           12 : extern poporon_config_t *poporon_ldpc_config_create(size_t block_size, poporon_ldpc_rate_t rate,
     173              :                                                     poporon_ldpc_matrix_type_t matrix_type, uint32_t column_weight,
     174              :                                                     bool use_soft_decode, bool use_outer_interleave,
     175              :                                                     bool use_inner_interleave, uint32_t interleave_depth,
     176              :                                                     uint32_t lifting_factor, uint32_t max_iterations,
     177              :                                                     const int8_t *soft_llr, size_t soft_llr_size, uint64_t seed)
     178              : {
     179           12 :     poporon_config_t *config = (poporon_config_t *)pcalloc(1, sizeof(poporon_config_t));
     180           12 :     if (!config) {
     181            0 :         return NULL;
     182              :     }
     183              : 
     184           12 :     config->fec_type = PPLN_FEC_LDPC;
     185           12 :     config->params.ldpc.block_size = block_size;
     186           12 :     config->params.ldpc.rate = rate;
     187           12 :     config->params.ldpc.matrix_type = matrix_type;
     188           12 :     config->params.ldpc.column_weight = column_weight;
     189           12 :     config->params.ldpc.use_soft_decode = use_soft_decode;
     190           12 :     config->params.ldpc.use_outer_interleave = use_outer_interleave;
     191           12 :     config->params.ldpc.use_inner_interleave = use_inner_interleave;
     192           12 :     config->params.ldpc.interleave_depth = interleave_depth;
     193           12 :     config->params.ldpc.lifting_factor = lifting_factor;
     194           12 :     config->params.ldpc.max_iterations = max_iterations;
     195           12 :     config->params.ldpc.soft_llr = soft_llr;
     196           12 :     config->params.ldpc.soft_llr_size = soft_llr_size;
     197           12 :     config->params.ldpc.seed = seed;
     198              : 
     199           12 :     return config;
     200              : }
     201              : 
     202            2 : extern poporon_config_t *poporon_bch_config_create(uint8_t symbol_size, uint16_t generator_polynomial,
     203              :                                                    uint8_t correction_capability)
     204              : {
     205            2 :     poporon_config_t *config = (poporon_config_t *)pcalloc(1, sizeof(poporon_config_t));
     206            2 :     if (!config) {
     207            0 :         return NULL;
     208              :     }
     209              : 
     210            2 :     config->fec_type = PPLN_FEC_BCH;
     211            2 :     config->params.bch.symbol_size = symbol_size;
     212            2 :     config->params.bch.generator_polynomial = generator_polynomial;
     213            2 :     config->params.bch.correction_capability = correction_capability;
     214              : 
     215            2 :     return config;
     216              : }
     217              : 
     218            5 : extern poporon_config_t *poporon_config_rs_default(void)
     219              : {
     220            5 :     return poporon_rs_config_create(8, 0x11D, 1, 1, 32, NULL, NULL);
     221              : }
     222              : 
     223            5 : extern poporon_config_t *poporon_config_ldpc_default(size_t block_size, poporon_ldpc_rate_t rate)
     224              : {
     225            5 :     return poporon_ldpc_config_create(block_size, rate, PPRN_LDPC_RANDOM, 3, true, true, true, 0, 0, 0, NULL, 0, 0);
     226              : }
     227              : 
     228            1 : extern poporon_config_t *poporon_config_ldpc_burst_resistant(size_t block_size, poporon_ldpc_rate_t rate)
     229              : {
     230            1 :     return poporon_ldpc_config_create(block_size, rate, PPRN_LDPC_RANDOM, 7, true, true, true, 0, 0, 0, NULL, 0, 0);
     231              : }
     232              : 
     233            2 : extern poporon_config_t *poporon_config_bch_default(void)
     234              : {
     235            2 :     return poporon_bch_config_create(4, 0x13, 3);
     236              : }
     237              : 
     238           24 : extern void poporon_config_destroy(poporon_config_t *config)
     239              : {
     240           24 :     pfree(config);
     241           24 : }
     242              : 
     243            5 : extern poporon_fec_type_t poporon_get_fec_type(const poporon_t *pprn)
     244              : {
     245            5 :     if (!pprn) {
     246            0 :         return PPLN_FEC_UNKNOWN;
     247              :     }
     248              : 
     249            5 :     return pprn->fec_type;
     250              : }
     251              : 
     252            1 : extern uint32_t poporon_get_iterations_used(const poporon_t *pprn)
     253              : {
     254            1 :     if (!pprn || pprn->fec_type != PPLN_FEC_LDPC) {
     255            0 :         return 0;
     256              :     }
     257              : 
     258            1 :     return pprn->ctx.ldpc.last_iterations;
     259              : }
     260              : 
     261           12 : extern size_t poporon_get_parity_size(const poporon_t *pprn)
     262              : {
     263              :     uint16_t cw, data;
     264              : 
     265           12 :     if (!pprn) {
     266            0 :         return 0;
     267              :     }
     268              : 
     269           12 :     switch (pprn->fec_type) {
     270            1 :     case PPLN_FEC_RS:
     271            1 :         return pprn->ctx.rs.rs->num_roots;
     272           11 :     case PPLN_FEC_LDPC:
     273           11 :         return poporon_ldpc_parity_size(pprn->ctx.ldpc.ldpc);
     274            0 :     case PPLN_FEC_BCH:
     275            0 :         cw = poporon_bch_get_codeword_length(pprn->ctx.bch.bch);
     276            0 :         data = poporon_bch_get_data_length(pprn->ctx.bch.bch);
     277            0 :         return (size_t)(cw - data + 7) / 8;
     278            0 :     default:
     279            0 :         return 0;
     280              :     }
     281              : }
     282              : 
     283            7 : extern size_t poporon_get_info_size(const poporon_t *pprn)
     284              : {
     285            7 :     if (!pprn) {
     286            1 :         return 0;
     287              :     }
     288              : 
     289            6 :     switch (pprn->fec_type) {
     290            2 :     case PPLN_FEC_RS:
     291            2 :         return (size_t)(pprn->ctx.rs.rs->gf->field_size - pprn->ctx.rs.rs->num_roots);
     292            2 :     case PPLN_FEC_LDPC:
     293            2 :         return poporon_ldpc_info_size(pprn->ctx.ldpc.ldpc);
     294            2 :     case PPLN_FEC_BCH:
     295            2 :         return (size_t)(poporon_bch_get_data_length(pprn->ctx.bch.bch) + 7) / 8;
     296            0 :     default:
     297            0 :         return 0;
     298              :     }
     299              : }
     300              : 
     301            1 : extern uint32_t poporon_version_id(void)
     302              : {
     303            1 :     return (uint32_t)POPORON_VERSION_ID;
     304              : }
     305              : 
     306            1 : extern poporon_buildtime_t poporon_buildtime(void)
     307              : {
     308            1 :     return (poporon_buildtime_t)POPORON_BUILDTIME;
     309              : }
        

Generated by: LCOV version 2.0-1