1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2001-2009 Josh Coalson
3 * Copyright (C) 2011-2016 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.
41 #include "private/memory.h"
42 #include "FLAC/assert.h"
43 #include "share/compat.h"
44 #include "share/alloc.h"
46 void *FLAC__memory_alloc_aligned(size_t bytes
, void **aligned_address
)
50 FLAC__ASSERT(0 != aligned_address
);
52 #ifdef FLAC__ALIGN_MALLOC_DATA
53 /* align on 32-byte (256-bit) boundary */
54 x
= safe_malloc_add_2op_(bytes
, /*+*/31L);
55 *aligned_address
= (void*)(((uintptr_t)x
+ 31L) & -32L);
57 x
= safe_malloc_(bytes
);
63 FLAC__bool
FLAC__memory_alloc_aligned_int32_array(size_t elements
, FLAC__int32
**unaligned_pointer
, FLAC__int32
**aligned_pointer
)
65 FLAC__int32
*pu
; /* unaligned pointer */
66 union { /* union needed to comply with C99 pointer aliasing rules */
67 FLAC__int32
*pa
; /* aligned pointer */
68 void *pv
; /* aligned pointer alias */
71 FLAC__ASSERT(elements
> 0);
72 FLAC__ASSERT(0 != unaligned_pointer
);
73 FLAC__ASSERT(0 != aligned_pointer
);
74 FLAC__ASSERT(unaligned_pointer
!= aligned_pointer
);
76 if(elements
> SIZE_MAX
/ sizeof(*pu
)) /* overflow check */
79 pu
= FLAC__memory_alloc_aligned(sizeof(*pu
) * elements
, &u
.pv
);
84 if(*unaligned_pointer
!= 0)
85 free(*unaligned_pointer
);
86 *unaligned_pointer
= pu
;
87 *aligned_pointer
= u
.pa
;
92 FLAC__bool
FLAC__memory_alloc_aligned_uint32_array(size_t elements
, FLAC__uint32
**unaligned_pointer
, FLAC__uint32
**aligned_pointer
)
94 FLAC__uint32
*pu
; /* unaligned pointer */
95 union { /* union needed to comply with C99 pointer aliasing rules */
96 FLAC__uint32
*pa
; /* aligned pointer */
97 void *pv
; /* aligned pointer alias */
100 FLAC__ASSERT(elements
> 0);
101 FLAC__ASSERT(0 != unaligned_pointer
);
102 FLAC__ASSERT(0 != aligned_pointer
);
103 FLAC__ASSERT(unaligned_pointer
!= aligned_pointer
);
105 if(elements
> SIZE_MAX
/ sizeof(*pu
)) /* overflow check */
108 pu
= FLAC__memory_alloc_aligned(sizeof(*pu
) * elements
, &u
.pv
);
113 if(*unaligned_pointer
!= 0)
114 free(*unaligned_pointer
);
115 *unaligned_pointer
= pu
;
116 *aligned_pointer
= u
.pa
;
121 FLAC__bool
FLAC__memory_alloc_aligned_uint64_array(size_t elements
, FLAC__uint64
**unaligned_pointer
, FLAC__uint64
**aligned_pointer
)
123 FLAC__uint64
*pu
; /* unaligned pointer */
124 union { /* union needed to comply with C99 pointer aliasing rules */
125 FLAC__uint64
*pa
; /* aligned pointer */
126 void *pv
; /* aligned pointer alias */
129 FLAC__ASSERT(elements
> 0);
130 FLAC__ASSERT(0 != unaligned_pointer
);
131 FLAC__ASSERT(0 != aligned_pointer
);
132 FLAC__ASSERT(unaligned_pointer
!= aligned_pointer
);
134 if(elements
> SIZE_MAX
/ sizeof(*pu
)) /* overflow check */
137 pu
= FLAC__memory_alloc_aligned(sizeof(*pu
) * elements
, &u
.pv
);
142 if(*unaligned_pointer
!= 0)
143 free(*unaligned_pointer
);
144 *unaligned_pointer
= pu
;
145 *aligned_pointer
= u
.pa
;
150 FLAC__bool
FLAC__memory_alloc_aligned_unsigned_array(size_t elements
, uint32_t **unaligned_pointer
, uint32_t **aligned_pointer
)
152 uint32_t *pu
; /* unaligned pointer */
153 union { /* union needed to comply with C99 pointer aliasing rules */
154 uint32_t *pa
; /* aligned pointer */
155 void *pv
; /* aligned pointer alias */
158 FLAC__ASSERT(elements
> 0);
159 FLAC__ASSERT(0 != unaligned_pointer
);
160 FLAC__ASSERT(0 != aligned_pointer
);
161 FLAC__ASSERT(unaligned_pointer
!= aligned_pointer
);
163 if(elements
> SIZE_MAX
/ sizeof(*pu
)) /* overflow check */
166 pu
= FLAC__memory_alloc_aligned(sizeof(*pu
) * elements
, &u
.pv
);
171 if(*unaligned_pointer
!= 0)
172 free(*unaligned_pointer
);
173 *unaligned_pointer
= pu
;
174 *aligned_pointer
= u
.pa
;
179 #ifndef FLAC__INTEGER_ONLY_LIBRARY
181 FLAC__bool
FLAC__memory_alloc_aligned_real_array(size_t elements
, FLAC__real
**unaligned_pointer
, FLAC__real
**aligned_pointer
)
183 FLAC__real
*pu
; /* unaligned pointer */
184 union { /* union needed to comply with C99 pointer aliasing rules */
185 FLAC__real
*pa
; /* aligned pointer */
186 void *pv
; /* aligned pointer alias */
189 FLAC__ASSERT(elements
> 0);
190 FLAC__ASSERT(0 != unaligned_pointer
);
191 FLAC__ASSERT(0 != aligned_pointer
);
192 FLAC__ASSERT(unaligned_pointer
!= aligned_pointer
);
194 if(elements
> SIZE_MAX
/ sizeof(*pu
)) /* overflow check */
197 pu
= FLAC__memory_alloc_aligned(sizeof(*pu
) * elements
, &u
.pv
);
202 if(*unaligned_pointer
!= 0)
203 free(*unaligned_pointer
);
204 *unaligned_pointer
= pu
;
205 *aligned_pointer
= u
.pa
;
212 void *safe_malloc_mul_2op_p(size_t size1
, size_t size2
)
215 return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
216 if(size1
> SIZE_MAX
/ size2
)
218 return malloc(size1
*size2
);