rangecoder.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:3k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Range coder
  3.  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  */
  20.  
  21. /**
  22.  * @file rangecoder.h
  23.  * Range coder.
  24.  */
  25. typedef struct RangeCoder{
  26.     int low;
  27.     int range;
  28.     int outstanding_count;
  29.     int outstanding_byte;
  30.     uint8_t zero_state[256];
  31.     uint8_t  one_state[256];
  32.     uint8_t *bytestream_start;
  33.     uint8_t *bytestream;
  34.     uint8_t *bytestream_end;
  35. }RangeCoder;
  36. void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size);
  37. void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size);
  38. int ff_rac_terminate(RangeCoder *c);
  39. void ff_build_rac_states(RangeCoder *c, int factor, int max_p);
  40. static inline void renorm_encoder(RangeCoder *c){
  41.     //FIXME optimize
  42.     while(c->range < 0x100){
  43.         if(c->outstanding_byte < 0){
  44.             c->outstanding_byte= c->low>>8;
  45.         }else if(c->low <= 0xFF00){
  46.             *c->bytestream++ = c->outstanding_byte;
  47.             for(;c->outstanding_count; c->outstanding_count--)
  48.                 *c->bytestream++ = 0xFF;
  49.             c->outstanding_byte= c->low>>8;
  50.         }else if(c->low >= 0x10000){
  51.             *c->bytestream++ = c->outstanding_byte + 1;
  52.             for(;c->outstanding_count; c->outstanding_count--)
  53.                 *c->bytestream++ = 0x00;
  54.             c->outstanding_byte= (c->low>>8) & 0xFF;
  55.         }else{
  56.             c->outstanding_count++;
  57.         }
  58.         
  59.         c->low = (c->low & 0xFF)<<8;
  60.         c->range <<= 8;
  61.     }
  62. }
  63. static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){
  64.     int range1= (c->range * (*state)) >> 8;
  65.     assert(*state);
  66.     assert(range1 < c->range);
  67.     assert(range1 > 0);
  68.     if(!bit){
  69.         c->range -= range1;
  70.         *state= c->zero_state[*state];
  71.     }else{
  72.         c->low += c->range - range1;
  73.         c->range = range1;
  74.         *state= c->one_state[*state];
  75.     }
  76.     
  77.     renorm_encoder(c);
  78. }
  79. static inline void refill(RangeCoder *c){
  80.     if(c->range < 0x100){
  81.         c->range <<= 8;
  82.         c->low <<= 8;
  83.         if(c->bytestream < c->bytestream_end)
  84.             c->low+= c->bytestream[0];
  85.         c->bytestream++;
  86.     }
  87. }
  88. static inline int get_rac(RangeCoder *c, uint8_t * const state){
  89.     int range1= (c->range * (*state)) >> 8;
  90.     int attribute_unused one_mask;
  91.     
  92.     c->range -= range1;
  93. #if 1
  94.     if(c->low < c->range){
  95.         *state= c->zero_state[*state];
  96.         refill(c);
  97.         return 0;
  98.     }else{
  99.         c->low -= c->range;
  100.         *state= c->one_state[*state];
  101.         c->range = range1;
  102.         refill(c);
  103.         return 1;
  104.     }
  105. #else
  106.     one_mask= (c->range - c->low-1)>>31;
  107.     
  108.     c->low -= c->range & one_mask;
  109.     c->range += (range1 - c->range) & one_mask;
  110.     
  111.     *state= c->zero_state[(*state) + (256&one_mask)];
  112.     
  113.     refill(c);
  114.     return one_mask&1;
  115. #endif
  116. }