Mercurial > libavcodec.hg
annotate rangecoder.c @ 10311:943b63f364ca libavcodec
Make sure all the bits are written to output in fax data decoder.
This fixes decoding TIFF images with fax compression and width being not
multiple of eight (and issue 1429).
author | kostya |
---|---|
date | Tue, 29 Sep 2009 05:55:14 +0000 |
parents | 2313bf51945b |
children | 7dd2a45249a9 |
rev | line source |
---|---|
2334 | 1 /* |
2 * Range coder | |
3 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2334 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2334 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2334 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3184
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2334 | 20 */ |
2967 | 21 |
2334 | 22 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
6169
diff
changeset
|
23 * @file libavcodec/rangecoder.c |
2334 | 24 * Range coder. |
25 * based upon | |
26 * "Range encoding: an algorithm for removing redundancy from a digitised | |
27 * message. | |
28 * G. N. N. Martin Presented in March 1979 to the Video & | |
29 * Data Recording Conference, | |
30 * IBM UK Scientific Center held in Southampton July 24-27 1979." | |
31 * | |
32 */ | |
33 | |
34 #include <string.h> | |
35 | |
36 #include "avcodec.h" | |
37 #include "rangecoder.h" | |
5089 | 38 #include "bytestream.h" |
2334 | 39 |
40 | |
41 void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){ | |
2967 | 42 c->bytestream_start= |
2334 | 43 c->bytestream= buf; |
44 c->bytestream_end= buf + buf_size; | |
45 | |
46 c->low= 0; | |
47 c->range= 0xFF00; | |
48 c->outstanding_count= 0; | |
49 c->outstanding_byte= -1; | |
50 } | |
51 | |
52 void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){ | |
2864
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2522
diff
changeset
|
53 /* cast to avoid compiler warning */ |
95bac7109ff0
Kill some compiler warnings. Compiled code verified identical after changes.
mru
parents:
2522
diff
changeset
|
54 ff_init_range_encoder(c, (uint8_t *) buf, buf_size); |
2334 | 55 |
5089 | 56 c->low = bytestream_get_be16(&c->bytestream); |
2334 | 57 } |
58 | |
59 void ff_build_rac_states(RangeCoder *c, int factor, int max_p){ | |
60 const int64_t one= 1LL<<32; | |
61 int64_t p; | |
2522
e25782262d7d
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
2334
diff
changeset
|
62 int last_p8, p8, i; |
2334 | 63 |
64 memset(c->zero_state, 0, sizeof(c->zero_state)); | |
65 memset(c-> one_state, 0, sizeof(c-> one_state)); | |
66 | |
67 last_p8= 0; | |
68 p= one/2; | |
69 for(i=0; i<128; i++){ | |
70 p8= (256*p + one/2) >> 32; //FIXME try without the one | |
71 if(p8 <= last_p8) p8= last_p8+1; | |
72 if(last_p8 && last_p8<256 && p8<=max_p) | |
73 c->one_state[last_p8]= p8; | |
2967 | 74 |
2334 | 75 p+= ((one-p)*factor + one/2) >> 32; |
76 last_p8= p8; | |
77 } | |
4410 | 78 |
2334 | 79 for(i=256-max_p; i<=max_p; i++){ |
2967 | 80 if(c->one_state[i]) |
2334 | 81 continue; |
82 | |
83 p= (i*one + 128) >> 8; | |
84 p+= ((one-p)*factor + one/2) >> 32; | |
85 p8= (256*p + one/2) >> 32; //FIXME try without the one | |
86 if(p8 <= i) p8= i+1; | |
87 if(p8 > max_p) p8= max_p; | |
88 c->one_state[ i]= p8; | |
89 } | |
2967 | 90 |
3184
68d7896a08e4
fixing out of array access (only cosmetic, this should never have had a end user vissible effect)
michael
parents:
3036
diff
changeset
|
91 for(i=1; i<255; i++) |
2334 | 92 c->zero_state[i]= 256-c->one_state[256-i]; |
93 } | |
94 | |
95 /** | |
96 * | |
97 * @return the number of bytes written | |
98 */ | |
99 int ff_rac_terminate(RangeCoder *c){ | |
100 c->range=0xFF; | |
101 c->low +=0xFF; | |
102 renorm_encoder(c); | |
103 c->range=0xFF; | |
104 renorm_encoder(c); | |
105 | |
106 assert(c->low == 0); | |
107 assert(c->range >= 0x100); | |
108 | |
109 return c->bytestream - c->bytestream_start; | |
110 } | |
111 | |
6164
ecaf5226e9b0
Consistently use TEST as the preprocessor condition to enable test code.
diego
parents:
5934
diff
changeset
|
112 #ifdef TEST |
2334 | 113 #define SIZE 10240 |
9199
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
8718
diff
changeset
|
114 |
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
8718
diff
changeset
|
115 #include "libavutil/lfg.h" |
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
8718
diff
changeset
|
116 |
5934 | 117 int main(void){ |
2334 | 118 RangeCoder c; |
119 uint8_t b[9*SIZE]; | |
120 uint8_t r[9*SIZE]; | |
121 int i; | |
122 uint8_t state[10]= {0}; | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9199
diff
changeset
|
123 AVLFG prng; |
9199
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
8718
diff
changeset
|
124 |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9199
diff
changeset
|
125 av_lfg_init(&prng, 1); |
2967 | 126 |
2334 | 127 ff_init_range_encoder(&c, b, SIZE); |
128 ff_build_rac_states(&c, 0.05*(1LL<<32), 128+64+32+16); | |
2967 | 129 |
2334 | 130 memset(state, 128, sizeof(state)); |
131 | |
132 for(i=0; i<SIZE; i++){ | |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9199
diff
changeset
|
133 r[i] = av_lfg_get(&prng) % 7; |
2334 | 134 } |
2967 | 135 |
2334 | 136 for(i=0; i<SIZE; i++){ |
137 START_TIMER | |
138 put_rac(&c, state, r[i]&1); | |
139 STOP_TIMER("put_rac") | |
140 } | |
141 | |
6169
43dd78019c14
Add #undef random and call the right function to fix test program compilation.
diego
parents:
6164
diff
changeset
|
142 ff_rac_terminate(&c); |
2967 | 143 |
2334 | 144 ff_init_range_decoder(&c, b, SIZE); |
2967 | 145 |
2334 | 146 memset(state, 128, sizeof(state)); |
2967 | 147 |
2334 | 148 for(i=0; i<SIZE; i++){ |
149 START_TIMER | |
150 if( (r[i]&1) != get_rac(&c, state) ) | |
151 av_log(NULL, AV_LOG_DEBUG, "rac failure at %d\n", i); | |
152 STOP_TIMER("get_rac") | |
153 } | |
2967 | 154 |
2334 | 155 return 0; |
156 } | |
6164
ecaf5226e9b0
Consistently use TEST as the preprocessor condition to enable test code.
diego
parents:
5934
diff
changeset
|
157 #endif /* TEST */ |