1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2001-2009 Josh Coalson
3 * Copyright (C) 2011-2013 Xiph.Org Foundation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
37 #include "private/memory.h"
38 #include "FLAC/assert.h"
39 #include "share/alloc.h"
41 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
45 FLAC__ASSERT(0 != aligned_address);
47 #ifdef FLAC__ALIGN_MALLOC_DATA
48 /* align on 32-byte (256-bit) boundary */
49 x = safe_malloc_add_2op_(bytes, /*+*/31);
52 /* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
53 *aligned_address = (void*)(((unsigned)x + 31) & -32);
54 #elif SIZEOF_VOIDP == 8
55 *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
57 # error Unsupported sizeof(void*)
60 /* there's got to be a better way to do this right for all archs */
61 if(sizeof(void*) == sizeof(unsigned))
62 *aligned_address = (void*)(((unsigned)x + 31) & -32);
63 else if(sizeof(void*) == sizeof(FLAC__uint64))
64 *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
69 x = safe_malloc_(bytes);
75 FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
77 FLAC__int32 *pu; /* unaligned pointer */
78 union { /* union needed to comply with C99 pointer aliasing rules */
79 FLAC__int32 *pa; /* aligned pointer */
80 void *pv; /* aligned pointer alias */
83 FLAC__ASSERT(elements > 0);
84 FLAC__ASSERT(0 != unaligned_pointer);
85 FLAC__ASSERT(0 != aligned_pointer);
86 FLAC__ASSERT(unaligned_pointer != aligned_pointer);
88 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
91 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
96 if(*unaligned_pointer != 0)
97 free(*unaligned_pointer);
98 *unaligned_pointer = pu;
99 *aligned_pointer = u.pa;
104 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
106 FLAC__uint32 *pu; /* unaligned pointer */
107 union { /* union needed to comply with C99 pointer aliasing rules */
108 FLAC__uint32 *pa; /* aligned pointer */
109 void *pv; /* aligned pointer alias */
112 FLAC__ASSERT(elements > 0);
113 FLAC__ASSERT(0 != unaligned_pointer);
114 FLAC__ASSERT(0 != aligned_pointer);
115 FLAC__ASSERT(unaligned_pointer != aligned_pointer);
117 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
120 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
125 if(*unaligned_pointer != 0)
126 free(*unaligned_pointer);
127 *unaligned_pointer = pu;
128 *aligned_pointer = u.pa;
133 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
135 FLAC__uint64 *pu; /* unaligned pointer */
136 union { /* union needed to comply with C99 pointer aliasing rules */
137 FLAC__uint64 *pa; /* aligned pointer */
138 void *pv; /* aligned pointer alias */
141 FLAC__ASSERT(elements > 0);
142 FLAC__ASSERT(0 != unaligned_pointer);
143 FLAC__ASSERT(0 != aligned_pointer);
144 FLAC__ASSERT(unaligned_pointer != aligned_pointer);
146 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
149 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
154 if(*unaligned_pointer != 0)
155 free(*unaligned_pointer);
156 *unaligned_pointer = pu;
157 *aligned_pointer = u.pa;
162 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
164 unsigned *pu; /* unaligned pointer */
165 union { /* union needed to comply with C99 pointer aliasing rules */
166 unsigned *pa; /* aligned pointer */
167 void *pv; /* aligned pointer alias */
170 FLAC__ASSERT(elements > 0);
171 FLAC__ASSERT(0 != unaligned_pointer);
172 FLAC__ASSERT(0 != aligned_pointer);
173 FLAC__ASSERT(unaligned_pointer != aligned_pointer);
175 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
178 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
183 if(*unaligned_pointer != 0)
184 free(*unaligned_pointer);
185 *unaligned_pointer = pu;
186 *aligned_pointer = u.pa;
191 #ifndef FLAC__INTEGER_ONLY_LIBRARY
193 FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
195 FLAC__real *pu; /* unaligned pointer */
196 union { /* union needed to comply with C99 pointer aliasing rules */
197 FLAC__real *pa; /* aligned pointer */
198 void *pv; /* aligned pointer alias */
201 FLAC__ASSERT(elements > 0);
202 FLAC__ASSERT(0 != unaligned_pointer);
203 FLAC__ASSERT(0 != aligned_pointer);
204 FLAC__ASSERT(unaligned_pointer != aligned_pointer);
206 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
209 pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
214 if(*unaligned_pointer != 0)
215 free(*unaligned_pointer);
216 *unaligned_pointer = pu;
217 *aligned_pointer = u.pa;
224 void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
227 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
228 if(size1 > SIZE_MAX / size2)
230 return malloc(size1*size2);