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