/src/dcmtk/dcmdata/libsrc/dcswap.cc
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (C) 1994-2017, OFFIS e.V. |
4 | | * All rights reserved. See COPYRIGHT file for details. |
5 | | * |
6 | | * This software and supporting documentation were developed by |
7 | | * |
8 | | * OFFIS e.V. |
9 | | * R&D Division Health |
10 | | * Escherweg 2 |
11 | | * D-26121 Oldenburg, Germany |
12 | | * |
13 | | * |
14 | | * Module: dcmdata |
15 | | * |
16 | | * Author: Andreas Barth |
17 | | * |
18 | | * Purpose: byte order functions |
19 | | * |
20 | | */ |
21 | | |
22 | | #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ |
23 | | #include "dcmtk/dcmdata/dcswap.h" |
24 | | |
25 | | OFCondition swapIfNecessary(const E_ByteOrder newByteOrder, |
26 | | const E_ByteOrder oldByteOrder, |
27 | | void * value, const Uint32 byteLength, |
28 | | const size_t valWidth) |
29 | | /* |
30 | | * This function swaps byteLength bytes in value if newByteOrder and oldByteOrder |
31 | | * differ from each other. In case bytes have to be swapped, these bytes are separated |
32 | | * in valWidth elements which will be swapped separately. |
33 | | * |
34 | | * Parameters: |
35 | | * newByteOrder - [in] The new byte ordering (little or big endian). |
36 | | * oldByteOrder - [in] The current old byte ordering (little or big endian). |
37 | | * value - [in] Array that contains the actual bytes which might have to be swapped. |
38 | | * byteLength - [in] Length of the above array. |
39 | | * valWidth - [in] Specifies how many bytes shall be treated together as one element. |
40 | | */ |
41 | 0 | { |
42 | | /* if the two byte orderings are unknown this is an illegal call */ |
43 | 0 | if (oldByteOrder != EBO_unknown && newByteOrder != EBO_unknown) |
44 | 0 | { |
45 | | /* and if they differ from each other and valWidth is not 1 */ |
46 | 0 | if (oldByteOrder != newByteOrder && valWidth != 1) |
47 | 0 | { |
48 | | /* in case the array length equals valWidth and only 2 or 4 bytes have to be swapped */ |
49 | | /* we can swiftly swap these bytes by calling the corresponding functions. If this is */ |
50 | | /* not the case we have to call a more sophisticated function. */ |
51 | 0 | if (byteLength == valWidth) |
52 | 0 | { |
53 | 0 | if (valWidth == 2) |
54 | 0 | swap2Bytes(OFstatic_cast(Uint8 *, value)); |
55 | 0 | else if (valWidth == 4) |
56 | 0 | swap4Bytes(OFstatic_cast(Uint8 *, value)); |
57 | 0 | else |
58 | 0 | swapBytes(value, byteLength, valWidth); |
59 | 0 | } |
60 | 0 | else |
61 | 0 | swapBytes(value, byteLength, valWidth); |
62 | 0 | } |
63 | 0 | return EC_Normal; |
64 | 0 | } |
65 | 0 | return EC_IllegalCall; |
66 | 0 | } |
67 | | |
68 | | |
69 | | |
70 | | void swapBytes(void * value, const Uint32 byteLength, |
71 | | const size_t valWidth) |
72 | | /* |
73 | | * This function swaps byteLength bytes in value. These bytes are separated |
74 | | * in valWidth elements which will be swapped separately. |
75 | | * |
76 | | * Parameters: |
77 | | * value - [in] Array that contains the actual bytes which might have to be swapped. |
78 | | * byteLength - [in] Length of the above array. |
79 | | * valWidth - [in] Specifies how many bytes shall be treated together as one element. |
80 | | */ |
81 | 0 | { |
82 | 0 | Uint8 save; |
83 | | |
84 | | /* in case valWidth equals 2, swap correspondingly */ |
85 | 0 | if (valWidth == 2) |
86 | 0 | { |
87 | 0 | Uint8 *first = &OFstatic_cast(Uint8*, value)[0]; |
88 | 0 | Uint8 *second = &OFstatic_cast(Uint8*, value)[1]; |
89 | 0 | Uint32 times = byteLength / 2; |
90 | 0 | while(times) |
91 | 0 | { |
92 | 0 | --times; |
93 | 0 | save = *first; |
94 | 0 | *first = *second; |
95 | 0 | *second = save; |
96 | 0 | first += 2; |
97 | 0 | second += 2; |
98 | 0 | } |
99 | 0 | } |
100 | | /* if valWidth is greater than 2, swap correspondingly */ |
101 | 0 | else if (valWidth > 2) |
102 | 0 | { |
103 | 0 | size_t i; |
104 | 0 | const size_t halfWidth = valWidth / 2; |
105 | 0 | const size_t offset = valWidth - 1; |
106 | 0 | Uint8 *start; |
107 | 0 | Uint8 *end; |
108 | |
|
109 | 0 | Uint32 times = OFstatic_cast(Uint32, byteLength / valWidth); |
110 | 0 | Uint8 *base = OFstatic_cast(Uint8 *, value); |
111 | |
|
112 | 0 | while (times) |
113 | 0 | { |
114 | 0 | --times; |
115 | 0 | i = halfWidth; |
116 | 0 | start = base; |
117 | 0 | end = base+offset; |
118 | 0 | while (i) |
119 | 0 | { |
120 | 0 | --i; |
121 | 0 | save = *start; |
122 | 0 | *start++ = *end; |
123 | 0 | *end-- = save; |
124 | 0 | } |
125 | 0 | base += valWidth; |
126 | 0 | } |
127 | 0 | } |
128 | 0 | } |
129 | | |
130 | | |
131 | | Uint16 swapShort(const Uint16 toSwap) |
132 | 0 | { |
133 | 0 | Uint8 *swapped = OFreinterpret_cast(Uint8 *, OFconst_cast(Uint16 *, &toSwap)); |
134 | 0 | swap2Bytes(swapped); |
135 | 0 | return *OFreinterpret_cast(Uint16*, swapped); |
136 | 0 | } |