Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> | ||
3 | * | ||
4 | * This file is part of FFmpeg. | ||
5 | * | ||
6 | * FFmpeg is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU Lesser General Public | ||
8 | * License as published by the Free Software Foundation; either | ||
9 | * version 2.1 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * FFmpeg is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with FFmpeg; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file | ||
23 | * common internal and external API header | ||
24 | */ | ||
25 | |||
26 | #ifndef AVUTIL_COMMON_H | ||
27 | #define AVUTIL_COMMON_H | ||
28 | |||
29 | #if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) | ||
30 | #error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS | ||
31 | #endif | ||
32 | |||
33 | #include <errno.h> | ||
34 | #include <inttypes.h> | ||
35 | #include <limits.h> | ||
36 | #include <math.h> | ||
37 | #include <stdint.h> | ||
38 | #include <stdio.h> | ||
39 | #include <stdlib.h> | ||
40 | #include <string.h> | ||
41 | |||
42 | #include "attributes.h" | ||
43 | #include "error.h" | ||
44 | #include "macros.h" | ||
45 | |||
46 | #ifdef HAVE_AV_CONFIG_H | ||
47 | # include "config.h" | ||
48 | # include "intmath.h" | ||
49 | # include "internal.h" | ||
50 | #else | ||
51 | # include "mem.h" | ||
52 | #endif /* HAVE_AV_CONFIG_H */ | ||
53 | |||
54 | //rounded division & shift | ||
55 | #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) | ||
56 | /* assume b>0 */ | ||
57 | #define ROUNDED_DIV(a,b) (((a)>=0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) | ||
58 | /* Fast a/(1<<b) rounded toward +inf. Assume a>=0 and b>=0 */ | ||
59 | #define AV_CEIL_RSHIFT(a,b) (!av_builtin_constant_p(b) ? -((-(a)) >> (b)) \ | ||
60 | : ((a) + (1<<(b)) - 1) >> (b)) | ||
61 | /* Backwards compat. */ | ||
62 | #define FF_CEIL_RSHIFT AV_CEIL_RSHIFT | ||
63 | |||
64 | #define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) | ||
65 | #define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) | ||
66 | |||
67 | /** | ||
68 | * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they | ||
69 | * are not representable as absolute values of their type. This is the same | ||
70 | * as with *abs() | ||
71 | * @see FFNABS() | ||
72 | */ | ||
73 | #define FFABS(a) ((a) >= 0 ? (a) : (-(a))) | ||
74 | #define FFSIGN(a) ((a) > 0 ? 1 : -1) | ||
75 | |||
76 | /** | ||
77 | * Negative Absolute value. | ||
78 | * this works for all integers of all types. | ||
79 | * As with many macros, this evaluates its argument twice, it thus must not have | ||
80 | * a sideeffect, that is FFNABS(x++) has undefined behavior. | ||
81 | */ | ||
82 | #define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) | ||
83 | |||
84 | /** | ||
85 | * Unsigned Absolute value. | ||
86 | * This takes the absolute value of a signed int and returns it as a unsigned. | ||
87 | * This also works with INT_MIN which would otherwise not be representable | ||
88 | * As with many macros, this evaluates its argument twice. | ||
89 | */ | ||
90 | #define FFABSU(a) ((a) <= 0 ? -(unsigned)(a) : (unsigned)(a)) | ||
91 | #define FFABS64U(a) ((a) <= 0 ? -(uint64_t)(a) : (uint64_t)(a)) | ||
92 | |||
93 | /* misc math functions */ | ||
94 | |||
95 | #ifndef av_ceil_log2 | ||
96 | # define av_ceil_log2 av_ceil_log2_c | ||
97 | #endif | ||
98 | #ifndef av_clip | ||
99 | # define av_clip av_clip_c | ||
100 | #endif | ||
101 | #ifndef av_clip64 | ||
102 | # define av_clip64 av_clip64_c | ||
103 | #endif | ||
104 | #ifndef av_clip_uint8 | ||
105 | # define av_clip_uint8 av_clip_uint8_c | ||
106 | #endif | ||
107 | #ifndef av_clip_int8 | ||
108 | # define av_clip_int8 av_clip_int8_c | ||
109 | #endif | ||
110 | #ifndef av_clip_uint16 | ||
111 | # define av_clip_uint16 av_clip_uint16_c | ||
112 | #endif | ||
113 | #ifndef av_clip_int16 | ||
114 | # define av_clip_int16 av_clip_int16_c | ||
115 | #endif | ||
116 | #ifndef av_clipl_int32 | ||
117 | # define av_clipl_int32 av_clipl_int32_c | ||
118 | #endif | ||
119 | #ifndef av_clip_intp2 | ||
120 | # define av_clip_intp2 av_clip_intp2_c | ||
121 | #endif | ||
122 | #ifndef av_clip_uintp2 | ||
123 | # define av_clip_uintp2 av_clip_uintp2_c | ||
124 | #endif | ||
125 | #ifndef av_mod_uintp2 | ||
126 | # define av_mod_uintp2 av_mod_uintp2_c | ||
127 | #endif | ||
128 | #ifndef av_sat_add32 | ||
129 | # define av_sat_add32 av_sat_add32_c | ||
130 | #endif | ||
131 | #ifndef av_sat_dadd32 | ||
132 | # define av_sat_dadd32 av_sat_dadd32_c | ||
133 | #endif | ||
134 | #ifndef av_sat_sub32 | ||
135 | # define av_sat_sub32 av_sat_sub32_c | ||
136 | #endif | ||
137 | #ifndef av_sat_dsub32 | ||
138 | # define av_sat_dsub32 av_sat_dsub32_c | ||
139 | #endif | ||
140 | #ifndef av_sat_add64 | ||
141 | # define av_sat_add64 av_sat_add64_c | ||
142 | #endif | ||
143 | #ifndef av_sat_sub64 | ||
144 | # define av_sat_sub64 av_sat_sub64_c | ||
145 | #endif | ||
146 | #ifndef av_clipf | ||
147 | # define av_clipf av_clipf_c | ||
148 | #endif | ||
149 | #ifndef av_clipd | ||
150 | # define av_clipd av_clipd_c | ||
151 | #endif | ||
152 | #ifndef av_popcount | ||
153 | # define av_popcount av_popcount_c | ||
154 | #endif | ||
155 | #ifndef av_popcount64 | ||
156 | # define av_popcount64 av_popcount64_c | ||
157 | #endif | ||
158 | #ifndef av_parity | ||
159 | # define av_parity av_parity_c | ||
160 | #endif | ||
161 | |||
162 | #ifndef av_log2 | ||
163 | av_const int av_log2(unsigned v); | ||
164 | #endif | ||
165 | |||
166 | #ifndef av_log2_16bit | ||
167 | av_const int av_log2_16bit(unsigned v); | ||
168 | #endif | ||
169 | |||
170 | /** | ||
171 | * Clip a signed integer value into the amin-amax range. | ||
172 | * @param a value to clip | ||
173 | * @param amin minimum value of the clip range | ||
174 | * @param amax maximum value of the clip range | ||
175 | * @return clipped value | ||
176 | */ | ||
177 | 11848583775 | static av_always_inline av_const int av_clip_c(int a, int amin, int amax) | |
178 | { | ||
179 | #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 | ||
180 | if (amin > amax) abort(); | ||
181 | #endif | ||
182 |
2/2✓ Branch 0 taken 369505265 times.
✓ Branch 1 taken 11479078510 times.
|
11848583775 | if (a < amin) return amin; |
183 |
2/2✓ Branch 0 taken 391402380 times.
✓ Branch 1 taken 11087676130 times.
|
11479078510 | else if (a > amax) return amax; |
184 | 11087676130 | else return a; | |
185 | } | ||
186 | |||
187 | /** | ||
188 | * Clip a signed 64bit integer value into the amin-amax range. | ||
189 | * @param a value to clip | ||
190 | * @param amin minimum value of the clip range | ||
191 | * @param amax maximum value of the clip range | ||
192 | * @return clipped value | ||
193 | */ | ||
194 | 30171696 | static av_always_inline av_const int64_t av_clip64_c(int64_t a, int64_t amin, int64_t amax) | |
195 | { | ||
196 | #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 | ||
197 | if (amin > amax) abort(); | ||
198 | #endif | ||
199 |
2/2✓ Branch 0 taken 144 times.
✓ Branch 1 taken 30171552 times.
|
30171696 | if (a < amin) return amin; |
200 |
2/2✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 30170464 times.
|
30171552 | else if (a > amax) return amax; |
201 | 30170464 | else return a; | |
202 | } | ||
203 | |||
204 | /** | ||
205 | * Clip a signed integer value into the 0-255 range. | ||
206 | * @param a value to clip | ||
207 | * @return clipped value | ||
208 | */ | ||
209 | 30723207501 | static av_always_inline av_const uint8_t av_clip_uint8_c(int a) | |
210 | { | ||
211 |
2/2✓ Branch 0 taken 73017513 times.
✓ Branch 1 taken 30650189988 times.
|
30723207501 | if (a&(~0xFF)) return (~a)>>31; |
212 | 30650189988 | else return a; | |
213 | } | ||
214 | |||
215 | /** | ||
216 | * Clip a signed integer value into the -128,127 range. | ||
217 | * @param a value to clip | ||
218 | * @return clipped value | ||
219 | */ | ||
220 | 7719920 | static av_always_inline av_const int8_t av_clip_int8_c(int a) | |
221 | { | ||
222 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 7719902 times.
|
7719920 | if ((a+0x80U) & ~0xFF) return (a>>31) ^ 0x7F; |
223 | 7719902 | else return a; | |
224 | } | ||
225 | |||
226 | /** | ||
227 | * Clip a signed integer value into the 0-65535 range. | ||
228 | * @param a value to clip | ||
229 | * @return clipped value | ||
230 | */ | ||
231 | 139030716 | static av_always_inline av_const uint16_t av_clip_uint16_c(int a) | |
232 | { | ||
233 |
2/2✓ Branch 0 taken 31430 times.
✓ Branch 1 taken 138999286 times.
|
139030716 | if (a&(~0xFFFF)) return (~a)>>31; |
234 | 138999286 | else return a; | |
235 | } | ||
236 | |||
237 | /** | ||
238 | * Clip a signed integer value into the -32768,32767 range. | ||
239 | * @param a value to clip | ||
240 | * @return clipped value | ||
241 | */ | ||
242 | 2826795668 | static av_always_inline av_const int16_t av_clip_int16_c(int a) | |
243 | { | ||
244 |
2/2✓ Branch 0 taken 3214702 times.
✓ Branch 1 taken 2823580966 times.
|
2826795668 | if ((a+0x8000U) & ~0xFFFF) return (a>>31) ^ 0x7FFF; |
245 | 2823580966 | else return a; | |
246 | } | ||
247 | |||
248 | /** | ||
249 | * Clip a signed 64-bit integer value into the -2147483648,2147483647 range. | ||
250 | * @param a value to clip | ||
251 | * @return clipped value | ||
252 | */ | ||
253 | 467068680 | static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a) | |
254 | { | ||
255 |
2/2✓ Branch 0 taken 14567 times.
✓ Branch 1 taken 467054113 times.
|
467068680 | if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF); |
256 | 467054113 | else return (int32_t)a; | |
257 | } | ||
258 | |||
259 | /** | ||
260 | * Clip a signed integer into the -(2^p),(2^p-1) range. | ||
261 | * @param a value to clip | ||
262 | * @param p bit position to clip at | ||
263 | * @return clipped value | ||
264 | */ | ||
265 | 179096234 | static av_always_inline av_const int av_clip_intp2_c(int a, int p) | |
266 | { | ||
267 |
2/2✓ Branch 0 taken 363338 times.
✓ Branch 1 taken 178732896 times.
|
179096234 | if (((unsigned)a + (1 << p)) & ~((2 << p) - 1)) |
268 | 363338 | return (a >> 31) ^ ((1 << p) - 1); | |
269 | else | ||
270 | 178732896 | return a; | |
271 | } | ||
272 | |||
273 | /** | ||
274 | * Clip a signed integer to an unsigned power of two range. | ||
275 | * @param a value to clip | ||
276 | * @param p bit position to clip at | ||
277 | * @return clipped value | ||
278 | */ | ||
279 | 5282195768 | static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) | |
280 | { | ||
281 |
2/2✓ Branch 0 taken 82975472 times.
✓ Branch 1 taken 5199220296 times.
|
5282195768 | if (a & ~((1<<p) - 1)) return (~a) >> 31 & ((1<<p) - 1); |
282 | 5199220296 | else return a; | |
283 | } | ||
284 | |||
285 | /** | ||
286 | * Clear high bits from an unsigned integer starting with specific bit position | ||
287 | * @param a value to clip | ||
288 | * @param p bit position to clip at | ||
289 | * @return clipped value | ||
290 | */ | ||
291 | 919352079 | static av_always_inline av_const unsigned av_mod_uintp2_c(unsigned a, unsigned p) | |
292 | { | ||
293 | 919352079 | return a & ((1U << p) - 1); | |
294 | } | ||
295 | |||
296 | /** | ||
297 | * Add two signed 32-bit values with saturation. | ||
298 | * | ||
299 | * @param a one value | ||
300 | * @param b another value | ||
301 | * @return sum with signed saturation | ||
302 | */ | ||
303 | 1931413 | static av_always_inline int av_sat_add32_c(int a, int b) | |
304 | { | ||
305 | 1931413 | return av_clipl_int32((int64_t)a + b); | |
306 | } | ||
307 | |||
308 | /** | ||
309 | * Add a doubled value to another value with saturation at both stages. | ||
310 | * | ||
311 | * @param a first value | ||
312 | * @param b value doubled and added to a | ||
313 | * @return sum sat(a + sat(2*b)) with signed saturation | ||
314 | */ | ||
315 | 566960 | static av_always_inline int av_sat_dadd32_c(int a, int b) | |
316 | { | ||
317 | 566960 | return av_sat_add32(a, av_sat_add32(b, b)); | |
318 | } | ||
319 | |||
320 | /** | ||
321 | * Subtract two signed 32-bit values with saturation. | ||
322 | * | ||
323 | * @param a one value | ||
324 | * @param b another value | ||
325 | * @return difference with signed saturation | ||
326 | */ | ||
327 | 1470722 | static av_always_inline int av_sat_sub32_c(int a, int b) | |
328 | { | ||
329 | 1470722 | return av_clipl_int32((int64_t)a - b); | |
330 | } | ||
331 | |||
332 | /** | ||
333 | * Subtract a doubled value from another value with saturation at both stages. | ||
334 | * | ||
335 | * @param a first value | ||
336 | * @param b value doubled and subtracted from a | ||
337 | * @return difference sat(a - sat(2*b)) with signed saturation | ||
338 | */ | ||
339 | static av_always_inline int av_sat_dsub32_c(int a, int b) | ||
340 | { | ||
341 | return av_sat_sub32(a, av_sat_add32(b, b)); | ||
342 | } | ||
343 | |||
344 | /** | ||
345 | * Add two signed 64-bit values with saturation. | ||
346 | * | ||
347 | * @param a one value | ||
348 | * @param b another value | ||
349 | * @return sum with signed saturation | ||
350 | */ | ||
351 | 31218 | static av_always_inline int64_t av_sat_add64_c(int64_t a, int64_t b) { | |
352 | #if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_add_overflow) | ||
353 | int64_t tmp; | ||
354 |
1/4✓ Branch 0 taken 31218 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
31218 | return !__builtin_add_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); |
355 | #else | ||
356 | int64_t s = a+(uint64_t)b; | ||
357 | if ((int64_t)(a^b | ~s^b) >= 0) | ||
358 | return INT64_MAX ^ (b >> 63); | ||
359 | return s; | ||
360 | #endif | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * Subtract two signed 64-bit values with saturation. | ||
365 | * | ||
366 | * @param a one value | ||
367 | * @param b another value | ||
368 | * @return difference with signed saturation | ||
369 | */ | ||
370 | 69795 | static av_always_inline int64_t av_sat_sub64_c(int64_t a, int64_t b) { | |
371 | #if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_sub_overflow) | ||
372 | int64_t tmp; | ||
373 |
1/4✓ Branch 0 taken 69795 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
69795 | return !__builtin_sub_overflow(a, b, &tmp) ? tmp : (tmp < 0 ? INT64_MAX : INT64_MIN); |
374 | #else | ||
375 | if (b <= 0 && a >= INT64_MAX + b) | ||
376 | return INT64_MAX; | ||
377 | if (b >= 0 && a <= INT64_MIN + b) | ||
378 | return INT64_MIN; | ||
379 | return a - b; | ||
380 | #endif | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Clip a float value into the amin-amax range. | ||
385 | * If a is nan or -inf amin will be returned. | ||
386 | * If a is +inf amax will be returned. | ||
387 | * @param a value to clip | ||
388 | * @param amin minimum value of the clip range | ||
389 | * @param amax maximum value of the clip range | ||
390 | * @return clipped value | ||
391 | */ | ||
392 | 196608 | static av_always_inline av_const float av_clipf_c(float a, float amin, float amax) | |
393 | { | ||
394 | #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 | ||
395 | if (amin > amax) abort(); | ||
396 | #endif | ||
397 |
3/6✓ Branch 0 taken 196608 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 196608 times.
✓ Branch 4 taken 196608 times.
✗ Branch 5 not taken.
|
196608 | return FFMIN(FFMAX(a, amin), amax); |
398 | } | ||
399 | |||
400 | /** | ||
401 | * Clip a double value into the amin-amax range. | ||
402 | * If a is nan or -inf amin will be returned. | ||
403 | * If a is +inf amax will be returned. | ||
404 | * @param a value to clip | ||
405 | * @param amin minimum value of the clip range | ||
406 | * @param amax maximum value of the clip range | ||
407 | * @return clipped value | ||
408 | */ | ||
409 | static av_always_inline av_const double av_clipd_c(double a, double amin, double amax) | ||
410 | { | ||
411 | #if defined(HAVE_AV_CONFIG_H) && defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 | ||
412 | if (amin > amax) abort(); | ||
413 | #endif | ||
414 | return FFMIN(FFMAX(a, amin), amax); | ||
415 | } | ||
416 | |||
417 | /** Compute ceil(log2(x)). | ||
418 | * @param x value used to compute ceil(log2(x)) | ||
419 | * @return computed ceiling of log2(x) | ||
420 | */ | ||
421 | 1133846 | static av_always_inline av_const int av_ceil_log2_c(int x) | |
422 | { | ||
423 | 1133846 | return av_log2((x - 1U) << 1); | |
424 | } | ||
425 | |||
426 | /** | ||
427 | * Count number of bits set to one in x | ||
428 | * @param x value to count bits of | ||
429 | * @return the number of bits set to one in x | ||
430 | */ | ||
431 | 717801 | static av_always_inline av_const int av_popcount_c(uint32_t x) | |
432 | { | ||
433 | 717801 | x -= (x >> 1) & 0x55555555; | |
434 | 717801 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333); | |
435 | 717801 | x = (x + (x >> 4)) & 0x0F0F0F0F; | |
436 | 717801 | x += x >> 8; | |
437 | 717801 | return (x + (x >> 16)) & 0x3F; | |
438 | } | ||
439 | |||
440 | /** | ||
441 | * Count number of bits set to one in x | ||
442 | * @param x value to count bits of | ||
443 | * @return the number of bits set to one in x | ||
444 | */ | ||
445 | 322886 | static av_always_inline av_const int av_popcount64_c(uint64_t x) | |
446 | { | ||
447 | 322886 | return av_popcount((uint32_t)x) + av_popcount((uint32_t)(x >> 32)); | |
448 | } | ||
449 | |||
450 | static av_always_inline av_const int av_parity_c(uint32_t v) | ||
451 | { | ||
452 | return av_popcount(v) & 1; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form. | ||
457 | * | ||
458 | * @param val Output value, must be an lvalue of type uint32_t. | ||
459 | * @param GET_BYTE Expression reading one byte from the input. | ||
460 | * Evaluated up to 7 times (4 for the currently | ||
461 | * assigned Unicode range). With a memory buffer | ||
462 | * input, this could be *ptr++, or if you want to make sure | ||
463 | * that *ptr stops at the end of a NULL terminated string then | ||
464 | * *ptr ? *ptr++ : 0 | ||
465 | * @param ERROR Expression to be evaluated on invalid input, | ||
466 | * typically a goto statement. | ||
467 | * | ||
468 | * @warning ERROR should not contain a loop control statement which | ||
469 | * could interact with the internal while loop, and should force an | ||
470 | * exit from the macro code (e.g. through a goto or a return) in order | ||
471 | * to prevent undefined results. | ||
472 | */ | ||
473 | #define GET_UTF8(val, GET_BYTE, ERROR)\ | ||
474 | val= (GET_BYTE);\ | ||
475 | {\ | ||
476 | uint32_t top = (val & 128) >> 1;\ | ||
477 | if ((val & 0xc0) == 0x80 || val >= 0xFE)\ | ||
478 | {ERROR}\ | ||
479 | while (val & top) {\ | ||
480 | unsigned int tmp = (GET_BYTE) - 128;\ | ||
481 | if(tmp>>6)\ | ||
482 | {ERROR}\ | ||
483 | val= (val<<6) + tmp;\ | ||
484 | top <<= 5;\ | ||
485 | }\ | ||
486 | val &= (top << 1) - 1;\ | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form. | ||
491 | * | ||
492 | * @param val Output value, must be an lvalue of type uint32_t. | ||
493 | * @param GET_16BIT Expression returning two bytes of UTF-16 data converted | ||
494 | * to native byte order. Evaluated one or two times. | ||
495 | * @param ERROR Expression to be evaluated on invalid input, | ||
496 | * typically a goto statement. | ||
497 | */ | ||
498 | #define GET_UTF16(val, GET_16BIT, ERROR)\ | ||
499 | val = (GET_16BIT);\ | ||
500 | {\ | ||
501 | unsigned int hi = val - 0xD800;\ | ||
502 | if (hi < 0x800) {\ | ||
503 | val = (GET_16BIT) - 0xDC00;\ | ||
504 | if (val > 0x3FFU || hi > 0x3FFU)\ | ||
505 | {ERROR}\ | ||
506 | val += (hi<<10) + 0x10000;\ | ||
507 | }\ | ||
508 | }\ | ||
509 | |||
510 | /** | ||
511 | * @def PUT_UTF8(val, tmp, PUT_BYTE) | ||
512 | * Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). | ||
513 | * @param val is an input-only argument and should be of type uint32_t. It holds | ||
514 | * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If | ||
515 | * val is given as a function it is executed only once. | ||
516 | * @param tmp is a temporary variable and should be of type uint8_t. It | ||
517 | * represents an intermediate value during conversion that is to be | ||
518 | * output by PUT_BYTE. | ||
519 | * @param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. | ||
520 | * It could be a function or a statement, and uses tmp as the input byte. | ||
521 | * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be | ||
522 | * executed up to 4 times for values in the valid UTF-8 range and up to | ||
523 | * 7 times in the general case, depending on the length of the converted | ||
524 | * Unicode character. | ||
525 | */ | ||
526 | #define PUT_UTF8(val, tmp, PUT_BYTE)\ | ||
527 | {\ | ||
528 | int bytes, shift;\ | ||
529 | uint32_t in = val;\ | ||
530 | if (in < 0x80) {\ | ||
531 | tmp = in;\ | ||
532 | PUT_BYTE\ | ||
533 | } else {\ | ||
534 | bytes = (av_log2(in) + 4) / 5;\ | ||
535 | shift = (bytes - 1) * 6;\ | ||
536 | tmp = (256 - (256 >> bytes)) | (in >> shift);\ | ||
537 | PUT_BYTE\ | ||
538 | while (shift >= 6) {\ | ||
539 | shift -= 6;\ | ||
540 | tmp = 0x80 | ((in >> shift) & 0x3f);\ | ||
541 | PUT_BYTE\ | ||
542 | }\ | ||
543 | }\ | ||
544 | } | ||
545 | |||
546 | /** | ||
547 | * @def PUT_UTF16(val, tmp, PUT_16BIT) | ||
548 | * Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). | ||
549 | * @param val is an input-only argument and should be of type uint32_t. It holds | ||
550 | * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If | ||
551 | * val is given as a function it is executed only once. | ||
552 | * @param tmp is a temporary variable and should be of type uint16_t. It | ||
553 | * represents an intermediate value during conversion that is to be | ||
554 | * output by PUT_16BIT. | ||
555 | * @param PUT_16BIT writes the converted UTF-16 data to any proper destination | ||
556 | * in desired endianness. It could be a function or a statement, and uses tmp | ||
557 | * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" | ||
558 | * PUT_BYTE will be executed 1 or 2 times depending on input character. | ||
559 | */ | ||
560 | #define PUT_UTF16(val, tmp, PUT_16BIT)\ | ||
561 | {\ | ||
562 | uint32_t in = val;\ | ||
563 | if (in < 0x10000) {\ | ||
564 | tmp = in;\ | ||
565 | PUT_16BIT\ | ||
566 | } else {\ | ||
567 | tmp = 0xD800 | ((in - 0x10000) >> 10);\ | ||
568 | PUT_16BIT\ | ||
569 | tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ | ||
570 | PUT_16BIT\ | ||
571 | }\ | ||
572 | }\ | ||
573 | |||
574 | #endif /* AVUTIL_COMMON_H */ | ||
575 |