Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

gevd_bufferxy.cxx

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

Generated on Thu Jan 10 14:47:16 2008 for contrib/gel/gevd by  doxygen 1.4.4