libFLAC/cpu.c: Get rid of OS_IS_ANDROID function
[flac.git] / src / libFLAC / memory.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2001-2009  Josh Coalson
3  * Copyright (C) 2011-2014  Xiph.Org Foundation
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * - Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the Xiph.org Foundation nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #  include <config.h>
35 #endif
36
37 #ifdef HAVE_STDINT_H
38 #include <stdint.h>
39 #endif
40
41 #include "private/memory.h"
42 #include "FLAC/assert.h"
43 #include "share/alloc.h"
44
45 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
46 {
47         void *x;
48
49         FLAC__ASSERT(0 != aligned_address);
50
51 #ifdef FLAC__ALIGN_MALLOC_DATA
52         /* align on 32-byte (256-bit) boundary */
53         x = safe_malloc_add_2op_(bytes, /*+*/31L);
54         *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
55 #else
56         x = safe_malloc_(bytes);
57         *aligned_address = x;
58 #endif
59         return x;
60 }
61
62 FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
63 {
64         FLAC__int32 *pu; /* unaligned pointer */
65         union { /* union needed to comply with C99 pointer aliasing rules */
66                 FLAC__int32 *pa; /* aligned pointer */
67                 void        *pv; /* aligned pointer alias */
68         } u;
69
70         FLAC__ASSERT(elements > 0);
71         FLAC__ASSERT(0 != unaligned_pointer);
72         FLAC__ASSERT(0 != aligned_pointer);
73         FLAC__ASSERT(unaligned_pointer != aligned_pointer);
74
75         if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
76                 return false;
77
78         pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
79         if(0 == pu) {
80                 return false;
81         }
82         else {
83                 if(*unaligned_pointer != 0)
84                         free(*unaligned_pointer);
85                 *unaligned_pointer = pu;
86                 *aligned_pointer = u.pa;
87                 return true;
88         }
89 }
90
91 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
92 {
93         FLAC__uint32 *pu; /* unaligned pointer */
94         union { /* union needed to comply with C99 pointer aliasing rules */
95                 FLAC__uint32 *pa; /* aligned pointer */
96                 void         *pv; /* aligned pointer alias */
97         } u;
98
99         FLAC__ASSERT(elements > 0);
100         FLAC__ASSERT(0 != unaligned_pointer);
101         FLAC__ASSERT(0 != aligned_pointer);
102         FLAC__ASSERT(unaligned_pointer != aligned_pointer);
103
104         if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
105                 return false;
106
107         pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
108         if(0 == pu) {
109                 return false;
110         }
111         else {
112                 if(*unaligned_pointer != 0)
113                         free(*unaligned_pointer);
114                 *unaligned_pointer = pu;
115                 *aligned_pointer = u.pa;
116                 return true;
117         }
118 }
119
120 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
121 {
122         FLAC__uint64 *pu; /* unaligned pointer */
123         union { /* union needed to comply with C99 pointer aliasing rules */
124                 FLAC__uint64 *pa; /* aligned pointer */
125                 void         *pv; /* aligned pointer alias */
126         } u;
127
128         FLAC__ASSERT(elements > 0);
129         FLAC__ASSERT(0 != unaligned_pointer);
130         FLAC__ASSERT(0 != aligned_pointer);
131         FLAC__ASSERT(unaligned_pointer != aligned_pointer);
132
133         if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
134                 return false;
135
136         pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
137         if(0 == pu) {
138                 return false;
139         }
140         else {
141                 if(*unaligned_pointer != 0)
142                         free(*unaligned_pointer);
143                 *unaligned_pointer = pu;
144                 *aligned_pointer = u.pa;
145                 return true;
146         }
147 }
148
149 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
150 {
151         unsigned *pu; /* unaligned pointer */
152         union { /* union needed to comply with C99 pointer aliasing rules */
153                 unsigned *pa; /* aligned pointer */
154                 void     *pv; /* aligned pointer alias */
155         } u;
156
157         FLAC__ASSERT(elements > 0);
158         FLAC__ASSERT(0 != unaligned_pointer);
159         FLAC__ASSERT(0 != aligned_pointer);
160         FLAC__ASSERT(unaligned_pointer != aligned_pointer);
161
162         if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
163                 return false;
164
165         pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
166         if(0 == pu) {
167                 return false;
168         }
169         else {
170                 if(*unaligned_pointer != 0)
171                         free(*unaligned_pointer);
172                 *unaligned_pointer = pu;
173                 *aligned_pointer = u.pa;
174                 return true;
175         }
176 }
177
178 #ifndef FLAC__INTEGER_ONLY_LIBRARY
179
180 FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
181 {
182         FLAC__real *pu; /* unaligned pointer */
183         union { /* union needed to comply with C99 pointer aliasing rules */
184                 FLAC__real *pa; /* aligned pointer */
185                 void       *pv; /* aligned pointer alias */
186         } u;
187
188         FLAC__ASSERT(elements > 0);
189         FLAC__ASSERT(0 != unaligned_pointer);
190         FLAC__ASSERT(0 != aligned_pointer);
191         FLAC__ASSERT(unaligned_pointer != aligned_pointer);
192
193         if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
194                 return false;
195
196         pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
197         if(0 == pu) {
198                 return false;
199         }
200         else {
201                 if(*unaligned_pointer != 0)
202                         free(*unaligned_pointer);
203                 *unaligned_pointer = pu;
204                 *aligned_pointer = u.pa;
205                 return true;
206         }
207 }
208
209 #endif
210
211 void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
212 {
213         if(!size1 || !size2)
214                 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
215         if(size1 > SIZE_MAX / size2)
216                 return 0;
217         return malloc(size1*size2);
218 }