Пример #1
0
    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;
    }
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
/* 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);
}
Пример #6
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;
    }
Пример #7
0
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;
}
Пример #8
0
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());
    }
}
Пример #10
0
// 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;
}
Пример #11
0
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 */
	}
      }
    }
Пример #12
0
/* 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;
}
Пример #13
0
/* 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;
}
Пример #14
0
/* 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);
}
Пример #15
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;
    }
}