OSDN Git Service

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