endian.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /** @file endian.c
  2. * @brief Functions to handle endian specifics
  3. */
  4. /*
  5. * Copyright (C) 2005-2006 Christopher C. Hulbert
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <stdlib.h>
  22. #include "matio.h"
  23. #include "matio_private.h"
  24. /** @brief swap the bytes @c a and @c b
  25. * @ingroup mat_internal
  26. */
  27. #define swap(a,b) a^=b;b^=a;a^=b
  28. #ifdef HAVE_MAT_INT64_T
  29. /** @brief swap the bytes of a 64-bit signed integer
  30. * @ingroup mat_internal
  31. * @param a pointer to integer to swap
  32. * @return the swapped integer
  33. */
  34. mat_int64_t
  35. Mat_int64Swap( mat_int64_t *a )
  36. {
  37. union {
  38. mat_int8_t i1[8];
  39. mat_int64_t i8;
  40. } tmp;
  41. tmp.i8 = *a;
  42. swap( tmp.i1[0], tmp.i1[7] );
  43. swap( tmp.i1[1], tmp.i1[6] );
  44. swap( tmp.i1[2], tmp.i1[5] );
  45. swap( tmp.i1[3], tmp.i1[4] );
  46. *a = tmp.i8;
  47. return *a;
  48. }
  49. #endif /* HAVE_MAT_INT64_T */
  50. #ifdef HAVE_MAT_UINT64_T
  51. /** @brief swap the bytes of a 64-bit unsigned integer
  52. * @ingroup mat_internal
  53. * @param a pointer to integer to swap
  54. * @return the swapped integer
  55. */
  56. mat_uint64_t
  57. Mat_uint64Swap( mat_uint64_t *a )
  58. {
  59. union {
  60. mat_uint8_t i1[8];
  61. mat_uint64_t i8;
  62. } tmp;
  63. tmp.i8 = *a;
  64. swap( tmp.i1[0], tmp.i1[7] );
  65. swap( tmp.i1[1], tmp.i1[6] );
  66. swap( tmp.i1[2], tmp.i1[5] );
  67. swap( tmp.i1[3], tmp.i1[4] );
  68. *a = tmp.i8;
  69. return *a;
  70. }
  71. #endif /* HAVE_MAT_UINT64_T */
  72. /** @brief swap the bytes of a 32-bit signed integer
  73. * @ingroup mat_internal
  74. * @param a pointer to integer to swap
  75. * @return the swapped integer
  76. */
  77. mat_int32_t
  78. Mat_int32Swap( mat_int32_t *a )
  79. {
  80. union {
  81. mat_int8_t i1[4];
  82. mat_int32_t i4;
  83. } tmp;
  84. tmp.i4 = *a;
  85. swap( tmp.i1[0], tmp.i1[3] );
  86. swap( tmp.i1[1], tmp.i1[2] );
  87. *a = tmp.i4;
  88. return *a;
  89. }
  90. /** @brief swap the bytes of a 32-bit unsigned integer
  91. * @ingroup mat_internal
  92. * @param a pointer to integer to swap
  93. * @return the swapped integer
  94. */
  95. mat_uint32_t
  96. Mat_uint32Swap( mat_uint32_t *a )
  97. {
  98. union {
  99. mat_uint8_t i1[4];
  100. mat_uint32_t i4;
  101. } tmp;
  102. tmp.i4 = *a;
  103. swap( tmp.i1[0], tmp.i1[3] );
  104. swap( tmp.i1[1], tmp.i1[2] );
  105. *a = tmp.i4;
  106. return *a;
  107. }
  108. /** @brief swap the bytes of a 16-bit signed integer
  109. * @ingroup mat_internal
  110. * @param a pointer to integer to swap
  111. * @return the swapped integer
  112. */
  113. mat_int16_t
  114. Mat_int16Swap( mat_int16_t *a )
  115. {
  116. union {
  117. mat_int8_t i1[2];
  118. mat_int16_t i2;
  119. } tmp;
  120. tmp.i2 = *a;
  121. swap( tmp.i1[0], tmp.i1[1] );
  122. *a = tmp.i2;
  123. return *a;
  124. }
  125. /** @brief swap the bytes of a 16-bit unsigned integer
  126. * @ingroup mat_internal
  127. * @param a pointer to integer to swap
  128. * @return the swapped integer
  129. */
  130. mat_uint16_t
  131. Mat_uint16Swap( mat_uint16_t *a )
  132. {
  133. union {
  134. mat_uint8_t i1[2];
  135. mat_uint16_t i2;
  136. } tmp;
  137. tmp.i2 = *a;
  138. swap( tmp.i1[0], tmp.i1[1] );
  139. *a = tmp.i2;
  140. return *a;
  141. }
  142. /** @brief swap the bytes of a 4 byte single-precision float
  143. * @ingroup mat_internal
  144. * @param a pointer to integer to swap
  145. * @return the swapped integer
  146. */
  147. float
  148. Mat_floatSwap( float *a )
  149. {
  150. union {
  151. char i1[4];
  152. float r4;
  153. } tmp;
  154. tmp.r4 = *a;
  155. swap( tmp.i1[0], tmp.i1[3] );
  156. swap( tmp.i1[1], tmp.i1[2] );
  157. *a = tmp.r4;
  158. return *a;
  159. }
  160. /** @brief swap the bytes of a 4 or 8 byte double-precision float
  161. * @ingroup mat_internal
  162. * @param a pointer to integer to swap
  163. * @return the swapped integer
  164. */
  165. double
  166. Mat_doubleSwap( double *a )
  167. {
  168. #ifndef SIZEOF_DOUBLE
  169. #define SIZEOF_DOUBLE 8
  170. #endif
  171. union {
  172. char a[SIZEOF_DOUBLE];
  173. double b;
  174. } tmp;
  175. tmp.b = *a;
  176. #if SIZEOF_DOUBLE == 4
  177. swap( tmp.a[0], tmp.a[3] );
  178. swap( tmp.a[1], tmp.a[2] );
  179. #elif SIZEOF_DOUBLE == 8
  180. swap( tmp.a[0], tmp.a[7] );
  181. swap( tmp.a[1], tmp.a[6] );
  182. swap( tmp.a[2], tmp.a[5] );
  183. swap( tmp.a[3], tmp.a[4] );
  184. #elif SIZEOF_DOUBLE == 16
  185. swap( tmp.a[0], tmp.a[15] );
  186. swap( tmp.a[1], tmp.a[14] );
  187. swap( tmp.a[2], tmp.a[13] );
  188. swap( tmp.a[3], tmp.a[12] );
  189. swap( tmp.a[4], tmp.a[11] );
  190. swap( tmp.a[5], tmp.a[10] );
  191. swap( tmp.a[6], tmp.a[9] );
  192. swap( tmp.a[7], tmp.a[8] );
  193. #endif
  194. *a = tmp.b;
  195. return *a;
  196. }