Beispiel #1
0
static void decode_rs(struct image_proc_ctx *ctx)
{
    struct image *fcx = ctx->ctx;
    int j, rv;
    uint8_t data[fcx->rs_n + fcx->roots];
    uint64_t i;

    assert(sizeof(data) == FEC_RSM);

    for (i = ctx->start; i < ctx->end; i += fcx->rs_n) {
        for (j = 0; j < fcx->rs_n; ++j) {
            data[j] = image_get_interleaved_byte(i + j, fcx);
        }

        memcpy(&data[fcx->rs_n], &fcx->fec[ctx->fec_pos], fcx->roots);
        rv = decode_rs_char(ctx->rs, data, NULL, 0);

        if (rv < 0) {
            FATAL("failed to recover [%" PRIu64 ", %" PRIu64 ")\n",
                i, i + fcx->rs_n);
        } else if (rv > 0) {
            /* copy corrected data to output */
            for (j = 0; j < fcx->rs_n; ++j) {
                image_set_interleaved_byte(i + j, fcx, data[j]);
            }

            ctx->rv += rv;
        }

        ctx->fec_pos += fcx->roots;
    }
}
Beispiel #2
0
//unsigned int
void fec_rs_decode(fec _q,
                   unsigned int _dec_msg_len,
                   unsigned char *_msg_enc,
                   unsigned char *_msg_dec)
{
    // validate input
    if (_dec_msg_len == 0) {
        fprintf(stderr,"error: fec_rs_encode(), input lenght must be > 0\n");
        exit(1);
    }

    // re-allocate resources if necessary
    fec_rs_setlength(_q, _dec_msg_len);

    // set erasures, error locations to zero
    memset(_q->errlocs,  0x00, _q->nn*sizeof(unsigned char));
    memset(_q->derrlocs, 0x00, _q->nn*sizeof(unsigned char));
    _q->erasures = 0;

    unsigned int i;
    unsigned int n0=0;
    unsigned int n1=0;
    unsigned int block_size = _q->dec_block_len;
    //int derrors; // number of decoder errors
    for (i=0; i<_q->num_blocks; i++) {

        // the last block is smaller by the residual block length
        if (i == _q->num_blocks-1)
            block_size -= _q->res_block_len;

        // copy sequence
        memmove(_q->tblock, &_msg_enc[n0], _q->enc_block_len*sizeof(unsigned char));

        // decode block
        //derrors = 
        decode_rs_char(_q->rs,
                       _q->tblock,
                       _q->derrlocs,
                       _q->erasures);

        // copy result
        memmove(&_msg_dec[n1], _q->tblock, block_size*sizeof(unsigned char));

        // increment counters
        n0 += _q->enc_block_len;
        n1 += block_size;
    }

    // sanity check
    assert( n0 == _q->num_enc_bytes );
    assert( n1 == _q->num_dec_bytes );
}
Beispiel #3
0
/**
 * @brief  XXX
 * @param  code
 * @param  sizeIdx
 * @param  fix
 * @return DMTX_SUCCESS | DMTX_FAILURE
 */
static int
DecodeCheckErrors(unsigned char *code, int sizeIdx, int fix)
{
   int i, j;
   int interleavedBlocks;
   int blockErrorWords;
   int blockTotalWords;
   int blockMaxCorrectable;
   struct rs *rs;
   int fixedErr, fixedErrSum;
   unsigned char data[255];

   interleavedBlocks = dmtxGetSymbolAttribute(DmtxSymAttribInterleavedBlocks, sizeIdx);
   blockErrorWords = dmtxGetSymbolAttribute(DmtxSymAttribBlockErrorWords, sizeIdx);
   blockTotalWords = dmtxGetSymbolAttribute(DmtxSymAttribBlockTotalWords, sizeIdx);
   blockMaxCorrectable = dmtxGetSymbolAttribute(DmtxSymAttribBlockMaxCorrectable, sizeIdx);

   rs = init_rs_char(blockErrorWords, 255 - blockTotalWords);
   if(rs == NULL)
      return DMTX_FAILURE;

   fixedErrSum = 0;
   for(i = 0; i < interleavedBlocks; i++) {

      for(j = 0; j < blockTotalWords; j++)
         data[j] = code[j*interleavedBlocks+i];

      fixedErr = decode_rs_char(rs, data, NULL, 0, fix);

      if(fixedErr < 0 || fixedErr > blockMaxCorrectable) {
         free_rs_char(rs);
         return DMTX_FAILURE;
      }

      fixedErrSum += fixedErr;

      for(j = 0; j < blockTotalWords; j++)
         code[j*interleavedBlocks+i] = data[j];
   }

   free_rs_char(rs);

   if(fix >= 0 && fixedErrSum > fix)
      return DMTX_FAILURE;

   return DMTX_SUCCESS;
}
int main(){
  unsigned char block[255];
  int i;
  void *rs;
  struct rusage start,finish;
  double extime;
  int trials = 10000;

  for(i=0;i<223;i++)
    block[i] = 0x01;

  rs = init_rs_char(8,0x187,112,11,32,0);
  encode_rs_char(rs,block,&block[223]);

  getrusage(RUSAGE_SELF,&start);
  for(i=0;i<trials;i++){
#if 0
    block[0] ^= 0xff; /* Introduce an error */
    block[2] ^= 0xff; /* Introduce an error */
#endif
    decode_rs_char(rs,block,NULL,0);
  }
  getrusage(RUSAGE_SELF,&finish);
  extime = finish.ru_utime.tv_sec - start.ru_utime.tv_sec + 1e-6*(finish.ru_utime.tv_usec - start.ru_utime.tv_usec);
  
  printf("Execution time for %d Reed-Solomon blocks using general decoder: %.2f sec\n",trials,extime);
  printf("decoder speed: %g bits/s\n",trials*223*8/extime);


  encode_rs_8(block,&block[223],0);
  getrusage(RUSAGE_SELF,&start);
  for(i=0;i<trials;i++){
#if 0
    block[0] ^= 0xff; /* Introduce an error */
    block[2] ^= 0xff; /* Introduce an error */
#endif
    decode_rs_8(block,NULL,0,0);
  }
  getrusage(RUSAGE_SELF,&finish);
  extime = finish.ru_utime.tv_sec - start.ru_utime.tv_sec + 1e-6*(finish.ru_utime.tv_usec - start.ru_utime.tv_usec);
  printf("Execution time for %d Reed-Solomon blocks using CCSDS decoder: %.2f sec\n",trials,extime);
  printf("decoder speed: %g bits/s\n",trials*223*8/extime);

  exit(0);
}
Beispiel #5
0
void test_char()
{
  int nn = 255;
  int roots = 8;
  int kk = nn - roots;
  int i;
  int r;
  int nerr = 0;
  unsigned char block[nn];
  unsigned char blocktmp[nn];
  int pad = 215;
  void *rs;

  printf("Using RS(%d, %d), it means words of %d 8-bit symbols and %d redundant symbols\n", nn, kk, kk - pad, roots);

  rs = init_rs_char(8, 0x187, 112, 11, roots, pad);

  memset(block, 0, nn);

  for (i = 0; i < kk - pad; ++i)
    block[i] = 'a' + i % 26;

  dump_buf("dump-before", block, nn);
  encode_rs_char(rs, block, &block[kk - pad]);
  dump_buf("dump-after", block, nn);

  do {
    nerr ++;
    memcpy(blocktmp, block, nn);
    for (i = 0; i < nerr; ++i)
      blocktmp[i] = ~blocktmp[i];
    if (nerr == 16)
      dump_buf("dump-decode-16-before", blocktmp, nn);
    r = decode_rs_char(rs, blocktmp, NULL, 0);
    if (nerr == 16)
      dump_buf("dump-decode-16-after", blocktmp, nn);
    printf("decode with %d bad symbols returns %d\n", nerr, r);
  } while (r >= 0 && nerr < 18);
}
Beispiel #6
0
int main(int argc, char *argv[]) {
    int i, len, l;
    char *str = NULL, strbuf[2*BFSIZE+1];
    FILE *fp = NULL;


    rs = init_rs_char( 8, 0x11d, 0, 1, R, 0); // fec.c

    rs_init_RS255(); // bch_ecc.c

    if (argc < 2) {
        fp = stdin;
        str = fgets(strbuf, 2*BFSIZE, fp);
    }
    else {
        str = argv[1];
    }

    while (str) {

        len = strlen(str)/2;
        if (len > BFSIZE) return -1;

        for (i = 0; i < BFSIZE; i++)  data[i] = 0;
        for (i = 0; i < N; i++) codeword1[i] = codeword2[i] = 0;

        for (i = 0; i < len; i++) {
            l = sscanf(str+2*i, "%2hhx", data+i);  if (l < 1) {/*len = i;*/}
        }

        cfg = detect(data, len);

        if ( cfg.typ == 92 ) {

            for (i = 0; i < cfg.msglen; i++) codeword1[K-1-i] = data[cfg.msgpos+i];
            for (i = 0; i < R; i++) codeword1[N-1-i] = data[cfg.parpos+i];

            for (i = 0; i < N; i++) cw1[i] = codeword1[N-1-i];

            errors1 = decode_rs_char(rs, codeword1, errpos1, 0);

            errs1 = rs_decode(cw1, err_pos1, err_val1);

            if (fp == NULL) {
                printf("RS%d\n", cfg.typ);
                printf("codeword\n");
                printf("errors: %d\n", errors1);
                if (errors1 > 0) {
                    printf("pos: ");
                    for (i = 0; i < errors1; i++) printf(" %d", errpos1[i]);
                    printf("\n");
                }
                for (i = 0; i < N; i++) printf("%02X", codeword1[i]); printf("\n");
                printf("frame:\n");
            }

            for (i = 0; i < cfg.hdrlen; i++) frame[i] = data[i];
            for (i = 0; i < cfg.msglen; i++) frame[cfg.msgpos+i] = codeword1[K-1-i];
            for (i = 0; i < R; i++)          frame[cfg.parpos+i] = codeword1[N-1-i];

            for (i = 0; i < cfg.frmlen; i++) printf("%02x", frame[i]); printf("\n");

            for (i = 0; i < N; i++) {
                if (cw1[i] != codeword1[N-1-i]) {
                    printf("diff[%3d]:  cw: %02x  codeword: %02x\n", i, cw1[i], codeword1[N-1-i]);
                }
            }
        }
        else
          if ( cfg.typ == 41 ) {

            for (i = 0; i < cfg.msglen; i++) {
                codeword1[K-1-i] = data[cfg.msgpos+  2*i];
                codeword2[K-1-i] = data[cfg.msgpos+1+2*i];
            }

            for (i = 0; i < R; i++) {
                codeword1[N-1-i] = data[cfg.parpos+  i];
                codeword2[N-1-i] = data[cfg.parpos+R+i];
            }

            for (i = 0; i < N; i++) cw1[i] = codeword1[N-1-i];
            for (i = 0; i < N; i++) cw2[i] = codeword2[N-1-i];

            errors1 = decode_rs_char(rs, codeword1, errpos1, 0);
            errors2 = decode_rs_char(rs, codeword2, errpos2, 0);

            errs1 = rs_decode(cw1, err_pos1, err_val1);
            errs2 = rs_decode(cw2, err_pos2, err_val2);

            if (fp == NULL) {
                printf("RS%d\n", cfg.typ);
                printf("codeword1\n");
                printf("errors: %d\n", errors1);
                if (errors1 > 0) {
                    printf("pos: ");
                    for (i = 0; i < errors1; i++) printf(" %d", errpos1[i]);
                    printf("\n");
                }
                for (i = 0; i < N; i++) printf("%02X", codeword1[i]); printf("\n");

                printf("codeword2\n");
                printf("errors: %d\n", errors2);
                if (errors2 > 0) {
                    printf("pos: ");
                    for (i = 0; i < errors2; i++) printf(" %d", errpos2[i]);
                    printf("\n");
                }
                for (i = 0; i < N; i++) printf("%02X", codeword2[i]); printf("\n");
                printf("frame:\n");
            }

            for (i = 0; i < cfg.hdrlen; i++) frame[i] = data[i];
            for (i = 0; i < R; i++) {
                frame[cfg.parpos+  i] = codeword1[N-1-i];
                frame[cfg.parpos+R+i] = codeword2[N-1-i];
            }
            for (i = 0; i < cfg.msglen; i++) {
                frame[cfg.msgpos+  2*i] = codeword1[K-1-i];
                frame[cfg.msgpos+1+2*i] = codeword2[K-1-i];
            }

            for (i = 0; i < cfg.frmlen; i++) printf("%02x", frame[i]); printf("\n");

            for (i = 0; i < N; i++) {
                if (cw1[i] != codeword1[N-1-i]) {
                    printf("diff[%3d]:  cw1: %02x  codeword1: %02x\n", i, cw1[i], codeword1[N-1-i]);
                }
            }
            for (i = 0; i < N; i++) {
                if (cw2[i] != codeword2[N-1-i]) {
                    printf("diff[%3d]:  cw2: %02x  codeword2: %02x\n", i, cw2[i], codeword2[N-1-i]);
                }
            }

        }

        if (fp) str = fgets(strbuf, 2*BFSIZE, fp);
        else    str = NULL;
    }


    return 0;
}
/* reads and decodes a single block starting from `offset', returns the number
   of bytes corrected in `errors' */
static int __ecc_read(fec_handle *f, void *rs, uint8_t *dest, uint64_t offset,
                      bool use_erasures, uint8_t *ecc_data, size_t *errors)
{
    check(offset % FEC_BLOCKSIZE == 0);
    ecc_info *e = &f->ecc;

    /* reverse interleaving: calculate the RS block that includes the requested
       offset */
    uint64_t rsb = offset - (offset / (e->rounds * FEC_BLOCKSIZE)) *
                   e->rounds * FEC_BLOCKSIZE;
    int data_index = -1;
    int erasures[e->rsn];
    int neras = 0;

    /* verity is required to check for erasures */
    check(!use_erasures || f->verity.hash);

    for (int i = 0; i < e->rsn; ++i) {
        uint64_t interleaved = fec_ecc_interleave(rsb * e->rsn + i, e->rsn,
                               e->rounds);

        if (interleaved == offset) {
            data_index = i;
        }

        /* copy raw data to reconstruct the RS block */
        uint8_t bbuf[FEC_BLOCKSIZE];

        if (unlikely(interleaved >= e->start) ||
                is_zero(f, interleaved)) {
            memset(bbuf, 0, FEC_BLOCKSIZE);
        } else {
            if (!raw_pread(f, bbuf, FEC_BLOCKSIZE, interleaved)) {
                error("failed to read: %s", strerror(errno));
                return -1;
            }

            if (use_erasures && neras <= e->roots &&
                    is_erasure(f, interleaved, bbuf)) {
                erasures[neras++] = i;
            }
        }

        for (int j = 0; j < FEC_BLOCKSIZE; ++j) {
            ecc_data[j * FEC_RSM + i] = bbuf[j];
        }
    }

    check(data_index >= 0);

    size_t nerrs = 0;
    uint8_t copy[FEC_RSM];

    for (int i = 0; i < FEC_BLOCKSIZE; ++i) {
        /* copy parity data */
        if (!raw_pread(f, &ecc_data[i * FEC_RSM + e->rsn], e->roots,
                       e->start + (i + rsb) * e->roots)) {
            error("failed to read ecc data: %s", strerror(errno));
            return -1;
        }

        /* for debugging decoding failures, because decode_rs_char can mangle
           ecc_data */
        if (unlikely(use_erasures)) {
            memcpy(copy, &ecc_data[i * FEC_RSM], FEC_RSM);
        }

        /* decode */
        int rc = decode_rs_char(rs, &ecc_data[i * FEC_RSM], erasures, neras);

        if (unlikely(rc < 0)) {
            if (use_erasures) {
                error("RS block %" PRIu64 ": decoding failed (%d erasures)",
                      rsb, neras);
                dump("raw RS block", rsb, copy, FEC_RSM);
            } else if (!f->verity.hash) {
                warn("RS block %" PRIu64 ": decoding failed", rsb);
            } else {
                debug("RS block %" PRIu64 ": decoding failed", rsb);
            }

            errno = EIO;
            return -1;
        } else if (unlikely(rc > 0)) {
            check(rc <= (use_erasures ? e->roots : e->roots / 2));
            nerrs += rc;
        }

        dest[i] = ecc_data[i * FEC_RSM + data_index];
    }

    if (nerrs) {
        warn("RS block %" PRIu64 ": corrected %zu errors", rsb, nerrs);
        *errors += nerrs;
    }

    return FEC_BLOCKSIZE;
}