bool Payload::decode_symbol_table(SymbolTable & symtab) { if ( nsyms > 1024 ) { LOG_ERROR("Too many payloads\n"); return false; } /* * Add symbols representing the start and end of the payload's * text region. */ size_t buflen = strlen(name) + 7 + 1; char *buf = new char[buflen]; snprintf(buf, buflen, "%s._stext", name); symtab.insert(new Symbol(text_addr, 'T', buf)); snprintf(buf, buflen, "%s._etext", name); symtab.insert(new Symbol(text_end, 'T', buf)); SAFE_DELETE_ARRAY(buf); symtab.add_text_region(text_addr, text_end); for ( unsigned int i = 0; i < nsyms; i++ ) { symtab.insert(decode_symbol(symtab_ptr)); symtab_ptr += LIVEPATCH_symbol_sizeof; } return true; }
void decode_qtree_level(ezbc_subband_codec_t *codec, int l, int index) { int i; int x, y; int W, H; ezbc_point_t coord, *LIS_cur, *LIS_end, *LIS_end_old; ezbc_coeff_t **nodes; int **node_state = codec->node_state[l]; binary_model_t *node_models = &codec->context_models[codec->context_node[l].offset]; ezbc_byte_t *node_table = codec->context_node[l].table; binary_model_t *sign_models = &codec->context_models[codec->context_sign.offset]; ezbc_coeff_t threshold; int **child_node_state = NULL; /* for good measure */ int sig; if(codec->child_codec) child_node_state = codec->child_codec->node_state[l+1]; /* compare to this threshold to determine signifiance */ threshold = 1 << index; W = shift_ceil(codec->width, l-1); H = shift_ceil(codec->height, l-1); /* rescale sign models */ for(i = 0; i < codec->context_sign.count - 1; i++) binary_model_scale(sign_models[i]); LIS_cur = LIS_end = codec->LIS[l] - 1; LIS_end_old = codec->LIS_end[l]; nodes = codec->nodes[l]; while(LIS_cur < LIS_end_old){ coord = *(++LIS_cur); y = ezbc_coord_y(coord); x = ezbc_coord_x(coord); if(decode_symbol(codec, &node_models[node_table[node_state[y][x] & ZC_MASK]])) { update_zc_state(node_state, x, y); if(codec->child_codec) update_child_state(child_node_state, x, y); /* decode the significant node */ sig = decode_sig_node_child(codec, 2*x+0, 2*y+0, l - 1, index, 0); sig = decode_sig_node_child(codec, 2*x+1, 2*y+0, l - 1, index, sig); sig = decode_sig_node_child(codec, 2*x+0, 2*y+1, l - 1, index, sig); sig = decode_sig_node_child(codec, 2*x+1, 2*y+1, l - 1, index, sig); decode_LIS_stack(codec, index); } else { /* leave the node in the List of Insignificant Sets */ *++LIS_end = coord; } } codec->LIS_end[l] = LIS_end; codec->LSP_ids[EZBC_MSB - index][l] = codec->LSP_end; }
size_t huf_decode(file *f, symbol **data, huf_tree tree){ symbol_buffer buf; buf.size = 1024; buf.dataLength = 0; buf.buffer = NULL; int s = decode_symbol(f, tree); if(s==EOF) return 0; do{ if(s==EOF) die_format(); buffer_put(s, &buf); s = decode_symbol(f, tree); }while(s!=HUF_EOF); *data = buf.buffer; return buf.dataLength; }
void Compression::decomp() { //int symbol = 1; int ch; for ( cc = 255; cc-->0; ) { ff[cc].Fone = 1; ff[cc].Ftot = 2; } cc = 0; start_decoding(); if (ZATE == 1 && ZEND == 1 && VALUE == Half) { outd.w(-1); /* only a eof marker in file */ return; } if (VALUE < Half) { VALUE += Half; ch = 1; sw = 1; } else { sw = 0; ch = 1; } high = Top_value; low = Half - 1; ff[cc].Fone = 2; ff[cc].Ftot = 3; Zero_av = 1; cc = 2; for (;;) { /* Loop through characters. */ if (ZEND == 1 && ZATE == 1) { if ((VALUE == 0 && Zero_av == 1) || VALUE == Half) break; } if(outd.w(sw^ch) == -3) break; ch = decode_symbol(ff[cc]); if (ch == 1) ff[cc].Fone++; ff[cc].Ftot++; if ((sw^ch) == 0 ) { cc = 2 * cc + 1; } else { cc = 2 * cc + 2; } if (cc >= 255 ) cc = 0; /* cc = 0; */ } outd.w(-1); }
/* decode a significant node of the quad tree at coord x,y and level l */ int decode_sig_node_child(ezbc_subband_codec_t *codec, int x, int y, int l, int index, int sig) { int w, h; int ***node_state = codec->node_state; binary_model_t *sig_models = &codec->context_models[codec->context_sig[l].offset]; ezbc_byte_t *sig_table; ezbc_coeff_t threshold; int **child_node_state = NULL; /* for good measure */ if(codec->child_codec) child_node_state = codec->child_codec->node_state[l+1]; if(sig) sig_table = codec->context_jsig[4 * l + 3].table; else sig_table = codec->context_jsig[4 * l + (x & 1) + ((y & 1) << 1)].table; /* compare to this threshold to determine signifiance */ threshold = 1 << index; w = shift_ceil(codec->width, l); h = shift_ceil(codec->height, l); if(x < w && y < h) { /* last child need not be coded if all other children are insignificant then it is the one causing significance of its parent */ if(LAST_NSIG_IN_GROUP || decode_symbol(codec, &sig_models[sig_table[node_state[l][y][x] & ZC_MASK]])) { /* update zero coding state */ update_zc_state(node_state[l], x, y); if(codec->child_codec) update_child_state(child_node_state, x, y); /* add to the stack of insignificant sets */ codec->LIS_stack_top++; codec->LIS_stack_top->x = x; codec->LIS_stack_top->y = y; codec->LIS_stack_top->l = l; return(sig | 1); } else { /* add back to the list of insignificant nodes */ *(++codec->LIS_end[l]) = ezbc_point(x, y); return(sig); } } return(0); }
bool _try_next_context(const std::string &context, const kvpv &keys) { const auto info = symbol_info(context, keys); if (info[0] >= info[1]) { throw std::runtime_error("bad info for: " + context); } if (decode_symbol(info[0], info[1], info[2])) { _dst << context.back(); _current_context = context; _contexts.insert(_current_context); std::cerr << context << " fits!" << std::endl; return true; } return false; }
bool bar_decode_ascii(struct barcode *bc) { unsigned char code[BARCODE_ASCII_BYTES]; int i; int bit=0; for (i=0; i < BARCODE_ASCII_BYTES; i++) if (!decode_symbol(bc->ascii[i], &code[i])) { fprintf(stderr, "Decoding `%s' digit %u failed\n", bc->ascii, i); return false; } for (i=0; i < sizeof(bc->data); i++) bc->data[i] = pull_bits(code, &bit, 8); bc->checksum = pull_bits(code, &bit, BARCODE_CHECKSUM_BITS); return true; }
unsigned int do_deari(unsigned int insize) { in_size = (unsigned int)insize; in_pos = 0; deari_pos = 0; start_model(); /* Set up other modules. */ start_inputing_bits(); start_decoding(); for (;;) { /* Loop through characters. */ int ch; int symbol; symbol = decode_symbol(cum_freq); /* Decode next symbol. */ if (symbol==EOF_symbol) break; /* Exit loop if EOF symbol. */ ch = index_to_char[symbol]; /* Translate to a character.*/ deari[deari_pos++]=(unsigned char)ch; /* Write that character. */ update_model(symbol); /* Update the model. */ } return deari_pos; }
TEST(TestTraceLinearBlockDecoder, print) { typedef fifi::binary field_type; typedef kodo::full_rlnc_decoder<field_type, kodo::enable_trace> decoder_type; uint32_t symbols = 3; uint32_t symbol_size = 10; decoder_type::factory decoder_factory(symbols, symbol_size); auto decoder = decoder_factory.build(); // Check that this code compiles { std::stringstream out; decoder->print_decoder_state(out); std::string result = "000 ?: 0 0 0 \n" "001 ?: 0 0 0 \n" "002 ?: 0 0 0 \n"; EXPECT_EQ(result, out.str()); } // Create a empty symbol and put it in std::vector<uint8_t> coefficients( decoder->coefficient_vector_size(), '\0'); std::vector<uint8_t> symbol( decoder->symbol_size(), '\0'); decoder->decode_symbol(&symbol[0], &coefficients[0]); { std::stringstream out; decoder->print_decoder_state(out); std::string result = "000 ?: 0 0 0 \n" "001 ?: 0 0 0 \n" "002 ?: 0 0 0 \n"; EXPECT_EQ(result, out.str()); } // Create a dummy symbol and put it in std::fill(coefficients.begin(), coefficients.end(), '\0'); fifi::set_value<field_type>(&coefficients[0], 1, 1U); fifi::set_value<field_type>(&coefficients[0], 2, 1U); std::fill(symbol.begin(), symbol.end(), 'a'); decoder->decode_symbol(&symbol[0], &coefficients[0]); { std::stringstream out; decoder->print_decoder_state(out); std::string result = "000 ?: 0 0 0 \n" "001 C: 0 1 1 \n" "002 ?: 0 0 0 \n"; EXPECT_EQ(result, out.str()); } std::fill(symbol.begin(), symbol.end(), 'b'); decoder->decode_symbol(&symbol[0], 0U); { std::stringstream out; decoder->print_decoder_state(out); std::string result = "000 U: 1 0 0 \n" "001 C: 0 1 1 \n" "002 ?: 0 0 0 \n"; EXPECT_EQ(result, out.str()); } }
// thread function to wait for the decoders to finish decoding and // print output. Only used when decoding static void print_output (struct write_out_args args) { size_t bytes_left = args.bytes; size_t current_block = 0; uint16_t last_symbol = 0; std::unique_lock<std::mutex> lock (*args.mtx, std::defer_lock); while (*args.status == Out_Status::WORKING || *args.status == Out_Status::GRACEFUL_STOP) { lock.lock(); auto dec_it = args.decoders->find (current_block); if (dec_it == args.decoders->end()) { if (*args.status == Out_Status::GRACEFUL_STOP) { lock.unlock(); break; } args.cond->wait (lock); lock.unlock(); continue; } auto dec = dec_it->second.get(); if (!dec->can_decode()) { if (*args.status == Out_Status::GRACEFUL_STOP) { *args.status = Out_Status::ERROR; return; } args.cond->wait (lock); lock.unlock(); continue; } lock.unlock(); auto pair = dec->wait_sync(); if (pair.first == RaptorQ__v1::Error::NEED_DATA) { if (*args.status == Out_Status::GRACEFUL_STOP) { lock.lock(); if (dec->poll().first == RaptorQ__v1::Error::NONE) continue; *args.status = Out_Status::ERROR; return; } continue; } if (pair.first != RaptorQ__v1::Error::NONE) { // internal error or interrupted computation lock.lock(); *args.status = Out_Status::ERROR; return; } size_t sym_size = dec->symbol_size(); std::vector<uint8_t> buffer (sym_size);; for (; last_symbol < pair.second; ++last_symbol) { buffer.clear(); buffer.insert (buffer.begin(), sym_size, 0); auto buf_start = buffer.begin(); auto to_write = dec->decode_symbol (buf_start, buffer.end(), last_symbol); if (to_write != RaptorQ__v1::Error::NONE) { std::cerr << "ERR: partial or empty symbol from decoder\n"; lock.lock(); *args.status = Out_Status::ERROR; return; } size_t writes_left = std::min (bytes_left, static_cast<size_t> (sym_size)); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshorten-64-to-32" args.output->write (reinterpret_cast<char *> (buffer.data()), static_cast<int64_t> (writes_left)); #pragma clang diagnostic pop bytes_left -= writes_left; if (bytes_left == 0) { // early exit. we wrote everything. last_symbol = dec->symbols(); break; } } if (last_symbol == dec->symbols()) { lock.lock(); dec_it = args.decoders->find (current_block); dec_it->second.reset (nullptr); lock.unlock(); ++current_block; last_symbol = 0; } } lock.lock(); *args.status = Out_Status::EXITED; }
void decode_LSP_and_bit_index(ezbc_subband_codec_t *codec, int index) { ezbc_coord_t x, y; ezbc_point_t coord; ezbc_point_t *last, *sp; int LSP_plane = codec->LSP_plane; ezbc_point_t *LSP_mark = codec->LSP_mark; ezbc_point_t **LSP_bit_index_marks = codec->LSP_bit_index_marks; ezbc_point_t ***LSP_ids = codec->LSP_ids; int i; int depth = codec->depth; binary_model_t *LSP_models = &codec->context_models[codec->context_LSP.offset]; ezbc_byte_t *LSP_table = codec->context_LSP.table; int **base_state = codec->base_state; ezbc_coeff_t **coeffs = codec->nodes[0]; ezbc_coeff_t mag; int bit; int LSP_level; int LSP_offset; LSP_mark[LSP_plane] = codec->LSP_end - codec->LSP; LSP_bit_index_marks[EZBC_MSB - index] = codec->LSP_end; if(index < EZBC_MSB) { sp = LSP_bit_index_marks[EZBC_MSB - index - 1]; for(LSP_level = depth - 1; LSP_level > 1; LSP_level--) { last = LSP_ids[EZBC_MSB - index - 1][LSP_level - 1]; for(; sp > last; sp--) { coord = *sp; y = ezbc_coord_y(coord); x = ezbc_coord_x(coord); mag = (coeffs[y][x] & EZBC_ABS) >> index; LSP_offset = LSP_table[base_state[y][x]]; if(!vlc_is_leaf(codec, coeffs[y][x])) { /* decode refinement bit */ bit = decode_symbol(codec, &LSP_models[LSP_offset]); coeffs[y][x] |= bit << index; coeffs[y][x]++; /* increase the length */ } } /* scale LSP models */ for(i = 0; i < codec->context_LSP.count; i++) binary_model_scale(LSP_models[i]); } if(index < EZBC_MSB - 1) { /* from leaves ?? */ last = LSP_ids[EZBC_MSB - index - 1][0]; for(; sp > last; sp--) { coord = *sp; y = ezbc_coord_y(coord); x = ezbc_coord_x(coord); mag = (coeffs[y][x] & EZBC_ABS) >> index; LSP_offset = LSP_table[base_state[y][x]]; if(!vlc_is_leaf(codec, coeffs[y][x])) { /* decode refinement bit */ bit = decode_symbol(codec, &LSP_models[LSP_offset]); coeffs[y][x] |= bit << index; coeffs[y][x]++; /* increase the length */ } } /* scale LSP models */ for(i = 0; i < codec->context_LSP.count; i++) binary_model_scale(LSP_models[i]); last = LSP_bit_index_marks[EZBC_MSB - index - 2]; for(; sp > last; sp--) { coord = *sp; y = ezbc_coord_y(coord); x = ezbc_coord_x(coord); mag = (coeffs[y][x] & EZBC_ABS) >> index; LSP_offset = LSP_table[base_state[y][x]]; if(!vlc_is_leaf(codec, coeffs[y][x])) { /* decode refinement bit */ bit = decode_symbol(codec, &LSP_models[LSP_offset]); coeffs[y][x] |= bit << index; coeffs[y][x]++; /* increase the length */ } } }
/* decode the List of Insignificant Pixels */ void decode_LIP(ezbc_subband_codec_t *codec, int index) { int width = codec->width; int height = codec->height; int x, y; ezbc_point_t cur_coord; ezbc_coeff_t coeff; ezbc_coeff_t ***nodes = codec->nodes; ezbc_point_t *LIP_cur, *LIP_end, *LIP_old_end, *LIP; ezbc_point_t *LSP_end, *LSP; int **base_state = codec->base_state; binary_model_t *LIP_models = &codec->context_models[codec->context_LIP.offset]; ezbc_byte_t *LIP_context_table = codec->context_LIP.table; binary_model_t *sign_models = &codec->context_models[codec->context_sign.offset]; ezbc_byte_t *sign_context_table = codec->context_sign.table; int **sign_state = codec->sign_state; int sign_predict, sign_bit; ezbc_coeff_t threshold; int **child_node_state = NULL; /* for good measure */ int **child_base_state = NULL; if(codec->child_codec) { child_node_state = codec->child_codec->node_state[1]; child_base_state = codec->child_codec->base_state; } /* compare to this threshold to determine signifiance */ threshold = 1 << index; LIP = codec->LIP; LIP_cur = LIP_end = LIP + width * height; LIP_old_end = codec->LIP_end; LSP = codec->LSP; LSP_end = codec->LSP_end; while(LIP_cur != LIP_old_end){ cur_coord = *(--LIP_cur); x = ezbc_coord_x(cur_coord); y = ezbc_coord_y(cur_coord); coeff = nodes[0][y][x]; if(decode_symbol(codec, &LIP_models[LIP_context_table[base_state[y][x] & ZC_MASK]])) { /* coefficient is significant */ nodes[0][y][x] |= threshold; nodes[0][y][x] |= EZBC_MSB - index + 1; /* set the length */ if(++LSP_end == LIP_old_end) /* LSP_pos runs beyond the end of the LSP */ *(LIP_cur++) = *(LIP_old_end++); *LSP_end = cur_coord; /* update contexts */ update_zc_state(base_state, x, y); if(codec->child_codec) { update_child_state(child_node_state, x, y); update_child_state(child_base_state, 2*x+0, 2*y+0); /* predict */ update_child_state(child_base_state, 2*x+1, 2*y+0); /* children */ update_child_state(child_base_state, 2*x+0, 2*y+1); /* are */ update_child_state(child_base_state, 2*x+1, 2*y+1); /* significant */ } /* decode the sign */ sign_predict = sign_context_table[sign_state[y][x] & SC_MASK]; sign_bit = decode_symbol(codec, &sign_models[EZBC_SIGN_CONTEXT(sign_predict)]); sign_bit ^= EZBC_SIGN_PREDICTOR(sign_predict); update_sc_state(sign_state, x, y, sign_bit); if(sign_bit) nodes[0][y][x] |= EZBC_SIGN; } else { /* coefficient is still insignificant */ *(--LIP_end) = cur_coord; } } codec->LSP_end = LSP_end; codec->LIP_end = LIP_end; codec->LSP_ids[EZBC_MSB - index][0] = codec->LSP_end; }
/* decode leaves of the List of Insignificant Sets */ void decode_LIS_leaves(ezbc_subband_codec_t *codec, int index) { int i; int x, y; int W, H; ezbc_point_t cur_coord, *LIS_cur, *LIS_end, *LIS_end_old; ezbc_coeff_t **node; int **node_state; binary_model_t *sign_models; binary_model_t *leaf_models; ezbc_byte_t *leaf_table; ezbc_coeff_t threshold; int **child_node_state = NULL; /* for good measure */ int sig; if(codec->child_codec) child_node_state = codec->child_codec->node_state[2]; /* compare to this threshold to determine signifiance */ threshold = 1 << index; W = codec->width; H = codec->height; node_state = codec->node_state[1]; node = codec->nodes[1]; leaf_models = &codec->context_models[codec->context_node[1].offset]; leaf_table = codec->context_node[1].table; /* scale sign models */ sign_models = &codec->context_models[codec->context_sign.offset]; for(i = 0; i < codec->context_sign.count; i++) binary_model_scale(sign_models[i]); LIS_cur = LIS_end = codec->LIS[1] - 1; LIS_end_old = codec->LIS_end[1]; while(LIS_cur < LIS_end_old) { cur_coord = *(++LIS_cur); y = ezbc_coord_y(cur_coord); x = ezbc_coord_x(cur_coord); if(decode_symbol(codec, &leaf_models[leaf_table[node_state[y][x] & ZC_MASK]])) { /* update the zero coding state for that leaf */ update_zc_state(node_state, x, y); if(codec->child_codec) update_child_state(child_node_state, x, y); /* decode each coefficient of a significant leaf */ sig = decode_sig_leaf_coeff(codec, 2*x + 0, 2*y + 0, index, 0); sig = decode_sig_leaf_coeff(codec, 2*x + 1, 2*y + 0, index, sig); sig = decode_sig_leaf_coeff(codec, 2*x + 0, 2*y + 1, index, sig); sig = decode_sig_leaf_coeff(codec, 2*x + 1, 2*y + 1, index, sig); } else { /* add back to the end of List of Insignificant Sets */ *++LIS_end = cur_coord; } } codec->LIS_end[1] = LIS_end; codec->LSP_ids[EZBC_MSB - index][1] = codec->LSP_end; }
/* decode a significant leaf */ int decode_sig_leaf_coeff(ezbc_subband_codec_t *codec, int x, int y, int index, int sig) { int width = codec->width; int height = codec->height; int **base_state = codec->base_state; ezbc_coeff_t **coeffs = codec->nodes[0]; binary_model_t *sig_models = &codec->context_models[codec->context_sig[0].offset]; ezbc_byte_t *sig_table; binary_model_t *sign_models = &codec->context_models[codec->context_sign.offset]; ezbc_byte_t *sign_table = codec->context_sign.table; int **sign_state = codec->sign_state; int sign_predict, sign_bit; ezbc_coeff_t threshold; int **child_node_state = NULL; /* for good measure */ int **child_base_state = NULL; if(codec->child_codec) { child_node_state = codec->child_codec->node_state[1]; child_base_state = codec->child_codec->base_state; } if(sig) sig_table = codec->context_jsig[(x & 1) + ((y & 1) << 1)].table; else sig_table = codec->context_jsig[3].table; /* compare to this threshold to determine signifiance */ threshold = 1 << index; if(x < width && y < height) { /* last child need not be coded if all other children are insignificant then it is the one causing significance of its parent */ if(LAST_NSIG_IN_GROUP || decode_symbol(codec, &sig_models[sig_table[base_state[y][x] & ZC_MASK]])) { /* coefficient is significant */ coeffs[y][x] |= threshold; coeffs[y][x] |= EZBC_MSB - index + 1; /* set the length */ /* update the zero coding state */ update_zc_state(base_state, x, y); if(codec->child_codec) { update_child_state(child_node_state, x, y); update_child_state(child_base_state, 2*x+0, 2*y+0); /* predict */ update_child_state(child_base_state, 2*x+1, 2*y+0); /* children */ update_child_state(child_base_state, 2*x+0, 2*y+1); /* are */ update_child_state(child_base_state, 2*x+1, 2*y+1); /* significant */ } /* sign coding */ sign_predict = sign_table[sign_state[y][x] & SC_MASK]; sign_bit = decode_symbol(codec, &sign_models[EZBC_SIGN_CONTEXT(sign_predict)]); sign_bit ^= EZBC_SIGN_PREDICTOR(sign_predict); /* update the sign coding context */ update_sc_state(sign_state, x, y, sign_bit); if(sign_bit) coeffs[y][x] |= EZBC_SIGN; /* add to the List of Significant Pixels */ *++codec->LSP_end = ezbc_point(x, y); return(sig | 1); } else { /* add to the list of Insignificant Pixels */ *--codec->LIP_end = ezbc_point(x, y); return(sig); } } return(0); }
/// @example use_cached_symbol_decoder.cpp /// /// This example shows how to use the cached symbol decoder to "extract" /// the symbol coding coefficients and the encoded symbol data from an /// incoming symbol. int main() { // The finite field we will use in the example. You can try // with other fields by specifying e.g. fifi::binary8 for the // extension field 2^8 typedef fifi::binary finite_field; // Set the number of symbols (i.e. the generation size in RLNC // terminology) and the size of a symbol in bytes uint32_t symbols = 8; uint32_t symbol_size = 160; // Typdefs for the encoder/decoder type we wish to use typedef kodo::full_rlnc_encoder<finite_field> rlnc_encoder; typedef kodo::full_rlnc_decoder<finite_field> rlnc_decoder; typedef kodo::symbol_info_decoder<finite_field> rlnc_info_decoder; // In the following we will make an encoder/decoder factory. // The factories are used to build actual encoders/decoders. // Each stack we use have their own factories. rlnc_encoder::factory encoder_factory(symbols, symbol_size); auto encoder = encoder_factory.build(); rlnc_decoder::factory decoder_factory(symbols, symbol_size); auto decoder = decoder_factory.build(); rlnc_info_decoder::factory info_decoder_factory(symbols, symbol_size); auto info_decoder = info_decoder_factory.build(); // Allocate some storage for a "payload" the payload is what we would // eventually send over a network std::vector<uint8_t> payload(encoder->payload_size()); // Allocate some data to encode. In this case we make a buffer // with the same size as the encoder's block size (the max. // amount a single encoder can encode) std::vector<uint8_t> data_in(encoder->block_size()); // Just for fun - fill the data with random data for(auto &e: data_in) e = rand() % 256; // Assign the data buffer to the encoder so that we may start // to produce encoded symbols from it encoder->set_symbols(sak::storage(data_in)); while( !decoder->is_complete()) { // Encode a packet into the payload buffer encoder->encode( &payload[0] ); // Here we "simulate" a packet loss of approximately 50% // by dropping half of the encoded packets. // When running this example you will notice that the initial // symbols are received systematically (i.e. uncoded). After // sending all symbols once uncoded, the encoder will switch // to full coding, in which case you will see the full encoding // vectors being sent and received. if((rand() % 2) == 0) continue; // Pass the encoded packet to the info decoder. After this // information about the coded symbol can be fetched using the // cached_symbol_decoder API info_decoder->decode( &payload[0] ); if(!info_decoder->cached_symbol_coded()) { // The symbol was uncoded so we may ask the cache which of the // original symbols we have received. std::cout << "Symbol was uncoded, index = " << info_decoder->cached_symbol_index() << std::endl; // Now we pass the data directly into our actual decoder. This is // done using the "Codec API" directly, and not through the "Payload // API" as we would typically do. decoder->decode_symbol( info_decoder->cached_symbol_data(), info_decoder->cached_symbol_index()); } else { // The symbol was coded so we may ask the cache to return // the coding coefficients used to create the encoded symbol. std::cout << "Symbol was coded, encoding vector = "; const uint8_t* c = info_decoder->cached_symbol_coefficients(); // We loop through the coefficient buffer and print the coefficients for(uint32_t i = 0; i < info_decoder->symbols(); ++i) { std::cout << (uint32_t) fifi::get_value<finite_field>(c, i) << " "; } std::cout << std::endl; // Pass that packet to the decoder, as with the uncoded symbols // above we pass it directly to the "Codec API" decoder->decode_symbol(info_decoder->cached_symbol_data(), info_decoder->cached_symbol_coefficients()); } } // The decoder is complete, now copy the symbols from the decoder std::vector<uint8_t> data_out(decoder->block_size()); decoder->copy_symbols(sak::storage(data_out)); // Check we properly decoded the data if (std::equal(data_out.begin(), data_out.end(), data_in.begin())) { std::cout << "Data decoded correctly" << std::endl; } else { std::cout << "Unexpected failure to decode " << "please file a bug report :)" << std::endl; } }