1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include <schroedinger/schroutils.h>
7 #include <schroedinger/schrotables.h>
8 #include <schroedinger/schrodebug.h>
9 #include <schroedinger/schro-stdint.h>
10 #include <string.h>
11 #include <math.h>
12 #ifndef _WIN32
13 #include <time.h>
14 #include <sys/time.h>
15 #endif
16 #include <orc/orc.h>
17
18 #ifndef SCHRO_MALLOC_USE_MMAP
19 /* enable this for mmap based buffer overrun checks */
20 //# define SCHRO_MALLOC_USE_MMAP
21 /* enable this if there are alignment issues */
22 //# define ALIGN_16
23 #endif
24
25 #ifdef _WIN32
26 #include <windows.h>
27 #undef SCHRO_MALLOC_USE_MMAP
28 #endif
29
30 #ifdef SCHRO_MALLOC_USE_MMAP
31 #include <sys/mman.h>
32 #endif
33
34 #ifndef SCHRO_MALLOC_USE_MMAP
35 void *
schro_malloc(int size)36 schro_malloc (int size)
37 {
38 void *ptr;
39
40 ptr = malloc (size);
41 SCHRO_DEBUG ("alloc %p %d", ptr, size);
42
43 return ptr;
44 }
45
46 void *
schro_malloc0(int size)47 schro_malloc0 (int size)
48 {
49 void *ptr;
50
51 ptr = malloc (size);
52 memset (ptr, 0, size);
53 SCHRO_DEBUG ("alloc %p %d", ptr, size);
54
55 return ptr;
56 }
57
58 void *
schro_realloc(void * ptr,int size)59 schro_realloc (void *ptr, int size)
60 {
61 ptr = realloc (ptr, size);
62 SCHRO_DEBUG ("realloc %p %d", ptr, size);
63
64 return ptr;
65 }
66
67 void
schro_free(void * ptr)68 schro_free (void *ptr)
69 {
70 SCHRO_DEBUG ("free %p", ptr);
71 free (ptr);
72 }
73 #else /* SCHRO_MALLOC_USE_MMAP */
74
75 static const char sentinel[] = "This came from schro";
76
77 void *
schro_malloc(int size)78 schro_malloc (int size)
79 {
80 void *ptr;
81 int rsize;
82
83 #ifdef ALIGN_16
84 size = ROUND_UP_POW2 (size, 4);
85 #endif
86
87 rsize = ROUND_UP_POW2 (size + sizeof (int) + sizeof (sentinel), 12);
88 ptr =
89 mmap (NULL, rsize + 8192, PROT_READ | PROT_WRITE,
90 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
91 SCHRO_ASSERT (ptr != MAP_FAILED);
92
93 mprotect (ptr, 4096, PROT_NONE);
94 mprotect (OFFSET (ptr, 4096 + rsize), 4096, PROT_NONE);
95
96 SCHRO_DEBUG ("alloc %p %d", ptr, size);
97
98 *(int *) OFFSET (ptr, 4096) = rsize;
99 memcpy (OFFSET (ptr, 4096 + sizeof (int)), sentinel, sizeof (sentinel));
100
101 return OFFSET (ptr, 4096 + rsize - size);
102 }
103
104 void *
schro_malloc0(int size)105 schro_malloc0 (int size)
106 {
107 return schro_malloc (size);
108 }
109
110 void *
schro_realloc(void * ptr,int size)111 schro_realloc (void *ptr, int size)
112 {
113 unsigned long page = ((unsigned long) ptr) & ~(4095);
114 int rsize, old_size;
115
116 if (!ptr)
117 return schro_malloc (size);
118
119 /* find original size */
120 if ((unsigned long) ptr - page <= sizeof (int) + sizeof (sentinel)) {
121 /* if ptr is too close to start of page, then the base pointer is
122 * the previous page */
123 page -= 4096;
124 }
125 rsize = *(int *) page;
126 old_size = page + rsize - (unsigned long) ptr;;
127
128 void *new = schro_malloc (size);
129 if (size < old_size)
130 memcpy (new, ptr, size);
131 else
132 memcpy (new, ptr, old_size);
133
134 schro_free (ptr);
135
136 return new;
137 }
138
139 void
schro_free(void * ptr)140 schro_free (void *ptr)
141 {
142 unsigned long page = ((unsigned long) ptr) & ~(4095);
143 int rsize;
144
145 if ((unsigned long) ptr - page <= sizeof (int) + sizeof (sentinel)) {
146 /* if ptr is too close to start of page, then the base pointer is
147 * the previous page */
148 page -= 4096;
149 }
150
151 rsize = *(int *) page;
152
153 SCHRO_ASSERT (!memcmp ((void *) page + sizeof (int), sentinel,
154 sizeof (sentinel)));
155
156 munmap ((void *) (page - 4096), rsize + 8192);
157 }
158 #endif /* SCHRO_MALLOC_USE_MMAP */
159
160 int
muldiv64(int a,int b,int c)161 muldiv64 (int a, int b, int c)
162 {
163 orc_int64 x;
164
165 x = a;
166 x *= b;
167 x /= c;
168
169 return (int) x;
170 }
171
172 int
schro_utils_multiplier_to_quant_index(double x)173 schro_utils_multiplier_to_quant_index (double x)
174 {
175 return CLAMP (rint (log (x) / log (2) * 4.0), 0, 60);
176 }
177
178
179 static int
__schro_dequantise(int q,int quant_factor,int quant_offset)180 __schro_dequantise (int q, int quant_factor, int quant_offset)
181 {
182 if (q == 0)
183 return 0;
184 if (q < 0) {
185 return -((-q * quant_factor + quant_offset + 2) >> 2);
186 } else {
187 return (q * quant_factor + quant_offset + 2) >> 2;
188 }
189 }
190
191 int
schro_dequantise(int q,int quant_factor,int quant_offset)192 schro_dequantise (int q, int quant_factor, int quant_offset)
193 {
194 return __schro_dequantise (q, quant_factor, quant_offset);
195 }
196
197 static int
__schro_quantise(int value,int quant_factor,int quant_offset)198 __schro_quantise (int value, int quant_factor, int quant_offset)
199 {
200 int x;
201 int dead_zone = quant_offset;
202 int offset = quant_offset - quant_factor / 2;
203 /*
204 * offset = quant_offset always undershoots
205 * offset = quant_offset - quant_factor always overshoots
206 * offset = quant_offset - quant_factor/2 gives an error that averages 0
207 */
208
209 if (value == 0)
210 return 0;
211 if (value < 0) {
212 x = (-value) << 2;
213 if (x < dead_zone) {
214 x = 0;
215 } else {
216 x = (x - offset) / quant_factor;
217 }
218 value = -x;
219 } else {
220 x = value << 2;
221 if (x < dead_zone) {
222 x = 0;
223 } else {
224 x = (x - offset) / quant_factor;
225 }
226 value = x;
227 }
228 return value;
229 }
230
231 int
schro_quantise(int value,int quant_factor,int quant_offset)232 schro_quantise (int value, int quant_factor, int quant_offset)
233 {
234 return __schro_quantise (value, quant_factor, quant_offset);
235 }
236
237 void
schro_quantise_s16(int16_t * dest,int16_t * src,int quant_factor,int quant_offset,int n)238 schro_quantise_s16 (int16_t * dest, int16_t * src, int quant_factor,
239 int quant_offset, int n)
240 {
241 int i;
242 for (i = 0; i < n; i++) {
243 dest[i] = __schro_quantise (src[i], quant_factor, quant_offset);
244 src[i] = __schro_dequantise (dest[i], quant_factor, quant_offset);
245 }
246 }
247
248 void
schro_quantise_s32(int32_t * dest,int32_t * src,int quant_factor,int quant_offset,int n)249 schro_quantise_s32 (int32_t * dest, int32_t * src, int quant_factor,
250 int quant_offset, int n)
251 {
252 int i;
253 for (i = 0; i < n; i++) {
254 dest[i] = __schro_quantise (src[i], quant_factor, quant_offset);
255 src[i] = __schro_dequantise (dest[i], quant_factor, quant_offset);
256 }
257 }
258
259 #ifdef unused
260 void
schro_quantise_s16_table(int16_t * dest,int16_t * src,int quant_index,schro_bool is_intra,int n)261 schro_quantise_s16_table (int16_t * dest, int16_t * src, int quant_index,
262 schro_bool is_intra, int n)
263 {
264 int i;
265 int16_t *table;
266
267 table = schro_tables_get_quantise_table (quant_index, is_intra);
268
269 table += 32768;
270
271 for (i = 0; i < n; i++) {
272 dest[i] = table[src[i]];
273 }
274 }
275
276 void
schro_dequantise_s16_table(int16_t * dest,int16_t * src,int quant_index,schro_bool is_intra,int n)277 schro_dequantise_s16_table (int16_t * dest, int16_t * src, int quant_index,
278 schro_bool is_intra, int n)
279 {
280 int i;
281 int16_t *table;
282
283 table = schro_tables_get_dequantise_table (quant_index, is_intra);
284
285 table += 32768;
286
287 for (i = 0; i < n; i++) {
288 dest[i] = table[src[i]];
289 }
290 }
291 #endif
292
293 void
schro_dequantise_s16(int16_t * dest,int16_t * src,int quant_factor,int quant_offset,int n)294 schro_dequantise_s16 (int16_t * dest, int16_t * src, int quant_factor,
295 int quant_offset, int n)
296 {
297 int i;
298 for (i = 0; i < n; i++) {
299 dest[i] = __schro_dequantise (src[i], quant_factor, quant_offset);
300 }
301 }
302
303 /* log(2.0) */
304 #define LOG_2 0.69314718055994528623
305 /* 1.0/log(2.0) */
306 #define INV_LOG_2 1.44269504088896338700
307
308 double
schro_utils_probability_to_entropy(double x)309 schro_utils_probability_to_entropy (double x)
310 {
311 if (x <= 0 || x >= 1.0)
312 return 0;
313
314 return -(x * log (x) + (1 - x) * log (1 - x)) * INV_LOG_2;
315 }
316
317 double
schro_utils_entropy(double a,double total)318 schro_utils_entropy (double a, double total)
319 {
320 double x;
321
322 if (total == 0)
323 return 0;
324
325 x = a / total;
326 return schro_utils_probability_to_entropy (x) * total;
327 }
328
329 void
schro_utils_reduce_fraction(int * n,int * d)330 schro_utils_reduce_fraction (int *n, int *d)
331 {
332 static const int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
333 91
334 };
335 int i;
336 int p;
337
338 SCHRO_DEBUG ("reduce %d/%d", *n, *d);
339 for (i = 0; i < sizeof (primes) / sizeof (primes[0]); i++) {
340 p = primes[i];
341 while (*n % p == 0 && *d % p == 0) {
342 *n /= p;
343 *d /= p;
344 }
345 if (*d == 1)
346 break;
347 }
348 SCHRO_DEBUG ("to %d/%d", *n, *d);
349 }
350
351 double
schro_utils_get_time(void)352 schro_utils_get_time (void)
353 {
354 #ifndef _WIN32
355 struct timeval tv;
356
357 gettimeofday (&tv, NULL);
358
359 return tv.tv_sec + 1e-6 * tv.tv_usec;
360 #else
361 return (double) GetTickCount () / 1000.;
362 #endif
363 }
364