flac_memory.c 6.8 KB

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