1 /*
2 NrrdIO: stand-alone code for basic nrrd functionality
3 Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago
4 Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann
5 Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah
6
7 This software is provided 'as-is', without any express or implied
8 warranty. In no event will the authors be held liable for any
9 damages arising from the use of this software.
10
11 Permission is granted to anyone to use this software for any
12 purpose, including commercial applications, and to alter it and
13 redistribute it freely, subject to the following restrictions:
14
15 1. The origin of this software must not be misrepresented; you must
16 not claim that you wrote the original software. If you use this
17 software in a product, an acknowledgment in the product
18 documentation would be appreciated but is not required.
19
20 2. Altered source versions must be plainly marked as such, and must
21 not be misrepresented as being the original software.
22
23 3. This notice may not be removed or altered from any source distribution.
24 */
25
26 #include "NrrdIO.h"
27
28 static void
_nrrdSwap16Endian(void * _data,size_t N)29 _nrrdSwap16Endian(void *_data, size_t N) {
30 unsigned short *data, dd, fix, mask;
31 size_t I;
32
33 if (!_data) {
34 return;
35 }
36 data = AIR_CAST(unsigned short *, _data);
37 mask = AIR_CAST(unsigned short, 0x00FFu);
38 for (I=0; I<N; I++) {
39 dd = data[I];
40 fix = (dd & mask); dd >>= 0x08;
41 fix = (dd & mask) | AIR_CAST(unsigned short, fix << 0x08);
42 data[I] = fix;
43 }
44 }
45
46 static void
_nrrdSwap32Endian(void * _data,size_t N)47 _nrrdSwap32Endian(void *_data, size_t N) {
48 unsigned int *data, dd, fix, mask;
49 size_t I;
50
51 if (!_data) {
52 return;
53 }
54 data = AIR_CAST(unsigned int *, _data);
55 mask = 0x000000FFu;
56 for (I=0; I<N; I++) {
57 dd = data[I];
58 fix = (dd & mask); dd >>= 0x08;
59 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
60 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
61 fix = (dd & mask) | (fix << 0x08);
62 data[I] = fix;
63 }
64 }
65
66 static void
_nrrdSwap64Endian(void * _data,size_t N)67 _nrrdSwap64Endian(void *_data, size_t N) {
68 airULLong *data, dd, fix, mask;
69 size_t I;
70
71 if (!_data) {
72 return;
73 }
74 data = AIR_CAST(airULLong *, _data);
75 mask = AIR_ULLONG(0x00000000000000FF);
76 for (I=0; I<N; I++) {
77 dd = data[I];
78 fix = (dd & mask); dd >>= 0x08;
79 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
80 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
81 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
82 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
83 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
84 fix = (dd & mask) | (fix << 0x08); dd >>= 0x08;
85 fix = (dd & mask) | (fix << 0x08);
86 data[I] = fix;
87 }
88 }
89
90 static void
_nrrdNoopEndian(void * data,size_t N)91 _nrrdNoopEndian(void *data, size_t N) {
92 AIR_UNUSED(data);
93 AIR_UNUSED(N);
94 return;
95 }
96
97 static void
_nrrdBlockEndian(void * data,size_t N)98 _nrrdBlockEndian(void *data, size_t N) {
99 char me[]="_nrrdBlockEndian";
100
101 AIR_UNUSED(data);
102 AIR_UNUSED(N);
103 fprintf(stderr, "%s: WARNING: can't fix endiannes of nrrd type %s\n", me,
104 airEnumStr(nrrdType, nrrdTypeBlock));
105 }
106
107 static void
108 (*_nrrdSwapEndian[])(void *, size_t) = {
109 _nrrdNoopEndian, /* 0: nobody knows! */
110 _nrrdNoopEndian, /* 1: signed 1-byte integer */
111 _nrrdNoopEndian, /* 2: unsigned 1-byte integer */
112 _nrrdSwap16Endian, /* 3: signed 2-byte integer */
113 _nrrdSwap16Endian, /* 4: unsigned 2-byte integer */
114 _nrrdSwap32Endian, /* 5: signed 4-byte integer */
115 _nrrdSwap32Endian, /* 6: unsigned 4-byte integer */
116 _nrrdSwap64Endian, /* 7: signed 8-byte integer */
117 _nrrdSwap64Endian, /* 8: unsigned 8-byte integer */
118 _nrrdSwap32Endian, /* 9: 4-byte floating point */
119 _nrrdSwap64Endian, /* 10: 8-byte floating point */
120 _nrrdBlockEndian /* 11: size user defined at run time */
121 };
122
123 void
nrrdSwapEndian(Nrrd * nrrd)124 nrrdSwapEndian(Nrrd *nrrd) {
125
126 if (nrrd
127 && nrrd->data
128 && !airEnumValCheck(nrrdType, nrrd->type)) {
129 _nrrdSwapEndian[nrrd->type](nrrd->data, nrrdElementNumber(nrrd));
130 }
131 return;
132 }
133