memory.c (5910B)
1 /* libFLAC - Free Lossless Audio Codec library 2 * Copyright (C) 2001,2002,2003,2004,2005 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 #include "private/memory.h" 33 #include "FLAC/assert.h" 34 35 #ifdef HAVE_CONFIG_H 36 #include <config.h> 37 #endif 38 39 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) 40 { 41 void *x; 42 43 FLAC__ASSERT(0 != aligned_address); 44 45 #ifdef FLAC__ALIGN_MALLOC_DATA 46 /* align on 32-byte (256-bit) boundary */ 47 x = malloc(bytes+31); 48 *aligned_address = (void*)(((unsigned)x + 31) & -32); 49 #else 50 x = malloc(bytes); 51 *aligned_address = x; 52 #endif 53 return x; 54 } 55 56 FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) 57 { 58 FLAC__int32 *pu; /* unaligned pointer */ 59 union { /* union needed to comply with C99 pointer aliasing rules */ 60 FLAC__int32 *pa; /* aligned pointer */ 61 void *pv; /* aligned pointer alias */ 62 } u; 63 64 FLAC__ASSERT(elements > 0); 65 FLAC__ASSERT(0 != unaligned_pointer); 66 FLAC__ASSERT(0 != aligned_pointer); 67 FLAC__ASSERT(unaligned_pointer != aligned_pointer); 68 69 pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv); 70 if(0 == pu) { 71 return false; 72 } 73 else { 74 if(*unaligned_pointer != 0) 75 free(*unaligned_pointer); 76 *unaligned_pointer = pu; 77 *aligned_pointer = u.pa; 78 return true; 79 } 80 } 81 82 FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) 83 { 84 FLAC__uint32 *pu; /* unaligned pointer */ 85 union { /* union needed to comply with C99 pointer aliasing rules */ 86 FLAC__uint32 *pa; /* aligned pointer */ 87 void *pv; /* aligned pointer alias */ 88 } u; 89 90 FLAC__ASSERT(elements > 0); 91 FLAC__ASSERT(0 != unaligned_pointer); 92 FLAC__ASSERT(0 != aligned_pointer); 93 FLAC__ASSERT(unaligned_pointer != aligned_pointer); 94 95 pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv); 96 if(0 == pu) { 97 return false; 98 } 99 else { 100 if(*unaligned_pointer != 0) 101 free(*unaligned_pointer); 102 *unaligned_pointer = pu; 103 *aligned_pointer = u.pa; 104 return true; 105 } 106 } 107 108 FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) 109 { 110 FLAC__uint64 *pu; /* unaligned pointer */ 111 union { /* union needed to comply with C99 pointer aliasing rules */ 112 FLAC__uint64 *pa; /* aligned pointer */ 113 void *pv; /* aligned pointer alias */ 114 } u; 115 116 FLAC__ASSERT(elements > 0); 117 FLAC__ASSERT(0 != unaligned_pointer); 118 FLAC__ASSERT(0 != aligned_pointer); 119 FLAC__ASSERT(unaligned_pointer != aligned_pointer); 120 121 pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv); 122 if(0 == pu) { 123 return false; 124 } 125 else { 126 if(*unaligned_pointer != 0) 127 free(*unaligned_pointer); 128 *unaligned_pointer = pu; 129 *aligned_pointer = u.pa; 130 return true; 131 } 132 } 133 134 FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) 135 { 136 unsigned *pu; /* unaligned pointer */ 137 union { /* union needed to comply with C99 pointer aliasing rules */ 138 unsigned *pa; /* aligned pointer */ 139 void *pv; /* aligned pointer alias */ 140 } u; 141 142 FLAC__ASSERT(elements > 0); 143 FLAC__ASSERT(0 != unaligned_pointer); 144 FLAC__ASSERT(0 != aligned_pointer); 145 FLAC__ASSERT(unaligned_pointer != aligned_pointer); 146 147 pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv); 148 if(0 == pu) { 149 return false; 150 } 151 else { 152 if(*unaligned_pointer != 0) 153 free(*unaligned_pointer); 154 *unaligned_pointer = pu; 155 *aligned_pointer = u.pa; 156 return true; 157 } 158 } 159 160 #ifndef FLAC__INTEGER_ONLY_LIBRARY 161 162 FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) 163 { 164 FLAC__real *pu; /* unaligned pointer */ 165 union { /* union needed to comply with C99 pointer aliasing rules */ 166 FLAC__real *pa; /* aligned pointer */ 167 void *pv; /* aligned pointer alias */ 168 } u; 169 170 FLAC__ASSERT(elements > 0); 171 FLAC__ASSERT(0 != unaligned_pointer); 172 FLAC__ASSERT(0 != aligned_pointer); 173 FLAC__ASSERT(unaligned_pointer != aligned_pointer); 174 175 pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv); 176 if(0 == pu) { 177 return false; 178 } 179 else { 180 if(*unaligned_pointer != 0) 181 free(*unaligned_pointer); 182 *unaligned_pointer = pu; 183 *aligned_pointer = u.pa; 184 return true; 185 } 186 } 187 188 #endif