Пример #1
0
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
                             opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{
    void *silk_dec;
    CELTDecoder *celt_dec;
    int i, silk_ret=0, celt_ret=0;
    ec_dec dec;
    opus_int32 silk_frame_size;
    int pcm_silk_size;
    VARDECL(opus_int16, pcm_silk);
    int pcm_transition_silk_size;
    VARDECL(opus_val16, pcm_transition_silk);
    int pcm_transition_celt_size;
    VARDECL(opus_val16, pcm_transition_celt);
    opus_val16 *pcm_transition=NULL;
    int redundant_audio_size;
    VARDECL(opus_val16, redundant_audio);

    int audiosize;
    int mode;
    int transition=0;
    int start_band;
    int redundancy=0;
    int redundancy_bytes = 0;
    int celt_to_silk=0;
    int c;
    int F2_5, F5, F10, F20;
    const opus_val16 *window;
    opus_uint32 redundant_rng = 0;
    int celt_accum;
    ALLOC_STACK;

    silk_dec = (char*)st+st->silk_dec_offset;
    celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
    F20 = st->Fs/50;
    F10 = F20>>1;
    F5 = F10>>1;
    F2_5 = F5>>1;
    if (frame_size < F2_5)
    {
        RESTORE_STACK;
        return OPUS_BUFFER_TOO_SMALL;
    }
    /* Limit frame_size to avoid excessive stack allocations. */
    frame_size = IMIN(frame_size, st->Fs/25*3);
    /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
    if (len<=1)
    {
        data = NULL;
        /* In that case, don't conceal more than what the ToC says */
        frame_size = IMIN(frame_size, st->frame_size);
    }
    if (data != NULL)
    {
        audiosize = st->frame_size;
        mode = st->mode;
        ec_dec_init(&dec,(unsigned char*)data,len);
    } else {
        audiosize = frame_size;
        mode = st->prev_mode;

        if (mode == 0)
        {
            /* If we haven't got any packet yet, all we can do is return zeros */
            for (i=0; i<audiosize*st->channels; i++)
                pcm[i] = 0;
            RESTORE_STACK;
            return audiosize;
        }

        /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),
           10, or 20 (e.g. 12.5 or 30 ms). */
        if (audiosize > F20)
        {
            do {
                int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
                if (ret<0)
                {
                    RESTORE_STACK;
                    return ret;
                }
                pcm += ret*st->channels;
                audiosize -= ret;
            } while (audiosize > 0);
            RESTORE_STACK;
            return frame_size;
        } else if (audiosize < F20)
        {
            if (audiosize > F10)
                audiosize = F10;
            else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
                audiosize = F5;
        }
    }

    /* In fixed-point, we can tell CELT to do the accumulation on top of the
       SILK PCM buffer. This saves some stack space. */
#ifdef FIXED_POINT
    celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
#else
    celt_accum = 0;
#endif

    pcm_transition_silk_size = ALLOC_NONE;
    pcm_transition_celt_size = ALLOC_NONE;
    if (data!=NULL && st->prev_mode > 0 && (
                (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
                || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
       )
    {
        transition = 1;
        /* Decide where to allocate the stack memory for pcm_transition */
        if (mode == MODE_CELT_ONLY)
            pcm_transition_celt_size = F5*st->channels;
        else
            pcm_transition_silk_size = F5*st->channels;
    }
    ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);
    if (transition && mode == MODE_CELT_ONLY)
    {
        pcm_transition = pcm_transition_celt;
        opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
    }
    if (audiosize > frame_size)
    {
        /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
        RESTORE_STACK;
        return OPUS_BAD_ARG;
    } else {
        frame_size = audiosize;
    }

    /* Don't allocate any memory when in CELT-only mode */
    pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
    ALLOC(pcm_silk, pcm_silk_size, opus_int16);

    /* SILK processing */
    if (mode != MODE_CELT_ONLY)
    {
        int lost_flag, decoded_samples;
        opus_int16 *pcm_ptr;
#ifdef FIXED_POINT
        if (celt_accum)
            pcm_ptr = pcm;
        else
#endif
            pcm_ptr = pcm_silk;

        if (st->prev_mode==MODE_CELT_ONLY)
            silk_InitDecoder( silk_dec );

        /* The SILK PLC cannot produce frames of less than 10 ms */
        st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);

        if (data != NULL)
        {
            st->DecControl.nChannelsInternal = st->stream_channels;
            if( mode == MODE_SILK_ONLY ) {
                if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
                    st->DecControl.internalSampleRate = 8000;
                } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
                    st->DecControl.internalSampleRate = 12000;
                } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
                    st->DecControl.internalSampleRate = 16000;
                } else {
                    st->DecControl.internalSampleRate = 16000;
                    silk_assert( 0 );
                }
            } else {
                /* Hybrid mode */
                st->DecControl.internalSampleRate = 16000;
            }
        }

        lost_flag = data == NULL ? 1 : 2 * decode_fec;
        decoded_samples = 0;
        do {
            /* Call SILK decoder */
            int first_frame = decoded_samples == 0;
            silk_ret = silk_Decode( silk_dec, &st->DecControl,
                                    lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
            if( silk_ret ) {
                if (lost_flag) {
                    /* PLC failure should not be fatal */
                    silk_frame_size = frame_size;
                    for (i=0; i<frame_size*st->channels; i++)
                        pcm_ptr[i] = 0;
                } else {
                    RESTORE_STACK;
                    return OPUS_INTERNAL_ERROR;
                }
            }
            pcm_ptr += silk_frame_size * st->channels;
            decoded_samples += silk_frame_size;
        } while( decoded_samples < frame_size );
    }

    start_band = 0;
    if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL
            && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len)
    {
        /* Check if we have a redundant 0-8 kHz band */
        if (mode == MODE_HYBRID)
            redundancy = ec_dec_bit_logp(&dec, 12);
        else
            redundancy = 1;
        if (redundancy)
        {
            celt_to_silk = ec_dec_bit_logp(&dec, 1);
            /* redundancy_bytes will be at least two, in the non-hybrid
               case due to the ec_tell() check above */
            redundancy_bytes = mode==MODE_HYBRID ?
                               (opus_int32)ec_dec_uint(&dec, 256)+2 :
                               len-((ec_tell(&dec)+7)>>3);
            len -= redundancy_bytes;
            /* This is a sanity check. It should never happen for a valid
               packet, so the exact behaviour is not normative. */
            if (len*8 < ec_tell(&dec))
            {
                len = 0;
                redundancy_bytes = 0;
                redundancy = 0;
            }
            /* Shrink decoder because of raw bits */
            dec.storage -= redundancy_bytes;
        }
    }
    if (mode != MODE_CELT_ONLY)
        start_band = 17;

    {
        int endband=21;

        switch(st->bandwidth)
        {
        case OPUS_BANDWIDTH_NARROWBAND:
            endband = 13;
            break;
        case OPUS_BANDWIDTH_MEDIUMBAND:
        case OPUS_BANDWIDTH_WIDEBAND:
            endband = 17;
            break;
        case OPUS_BANDWIDTH_SUPERWIDEBAND:
            endband = 19;
            break;
        case OPUS_BANDWIDTH_FULLBAND:
            endband = 21;
            break;
        }
        celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
        celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
    }

    if (redundancy)
    {
        transition = 0;
        pcm_transition_silk_size=ALLOC_NONE;
    }

    ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);

    if (transition && mode != MODE_CELT_ONLY)
    {
        pcm_transition = pcm_transition_silk;
        opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
    }

    /* Only allocation memory for redundancy if/when needed */
    redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
    ALLOC(redundant_audio, redundant_audio_size, opus_val16);

    /* 5 ms redundant frame for CELT->SILK*/
    if (redundancy && celt_to_silk)
    {
        celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
        celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
                            redundant_audio, F5, NULL, 0);
        celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
    }

    /* MUST be after PLC */
    celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));

    if (mode != MODE_SILK_ONLY)
    {
        int celt_frame_size = IMIN(F20, frame_size);
        /* Make sure to discard any previous CELT state */
        if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
            celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
        /* Decode CELT */
        celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
                                       len, pcm, celt_frame_size, &dec, celt_accum);
    } else {
        unsigned char silence[2] = {0xFF, 0xFF};
        if (!celt_accum)
        {
            for (i=0; i<frame_size*st->channels; i++)
                pcm[i] = 0;
        }
        /* For hybrid -> SILK transitions, we let the CELT MDCT
           do a fade-out by decoding a silence frame */
        if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
        {
            celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
            celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
        }
    }

    if (mode != MODE_CELT_ONLY && !celt_accum)
    {
#ifdef FIXED_POINT
        for (i=0; i<frame_size*st->channels; i++)
            pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
#else
        for (i=0; i<frame_size*st->channels; i++)
            pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
#endif
    }

    {
        const CELTMode *celt_mode;
        celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
        window = celt_mode->window;
    }

    /* 5 ms redundant frame for SILK->CELT */
    if (redundancy && !celt_to_silk)
    {
        celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
        celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));

        celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
        celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
        smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
                    pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
    }
    if (redundancy && celt_to_silk)
    {
        for (c=0; c<st->channels; c++)
        {
            for (i=0; i<F2_5; i++)
                pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
        }
        smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,
                    pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
    }
    if (transition)
    {
        if (audiosize >= F5)
        {
            for (i=0; i<st->channels*F2_5; i++)
                pcm[i] = pcm_transition[i];
            smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
                        pcm+st->channels*F2_5, F2_5,
                        st->channels, window, st->Fs);
        } else {
            /* Not enough time to do a clean transition, but we do it anyway
               This will not preserve amplitude perfectly and may introduce
               a bit of temporal aliasing, but it shouldn't be too bad and
               that's pretty much the best we can do. In any case, generating this
               transition it pretty silly in the first place */
            smooth_fade(pcm_transition, pcm,
                        pcm, F2_5,
                        st->channels, window, st->Fs);
        }
    }

    if(st->decode_gain)
    {
        opus_val32 gain;
        gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));
        for (i=0; i<frame_size*st->channels; i++)
        {
            opus_val32 x;
            x = MULT16_32_P16(pcm[i],gain);
            pcm[i] = SATURATE(x, 32767);
        }
    }

    if (len <= 1)
        st->rangeFinal = 0;
    else
        st->rangeFinal = dec.rng ^ redundant_rng;

    st->prev_mode = mode;
    st->prev_redundancy = redundancy && !celt_to_silk;

    if (celt_ret>=0)
    {
        if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels))
            OPUS_PRINT_INT(audiosize);
    }

    RESTORE_STACK;
    return celt_ret < 0 ? celt_ret : audiosize;

}
Пример #2
0
int main(int _argc,char **_argv){
  ec_enc         enc;
  ec_dec         dec;
  long           nbits;
  long           nbits2;
  double         entropy;
  int            ft;
  int            ftb;
  int            sz;
  int            i;
  int            ret;
  unsigned int   sym;
  unsigned int   seed;
  unsigned char *ptr;
  const char    *env_seed;
  ret=0;
  entropy=0;
    if (_argc > 2) {
	fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
	return 1;
    }
  env_seed = getenv("SEED");
  if (_argc > 1)
    seed = atoi(_argv[1]);
  else if (env_seed)
    seed = atoi(env_seed);
  else
    seed = time(NULL);
  /*Testing encoding of raw bit values.*/
  ptr = (unsigned char *)malloc(DATA_SIZE);
  ec_enc_init(&enc,ptr, DATA_SIZE);
  for(ft=2;ft<1024;ft++){
    for(i=0;i<ft;i++){
      entropy+=log(ft)*M_LOG2E;
      ec_enc_uint(&enc,i,ft);
    }
  }
  /*Testing encoding of raw bit values.*/
  for(ftb=1;ftb<16;ftb++){
    for(i=0;i<(1<<ftb);i++){
      entropy+=ftb;
      nbits=ec_tell(&enc);
      ec_enc_bits(&enc,i,ftb);
      nbits2=ec_tell(&enc);
      if(nbits2-nbits!=ftb){
        fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
         nbits2-nbits,ftb);
        ret=-1;
      }
    }
  }
  nbits=ec_tell_frac(&enc);
  ec_enc_done(&enc);
  fprintf(stderr,
   "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
   entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
  fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
  ec_dec_init(&dec,ptr,DATA_SIZE);
  for(ft=2;ft<1024;ft++){
    for(i=0;i<ft;i++){
      sym=ec_dec_uint(&dec,ft);
      if(sym!=(unsigned)i){
        fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
        ret=-1;
      }
    }
  }
  for(ftb=1;ftb<16;ftb++){
    for(i=0;i<(1<<ftb);i++){
      sym=ec_dec_bits(&dec,ftb);
      if(sym!=(unsigned)i){
        fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
        ret=-1;
      }
    }
  }
  nbits2=ec_tell_frac(&dec);
  if(nbits!=nbits2){
    fprintf(stderr,
     "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
     ldexp(nbits2,-3),ldexp(nbits,-3));
    ret=-1;
  }
  /*Testing an encoder bust prefers range coder data over raw bits.
    This isn't a general guarantee, will only work for data that is buffered in
     the encoder state and not yet stored in the user buffer, and should never
     get used in practice.
    It's mostly here for code coverage completeness.*/
  /*Start with a 16-bit buffer.*/
  ec_enc_init(&enc,ptr,2);
  /*Write 7 raw bits.*/
  ec_enc_bits(&enc,0x55,7);
  /*Write 12.3 bits of range coder data.*/
  ec_enc_uint(&enc,1,2);
  ec_enc_uint(&enc,1,3);
  ec_enc_uint(&enc,1,4);
  ec_enc_uint(&enc,1,5);
  ec_enc_uint(&enc,2,6);
  ec_enc_uint(&enc,6,7);
  ec_enc_done(&enc);
  ec_dec_init(&dec,ptr,2);
  if(!enc.error
   /*The raw bits should have been overwritten by the range coder data.*/
   ||ec_dec_bits(&dec,7)!=0x05
   /*And all the range coder data should have been encoded correctly.*/
   ||ec_dec_uint(&dec,2)!=1
   ||ec_dec_uint(&dec,3)!=1
   ||ec_dec_uint(&dec,4)!=1
   ||ec_dec_uint(&dec,5)!=1
   ||ec_dec_uint(&dec,6)!=2
   ||ec_dec_uint(&dec,7)!=6){
    fprintf(stderr,"Encoder bust overwrote range coder data with raw bits.\n");
    ret=-1;
  }
  srand(seed);
  fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
  for(i=0;i<409600;i++){
    unsigned *data;
    unsigned *tell;
    unsigned tell_bits;
    int       j;
    int zeros;
    ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
    data=(unsigned *)malloc(sz*sizeof(*data));
    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
    ec_enc_init(&enc,ptr,DATA_SIZE2);
    zeros = rand()%13==0;
    tell[0]=ec_tell_frac(&enc);
    for(j=0;j<sz;j++){
      if (zeros)
        data[j]=0;
      else
        data[j]=rand()%ft;
      ec_enc_uint(&enc,data[j],ft);
      tell[j+1]=ec_tell_frac(&enc);
    }
    if (rand()%2==0)
      while(ec_tell(&enc)%8 != 0)
        ec_enc_uint(&enc, rand()%2, 2);
    tell_bits = ec_tell(&enc);
    ec_enc_done(&enc);
    if(tell_bits!=(unsigned)ec_tell(&enc)){
      fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
       ec_tell(&enc),tell_bits,seed);
      ret=-1;
    }
    if ((tell_bits+7)/8 < ec_range_bytes(&enc))
    {
      fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
               ec_range_bytes(&enc), (tell_bits+7)/8,seed);
      ret=-1;
    }
    ec_dec_init(&dec,ptr,DATA_SIZE2);
    if(ec_tell_frac(&dec)!=tell[0]){
      fprintf(stderr,
       "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
       0,ec_tell_frac(&dec),tell[0],seed);
    }
    for(j=0;j<sz;j++){
      sym=ec_dec_uint(&dec,ft);
      if(sym!=data[j]){
        fprintf(stderr,
         "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
         sym,data[j],ft,j,sz,seed);
        ret=-1;
      }
      if(ec_tell_frac(&dec)!=tell[j+1]){
        fprintf(stderr,
         "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
         j+1,ec_tell_frac(&dec),tell[j+1],seed);
      }
    }
    free(tell);
    free(data);
  }
  /*Test compatibility between multiple different encode/decode routines.*/
  for(i=0;i<409600;i++){
    unsigned *logp1;
    unsigned *data;
    unsigned *tell;
    unsigned *enc_method;
    int       j;
    sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
    logp1=(unsigned *)malloc(sz*sizeof(*logp1));
    data=(unsigned *)malloc(sz*sizeof(*data));
    tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
    enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
    ec_enc_init(&enc,ptr,DATA_SIZE2);
    tell[0]=ec_tell_frac(&enc);
    for(j=0;j<sz;j++){
      data[j]=rand()/((RAND_MAX>>1)+1);
      logp1[j]=(rand()%15)+1;
      enc_method[j]=rand()/((RAND_MAX>>2)+1);
      switch(enc_method[j]){
        case 0:{
          ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
           (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
        }break;
        case 1:{
          ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
           (1<<logp1[j])-(data[j]?0:1),logp1[j]);
        }break;
        case 2:{
          ec_enc_bit_logp(&enc,data[j],logp1[j]);
        }break;
        case 3:{
          unsigned char icdf[2];
          icdf[0]=1;
          icdf[1]=0;
          ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
        }break;
      }
      tell[j+1]=ec_tell_frac(&enc);
    }
    ec_enc_done(&enc);
    if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
      fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
       ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
      ret=-1;
    }
    ec_dec_init(&dec,ptr,DATA_SIZE2);
    if(ec_tell_frac(&dec)!=tell[0]){
      fprintf(stderr,
       "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
       0,ec_tell_frac(&dec),tell[0],seed);
    }
    for(j=0;j<sz;j++){
      int fs;
      int dec_method;
      dec_method=rand()/((RAND_MAX>>2)+1);
      switch(dec_method){
        case 0:{
          fs=ec_decode(&dec,1<<logp1[j]);
          sym=fs>=(1<<logp1[j])-1;
          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
        }break;
        case 1:{
          fs=ec_decode_bin(&dec,logp1[j]);
          sym=fs>=(1<<logp1[j])-1;
          ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
           (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
        }break;
        case 2:{
          sym=ec_dec_bit_logp(&dec,logp1[j]);
        }break;
        case 3:{
          unsigned char icdf[2];
          icdf[0]=1;
          icdf[1]=0;
          sym=ec_dec_icdf(&dec,icdf,logp1[j]);
        }break;
      }
      if(sym!=data[j]){
        fprintf(stderr,
         "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
         sym,data[j],logp1[j],j,sz,seed);
        fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
         enc_method[j],dec_method);
        ret=-1;
      }
      if(ec_tell_frac(&dec)!=tell[j+1]){
        fprintf(stderr,
         "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
         j+1,ec_tell_frac(&dec),tell[j+1],seed);
      }
    }
    free(enc_method);
    free(tell);
    free(data);
    free(logp1);
  }
  ec_enc_init(&enc,ptr,DATA_SIZE2);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,0,2);
  ec_enc_patch_initial_bits(&enc,3,2);
  if(enc.error){
    fprintf(stderr,"patch_initial_bits failed");
    ret=-1;
  }
  ec_enc_patch_initial_bits(&enc,0,5);
  if(!enc.error){
    fprintf(stderr,"patch_initial_bits didn't fail when it should have");
    ret=-1;
  }
  ec_enc_done(&enc);
  if(ec_range_bytes(&enc)!=1||ptr[0]!=192){
    fprintf(stderr,"Got %d when expecting 192 for patch_initial_bits",ptr[0]);
    ret=-1;
  }
  ec_enc_init(&enc,ptr,DATA_SIZE2);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,0,1);
  ec_enc_bit_logp(&enc,1,6);
  ec_enc_bit_logp(&enc,0,2);
  ec_enc_patch_initial_bits(&enc,0,2);
  if(enc.error){
    fprintf(stderr,"patch_initial_bits failed");
    ret=-1;
  }
  ec_enc_done(&enc);
  if(ec_range_bytes(&enc)!=2||ptr[0]!=63){
    fprintf(stderr,"Got %d when expecting 63 for patch_initial_bits",ptr[0]);
    ret=-1;
  }
  ec_enc_init(&enc,ptr,2);
  ec_enc_bit_logp(&enc,0,2);
  for(i=0;i<48;i++){
    ec_enc_bits(&enc,0,1);
  }
  ec_enc_done(&enc);
  if(!enc.error){
    fprintf(stderr,"Raw bits overfill didn't fail when it should have");
    ret=-1;
  }
  ec_enc_init(&enc,ptr,2);
  for(i=0;i<17;i++){
    ec_enc_bits(&enc,0,1);
  }
  ec_enc_done(&enc);
  if(!enc.error){
    fprintf(stderr,"17 raw bits encoded in two bytes");
    ret=-1;
  }
  free(ptr);
  return ret;
}
Пример #3
0
int main(int _argc,char **_argv){
  ec_byte_buffer buf;
  ec_enc         enc;
  ec_dec         dec;
  long           nbits;
  long           nbits2;
  double         entropy;
  int            ft;
  int            ftb;
  int            sym;
  int            sz;
  int            i;
  int            ret;
  unsigned int   seed;
  ret=0;
  entropy=0;
  unsigned char *ptr;
    if (_argc > 2) {
	fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
	return 1;
    }
    if (_argc > 1)
	seed = atoi(_argv[1]);
    else
	seed = (time(NULL) ^ (getpid()%(1<<16) << 16));
  /*Testing encoding of raw bit values.*/
  ptr = malloc(DATA_SIZE);
  ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE);
  ec_enc_init(&enc,&buf);
  for(ft=2;ft<1024;ft++){
    for(i=0;i<ft;i++){
      entropy+=log(ft)*M_LOG2E;
      ec_enc_uint(&enc,i,ft);
    }
  }
  /*Testing encoding of raw bit values.*/
  for(ftb=0;ftb<16;ftb++){
    for(i=0;i<(1<<ftb);i++){
      entropy+=ftb;
      nbits=ec_enc_tell(&enc,0);
      ec_enc_bits(&enc,i,ftb);
      nbits2=ec_enc_tell(&enc,0);
      if(nbits2-nbits!=ftb){
        fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
         nbits2-nbits,ftb);
        ret=-1;
      }
    }
  }
  nbits=ec_enc_tell(&enc,4);
  ec_enc_done(&enc);
  fprintf(stderr,
   "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
   entropy,ldexp(nbits,-4),100*(nbits-ldexp(entropy,4))/nbits);
  fprintf(stderr,"Packed to %li bytes.\n",(long)(buf.ptr-buf.buf));
  ec_byte_readinit(&buf,ptr,DATA_SIZE);
  ec_dec_init(&dec,&buf);
  for(ft=2;ft<1024;ft++){
    for(i=0;i<ft;i++){
      sym=ec_dec_uint(&dec,ft);
      if(sym!=i){
        fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
        ret=-1;
      }
    }
  }
  for(ftb=0;ftb<16;ftb++){
    for(i=0;i<(1<<ftb);i++){
      sym=ec_dec_bits(&dec,ftb);
      if(sym!=i){
        fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
        ret=-1;
      }
    }
  }
  nbits2=ec_dec_tell(&dec,4);
  if(nbits!=nbits2){
    fprintf(stderr,
     "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
     ldexp(nbits2,-4),ldexp(nbits,-4));
    ret=-1;
  }
  ec_byte_writeclear(&buf);
  srand(seed);
  fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
  for(i=0;i<409600;i++){
    unsigned *data;
    int       j;
    int tell_bits;
    int zeros;
    ft=rand()/((RAND_MAX>>(rand()%11))+1)+10;
    sz=rand()/((RAND_MAX>>(rand()%9))+1);
    data=(unsigned *)malloc(sz*sizeof(*data));
    ec_byte_writeinit_buffer(&buf, ptr, DATA_SIZE2);
    ec_enc_init(&enc,&buf);
    zeros = rand()%13==0;
    for(j=0;j<sz;j++){
      if (zeros)
        data[j]=0;
      else
        data[j]=rand()%ft;
      ec_enc_uint(&enc,data[j],ft);
    }
    if (rand()%2==0)
      while(ec_enc_tell(&enc, 0)%8 != 0)
        ec_enc_uint(&enc, rand()%2, 2);
    tell_bits = ec_enc_tell(&enc, 0);
    ec_enc_done(&enc);
    if ((tell_bits+7)/8 < ec_byte_bytes(&buf))
    {
      fprintf (stderr, "tell() lied, there's %li bytes instead of %d (Random seed: %u)\n", 
               ec_byte_bytes(&buf), (tell_bits+7)/8,seed);
      ret=-1;
    }
    tell_bits -= 8*ec_byte_bytes(&buf);
    ec_byte_readinit(&buf,ptr,DATA_SIZE2);
    ec_dec_init(&dec,&buf);
    for(j=0;j<sz;j++){
      sym=ec_dec_uint(&dec,ft);
      if(sym!=data[j]){
        fprintf(stderr,
         "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
         sym,data[j],ft,j,sz,seed);
        ret=-1;
      }
    }
    ec_byte_writeclear(&buf);
    free(data);
  }
  free(ptr);
  return ret;
}