~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to adm_lavcodec/rangecoder.h

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
26
 
typedef struct RangeCoder{
27
 
    int low;
28
 
    int range;
29
 
    int outstanding_count;
30
 
    int outstanding_byte;
31
 
    uint8_t zero_state[256];
32
 
    uint8_t  one_state[256];
33
 
    uint8_t *bytestream_start;
34
 
    uint8_t *bytestream;
35
 
    uint8_t *bytestream_end;
36
 
}RangeCoder;
37
 
 
38
 
void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size);
39
 
void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size);
40
 
int ff_rac_terminate(RangeCoder *c);
41
 
void ff_build_rac_states(RangeCoder *c, int factor, int max_p);
42
 
 
43
 
static inline void renorm_encoder(RangeCoder *c){
44
 
    //FIXME optimize
45
 
    while(c->range < 0x100){
46
 
        if(c->outstanding_byte < 0){
47
 
            c->outstanding_byte= c->low>>8;
48
 
        }else if(c->low <= 0xFF00){
49
 
            *c->bytestream++ = c->outstanding_byte;
50
 
            for(;c->outstanding_count; c->outstanding_count--)
51
 
                *c->bytestream++ = 0xFF;
52
 
            c->outstanding_byte= c->low>>8;
53
 
        }else if(c->low >= 0x10000){
54
 
            *c->bytestream++ = c->outstanding_byte + 1;
55
 
            for(;c->outstanding_count; c->outstanding_count--)
56
 
                *c->bytestream++ = 0x00;
57
 
            c->outstanding_byte= (c->low>>8) & 0xFF;
58
 
        }else{
59
 
            c->outstanding_count++;
60
 
        }
61
 
 
62
 
        c->low = (c->low & 0xFF)<<8;
63
 
        c->range <<= 8;
64
 
    }
65
 
}
66
 
 
67
 
static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){
68
 
    int range1= (c->range * (*state)) >> 8;
69
 
 
70
 
    assert(*state);
71
 
    assert(range1 < c->range);
72
 
    assert(range1 > 0);
73
 
    if(!bit){
74
 
        c->range -= range1;
75
 
        *state= c->zero_state[*state];
76
 
    }else{
77
 
        c->low += c->range - range1;
78
 
        c->range = range1;
79
 
        *state= c->one_state[*state];
80
 
    }
81
 
 
82
 
    renorm_encoder(c);
83
 
}
84
 
 
85
 
static inline void refill(RangeCoder *c){
86
 
    if(c->range < 0x100){
87
 
        c->range <<= 8;
88
 
        c->low <<= 8;
89
 
        if(c->bytestream < c->bytestream_end)
90
 
            c->low+= c->bytestream[0];
91
 
        c->bytestream++;
92
 
    }
93
 
}
94
 
 
95
 
static inline int get_rac(RangeCoder *c, uint8_t * const state){
96
 
    int range1= (c->range * (*state)) >> 8;
97
 
    int attribute_unused one_mask;
98
 
 
99
 
    c->range -= range1;
100
 
#if 1
101
 
    if(c->low < c->range){
102
 
        *state= c->zero_state[*state];
103
 
        refill(c);
104
 
        return 0;
105
 
    }else{
106
 
        c->low -= c->range;
107
 
        *state= c->one_state[*state];
108
 
        c->range = range1;
109
 
        refill(c);
110
 
        return 1;
111
 
    }
112
 
#else
113
 
    one_mask= (c->range - c->low-1)>>31;
114
 
 
115
 
    c->low -= c->range & one_mask;
116
 
    c->range += (range1 - c->range) & one_mask;
117
 
 
118
 
    *state= c->zero_state[(*state) + (256&one_mask)];
119
 
 
120
 
    refill(c);
121
 
 
122
 
    return one_mask&1;
123
 
#endif
124
 
}
125