core/vil/vil_stream_read.cxx
Go to the documentation of this file.
00001 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00002 #pragma implementation
00003 #endif
00004 //:
00005 // \file
00006 // \brief read numbers from vil_stream
00007 //
00008 // Functions to read integers and floats from a vil_stream.
00009 // The endianness refers to the format in the stream, not the
00010 // native format of the compiler or execution environment.
00011 //
00012 // \author  fsm
00013 //
00014 // \verbatim
00015 //  Modifications
00016 //   Peter Vanroose, July 2000: corrected serious bug: VXL_LITTLE_ENDIAN not needed
00017 //                       (implementation was wrong for VXL_BIG_ENDIAN machines)
00018 //   Ian Scott, May 2003: rearrange explicit io, to allow for easier expansion.
00019 //   Peter Vanroose - 23 Oct.2003 - Added support for 64-bit int pixels
00020 // \endvarbatim
00021 // \endverbatim
00022 
00023 #include "vil_stream_read.h"
00024 #include <vcl_cassert.h>
00025 
00026 #include <vil/vil_stream.h>
00027 #include <vxl_config.h>
00028 
00029 vxl_uint_16 vil_stream_read_big_endian_uint_16(vil_stream *s)
00030 {
00031   vxl_uint_8 bytes[2];
00032   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00033   return vxl_uint_16(bytes[1]) | vxl_uint_16(bytes[0]<<8);
00034 }
00035 
00036 vxl_uint_16 vil_stream_read_little_endian_uint_16(vil_stream *s)
00037 {
00038   vxl_uint_8 bytes[2];
00039   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00040   return vxl_uint_16(bytes[0]) | vxl_uint_16(bytes[1]<<8);
00041 }
00042 
00043 #if VXL_HAS_INT_64
00044 
00045 vxl_uint_64 vil_stream_read_big_endian_uint_64(vil_stream *s)
00046 {
00047   vxl_byte bytes[8];
00048   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00049   return (vxl_uint_64(bytes[0])<<56) | (vxl_uint_64(bytes[1])<<48) | (vxl_uint_64(bytes[2])<<40) | (vxl_uint_64(bytes[3])<<32)
00050        | (vxl_uint_64(bytes[0])<<24) | (vxl_uint_64(bytes[1])<<16) | (vxl_uint_64(bytes[2])<< 8) |  vxl_uint_64(bytes[3]);
00051 }
00052 
00053 vxl_uint_64 vil_stream_read_little_endian_uint_64(vil_stream *s)
00054 {
00055   vxl_byte bytes[4];
00056   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00057   return (vxl_uint_64(bytes[3])<<56) | (vxl_uint_64(bytes[2])<<48) | (vxl_uint_64(bytes[1])<<40) | (vxl_uint_64(bytes[0])<<32)
00058        | (vxl_uint_64(bytes[3])<<24) | (vxl_uint_64(bytes[2])<<16) | (vxl_uint_64(bytes[1])<< 8) |  vxl_uint_64(bytes[0]);
00059 }
00060 
00061 #endif // VXL_HAS_INT_64
00062 
00063 vxl_uint_32 vil_stream_read_big_endian_uint_32(vil_stream *s)
00064 {
00065   vxl_byte bytes[4];
00066   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00067   return (vxl_uint_32(bytes[0])<<24) | (vxl_uint_32(bytes[1])<<16) | (vxl_uint_32(bytes[2])<<8) | (vxl_uint_32(bytes[3]));
00068 }
00069 
00070 vxl_uint_32 vil_stream_read_little_endian_uint_32(vil_stream *s)
00071 {
00072   vxl_byte bytes[4];
00073   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00074   return (vxl_uint_32(bytes[3])<<24) | (vxl_uint_32(bytes[2])<<16) | (vxl_uint_32(bytes[1])<<8) | (vxl_uint_32(bytes[0]));
00075 }
00076 
00077 
00078 // The following function should be moved to relevant places in vil soon
00079 // This static function is only needed if it will be used below
00080 #if VXL_LITTLE_ENDIAN
00081 static void swap16(char *a, unsigned n)
00082 {
00083   char c;
00084   for (unsigned i = 0; i < n * 2; i += 2)
00085   {
00086     c = a[i]; a[i] = a[i+1]; a[i+1] = c;
00087   }
00088 }
00089 #endif
00090 
00091 #if VXL_LITTLE_ENDIAN
00092 // The following function should be moved to relevant places in vil soon
00093 // This static function is only needed if it will be used below
00094 static void swap32(char *a, unsigned n)
00095 {
00096   char c;
00097   for (unsigned i = 0; i < n * 4; i += 4)
00098   {
00099     c = a[i];
00100     a[i] = a[i+3];
00101     a[i+3] = c;
00102     c = a[i+1];
00103     a[i+1] = a[i+2];
00104     a[i+2] = c;
00105   }
00106 }
00107 #endif
00108 
00109 // The following function should be moved to relevant places in vil soon
00110 float vil_stream_read_big_endian_float(vil_stream* is)
00111 {
00112   float f;
00113   is->read((char*)&f,4);
00114 #if VXL_LITTLE_ENDIAN
00115   swap32((char*)&f,1);
00116 #endif
00117   return f;
00118 }
00119 
00120 // The following function should be moved to relevant places in vil soon
00121 // Reads in n shorts, assumed to be two bytes, into data[i]
00122 void vil_stream_read_big_endian_int_16(vil_stream* is,
00123                                        vxl_uint_16* data, unsigned n)
00124 {
00125   assert(sizeof(short)==2);
00126   is->read((char*)data,n*2);
00127 #if VXL_LITTLE_ENDIAN
00128   swap16((char*)data,n);
00129 #endif
00130 }