contrib/gel/gevd/gevd_bufferxy.cxx
Go to the documentation of this file.
00001 // This is gel/gevd/gevd_bufferxy.cxx
00002 #include "gevd_bufferxy.h"
00003 //:
00004 // \file
00005 
00006 #include <vcl_fstream.h>
00007 #include <vcl_cstdio.h>
00008 #include <vcl_cstring.h>
00009 #include <vil/vil_pixel_format.h>
00010 #include <vil/vil_image_view.h>
00011 #include <vil/vil_math.h>
00012 
00013 #include <vcl_compiler.h>
00014 #if defined(VCL_VC) || defined(VCL_SUNPRO_CC_5) || defined(VCL_SGI_CC) || defined(VCL_GCC_3) || defined(VCL_GCC_4) || defined(__INTEL_COMPILER)
00015 #define iostream_char char
00016 #else
00017 #define iostream_char unsigned char
00018 #endif
00019 
00020 //============== Constructors and Destructors ======================
00021 
00022 void gevd_bufferxy::Init(int x, int y, int b)
00023 {
00024   SetBitsPixel(b);
00025   SetSizeX(x);
00026   SetSizeY(y);
00027 
00028   // Set the pointers appropriately
00029   typedef unsigned char * byteptr;
00030   yra = new byteptr[y];
00031   xra = new unsigned int[x];
00032   for (int i=0; i < x; i++)
00033     xra[i] = i * GetBytesPixel();
00034 
00035   for (int j=0; j < y; j++)
00036     yra[j] = GetBufferPtr() + j*x*GetBytesPixel();
00037 }
00038 
00039 //: Construct a gevd_bufferxy of width x, height y, and b bits per entry.
00040 gevd_bufferxy::gevd_bufferxy(int x, int y, int b) : gevd_memory_mixin(x*y*(int)((b+7)/8))
00041 {
00042   Init(x, y, b);
00043 }
00044 
00045 //: Construct a gevd_bufferxy of width x, height y, and b bits per entry, and load data from memptr.  Object will not free memptr.
00046 gevd_bufferxy::gevd_bufferxy(int x, int y, int b, void* memptr) : gevd_memory_mixin(x*y*(int)((b+7)/8),memptr)
00047 {
00048   Init(x, y, b);
00049   // Don't delete the buffer when destructing.  MM_PROTECTED should be
00050   // avoided, but with this constructor we do not know how memptr was
00051   // allocated, so we should not attempt to free or delete or delete[]
00052   // it.  If required, the interface could be expanded so the caller
00053   // has a way of telling the object whether to and how to free
00054   // memptr.
00055   SetStatus(MM_PROTECTED);
00056 }
00057 
00058 //: Construct a gevd_bufferxy from a vil1_image
00059 gevd_bufferxy::gevd_bufferxy(vil1_image const& image) : gevd_memory_mixin( image.get_size_bytes() )
00060 {
00061   int sizey= image.rows();
00062   int sizex= image.cols();
00063 
00064   Init(sizex, sizey, image.bits_per_component());
00065 
00066   image.get_section(GetBufferPtr(),     // copy bytes image into buf
00067                     0, 0, sizex, sizey);
00068 }
00069 
00070 //: Construct a gevd_bufferxy from a vil_image
00071 gevd_bufferxy::gevd_bufferxy(vil_image_resource_sptr const& image_s) :
00072   gevd_memory_mixin(image_s->nplanes()*image_s->ni()*image_s->nj()*vil_pixel_format_sizeof_components(image_s->pixel_format()))
00073 {
00074   if (!image_s)
00075   {
00076     vcl_cout << "In gevd_bufferxy - null image_resource\n";
00077     return;
00078   }
00079   vil_image_resource& image = *image_s;
00080   if (image.nplanes()!=1)
00081   {
00082     vcl_cout << "In gevd_bufferxy - can't handle image format, buffer invalid\n";
00083     return;
00084   }
00085   unsigned n_rows= image.nj();
00086   unsigned n_cols= image.ni();
00087 
00088   vil_pixel_format fmt = image.pixel_format();
00089   unsigned n_bytes = vil_pixel_format_sizeof_components(fmt);
00090 #if 0
00091   unsigned n_bits = 8*n_bytes;
00092   Init(n_cols, n_rows, n_bits);
00093 #endif
00094   Init(n_cols, n_rows, 8);
00095   //two cases of interest
00096   switch (n_bytes)
00097   {
00098    case 1:// unsigned byte pixels
00099    {
00100     unsigned char* buf = gevd_memory_mixin::GetBufferPtr();
00101     vil_image_view<unsigned char> view = image.get_view(0, n_cols,
00102                                                         0, n_rows);
00103     vcl_ptrdiff_t istep=view.istep(),jstep=view.jstep();
00104     const unsigned char* row = view.top_left_ptr();
00105     for (unsigned j=0;j<n_rows;++j,row += jstep, buf += jstep)
00106     {
00107       const unsigned char* pixel = row;
00108       unsigned char* buf_pixel = buf;
00109       for (unsigned i=0;i<n_cols;++i,pixel+=istep, buf_pixel += istep)
00110         *buf_pixel = *pixel;
00111     }
00112     break;
00113    }
00114    case 2://unsigned short pixels - convert to byte range for consistency
00115    {
00116     vil_image_view<unsigned short> view = image.get_view(0, n_cols,
00117                                                          0, n_rows);
00118     unsigned short imin=0, imax=0;
00119     vil_math_value_range<unsigned short>(view, imin, imax);
00120     float fmin = static_cast<float>(imin), fmax = static_cast<float>(imax);
00121     float scale = fmax-fmin;
00122     if (scale != 0.f)
00123       scale = 255.f/scale;
00124     else
00125       scale = 1.f;
00126     for (unsigned j=0;j<n_rows;++j)
00127       for (unsigned i=0;i<n_cols;++i)
00128         *((unsigned char*)GetElementAddr(i,j)) =
00129           static_cast<unsigned char>((view(i,j)-imin)*scale);
00130     break;
00131    }
00132    default:
00133     vcl_cout << "In gevd_bufferxy - can't handle pixel type, buffer invalid\n";
00134     return;
00135   }
00136 }
00137 
00138 gevd_bufferxy::~gevd_bufferxy()
00139 {
00140         delete [] yra;
00141         delete [] xra;
00142 }
00143 
00144 gevd_bufferxy::gevd_bufferxy(gevd_bufferxy const& buf) : gevd_memory_mixin(buf)
00145 {
00146   Init(buf.GetSizeX(), buf.GetSizeY(), buf.GetBitsPixel());
00147   vcl_memcpy(yra[0], buf.yra[0], GetSizeX()*GetSizeY()*GetBytesPixel());
00148 }
00149 
00150 //: Write to file.  Note that this can be OS-specific!
00151 void gevd_bufferxy::dump(const char* filename)
00152 {
00153   vcl_ofstream f(filename,vcl_ios_out|vcl_ios_binary);
00154   if (!f) { vcl_cerr << "Cannot open "<< filename <<" for writing\n"; return; }
00155   f << "BUFFERXYDUMP "<< GetSizeX() <<' '<< GetSizeY() <<' '<< GetBitsPixel()
00156 #ifdef WORDS_BIGENDIAN
00157     << " BIGENDIAN DATA\n";
00158 #else
00159     << " LITTLEENDIAN DATA\n";
00160 #endif
00161   iostream_char const* buf = (iostream_char const*)GetBuffer();
00162   f.write(buf, gevd_memory_mixin::GetSize());
00163 }
00164 
00165 static int read_from_file(const char* filename)
00166 {
00167   vcl_ifstream f(filename,vcl_ios_in|vcl_ios_binary); // ios::nocreate is on by default for VCL_WIN32
00168   if (!f) { vcl_cerr <<"Cannot open "<< filename <<" for reading\n"; return -1; }
00169   char l[1024];
00170   f.get(l, 1024); // read single line
00171   int x=-1, y=-1, b=-1; char w;
00172   if ( 4 > vcl_sscanf(l, "BUFFERXYDUMP %d %d %d %c", &x, &y, &b, &w)
00173        || x <= 0 || y <= 0 || b <= 0 )
00174     { vcl_cerr << filename << " is not a gevd_bufferxy dump file\n"; return -1; }
00175 #ifdef WORDS_BIGENDIAN
00176   if (w != 'B')
00177 #else
00178   if (w != 'L')
00179 #endif
00180     vcl_cerr << "Warning: "<<filename<<" was created on a different platform\n";
00181   return x*y*(int)((b+7)/8);
00182 }
00183 
00184 //: Read from file.  Note that this can be OS-specific!
00185 gevd_bufferxy::gevd_bufferxy(const char* filename) : gevd_memory_mixin(read_from_file(filename)),
00186   yra(0), xra(0)
00187 {
00188   if (gevd_memory_mixin::GetSize() > 0) {
00189     vcl_ifstream f(filename,vcl_ios_in|vcl_ios_binary); // ios::nocreate is on by default for VCL_WIN32
00190     char l[1024];
00191     f.get(l, 1024); // read single line
00192     int x=-1, y=-1, b=-1;
00193     vcl_sscanf(l, "BUFFERXYDUMP %d %d %d", &x, &y, &b);
00194     f.get(l[0]); // read end-of-line
00195     Init(x, y, b);
00196     iostream_char* buf = (iostream_char*)GetBuffer();
00197     f.read(buf, gevd_memory_mixin::GetSize());
00198   }
00199   else
00200     vcl_cerr<< "ERROR: This should not happen in gevd_bufferxy::gevd_bufferxy(char const*)\n";
00201 }