KWStyle - itkByteSwapper.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkByteSwapper.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:33 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12   Portions of this code are covered under the VTK copyright.
13   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14
15      This software is distributed WITHOUT ANY WARRANTY; without even 
16      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
17 IND *****PURPOSE.  See the above copyright notices for more information.
18
19 =========================================================================*/
20 DEF #ifndef _itkByteSwapper_txx
21 DEF #define _itkByteSwapper_txx
22 #include "itkByteSwapper.h"
23 #include "itkObjectFactory.h"
24 #include <memory>
25
26 namespace itk
27 {
28
29
30 EML
31 // The following are the public methods --------------------------------
32 //
33
34 // Machine definitions
35 #ifdef CMAKE_WORDS_BIGENDIAN
36 template <class T>
37 bool ByteSwapper<T>::SystemIsBigEndian() { return true; }
38 template <class T>
39 bool ByteSwapper<T>::SystemIsLittleEndian() { return false; }
40 #else
41 template <class T>
42 bool ByteSwapper<T>::SystemIsBigEndian() { return false; }
43 template <class T>
44 bool ByteSwapper<T>::SystemIsLittleEndian() { return true; }
45 #endif  
46
47   
48 //------Big Endian methods----------------------------------------------
49
50 // Use different swap methods based on type
51 #ifdef CMAKE_WORDS_BIGENDIAN
52 template <class T>
53 void 
54 ByteSwapper<T>
55 ::SwapFromSystemToBigEndian(T *){}
56 #else
57 template <class T>
58 void 
59 ByteSwapper<T>
60 ::SwapFromSystemToBigEndian(T *p)
61 {
62   switch ( sizeof(T) )
63     {
64     case 1:
65 IND ******return;
66     case 2:
67 IND ******ByteSwapper<T>::Swap2((void *)p);
68 IND ******return;
69     case 4:
70 IND ******ByteSwapper<T>::Swap4((void *)p);      
71 IND ******return;
72     case 8:
73 IND ******ByteSwapper<T>::Swap8((void *)p);      
74 IND ******return;
75     default:  
76 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
77     }
78 }
79 #endif  
80
81 #ifdef CMAKE_WORDS_BIGENDIAN
82 template <class T>
83 void 
84 ByteSwapper<T>
85 LEN ::SwapRangeFromSystemToBigEndian(T *, unsigned long ) // unused arguments removed
86 {  
87   // nothing needs to be done here...
88 }
89 #else
90 template <class T>
91 void 
92 ByteSwapper<T>
93 ::SwapRangeFromSystemToBigEndian(T *p, unsigned long num)
94 {
95   switch ( sizeof(T) )
96     {
97     case 1:
98 IND ******return;
99     case 2:
100 IND ******ByteSwapper<T>::Swap2Range((void *)p,num);
101 IND ******return;
102     case 4:
103 IND ******ByteSwapper<T>::Swap4Range((void *)p,num);      
104 IND ******return;
105     case 8:
106 IND ******ByteSwapper<T>::Swap8Range((void *)p,num);      
107 IND ******return;
108     default:  
109 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
110       return;
111     }
112 }
113 #endif  
114
115 #ifdef CMAKE_WORDS_BIGENDIAN
116 template <class T>
117 void 
118 ByteSwapper<T>
119 ::SwapWriteRangeFromSystemToBigEndian(T *p, int num, OStreamType *fp)
120 {
121   num *= sizeof(T);
122   fp->write((char *)p, num);
123 }
124 #else
125 template <class T>
126 void 
127 ByteSwapper<T>
128 ::SwapWriteRangeFromSystemToBigEndian(T *p, int num, OStreamType *fp)
129 {
130   switch ( sizeof(T) )
131     {
132     case 1:
133 IND ******return;
134     case 2:
135 IND ******ByteSwapper<T>::SwapWrite2Range((void *)p, num, fp);
136 IND ******return;
137     case 4:
138 IND ******ByteSwapper<T>::SwapWrite4Range((void *)p, num, fp);      
139 IND ******return;
140     case 8:
141 IND ******ByteSwapper<T>::SwapWrite8Range((void *)p, num, fp);      
142 IND ******return;
143     default:  
144 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
145     }
146 }
147 #endif
148
149 //------Little Endian methods----------------------------------------------
150
151 #ifdef CMAKE_WORDS_BIGENDIAN
152 template <class T>
153 void 
154 ByteSwapper<T>
155 ::SwapFromSystemToLittleEndian(T *p)
156 {
157   switch ( sizeof(T) )
158     {
159     case 1:
160 IND ******return;
161     case 2:
162 IND ******ByteSwapper<T>::Swap2((void *)p);
163 IND ******return;
164     case 4:
165 IND ******ByteSwapper<T>::Swap4((void *)p);      
166 IND ******return;
167     case 8:
168 IND ******ByteSwapper<T>::Swap8((void *)p);      
169 IND ******return;
170     default:  
171 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
172     }
173 }
174 #else
175 template <class T>
176 void 
177 ByteSwapper<T>
178 ::SwapFromSystemToLittleEndian(T *){}
179 #endif  
180
181
182 #ifdef CMAKE_WORDS_BIGENDIAN
183 template <class T>
184 void 
185 ByteSwapper<T>
186 ::SwapRangeFromSystemToLittleEndian(T *p, unsigned long num) 
187 {
188   switch ( sizeof(T) )
189     {
190     case 1:
191 IND ******return;
192     case 2:
193 IND ******ByteSwapper<T>::Swap2Range((void *)p,num);
194 IND ******return;
195     case 4:
196 IND ******ByteSwapper<T>::Swap4Range((void *)p,num);      
197 IND ******return;
198     case 8:
199 IND ******ByteSwapper<T>::Swap8Range((void *)p,num);      
200 IND ******return;
201     default:  
202 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
203     }
204 }
205 #else
206 template <class T>
207 void 
208 ByteSwapper<T>
209 ::SwapRangeFromSystemToLittleEndian(T *, unsigned long) {}
210 #endif  
211
212 #ifdef CMAKE_WORDS_BIGENDIAN
213 template <class T>
214 void 
215 ByteSwapper<T>
216 ::SwapWriteRangeFromSystemToLittleEndian(T *p, int num, OStreamType *fp)
217 {
218   switch ( sizeof(T) )
219     {
220     case 1:
221 IND ******return;
222     case 2:
223 IND ******ByteSwapper<T>::SwapWrite2Range((void *)p, num, fp);
224 IND ******return;
225     case 4:
226 IND ******ByteSwapper<T>::SwapWrite4Range((void *)p, num, fp);      
227 IND ******return;
228     case 8:
229 IND ******ByteSwapper<T>::SwapWrite8Range((void *)p, num, fp);      
230 IND ******return;
231     default:  
232 IND ******itkGenericExceptionMacro (<< "Cannot swap number of bytes requested");
233     }
234 }
235 #else
236 template <class T>
237 void 
238 ByteSwapper<T>
239 ::SwapWriteRangeFromSystemToLittleEndian(T *p, int num, OStreamType *fp)
240 {
241   num *= sizeof(T);
242   fp->write((char *)p, num);
243 }
244 #endif
245
246 // The following are the protected methods -------------------------
247 //
248
249 //------2-byte methods----------------------------------------------
250
251 // Swap 2 byte word.
252 template <class T>
253 void 
254 ByteSwapper<T>
255 ::Swap2(void *pin)
256 {
257   unsigned short h1,h2;
258   short* p = reinterpret_cast<short*>(pin);
259   
260   h1 = static_cast<unsigned short>(*p) << 8;
261   h2 = static_cast<unsigned short>(*p) >> 8;
262   *p = (short) h1 | h2;
263 }
264
265 // Swap bunch of bytes. Num is the number of two byte words to swap.
266 template <class T>
267 void 
268 ByteSwapper<T>
269 ::Swap2Range(void *ptr, unsigned long num)
270 {
271   char one_byte;
272   char *pos = reinterpret_cast<char *>(ptr);
273   unsigned long i;
274   
275   for (i = 0; i < num; i++)
276     {
277     one_byte = pos[0];
278     pos[0] = pos[1];
279     pos[1] = one_byte;
280     pos = pos + 2;
281     }
282 }
283
284 // Swap bunch of bytes. Num is the number of four byte words to swap.
285 template <class T>
286 void 
287 ByteSwapper<T>
288 ::SwapWrite2Range(void *ptr, unsigned long num, OStreamType *fp)
289 {
290   char one_byte;
291   char *pos;
292   unsigned long i;
293   char *cpy;
294   unsigned long chunkSize = 1000000;
295
296   if (num < chunkSize)
297     {
298     chunkSize = num;
299     }
300   cpy = new char [chunkSize * 2];
301  
302   while (num)
303     {
304     memcpy(cpy, ptr, chunkSize * 2);
305  
306     pos = cpy; 
307     for (i = 0; i < chunkSize; i++)
308       {
309       one_byte = pos[0];
310       pos[0] = pos[1];
311       pos[1] = one_byte;
312       pos = pos + 2;
313       }
314     fp->write((char *)cpy, 2*chunkSize);
315     ptr = (char *) ptr + chunkSize * 2;
316     num -= chunkSize;
317     if (num < chunkSize)
318       {
319       chunkSize = num;
320       }
321     }
322   delete [] cpy;
323 }
324
325 //------4-byte methods----------------------------------------------
326
327 // Swap four byte word.
328 template <class T>
329 void 
330 ByteSwapper<T>
331 ::Swap4(void *ptr)
332 {
333   char one_byte;
334   char *p = reinterpret_cast<char *>(ptr);
335
336   one_byte    = p[0];
337   p[0] = p[3];
338   p[3] = one_byte;
339
340   one_byte    = p[1];
341   p[1] = p[2];
342   p[2] = one_byte;
343 }
344
345 // Swap bunch of bytes. Num is the number of four byte words to swap.
346 template <class T>
347 void 
348 ByteSwapper<T>
349 ::Swap4Range(void *ptr, unsigned long num)
350 {
351   char one_byte;
352   char *pos = reinterpret_cast<char *>(ptr);
353   unsigned long i;
354
355   for (i = 0; i < num; i++)
356     {
357     one_byte = pos[0];
358     pos[0] = pos[3];
359     pos[3] = one_byte;
360     
361     one_byte = pos[1];
362     pos[1] = pos[2];
363     pos[2] = one_byte;
364     pos = pos + 4;
365     }
366 }
367
368 // Swap bunch of bytes. Num is the number of four byte words to swap.
369 template <class T>
370 void 
371 ByteSwapper<T>
372 ::SwapWrite4Range(void *ptr, unsigned long num, OStreamType *fp)
373 {
374   char one_byte;
375   char *pos;
376   unsigned long i;
377   char *cpy;
378   unsigned long chunkSize = 1000000;
379
380   if (num < chunkSize)
381     {
382     chunkSize = num;
383     }
384   cpy = new char [chunkSize * 4];
385  
386   while (num)
387     {
388     memcpy(cpy, ptr, chunkSize * 4);
389     
390     pos = cpy;   
391     for (i = 0; i < chunkSize; i++)
392       {
393       one_byte = pos[0];
394       pos[0] = pos[3];
395       pos[3] = one_byte;
396       
397       one_byte = pos[1];
398       pos[1] = pos[2];
399       pos[2] = one_byte;
400       pos = pos + 4;
401       }
402     fp->write((char *)cpy, 4*chunkSize);
403     ptr  = (char *) ptr + chunkSize*4;
404     num -= chunkSize;
405     if (num < chunkSize)
406       {
407       chunkSize = num;
408       }
409     }
410   delete [] cpy;
411 }
412
413 //------8-byte methods----------------------------------------------
414
415 // Swap 8 byte double precision
416 template <class T>
417 void 
418 ByteSwapper<T>
419 ::Swap8(void *ptr)
420 {
421   char one_byte;
422   char *p = reinterpret_cast<char *>(ptr);
423
424   one_byte    = p[0];
425   p[0] = p[7];
426   p[7] = one_byte;
427
428   one_byte    = p[1];
429   p[1] = p[6];
430   p[6] = one_byte;
431
432   one_byte    = p[2];
433   p[2] = p[5];
434   p[5] = one_byte;
435
436   one_byte    = p[3];
437   p[3] = p[4];
438   p[4] = one_byte;
439 }
440
441 // Swap bunch of bytes. Num is the number of eight byte words to swap.
442 template <class T>
443 void 
444 ByteSwapper<T>
445 ::Swap8Range(void *ptr, unsigned long num)
446 {
447   char one_byte;
448   char *pos = reinterpret_cast<char *>(ptr);
449   unsigned long i;
450
451   for (i = 0; i < num; i++)
452     {
453     one_byte    = pos[0];
454     pos[0] = pos[7];
455     pos[7] = one_byte;
456
457     one_byte    = pos[1];
458     pos[1] = pos[6];
459     pos[6] = one_byte;
460
461     one_byte    = pos[2];
462     pos[2] = pos[5];
463     pos[5] = one_byte;
464
465     one_byte    = pos[3];
466     pos[3] = pos[4];
467     pos[4] = one_byte;
468     pos = pos + 8;
469     }
470 }
471
472 // Swap bunch of bytes. Num is the number of four byte words to swap.
473 template <class T>
474 void 
475 ByteSwapper<T>
476 ::SwapWrite8Range(void *ptr, unsigned long num, OStreamType *fp)
477 {
478   char one_byte;
479   char *pos;
480   unsigned long i;
481   char *cpy;
482   unsigned long chunkSize = 1000000;
483
484   if (num < chunkSize)
485     {
486     chunkSize = num;
487     }
488   cpy = new char [chunkSize * 8];
489  
490   while (num)
491     {
492     memcpy(cpy, ptr, chunkSize * 8);
493     
494     pos = cpy;   
495     for (i = 0; i < chunkSize; i++)
496       {
497       one_byte    = pos[0];
498       pos[0] = pos[7];
499       pos[7] = one_byte;
500
501       one_byte    = pos[1];
502       pos[1] = pos[6];
503       pos[6] = one_byte;
504
505       one_byte    = pos[2];
506       pos[2] = pos[5];
507       pos[5] = one_byte;
508
509       one_byte    = pos[3];
510       pos[3] = pos[4];
511       pos[4] = one_byte;
512       pos = pos + 8;
513       }
514     fp->write((char *)cpy, 8*chunkSize);
515     ptr  = (char *) ptr + chunkSize*8;
516     num -= chunkSize;
517     if (num < chunkSize)
518       {
519       chunkSize = num;
520       }
521     }
522   delete [] cpy;
523 }
524
525 // end namespace itk
526
527 #endif
528

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:01PM
© Kitware Inc.