Line | Count | Source |
1 | | /******************************************************************** |
2 | | * * |
3 | | * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. * |
4 | | * * |
5 | | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
6 | | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
7 | | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
8 | | * * |
9 | | * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 * |
10 | | * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ * |
11 | | * * |
12 | | ******************************************************************** |
13 | | |
14 | | function: miscellaneous math and prototypes |
15 | | |
16 | | ********************************************************************/ |
17 | | |
18 | | #ifndef _V_RANDOM_H_ |
19 | | #define _V_RANDOM_H_ |
20 | | #include "ivorbiscodec.h" |
21 | | #include "os.h" |
22 | | |
23 | | #ifdef _LOW_ACCURACY_ |
24 | | # define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9)) |
25 | | # define LOOKUP_T const unsigned char |
26 | | #else |
27 | | # define X(n) (n) |
28 | 117M | # define LOOKUP_T const ogg_int32_t |
29 | | #endif |
30 | | |
31 | | #include "asm_arm.h" |
32 | | #include <stdlib.h> /* for abs() */ |
33 | | |
34 | | #ifndef _V_WIDE_MATH |
35 | | #define _V_WIDE_MATH |
36 | | |
37 | | #ifndef _LOW_ACCURACY_ |
38 | | /* 64 bit multiply */ |
39 | | |
40 | | #if !(defined WIN32 && defined WINCE) |
41 | | #include <sys/types.h> |
42 | | #endif |
43 | | |
44 | | #if BYTE_ORDER==LITTLE_ENDIAN |
45 | | union magic { |
46 | | struct { |
47 | | ogg_int32_t lo; |
48 | | ogg_int32_t hi; |
49 | | } halves; |
50 | | ogg_int64_t whole; |
51 | | }; |
52 | | #endif |
53 | | |
54 | | #if BYTE_ORDER==BIG_ENDIAN |
55 | | union magic { |
56 | | struct { |
57 | | ogg_int32_t hi; |
58 | | ogg_int32_t lo; |
59 | | } halves; |
60 | | ogg_int64_t whole; |
61 | | }; |
62 | | #endif |
63 | | |
64 | 41.7G | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { |
65 | 41.7G | union magic magic; |
66 | 41.7G | magic.whole = (ogg_int64_t)x * y; |
67 | 41.7G | return magic.halves.hi; |
68 | 41.7G | } Unexecuted instantiation: vorbisfile.c:MULT32 Unexecuted instantiation: block.c:MULT32 Line | Count | Source | 64 | 82.9M | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { | 65 | 82.9M | union magic magic; | 66 | 82.9M | magic.whole = (ogg_int64_t)x * y; | 67 | 82.9M | return magic.halves.hi; | 68 | 82.9M | } |
Unexecuted instantiation: synthesis.c:MULT32 Unexecuted instantiation: info.c:MULT32 Unexecuted instantiation: registry.c:MULT32 Unexecuted instantiation: codebook.c:MULT32 Line | Count | Source | 64 | 16.8M | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { | 65 | 16.8M | union magic magic; | 66 | 16.8M | magic.whole = (ogg_int64_t)x * y; | 67 | 16.8M | return magic.halves.hi; | 68 | 16.8M | } |
Unexecuted instantiation: floor1.c:MULT32 Line | Count | Source | 64 | 413k | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { | 65 | 413k | union magic magic; | 66 | 413k | magic.whole = (ogg_int64_t)x * y; | 67 | 413k | return magic.halves.hi; | 68 | 413k | } |
Unexecuted instantiation: res012.c:MULT32 Unexecuted instantiation: mapping0.c:MULT32 Line | Count | Source | 64 | 41.6G | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { | 65 | 41.6G | union magic magic; | 66 | 41.6G | magic.whole = (ogg_int64_t)x * y; | 67 | 41.6G | return magic.halves.hi; | 68 | 41.6G | } |
|
69 | | |
70 | 38.2G | STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { |
71 | 38.2G | return MULT32(x,y)<<1; |
72 | 38.2G | } Unexecuted instantiation: vorbisfile.c:MULT31 Unexecuted instantiation: block.c:MULT31 Line | Count | Source | 70 | 82.9M | STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { | 71 | 82.9M | return MULT32(x,y)<<1; | 72 | 82.9M | } |
Unexecuted instantiation: synthesis.c:MULT31 Unexecuted instantiation: info.c:MULT31 Unexecuted instantiation: registry.c:MULT31 Unexecuted instantiation: codebook.c:MULT31 Unexecuted instantiation: sharedbook.c:MULT31 Unexecuted instantiation: floor1.c:MULT31 Unexecuted instantiation: floor0.c:MULT31 Unexecuted instantiation: res012.c:MULT31 Unexecuted instantiation: mapping0.c:MULT31 Line | Count | Source | 70 | 38.1G | STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { | 71 | 38.1G | return MULT32(x,y)<<1; | 72 | 38.1G | } |
|
73 | | |
74 | 12.5M | STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { |
75 | 12.5M | union magic magic; |
76 | 12.5M | magic.whole = (ogg_int64_t)x * y; |
77 | 12.5M | return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); |
78 | 12.5M | } Unexecuted instantiation: vorbisfile.c:MULT31_SHIFT15 Unexecuted instantiation: block.c:MULT31_SHIFT15 Unexecuted instantiation: window.c:MULT31_SHIFT15 Unexecuted instantiation: synthesis.c:MULT31_SHIFT15 Unexecuted instantiation: info.c:MULT31_SHIFT15 Unexecuted instantiation: registry.c:MULT31_SHIFT15 Unexecuted instantiation: codebook.c:MULT31_SHIFT15 Unexecuted instantiation: sharedbook.c:MULT31_SHIFT15 Line | Count | Source | 74 | 3.79M | STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { | 75 | 3.79M | union magic magic; | 76 | 3.79M | magic.whole = (ogg_int64_t)x * y; | 77 | 3.79M | return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); | 78 | 3.79M | } |
Line | Count | Source | 74 | 8.75M | STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { | 75 | 8.75M | union magic magic; | 76 | 8.75M | magic.whole = (ogg_int64_t)x * y; | 77 | 8.75M | return ((ogg_uint32_t)(magic.halves.lo)>>15) | ((magic.halves.hi)<<17); | 78 | 8.75M | } |
Unexecuted instantiation: res012.c:MULT31_SHIFT15 Unexecuted instantiation: mapping0.c:MULT31_SHIFT15 Unexecuted instantiation: mdct.c:MULT31_SHIFT15 |
79 | | |
80 | | #else |
81 | | /* 32 bit multiply, more portable but less accurate */ |
82 | | |
83 | | /* |
84 | | * Note: Precision is biased towards the first argument therefore ordering |
85 | | * is important. Shift values were chosen for the best sound quality after |
86 | | * many listening tests. |
87 | | */ |
88 | | |
89 | | /* |
90 | | * For MULT32 and MULT31: The second argument is always a lookup table |
91 | | * value already preshifted from 31 to 8 bits. We therefore take the |
92 | | * opportunity to save on text space and use unsigned char for those |
93 | | * tables in this case. |
94 | | */ |
95 | | |
96 | | STIN ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) { |
97 | | return (x >> 9) * y; /* y preshifted >>23 */ |
98 | | } |
99 | | |
100 | | STIN ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) { |
101 | | return (x >> 8) * y; /* y preshifted >>23 */ |
102 | | } |
103 | | |
104 | | STIN ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) { |
105 | | return (x >> 6) * y; /* y preshifted >>9 */ |
106 | | } |
107 | | |
108 | | #endif |
109 | | |
110 | | /* |
111 | | * This should be used as a memory barrier, forcing all cached values in |
112 | | * registers to wr writen back to memory. Might or might not be beneficial |
113 | | * depending on the architecture and compiler. |
114 | | */ |
115 | | #define MB() |
116 | | |
117 | | /* |
118 | | * The XPROD functions are meant to optimize the cross products found all |
119 | | * over the place in mdct.c by forcing memory operation ordering to avoid |
120 | | * unnecessary register reloads as soon as memory is being written to. |
121 | | * However this is only beneficial on CPUs with a sane number of general |
122 | | * purpose registers which exclude the Intel x86. On Intel, better let the |
123 | | * compiler actually reload registers directly from original memory by using |
124 | | * macros. |
125 | | */ |
126 | | |
127 | | #ifdef __i386__ |
128 | | |
129 | | #define XPROD32(_a, _b, _t, _v, _x, _y) \ |
130 | | { *(_x)=MULT32(_a,_t)+MULT32(_b,_v); \ |
131 | | *(_y)=MULT32(_b,_t)-MULT32(_a,_v); } |
132 | | #define XPROD31(_a, _b, _t, _v, _x, _y) \ |
133 | | { *(_x)=MULT31(_a,_t)+MULT31(_b,_v); \ |
134 | | *(_y)=MULT31(_b,_t)-MULT31(_a,_v); } |
135 | | #define XNPROD31(_a, _b, _t, _v, _x, _y) \ |
136 | | { *(_x)=MULT31(_a,_t)-MULT31(_b,_v); \ |
137 | | *(_y)=MULT31(_b,_t)+MULT31(_a,_v); } |
138 | | |
139 | | #else |
140 | | |
141 | | STIN void XPROD32(ogg_int32_t a, ogg_int32_t b, |
142 | | ogg_int32_t t, ogg_int32_t v, |
143 | | ogg_int32_t *x, ogg_int32_t *y) |
144 | 859M | { |
145 | 859M | *x = MULT32(a, t) + MULT32(b, v); |
146 | 859M | *y = MULT32(b, t) - MULT32(a, v); |
147 | 859M | } Unexecuted instantiation: vorbisfile.c:XPROD32 Unexecuted instantiation: block.c:XPROD32 Unexecuted instantiation: window.c:XPROD32 Unexecuted instantiation: synthesis.c:XPROD32 Unexecuted instantiation: info.c:XPROD32 Unexecuted instantiation: registry.c:XPROD32 Unexecuted instantiation: codebook.c:XPROD32 Unexecuted instantiation: sharedbook.c:XPROD32 Unexecuted instantiation: floor1.c:XPROD32 Unexecuted instantiation: floor0.c:XPROD32 Unexecuted instantiation: res012.c:XPROD32 Unexecuted instantiation: mapping0.c:XPROD32 Line | Count | Source | 144 | 859M | { | 145 | 859M | *x = MULT32(a, t) + MULT32(b, v); | 146 | 859M | *y = MULT32(b, t) - MULT32(a, v); | 147 | 859M | } |
|
148 | | |
149 | | STIN void XPROD31(ogg_int32_t a, ogg_int32_t b, |
150 | | ogg_int32_t t, ogg_int32_t v, |
151 | | ogg_int32_t *x, ogg_int32_t *y) |
152 | 5.46G | { |
153 | 5.46G | *x = MULT31(a, t) + MULT31(b, v); |
154 | 5.46G | *y = MULT31(b, t) - MULT31(a, v); |
155 | 5.46G | } Unexecuted instantiation: vorbisfile.c:XPROD31 Unexecuted instantiation: block.c:XPROD31 Unexecuted instantiation: window.c:XPROD31 Unexecuted instantiation: synthesis.c:XPROD31 Unexecuted instantiation: info.c:XPROD31 Unexecuted instantiation: registry.c:XPROD31 Unexecuted instantiation: codebook.c:XPROD31 Unexecuted instantiation: sharedbook.c:XPROD31 Unexecuted instantiation: floor1.c:XPROD31 Unexecuted instantiation: floor0.c:XPROD31 Unexecuted instantiation: res012.c:XPROD31 Unexecuted instantiation: mapping0.c:XPROD31 Line | Count | Source | 152 | 5.46G | { | 153 | 5.46G | *x = MULT31(a, t) + MULT31(b, v); | 154 | 5.46G | *y = MULT31(b, t) - MULT31(a, v); | 155 | 5.46G | } |
|
156 | | |
157 | | STIN void XNPROD31(ogg_int32_t a, ogg_int32_t b, |
158 | | ogg_int32_t t, ogg_int32_t v, |
159 | | ogg_int32_t *x, ogg_int32_t *y) |
160 | 3.75G | { |
161 | 3.75G | *x = MULT31(a, t) - MULT31(b, v); |
162 | 3.75G | *y = MULT31(b, t) + MULT31(a, v); |
163 | 3.75G | } Unexecuted instantiation: vorbisfile.c:XNPROD31 Unexecuted instantiation: block.c:XNPROD31 Unexecuted instantiation: window.c:XNPROD31 Unexecuted instantiation: synthesis.c:XNPROD31 Unexecuted instantiation: info.c:XNPROD31 Unexecuted instantiation: registry.c:XNPROD31 Unexecuted instantiation: codebook.c:XNPROD31 Unexecuted instantiation: sharedbook.c:XNPROD31 Unexecuted instantiation: floor1.c:XNPROD31 Unexecuted instantiation: floor0.c:XNPROD31 Unexecuted instantiation: res012.c:XNPROD31 Unexecuted instantiation: mapping0.c:XNPROD31 Line | Count | Source | 160 | 3.75G | { | 161 | 3.75G | *x = MULT31(a, t) - MULT31(b, v); | 162 | 3.75G | *y = MULT31(b, t) + MULT31(a, v); | 163 | 3.75G | } |
|
164 | | |
165 | | #endif |
166 | | |
167 | | #endif |
168 | | |
169 | | #ifndef _V_CLIP_MATH |
170 | | #define _V_CLIP_MATH |
171 | | |
172 | 2.80G | STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) { |
173 | 2.80G | int ret=x; |
174 | 2.80G | ret-= ((x<=32767)-1)&(x-32767); |
175 | 2.80G | ret-= ((x>=-32768)-1)&(x+32768); |
176 | 2.80G | return(ret); |
177 | 2.80G | } Line | Count | Source | 172 | 2.80G | STIN ogg_int32_t CLIP_TO_15(ogg_int32_t x) { | 173 | 2.80G | int ret=x; | 174 | 2.80G | ret-= ((x<=32767)-1)&(x-32767); | 175 | 2.80G | ret-= ((x>=-32768)-1)&(x+32768); | 176 | 2.80G | return(ret); | 177 | 2.80G | } |
Unexecuted instantiation: block.c:CLIP_TO_15 Unexecuted instantiation: window.c:CLIP_TO_15 Unexecuted instantiation: synthesis.c:CLIP_TO_15 Unexecuted instantiation: info.c:CLIP_TO_15 Unexecuted instantiation: registry.c:CLIP_TO_15 Unexecuted instantiation: codebook.c:CLIP_TO_15 Unexecuted instantiation: sharedbook.c:CLIP_TO_15 Unexecuted instantiation: floor1.c:CLIP_TO_15 Unexecuted instantiation: floor0.c:CLIP_TO_15 Unexecuted instantiation: res012.c:CLIP_TO_15 Unexecuted instantiation: mapping0.c:CLIP_TO_15 Unexecuted instantiation: mdct.c:CLIP_TO_15 |
178 | | |
179 | | #endif |
180 | | |
181 | | STIN ogg_int32_t VFLOAT_MULT(ogg_int32_t a,ogg_int32_t ap, |
182 | | ogg_int32_t b,ogg_int32_t bp, |
183 | 23.9M | ogg_int32_t *p){ |
184 | 23.9M | if(a && b){ |
185 | 16.8M | #ifndef _LOW_ACCURACY_ |
186 | 16.8M | *p=ap+bp+32; |
187 | 16.8M | return MULT32(a,b); |
188 | | #else |
189 | | *p=ap+bp+31; |
190 | | return (a>>15)*(b>>16); |
191 | | #endif |
192 | 16.8M | }else |
193 | 7.11M | return 0; |
194 | 23.9M | } Unexecuted instantiation: vorbisfile.c:VFLOAT_MULT Unexecuted instantiation: block.c:VFLOAT_MULT Unexecuted instantiation: window.c:VFLOAT_MULT Unexecuted instantiation: synthesis.c:VFLOAT_MULT Unexecuted instantiation: info.c:VFLOAT_MULT Unexecuted instantiation: registry.c:VFLOAT_MULT Unexecuted instantiation: codebook.c:VFLOAT_MULT Line | Count | Source | 183 | 23.9M | ogg_int32_t *p){ | 184 | 23.9M | if(a && b){ | 185 | 16.8M | #ifndef _LOW_ACCURACY_ | 186 | 16.8M | *p=ap+bp+32; | 187 | 16.8M | return MULT32(a,b); | 188 | | #else | 189 | | *p=ap+bp+31; | 190 | | return (a>>15)*(b>>16); | 191 | | #endif | 192 | 16.8M | }else | 193 | 7.11M | return 0; | 194 | 23.9M | } |
Unexecuted instantiation: floor1.c:VFLOAT_MULT Unexecuted instantiation: floor0.c:VFLOAT_MULT Unexecuted instantiation: res012.c:VFLOAT_MULT Unexecuted instantiation: mapping0.c:VFLOAT_MULT Unexecuted instantiation: mdct.c:VFLOAT_MULT |
195 | | |
196 | | int _ilog(unsigned int); |
197 | | |
198 | | STIN ogg_int32_t VFLOAT_MULTI(ogg_int32_t a,ogg_int32_t ap, |
199 | | ogg_int32_t i, |
200 | 23.9M | ogg_int32_t *p){ |
201 | | |
202 | 23.9M | int ip=_ilog(abs(i))-31; |
203 | 23.9M | return VFLOAT_MULT(a,ap,i<<-ip,ip,p); |
204 | 23.9M | } Unexecuted instantiation: vorbisfile.c:VFLOAT_MULTI Unexecuted instantiation: block.c:VFLOAT_MULTI Unexecuted instantiation: window.c:VFLOAT_MULTI Unexecuted instantiation: synthesis.c:VFLOAT_MULTI Unexecuted instantiation: info.c:VFLOAT_MULTI Unexecuted instantiation: registry.c:VFLOAT_MULTI Unexecuted instantiation: codebook.c:VFLOAT_MULTI sharedbook.c:VFLOAT_MULTI Line | Count | Source | 200 | 23.9M | ogg_int32_t *p){ | 201 | | | 202 | 23.9M | int ip=_ilog(abs(i))-31; | 203 | 23.9M | return VFLOAT_MULT(a,ap,i<<-ip,ip,p); | 204 | 23.9M | } |
Unexecuted instantiation: floor1.c:VFLOAT_MULTI Unexecuted instantiation: floor0.c:VFLOAT_MULTI Unexecuted instantiation: res012.c:VFLOAT_MULTI Unexecuted instantiation: mapping0.c:VFLOAT_MULTI Unexecuted instantiation: mdct.c:VFLOAT_MULTI |
205 | | |
206 | | STIN ogg_int32_t VFLOAT_ADD(ogg_int32_t a,ogg_int32_t ap, |
207 | | ogg_int32_t b,ogg_int32_t bp, |
208 | 47.9M | ogg_int32_t *p){ |
209 | | |
210 | 47.9M | if(!a){ |
211 | 11.1M | *p=bp; |
212 | 11.1M | return b; |
213 | 36.8M | }else if(!b){ |
214 | 6.73M | *p=ap; |
215 | 6.73M | return a; |
216 | 6.73M | } |
217 | | |
218 | | /* yes, this can leak a bit. */ |
219 | 30.1M | if(ap>bp){ |
220 | 21.3M | int shift=ap-bp+1; |
221 | 21.3M | *p=ap+1; |
222 | 21.3M | a>>=1; |
223 | 21.3M | if(shift<32){ |
224 | 16.6M | b=(b+(1<<(shift-1)))>>shift; |
225 | 16.6M | }else{ |
226 | 4.75M | b=0; |
227 | 4.75M | } |
228 | 21.3M | }else{ |
229 | 8.77M | int shift=bp-ap+1; |
230 | 8.77M | *p=bp+1; |
231 | 8.77M | b>>=1; |
232 | 8.77M | if(shift<32){ |
233 | 2.19M | a=(a+(1<<(shift-1)))>>shift; |
234 | 6.57M | }else{ |
235 | 6.57M | a=0; |
236 | 6.57M | } |
237 | 8.77M | } |
238 | | |
239 | 30.1M | a+=b; |
240 | 30.1M | if((a&0xc0000000)==0xc0000000 || |
241 | 30.1M | (a&0xc0000000)==0){ |
242 | 29.0M | a<<=1; |
243 | 29.0M | (*p)--; |
244 | 29.0M | } |
245 | 30.1M | return(a); |
246 | 47.9M | } Unexecuted instantiation: vorbisfile.c:VFLOAT_ADD Unexecuted instantiation: block.c:VFLOAT_ADD Unexecuted instantiation: window.c:VFLOAT_ADD Unexecuted instantiation: synthesis.c:VFLOAT_ADD Unexecuted instantiation: info.c:VFLOAT_ADD Unexecuted instantiation: registry.c:VFLOAT_ADD Unexecuted instantiation: codebook.c:VFLOAT_ADD Line | Count | Source | 208 | 47.9M | ogg_int32_t *p){ | 209 | | | 210 | 47.9M | if(!a){ | 211 | 11.1M | *p=bp; | 212 | 11.1M | return b; | 213 | 36.8M | }else if(!b){ | 214 | 6.73M | *p=ap; | 215 | 6.73M | return a; | 216 | 6.73M | } | 217 | | | 218 | | /* yes, this can leak a bit. */ | 219 | 30.1M | if(ap>bp){ | 220 | 21.3M | int shift=ap-bp+1; | 221 | 21.3M | *p=ap+1; | 222 | 21.3M | a>>=1; | 223 | 21.3M | if(shift<32){ | 224 | 16.6M | b=(b+(1<<(shift-1)))>>shift; | 225 | 16.6M | }else{ | 226 | 4.75M | b=0; | 227 | 4.75M | } | 228 | 21.3M | }else{ | 229 | 8.77M | int shift=bp-ap+1; | 230 | 8.77M | *p=bp+1; | 231 | 8.77M | b>>=1; | 232 | 8.77M | if(shift<32){ | 233 | 2.19M | a=(a+(1<<(shift-1)))>>shift; | 234 | 6.57M | }else{ | 235 | 6.57M | a=0; | 236 | 6.57M | } | 237 | 8.77M | } | 238 | | | 239 | 30.1M | a+=b; | 240 | 30.1M | if((a&0xc0000000)==0xc0000000 || | 241 | 30.1M | (a&0xc0000000)==0){ | 242 | 29.0M | a<<=1; | 243 | 29.0M | (*p)--; | 244 | 29.0M | } | 245 | 30.1M | return(a); | 246 | 47.9M | } |
Unexecuted instantiation: floor1.c:VFLOAT_ADD Unexecuted instantiation: floor0.c:VFLOAT_ADD Unexecuted instantiation: res012.c:VFLOAT_ADD Unexecuted instantiation: mapping0.c:VFLOAT_ADD Unexecuted instantiation: mdct.c:VFLOAT_ADD |
247 | | |
248 | | #endif |
249 | | |
250 | | |
251 | | |
252 | | |