Ejemplo n.º 1
0
/** @brief After a character is decoded this is called to remove it from
 * the input.
 * @param symbol Symbol decoded 
 */
static void arith_code_remove_symbol (arith_code_symbol_t *symbol)
{
   int32_t range;

   // expand the range to account for removal
   range = (int32_t)(high - low) + 1;
   high = low + (uint16_t)((range * symbol->high_count) /
			   symbol->scale - 1);
   low = low + (uint16_t)((range * symbol->low_count) /
			  symbol->scale);

   for (;;) {
      if ((high & 0x8000) == (low & 0x8000)) {
	 // if msdigits match, bits will be shifted out below
      } else if ((low & 0x4000) == 0x4000 && (high & 0x4000) == 0) {
	 //underflow is looming shift out the 2nd msdigit
	 code ^= 0x4000;
	 low &= 0x3fff;
	 high |= 0x4000;
      } else {
	 // nothing can be shifted out, return
	 return;
      }

      low <<= 1;
      high <<= 1;
      high |= 1;
      code <<= 1;
      code += input_bit ();
   }
}
Ejemplo n.º 2
0
static int decode_symbol( int cum_freq[] )
{   long range;                 /* Size of current code region              */
    int cum;                    /* Cumulative frequency calculated          */
    int symbol;                 /* Symbol decoded                           */
    range = (long)(high-low)+1;
    cum = (int)                                 /* Find cum freq for value. */
      ((((long)(value-low)+1)*cum_freq[0]-1)/range);
    for (symbol = 1; cum_freq[symbol]>cum; symbol++) ; /* Then find symbol. */
    high = low +                                /* Narrow the code region   */
      (range*cum_freq[symbol-1])/cum_freq[0]-1; /* to that allotted to this */
    low = low +                                 /* symbol.                  */
      (range*cum_freq[symbol])/cum_freq[0];
    for (;;) {                                  /* Loop to get rid of bits. */
        if (high<Half) {
            /* nothing */                       /* Expand low half.         */
        }
        else if (low>=Half) {                   /* Expand high half.        */
            value -= Half;
            low -= Half;                        /* Subtract offset to top.  */
            high -= Half;
        }
        else if (low>=First_qtr                 /* Expand middle half.      */
              && high<Third_qtr) {
            value -= First_qtr;
            low -= First_qtr;                   /* Subtract offset to middle*/
            high -= First_qtr;
        }
        else break;                             /* Otherwise exit loop.     */
        low = 2*low;
        high = 2*high+1;                        /* Scale up code range.     */
        value = 2*value+input_bit();            /* Move in next input bit.  */
    }
    return symbol;
}
Ejemplo n.º 3
0
static void start_decoding( void )
{   int i;
    value = 0;                                  /* Input bits to fill the   */
    for (i = 1; i<=Code_value_bits; i++) {      /* code value.              */
        value = 2*value+input_bit();
    }
    low = 0;                                    /* Full code range.         */
    high = Top_value;
}
Ejemplo n.º 4
0
void Compression::start_decoding()
{
	int             i;
	VALUE = 0;
	ZEND = 0;
	ZATE = 1;
	for (i = 1; i <= Code_value_bits; i++) {	/* code value.              */
		VALUE = 2 * VALUE + input_bit();	/* Move in next input bit.  */
	}
}
Ejemplo n.º 5
0
/** @brief Initialize the decoding variables and read in 16 bits from input. */
static void arith_code_decode_init ()
{
   uint8_t i;

   code = 0;
   for (i = 0; i < 16; i++) {
      code <<= 1;
      code += input_bit ();
   }
   low = 0;
   high = 0xffff;
}
Ejemplo n.º 6
0
/*
 * This routine is called to initialize the state of the arithmetic
 * decoder.  This involves initializing the high and low registers
 * to their conventional starting values, plus reading the first
 * 16 bits from the input stream into the code value.
 */
void initialize_arithmetic_decoder( FILE *stream )
{
    int i;

    code = 0;
    for ( i = 0 ; i < 16 ; i++ )
    {
        code <<= 1;
        code += input_bit( stream );
    }
    low = 0;
    high = 0xffff;
}
Ejemplo n.º 7
0
/* DECODE THE NEXT SYMBOL. */
int Compression::decode_symbol(bij_2c ff)
{
	code_value      range;	/* Size of current code region              */
	int             symbol;	/* Symbol decoded                           */
	int             s1;
	range = (code_value) (high - low) + 1;	/* YEAH NO +1 */
	range = range / ff.Ftot;
	range = range * ff.Fone;
	range = high - range;
	if (VALUE >= range) {
		symbol = 1;
		low = range;
	} else {
		symbol = 0;
		high = range - 1;
	}
	ZATE = ((high < Half) || (low >= Half)) ? 1 : 0;
	s1 = 0;
	for (;;) {			/* Loop to get rid of bits. */
		if (high < Half) {
			/* nothing *//* Expand low half.         */
		} else if (low >= Half) {	/* Expand high half.        */
			Zero_av = 0;
			VALUE -= Half;
			low -= Half;		/* Subtract offset to top.  */
			high -= Half;
		} else if (low >= First_qtr	/* Expand middle half.      */
			&& high < Third_qtr) {
			Zero_av = 0;
			VALUE -= First_qtr;
			low -= First_qtr;	/* Subtract offset to middle */
			high -= First_qtr;
		} else
			break;			/* Otherwise exit loop.     */
		low = 2 * low;
		high = 2 * high + 1;	/* Scale up code range.     */
		s1 = 1;
		VALUE = 2 * VALUE + input_bit();	/* Move in next input bit.  */
	}
	if (ZATE == 1) {
		if (low == 0 && Zero_av == 0)
			Zero_av = 1;		/* only first time */
		else if (low > 0)
			Zero_av = 0;		/* available in future */
		else
			Zero_av = 2;		/* not available */
	} else if (s1 == 1)
		Zero_av = 0;
	return symbol;
}
Ejemplo n.º 8
0
/*
 * Just figuring out what the present symbol is doesn't remove
 * it from the input bit stream.  After the character has been
 * decoded, this routine has to be called to remove it from the
 * input stream.
 */
void remove_symbol_from_stream( FILE *stream, SYMBOL *s )
{
    long range;

/*
 * First, the range is expanded to account for the symbol removal.
 */
    range = (long)( high - low ) + 1;
    high = low + (unsigned short int)
                 (( range * s->high_count ) / s->scale - 1 );
    low = low + (unsigned short int)
                 (( range * s->low_count ) / s->scale );
/*
 * Next, any possible bits are shipped out.
 */
    for ( ; ; )
    {
/*
 * If the MSDigits match, the bits will be shifted out.
 */
        if ( ( high & 0x8000 ) == ( low & 0x8000 ) )
        {
        }
/*
 * Else, if underflow is threatining, shift out the 2nd MSDigit.
 */
        else if ((low & 0x4000) == 0x4000  && (high & 0x4000) == 0 )
        {
            code ^= 0x4000;
            low   &= 0x3fff;
            high  |= 0x4000;
        }
/*
 * Otherwise, nothing can be shifted out, so I return.
 */
        else
            return;
        low <<= 1;
        high <<= 1;
        high |= 1;
        code <<= 1;
        code += input_bit( stream );
    }
}
Ejemplo n.º 9
0
/*
 * Just figuring out what the present symbol is doesn't remove
 * it from the input bit stream.  After the character has been
 * decoded, this routine has to be called to remove it from the
 * input stream.
 */
void remove_symbol_from_stream( FILE *stream, SYMBOL *s )
{
    unsigned long long range;
    range = (unsigned long long) ( high-low ) + 1;
    high = SafeConvert(div128(mult128(range, s->high_count), s->scale).lo + low - 1);
    low = SafeConvert(div128(mult128(range, s->low_count), s->scale).lo + low);
/*
 * Next, any possible bits are shipped out.
 */
    for ( ; ; )
    {
/*
 * If the MSDigits match, the bits will be shifted out.
 */
        if ( ( high & LAST_BIT ) == ( low & LAST_BIT ) )
        {
        }
/*
 * Else, if underflow is threatining, shift out the 2nd MSDigit.
 */
        else if ((low & NEXT_TO_LAST_BIT) == NEXT_TO_LAST_BIT  && (high & NEXT_TO_LAST_BIT) == 0 )
        {
            code ^= NEXT_TO_LAST_BIT;
            low   &= NEXT_TO_LAST_BIT_MINUS_ONE;
            high  |= NEXT_TO_LAST_BIT;
        }
/*
 * Otherwise, nothing can be shifted out, so I return.
 */
        else
            return;
        low <<= 1;
        high <<= 1;
        high |= 1;
        code <<= 1;
        code += input_bit( stream );
    }
}