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 // \endverbatim
00021 
00022 #include "vil_stream_read.h"
00023 #include <vcl_cassert.h>
00024 
00025 #include <vil/vil_stream.h>
00026 #include <vxl_config.h>
00027 
00028 vxl_uint_16 vil_stream_read_big_endian_uint_16(vil_stream *s)
00029 {
00030   vxl_uint_8 bytes[2];
00031   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00032   return vxl_uint_16(bytes[1]) | vxl_uint_16(bytes[0]<<8);
00033 }
00034 
00035 vxl_uint_16 vil_stream_read_little_endian_uint_16(vil_stream *s)
00036 {
00037   vxl_uint_8 bytes[2];
00038   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00039   return vxl_uint_16(bytes[0]) | vxl_uint_16(bytes[1]<<8);
00040 }
00041 
00042 #if VXL_HAS_INT_64
00043 
00044 vxl_uint_64 vil_stream_read_big_endian_uint_64(vil_stream *s)
00045 {
00046   vxl_byte bytes[8];
00047   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00048   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)
00049        | (vxl_uint_64(bytes[0])<<24) | (vxl_uint_64(bytes[1])<<16) | (vxl_uint_64(bytes[2])<< 8) |  vxl_uint_64(bytes[3]);
00050 }
00051 
00052 vxl_uint_64 vil_stream_read_little_endian_uint_64(vil_stream *s)
00053 {
00054   vxl_byte bytes[4];
00055   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00056   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)
00057        | (vxl_uint_64(bytes[3])<<24) | (vxl_uint_64(bytes[2])<<16) | (vxl_uint_64(bytes[1])<< 8) |  vxl_uint_64(bytes[0]);
00058 }
00059 
00060 #endif // VXL_HAS_INT_64
00061 
00062 vxl_uint_32 vil_stream_read_big_endian_uint_32(vil_stream *s)
00063 {
00064   vxl_byte bytes[4];
00065   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00066   return (vxl_uint_32(bytes[0])<<24) | (vxl_uint_32(bytes[1])<<16) | (vxl_uint_32(bytes[2])<<8) | (vxl_uint_32(bytes[3]));
00067 }
00068 
00069 vxl_uint_32 vil_stream_read_little_endian_uint_32(vil_stream *s)
00070 {
00071   vxl_byte bytes[4];
00072   if (s->read(bytes, sizeof bytes) != sizeof bytes) return 0;
00073   return (vxl_uint_32(bytes[3])<<24) | (vxl_uint_32(bytes[2])<<16) | (vxl_uint_32(bytes[1])<<8) | (vxl_uint_32(bytes[0]));
00074 }
00075 
00076 
00077 // The following function should be moved to relevant places in vil soon
00078 // This static function is only needed if it will be used below
00079 #if VXL_LITTLE_ENDIAN
00080 static void swap16(char *a, unsigned n)
00081 {
00082   char c;
00083   for (unsigned i = 0; i < n * 2; i += 2)
00084   {
00085     c = a[i]; a[i] = a[i+1]; a[i+1] = c;
00086   }
00087 }
00088 #endif
00089 
00090 #if VXL_LITTLE_ENDIAN
00091 // The following function should be moved to relevant places in vil soon
00092 // This static function is only needed if it will be used below
00093 static void swap32(char *a, unsigned n)
00094 {
00095   char c;
00096   for (unsigned i = 0; i < n * 4; i += 4)
00097   {
00098     c = a[i];
00099     a[i] = a[i+3];
00100     a[i+3] = c;
00101     c = a[i+1];
00102     a[i+1] = a[i+2];
00103     a[i+2] = c;
00104   }
00105 }
00106 #endif
00107 
00108 // The following function should be moved to relevant places in vil soon
00109 float vil_stream_read_big_endian_float(vil_stream* is)
00110 {
00111   float f;
00112   is->read((char*)&f,4);
00113 #if VXL_LITTLE_ENDIAN
00114   swap32((char*)&f,1);
00115 #endif
00116   return f;
00117 }
00118 
00119 // The following function should be moved to relevant places in vil soon
00120 // Reads in n shorts, assumed to be two bytes, into data[i]
00121 void vil_stream_read_big_endian_int_16(vil_stream* is,
00122                                        vxl_uint_16* data, unsigned n)
00123 {
00124   assert(sizeof(short)==2);
00125   is->read((char*)data,n*2);
00126 #if VXL_LITTLE_ENDIAN
00127   swap16((char*)data,n);
00128 #endif
00129 }