utils: Make lsmash_ceil_log2 static inline.
[L-SMASH.git] / common / utils.c
blobe9ba2362d62651e95def8ca204c10791eacca46b
1 /*****************************************************************************
2 * utils.c
3 *****************************************************************************
4 * Copyright (C) 2010-2017 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "internal.h" /* must be placed first */
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #ifdef _WIN32
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31 #endif
33 /*---- type ----*/
34 double lsmash_fixed2double( uint64_t value, int frac_width )
36 return value / (double)(1ULL << frac_width);
39 float lsmash_int2float32( uint32_t value )
41 return (union {uint32_t i; float f;}){value}.f;
44 double lsmash_int2float64( uint64_t value )
46 return (union {uint64_t i; double d;}){value}.d;
48 /*---- ----*/
50 /*---- others ----*/
51 void lsmash_log
53 const void *class,
54 lsmash_log_level level,
55 const char *message,
56 ...
59 /* Dereference lsmash_class_t pointer if 'class' is non-NULL. */
60 lsmash_class_t *cls = class ? (lsmash_class_t *)*(intptr_t *)class : NULL;
61 if( cls && cls->log_level_offset )
63 lsmash_log_level log_level = *(lsmash_log_level *)((int8_t *)class + cls->log_level_offset);
64 if( level > log_level )
65 return;
67 char *prefix;
68 va_list args;
69 va_start( args, message );
70 switch( level )
72 case LSMASH_LOG_ERROR:
73 prefix = "Error";
74 break;
75 case LSMASH_LOG_WARNING:
76 prefix = "Warning";
77 break;
78 case LSMASH_LOG_INFO:
79 prefix = "Info";
80 break;
81 default:
82 prefix = "Unknown";
83 break;
85 if( cls )
86 fprintf( stderr, "[%s: %s]: ", cls->name, prefix );
87 else
88 fprintf( stderr, "[%s]: ", prefix );
89 vfprintf( stderr, message, args );
90 va_end( args );
93 void lsmash_log_refresh_line
95 const void *class /* unused, but for forward compatibility */
98 /* Assume 80 characters per line. */
99 fprintf( stderr, "%80c", '\r' );
102 uint32_t lsmash_count_bits
104 uint32_t bits
107 bits = (bits & 0x55555555) + ((bits >> 1) & 0x55555555);
108 bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
109 bits = (bits & 0x0f0f0f0f) + ((bits >> 4) & 0x0f0f0f0f);
110 bits = (bits & 0x00ff00ff) + ((bits >> 8) & 0x00ff00ff);
111 return (bits & 0x0000ffff) + ((bits >> 16) & 0x0000ffff);
114 void lsmash_ifprintf
116 FILE *fp,
117 int indent,
118 const char *format, ...
121 va_list args;
122 va_start( args, format );
123 if( indent <= 10 )
125 static const char *indent_string[] =
128 " ",
129 " ",
130 " ",
131 " ",
132 " ",
133 " ",
134 " ",
135 " ",
136 " ",
139 fprintf( fp, "%s", indent_string[indent] );
141 else
142 for( int i = 0; i < indent; i++ )
143 fprintf( fp, " " );
144 vfprintf( fp, format, args );
145 va_end( args );
148 /* for qsort function */
149 int lsmash_compare_dts
151 const lsmash_media_ts_t *a,
152 const lsmash_media_ts_t *b
155 int64_t diff = (int64_t)(a->dts - b->dts);
156 return diff > 0 ? 1 : (diff == 0 ? 0 : -1);
159 int lsmash_compare_cts
161 const lsmash_media_ts_t *a,
162 const lsmash_media_ts_t *b
165 int64_t diff = (int64_t)(a->cts - b->cts);
166 return diff > 0 ? 1 : (diff == 0 ? 0 : -1);
169 #ifdef _WIN32
170 int lsmash_convert_ansi_to_utf8( const char *ansi, char *utf8, int length )
172 int len0 = MultiByteToWideChar( CP_THREAD_ACP, 0, ansi, -1, 0, 0 );
173 wchar_t *buff = lsmash_malloc( len0 * sizeof(wchar_t) );
174 if( !buff )
175 return 0;
176 int len1 = MultiByteToWideChar( CP_THREAD_ACP, 0, ansi, -1, buff, len0 );
177 if( len0 != len1 )
178 goto convert_fail;
179 len0 = WideCharToMultiByte( CP_UTF8, 0, buff, -1, 0, 0, 0, 0 );
180 if( len0 > length - 1 )
181 goto convert_fail;
182 len1 = WideCharToMultiByte( CP_UTF8, 0, buff, -1, utf8, length, 0, 0 );
183 lsmash_free( buff );
184 if( len0 != len1 )
185 return 0;
186 return len1;
187 convert_fail:
188 lsmash_free( buff );
189 return 0;
191 #endif