diff --git a/Utilities/otbedison/GUI/BgImagPGM.cpp b/Utilities/otbedison/GUI/BgImagPGM.cpp
old mode 100755
new mode 100644
index bfce6715c3cbed5b479d29cdcd1085c3470048f3..636622e9e724c016ff9e3ad9c0fedb5026a4b058
--- a/Utilities/otbedison/GUI/BgImagPGM.cpp
+++ b/Utilities/otbedison/GUI/BgImagPGM.cpp
@@ -8,33 +8,33 @@
 // Modified by: Bogdan Georgescu
 //              read gray pgm
 /////////////////////////////////////////////////////////////////////////////
-
+
 #ifdef __GNUG__
 #pragma implementation "BgImagPGM.h"
 #endif
-
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
-
+
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
-
+
 #ifndef WX_PRECOMP
 #include "wx/setup.h"
 #endif
-
+
 #include "BgImagPGM.h"
 #include <wx/log.h>
 #include <wx/intl.h>
 #include <wx/txtstrm.h>
-
+
 //-----------------------------------------------------------------------------
 // bgPGMHandler
 //-----------------------------------------------------------------------------
-
+
 IMPLEMENT_DYNAMIC_CLASS(bgPGMHandler,wxImageHandler)
-
+
 void bgPGMHandler::Skip_Comment(wxInputStream &stream)
 {
   wxTextInputStream text_stream(stream);
@@ -44,18 +44,18 @@ void bgPGMHandler::Skip_Comment(wxInputStream &stream)
       Skip_Comment(stream);
     }
 }
-
+
 bool bgPGMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
 {
     wxUint32  width, height;
     wxUint16  maxval;
     char      c(0);
     image->Destroy();
-
+
     /*
      * Read the PGM header
      */
-
+
     wxBufferedInputStream buf_stream(stream);
     wxTextInputStream text_stream(buf_stream);
     Skip_Comment(buf_stream);
@@ -96,11 +96,11 @@ bool bgPGMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
             *ptr++=(unsigned char)value;
             *ptr++=(unsigned char)value;
             *ptr++=(unsigned char)value;
-#if wxCHECK_VERSION(2, 3, 0)
-            if (!buf_stream)
-#else
-            if (buf_stream.LastError()!=wxSTREAM_NOERROR)
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+            if (!buf_stream)
+#else
+            if (buf_stream.LastError()!=wxSTREAM_NOERROR)
+#endif
               {
                 if (verbose) wxLogError(_("PNM: File seems truncated."));
                 return FALSE;
@@ -122,26 +122,26 @@ bool bgPGMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
       }
     }
     image->SetMask( FALSE );
-#if wxCHECK_VERSION(2, 3, 0)
-    const wxStreamError err = buf_stream.GetLastError();
-    return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
-#else
-    return (buf_stream.LastError()==wxStream_NOERROR || buf_stream.LastError()==wxStream_EOF);
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+    const wxStreamError err = buf_stream.GetLastError();
+    return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
+#else
+    return (buf_stream.LastError()==wxStream_NOERROR || buf_stream.LastError()==wxStream_EOF);
+#endif
 }
-
+
 bool bgPGMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
 {
     //wxTextOutputStream text_stream(stream);
     //text_stream << "P5" << endl
     //<< image->GetWidth() << " " << image->GetHeight() << endl
     //<< "255" << endl;
-	char header[70];
-    int width, height;
-    width = image->GetWidth();
-    height = image->GetHeight();
-	sprintf(header, "P5\n%d %d\n255\n", width, height);
-	stream.Write(header, strlen(header));
+	char header[70];
+    int width, height;
+    width = image->GetWidth();
+    height = image->GetHeight();
+	sprintf(header, "P5\n%d %d\n255\n", width, height);
+	stream.Write(header, strlen(header));
      unsigned char *ptr = image->GetData();
     // convert it to bw;
     unsigned char *tptr;
@@ -155,13 +155,13 @@ bool bgPGMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUS
     }
     stream.Write(tptr,width*height);
     delete [] tptr;
-#if wxCHECK_VERSION(2, 3, 0)
-    return stream.IsOk();
-#else
-    return (stream.LastError()==wxStream_NOERROR);
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+    return stream.IsOk();
+#else
+    return (stream.LastError()==wxStream_NOERROR);
+#endif
 }
-
+
 bool bgPGMHandler::DoCanRead( wxInputStream& stream )
 {
     off_t pos = stream.TellI();
diff --git a/Utilities/otbedison/GUI/BgImagPGM.h b/Utilities/otbedison/GUI/BgImagPGM.h
old mode 100755
new mode 100644
index 8c4c3be24ed1a319afcb2573b99ab7d1ff03d8b6..637b46b1e5f5f7eb3864c83af6ee0dd00577a4c2
--- a/Utilities/otbedison/GUI/BgImagPGM.h
+++ b/Utilities/otbedison/GUI/BgImagPGM.h
@@ -8,29 +8,29 @@
 // Modified by: Bogdan Georgescu
 //              read gray pgm
 /////////////////////////////////////////////////////////////////////////////
-
+
 #ifndef _BG_IMAGPGM_H_
 #define _BG_IMAGPGM_H_
-
+
 #ifdef __GNUG__
 #pragma interface "BgImagPGM.h"
 #endif
-
+
 #include <wx/image.h>
-
+
 //-----------------------------------------------------------------------------
 // bgPGMHandler
 //-----------------------------------------------------------------------------
-
+
 #define RED_WEIGHT 0.299
 #define GREEN_WEIGHT 0.587
 #define BLUE_WEIGHT 0.114
-
+
 class bgPGMHandler : public wxImageHandler
 {
-
+
   DECLARE_DYNAMIC_CLASS(bgPGMHandler)
-
+
 public:
   inline bgPGMHandler()
   {
@@ -39,14 +39,14 @@ public:
       m_type = wxBITMAP_TYPE_ANY;
       m_mime = "image/pgm";
   };
-
+
   virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 );
   virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE );
   virtual bool DoCanRead( wxInputStream& stream );
-
+
   void Skip_Comment(wxInputStream &stream);
 };
-
+
 #endif
-
+
   // _BG_IMAGPGM_H_
\ No newline at end of file
diff --git a/Utilities/otbedison/GUI/BgImagPNM.cpp b/Utilities/otbedison/GUI/BgImagPNM.cpp
old mode 100755
new mode 100644
index 6fa2dff057097125c792354fca8f9f2ba9e23308..97bcdf2f6ee0a85c097882e2ae6f895cef2a2788
--- a/Utilities/otbedison/GUI/BgImagPNM.cpp
+++ b/Utilities/otbedison/GUI/BgImagPNM.cpp
@@ -8,35 +8,35 @@
 // Modified by: Chris M. Christoudias
 //              read/write pnm images
 /////////////////////////////////////////////////////////////////////////////
-
+
 #ifdef __GNUG__
 #pragma implementation "BgImagPNM.h"
 #endif
-
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
-
+
 #ifdef __BORLANDC__
 #pragma hdrstop
 #endif
-
+
 #ifndef WX_PRECOMP
 #include "wx/setup.h"
 #endif
-
+
 #include "BgImagPNM.h"
 #include <wx/log.h>
 #include <wx/intl.h>
 #include <wx/txtstrm.h>
-#include <string.h>
-#include <stdio.h>
-
+#include <string.h>
+#include <stdio.h>
+
 //-----------------------------------------------------------------------------
 // bgPGMHandler
 //-----------------------------------------------------------------------------
-
+
 IMPLEMENT_DYNAMIC_CLASS(bgPNMHandler,wxImageHandler)
-
+
 void bgPNMHandler::Skip_Comment(wxInputStream &stream)
 {
   wxTextInputStream text_stream(stream);
@@ -46,24 +46,24 @@ void bgPNMHandler::Skip_Comment(wxInputStream &stream)
       Skip_Comment(stream);
     }
 }
-
+
 bool bgPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
 {
     wxUint32  width, height;
     wxUint16  maxval;
     char      c(0);
     image->Destroy();
-
+
     /*
      * Read the PGM header
      */
-
+
     wxBufferedInputStream buf_stream(stream);
     wxTextInputStream text_stream(buf_stream);
     Skip_Comment(buf_stream);
     if (buf_stream.GetC()==wxT('P')) c=buf_stream.GetC();
     switch (c)
-    {
+    {
 		case wxT('2'):
         case wxT('5'):
         case wxT('6'): break;
@@ -97,11 +97,11 @@ bool bgPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
             *ptr++=(unsigned char)value;
             *ptr++=(unsigned char)value;
             *ptr++=(unsigned char)value;
-#if wxCHECK_VERSION(2, 3, 0)
-            if (!buf_stream)
-#else
-            if (buf_stream.LastError()!=wxSTREAM_NOERROR)
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+            if (!buf_stream)
+#else
+            if (buf_stream.LastError()!=wxSTREAM_NOERROR)
+#endif
               {
                 if (verbose) wxLogError(_("PNM: File seems truncated."));
                 return FALSE;
@@ -121,37 +121,37 @@ bool bgPNMHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
          ptr[idx--] = ptr[i];
          ptr[idx--] = ptr[i];
       }
-    }
-	if (c=='6') // Raw color
-	{
-		buf_stream.Read( ptr, width*height*3 );
-	}
+    }
+	if (c=='6') // Raw color
+	{
+		buf_stream.Read( ptr, width*height*3 );
+	}
     image->SetMask( FALSE );
-#if wxCHECK_VERSION(2, 3, 0)
-    const wxStreamError err = buf_stream.GetLastError();
-    return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
-#else
-    return (buf_stream.LastError()==wxStream_NOERROR || buf_stream.LastError()==wxStream_EOF);
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+    const wxStreamError err = buf_stream.GetLastError();
+    return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
+#else
+    return (buf_stream.LastError()==wxStream_NOERROR || buf_stream.LastError()==wxStream_EOF);
+#endif
 }
-
+
 bool bgPNMHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool WXUNUSED(verbose) )
 {
-	char header[70];
-    int width, height;
-    width = image->GetWidth();
-    height = image->GetHeight();
-	sprintf(header, "P6\n%d %d\n255\n", width, height);
+	char header[70];
+    int width, height;
+    width = image->GetWidth();
+    height = image->GetHeight();
+	sprintf(header, "P6\n%d %d\n255\n", width, height);
 	stream.Write(header, strlen(header));
     unsigned char *ptr = image->GetData();
     stream.Write(ptr,width*height*3);
-#if wxCHECK_VERSION(2, 3, 0)
-    return stream.IsOk();
-#else
-    return (stream.LastError()==wxStream_NOERROR);
-#endif
+#if wxCHECK_VERSION(2, 3, 0)
+    return stream.IsOk();
+#else
+    return (stream.LastError()==wxStream_NOERROR);
+#endif
 }
-
+
 bool bgPNMHandler::DoCanRead( wxInputStream& stream )
 {
     off_t pos = stream.TellI();
@@ -161,7 +161,7 @@ bool bgPNMHandler::DoCanRead( wxInputStream& stream )
         switch (stream.GetC())
         {
             case '2':
-            case '5':
+            case '5':
 			case '6':
                 stream.SeekI(pos);
                 return TRUE;
diff --git a/Utilities/otbedison/GUI/BgImagPNM.h b/Utilities/otbedison/GUI/BgImagPNM.h
old mode 100755
new mode 100644
index adcbfcfd75c840fb5ac02c69d7f667a15fd22930..e75744728c2e36ade9ad32bb2f85d37329178ded
--- a/Utilities/otbedison/GUI/BgImagPNM.h
+++ b/Utilities/otbedison/GUI/BgImagPNM.h
@@ -8,20 +8,20 @@
 // Modified by: Chris M. Christoudias
 //              read/write pnm image
 /////////////////////////////////////////////////////////////////////////////
-
+
 #ifndef _BG_IMAGPNM_H_
 #define _BG_IMAGPNM_H_
-
+
 #ifdef __GNUG__
 #pragma interface "BgImagPNM.h"
 #endif
-
+
 #include <wx/image.h>
-
+
 //-----------------------------------------------------------------------------
 // bgPGMHandler
 //-----------------------------------------------------------------------------
-
+
 class bgPNMHandler : public wxImageHandler
 {
   DECLARE_DYNAMIC_CLASS(bgPNMHandler)
@@ -33,12 +33,12 @@ public:
       m_type = wxBITMAP_TYPE_PNM;
       m_mime = "image/pnm";
   };
-
+
   virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 );
   virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE );
   virtual bool DoCanRead( wxInputStream& stream );
-
+
   void Skip_Comment(wxInputStream &stream);
 };
-
-#endif
+
+#endif
diff --git a/Utilities/otbedison/GUI/bgimsystem.cpp b/Utilities/otbedison/GUI/bgimsystem.cpp
old mode 100755
new mode 100644
index 39481dfb20c70ca4b15281aea85e92420456d9f0..a57939d2c1e37ec84c3ad5b16472e686de315788
--- a/Utilities/otbedison/GUI/bgimsystem.cpp
+++ b/Utilities/otbedison/GUI/bgimsystem.cpp
@@ -1,8229 +1,8229 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        bgimsystem.cpp
-// Purpose:     Image processing system
-// Author:      Bogdan Georgescu, Chris M. Christoudias
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu, Chris M. Christoudias
-// Version:     v0.1
-/////////////////////////////////////////////////////////////////////////////
-
-// For compilers that support precompilation, includes "wx/wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-   #pragma hdrstop
-#endif
-
-#ifndef WX_PRECOMP
-   #include "wx/wx.h"
-#endif
-
-#include <wx/toolbar.h>
-#include <wx/progdlg.h>
-
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-   #include "icons/mondrian.xpm"
-   #include "icons/new.xpm"
-   #include "icons/open.xpm"
-   #include "icons/save.xpm"
-   #include "icons/copy.xpm"
-   #include "icons/cut.xpm"
-   #include "icons/paste.xpm"
-   #include "icons/print.xpm"
-   #include "icons/help.xpm"
-#endif
-
-#include <wx/html/htmlwin.h>
-
-#include "BgImagPGM.h"
-#include "BgImagPNM.h"
-
-// Edge detection include stuff
-#include <math.h>
-#include "BgImage.h"
-#include "BgEdge.h"
-#include "BgEdgeList.h"
-#include "BgEdgeDetect.h"
-#include "BgDefaults.h"
-
-#include "msImageProcessor.h"
-
-#include <stdio.h>
-#include <string.h>
-#include "bgimsystem.h"
-
-IMPLEMENT_APP(BgApp)
-// ---------------------------------------------------------------------------
-// global variables
-// ---------------------------------------------------------------------------
-
-BgMdiFrame *g_frame = (BgMdiFrame *) NULL;
-wxList g_children;
-
-// For drawing lines in a canvas
-static long g_xpos = -1;
-static long g_ypos = -1;
-
-static int	gs_nFrames	= 0;
-static bool	on_exit		= false;
-#define DEFAULT_LOG_SIZE 100
-
-// ---------------------------------------------------------------------------
-// event tables
-// ---------------------------------------------------------------------------
-
-BEGIN_EVENT_TABLE(BgMdiFrame, wxMDIParentFrame)
-EVT_MENU(BG_ABOUT, BgMdiFrame::OnAbout)
-EVT_MENU(BG_HELP, BgMdiFrame::OnHelp)
-EVT_MENU(BG_QUIT, BgMdiFrame::OnQuit)
-EVT_MENU(BG_NEW_EDGE_WINDOW, BgMdiFrame::OnNewEdgeWindow)
-EVT_MENU(BG_NEW_SEGM_WINDOW, BgMdiFrame::OnNewSegmWindow)
-EVT_MENU(BG_LOAD_IMAGE, BgMdiFrame::OnLoadImage)
-EVT_MENU(BG_LOAD_IMAGE_EDGE, BgMdiFrame::OnLoadImageEdge)
-EVT_MENU(BG_SEGM_LOAD_IMAGE, BgMdiFrame::OnLoadImageSegm)
-EVT_MENU(BG_SAVE_RESULT, BgMdiFrame::OnSaveResult)
-EVT_MENU(BG_CROSS, BgMdiFrame::ZoomControl)
-EVT_MENU(BG_ZOOM_IN, BgMdiFrame::ZoomControl)
-EVT_MENU(BG_ZOOM_OUT, BgMdiFrame::ZoomControl)
-EVT_MENU(BG_POINTER, BgMdiFrame::ZoomControl)
-EVT_CLOSE(BgMdiFrame::OnClose)
-
-EVT_SIZE(BgMdiFrame::OnSize)
-END_EVENT_TABLE()
-
-// Note that BG_NEW_WINDOW and BG_ABOUT commands get passed
-// to the parent window for processing, so no need to
-// duplicate event handlers here.
-
-BEGIN_EVENT_TABLE(BgMdiEdgeChild, wxMDIChildFrame)
-EVT_MENU(BG_LOAD_IMAGE_EDGE, BgMdiEdgeChild::OnLoadImage)
-EVT_MENU(BG_EDGE_DETECT, BgMdiEdgeChild::OnEdgeDetect)
-EVT_MENU(BG_CHANGE_PARAM_EDGE, BgMdiEdgeChild::OnChangeParam)
-EVT_MENU(BG_CHILD_EDGE_QUIT, BgMdiEdgeChild::OnQuit)
-EVT_MENU(BG_EDGE_VIEW_ORIG, BgMdiEdgeChild::OnViewOrig)
-EVT_MENU(BG_EDGE_VIEW_EDGE, BgMdiEdgeChild::OnViewEdge)
-EVT_MENU(BG_EDGE_SAVE_MAP, BgMdiEdgeChild::OnSaveEdgeMap)
-
-EVT_SET_FOCUS(BgMdiEdgeChild::OnFocus)
-EVT_CLOSE(BgMdiEdgeChild::OnClose)
-EVT_SIZE(BgMdiEdgeChild::OnSize)
-
-EVT_BUTTON(BG_EDGE_DETECT, BgMdiEdgeChild::OnEdgeDetect)
-EVT_BUTTON(BG_CHANGE_PARAM_EDGE, BgMdiEdgeChild::OnChangeParam)
-EVT_CHECKBOX(BG_EDGE_CVIEW_ORIG, BgMdiEdgeChild::OnCViewOrig)
-EVT_CHECKBOX(BG_EDGE_CVIEW_EDGE, BgMdiEdgeChild::OnCViewEdge)
-
-EVT_COMMAND(BG_EVENT_UPDATE_ID, BG_EVENT_UPDATE, BgMdiEdgeChild::OnUpdateNum)
-
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgMdiSegmentChild, wxMDIChildFrame)
-EVT_MENU(BG_SEGM_LOAD_IMAGE, BgMdiSegmentChild::OnLoadImage)
-EVT_MENU(BG_SEGM_SAVE_SEGMENTED, BgMdiSegmentChild::OnSaveSegmentedImage)
-EVT_MENU(BG_SEGM_SAVE_EDGEMAP, BgMdiSegmentChild::OnSaveBoundaries)
-EVT_MENU(BG_CHILD_SEGM_QUIT, BgMdiSegmentChild::OnQuit)
-EVT_MENU(BG_SEGM_SEGMENT, BgMdiSegmentChild::OnSegment)
-EVT_MENU(BG_SEGM_LOAD_MAP, BgMdiSegmentChild::LoadCustomWeightMap)
-EVT_MENU(BG_SEGM_SPEEDUP_NONE, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
-EVT_MENU(BG_SEGM_SPEEDUP_MEDM, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
-EVT_MENU(BG_SEGM_SPEEDUP_HIGH, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
-EVT_MENU(BG_CANVAS_VIEW1_GRADMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
-EVT_MENU(BG_CANVAS_VIEW1_CONFMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
-EVT_MENU(BG_CANVAS_VIEW1_WEITMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
-EVT_MENU(BG_CANVAS_VIEW1_CUSTMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
-EVT_MENU(BG_CANVAS_VIEW2_GRADMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
-EVT_MENU(BG_CANVAS_VIEW2_CONFMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
-EVT_MENU(BG_CANVAS_VIEW2_WEITMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
-EVT_MENU(BG_CANVAS_VIEW2_CUSTMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
-EVT_MENU(BG_CANVAS_SAVE_GRADMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
-EVT_MENU(BG_CANVAS_SAVE_CONFMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
-EVT_MENU(BG_CANVAS_SAVE_WEITMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
-
-EVT_SET_FOCUS(BgMdiSegmentChild::OnFocus)
-EVT_CLOSE(BgMdiSegmentChild::OnClose)
-EVT_SIZE(BgMdiSegmentChild::OnSize)
-
-EVT_BUTTON(BG_SEGM_LOAD_IMAGE, BgMdiSegmentChild::OnLoadImage)
-EVT_BUTTON(BG_SEGM_SEGMENT, BgMdiSegmentChild::OnSegment)
-EVT_BUTTON(BG_SEGM_LOAD_MAP, BgMdiSegmentChild::LoadCustomWeightMap)
-EVT_RADIOBOX(BG_SEGM_VIEW_IMSEG, BgMdiSegmentChild::OnViewImSeg)
-EVT_RADIOBOX(BG_SEGM_OPERATION, BgMdiSegmentChild::OnChangeOperation)
-EVT_CHECKBOX(BG_SEGM_VIEW_EDGES, BgMdiSegmentChild::OnViewBoundaries)
-EVT_CHECKBOX(BG_SEGM_USE_EDGE_MAP, BgMdiSegmentChild::OnUseWeightMap)
-EVT_COMBOBOX(BG_SEGM_CHANGE_PARAMS, BgMdiSegmentChild::OnChangeParameters)
-
-EVT_TEXT(BG_SEGM_TEXT_SIGMAS, BgMdiSegmentChild::OnUpdateTextBoxes)
-EVT_TEXT(BG_SEGM_TEXT_SIGMAR, BgMdiSegmentChild::OnUpdateTextBoxes)
-EVT_TEXT(BG_SEGM_TEXT_MINREG, BgMdiSegmentChild::OnUpdateTextBoxes)
-EVT_TEXT(BG_SEGM_TEXT_GRADWIN, BgMdiSegmentChild::OnUpdateTextBoxes)
-EVT_TEXT(BG_SEGM_TEXT_AIJ, BgMdiSegmentChild::OnUpdateTextBoxes)
-EVT_TEXT(BG_SEGM_TEXT_EPSILON, BgMdiSegmentChild::OnUpdateTextBoxes)
-
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgImCanvas, wxScrolledWindow)
-EVT_RIGHT_DOWN(BgImCanvas::OnMouseRightDown)
-EVT_MOUSE_EVENTS(BgImCanvas::OnEvent)
-
-EVT_MENU(BG_IMC_ADDNODE, BgImCanvas::OnCustomAddNode)
-EVT_MENU(BG_IMC_DELETENODE, BgImCanvas::OnCustomDeleteNode)
-EVT_MENU(BG_IMC_SELTYPE_ELLIPSE, BgImCanvas::OnCTypeEllipse)
-EVT_MENU(BG_IMC_SELTYPE_VLINE, BgImCanvas::OnCTypeVLine)
-EVT_MENU(BG_IMC_SELTYPE_HLINE, BgImCanvas::OnCTypeHLine)
-EVT_MENU(BG_IMC_SELTYPE_LINE, BgImCanvas::OnCTypeLine)
-EVT_MENU(BG_IMC_SELTYPE_BOX, BgImCanvas::OnCTypeBox)
-EVT_MENU(BG_IMC_SELTYPE_CUSTOM, BgImCanvas::OnCTypeCustom)
-
-//EVT_SCROLLWIN(BgImCanvas::OnScroll)
-
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgParamDialog, wxDialog)
-EVT_BUTTON(BG_PARAMD_OK, BgParamDialog::OnOk)
-EVT_BUTTON(BG_PARAMD_CANCEL, BgParamDialog::OnCancel)
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgSpeedSelect, wxDialog)
-EVT_BUTTON(BG_SPEEDSEL_OK, BgSpeedSelect::OnOk)
-EVT_BUTTON(BG_SPEEDSEL_CANCEL, BgSpeedSelect::OnCancel)
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgDialog, wxDialog)
-EVT_BUTTON(BG_DIALOG_OK, BgDialog::OnExit)
-EVT_PAINT(BgDialog::OnPaint)
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgHoverBar, wxWindow)
-EVT_BUTTON(BG_CANVAS_VIEW_BUTTON, BgHoverBar::ShowMenu)
-EVT_BUTTON(BG_CANVAS_SAVE_BUTTON, BgHoverBar::ShowMenu)
-END_EVENT_TABLE()
-
-BEGIN_EVENT_TABLE(BgMenuPanel, wxPanel)
-EVT_BUTTON(BG_CANVAS_VIEW_BUTTON, BgMenuPanel::ShowMenu)
-EVT_BUTTON(BG_CANVAS_SAVE_BUTTON, BgMenuPanel::ShowMenu)
-EVT_SIZE(BgMenuPanel::OnSize)
-END_EVENT_TABLE()
-
-// ===========================================================================
-// implementation
-// ===========================================================================
-
-// ---------------------------------------------------------------------------
-// Global Data used for Multi-Threaded Enviornment
-// ---------------------------------------------------------------------------
-
-bool	stop_flag;
-int		percentDone;
-
-// ---------------------------------------------------------------------------
-// Log function
-// ---------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-// wxLogTextCtrl implementation
-// ----------------------------------------------------------------------------
-
-bgLogTextCtrl::bgLogTextCtrl(wxTextCtrl *pTextCtrl)
-{
-    m_pTextCtrl = pTextCtrl;
-}
-
-void bgLogTextCtrl::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
-{
-    wxString msg;
-    TimeStamp(&msg);
-    msg << szString;
-
-    m_pTextCtrl->AppendText(msg);
-}
-
-#define VAR_LOG_BUFFER_SIZE   (4096)
-
-static wxChar varszBuf[VAR_LOG_BUFFER_SIZE];
-
-FILE* glogfile;
-
-void bgLog(const char* szFormat, ...)
-{
-   va_list argptr;
-   va_start(argptr, szFormat);
-   wxVsnprintf(varszBuf, WXSIZEOF(varszBuf), szFormat, argptr);
-   va_end(argptr);
-   ::wxLogMessage(varszBuf);
-   bgLogFile(varszBuf);
-}
-
-void bgLogVar(const char* first, va_list alist)
-{
-//   va_start(alist, first);
-   wxVsnprintf(varszBuf, WXSIZEOF(varszBuf), first, alist);
-//   va_end(alist);
-   ::wxLogMessage(varszBuf);
-   bgLogFile(varszBuf);
-}
-
-void bgLogFile(const char* szFormat, ...)
-{
-   if (glogfile == 0)
-      glogfile = fopen("filelog.txt", "w");
-   va_list argptr;
-   va_start(argptr, szFormat);
-   vfprintf(glogfile, szFormat, argptr);
-   va_end(argptr);
-   fflush(glogfile);
-}
-
-inline int bgRound(double inline_x)
-{
-    return ((int) (inline_x+0.5));
-}
-
-// ---------------------------------------------------------------------------
-// BgApp
-// ---------------------------------------------------------------------------
-
-// Initialise this in OnInit, not statically
-bool BgApp::OnInit()
-{
-   // Create the main frame window
-   
-   g_frame = new BgMdiFrame((wxFrame *)NULL, -1, "Edge Detection and Image SegmentatiON System (EDISON)",
-      wxPoint(10, 10), wxSize(1024, 768),
-      wxDEFAULT_FRAME_STYLE | wxHSCROLL | wxVSCROLL);
-#ifdef __WXMSW__
-#if 0
-   // Experimental: change the window menu
-   wxMenu* windowMenu = new wxMenu;
-   windowMenu->Append(5000, "My menu item!");
-   frame->SetWindowMenu(windowMenu);
-#endif
-#endif
-   
-   // Give it an icon
-#ifdef __WXMSW__
-   g_frame->SetIcon(wxIcon("bg_icn"));
-#else
-   g_frame->SetIcon(wxIcon( mondrian_xpm ));
-#endif
-
-   // Make a menubar
-   wxMenu *file_menu = new wxMenu;
-   
-   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detect window");
-   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
-   file_menu->Append(BG_LOAD_IMAGE_EDGE, "&Load edge image\tCtrl-L", "Load a new image to perform edge detection");
-   file_menu->Append(BG_SEGM_LOAD_IMAGE, "&Load segment image\tShift-L", "Load a new image to perform segmentation");
-   file_menu->Append(BG_QUIT, "E&xit\tAlt-X", "Quit the program");
-   
-   wxMenu *help_menu = new wxMenu;
-   help_menu->Append(BG_ABOUT, "&About");
-   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
-   
-   wxMenuBar *menu_bar = new wxMenuBar;
-   
-   menu_bar->Append(file_menu, "&File");
-   menu_bar->Append(help_menu, "&Help");
-
-   // Associate the menu bar with the frame
-   g_frame->SetMenuBar(menu_bar);
-   
-   g_frame->CreateStatusBar();
-   
-   g_frame->Show(TRUE);
-   
-   SetTopWindow(g_frame);
-
-#if wxUSE_LIBPNG
-  wxImage::AddHandler( new wxPNGHandler );
-#endif
-
-#if wxUSE_LIBJPEG
-  wxImage::AddHandler( new wxJPEGHandler );
-#endif
-
-#if wxUSE_LIBTIFF
-  wxImage::AddHandler( new wxTIFFHandler );
-#endif
-
-#if wxUSE_GIF
-  wxImage::AddHandler( new wxGIFHandler );
-#endif
-
-#if wxUSE_PCX
-  wxImage::AddHandler( new wxPCXHandler );
-#endif
-
-  wxImage::AddHandler( new bgPNMHandler );
-  wxImage::AddHandler( new bgPGMHandler );
-   return TRUE;
-}
-
-// ---------------------------------------------------------------------------
-// BgMdiFrame
-// ---------------------------------------------------------------------------
-
-// Define my frame constructor
-BgMdiFrame::BgMdiFrame(wxWindow *parent,
-                       const wxWindowID id,
-                       const wxString& title,
-                       const wxPoint& pos,
-                       const wxSize& size,
-                       const long style)
-                       : wxMDIParentFrame(parent, id, title, pos, size, style)
-{
-    logtext_ = new wxTextCtrl(this, -1, "Log window.\n",
-                            wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY);
-    logtext_->SetBackgroundColour("wheat");
-     bglogctrl_ = new bgLogTextCtrl(logtext_);
-    logTargetOld_ = wxLog::SetActiveTarget(bglogctrl_);
-    logsize_ = DEFAULT_LOG_SIZE;
-
-   CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
-   InitToolBar(GetToolBar());
-   
-   //get program location directory
-   strcpy(programDir_, wxGetCwd());
-
-   //get help directory location
-   //(NOTE: This code must be altered to function properly in UNIX.)
-   strcpy(helpDir_, programDir_);
-   strcat(helpDir_, "\\doc\\help.html");
-
-   // Accelerators
-   wxAcceleratorEntry entries[13];
-   entries[0].Set(wxACCEL_ALT, (int) 'E', BG_NEW_EDGE_WINDOW);
-   entries[1].Set(wxACCEL_ALT, (int) 'S', BG_NEW_SEGM_WINDOW);
-   entries[2].Set(wxACCEL_ALT, (int) 'X', BG_QUIT);
-   entries[3].Set(wxACCEL_ALT, (int) 'C', BG_CHILD_EDGE_QUIT);
-   entries[4].Set(wxACCEL_SHIFT, (int) 'C', BG_CHILD_SEGM_QUIT);
-   entries[5].Set(wxACCEL_CTRL, (int) 'H', BG_HELP);
-   entries[6].Set(wxACCEL_CTRL, (int) 'S', BG_EDGE_SAVE_MAP);
-   entries[7].Set(wxACCEL_SHIFT, (int) 'S', BG_SEGM_SAVE_SEGMENTED);
-   entries[8].Set(wxACCEL_CTRL, (int) 'L', BG_LOAD_IMAGE_EDGE);
-   entries[9].Set(wxACCEL_SHIFT, (int) 'L', BG_SEGM_LOAD_IMAGE);
-   entries[10].Set(wxACCEL_SHIFT, (int) 'M', BG_SEGM_LOAD_MAP);
-   entries[11].Set(wxACCEL_CTRL, (int) 'R', BG_EDGE_DETECT);
-   entries[12].Set(wxACCEL_SHIFT, (int) 'R', BG_SEGM_SEGMENT);
-   wxAcceleratorTable accel(13, entries);
-   SetAcceleratorTable(accel);
-   
-   // bgFileLog
-   //glogfile = fopen("filelog.txt", "w");
-   glogfile = 0;
-}
-
-void BgMdiFrame::OnClose(wxCloseEvent& event)
-{
-   if ( event.CanVeto() && (gs_nFrames > 0) )
-   {
-      wxString msg;
-      if (gs_nFrames == 1)
-         msg.Printf(_T("%d window still open, close anyhow?"), gs_nFrames);
-      else
-         msg.Printf(_T("%d windows still open, close anyhow?"), gs_nFrames);
-      if ( wxMessageBox(msg, "Please confirm",
-         wxICON_QUESTION | wxYES_NO) != wxYES )
-      {
-         event.Veto();
-         
-         return;
-      }
-   }
-
-   //indicate that the system is exiting
-   on_exit	= true;
-
-   wxLog::SetActiveTarget(logTargetOld_);
-   delete bglogctrl_;
-   delete logtext_;
-
-   // bgFileLog
-   if (glogfile != 0)
-      fclose(glogfile);
-
-   event.Skip();
-}
-
-//sets the title of the active child frame
-void BgMdiFrame::SetChildTitle(wxMDIChildFrame *activeChild, int zconst, int maxZoom, int minZoom)
-{
-	wxString	title;
-	if(activeChild->GetId() == BG_EDGE_WINDOW)
-	{
-		BgMdiEdgeChild *edgeChild	= (BgMdiEdgeChild *) activeChild;
-		if(maxZoom)
-			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) x %d [Maximum Zoom]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_, zconst);
-		else if(minZoom)
-			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_);
-		else
-			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) x %d [Zoom]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_, zconst);
-	}
-	else if(activeChild->GetId() == BG_SEGM_WINDOW)
-	{
-		BgMdiSegmentChild *segmChild	= (BgMdiSegmentChild *) activeChild;
-		if(maxZoom)
-			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) x %d [Maximum Zoom]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_, zconst);
-		else if(minZoom)
-			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_);
-		else
-			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) x %d [Zoom]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_, zconst);
-	}
-	activeChild->SetTitle(title);
-	return;
-}
-
-//updates toolbar when maximum zoom occurs
-void BgMdiFrame::UpdateZoomControl(wxMDIChildFrame *activeChild, int maxZoom, int minZoom)
-{
-	if(activeChild->GetId()	== BG_EDGE_WINDOW)
-	{
-		if(maxZoom)
-			((BgMdiEdgeChild *) activeChild)->maxZoom_	= true;
-		else
-			((BgMdiEdgeChild *) activeChild)->maxZoom_	= false;
-		if(minZoom)
-			((BgMdiEdgeChild *) activeChild)->minZoom_	= true;
-		else
-			((BgMdiEdgeChild *) activeChild)->minZoom_	= false;
-		((BgMdiEdgeChild *) activeChild)->UpdateZoomControl();
-	}
-	else if (activeChild->GetId() == BG_SEGM_WINDOW)
-	{
-		if(maxZoom)
-			((BgMdiSegmentChild *) activeChild)->maxZoom_	= true;
-		else
-			((BgMdiSegmentChild *) activeChild)->maxZoom_	= false;
-		if(minZoom)
-			((BgMdiSegmentChild *) activeChild)->minZoom_	= true;
-		else
-			((BgMdiSegmentChild *) activeChild)->minZoom_	= false;
-		((BgMdiSegmentChild *) activeChild)->UpdateZoomControl();
-	}
-}
-
-void BgMdiFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-   Close();
-}
-
-void BgMdiFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
-{
-	const int BG_DIALOG_INDENT = 30, BG_DIALOG_TOP_MARGIN = 15;
-	BgDialog aboutDialog(this, -1, "About EDISON", wxPoint(-1,-1), wxSize(450, 300), wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL | wxBORDER | wxSYSTEM_MENU, "aboutDialog");
-	wxFont	myFont(9, wxSWISS, wxNORMAL, wxBOLD, false);
-	BgText	bgText(0, "Edge Detection and Image SegmentatiON System (EDISON) v1.1", myFont, BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN);
-	aboutDialog.AddText(&bgText);
-	myFont.SetWeight(wxNORMAL);
-	myFont.SetUnderlined(true);
-	bgText.SetId(1);
-	bgText.SetFont(myFont);
-	bgText.SetText("Authors");
-	bgText.SetPlotLocation(BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN+15);
-	aboutDialog.AddText(&bgText);
-	myFont.SetUnderlined(false);
-	bgText.SetId(2);
-	bgText.SetFont(myFont);
-	bgText.SetText(": Bogdan Georgescu, Chris Christoudias (freeware) 2002");
-	bgText.SetPlotLocation(BG_DIALOG_INDENT+44, BG_DIALOG_TOP_MARGIN+15);
-	aboutDialog.AddText(&bgText);
-	bgText.SetId(3);
-	bgText.SetText("Center for Advanced Information Processing (CAIP), Rutgers University");
-	bgText.SetPlotLocation(BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN+30);
-	aboutDialog.AddText(&bgText);
-	wxBitmap riul_logo("riul_logo", wxBITMAP_TYPE_RESOURCE), caip_logo("caip_logo", wxBITMAP_TYPE_RESOURCE), rutgers_logo("rutgers_logo", wxBITMAP_TYPE_RESOURCE);
-	BgBitmap myBitmap(&riul_logo, 0, BG_DIALOG_INDENT+20, BG_DIALOG_TOP_MARGIN+60);
-	aboutDialog.AddBitmap(&myBitmap);
-	myBitmap.SetId(1);
-	myBitmap.SetMap(&caip_logo);
-	myBitmap.SetPlotLocation(BG_DIALOG_INDENT+85, BG_DIALOG_TOP_MARGIN+170);
-	aboutDialog.AddBitmap(&myBitmap);
-	myBitmap.SetId(2);
-	myBitmap.SetMap(&rutgers_logo);
-	myBitmap.SetPlotLocation(BG_DIALOG_INDENT+145, BG_DIALOG_TOP_MARGIN+165);
-	aboutDialog.AddBitmap(&myBitmap);
-	aboutDialog.Centre(wxBOTH);
-	aboutDialog.ShowModal();
-}
-
-void BgMdiFrame::OnHelp(wxCommandEvent& WXUNUSED(event) )
-{  
-   wxDialog helpDialog(this, -1, "Help Window", wxPoint(10,10), wxSize(800,600), wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL | wxBORDER | wxSYSTEM_MENU);
-   wxHtmlWindow helpWind(&helpDialog, -1, wxPoint(10,10), wxSize(770,550));
-   helpWind.LoadPage(helpDir_);
-   helpDialog.ShowModal();
-   bgLog("\n");
-}
-
-void BgMdiFrame::OnLoadImage(wxCommandEvent& WXUNUSED(event))
-{
-
-	wxMDIChildFrame *activeChild = GetActiveChild();
-	wxCommandEvent zcev;
-	if(activeChild)
-	{
-		if(activeChild->GetId() == BG_EDGE_WINDOW)
-			((BgMdiEdgeChild*) activeChild)->OnLoadImage(zcev);
-		else if(activeChild->GetId() == BG_SEGM_WINDOW)
-			((BgMdiSegmentChild*) activeChild)->OnLoadImage(zcev);
-	} else
-	{
-		//read an image
-		char *pathname, *filename;
-		GetImageFileInfo(&pathname, &filename);
-		if(pathname)
-		{
-
-			//get current width and height of this window
-			int width, height;
-			GetSize(&width, &height);
-
-			//half window width
-			width = width/2;
-
-			//create an edge window
-			OnNewEdgeWindow(zcev);
-			
-			//load read image into edge window
-			activeChild = GetActiveChild();
-			((BgMdiEdgeChild*) activeChild)->ReadImage(pathname, filename);
-			((BgMdiEdgeChild*) activeChild)->RunEnable();
-			
-			//set position and size of edge detection window
-			activeChild->SetSize(0,-30,width,height);
-			
-			//create a segmentation window
-			OnNewSegmWindow(zcev);
-			
-			//load read image into segment window
-			activeChild = GetActiveChild();
-			((BgMdiSegmentChild*) activeChild)->ReadImage(pathname, filename);
-			((BgMdiSegmentChild*) activeChild)->RunEnable();
-
-			//set position and size of segmnetation window
-			activeChild->SetSize(width,-30,width,height);
-			
-			//de-allocate memory used by filename
-			delete [] filename;
-		}
-	}
-	
-}
-
-void BgMdiFrame::OnLoadImageEdge(wxCommandEvent& WXUNUSED(event))
-{
-   BgMdiEdgeChild* activeChild;
-   activeChild = 0;
-   activeChild = (BgMdiEdgeChild*) GetActiveChild();
-   wxCommandEvent zcev;
-   if (activeChild != 0)
-   {
-      activeChild->OnLoadImage(zcev);
-   } else
-   {
-      OnNewEdgeWindow(zcev);
-      activeChild = (BgMdiEdgeChild*) GetActiveChild();
-      activeChild->OnLoadImage(zcev);
-   }
-}
-
-void BgMdiFrame::OnLoadImageSegm(wxCommandEvent& WXUNUSED(event))
-{
-   BgMdiSegmentChild* activeChild;
-   activeChild = 0;
-   activeChild = (BgMdiSegmentChild*) GetActiveChild();
-   wxCommandEvent zcev;
-   if (activeChild != 0)
-   {
-      activeChild->OnLoadImage(zcev);
-   } else
-   {
-      OnNewSegmWindow(zcev);
-      activeChild = (BgMdiSegmentChild*) GetActiveChild();
-      activeChild->OnLoadImage(zcev);
-   }
-}
-
-void BgMdiFrame::OnSaveResult(wxCommandEvent& WXUNUSED(event))
-{
-	wxMDIChildFrame* activeChild = GetActiveChild();
-	if(activeChild)
-	{
-		wxCommandEvent zcev;
-		if (activeChild->GetId() == BG_EDGE_WINDOW)
-			((BgMdiEdgeChild *) activeChild)->OnSaveEdgeMap(zcev);
-		else if (activeChild->GetId() == BG_SEGM_WINDOW)
-			((BgMdiSegmentChild *) activeChild)->OnSaveSegmentedImage(zcev);
-	}
-}
-
-void BgMdiFrame::OnNewEdgeWindow(wxCommandEvent& WXUNUSED(event) )
-{
-
-   //indicate that another child frame will be created
-   gs_nFrames++;
-
-   // Make another frame, containing a edge processing window
-      BgMdiEdgeChild *subframe = new BgMdiEdgeChild(g_frame, "Edge Detection Frame",
-      wxPoint(-1, -1), wxSize(-1, -1),
-      wxDEFAULT_FRAME_STYLE);
-
-   wxString title;
-   title.Printf(_T("Edge Detection Frame %d"), gs_nFrames);
-   
-   subframe->SetTitle(title);
-   
-   // Give it an icon
-#ifdef __WXMSW__
-   subframe->SetIcon(wxIcon("chrt_icn"));
-#else
-   subframe->SetIcon(wxIcon( mondrian_xpm ));
-#endif
-   
-   // Make a menubar
-   wxMenu *file_menu = new wxMenu;
-   
-   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detection window");
-   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
-   file_menu->Append(BG_LOAD_IMAGE_EDGE, "&Load image\tCtrl-L", "Load image to perform edge detection");
-   file_menu->Append(BG_EDGE_SAVE_MAP, "&Save edge map\tCtrl-S");
-   file_menu->Append(BG_CHILD_EDGE_QUIT, "&Close edge window\tAlt-C", "Close this window");
-   file_menu->Append(BG_QUIT, "E&xit\tAlt-X");
-   
-   wxMenu *edge_menu = new wxMenu;
-   
-   edge_menu->Append(BG_EDGE_DETECT, "Edge Detect\tCtrl-R");
-   edge_menu->Append(BG_CHANGE_PARAM_EDGE, "Change Parameters...");
-
-   wxMenu *view_menu = new wxMenu;
-
-   subframe->miViewOrig_ = new wxMenuItem(view_menu, BG_EDGE_VIEW_ORIG, "Original", "View original", TRUE);
-   subframe->miViewEdge_ = new wxMenuItem(view_menu, BG_EDGE_VIEW_EDGE, "Edge map", "View edge map", TRUE);
-
-   view_menu->Append(subframe->miViewOrig_);
-   view_menu->Append(subframe->miViewEdge_);
-   
-   wxMenu *help_menu = new wxMenu;
-   help_menu->Append(BG_ABOUT, "&About");
-   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
-   
-   wxMenuBar *menu_bar = new wxMenuBar;
-   
-   menu_bar->Append(file_menu, "&File");
-   menu_bar->Append(edge_menu, "&Edge Detect");
-   menu_bar->Append(view_menu, "&View");
-   menu_bar->Append(help_menu, "&Help");
-
-   //disable items on menu bar
-   menu_bar->Enable(BG_EDGE_DETECT, false);
-   menu_bar->Enable(BG_EDGE_SAVE_MAP, false);
-   
-   // Associate the menu bar with the frame
-   subframe->SetMenuBar(menu_bar);
-   
-   subframe->CreateStatusBar();
-   subframe->SetStatusText(title);
-   
-   int width, height;
-   subframe->GetClientSize(&width, &height);
-   
-   subframe->Show(TRUE);
-   subframe->miViewOrig_->Check(TRUE);
-   subframe->miViewEdge_->Check(TRUE);
-}
-
-void BgMdiFrame::OnNewSegmWindow(wxCommandEvent& WXUNUSED(event) )
-{
-
-   //indicate that another child frame will be created
-   gs_nFrames++;
-
-   // Make another frame, containing a edge processing window
-      BgMdiSegmentChild *subframe = new BgMdiSegmentChild(g_frame, "Segmentation Frame",
-      wxPoint(-1, -1), wxSize(-1, -1),
-      wxDEFAULT_FRAME_STYLE);
-
-   wxString title;
-   title.Printf(_T("Segmentation Frame %d"), gs_nFrames);
-   
-   subframe->SetTitle(title);
-   
-   // Give it an icon
-#ifdef __WXMSW__
-   subframe->SetIcon(wxIcon("chrt_icn"));
-#else
-   subframe->SetIcon(wxIcon( mondrian_xpm ));
-#endif
-   
-   // Make a menubar
-   wxMenu *file_menu = new wxMenu;
-   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detection window");
-   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
-   file_menu->Append(BG_SEGM_LOAD_IMAGE, "&Load image\tShift-L", "Load image to perform segmentation");
-   file_menu->Append(BG_SEGM_SAVE_SEGMENTED, "&Save result\tShift-S");
-   file_menu->Append(BG_CHILD_SEGM_QUIT, "&Close window\tShift-C", "Close this window");
-   file_menu->Append(BG_QUIT, "E&xit\tAlt-X");
-   
-   wxMenu *segm_menu = new wxMenu;
-   segm_menu->Append(BG_SEGM_SEGMENT, "Segment Image\tShift-R");
-   segm_menu->AppendSeparator();
-   wxMenu *speedup_menu	= new wxMenu;
-   speedup_menu->Append(BG_SEGM_SPEEDUP_NONE, "&None", "", true);
-   speedup_menu->Append(BG_SEGM_SPEEDUP_MEDM, "&Medium", "", true);
-   speedup_menu->Append(BG_SEGM_SPEEDUP_HIGH, "&High", "", true);
-   wxMenuItem *segm_menu_item	= new wxMenuItem(segm_menu, BG_SEGM_SPEEDUP, "Speedup", "", false, speedup_menu);
-   segm_menu->Append(segm_menu_item);
-
-   wxMenu *weightmap_menu = new wxMenu;
-   weightmap_menu->Append(BG_SEGM_LOAD_MAP,  "Load custom weight &map\tShift-M", "Load map images to perform segmentation");
-   weightmap_menu->AppendSeparator();
-   weightmap_menu->Append(BG_SEGM_USE_MAP, "&Use custom weight map", "", true);
-   
-   wxMenu *help_menu = new wxMenu;
-   help_menu->Append(BG_ABOUT, "&About");
-   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
-
-   wxMenuBar *menu_bar = new wxMenuBar;
-   menu_bar->Append(file_menu, "&File");
-   menu_bar->Append(segm_menu, "&Algorithm");
-   menu_bar->Append(weightmap_menu, "&Weight Map");
-   menu_bar->Append(help_menu, "&Help");
-
-   //disable items on menu bar
-   menu_bar->Enable(BG_SEGM_SEGMENT, false);
-   menu_bar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
-   menu_bar->Enable(BG_SEGM_LOAD_MAP, false);
-   menu_bar->Enable(BG_SEGM_USE_MAP, false);
-
-   //check speedup to medium
-   menu_bar->Check(BG_SEGM_SPEEDUP_MEDM, true);
-
-   // Associate the menu bar with the frame
-   subframe->SetMenuBar(menu_bar);
-   subframe->CreateStatusBar();
-   subframe->SetStatusText(title);
-  
-   subframe->Show(TRUE);
-   subframe->Fit();
-}
-
-void BgMdiFrame::GetImageFileInfo(char **pathname, char **filename)
-{
-
-// get the file name
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-	wxFileDialog filedialog(this,"Choose an image file","","",
-		"*",wxOPEN);
-#else
-	wxFileDialog filedialog(this,"Choose an image file","","",
-		"Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
-		wxOPEN);
-#endif
-
-	//retrieve and check filename
-	*filename = (char *) NULL;
-	*pathname = (char *) NULL;
-   	BgImCanvas *temp = new BgImCanvas(this, this, wxDefaultPosition, wxDefaultSize);
-	if(filedialog.ShowModal()==wxID_OK)
-	{
-		char* temp_str	= (char *) filedialog.GetPath().c_str();
-		*pathname	= new char [strlen(temp_str) + 1];
-		strcpy(*pathname, temp_str);
-		temp_str	= (char *) filedialog.GetFilename().c_str();
-		*filename	= new char [strlen(temp_str) + 1];
-		strcpy(*filename, temp_str);
-		if (temp->SetImage(*pathname) == 0)
-		{
-			delete [] *pathname;
-			delete [] *filename;
-			*pathname	= (char *) NULL;
-			*filename	= (char *) NULL;
-		}
-		else
-			bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
-	}
-
-	//de-allocate memory
-	delete temp;
-
-	//done.
-	return;
-}
-
-//manages toolbar zoom controls
-void BgMdiFrame::ZoomControl(wxCommandEvent& event)
-{
-	//set display
-	wxToolBar	*toolbar = GetToolBar();
-	switch (event.m_id)
-	{
-	case BG_CROSS:
-		toolbar->ToggleTool(BG_CROSS, true);
-		toolbar->ToggleTool(BG_ZOOM_IN, false);
-		toolbar->ToggleTool(BG_ZOOM_OUT, false);
-		toolbar->ToggleTool(BG_POINTER, false);
-		break;
-	case BG_ZOOM_IN:
-		toolbar->ToggleTool(BG_CROSS, false);
-		toolbar->ToggleTool(BG_ZOOM_IN, true);
-		toolbar->ToggleTool(BG_ZOOM_OUT, false);
-		toolbar->ToggleTool(BG_POINTER, false);
-		break;
-	case BG_ZOOM_OUT:
-		toolbar->ToggleTool(BG_CROSS, false);
-		toolbar->ToggleTool(BG_ZOOM_IN, false);
-		toolbar->ToggleTool(BG_ZOOM_OUT, true);
-		toolbar->ToggleTool(BG_POINTER, false);
-		break;
-		//BG_POINTER:
-	default:
-		toolbar->ToggleTool(BG_CROSS, false);
-		toolbar->ToggleTool(BG_ZOOM_IN, false);
-		toolbar->ToggleTool(BG_ZOOM_OUT, false);
-		toolbar->ToggleTool(BG_POINTER, true);
-		break;
-	}
-
-	//set zoom functionality
-	wxMDIChildFrame	*activeChild	= GetActiveChild();
-	if(activeChild->GetId()	== BG_EDGE_WINDOW)
-	{
-		switch (event.m_id)
-		{
-		case BG_CROSS:
-			((BgMdiEdgeChild *) activeChild)->ZoomWindow();
-			break;
-		case BG_ZOOM_IN:
-			((BgMdiEdgeChild *) activeChild)->ZoomIn();
-			break;
-		case BG_ZOOM_OUT:
-			((BgMdiEdgeChild *) activeChild)->ZoomOut();
-			break;
-			//BG_POINTER:
-		default:
-			((BgMdiEdgeChild *) activeChild)->NoZoom();
-			break;
-		}
-	}
-	else if(activeChild->GetId() == BG_SEGM_WINDOW)
-	{
-		switch (event.m_id)
-		{
-		case BG_CROSS:
-			((BgMdiSegmentChild *) activeChild)->ZoomWindow();
-			break;
-		case BG_ZOOM_IN:
-			((BgMdiSegmentChild *) activeChild)->ZoomIn();
-			break;
-		case BG_ZOOM_OUT:
-			((BgMdiSegmentChild *) activeChild)->ZoomOut();
-			break;
-			//BG_POINTER:
-		default:
-			((BgMdiSegmentChild *) activeChild)->NoZoom();
-			break;
-		}
-	}
-
-	return;
-		
-}
-
-
-void BgMdiFrame::OnSize(wxSizeEvent& WXUNUSED(event))
-{
-   int w, h;
-   GetClientSize(&w, &h);
-   logtext_->SetSize(0, h-logsize_, w, logsize_);
-   GetClientWindow()->SetSize(0, 0, w, h-logsize_);
-}
-
-
-void BgMdiFrame::InitToolBar(wxToolBar* toolBar)
-{
-   const int	BITMAP_COUNT = 9;
-   wxBitmap* bitmaps[BITMAP_COUNT];
-   
-#ifdef __WXMSW__
-   bitmaps[0] = new wxBitmap( "icon1", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[1] = new wxBitmap( "icon7", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[2] = new wxBitmap( "icon8", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[3] = new wxBitmap( "icon2", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[4] = new wxBitmap( "icon3", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[5] = new wxBitmap( "icon9", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[6] = new wxBitmap("icon10", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[7] = new wxBitmap("icon11", wxBITMAP_TYPE_RESOURCE);
-   bitmaps[8] = new wxBitmap("icon12", wxBITMAP_TYPE_RESOURCE);
-#else
-   bitmaps[0] = new wxBitmap( bnew_xpm );
-   bitmaps[1] = new wxBitmap( bnsg_xpm );
-   bitmaps[2] = new wxBitmap( bhelp_xpm );
-   bitmaps[3] = new wxBitmap( bopen_xpm );
-   bitmaps[4] = new wxBitmap( bsave_xpm );
-   bitmaps[5] = new wxBitmap( bcros_xpm );
-   bitmaps[6] = new wxBitmap( bzin_xpm );
-   bitmaps[7] = new wxBitmap( bzout_xpm );
-   bitmaps[8] = new wxBitmap( bpoin_xpm );
-
-#endif
-   
-#ifdef __WXMSW__
-   int width = 24;
-#else
-   int width = 16;
-#endif
-   int currentX = 5;
-   
-   //add tools to tool bar
-   toolBar->AddTool( BG_NEW_EDGE_WINDOW, *(bitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "New edge window");
-   currentX += width + 5;
-   toolBar->AddTool( BG_NEW_SEGM_WINDOW, *(bitmaps[1]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "New segment window");
-   currentX += width + 5;
-   toolBar->AddTool( BG_LOAD_IMAGE, *(bitmaps[3]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Load image for processing");
-   currentX += width + 5;
-   toolBar->AddTool( BG_SAVE_RESULT, *(bitmaps[4]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Save result");
-   currentX += width + 5;
-   toolBar->AddSeparator();
-   toolBar->AddTool( BG_CROSS, *(bitmaps[5]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom Window");
-   currentX += width + 5;
-   toolBar->AddTool( BG_ZOOM_IN, *(bitmaps[6]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom In");
-   currentX += width + 5;
-   toolBar->AddTool( BG_ZOOM_OUT, *(bitmaps[7]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom Out");
-   currentX += width + 5;
-   toolBar->AddTool( BG_POINTER, *(bitmaps[8]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Select");
-   currentX += width + 5;
-   toolBar->AddSeparator();
-   toolBar->AddTool( BG_HELP, *bitmaps[2], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Help");
-   
-   //set bitmap size of controls buttons to 20x20
-   wxSize tool_size(20,20);
-   toolBar->SetToolBitmapSize(tool_size);
-
-   toolBar->Realize();
-
-   //disable certain tools
-   toolBar->EnableTool(BG_SAVE_RESULT, false);
-   toolBar->EnableTool(BG_CROSS, false);
-   toolBar->EnableTool(BG_ZOOM_IN, false);
-   toolBar->EnableTool(BG_ZOOM_OUT, false);
-   toolBar->EnableTool(BG_POINTER, false);
-   
-   int i;
-   for (i = 0; i < BITMAP_COUNT; i++)
-      delete bitmaps[i];
-}
-
-// ---------------------------------------------------------------------------
-// BgPointSet
-// ---------------------------------------------------------------------------
-
-BgPointSet::BgPointSet()
-{
-   x_ = y_ = 0;
-   n_ = 0;
-   type_ = 0;
-   pen_.SetColour(*wxBLUE);
-   //pen_.SetColour(*wxWHITE);
-   pen_.SetWidth(1);
-   pen_.SetStyle(wxSOLID);
-}
-
-BgPointSet::~BgPointSet()
-{
-   CleanData();
-}
-
-void BgPointSet::CleanData()
-{
-   if (n_ > 0)
-   {
-      delete [] x_;
-      delete [] y_;
-      x_ = y_ = 0;
-      n_ = 0;
-   }
-}
-
-void BgPointSet::SetPoints(int* x, int* y, int n)
-{
-   CleanData();
-   n_ = n;
-   x_ = new int[n_];
-   y_ = new int[n_];
-   for (int i=0; i<n; i++)
-   {
-      x_[i] = x[i];
-      y_[i] = y[i];
-   }
-}
-
-// ---------------------------------------------------------------------------
-// BgCurveSet
-// ---------------------------------------------------------------------------
-
-BgCurveSet::BgCurveSet()
-{
-   x_ = y_ = 0;
-   xs_ = ys_ = 0;
-   n_ = 0;
-   type_ = -1;
-   pen_.SetColour(*wxBLUE);
-   pen_.SetWidth(3);
-   pen_.SetStyle(wxSOLID);
-   isDragging_ = 0;
-}
-
-BgCurveSet::~BgCurveSet()
-{
-   CleanData();
-}
-
-void BgCurveSet::CleanData()
-{
-   if (n_ > 0)
-   {
-      delete [] x_;
-      delete [] y_;
-      x_ = y_ = 0;
-      n_ = 0;
-   }
-   type_ = -1;
-   xs_ = ys_ = 0;
-}
-
-void BgCurveSet::SetCurve(BgCurveSet* bgc)
-{
-   CleanData();
-   type_ = bgc->type_;
-   n_ = bgc->n_;
-   x_ = new int[n_];
-   y_ = new int[n_];
-   xs_ = bgc->xs_;
-   ys_ = bgc->ys_;
-   for (int i=0; i<n_; i++)
-   {
-      x_[i] = bgc->x_[i];
-      y_[i] = bgc->y_[i];
-   }
-}
-
-void BgCurveSet::SetParamCurve(int type, double* x, double* y, int n, int xs, int ys)
-{
-   CleanData();
-   type_ = type;
-   n_ = n;
-   x_ = new int[n_];
-   y_ = new int[n_];
-   xs_ = xs;
-   ys_ = ys;
-   for (int i=0; i<n; i++)
-   {
-      x_[i] = (int) (x[i]*xs);
-      y_[i] = (int) (ys-y[i]*ys);
-   }
-}
-
-void BgCurveSet::GetParamCurve(double* x, double* y, int& type, int& n)
-{
-   for (int i=0; i<n_; i++)
-   {
-      x[i] = ((double)x_[i])/xs_;
-      y[i] = ((double)(ys_-y_[i]))/ys_;
-   }
-   type = type_;
-   n = n_;
-}
-
-void BgCurveSet::DrawYourself(unsigned char* buf, int val)
-{
-   int j;
-   switch (type_)
-   {
-   case -1:
-      break;
-   case FC_ELLIPSE:
-      DrawEllipticArc(buf, val, -x_[0], y_[0], 2*x_[0], 2*(ys_-y_[0]), 0, 90);
-      break;
-   case FC_VERT_LINE:
-      DrawLine(buf, val, x_[0], 0, x_[0], ys_);
-      break;
-   case FC_HORIZ_LINE:
-      DrawLine(buf, val, 0, y_[0], xs_, y_[0]);
-      break;
-   case FC_LINE:
-      DrawLine(buf, val, 0, y_[0], x_[0], ys_);
-      break;
-   case FC_SQUARE_BOX:
-      DrawLine(buf, val, 0, y_[0], x_[0], y_[0]);
-      DrawLine(buf, val, x_[0], y_[0], x_[0], ys_);
-      break;
-   case FC_CUSTOM:
-      // lines
-      for (j=0; j<(n_-1); j++)
-         DrawLine(buf, val, x_[j], y_[j], x_[j+1], y_[j+1]);
-      // control points
-      for (j=0; j<n_; j++)
-         DrawPoint(buf, val ,x_[j], y_[j]);
-      break;
-   }
-   
-}
-
-void BgCurveSet::DrawPoint(unsigned char* buf, int val, int x, int y)
-{
-   int r, c;
-   int dx, dy;
-   for (dx=-2; dx<=2; dx++)
-   {
-      for (dy=-2; dy<=2; dy++)
-      {
-         c=x+dx;
-         r=y+dy;
-         if ((c>=0) && (c<xs_) && (r>=0) && (r<ys_) && ((abs(dx)+abs(dy))<4))
-            buf[c+r*ys_] = val;
-      }
-   }
-}
-
-void BgCurveSet::DrawLine(unsigned char* buf, int val, int xs, int ys, int xe, int ye)
-{
-   int r, c;
-   double dsx, dsy, dex, dey;
-   if (abs(xs-xe)>abs(ys-ye))
-   {
-      // x scan
-      if (xs > xe)
-      {
-         dsx = xe;
-         dsy = ye;
-         dex = xs;
-         dey = ys;
-      }
-      else 
-      {
-         dex = xe;
-         dey = ye;
-         dsx = xs;
-         dsy = ys;
-      }
-
-      for (c = (int) dsx; c<=(int)dex; c++)
-      {
-         if (c>=0 && c<xs_)
-         {
-            r = bgRound(dey-(dey-dsy)*(dex-c)/(dex-dsx));
-            if (r>=0 && r<ys_)
-            {
-               buf[c+r*xs_] = val;
-               // +/- 1
-               if ((r+1)<ys_) buf[c+(r+1)*xs_] = val;
-               if ((r-1)>=0) buf[c+(r-1)*xs_] = val;
-               // +/- 2
-               if ((r+2)<ys_) buf[c+(r+2)*xs_] = val;
-               if ((r-2)>=0) buf[c+(r-2)*xs_] = val;
-            }
-         }
-      }
-   }
-   else
-   {
-      // y scan
-      if (ys > ye)
-      {
-         dsx = xe;
-         dsy = ye;
-         dex = xs;
-         dey = ys;
-      }
-      else 
-      {
-         dex = xe;
-         dey = ye;
-         dsx = xs;
-         dsy = ys;
-      }
-      
-      // check bounds
-      
-      for (r = (int) dsy; r<=(int) dey; r++)
-      {
-         if (r>=0 && r<ys_)
-         {
-            c = bgRound(dex-(dex-dsx)*(dey-r)/(dey-dsy));
-            if (c>=0 && c<xs_)
-            {
-               buf[c+r*xs_] = val;
-               // +/- 1
-               if ((c+1)<xs_) buf[c+1+r*xs_] = val;
-               if ((c-1)>=0) buf[c-1+r*xs_] = val;
-               // +/- 2
-               if ((c+2)<xs_) buf[c+2+r*xs_] = val;
-               if ((c-2)>=0) buf[c-2+r*xs_] = val;
-            }
-         }
-      }
-   }
-}
-void BgCurveSet::DrawEllipticArc(unsigned char* buf, int val, int x, int y, int w, int h, int sa, int ea)
-{
-   double xc, yc, rx, ry;
-   rx = w/2;
-   ry = h/2;
-   xc = x+rx;
-   yc = y+ry;
-   int r, c;
-
-//   if (rx > ry)
-//   {
-      // x scan
-      for (c = (int) xc; c<=(int) (xc+rx); c++)
-      {
-         if (c>=0 && c<xs_)
-         {
-            r = bgRound(yc-ry*sqrt(1-(c-xc)*(c-xc)/(rx*rx)));
-            if (r>=0 && r<ys_)
-            {
-               buf[c+r*xs_] = val;
-               // +/- 1
-               if ((r+1)<ys_) buf[c+(r+1)*xs_] = val;
-               if ((r-1)>=0) buf[c+(r-1)*xs_] = val;
-               // +/- 2
-               if ((r+2)<ys_) buf[c+(r+2)*xs_] = val;
-               if ((r-2)>=0) buf[c+(r-2)*xs_] = val;
-            }
-         }
-      }
-//   }
-//   else
-//   {
-      // y scan
-      for (r = (int)(yc-ry); r<=(int) yc; r++)
-      {
-         if (r>=0 && r<ys_)
-         {
-            c = bgRound(xc+rx*sqrt(1-(r-yc)*(r-yc)/(ry*ry)));
-            if (c>=0 && c<xs_)
-            {
-               buf[c+r*xs_] = val;
-               // +/- 1
-               if ((c+1)<xs_) buf[c+1+r*xs_] = val;
-               if ((c-1)>=0) buf[c-1+r*xs_] = val;
-               // +/- 2
-               if ((c+2)<xs_) buf[c+2+r*xs_] = val;
-               if ((c-2)>=0) buf[c-2+r*xs_] = val;
-            }
-         }
-      }
-//   }
-}
-
-void BgCurveSet::StartDragging(int x, int y)
-{
-   isDragging_ = 1;
-   int j;
-   switch (type_)
-   {
-   case -1:
-      break;
-   case FC_ELLIPSE:
-      if (abs(x)<3)
-         ltodrag_ = 1;
-      else if (abs(y-ys_)<3)
-         ltodrag_ = 2;
-      else
-         ltodrag_ = 0;
-      break;
-   case FC_VERT_LINE:
-      ltodrag_ = 0;
-      break;
-   case FC_HORIZ_LINE:
-      ltodrag_ = 0;
-      break;
-   case FC_LINE:
-      if (abs(x)<3)
-         ltodrag_ = 1;
-      else if (abs(y-ys_)<3)
-         ltodrag_ = 2;
-      else
-         ltodrag_ = 0;
-      break;
-   case FC_SQUARE_BOX:
-      if (abs((abs(x-x_[0])-abs(y-y_[0])))<3)
-      {
-         // drag corner
-         ltodrag_ = 2;
-      }
-      else if (abs(x-x_[0])>abs(y-y_[0]))
-      {
-         // drag horizontal
-         ltodrag_ = 0;
-      }
-      else
-      {
-         // drag vertical
-         ltodrag_ = 1;
-      }
-      break;
-   case FC_CUSTOM:
-      // find point to drag
-      int mind = abs(x-x_[0]) + abs(y-y_[0]);
-      int cmind, mj;
-      mj = 0;
-      for (j=1; j<n_; j++)
-      {
-         cmind = abs(x-x_[j]) + abs(y-y_[j]);
-         if (cmind < mind)
-         {
-            mind = cmind;
-            mj = j;
-         }
-      }
-      ltodrag_ = mj;
-      break;
-   }
-}
-
-void BgCurveSet::DragTo(int x, int y)
-{
-   if ((x<0) || (y<0) || (x>=xs_) || (y>=ys_))
-      return;
-   double k, ry;
-   switch (type_)
-   {
-   case -1:
-      break;
-   case FC_ELLIPSE:
-      // modify ellipse to drag
-      if (ltodrag_ == 0)
-      {
-         k = ((double)x_[0])/(ys_-y_[0]);
-         ry = sqrt(((double)x*x)/(k*k)+(y-ys_)*(y-ys_));
-         x_[0] = bgRound(k*ry);
-         y_[0] = bgRound(ys_-ry);
-      }
-      else if (ltodrag_ == 1)
-      {
-         y_[0] = y;
-      }
-      else
-      {
-         x_[0] = x;
-      }
-      break;
-   case FC_VERT_LINE:
-      x_[0] = x;
-      break;
-   case FC_HORIZ_LINE:
-      y_[0] = y;
-      break;
-   case FC_LINE:
-      // modify line to drag
-      if (ltodrag_ == 0)
-      {
-         k = ((double) (ys_-y_[0])/x_[0]);
-         y_[0] = ys_-bgRound((double (ys_-y)+k*x));
-         x_[0] = bgRound((double (ys_-y)+k*x)/(k));
-      }
-      else if (ltodrag_ == 1)
-      {
-         y_[0] = y;
-      }
-      else
-      {
-         x_[0] = x;
-      }
-      break;
-   case FC_SQUARE_BOX:
-      if (ltodrag_ == 0)
-         y_[0] = y;
-      else if (ltodrag_ == 1)
-         x_[0] = x;
-      else
-      {
-         x_[0] = x;
-         y_[0] = y;
-      }
-      break;
-   case FC_CUSTOM:
-      // modify line to drag
-      if (ltodrag_ == 0)
-      {
-         y_[0] = y;
-      } else if (ltodrag_ == (n_-1))
-      {
-         x_[n_-1] = x;
-      } else
-      {
-         x_[ltodrag_] = x;
-         y_[ltodrag_] = y;
-      }
-      break;
-   }
-}
-
-void BgCurveSet::EndDragging(int x, int y)
-{
-   isDragging_ = 0;
-}
-
-// ---------------------------------------------------------------------------
-// BgParameterHistory
-// ---------------------------------------------------------------------------
-
-BgParameterHistory::BgParameterHistory( void )
-{
-	params_		= (void *) NULL;
-	listSize_	= 0;
-	next_		= (BgParameterHistory *) NULL;
-}
-
-BgParameterHistory::BgParameterHistory(void *parameters, int itemCount)
-{
-	params_		= parameters;
-	listSize_	= itemCount;
-	next_		= (BgParameterHistory *) NULL;
-}
-
-
-BgParameterHistory::~BgParameterHistory( void )
-{
-	if(params_) delete [] params_;
-}
-
-// ---------------------------------------------------------------------------
-// BgParameterHistoryBox
-// ---------------------------------------------------------------------------
-
-BgParameterHistoryBox::BgParameterHistoryBox(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, int n, long style, const wxValidator& validator, const wxString& name)
-                     : wxComboBox(parent, id, value, pos, size, 0, (wxString*) NULL, style, validator, name)
-{
-	//initialize history list
-	maxCount_		= n;
-	listCount_		= 0;
-	historyList_	= (BgParameterHistory *) NULL;
-
-	//initialize combo box
-	Append("Current");
-	SetSelection(0);
-}
-
-BgParameterHistoryBox::~BgParameterHistoryBox( void )
-{
-	//delete history...
-	BgParameterHistory	*temp;
-	while(historyList_)
-	{
-		temp			= historyList_;
-		historyList_	= historyList_->next_;
-		delete temp;
-	}
-}
-
-void BgParameterHistoryBox::AddParameterList(void *parameters, int itemCount)
-{
-	if(listCount_ < maxCount_)
-	{
-		BgParameterHistory	*newHistory	= new BgParameterHistory(parameters, itemCount);
-		newHistory->next_	= historyList_;
-		historyList_		= newHistory;
-		listCount_++;
-		char str[40];
-		sprintf(str, "Parameter List -%d", listCount_);
-		Append(str);
-	}
-	else
-	{
-		BgParameterHistory	*newHistory	= historyList_;
-		while(newHistory->next_->next_)	newHistory	= newHistory->next_;
-		if(newHistory->next_->params_) delete newHistory->next_->params_;
-		newHistory->next_->params_		= parameters;
-		newHistory->next_->listSize_	= itemCount;
-		newHistory->next_->next_		= historyList_;
-		historyList_					= newHistory->next_;
-		newHistory->next_				= (BgParameterHistory *) NULL;
-	}
-}
-
-void *BgParameterHistoryBox::GetParameterListData(int indexNumber)
-{
-	if(indexNumber < listCount_)
-	{
-		BgParameterHistory	*currentHistory	= historyList_;
-		int count = 0;
-		while(indexNumber != count)
-		{
-			currentHistory	= currentHistory->next_;
-			count++;
-		}
-		return currentHistory->params_;
-	}
-	return (void *) NULL;
-}
-
-int BgParameterHistoryBox::GetParameterListCount(int indexNumber)
-{
-	if(indexNumber < listCount_)
-	{
-		BgParameterHistory	*currentHistory	= historyList_;
-		int count = 0;
-		while(indexNumber != count)
-		{
-			currentHistory	= currentHistory->next_;
-			count++;
-		}
-		return currentHistory->listSize_;
-	}
-	return -1;
-}
-
-void BgParameterHistoryBox::UseParameterList(int indexNumber)
-{
-	if((indexNumber < listCount_) && (indexNumber != 0))
-	{
-		BgParameterHistory	*previousHistory	= historyList_;
-		int count = 0;
-		while(count != indexNumber - 1)
-		{
-			previousHistory	= previousHistory->next_;
-			count++;
-		}
-		BgParameterHistory	*currentHistory		= previousHistory->next_;
-		previousHistory->next_					= currentHistory->next_;
-		currentHistory->next_					= historyList_;
-		historyList_							= currentHistory;
-	}
-	return;
-}
-
-void BgParameterHistoryBox::SetCurrentList(void *parameters, int itemCount)
-{
-	currentList_.params_	= parameters;
-	currentList_.listSize_	= itemCount;
-}
-
-void *BgParameterHistoryBox::GetCurrentListData( void )
-{
-	return currentList_.params_;
-}
-
-int BgParameterHistoryBox::GetCurrentListCount( void )
-{
-	return currentList_.listSize_;
-}
-
-// ---------------------------------------------------------------------------
-// BgText
-// ---------------------------------------------------------------------------
-
-//default constructor
-BgText::BgText(void)
-{
-	text_	= (char *)	NULL;
-	font_	= (wxFont *)	NULL;
-	id_		= 0;
-	x_		= 0;
-	y_		= 0;
-}
-
-//overloaded constructor
-BgText::BgText(int id, char *text, wxFont font, int x, int y)
-{
-	text_		= new char [strlen(text) + 1];
-	strcpy(text_, text);
-	font_		= new wxFont;
-	(*font_)	= font;
-	id_			= id;
-	x_			= x;
-	y_			= y;
-}
-
-//destructor
-BgText::~BgText(void)
-{
-	delete text_;
-	delete font_;
-}
-
-//sets text string
-//pre : text is a character string used to set the text
-//      field of the text object
-//post: the text field of the text object has been set to text
-void BgText::SetText(char *text)
-{
-	if((text_)&&(strlen(text) > strlen(text_)))
-	{
-		delete [] text_;
-		text_	= new char [strlen(text) + 1];
-	}
-	strcpy(text_, text);
-	return;
-}
-
-//sets font of text
-//pre : font specifies the new font of the text object
-//post: the font of the text object has been changed to font
-void BgText::SetFont(wxFont font)
-{
-	if(!font_)	font_	= new wxFont;
-	(*font_)	= font;
-	return;
-}
-
-//sets id of text
-//pre : id is the new id of the text object
-//post: the id of the text object has been set to id
-void BgText::SetId(int id)
-{
-	id_	= id;
-}
-
-//sets plot location of text
-//pre : (x,y) determine the new plot location of the text object
-//post: the plot location of the text object has been set to (x,y)
-void BgText::SetPlotLocation(int x, int y)
-{
-	x_	= x;
-	y_	= y;
-}
-
-// ---------------------------------------------------------------------------
-// BgTextObj
-// ---------------------------------------------------------------------------
-
-//constructor
-BgTextObj::BgTextObj(BgText *text)
-{
-	text_	= new BgText(text->id_, text->text_, *(text->font_), text->x_, text->y_);
-	next_	= NULL;
-}
-
-//destructor
-BgTextObj::~BgTextObj(void)
-{
-	delete text_;
-}
-
-// ---------------------------------------------------------------------------
-// BgTextList
-// ---------------------------------------------------------------------------
-
-// *** public methods *** //
-
-//constructor
-BgTextList::BgTextList(void)
-{
-	head_		= cur_	= (BgTextObj *) NULL;
-	itemcount_	= 0;
-}
-
-//destructor
-BgTextList::~BgTextList(void)
-{
-	cur_ = head_;
-	while(cur_)
-		DeleteText();
-}
-
-//adds text object to list
-//pre : text is a text object to be added to the list
-//post: text has been added to the list
-int BgTextList::AddText(BgText *text)
-{
-	//search for existsing text object
-	int id	= text->id_;
-	cur_	= head_;
-	while((cur_)&&(cur_->text_->id_ != id))
-		cur_ = cur_->next_;
-
-	//if it exists change its contents
-	if(cur_)
-	{
-		BgText *tmp_text	= cur_->text_;
-		tmp_text->SetText(text->text_);
-		tmp_text->SetFont(*(text->font_));
-		tmp_text->SetPlotLocation(text->x_, text->y_);
-	}
-	//otherwise add it to existing list
-	else
-	{
-		BgTextObj	*temp;
-		if((temp = new BgTextObj(text)) == NULL)
-			return 1;
-		
-		temp->next_	= head_;
-		if(head_ == NULL)
-			cur_	= temp;
-		head_		= temp;
-		itemcount_++;
-	}
-
-	return 0;
-}		
-
-//removes text object from list
-//pre : textId is the id of the text to be removed from the
-//      list
-//post: text object having id textId has been removed from the
-//      list if it exists (1 is returned upon error)
-int BgTextList::RemoveText(int textId)
-{
-	cur_ = head_;
-	while((cur_)&&(cur_->text_->id_ != textId))
-		cur_	= cur_->next_;
-
-	if(cur_)
-	{
-		DeleteText();
-		return 0;
-	}
-	else
-		return 1;
-}
-
-//returns text object from text list
-//post: the text object pointed to by cur_ is returned
-BgText	*BgTextList::GetText(void)
-{
-	if(cur_)
-	{
-		BgText	*text;
-		text	= cur_->text_;
-		cur_	= cur_->next_;
-		return text;
-	}
-	else
-		return (BgText *) NULL;
-}
-
-//resets cur_ pointer to head of the list
-void BgTextList::ResetList(void)
-{
-	cur_	= head_;
-}
-
-//returns the number of text objects contained
-//within the list
-//post: count of text objects contained by list is returned
-int	BgTextList::GetTextCount(void)
-{
-	return itemcount_;
-}
-
-// *** private methods ***
-
-//deletes a text object node pointed to
-//by cur_
-//post: text object has been deleted from the text list
-void BgTextList::DeleteText(void)
-{
-	if(cur_ == head_)
-	{
-		head_	= head_->next_;
-		delete cur_;
-		cur_		= head_;
-	}
-	else
-	{
-		BgTextObj	*temp = cur_;
-		cur_	= cur_->next_;
-		if(!cur_)	cur_	= head_;
-		delete temp;
-	}
-}
-
-// ---------------------------------------------------------------------------
-// BgBitmap
-// ---------------------------------------------------------------------------
-
-//default constructor
-BgBitmap::BgBitmap(void)
-{
-	bitmap_		= (wxBitmap *) NULL;
-	location_x_	= location_y_	= 0;
-	id_			= 0;
-}
-
-//overloaded constructor
-BgBitmap::BgBitmap(wxBitmap *bitmap, int id, int location_x, int location_y)
-{
-	bitmap_		= new wxBitmap;
-	(*bitmap_)	= (*bitmap);
-	id_			= id;
-	location_x_	= location_x;
-	location_y_	= location_y;
-}
-
-//destructor
-BgBitmap::~BgBitmap(void)
-{
-	if(bitmap_)	delete bitmap_;
-}
-
-//set bitmap content
-//pre : bitmap is the new bitmap content
-//post: bitmap content has been changed to that of bitmap
-void BgBitmap::SetMap(wxBitmap *bitmap)
-{
-	if(!bitmap_)	bitmap_	= new wxBitmap;
-	(*bitmap_)	= (*bitmap);
-}
-
-//set plot location
-//pre : (location_x, location_y) define new plot location of bitmap
-//post: plot location of bitmap has been set to (location_x, location_y)
-void BgBitmap::SetPlotLocation(int location_x, int location_y)
-{
-	location_x_	= location_x;
-	location_y_	= location_y;
-}
-
-//set bitmap id
-//pre : id is the new bitmap id
-//post: the bitmap id has been set to id
-void BgBitmap::SetId(int id)
-{
-	id_	= id;
-}
-
-// ---------------------------------------------------------------------------
-// BgBitmapObj
-// ---------------------------------------------------------------------------
-
-//default constructor
-BgBitmapObj::BgBitmapObj(void)
-{
-	bitmap_	= (BgBitmap *) NULL;
-	next_	= (BgBitmapObj *) NULL;
-}
-
-//overloaded constructor
-BgBitmapObj::BgBitmapObj(BgBitmap* bitmap)
-{
-	bitmap_	= new BgBitmap(bitmap->bitmap_, bitmap->id_,
-						   bitmap->location_x_, bitmap->location_y_);
-	next_	= (BgBitmapObj *) NULL;
-}
-
-//destructor
-BgBitmapObj::~BgBitmapObj(void)
-{
-	if(bitmap_)	delete bitmap_;
-}
-
-// ---------------------------------------------------------------------------
-// BgBitmap
-// ---------------------------------------------------------------------------
-
-//constructor
-BgBitmapList::BgBitmapList(void)
-{
-	head_		= cur_	= (BgBitmapObj *) NULL;
-	itemcount_	= 0;
-}
-
-//destuctor
-BgBitmapList::~BgBitmapList(void)
-{
-	cur_ = head_;
-	while(cur_)
-		DeleteBitmap();
-}
-
-//add a bitmap object to the list
-//pre : bitmap is a bitmap object to be added to the list
-//post: bitmap has been added to the list
-int BgBitmapList::AddBitmap(BgBitmap *bitmap)
-{
-	BgBitmapObj	*temp;
-	if((temp = new BgBitmapObj(bitmap)) == NULL)
-		return 1;
-
-	temp->next_	= head_;
-	if(head_ == NULL)
-		cur_	= temp;
-	head_		= temp;
-	itemcount_++;
-
-	return 0;
-}		
-
-//remove bitmap from list
-//pre : bitmap is to be removed from list
-//post: bitmap has been removed from the list
-void BgBitmapList::RemoveBitmap(BgBitmap *bitmap)
-{
-	int	id	= bitmap->id_;
-	cur_	= head_;
-	while((cur_)&&(cur_->bitmap_->id_ != id))
-		cur_	= cur_->next_;
-	DeleteBitmap();
-}
-
-//get bitmap from the list pointed to by cur_
-//post: bitmap pointed to by cur_ has been returned
-//      and cur_ has been incremented to the next list
-//      item
-BgBitmap *BgBitmapList::GetBitmap(void)
-{
-	BgBitmap	*temp	= (BgBitmap *)	NULL;
-	if(cur_)
-	{
-		temp	= cur_->bitmap_;
-		cur_	= cur_->next_;
-	}
-
-	return temp;
-}
-
-//reset bitmap list cur_ pointer
-//post: cur_ has been set to the head of the list
-void BgBitmapList::ResetList(void)
-{
-	cur_	= head_;
-}
-
-//get the number of bitmaps stored by list
-//post: bitmap count has been returned
-int BgBitmapList::GetBitmapCount(void)
-{
-	return itemcount_;
-}
-
-//delete bitmap object from list
-//post: bitmap object pointed to by cur has been deleted
-void BgBitmapList::DeleteBitmap(void)
-{
-	if(cur_)
-	{
-		BgBitmapObj	*temp	= cur_;
-		cur_				= cur_->next_;
-		delete temp;
-		itemcount_--;
-	}
-}
-
-// ---------------------------------------------------------------------------
-// BgAxis
-// ---------------------------------------------------------------------------
-
-//default constructor
-BgAxis::BgAxis(void)
-{
-	start_x_	= 0; start_y_	= 0;
-	length_		= 0;
-	ticknum_	= 0;
-	direction_	= 0;
-	start_val_	= 0; stop_val_	= 0;
-	label_		= (BgText *) NULL;
-	rotation_	= 0;
-}
-
-//overloaded constructor
-BgAxis::BgAxis(int start_x, int start_y, int length, int ticknum, int direction, float start_val, float stop_val)
-{
-	start_x_	= start_x;
-	start_y_	= start_y;
-	length_		= length;
-	ticknum_	= ticknum;
-	direction_	= direction;
-	start_val_	= start_val;
-	stop_val_	= stop_val;
-	label_		= (BgText *) NULL;
-	rotation_	= 0;
-}
-
-//destuctor
-BgAxis::~BgAxis(void)
-{
-	if(label_)	delete label_;
-}
-
-//set plotting origin
-//pre : (start_x, start_y) specify the new axis plotting origin
-//post: axis plotting origin has been set to (start_x, start_y)
-void BgAxis::SetPlotOrigin(int start_x, int start_y)
-{
-	start_x_	= start_x;
-	start_y_	= start_y;
-}
-
-//set axis length
-//pre : length specifies the new length of the axis
-//post: the axis lengh has been set to length
-void BgAxis::SetLength(int length)
-{
-	length_		= length;
-}
-
-//set axis tick number
-//pre : ticknum is the new tick number of the axis
-//post: the axis tick number has been set to ticknum
-void BgAxis::SetTicknum(int ticknum)
-{
-	ticknum_	= ticknum;
-}
-
-//set axis boundaries
-//pre : (start_val, stop_val) define the new axis boundaries
-//post: the axis boundaries have been set to (start_val, stop_val)
-void BgAxis::SetBounds(float start_val, float stop_val)
-{
-	start_val_	= start_val;
-	stop_val_	= stop_val;
-}
-
-//add axis label
-//pre : label specifies the axis label
-//post: the axis has been labeled using label
-void BgAxis::Label(BgText *label)
-{
-	if(label_)	delete label_;
-	char *text	= label->text_;
-	int label_length	= 3*strlen(text);
-	//horizontal axis
-	if(direction_ == 0)
-	{
-		label_x_	= start_x_ + length_/2 - label_length;
-		label_y_	= start_y_ + 30;
-	}
-	//vertical axis
-	else
-	{
-		label_x_	= start_x_ - 60;
-		label_y_	= start_y_ - length_/2 + label_length;
-	}
-	label_	= new BgText(label->id_, text, *(label->font_), label_x_, label_y_);
-}
-
-//removes axis label
-//post: the axis label has been removed
-void BgAxis::RemoveLabel(void)
-{
-	if(label_)	delete label_;
-	label_	= (BgText *) NULL;
-}
-
-//sets label rotation
-//pre : rotation specifies clockwise label rotation (rotation = 0
-//      leaves the label parallel to the axis)
-//post: label rotation has been set to rotation
-void BgAxis::SetLabelRotation(int rotation)
-{
-	rotation_	= rotation;
-}
-
-//draw axis object
-//pre : dc is a dc object used to draw onto a window
-//post: the axis has been drawn onto the window using
-//      using the dc object
-void BgAxis::PlotAxis(wxDC *dc)
-{
-	//set tick length
-	int	ticklength = 8;
-
-	//calculate axis ending locations
-	int	end_x	= start_x_ + length_;
-	int	end_y	= start_y_ - length_;
-
-	//define shift in x and y direction
-	int	shift_x	= 5;
-	int	shift_y	= 5;
-
-	//create font
-	wxFont plotFont(7, wxSWISS, wxNORMAL, wxNORMAL, false, "", wxFONTENCODING_DEFAULT);
-
-	//plot axis line
-	//horizontal axis
-	if(direction_ == 0)
-	{
-		//draw axis line
-		dc->DrawLine(start_x_, start_y_, end_x, start_y_);
-		dc->DrawLine(start_x_, start_y_+1, end_x, start_y_+1);
-
-		//draw tick marks
-		int	increment	= length_/ticknum_;
-		if(length_%ticknum_ != 0)	increment++;
-		int	x_location	= start_x_;
-		while(x_location < end_x)
-		{
-			dc->DrawLine(x_location, start_y_, x_location, start_y_+ticklength);
-			dc->DrawLine(x_location+1, start_y_, x_location+1, start_y_+ticklength);
-			x_location	= x_location + increment;
-		}
-		dc->DrawLine(end_x-1, start_y_, end_x-1, start_y_+ticklength);
-		dc->DrawLine(end_x, start_y_, end_x, start_y_+ticklength);
-
-		//draw floating point axis markers
-		x_location	= start_x_ - shift_x;
-		float	marker_x			= start_val_;
-		float	marker_increment	= (stop_val_ - start_val_)/ticknum_;
-		char	marker_str[8];
-		int i	= 0, fixed_y	= start_y_ + 10;
-		char	align[6];
-		if(stop_val_ < 10)
-			strcpy(align, "%4.2f");
-		else
-		{
-			strcpy(align, "%4.0f");
-			x_location	= x_location - shift_x;
-			shift_x		= 2*shift_x;
-		}
-		dc->SetFont(plotFont);
-		for(i = 0; i < ticknum_; i++)
-		{
-			sprintf(marker_str, align, marker_x);
-			dc->DrawText(marker_str, x_location, fixed_y);
-			marker_x	+= marker_increment;
-			x_location	+= increment;
-		}
-		sprintf(marker_str, align, marker_x);
-		dc->DrawText(marker_str, end_x - shift_x, fixed_y);
-
-		//add label
-		if(label_)
-		{
-			dc->SetFont(*(label_->font_));
-			dc->DrawRotatedText(label_->text_, label_x_, label_y_, 0+rotation_);
-		}
-	}
-	//vertical axis
-	else
-	{
-		//draw axis line
-		dc->DrawLine(start_x_, start_y_, start_x_, end_y);
-		dc->DrawLine(start_x_-1, start_y_, start_x_-1, end_y);
-
-		//draw tick marks
-		int	increment	= length_/ticknum_;
-		if(length_%ticknum_ != 0)	increment++;
-		int	y_location	= end_y;
-		while(y_location < start_y_)
-		{
-			dc->DrawLine(start_x_, y_location, start_x_-ticklength, y_location);
-			dc->DrawLine(start_x_, y_location+1, start_x_-ticklength, y_location+1);
-			y_location	= y_location + increment;
-		}
-		dc->DrawLine(start_x_, start_y_, start_x_-ticklength, start_y_);
-		dc->DrawLine(start_x_, start_y_+1, start_x_-ticklength, start_y_+1);
-
-		//draw floating point axis markers
-		y_location	= start_y_;
-		float	marker_y			= start_val_;
-		float	marker_increment	= (stop_val_ - start_val_)/ticknum_;
-		char	marker_str[8];
-		int i	= 0, fixed_x = start_x_ - 30;
-		char	align[6];
-		if(stop_val_ < 10)
-			strcpy(align, "%4.2f");
-		else
-			strcpy(align, "%4.0f");
-		dc->SetFont(plotFont);
-		sprintf(marker_str, align, marker_y);
-		dc->DrawText(marker_str, fixed_x, y_location - shift_y);
-		marker_y	+= marker_increment;
-		y_location	-= increment;
-		for(i = 1; i < ticknum_; i++)
-		{
-			sprintf(marker_str, align, marker_y);
-			dc->DrawText(marker_str, fixed_x, y_location);
-			marker_y	+= marker_increment;
-			y_location	-= increment;
-		}
-		sprintf(marker_str, align, marker_y);
-		dc->DrawText(marker_str, fixed_x, end_y - shift_y);
-
-		//add label
-		if(label_)
-		{
-			dc->SetFont(*(label_->font_));
-			dc->DrawRotatedText(label_->text_, label_x_, label_y_, 90+rotation_);
-		}
-	}
-}
-
-// ---------------------------------------------------------------------------
-// BgThread
-// ---------------------------------------------------------------------------
-
-BgThread::BgThread(wxThreadKind kind, void foo(void*), void *Object) : wxThread(kind)
-{
-	function_	= foo;
-	Object_		= Object;
-}
-
-BgThread::~BgThread( void )
-{
-	function_	= NULL;
-	Object_		= NULL;
-}
-
-void *BgThread::Entry( void )
-{
-	function_(Object_);
-	return (void *) NULL;
-}
-
-// ---------------------------------------------------------------------------
-// BgDialog
-// ---------------------------------------------------------------------------
-
-BgDialog::BgDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
-		: wxDialog(parent, id, title, pos, size, style, name)
-{
-	
-	okButton_	= new wxButton(this, BG_DIALOG_OK, "OK", wxPoint(size.GetWidth()/2-40, size.GetHeight()-60));
-}
-
-BgDialog::~BgDialog( void )
-{
-	delete okButton_;
-}
-
-void BgDialog::AddText(BgText *text)
-{
-	tlist_.AddText(text);
-}
-
-void BgDialog::AddBitmap(BgBitmap *bitmap)
-{
-	blist_.AddBitmap(bitmap);
-}
-
-void BgDialog::RemoveText(int id)
-{
-	tlist_.RemoveText(id);
-}
-
-void BgDialog::RemoveBitmap(BgBitmap *bitmap)
-{
-	blist_.RemoveBitmap(bitmap);
-}
-
-void BgDialog::OnPaint(wxPaintEvent& WXUNUSED(event))
-{
-
-	wxPaintDC	dc(this);
-
-	//draw new text to the image from text object list
-	BgText	*bgText;
-	tlist_.ResetList();
-	while(bgText = tlist_.GetText())
-	{
-		dc.SetFont(*(bgText->font_));
-		dc.DrawText(bgText->text_, bgText->x_, bgText->y_);
-	}
-
-	//draw bitmaps
-	blist_.ResetList();
-	BgBitmap	*bitmap;
-	while(bitmap = blist_.GetBitmap())
-		dc.DrawBitmap(*(bitmap->bitmap_), bitmap->location_x_, bitmap->location_y_, true);
-
-}
-
-void BgDialog::OnExit(wxCommandEvent& WXUNUSED(event))
-{
-	EndModal(wxID_OK);
-}
-
-// ---------------------------------------------------------------------------
-// BgHoverBar
-// ---------------------------------------------------------------------------
-
-BgHoverBar::BgHoverBar(wxWindow* parent, wxWindowID id, int gradViewId, int confViewId, int weitViewId, int custViewId, int gradSaveId, int confSaveId, int weitSaveId)
-		  : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER)
-{
-	//set the size of the window
-	SetSize(120,30);
-
-	//place a button using a bitmap
-	menuButton1_	= new wxBitmapButton(this, BG_CANVAS_VIEW_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(33,2), wxSize(18,20));
-	menuButton2_	= new wxBitmapButton(this, BG_CANVAS_SAVE_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(92,2), wxSize(18,20));
-	menuText1_		= new wxStaticText(this, -1, "View", wxPoint(5,5), wxSize(25,20));
-	menuText2_		= new wxStaticText(this, -1, "Save", wxPoint(62,5), wxSize(25,20));
-
-	//get view menu identification constants
-	gradViewId_	= gradViewId;
-	confViewId_	= confViewId;
-	weitViewId_	= weitViewId;
-	custViewId_	= custViewId;
-	gradSaveId_	= gradSaveId;
-	confSaveId_	= confSaveId;
-	weitSaveId_	= weitSaveId;
-
-	//create view menu
-	view_menu = new wxMenu;
-	view_menu->Append(gradViewId_, "&Gradient Map", "", true);
-	view_menu->Append(confViewId_, "&Confidence Map", "", true);
-	view_menu->Append(weitViewId_, "&Weight Map", "", true);
-	view_menu->Append(custViewId_, "C&ustom Weight Map", "", true);
-
-	//create save menu
-	save_menu = new wxMenu;
-	save_menu->Append(gradSaveId_, "&Gradient Map");
-	save_menu->Append(confSaveId_, "&Confidence Map");
-	save_menu->Append(weitSaveId_, "&Weight Map");
-
-}
-
-BgHoverBar::~BgHoverBar( void )
-{
-	//de-allocate menus...
-	delete view_menu;
-	delete save_menu;
-}
-
-void BgHoverBar::ShowMenu(wxCommandEvent& event)
-{
-	int buttonId	= event.GetId();
-	if(buttonId	== BG_CANVAS_VIEW_BUTTON)
-	{
-		menuText1_->SetForegroundColour(wxColour(0,0,100));
-		menuText2_->SetForegroundColour(wxColour(0,0,0));
-		menuText1_->Refresh();
-		menuText2_->Refresh();
-		PopupMenu(view_menu, 0, 26);
-	}
-	else
-	{
-		menuText1_->SetForegroundColour(wxColour(0,0,0));
-		menuText2_->SetForegroundColour(wxColour(0,0,100));
-		menuText1_->Refresh();
-		menuText2_->Refresh();
-		PopupMenu(save_menu, 0, 26);
-	}
-	Update();
-}
-
-void BgHoverBar::CheckViewItem(long viewItemId)
-{
-	view_menu->Check(gradViewId_, false);
-	view_menu->Check(confViewId_, false);
-	view_menu->Check(weitViewId_, false);
-	view_menu->Check(custViewId_, false);
-	view_menu->Check(viewItemId, true);
-}
-
-void BgHoverBar::Update( void )
-{
-	menuText1_->SetForegroundColour(wxColour(0,0,0));
-	menuText2_->SetForegroundColour(wxColour(0,0,0));
-	menuText1_->Refresh();
-	menuText2_->Refresh();
-}
-
-// ---------------------------------------------------------------------------
-// BgMenuPanel
-// ---------------------------------------------------------------------------
-
-BgMenuPanel::BgMenuPanel(wxWindow* parent, wxWindowID id, int gradViewId, int confViewId, int weitViewId, int custViewId, int gradSaveId, int confSaveId, int weitSaveId)
-		   : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize)
-{
-	//keep pointer to scroll window
-	scrollWindow_	= (wxWindow *) NULL;
-
-	//set the position and size of the window
-	SetSize(0,0,120,30);
-
-	//place a button using a bitmap
-	menuButton1_	= new wxBitmapButton(this, BG_CANVAS_VIEW_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(33,2), wxSize(18,20));
-	menuButton2_	= new wxBitmapButton(this, BG_CANVAS_SAVE_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(92,2), wxSize(18,20));
-	menuText1_		= new wxStaticText(this, -1, "View", wxPoint(5,5), wxSize(25,20));
-	menuText2_		= new wxStaticText(this, -1, "Save", wxPoint(62,5), wxSize(25,20));
-
-	//get view menu identification constants
-	gradViewId_	= gradViewId;
-	confViewId_	= confViewId;
-	weitViewId_	= weitViewId;
-	custViewId_	= custViewId;
-	gradSaveId_	= gradSaveId;
-	confSaveId_	= confSaveId;
-	weitSaveId_	= weitSaveId;
-
-	//create view menu
-	view_menu = new wxMenu;
-	view_menu->Append(gradViewId_, "&Gradient Map", "", true);
-	view_menu->Append(confViewId_, "&Confidence Map", "", true);
-	view_menu->Append(weitViewId_, "&Weight Map", "", true);
-	view_menu->Append(custViewId_, "C&ustom Weight Map", "", true);
-
-	//create save menu
-	save_menu = new wxMenu;
-	save_menu->Append(gradSaveId_, "&Gradient Map");
-	save_menu->Append(confSaveId_, "&Confidence Map");
-	save_menu->Append(weitSaveId_, "&Weight Map");
-
-}
-
-BgMenuPanel::~BgMenuPanel( void )
-{
-	//de-allocate menus...
-	delete view_menu;
-	delete save_menu;
-}
-
-void BgMenuPanel::ShowMenu(wxCommandEvent& event)
-{
-	int buttonId	= event.GetId();
-	if(buttonId	== BG_CANVAS_VIEW_BUTTON)
-	{
-		menuText1_->SetForegroundColour(wxColour(0,0,200));
-		menuText2_->SetForegroundColour(wxColour(0,0,0));
-		menuText1_->Refresh();
-		menuText2_->Refresh();
-		PopupMenu(view_menu, 0, 26);
-	}
-	else
-	{
-		menuText1_->SetForegroundColour(wxColour(0,0,0));
-		menuText2_->SetForegroundColour(wxColour(0,0,200));
-		menuText1_->Refresh();
-		menuText2_->Refresh();
-		PopupMenu(save_menu, 0, 26);
-	}
-	Update();
-}
-
-void BgMenuPanel::CheckViewItem(long viewItemId)
-{
-	view_menu->Check(gradViewId_, false);
-	view_menu->Check(confViewId_, false);
-	view_menu->Check(weitViewId_, false);
-	view_menu->Check(custViewId_, false);
-	view_menu->Check(viewItemId, true);
-}
-
-void BgMenuPanel::Update( void )
-{
-	menuText1_->SetForegroundColour(wxColour(0,0,0));
-	menuText2_->SetForegroundColour(wxColour(0,0,0));
-	menuText1_->Refresh();
-	menuText2_->Refresh();
-}
-
-void BgMenuPanel::EnableMenu(bool enable)
-{
-	menuText1_->Enable(enable);
-	menuText2_->Enable(enable);
-	menuButton1_->Enable(enable);
-	menuButton2_->Enable(enable);
-}
-
-//adjusts size of scroll window
-void BgMenuPanel::OnSize(wxSizeEvent& WXUNUSED(event))
-{
-	if(scrollWindow_)
-	{
-		int w, h;
-		GetClientSize(&w, &h);
-		scrollWindow_->SetSize(0,PLOT_MENU_HEIGHT,w,h-PLOT_MENU_HEIGHT);
-	}
-}
-
-void BgMenuPanel::SetScrollWindow(wxWindow *scrollwindow)
-{
-	scrollWindow_	= scrollwindow;
-}
-
-// ---------------------------------------------------------------------------
-// BgLineSet
-// ---------------------------------------------------------------------------
-
-BgLineSet::BgLineSet()
-{
-   xs_ = ys_ = xe_ = ye_ = 0;
-   lineParam_ = 0;
-   n_ = 0;
-   pen_.SetColour(*wxRED);
-   //pen_.SetColour(*wxWHITE);
-   pen_.SetWidth(2);
-   pen_.SetStyle(wxSOLID);
-}
-
-BgLineSet::~BgLineSet()
-{
-   CleanData();
-}
-
-void BgLineSet::CleanData()
-{
-   if (n_ > 0)
-   {
-      delete [] xs_;
-      delete [] xe_;
-      delete [] ys_;
-      delete [] ye_;
-      delete [] lineParam_;
-      xs_ = ys_ = xe_ = ye_ = 0;
-      lineParam_ = 0;
-      n_ = 0;
-   }
-}
-
-void BgLineSet::SetLines(int* xs, int* xe, int* ys, int* ye, double* lineParam, int n)
-{
-   CleanData();
-   n_ = n;
-   xs_ = new int[n_];
-   xe_ = new int[n_];
-   ys_ = new int[n_];
-   ye_ = new int[n_];
-   lineParam_ = new double[n_*3];
-   int i;
-   for (i=0; i<n; i++)
-   {
-      xs_[i] = xs[i];
-      ys_[i] = ys[i];
-      xe_[i] = xe[i];
-      ye_[i] = ye[i];
-   }
-   for (i=0; i<(3*n); i++)
-      lineParam_[i] = lineParam[i];
-}
-
-void BgLineSet::SetLines(double* startp, double* endp, double* lineParam, int n)
-{
-   CleanData();
-   n_ = n;
-   xs_ = new int[n_];
-   xe_ = new int[n_];
-   ys_ = new int[n_];
-   ye_ = new int[n_];
-   lineParam_ = new double[n_*3];
-   int i;
-   for (i=0; i<n; i++)
-   {
-      xs_[i] = (int) startp[2*i];
-      ys_[i] = (int) startp[2*i+1];
-      xe_[i] = (int) endp[2*i];
-      ye_[i] = (int) endp[2*i+1];
-   }
-   for (i=0; i<(3*n); i++)
-      lineParam_[i] = lineParam[i];
-}
-
-// ---------------------------------------------------------------------------
-// BgImCanvas
-// ---------------------------------------------------------------------------
-
-// Define a constructor for my canvas
-BgImCanvas::BgImCanvas(wxWindow *child_frame, wxWindow *parent, const wxPoint& pos, const wxSize& size)
-: wxScrolledWindow(parent, -1, pos, size,
-                   wxSIMPLE_BORDER|wxVSCROLL|wxHSCROLL)
-{
-   SetBackgroundColour(wxColour("WHITE"));
-   pbitmap=(wxBitmap*) NULL;
-   pimage=(wxImage*) NULL;
-   hasbitmap=FALSE;
-   showbitmap_ = TRUE;
-   m_dirty = FALSE;
-   nLineSets_ = nPointSets_ = 0;
-
-   //set pointer to child frame (e.g. used to update window title)
-   child_frame_	= child_frame;
-
-   // clickable curve stuff
-   nCurveSets_ = 0;
-   ccx_ = RANK_CONF_IMSIZEX;
-   ccy_ = RANK_CONF_IMSIZEY;
-   curveClick_ = new unsigned char[ccx_*ccy_];
-   isDragging_ = 0;
-   FillCurveClick();
-   mouseModif_ = 0;
-   crossCursor_ = 0;
-   showtrack_ = 0;
-
-   //initialize window events
-   has_focus		= false;
-   leaving			= false;
-
-   //initialize plotting canvas
-   x_offset_		= 0;
-   y_offset_		= 0;
-   textObjectCount_	= 0;
-   xAxis			= (BgAxis *) NULL;
-   yAxis			= (BgAxis *) NULL;
-   clear_display_	= false;
-
-   //initializing zooming parameters
-   zoom_in			= false;
-   zoom_out			= false;
-   zoom_window		= false;
-   zoom_level		= 1;
-
-   //initialize empty zoom box and refresh box
-   zoombox			= (wxImage  *) NULL;
-   refresh_box		= (wxImage  *) NULL;
-
-   //initialize point map
-   point_map		= NULL;
-   point_colour		= (wxColour *) NULL;
-
-   //initialize zoomed image buffer
-   zImg				= NULL;
-
-   //initialize zoom window corner
-   cx				= 0;
-   cy				= 0;
-
-   //initialize mouse pointer location
-   m_x_	= 0;
-   m_y_	= 0;
-
-   //initialize zoom buffers
-   buf	= (unsigned char *) NULL;
-
-   //initialize hover window such that
-   //it does not popup
-   popup	= 0;
-
-   //initialize hover window
-   menuWindow	= (wxWindow *) NULL;
-
-   //pay attention to updates
-   noUpdate_	= false;
-
-   //construct zoom cursors
-   //??????????????????????????????
-   wxString str;
-   str.Printf(wxT("icon10"));
-   bgCURSOR_MAGNIFIER_PLUS	= new wxCursor(str, wxBITMAP_TYPE_CUR_RESOURCE);
-   //bgCURSOR_MAGNIFIER_PLUS	= new wxCursor("icon10", wxBITMAP_TYPE_RESOURCE, 0, 0);
-   str.Printf(wxT("icon11"));
-   bgCURSOR_MAGNIFIER_MINUS	= new wxCursor(str, wxBITMAP_TYPE_CUR_RESOURCE);
-   //bgCURSOR_MAGNIFIER_MINUS	= new wxCursor("icon11", wxBITMAP_TYPE_RESOURCE, 0, 0);
-
-   //build local menu
-   localMenu_ = new wxMenu();
-   localMenu_->Append(BG_IMC_ADDNODE,"Add node");
-   localMenu_->Append(BG_IMC_DELETENODE,"Delete node");
-   localMenu_->AppendSeparator();
-   localMenu_->Append(BG_IMC_SELTYPE_ELLIPSE,"Arc");
-   localMenu_->Append(BG_IMC_SELTYPE_VLINE,"Vertical line");
-   localMenu_->Append(BG_IMC_SELTYPE_HLINE,"Horizontal line");
-   localMenu_->Append(BG_IMC_SELTYPE_LINE,"Line");
-   localMenu_->Append(BG_IMC_SELTYPE_BOX,"Box");
-   localMenu_->Append(BG_IMC_SELTYPE_CUSTOM,"Custom");
-}
-
-BgImCanvas::~BgImCanvas()
-{
-   ClearData();
-   if(xAxis)	delete xAxis;
-   if(yAxis)	delete yAxis;
-   delete [] curveClick_;
-   delete localMenu_;
-   delete bgCURSOR_MAGNIFIER_PLUS;
-   delete bgCURSOR_MAGNIFIER_MINUS;
-}
-
-void BgImCanvas::OnCustomAddNode(wxCommandEvent& WXUNUSED(event))
-{
-   if ((lmEventCurve_ < 0) || (lmEventCurve_ >= nCurveSets_) ||
-      (curveSet_[lmEventCurve_]->type_!=FC_CUSTOM))
-   {
-      return;
-   }
-   int n, type;
-   n = curveSet_[lmEventCurve_]->n_;
-   double *tx, *ty;
-   tx = new double[n+1];
-   ty = new double[n+1];
-   curveSet_[lmEventCurve_]->GetParamCurve(tx, ty, type, n);
-   double x, y;
-   x = ((double) lmEventX_)/ccx_;
-   y = (ccy_ - ((double) lmEventY_))/ccy_;
-
-   // determine closest line
-   double cx, cy, cr, ax, ay, dx, dy;
-   double mny = 10;
-   int ci = -1;
-   int i;
-   for (i=0; i<(n-1); i++)
-   {
-      cx = tx[i+1]-tx[i];
-      cy = ty[i+1]-ty[i];
-      cr = sqrt(cx*cx+cy*cy);
-      if (cr <= 0)
-         continue;
-      ax = x-tx[i];
-      ay = y-ty[i];
-      dx = (cx*ax+cy*ay)/cr;
-      dy = fabs((-cy*ax+cx*ay)/cr);
-      if ((dx>=0) && (dx<=cr))
-      {
-         if (dy<mny)
-         {
-            mny = dy;
-            ci = i;
-         }
-      }
-   }
-   if (ci >= 0)
-   {
-      // modify curve
-      for (i=n; i>ci; i--)
-      {
-         tx[i] = tx[i-1];
-         ty[i] = ty[i-1];
-      }
-      tx[ci+1] = x;
-      ty[ci+1] = y;
-      curveSet_[lmEventCurve_]->SetParamCurve(type, tx, ty, n+1, ccx_, ccy_);
-   }
-      
-   delete [] ty;
-   delete [] tx;
-   mouseModif_ = 1;
-   AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-
-   FillCurveClick();
-   return;
-}
-void BgImCanvas::OnCustomDeleteNode(wxCommandEvent& WXUNUSED(event))
-{
-   if ((lmEventCurve_ < 0) || (lmEventCurve_ >= nCurveSets_) || 
-      (lmEventNode_ < 0) || (lmEventNode_ >= (curveSet_[lmEventCurve_]->n_-1)))
-   {
-      return;
-   }
-   if (lmEventNode_ == 0)
-   {
-      bgLog("Cannot delete first node.\n");
-      return;
-   }
-   if (lmEventNode_ == (curveSet_[lmEventCurve_]->n_-1))
-   {
-      bgLog("Cannot delete last node.\n");
-      return;
-   }
-   // delete the node
-   int i;
-   int n = curveSet_[lmEventCurve_]->n_;
-   int *tx, *ty;
-   tx = curveSet_[lmEventCurve_]->x_;
-   ty = curveSet_[lmEventCurve_]->y_;
-   for (i=lmEventNode_; i<(n-1); i++)
-   {
-      tx[i] = tx[i+1];
-      ty[i] = ty[i+1];
-   }
-   curveSet_[lmEventCurve_]->n_ = n-1;
-   mouseModif_ = 1;
-   AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-   FillCurveClick();
-   return;
-}
-void BgImCanvas::OnCTypeEllipse(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-      {
-         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
-         curveSet_[lmEventCurve_]->n_ = 1;
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_ELLIPSE;
-      FillCurveClick();
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-   }
-}
-void BgImCanvas::OnCTypeVLine(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-      {
-         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
-         curveSet_[lmEventCurve_]->n_ = 1;
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_VERT_LINE;
-      FillCurveClick();
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-   }
-}
-void BgImCanvas::OnCTypeHLine(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-      {
-         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
-         curveSet_[lmEventCurve_]->n_ = 1;
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_HORIZ_LINE;
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-      FillCurveClick();
-   }
-}
-void BgImCanvas::OnCTypeLine(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-      {
-         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
-         curveSet_[lmEventCurve_]->n_ = 1;
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_LINE;
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-      FillCurveClick();
-   }
-}
-void BgImCanvas::OnCTypeBox(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-      {
-         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
-         curveSet_[lmEventCurve_]->n_ = 1;
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_SQUARE_BOX;
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-      FillCurveClick();
-   }
-}
-void BgImCanvas::OnCTypeCustom(wxCommandEvent& WXUNUSED(event))
-{
-   if (lmEventCurve_ < nCurveSets_)
-   {
-      if (curveSet_[lmEventCurve_]->type_ != FC_CUSTOM)
-      {
-         double x[3];
-         double y[3];
-         int n,type;
-         curveSet_[lmEventCurve_]->GetParamCurve(x,y,type,n);
-         n = 3;
-         type = FC_CUSTOM;
-         x[2] = x[0];
-         x[0] = 0;
-         y[2] = 0;
-         x[2] = (x[2]>1) ? 1:x[2];
-         x[2] = (x[2]<0) ? 0:x[2];
-         y[0] = (y[0]>1) ? 1:y[0];
-         y[0] = (y[0]<0) ? 0:y[0];
-         x[1] = (x[0]+x[2])*2.0/3.0;
-         y[1] = (y[0]+y[2])*2.0/3.0;
-         curveSet_[lmEventCurve_]->SetParamCurve(type, x, y, n, ccx_, ccy_);
-      }
-      curveSet_[lmEventCurve_]->type_ = FC_CUSTOM;
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-      FillCurveClick();
-   }
-}
-
-void BgImCanvas::AddPointSet(BgPointSet* ps)
-{
-   pointSet_[nPointSets_++] = ps;
-
-   //update point map if the point set consists
-   //of data points (not circles)
-   if((ps->type_	== 1)&&(hasbitmap))
-   {
-	   int nt, *tx, *ty;
-	   nt = ps->n_;
-	   tx = ps->x_;
-	   ty = ps->y_;
-	   int i, dp, width = pimage->GetWidth();
-	   for(i=0; i<nt; i++)
-	   {
-		   dp				= ty[i]*width+tx[i];
-		   point_map[dp]	= true;
-	   }
-   }
-
-   //define new pen colour is yet defined, define it
-   if(point_colour)	delete point_colour;
-   point_colour	= new wxColour(ps->pen_.GetColour());
-
-   //add point data to zoomed image (if it has been defined,
-   //i.e. an image has been loaded into the image canvas)
-   if(zImg)	AddPoints(zImg, ((pimage->GetWidth())*zoom_level));
-
-   Refresh();
-}
-
-void BgImCanvas::RemovePointSet(BgPointSet* ps)
-{
-   int i = 0;
-   while (i<nPointSets_ && pointSet_[i]!=ps)
-      i++;
-   if (i<nPointSets_)
-   {
-      i++;
-      while(i<nPointSets_)
-      {
-         pointSet_[i-1] = pointSet_[i];
-         i++;
-      }
-      nPointSets_--;
-   }
-
-   //adjust point map accordingly
-   if((point_map)&&(ps->type_	== 1))	//point
-   {
-	   int width = pimage->GetWidth();
-	   int nt, *tx, *ty;
-	   nt	= ps->n_;
-	   tx	= ps->x_;
-	   ty	= ps->y_;
-	   for(i=0; i<nt; i++)
-		   point_map[ty[i]*width+tx[i]] = false;
-   }
-
-   //delete pen colour if no more point sets exist
-   if(nPointSets_ == 0)
-   {
-	   delete point_colour;
-	   point_colour	= (wxColour *) NULL;
-   }
-
-   //remove this point set from the zoomed image...
-
-   /*********************************************************/
-
-   if(zImg)
-   {
-	   delete [] zImg;
-	   int width, height;
-	   width	= (pimage->GetWidth())*zoom_level;
-	   height	= (pimage->GetHeight())*zoom_level;
-	   zImg		= new unsigned char [3*width*height];
-	   if(zoom_level > 1)
-		   bgZoomIn(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), zoom_level, false);
-	   else if(zoom_level == 1)
-		   memcpy(zImg, pimage->GetData(), 3*width*height*sizeof(unsigned char));
-
-	   //add any other point sets that may exist
-	   AddPoints(zImg, width);
-   }
-
-   /*********************************************************/
-
-   Refresh(false);
-
-}
-
-void BgImCanvas::AddLineSet(BgLineSet* ls)
-{
-   lineSet_[nLineSets_++] = ls;
-   Refresh();
-}
-
-void BgImCanvas::AddTrackSet(int x, int y, int hx, int hy)
-{
-   trackval_[0] = x;
-   trackval_[1] = y;
-   hx_ = hx;
-   hy_ = hy;
-   showtrack_ = 1;
-   Refresh();
-
-}
-
-void BgImCanvas::RemoveTrackSet()
-{
-   showtrack_ = 0;
-   Refresh();
-}
-   
-
-void BgImCanvas::RemoveLineSet(BgLineSet* ls)
-{
-   int i = 0;
-   while (i<nLineSets_ && lineSet_[i]!=ls)
-      i++;
-   if (i<nLineSets_)
-   {
-      i++;
-      while(i<nLineSets_)
-      {
-         lineSet_[i-1] = lineSet_[i];
-         i++;
-      }
-      nLineSets_--;
-   }
-   Refresh();
-}
-
-void BgImCanvas::AddCurveSet(BgCurveSet* cs)
-{
-   curveSet_[nCurveSets_++] = cs;
-   Refresh();
-}
-
-void BgImCanvas::RemoveCurveSet(BgCurveSet* cs)
-{
-   int i = 0;
-   while (i<nCurveSets_ && curveSet_[i]!=cs)
-      i++;
-   if (i<nCurveSets_)
-   {
-      i++;
-      while(i<nCurveSets_)
-      {
-         curveSet_[i-1] = curveSet_[i];
-         i++;
-      }
-      nCurveSets_--;
-   }
-   Refresh();
-}
-
-//adds text object to be dran to the image
-//pre : bgText is the text object to be plotted
-//post: bgText has been added to the image
-void BgImCanvas::AddText(BgText *bgText)
-{
-	//add text to text list
-	if(tlist_.AddText(bgText))
-	{
-		bgLog("BgImCanvas::AddText Error: Out of memory.\n");
-		return;
-	}
-
-	//obtain new text object count
-	textObjectCount_	= tlist_.GetTextCount();
-}
-
-//clears all text object from text list
-void BgImCanvas::RemoveText(int text_id)
-{
-	tlist_.RemoveText(text_id);
-	return;
-}
-
-//adds horizontal axis
-void BgImCanvas::AddHorizontalAxis(int start_x, int start_y, int length, int ticknum, float start_val, float stop_val)
-{
-	if(xAxis)	delete xAxis;
-	xAxis	= new BgAxis(start_x, start_y, length, ticknum, 0, start_val, stop_val);
-}
-
-//adds horizontal axis
-void BgImCanvas::AddVerticalAxis(int start_x, int start_y, int length, int ticknum, float start_val, float stop_val)
-{
-	if(yAxis)	delete yAxis;
-	yAxis	= new BgAxis(start_x, start_y, length, ticknum, 1, start_val, stop_val);
-}
-
-//clears axis
-void BgImCanvas::ClearAxis( void )
-{
-	if(xAxis)	delete xAxis;
-	if(yAxis)	delete yAxis;
-	xAxis	= yAxis	= (BgAxis *) NULL;
-}
-
-//labels horizontal axis
-void BgImCanvas::LabelHorizontalAxis(BgText *bgText)
-{
-	if(xAxis)	xAxis->Label(bgText);
-}
-
-//labels vertical axis
-void BgImCanvas::LabelVerticalAxis(BgText *bgText)
-{
-	if(yAxis)	yAxis->Label(bgText);
-}
-
-//removes label on horizontal axis
-void BgImCanvas::RemoveHorizontalAxisLabel(void)
-{
-	if(xAxis)	xAxis->RemoveLabel();
-}
-
-//removes lable on vertical axis
-void BgImCanvas::RemoveVerticalAxisLabel(void)
-{
-	if(yAxis)	yAxis->RemoveLabel();
-}
-
-//rotates horizontal axis label clockwise from default position
-void BgImCanvas::RotateHorizontalAxisLabel(int rotation)
-{
-	if(xAxis)	xAxis->SetLabelRotation(rotation);
-}
-
-//rotates vertical axis label clockwise from default position
-void BgImCanvas::RotateVerticalAxisLabel(int rotation)
-{
-	if(yAxis)	yAxis->SetLabelRotation(rotation);
-}
-
-//plot bitmap at specified location
-void BgImCanvas::AddBitmap(BgBitmap *bitmap)
-{
-	blist_.AddBitmap(bitmap);
-}
-
-//remove bitmap from plot
-void BgImCanvas::RemoveBitmap(BgBitmap *bitmap)
-{
-	blist_.RemoveBitmap(bitmap);
-}
-
-//clears display
-void BgImCanvas::ClearDisplay(void)
-{
-	clear_display_	= true;
-	Refresh();
-}
-
-void BgImCanvas::ClearData(int refresh)
-{
-   if(hasbitmap==TRUE) {
-      delete pbitmap;
-      delete pimage;
-   }
-   if(zoombox)			delete zoombox;
-   if(refresh_box)		delete refresh_box;
-   if(zImg)				delete zImg;
-   if(point_map)		delete [] point_map;
-   if(buf)				delete [] buf;
-   hasbitmap=FALSE;
-   pbitmap=(wxBitmap*) NULL;
-   pimage=(wxImage*) NULL;
-   zoombox=(wxImage*) NULL;
-   refresh_box=(wxImage*) NULL;
-   zImg=NULL;
-   point_map=NULL;
-   showtrack_ = 0;
-   if (refresh > 0)
-      Refresh();
-}
-
-int BgImCanvas::SetImage(wxString imname)
-{
-   ClearData();
-   pimage=new wxImage();
-   if (!pimage->LoadFile(imname))
-   {
-      delete pimage;
-      wxLogError("Can't load image "+imname);
-      return 0;
-   }
-   else
-   {
-      SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
-#if wxCHECK_VERSION(2, 3, 0)
-      pbitmap = new wxBitmap(pimage);
-#else
-      pbitmap = new wxBitmap(pimage->ConvertToBitmap());
-#endif
-      hasbitmap=TRUE;
-      m_dirty=TRUE;
-
-	  //create point map
-	  CreatePointMap(pimage->GetWidth(), pimage->GetHeight());
-
-	  //take account for zoom (takes care of refresh)
-	  Zoom(zoom_level);
-   }
-   return 1;
-}
-
-void BgImCanvas::SetImage(wxImage& image)
-{
-   ClearData();
-   pimage=new wxImage();
-   *pimage = image;
-   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
-   
-#if wxCHECK_VERSION(2, 3, 0)
-      pbitmap = new wxBitmap(pimage);
-#else
-      pbitmap = new wxBitmap(pimage->ConvertToBitmap());
-#endif
-   hasbitmap=TRUE;
-   m_dirty=TRUE;
-
-   //create point map
-   CreatePointMap(image.GetWidth(), image.GetHeight());
-
-   //take account for zoom (takes care of refresh)
-   Zoom(zoom_level);
-   
-}
-
-void BgImCanvas::SetSameImage(wxImage& image)
-{
-   *pimage = image;
-#if wxCHECK_VERSION(2, 3, 0)
-   *pbitmap = wxBitmap(image);
-#else
-   *pbitmap = image.ConvertToBitmap();
-#endif
-
-   //create point map
-   CreatePointMap(image.GetWidth(), image.GetHeight());
-
-   //take account for zoom (takes care of refresh)
-   Zoom(zoom_level);
-}
-
-void BgImCanvas::SetImageFromGray(unsigned char* data, int w, int h)
-{
-   ClearData();
-   
-   pimage = new wxImage(w, h);
-
-   int i;
-   unsigned char* itTData;
-   itTData = pimage->GetData();
-
-   for (i=0; i<w*h; i++)
-   {
-      *(itTData++)=data[i];
-      *(itTData++)=data[i];
-      *(itTData++)=data[i];
-   }
-   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
-
-#if wxCHECK_VERSION(2, 3, 0)
-   pbitmap = new wxBitmap(pimage);
-#else
-   pbitmap = new wxBitmap(pimage->ConvertToBitmap());
-#endif
-   hasbitmap=TRUE;
-   m_dirty=TRUE;
-
-   //create point map
-   CreatePointMap(w, h);
-
-   //take account for zoom (takes care of refresh)
-   Zoom(zoom_level);
-}
-
-void BgImCanvas::SetImage(unsigned char* data, int w, int h, bool colorim)
-{
-   ClearData();
-   
-   pimage = new wxImage(w, h);
-
-   int i;
-   unsigned char* itTData;
-   itTData = pimage->GetData();
-
-   if (colorim == false)
-   {
-      for (i=0; i<w*h; i++)
-      {
-         *(itTData++)=data[i];
-         *(itTData++)=data[i];
-         *(itTData++)=data[i];
-      }
-   } else
-   {
-      for (i=0; i<(3*w*h); i++)
-      {
-         *(itTData++)=data[i];
-      }
-   }
-   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
-
-#if wxCHECK_VERSION(2, 3, 0)
-   pbitmap = new wxBitmap(pimage);
-#else
-   pbitmap = new wxBitmap(pimage->ConvertToBitmap());
-#endif
-   hasbitmap=TRUE;
-   m_dirty=TRUE;
-
-
-   //create point map
-   CreatePointMap(w, h);
-
-   //take account for zoom (takes care of refresh)
-   Zoom(zoom_level);
-}
-
-/*
-Still needs work!!!!!!
-*/
-
-void BgImCanvas::ShowBitmap(bool showbitmap)
-{
-	showbitmap_	= showbitmap;
-	if(hasbitmap)
-	{
-		//compute height and width of original image
-		int width	= pimage->GetWidth();
-		int height	= pimage->GetHeight();
-
-		//paint zoom image
-		if(!showbitmap_)
-			memset(zImg, 255, 3*zoom_level*zoom_level*width*height*sizeof(unsigned char));
-		else
-			bgZoomIn(&zImg, pimage->GetData(), width, height, zoom_level, false);
-
-		//plot points from point set onto zoom image
-		AddPoints(zImg, width*zoom_level);
-
-		//re-draw image onto canvas
-		Refresh();
-	}
-	return;
-}
-
-
-// Define the repainting behaviour
-void BgImCanvas::OnDraw(wxDC& dc)
-{
-	//clear the display
-	if(clear_display_)
-	{
-		clear_display_	= false;
-		dc.Clear();
-		return;
-	}
-
-	//do not update the display (good for keeping
-	//a display clear in light of onSize() events
-	//for example)
-	if(noUpdate_) return;
-
-	//catch leaving event
-	if((zoom_window)&&(leaving))
-	{
-		//if a refresh window remains, plot it and delete it
-		if(refresh_box)
-		{
-#if wxCHECK_VERSION(2, 3, 0)
-         dc.DrawBitmap(wxBitmap(refresh_box), cx, cy);
-#else
-			dc.DrawBitmap(refresh_box->ConvertToBitmap(), cx, cy);
-#endif
-			delete refresh_box;
-			refresh_box	= (wxImage*) NULL;
-		}
-		
-		//retrieve leaving event
-		leaving	= false;
-
-		//exit
-		return;
-	}
-
-
-	if (hasbitmap==false)
-	{
-		dc.Clear();
-		return;
-	}
-	//re-plot image bitmap
-	if(hasbitmap==true && showbitmap_==true)
-	{
-		if((!zoom_window)||(!has_focus))
-			dc.DrawBitmap(*pbitmap,0+x_offset_,0+y_offset_);
-	}
-	else if(!zoom_window)
-	{
-		dc.Clear();
-	}
-	if (showtrack_ == 1)
-	{
-		wxPen tPen=dc.GetPen();
-		dc.SetBrush(*wxTRANSPARENT_BRUSH);
-		dc.SetPen(*wxRED_PEN);
-		//+x_offset_+y_offset_
-		dc.DrawEllipse(trackval_[0]-2, trackval_[1]-2, 5,5);
-		dc.DrawEllipse(trackval_[0]-hx_, trackval_[1]-hy_, 2*hx_+1, 2*hy_+1);
-		dc.SetPen(tPen);
-		dc.SetBrush(wxNullBrush);
-	}
-	if ((nPointSets_ > 0)&&((!zoom_window)||(!has_focus)))
-	{
-		int i,j;
-		int* tx;
-		int* ty;
-		int x, xc;
-		int y, yc;
-		int nt;
-		wxPen tPen=dc.GetPen();
-		dc.SetBrush(*wxTRANSPARENT_BRUSH);
-		for (i=0; i<nPointSets_; i++)
-		{
-			dc.SetPen(pointSet_[i]->pen_);
-			nt = pointSet_[i]->n_;
-			tx = pointSet_[i]->x_;
-			ty = pointSet_[i]->y_;
-			if(pointSet_[i]->type_ == 0) // circle
-			{
-				for (j=0; j<nt; j++)
-				{
-					dc.DrawEllipse(tx[j]-2+x_offset_, ty[j]-2+y_offset_, 5,5);
-				}
-			}
-			else if(pointSet_[i]->type_ == 1) // point
-			{
-				for (j=0; j<nt; j++)
-				{
-					xc	= zoom_level*(tx[j] + x_offset_);
-					yc	= zoom_level*(ty[j] + y_offset_);
-					for(y=0; y<zoom_level; y++)
-					{
-						for(x=0; x<zoom_level; x++)
-						{
-							dc.DrawPoint(xc+x, yc+y);
-						}
-					}
-				}
-			}
-		}
-		dc.SetPen(tPen);
-		dc.SetBrush(wxNullBrush);
-	}
-	
-	if (nLineSets_ > 0)
-	{
-		int i,j;
-		int* tsx;
-		int* tsy;
-		int* tex;
-		int* tey;
-		int nt;
-		wxPen tPen=dc.GetPen();
-		dc.SetBrush(*wxTRANSPARENT_BRUSH);
-		for (i=0; i<nLineSets_; i++)
-		{
-			dc.SetPen(lineSet_[i]->pen_);
-			nt = lineSet_[i]->n_;
-			tsx = lineSet_[i]->xs_;
-			tsy = lineSet_[i]->ys_;
-			tex = lineSet_[i]->xe_;
-			tey = lineSet_[i]->ye_;
-			for (j=0; j<nt; j++)
-			{
-				dc.DrawLine(tsx[j]+x_offset_, tsy[j]+y_offset_, tex[j]+x_offset_, tey[j]+y_offset_);
-			}
-		}
-		dc.SetPen(tPen);
-		dc.SetBrush(wxNullBrush);
-	}
-	int txs,tys,txe,tye;
-	
-	if (nCurveSets_ > 0)
-	{
-		int i,j;
-		int* tx;
-		int* ty;
-		int xs, ys;
-		int nt;
-		wxPen tPen=dc.GetPen();
-		dc.SetBrush(*wxTRANSPARENT_BRUSH);
-		for (i=0; i<nCurveSets_; i++)
-		{
-			dc.SetPen(curveSet_[i]->pen_);
-			tx = curveSet_[i]->x_;
-			ty = curveSet_[i]->y_;
-			nt = curveSet_[i]->n_;
-			xs = curveSet_[i]->xs_;
-			ys = curveSet_[i]->ys_;
-			
-			switch (curveSet_[i]->type_)
-			{
-			case -1:
-				break;
-			case FC_ELLIPSE:
-				MyDrawEllipticArc(dc,-tx[0]+x_offset_, ty[0]+y_offset_, 2*tx[0], 2*(ys-ty[0]), 0, 90);
-				break;
-			case FC_VERT_LINE:
-				//            if ((tx[0]>=0) && (tx[0]<xs))
-				dc.DrawLine(tx[0]+x_offset_, 0+y_offset_, tx[0]+x_offset_, ys+y_offset_);
-				break;
-			case FC_HORIZ_LINE:
-				if ((ty[0]>=0) && (ty[0]<ys))
-					dc.DrawLine(0+x_offset_, ty[0]+y_offset_, xs+x_offset_, ty[0]+y_offset_);
-				break;
-			case FC_LINE:
-				// determine clipping
-				tye = ys;
-				txe = tx[0];
-				txe = (txe<=0)?1:txe;
-				txs = 0;
-				tys = ty[0];
-				tys = (tys>ys)?ys:tys;
-				if (txe>xs)
-				{
-					tye = ccy_-((ccy_-tys)*(txe-xs))/txe;
-					txe = xs;
-				}
-				if (tys<0)
-				{
-					txs= (txe*(-tys))/(tye-tys);
-					tys= 0;
-				}
-				
-				dc.DrawLine(0+x_offset_, ty[0]+y_offset_, tx[0]+x_offset_, ys+y_offset_);
-				break;
-			case FC_SQUARE_BOX:
-				txs = (tx[0]<0)?0:tx[0];
-				txs = (txs>=xs)?xs-1:txs;
-				tys = (ty[0]<0)?0:ty[0];
-				tys = (tys>=ys)?ys-1:tys;
-				dc.DrawLine(0+x_offset_, tys+y_offset_, txs+x_offset_, tys+y_offset_);
-				dc.DrawLine(txs+x_offset_, tys+y_offset_, txs+x_offset_, ys+y_offset_);
-				break;
-			case FC_CUSTOM:
-				for (j=0; j<(nt-1); j++)
-					dc.DrawLine(tx[j]+x_offset_, ty[j]+y_offset_, tx[j+1]+x_offset_, ty[j+1]+y_offset_);
-				break;
-			}
-			//         wxPen pPen=dc.GetPen();
-			//         pPen.SetWidth(17);
-			//         pPen.SetColour(64,64,64);
-			//         dc.SetPen(pPen);
-			switch (curveSet_[i]->type_)
-			{
-			case -1:
-				break;
-			case FC_ELLIPSE:
-			case FC_LINE:
-				//            dc.DrawPoint(0,ty[0]);
-				//            dc.DrawPoint(tx[0],ys);
-				dc.DrawRectangle(0-2+x_offset_,ty[0]-2+y_offset_,5,5);
-				dc.DrawRectangle(tx[0]-2+x_offset_,ys-2+y_offset_,5,5);
-				break;
-			case FC_SQUARE_BOX:
-				//            dc.DrawPoint(0,ty[0]);
-				//            dc.DrawPoint(tx[0],ys);
-				//            dc.DrawPoint(tx[0],ty[0]);
-				dc.DrawRectangle(0-2+x_offset_,ty[0]-2+y_offset_,5,5);
-				dc.DrawRectangle(tx[0]-2+x_offset_,ys-2+y_offset_,5,5);
-				dc.DrawRectangle(tx[0]-2+x_offset_,ty[0]-2+y_offset_,5,5);
-				break;
-			case FC_CUSTOM:
-				for (j=0; j<nt; j++)
-					dc.DrawRectangle(tx[j]-2+x_offset_,ty[j]-2+y_offset_,5,5);
-				//               dc.DrawPoint(tx[j],ty[j]);
-				break;
-			}
-		}
-		dc.SetPen(tPen);
-		dc.SetBrush(wxNullBrush);
-	}
-	
-	if (isDragging_ == 1)
-	{ 
-		int j;
-		int* tx;
-		int* ty;
-		int xs, ys;
-		int nt;
-		wxPen tPen=dc.GetPen();
-		dc.SetBrush(*wxTRANSPARENT_BRUSH);
-		dc.SetPen(dragCurve_.pen_);
-		tx = dragCurve_.x_;
-		ty = dragCurve_.y_;
-		nt = dragCurve_.n_;
-		xs = dragCurve_.xs_;
-		ys = dragCurve_.ys_;
-		
-		switch (dragCurve_.type_)
-		{
-		case -1:
-			break;
-		case FC_ELLIPSE:
-            MyDrawEllipticArc(dc,-tx[0]+x_offset_, ty[0]+y_offset_, 2*tx[0], 2*(ys-ty[0]), 0, 90);
-            break;
-		case FC_VERT_LINE:
-			//            if ((tx[0]>=0) && (tx[0]<xs))
-			dc.DrawLine(tx[0]+x_offset_, 0+y_offset_, tx[0]+x_offset_, ys+y_offset_);
-            break;
-		case FC_HORIZ_LINE:
-            if ((ty[0]>=0) && (ty[0]<ys))
-				dc.DrawLine(0+x_offset_, ty[0]+y_offset_, xs+x_offset_, ty[0]+y_offset_);
-            break;
-		case FC_LINE:
-            // determine clipping
-            tye = ys;
-            txe = tx[0];
-            txe = (txe<=0)?1:txe;
-            txs = 0;
-            tys = ty[0];
-            tys = (tys>ys)?ys:tys;
-            if (txe>xs)
-            {
-				tye = ccy_-((ccy_-tys)*(txe-xs))/txe;
-				txe = xs;
-            }
-            if (tys<0)
-            {
-				txs= (txe*(-tys))/(tye-tys);
-				tys= 0;
-            }
-			
-            dc.DrawLine(0+x_offset_, ty[0]+y_offset_, tx[0]+x_offset_, ys+y_offset_);
-            break;
-		case FC_SQUARE_BOX:
-            txs = (tx[0]<0)?0:tx[0];
-            txs = (txs>=xs)?xs-1:txs;
-            tys = (ty[0]<0)?0:ty[0];
-            tys = (tys>=ys)?ys-1:tys;
-            dc.DrawLine(0+x_offset_, tys+y_offset_, txs+x_offset_, tys+y_offset_);
-            dc.DrawLine(txs+x_offset_, tys+y_offset_, txs+x_offset_, ys+y_offset_);
-            break;
-		case FC_CUSTOM:
-            for (j=0; j<(nt-1); j++)
-				dc.DrawLine(tx[j]+x_offset_, ty[j]+y_offset_, tx[j+1]+x_offset_, ty[j+1]+y_offset_);
-            break;
-		}
-		
-		dc.SetPen(tPen);
-		dc.SetBrush(wxNullBrush);
-		
-	}
-	
-	//draw horizontal and vertical axis
-	if(xAxis)	xAxis->PlotAxis(&dc);
-	if(yAxis)	yAxis->PlotAxis(&dc);
-	
-	//draw new text to the image from text object list
-	BgText	*bgText;
-	tlist_.ResetList();
-	while(bgText = tlist_.GetText())
-	{
-		dc.SetFont(*(bgText->font_));
-		dc.DrawText(bgText->text_, bgText->x_, bgText->y_);
-	}
-	
-	//draw bitmaps
-	blist_.ResetList();
-	BgBitmap	*bitmap;
-	while(bitmap = blist_.GetBitmap())
-		dc.DrawBitmap(*(bitmap->bitmap_), bitmap->location_x_, bitmap->location_y_, true);
-
-	//draw zoom window box
-	if((zoom_window)&&(has_focus))
-	{
-		//draw refresh window
-#if wxCHECK_VERSION(2, 3, 0)
-      if(refresh_box)   dc.DrawBitmap(wxBitmap(refresh_box), cx, cy);
-#else
-		if(refresh_box)	dc.DrawBitmap(refresh_box->ConvertToBitmap(), cx, cy);
-#endif
-
-		//compute height and width of zoom box and window
-		int zWidth, zHeight;
-		int dWidth, dHeight;
-		zWidth	= zoombox->GetWidth();
-		zHeight	= zoombox->GetHeight();
-		GetSize(&dWidth, &dHeight);
-
-		//compute upper corner of window
-		cx = m_x_ - zWidth/2;
-		cy = m_y_ - zHeight/2;
-
-		//check bounds....
-		if(cx < 0)	cx = 0;
-		if(cy < 0)	cy = 0;
-		if(cx >= dWidth - zWidth)	cx	= dWidth  - zWidth - 1;
-		if(cy >= dHeight - zHeight)	cy	= dHeight - zHeight - 1;
-
-		//place in image coordinate frame
-		cx	= cx + GetScrollPos(wxHORIZONTAL);
-		cy	= cy + GetScrollPos(wxVERTICAL);
-
-		//check bounds		
-		int width	= pimage->GetWidth()*zoom_level, height	= pimage->GetHeight()*zoom_level;
-		if(cx >= width - zWidth)	cx	= width - zWidth - 1;
-		if(cy >= height - zHeight)	cy	= height - zHeight - 1;
-
-		//draw zoom window
-#if wxCHECK_VERSION(2, 3, 0)
-      dc.DrawBitmap(wxBitmap(zoombox), cx, cy);
-#else
-		dc.DrawBitmap(zoombox->ConvertToBitmap(), cx, cy);
-#endif
-
-		//create refresh box for next iteration
-		DefineRefreshBox();
-	}
-
-}
-
-//adds an image margin to the image
-//pre : (x_margin, y_margin) define the margins in the
-//      x and y direction respectively
-//post: an image margin has been added
-void BgImCanvas::AddMargin(int x_margin, int y_margin)
-{
-	//shift the image
-	x_offset_	= x_margin;
-	y_offset_	= y_margin;
-
-	//redraw the image
-	Refresh();
-
-}
-
-//overloaded zoom function that does not use current mouse position
-int BgImCanvas::Zoom(int zconst)
-{
-	return Zoom(zconst, 0, 0);
-}
-
-//allows one to zoom into/out of the image dispalyed by the image canvas
-//pre : zconst is the zoom constant
-//      (m_x, m_y) is the current position of the mouse
-//post: the image has been zoomed in by a factor of zconst
-//      returns 1 when zoom not possible due to image constraints,
-//		zoom at maximum or minimum image dimensions, or possible error
-int BgImCanvas::Zoom(int zconst, int m_x, int m_y)
-{
-	//must have bitmap to zoom
-	if(hasbitmap)
-	{
-		//determine zooming action
-		int	action;
-		if(zconst < zoom_level)
-			action	= ZOOM_OUT;
-		else if(zconst > zoom_level)
-			action	= ZOOM_IN;
-		
-		//check bounds
-		int	width	= pimage->GetWidth(), height	= pimage->GetHeight();
-		if(zconst < 0)
-		{
-			//take absolute value of zoom constant
-			int	pos_zc	= -zconst;
-
-			//compute new width
-			if(width%pos_zc)
-				width	= width/pos_zc+1;
-			else
-				width	/= pos_zc;
-
-			//compute new height
-			if(height%pos_zc)
-				height	= height/pos_zc+1;
-			else
-				height	/= -zconst;
-
-			//make sure width and height are above minimum
-			//before continuing
-			if((width < MIN_WIDTH)||(height < MIN_HEIGHT))
-				return 1;
-		}
-		else if (zconst > 0)
-		{
-			width	*= zconst;
-			height	*= zconst;
-			if((width > MAX_WIDTH)||(height > MAX_HEIGHT))
-				return 1;
-		}
-		else
-		{
-			//zconst equals zero (ambiguous so exit)
-			return 1;
-		}
-		
-		//set zoom_level
-		zoom_level	= zconst;
-
-		if(zoom_level == 1)
-		{
-			delete	pbitmap;
-#if wxCHECK_VERSION(2, 3, 0)
-         pbitmap = new wxBitmap(pimage);
-#else
-			pbitmap	= new wxBitmap(pimage->ConvertToBitmap());
-#endif
-			if(zImg)	delete zImg;
-			zImg	= new unsigned char [3*height*width];
-			memcpy(zImg, pimage->GetData(), 3*height*width);
-		}
-		else if(zoom_level > 1)
-		{
-			//zoom into image using zoom level
-			wxImage	tempIm(width, height);
-			if(zImg)	delete [] zImg;
-			zImg	= new unsigned char [3*width*height];
-			bgZoomIn(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), zoom_level, false);
-			memcpy(tempIm.GetData(), zImg, 3*width*height*sizeof(unsigned char));
-			
-			//reset the bitmap using zoomed image
-			delete pbitmap;
-#if wxCHECK_VERSION(2, 3, 0)
-         pbitmap = new wxBitmap(tempIm);
-#else
-			pbitmap = new wxBitmap(tempIm.ConvertToBitmap());
-#endif
-		}
-		else if(zoom_level < -1)
-		{
-			//zoom out of image using zoom level
-			wxImage	tempIm(width, height);
-			if(zImg)	delete [] zImg;
-			zImg	= new unsigned char [3*width*height];
-			bgZoomOut(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), (-zoom_level), false);
-			memcpy(tempIm.GetData(), zImg, 3*width*height*sizeof(unsigned char));
-			
-			//reset the bitmap using zoomed image
-			delete pbitmap;
-#if wxCHECK_VERSION(2, 3, 0)
-         pbitmap = new wxBitmap(tempIm);
-#else
-			pbitmap = new wxBitmap(tempIm.ConvertToBitmap());
-#endif
-		}
-
-		//if a bitmap is not to be shown, clear (make white) the
-		//zoomed image
-		if(!showbitmap_)
-			memset(zImg, 255, 3*width*height*sizeof(unsigned char));
-
-		//add point data to zoomed image
-		AddPoints(zImg, width);
-
-		//re-display image
-		Refresh();
-
-		//set scroll bars according to current mouse position and zooming action
-		AdjustScroll(m_x, m_y, action);
-
-		//return 1 when maximum or minimum image dimension has occured
-		if((width == MAX_WIDTH)||(width == MIN_WIDTH)||(height == MAX_HEIGHT)||(height == MIN_HEIGHT))
-			return 1;
-
-		//return 1 when close to maximum or minimum image dimension...
-		/*********************************************************************/
-
-		if(zconst > 0)
-		{
-			width	+= pimage->GetWidth();
-			height	+= pimage->GetHeight();
-			if((width > MAX_WIDTH)||(height > MAX_HEIGHT))
-				return 1;
-		}
-		else if(zconst < 0)
-		{
-			
-			//obtain width and height of original image
-			width	= pimage->GetWidth();
-			height	= pimage->GetHeight();
-			
-			//take absolute value of zoom constant
-			int	pos_zc	= -zconst;
-			
-			//compute new width
-			if(width%pos_zc)
-				width	= width/pos_zc+1;
-			else
-				width	/= pos_zc;
-			
-			//compute new height
-			if(height%pos_zc)
-				height	= height/pos_zc+1;
-			else
-				height	/= -zconst;
-			width	= (pimage->GetWidth());
-
-			//check image bounds...
-			if((width < MIN_WIDTH)||(height < MIN_HEIGHT))
-				return 1;
-		}
-
-		/*********************************************************************/
-	}
-
-	//done.
-	return 0;
-
-}
-
-//allows one to zoom into the image stored by the image canvas
-//pre : (m_x, m_y) is the current mouse position
-//post: the image has been zoomed in by a factor of zoom_level+1
-//      1 is returned when max zoom level is reached
-int BgImCanvas::ZoomIn(int m_x, int m_y)
-{
-	//must have bitmap to zoom into
-	if(hasbitmap)
-	{
-		//make sure zoom level is not at maximum before proceeding -
-		//max_zoom_level has value 0 when unspecified
-		if((max_zoom_level)&&(zoom_level == max_zoom_level))
-		{
-			wxWindow *parent	= child_frame_->GetParent();
-			((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, true, false);
-			return 1;
-		}
-
-		//zoom image
-		int zconst = zoom_level + 1;
-		if(zconst == -1) zconst = 1;
-		int	maxZoom	= Zoom(zconst, m_x, m_y);
-
-		//take into account maximum zoom level
-		maxZoom = (maxZoom || ((max_zoom_level)&&(zoom_level == max_zoom_level)));
-
-		//set title of child frame
-		wxWindow *parent	= child_frame_->GetParent();
-		((BgMdiFrame *) parent)->SetChildTitle((wxMDIChildFrame *) child_frame_, zoom_level, maxZoom, false);
-
-		//update zoom control of child frame
-		((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, maxZoom, false);
-
-		//indicate if max zoom has occured
-		return maxZoom;
-	}
-
-	//done.
-	return 0;
-}
-
-//allows one to zoom out of the image stored by the image canvas
-//pre : (m_x, m_y) is the current mouse position
-//post: the image has been zoomed out by a factor of zoom_level-1
-//      returns 1 if minimum zoom has occured
-int BgImCanvas::ZoomOut(int m_x, int m_y)
-{
-	//must have bitmap to zoom into
-	if(hasbitmap)
-	{
-		//make sure zoom level is not at minimum before proceeding -
-		//min_zoom_level has value 0 when unspecified
-		if((min_zoom_level)&&(zoom_level == min_zoom_level))
-		{
-			wxWindow *parent	= child_frame_->GetParent();
-			((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, false, true);
-			return 1;
-		}
-
-		//zoom image
-		int zconst = zoom_level - 1;
-		if(zconst == 0)	zconst = -2;
-		int	minZoom	= Zoom(zconst, m_x, m_y);
-
-		//take into account mininimum zoom level;
-		minZoom = (int)(minZoom ||((min_zoom_level)&&(zoom_level == min_zoom_level)));
-
-		//set title of child frame
-		wxWindow *parent	= child_frame_->GetParent();
-		((BgMdiFrame *) parent)->SetChildTitle((wxMDIChildFrame *) child_frame_, zoom_level, false, minZoom);
-
-		//update zoom control of child frame
-		((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, false, minZoom);
-
-		//indicate if min zoom has occured
-		return minZoom;
-	}
-
-	//done.
-	return 0;
-}
-
-//sets max zoom level
-void BgImCanvas::SetMaxZoomLevel(int mzl)
-{
-	max_zoom_level	= mzl;
-}
-
-//sets min zoom level
-void BgImCanvas::SetMinZoomLevel(int mzl)
-{
-	min_zoom_level	= mzl;
-}
-
-
-#define WIN_PERC 16
-
-void BgImCanvas::DefineZoomBox(int l_x, int h_x, int l_y, int h_y)
-{
-
-	//obtain image height and width
-	int	iWidth = pimage->GetWidth(), iHeight = pimage->GetHeight();
-
-	//calculate box height and width
-	static int bWidth = h_x-l_x+1, bHeight = h_y-l_y+1;
-
-	//allocate/deallocate memory
-	if((bWidth != h_x-l_x+1)||(!buf))
-	{
-		bWidth	= h_x-l_x+1;
-		bHeight	= h_y-l_y+1;
-		if(buf)	delete buf;
-		buf	= new unsigned char [3*bWidth*bHeight];
-	}
-
-	//get point pen colour
-	unsigned char r, g, b;
-	if(point_colour)
-	{
-		r	= point_colour->Red();
-		g	= point_colour->Green();
-		b	= point_colour->Blue();
-	}
-
-	//crop image data and store it into buf (if the bitmap is being displayed...)
-	unsigned char	*imData		= pimage->GetData();
-	int bx, by, ix, iy, idp, bdp;
-	if(showbitmap_)
-	{
-		for(by=0; by<bHeight; by++)
-		{
-			for(bx=0; bx<bWidth; bx++)
-			{
-				ix	= bx + l_x;
-				iy	= by + l_y;
-				idp	= 3*(iy*iWidth + ix);
-				bdp	= 3*(by*bWidth + bx);
-				buf[bdp  ]	= imData[idp  ];
-				buf[bdp+1]	= imData[idp+1];
-				buf[bdp+2]	= imData[idp+2];
-				
-				//account for point sets using point map
-				if(point_map[idp/3])
-				{
-					buf[bdp]	= r;
-					buf[bdp+1]	= g;
-					buf[bdp+2]	= b;
-				}
-			}
-		}
-	}
-	//create blank (white) image and plot point set onto it
-	//prior to zoom
-	else
-	{
-		memset(buf, 255, 3*bWidth*bHeight*sizeof(unsigned char));
-		for(by=0; by<bHeight; by++)
-		{
-			for(bx=0; bx<bWidth; bx++)
-			{
-				ix	= bx + l_x;
-				iy	= by + l_y;
-				idp	= 3*(iy*iWidth + ix);
-				bdp	= 3*(by*bWidth + bx);
-
-				//account for point sets using point map
-				if(point_map[idp/3])
-				{
-					buf[bdp]	= r;
-					buf[bdp+1]	= g;
-					buf[bdp+2]	= b;
-				}
-			}
-		}
-	}
-
-	//zoom the data in buf...
-
-	//set zoom window size and allocate memory
-	static int	zWidth	= bWidth*zoom_level*2;
-	static int	zHeight	= bHeight*zoom_level*2;
-	if((zWidth != bWidth*zoom_level*2)||(!zoombox))
-	{
-		zWidth	= bWidth*zoom_level*2;
-		zHeight	= bHeight*zoom_level*2;
-		if(zoombox)	delete zoombox;
-		zoombox	= new wxImage(zWidth, zHeight);
-
-	}
-
-	//create a zoom box image using buf
-	unsigned char	*zbData	= zoombox->GetData();
-	bgZoomIn(&zbData, buf, bWidth, bHeight, zoom_level*2, false);
-
-	//done.
-	return;
-}
-
-void BgImCanvas::DefineRefreshBox(void)
-{
-
-	//obtain image height and width
-	int	iWidth = pimage->GetWidth()*zoom_level, iHeight = pimage->GetHeight()*zoom_level;
-
-	//calculate box height and width
-	static int bWidth = zoombox->GetWidth(), bHeight = zoombox->GetHeight();
-
-	//allocate/de-allocate memory for refresh box
-	if((bWidth != zoombox->GetWidth())||(!refresh_box))
-	{
-		bWidth	= zoombox->GetWidth();
-		bHeight	= zoombox->GetHeight();
-		if(refresh_box)	delete [] refresh_box;
-		refresh_box	= new wxImage(bWidth, bHeight);
-	}
-	unsigned char *rBuf	= refresh_box->GetData();
-
-	//get point pen colour
-	unsigned char r, g, b;
-	if(point_colour)
-	{
-		r	= point_colour->Red();
-		g	= point_colour->Green();
-		b	= point_colour->Blue();
-	}
-
-	//define refresh box...
-
-	//crop image data and store it into rBuf...
-	unsigned char *imData	= pimage->GetData();
-	int bx, by, ix, iy, bdp, idp;
-	for(by=0; by<bHeight; by++)
-	{
-		for(bx=0; bx<bWidth; bx++)
-		{
-			ix	= bx + cx;
-			iy	= by + cy;
-			idp	= 3*(iy*iWidth + ix);
-			bdp	= 3*(by*bWidth + bx);
-			rBuf[bdp  ]	= zImg[idp  ];
-			rBuf[bdp+1]	= zImg[idp+1];
-			rBuf[bdp+2]	= zImg[idp+2];
-		}
-	}
-
-	//done.
-	return;
-}
-
-//creates point map used by zoom and refresh windows
-void BgImCanvas::CreatePointMap(int w, int h)
-{
-
-	//initialze point map
-	if(point_map)	delete [] point_map;
-	point_map	= new bool [w*h];
-	memset(point_map, 0, w*h*sizeof(bool));
-
-	//if point sets already exist then add the,
-	if (nPointSets_ > 0)
-	{
-		//adjust point pen colour to be that of the last
-		//point set added
-		if(point_colour)	delete point_colour;
-		point_colour	= new wxColour(pointSet_[nPointSets_-1]->pen_.GetColour());
-
-		int nt, *tx, *ty, i, j;
-		for (i=0; i<nPointSets_; i++)
-		{
-			nt = pointSet_[i]->n_;
-			tx = pointSet_[i]->x_;
-			ty = pointSet_[i]->y_;
-			if(pointSet_[i]->type_ == 1) // point
-			{
-				for(j=0; j<nt; j++)
-					point_map[ty[j]*w+tx[j]] = true;
-			}
-		}
-	}
-}
-
-//adds points from point sets onto specified image
-void BgImCanvas::AddPoints(unsigned char *im, int width)
-{
-	//if point sets have been defined add point data to image
-	if(nPointSets_	> 0)
-	{
-		unsigned char r, g, b;
-		wxColour	pen_colour;
-		int	nt, *tx, *ty, i, j, x, y, dp, offset;
-		for(i=0; i < nPointSets_; i++)
-		{
-			if(pointSet_[i]->type_ == 1) //point
-			{
-				//get pen colour
-				pen_colour	= pointSet_[i]->pen_.GetColour();
-				r	= pen_colour.Red();
-				g	= pen_colour.Green();
-				b	= pen_colour.Blue();
-
-				//place points
-				nt	= pointSet_[i]->n_;
-				tx	= pointSet_[i]->x_;
-				ty	= pointSet_[i]->y_;
-				for(j=0; j<nt; j++)
-				{
-					dp = 3*(ty[j]*width+tx[j])*zoom_level;
-					for(y=0; y<zoom_level; y++)
-					{
-						for(x=0; x<zoom_level; x++)
-						{
-							offset	= 3*(y*width+x);
-							im[dp+offset  ]	= r;
-							im[dp+offset+1]	= g;
-							im[dp+offset+2]	= b;
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-//displays zoom window at cursor position
-void BgImCanvas::DisplayZoomWindow(int m_x, int m_y)
-{
-
-	//set mouse position...
-	m_x_	= m_x;
-	m_y_	= m_y;
-
-	//compute width and height of window....
-
-	/***********************************************************/
-
-	//obtain image height and width
-	int w = pimage->GetWidth(), h = pimage->GetHeight();
-
-	//take percentage of height and width to compute
-	//box half-width and half-height
-	int	hw, hh;
-	int	wp	= WIN_PERC;
-	if(w%wp)
-		hw	= w/wp + 1;
-	else
-		hw	= w/wp;
-
-	if(h%wp)
-		hh	= h/wp + 1;
-	else
-		hh	= h/wp;
-
-	/***********************************************************/
-
-	//normalize mouse coordinates to image coordinate frame
-
-	/***********************************************************/
-
-	if(zoom_level > 0)
-	{
-		m_x	= (m_x + GetScrollPos(wxHORIZONTAL))/zoom_level;
-		m_y	= (m_y + GetScrollPos(wxVERTICAL))/zoom_level;
-	}
-	else if(zoom_level < 0)
-	{
-		m_x	= (m_x + GetScrollPos(wxHORIZONTAL))*(-zoom_level);
-		m_y	= (m_y + GetScrollPos(wxVERTICAL))*(-zoom_level);
-	}
-
-	/***********************************************************/
-
-	//make sure x_m and y_m are with bounds before proceeding...
-
-	/***********************************************************/
-
-	if((m_x < 0)||(m_x >= w)||(m_y < 0)||(m_y >= h))
-		return;
-
-	/***********************************************************/
-
-	//compute zoom window bounds...
-
-	/***********************************************************/
-
-	//define window bounds based on current mouse position
-	int low_x, hi_x, low_y, hi_y;
-	if((low_x	= m_x - hw) <  0) low_x	= 0;
-	if((hi_x	= m_x + hw) >= w) hi_x	= w-1;
-	if((low_y	= m_y - hh) <  0) low_y	= 0;
-	if((hi_y	= m_y + hh) >= h) hi_y	= h-1;
-
-	//make window larger according to current mouse position	
-	if(m_x			<= hw) hi_x		+= hw-m_x;
-	if((w-m_x-1)	<= hw) low_x	-= hw-(w-m_x-1);
-	if(m_y			<= hh) hi_y		+= hh-m_y;
-	if((h-m_y-1)	<= hh) low_y	-= hh-(h-m_y-1);
-
-	/***********************************************************/
-
-	//define zoom box...
-
-	/***********************************************************/
-
-	DefineZoomBox(low_x, hi_x, low_y, hi_y);
-
-	/***********************************************************/
-
-	//display zoomed image over current mouse position...
-
-	/***********************************************************/
-
-	Refresh(false);
-
-	/***********************************************************/
-
-	//done.
-	return;
-
-}
-
-/*
-void BgImCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
-{
-}
-*/
-void BgImCanvas::FillCurveClick()
-{
-   int i;
-   for (i=0; i<ccx_*ccy_; i++)
-      curveClick_[i] = 0;
-   
-   for (i=0; i<nCurveSets_; i++)
-      curveSet_[i]->DrawYourself(curveClick_, i+1);
-
-   Refresh();
-//   write_pgm_image("curveclick.pgm", curveClick_, 256, 256, "", 4);
-}
-
-/*
-void BgImCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
-{
-   wxClientDC dc(this);
-   PrepareDC(dc);
-   if(hasbitmap==TRUE)
-   {
-      dc.DrawBitmap(*pbitmap,0,0);
-   }
-   else 
-   {
-      dc.Clear();
-   }
-}
-*/
-
-void BgImCanvas::MyDrawEllipticArc(wxDC& dc, int x, int y, int w, int h, int sa, int ea)
-{
-   double xc, yc, rx, ry;
-   rx = w/2;
-   ry = h/2;
-   xc = x+rx;
-   yc = y+ry;
-   int r, c;
-   int low_r = y_offset_;
-   int hig_r = ccy_+y_offset_;
-   int low_c = x_offset_;
-   int hig_c = ccx_+x_offset_;
-
-//   if (rx > ry)
-//   {
-      // x scan
-      for (c = (int) xc; c<=(int) (xc+rx); c++)
-      {
-         if (c>=low_c && c<hig_c)
-         {
-            r = bgRound(yc-ry*sqrt(1-(c-xc)*(c-xc)/(rx*rx)));
-            if (r>=low_r && r<hig_r)
-            {
-               dc.DrawPoint(c,r);
-               // +/- 1
-               if ((r+1)<hig_r) dc.DrawPoint(c,r+1);
-               if ((r-1)>=low_r) dc.DrawPoint(c,r-1);;
-            }
-         }
-      }
-//   }
-//   else
-//   {
-      // y scan
-      for (r = (int)(yc-ry); r<=(int) yc; r++)
-      {
-         if (r>=low_r && r<hig_r)
-         {
-            c = bgRound(xc+rx*sqrt(1-(r-yc)*(r-yc)/(ry*ry)));
-            if (c>=low_c && c<hig_c)
-            {
-               dc.DrawPoint(c,r);
-               // +/- 1
-               if ((c+1)<hig_c) dc.DrawPoint(c+1,r);
-               if ((c-1)>=low_c) dc.DrawPoint(c-1,r);;
-            }
-         }
-      }
-//   }
-}
-
-void BgImCanvas::OnMouseRightDown(wxMouseEvent& event)
-{
-   wxClientDC dc(this);
-   PrepareDC(dc);
-   wxPoint pt(event.GetLogicalPosition(dc));
-   static int x;
-   static int y;
-   x = pt.x-x_offset_;
-   y = pt.y-y_offset_;
-   if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
-   {
-      if (curveClick_[x+y*ccx_]>0)
-      {
-         lmEventCurve_ = curveClick_[x+y*ccx_] - 1;
-         if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
-         {
-            // determine if close to a node
-            int *tempx, *tempy, tempn;
-            double mindist, crtdist;
-            int i, minnode;
-            tempx = curveSet_[lmEventCurve_]->x_;
-            tempy = curveSet_[lmEventCurve_]->y_;
-            tempn = curveSet_[lmEventCurve_]->n_;
-            mindist = sqrt((x-tempx[0])*(x-tempx[0])+(y-tempy[0])*(y-tempy[0]));
-            minnode = 0;
-            for (i=1; i<tempn; i++)
-            {
-               crtdist = sqrt((x-tempx[i])*(x-tempx[i])+(y-tempy[i])*(y-tempy[i]));
-               if (crtdist < mindist)
-               {
-                  mindist = crtdist;
-                  minnode = i;
-               }
-            }
-            if (mindist <= 3)
-            {
-               // delete node option
-               lmEventNode_ = minnode;
-               localMenu_->Enable(BG_IMC_ADDNODE,FALSE);
-               localMenu_->Enable(BG_IMC_DELETENODE,TRUE);
-            } else
-            {
-               // add node option
-               localMenu_->Enable(BG_IMC_ADDNODE,TRUE);
-               localMenu_->Enable(BG_IMC_DELETENODE,FALSE);
-            }
-         }
-         else
-         {
-            localMenu_->Enable(BG_IMC_ADDNODE,FALSE);
-            localMenu_->Enable(BG_IMC_DELETENODE,FALSE);
-         }
-         lmEventX_ = x;//+x_offset_;
-         lmEventY_ = y;//+y_offset_;
-         PopupMenu(localMenu_, x+x_offset_, y+y_offset_);
-      }
-   }
-}
-
-/*
-//updates hover menu during scroll event
-void BgImCanvas::OnScroll(wxScrollWinEvent& event)
-{
-
-}
-*/
-
-//attemtps to adjust scroll position of window according
-//to current mouse position
-void BgImCanvas::AdjustScroll(int x, int y, int action)
-{
-	if(zoom_level > 1)
-	{
-
-		//get window width and height
-		int	winWidth, winHeight;
-		GetSize(&winWidth, &winHeight);
-
-		//get window vertical and horzontal scroll position
-		//and offset current mouse position to obtain mouse
-		//position relative to the image
-		x	= x + GetScrollPos(wxHORIZONTAL);
-		y	= y + GetScrollPos(wxVERTICAL);
-
-		//re-location mouse position relative to new image width
-		//and height
-		if(action == ZOOM_IN)
-		{
-			x	= zoom_level*(x/(zoom_level-1));
-			y	= zoom_level*(y/(zoom_level-1));
-		}
-		else if(action == ZOOM_OUT)
-		{
-			x	= zoom_level*(x/(zoom_level+1));
-			y	= zoom_level*(y/(zoom_level+1));
-		}
-
-		//resize scroll
-		int	width	= (pimage->GetHeight())*zoom_level;
-		int	height	= (pimage->GetWidth())*zoom_level;
-		SetScrollbars(1, 1, width, height);
-
-		//set scroll position according to x and y
-		int offset_x	= x/2;
-		int offset_y	= y/2;
-		SetScrollPos(wxHORIZONTAL, offset_x, true);
-		SetScrollPos(wxVERTICAL, offset_y, true);
-
-		//refresh window contents
-		Scroll(offset_x, offset_y);
-	}
-}
-
-void BgImCanvas::OnEvent(wxMouseEvent& event)
-{
-/*
-   wxClientDC dc(this);
-   PrepareDC(dc);
-   
-   wxPoint pt(event.GetLogicalPosition(dc));
-   
-   if (g_xpos > -1 && g_ypos > -1 && event.Dragging())
-   {
-      dc.SetPen(*wxBLACK_PEN);
-      dc.DrawLine(g_xpos, g_ypos, pt.x, pt.y);
-      
-      m_dirty = TRUE;
-   }
-   
-   g_xpos = pt.x;
-   g_ypos = pt.y;
-   */
-
-
-   //store mouse pointer location...
-   m_x_	= event.m_x;
-   m_y_	= event.m_y;
-
-   //keep track of menu window (hide/show)...
-   static bool hideWindow = true;
-   if((m_x_ >= menuXl_)&&(m_y_ >= menuYl_)&&(m_x_ <= menuXu_)&&(m_y_ <= menuYu_))
-	   hideWindow	= false;
-   else if(!event.Leaving())
-	   hideWindow	= true;
-
-   wxClientDC dc(this);
-   PrepareDC(dc);
-   wxPoint pt(event.GetLogicalPosition(dc));
-   static int x;
-   static int y;
-   static int curvedrag;
-   x = pt.x-x_offset_;
-   y = pt.y-y_offset_;
-//   x = event.GetX();
-//   y = event.GetY();
-
-   if (isDragging_ == 0 && event.LeftDown())
-   {
-      // check if over any line
-      if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
-      {
-         if (curveClick_[x+y*ccx_]>0)
-         {
-            isDragging_ = 1;
-            curvedrag = curveClick_[x+y*ccx_]-1;
-            dragCurve_.SetCurve(curveSet_[curveClick_[x+y*ccx_]-1]);
-            dragCurve_.pen_.SetColour(wxColour(128,128,128));
-            dragCurve_.StartDragging(x, y);
-            Refresh();
-         }
-      }
-   }
-   else if (isDragging_ == 1 && event.Dragging())
-   {
-      // modify curve to drag
-      dragCurve_.DragTo(x, y);
-      Refresh(false);
-   }
-   else if (isDragging_ == 1)// && event.LeftUp())
-   {
-      isDragging_ = 0;
-      dragCurve_.EndDragging(x, y);
-      curveSet_[curvedrag]->SetCurve(&dragCurve_);
-      FillCurveClick();
-      mouseModif_ = 1;
-      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
-      Refresh();
-   }
-   else if (isDragging_ == 0 && event.Moving())
-   {
-      // check if over any line
-      if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
-      {
-         if (curveClick_[x+y*ccx_]>0 && crossCursor_ == 0)
-         {
-            crossCursor_ = 1;
-            SetCursor(*wxCROSS_CURSOR);
-         }
-         else if (crossCursor_ == 1)
-         {
-            SetCursor(*wxSTANDARD_CURSOR);
-            crossCursor_ = 0;
-         }
-      }
-   }
-
-   //if zoom is enabled, set the cursor to the zoom icon
-   //otherwise leave it as default
-   if(event.Entering())
-   {
-	   //when parent is not the active child frame, set the cursor
-	   //to wxCURSOR_ARROW
-	   bool	current_child	= false;
-	   wxMDIParentFrame *parent	= (wxMDIParentFrame *)(child_frame_->GetParent());
-	   wxMDIChildFrame	*activeChild	= parent->GetActiveChild();
-	   if(activeChild == (wxMDIChildFrame *) child_frame_)
-		   current_child	= true;
-
-	   if((zoom_out || zoom_in)&&(current_child))
-		   SetCursor(wxCURSOR_MAGNIFIER);
-	   else if((zoom_window)&&(current_child))
-		   SetCursor(wxCURSOR_CROSS);
-	   else
-		   SetCursor(wxCURSOR_ARROW);
-
-	   //indiciate that the window has acquired focus
-	   has_focus	= true;
-
-	   //show the menu window
-	   if((menuWindow)&&(popup))
-		   menuWindow->Show(TRUE);
-   }
-
-   //indicate that the window has lost focus
-   if(event.Leaving())
-   {
-	   //indicate that the window has lost focus
-	   has_focus	= false;
-
-	   //indicate that the mouse pointer is leaving
-	   //this window
-	   leaving		= true;
-
-	   //refresh canvas upon using a zoom window
-	   if(zoom_window)
-		Refresh(false);
-
-	   //hide the menu window
-	   if((hideWindow)&&(popup)&&(menuWindow))
-		   menuWindow->Show(FALSE);
-
-   }
-
-   //check if the left mouse button has been clicked and zoom is activated
-   //if so zoom the image
-   if(event.LeftDown()&&zoom_in)
-	   ZoomIn(m_x_, m_y_);
-
-   if((event.LeftDown())&&zoom_out)
-	   ZoomOut(m_x_, m_y_);
-
-   if(zoom_window)
-	   DisplayZoomWindow(m_x_, m_y_);
-
-}
-
-void BgImCanvas::AddHoverWindow(wxWindow* hoverWindow, int pp)
-{
-	popup		= pp;
-	menuWindow	= hoverWindow;
-	if(popup)	menuWindow->Show(FALSE);
-	else		menuWindow->Show(TRUE);
-	int width, height;
-	menuWindow->GetSize(&width, &height);
-	menuXl_	= HOVER_MENU_X - HOVER_MENU_BOUND;
-	menuYl_	= HOVER_MENU_Y - HOVER_MENU_BOUND;
-	menuXu_	= menuXl_ + width + HOVER_MENU_BOUND;
-	menuYu_	= menuXu_ + width + HOVER_MENU_BOUND;
-	menuWindow->SetSize(HOVER_MENU_X, HOVER_MENU_Y, width, height);
-}
-
-void BgImCanvas::SetHoverWindowLocation(int x, int y)
-{
-	int width, height;
-	menuWindow->GetSize(&width, &height);
-	if((x < 0)||(x >= width)||(y < 0)||(y >= height))	return;
-	menuWindow->SetSize(x, y, width, height);
-}
-
-// ---------------------------------------------------------------------------
-// BgMdiEdgeChild
-// ---------------------------------------------------------------------------
-
-BgMdiEdgeChild::BgMdiEdgeChild(wxMDIParentFrame *parent, const wxString& title,
-                           const wxPoint& pos, const wxSize& size,
-                           const long style)
-                           : wxMDIChildFrame(parent, BG_EDGE_WINDOW, title, pos, size, style)
-{
-
-   //set window number
-   window_number_ = gs_nFrames;
-
-   //assume image is not yet loaded into segmentation window
-   filename_	= NULL;
-
-   bpsize_ = 160;
-
-   imagePlotSplitter_ = new wxSplitterWindow(this, -1, wxPoint(bpsize_, 0), wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   plotSplitter_ = new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   origEdgeImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
-   origEdgeImage_->SetScrollbars(20, 20, 50, 50);
-   plotNmxImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
-
-   plotNmxImage_->SetScrollbars(20, 20, 50, 50);
-   plotTotImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
-
-   plotTotImage_->SetScrollbars(20, 20, 50, 50);
-   
-   g_children.Append(this);
-   //imagePlotSplitter_->SetClientSize(GetClientSize());
-   imagePlotSplitter_->SplitVertically(origEdgeImage_, plotSplitter_,256);
-   plotSplitter_->SplitHorizontally(plotNmxImage_, plotTotImage_,256);
-
-   // panel stuff
-   buttonPanel_ = new wxPanel(this, -1, wxPoint(0, 0));
-   edButton_ = new wxButton(buttonPanel_, BG_EDGE_DETECT, "Edge Detect", wxPoint(40,10));
-   cpButton_ = new wxButton(buttonPanel_, BG_CHANGE_PARAM_EDGE, "Change...", wxPoint(40,155));
-
-   wxStaticBox* viewSB = new wxStaticBox(buttonPanel_, -1, "View", wxPoint(35, 45), wxSize(85, 65)); 
-   viewOrigCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_ORIG, "Image", wxPoint(45,65));//, wxPoint(10,85));
-   viewEdgeCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_EDGE, "Edges", wxPoint(45,85));//, wxPoint(10,105));
-
-   int deltal = 45;
-   // put the parameters
-   wxStaticText* stParam = new wxStaticText(buttonPanel_, -1, "PARAMETERS:", wxPoint(C_PARAMX-5, 105 + C_PARAMY));
-
-   txtKernelSize_ = new wxStaticText(buttonPanel_, -1, "Grad Win.", wxPoint(C_PARAMX-5,deltal+125+C_PARAMY+0*C_PARAMDY));
-   valKernelSize_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX+35,deltal+125+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
-
-   txtMinPt_ = new wxStaticText(buttonPanel_, -1, "Min. length", wxPoint(C_PARAMX-5,deltal+125+C_PARAMY+1*C_PARAMDY));
-   valMinPt_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX+35,deltal+125+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
-
-   wxStaticBox* nmxSB = new wxStaticBox(buttonPanel_, -1, "Nonmaxima supp.", wxPoint(5, deltal+205+0), wxSize(140,4*C_PARAMDY-5));
-   txtNmxType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX, deltal+205+C_PARAMY+0*C_PARAMDY));
-   valNmxType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   txtNmxR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+205+C_PARAMY+1*C_PARAMDY));
-   valNmxR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   txtNmxC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+205+C_PARAMY+2*C_PARAMDY));
-   valNmxC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-
-   wxStaticBox* hhSB = new wxStaticBox(buttonPanel_, -1, "Hyst. High Tr.", wxPoint(5, deltal+325+0), wxSize(140,4*C_PARAMDY-5));
-   txtHHType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX,deltal+325+C_PARAMY+0*C_PARAMDY));
-   txtHHR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+325+C_PARAMY+1*C_PARAMDY));
-   txtHHC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+325+C_PARAMY+2*C_PARAMDY));
-   valHHType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHHR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHHC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-
-   wxStaticBox* hlSB = new wxStaticBox(buttonPanel_, -1, "Hyst. Low Tr.", wxPoint(5, deltal+445+0), wxSize(140, 4*C_PARAMDY-5));
-   txtHLType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX,deltal+445+C_PARAMY+0*C_PARAMDY));
-   txtHLR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+445+C_PARAMY+1*C_PARAMDY));
-   txtHLC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+445+C_PARAMY+2*C_PARAMDY));
-   valHLType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHLR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHLC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   
-
-   //set lower bound zoom limit on display image
-   //to the size of the original image
-   origEdgeImage_->SetMinZoomLevel(1);
-
-   // set default parameters for edge detection
-   rankNmx_ = RANK_NMX;
-   confNmx_ = CONF_NMX;
-   rankH_ = RANK_H;
-   confH_ = CONF_H;
-   rankL_ = RANK_L;
-   confL_ = CONF_L;
-   nMin_ = NMIN;
-   nmxType_ = FC_ELLIPSE;
-   hystHighType_ = FC_SQUARE_BOX;
-   hystLowType_ = FC_ELLIPSE;
-   kernelSize_ = KERNEL_SIZE;
-
-   //set params
-   SetParametersNum();
-   SetParametersStr();
-
-   // also default custom parameters
-   nCustH_ = 3;
-   nCustL_ = 3;
-   custHx_[0] = 0;
-   custHx_[1] = 0.7;
-   custHx_[2] = 1;
-   custHy_[0] = 1;
-   custHy_[1] = 0.7;
-   custHy_[2] = 0;
-
-   custLx_[0] = 0;
-   custLx_[1] = 0.5;
-   custLx_[2] = 0.7;
-   custLy_[0] = 0.7;
-   custLy_[1] = 0.5;
-   custLy_[2] = 0;
-
-   // set the values in the boxes
-
-//   cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
-   cbgEdgeDetect_ = 0;
-   cbgImage_ = new BgImage();
-   cbgEdgeList_ = 0;
-   hasEdge_ = 0;
-   hasImage_ = 0;
-
-   int w, h;
-   GetClientSize(&w, &h);
-   buttonPanel_->SetSize(0, 0, bpsize_, h);
-   imagePlotSplitter_->SetSize(bpsize_, 0, w-bpsize_, h);
-   imagePlotSplitter_->SetSashPosition(bpsize_+(w-bpsize_)/2,TRUE);
-   plotSplitter_->SetSashPosition(h/2,TRUE);
-   rightsize_ = (w-bpsize_)/2;
-   viewOrigCheck_->SetValue(TRUE);
-   viewEdgeCheck_->SetValue(TRUE);
-
-   plotTotImage_->AddCurveSet(&nmxCurve_);
-   plotNmxImage_->AddCurveSet(&highCurve_);
-   plotNmxImage_->AddCurveSet(&lowCurve_);
-   lowCurve_.pen_.SetColour(255,0,0);
-
-   //add margin to plots
-   plotNmxImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-   plotTotImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-
-   //add title to each individual plot
-   BgText bgText(1, "      Diagram after Non-Maxima Supression", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
-
-   plotNmxImage_->AddText(&bgText);
-   bgText.SetText("      Diagram before Non-Maxima Supression");
-   plotTotImage_->AddText(&bgText);
-
-   //add x and y axis
-   plotNmxImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
-   plotNmxImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
-   plotTotImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
-   plotTotImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
-
-   //label x and y axis
-   bgText.SetText("Rank (   )");
-   plotNmxImage_->LabelHorizontalAxis(&bgText);
-   plotTotImage_->LabelHorizontalAxis(&bgText);
-   bgText.SetText("Confidence (  )");
-   plotNmxImage_->LabelVerticalAxis(&bgText);
-   plotTotImage_->LabelVerticalAxis(&bgText);
-
-   //place greek symbols
-   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
-   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
-   plotNmxImage_->AddBitmap(&ro_bmp);
-   plotNmxImage_->AddBitmap(&eta_bmp);
-   plotTotImage_->AddBitmap(&ro_bmp);
-   plotTotImage_->AddBitmap(&eta_bmp);
-   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
-   ro_bmp.SetId(3);
-   plotNmxImage_->AddBitmap(&ro_bmp);
-   plotTotImage_->AddBitmap(&ro_bmp);
-   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
-   plotNmxImage_->AddBitmap(&rotated_eta_bmp);
-   plotTotImage_->AddBitmap(&rotated_eta_bmp);
-
-   //indicate that the edge window is now open
-   window_open	= true;
-
-   //disable edge detection button
-   edButton_->Enable(false);
-
-   //get parent tool bar and update it
-   toolbar	= parent->GetToolBar();
-   UpdateToolBar();
-
-   //set max/min zoom
-   maxZoom_	= 0;
-   minZoom_	= 1;
-
-}
-
-/*
-BgMdiEdgeChild::BgMdiEdgeChild(wxMDIParentFrame *parent, const wxString& title,
-                           const wxPoint& pos, const wxSize& size,
-                           const long style)
-                           : wxMDIChildFrame(parent, BG_EDGE_WINDOW, title, pos, size, style)
-{
-
-   //set window number
-   window_number_ = gs_nFrames;
-
-   //assume image is not yet loaded into segmentation window
-   filename_	= NULL;
-
-   bpsize_ = 100;
-   imagePlotSplitter_ = new wxSplitterWindow(this, -1,wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   plotSplitter_ = new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   origEdgeImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
-   origEdgeImage_->SetScrollbars(20, 20, 50, 50);
-   plotNmxImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
-
-   plotNmxImage_->SetScrollbars(20, 20, 50, 50);
-   plotTotImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
-
-   plotTotImage_->SetScrollbars(20, 20, 50, 50);
-   
-   g_children.Append(this);
-   //imagePlotSplitter_->SetClientSize(GetClientSize());
-   imagePlotSplitter_->SplitVertically(origEdgeImage_, plotSplitter_,256);
-   plotSplitter_->SplitHorizontally(plotNmxImage_, plotTotImage_,256);
-   // panel stuff
-   buttonPanel_ = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
-   edButton_ = new wxButton(buttonPanel_, BG_EDGE_DETECT, "Edge Detect", wxPoint(10,10));
-   cpButton_ = new wxButton(buttonPanel_, BG_CHANGE_PARAM_EDGE, "Parameters...", wxPoint(10,45));
-   viewOrigCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_ORIG, "View Image", wxPoint(10,85));
-   viewEdgeCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_EDGE, "View Edges", wxPoint(10,105));
-
-   //set lower bound zoom limit on display image
-   //to the size of the original image
-   origEdgeImage_->SetMinZoomLevel(1);
-
-   // set default parameters for edge detection
-   rankNmx_ = RANK_NMX;
-   confNmx_ = CONF_NMX;
-   rankH_ = RANK_H;
-   confH_ = CONF_H;
-   rankL_ = RANK_L;
-   confL_ = CONF_L;
-   nMin_ = NMIN;
-   nmxType_ = FC_ELLIPSE;
-   hystHighType_ = FC_SQUARE_BOX;
-   hystLowType_ = FC_ELLIPSE;
-   kernelSize_ = KERNEL_SIZE;
-
-   // also default custom parameters
-   nCustH_ = 3;
-   nCustL_ = 3;
-   custHx_[0] = 0;
-   custHx_[1] = 0.7;
-   custHx_[2] = 1;
-   custHy_[0] = 1;
-   custHy_[1] = 0.7;
-   custHy_[2] = 0;
-
-   custLx_[0] = 0;
-   custLx_[1] = 0.5;
-   custLx_[2] = 0.7;
-   custLy_[0] = 0.7;
-   custLy_[1] = 0.5;
-   custLy_[2] = 0;
-
-
-
-//   cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
-   cbgEdgeDetect_ = 0;
-   cbgImage_ = new BgImage();
-   cbgEdgeList_ = 0;
-   hasEdge_ = 0;
-   hasImage_ = 0;
-
-   int w, h;
-   GetClientSize(&w, &h);
-   buttonPanel_->SetSize(w-bpsize_, 0, bpsize_, h);
-   imagePlotSplitter_->SetSize(0, 0, w-bpsize_, h);
-   imagePlotSplitter_->SetSashPosition((w-bpsize_)/2,TRUE);
-   plotSplitter_->SetSashPosition(h/2,TRUE);
-   rightsize_ = (w-bpsize_)/2;
-   viewOrigCheck_->SetValue(TRUE);
-   viewEdgeCheck_->SetValue(TRUE);
-
-   plotTotImage_->AddCurveSet(&nmxCurve_);
-   plotNmxImage_->AddCurveSet(&highCurve_);
-   plotNmxImage_->AddCurveSet(&lowCurve_);
-   lowCurve_.pen_.SetColour(255,0,0);
-
-   //add margin to plots
-   plotNmxImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-   plotTotImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-
-   //add title to each individual plot
-   BgText bgText(1, "      Diagram after Non-Maxima Supression", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
-
-   plotNmxImage_->AddText(&bgText);
-   bgText.SetText("      Diagram before Non-Maxima Supression");
-   plotTotImage_->AddText(&bgText);
-
-   //add x and y axis
-   plotNmxImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
-   plotNmxImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
-   plotTotImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
-   plotTotImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
-
-   //label x and y axis
-   bgText.SetText("Rank (   )");
-   plotNmxImage_->LabelHorizontalAxis(&bgText);
-   plotTotImage_->LabelHorizontalAxis(&bgText);
-   bgText.SetText("Confidence (  )");
-   plotNmxImage_->LabelVerticalAxis(&bgText);
-   plotTotImage_->LabelVerticalAxis(&bgText);
-
-   //place greek symbols
-   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
-   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
-   plotNmxImage_->AddBitmap(&ro_bmp);
-   plotNmxImage_->AddBitmap(&eta_bmp);
-   plotTotImage_->AddBitmap(&ro_bmp);
-   plotTotImage_->AddBitmap(&eta_bmp);
-   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
-   ro_bmp.SetId(3);
-   plotNmxImage_->AddBitmap(&ro_bmp);
-   plotTotImage_->AddBitmap(&ro_bmp);
-   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
-   plotNmxImage_->AddBitmap(&rotated_eta_bmp);
-   plotTotImage_->AddBitmap(&rotated_eta_bmp);
-
-   //indicate that the edge window is now open
-   window_open	= true;
-
-   //disable edge detection button
-   edButton_->Enable(false);
-
-   //get parent tool bar and update it
-   toolbar	= parent->GetToolBar();
-   UpdateToolBar();
-
-   //set max/min zoom
-   maxZoom_	= 0;
-   minZoom_	= 1;
-
-}
-*/
-
-BgMdiEdgeChild::~BgMdiEdgeChild()
-{
-   if(filename_)	delete [] filename_;
-
-   if (hasEdge_ == 1)
-     origEdgeImage_->RemovePointSet(&cbgPointSet_);
-
-   if (cbgEdgeList_ != 0)
-      delete cbgEdgeList_;
-   delete cbgImage_;
-   if (cbgEdgeDetect_ != 0)
-      delete cbgEdgeDetect_;
-
-   delete viewEdgeCheck_;
-   delete viewOrigCheck_;
-   delete cpButton_;
-   delete edButton_;
-   delete buttonPanel_;
-
-
-
-   delete origEdgeImage_;
-   delete plotNmxImage_;
-   delete plotTotImage_;
-
-   delete plotSplitter_;
-   delete imagePlotSplitter_;
-   g_children.DeleteObject(this);
-}
-
-void BgMdiEdgeChild::OnUpdateNum(wxCommandEvent& WXUNUSED(event))
-{
-   double tx[MAX_CUSTOM_NODES];
-   double ty[MAX_CUSTOM_NODES];
-   int ttype,i;
-   int npoints,modif=0;
-   if (plotNmxImage_->mouseModif_ == 1)
-   {
-      modif = 1;
-      // get new hyst params
-      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystHighType_ = ttype;
-         rankH_ = tx[0];
-         confH_ = ty[0];
-      } else
-      {
-         hystHighType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custHx_[i] = tx[i];
-            custHy_[i] = ty[i];
-         }
-         nCustH_ = npoints;
-      }
-      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystLowType_ = ttype;
-         rankL_ = tx[0];
-         confL_ = ty[0];
-      } else
-      {
-         hystLowType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custLx_[i] = tx[i];
-            custLy_[i] = ty[i];
-         }
-         nCustL_ = npoints;
-      }
-      plotNmxImage_->mouseModif_ = 0;
-   }
-   if (plotTotImage_->mouseModif_ == 1)
-   {
-      modif = 1;
-      // get new nmx params
-      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         nmxType_ = ttype;
-         rankNmx_ = tx[0];
-         confNmx_ = ty[0];
-      }
-      plotTotImage_->mouseModif_ = 0;
-   }
-   if (modif == 1)
-   {
-      SetParametersNum();
-      SetParametersStr();
-   }
-}
-
-void BgMdiEdgeChild::SetParametersNum()
-{
-   wxString ts;
-   ts = wxString::Format("%.3g", rankH_);
-   valHHR_->SetLabel(ts);
-   ts = wxString::Format("%.3g", confH_);
-   valHHC_->SetLabel(ts);
-   ts = wxString::Format("%.3g", rankL_);
-   valHLR_->SetLabel(ts);
-   ts = wxString::Format("%.3g", confL_);
-   valHLC_->SetLabel(ts);
-   ts = wxString::Format("%.3g", rankNmx_);
-   valNmxR_->SetLabel(ts);
-   ts = wxString::Format("%.3g", confNmx_);
-   valNmxC_->SetLabel(ts);
-}
-void BgMdiEdgeChild::SetParametersStr()
-{
-   switch(hystHighType_)
-   {
-   case FC_ELLIPSE:
-      valHHType_->SetLabel("arc");
-      break;
-   case FC_VERT_LINE:
-      valHHType_->SetLabel("vertical line");		
-      break;
-   case FC_HORIZ_LINE:
-      valHHType_->SetLabel("horizontal line");		
-      break;
-   case FC_SQUARE_BOX:
-      valHHType_->SetLabel("box");		
-      break;
-   case FC_LINE:
-      valHHType_->SetLabel("line");  		
-      break;
-  	case FC_CUSTOM:
-      valHHType_->SetLabel("custom");
-      break;
-   }
-
-   switch(hystLowType_)
-   {
-   case FC_ELLIPSE:
-      valHLType_->SetLabel("arc");
-      break;
-   case FC_VERT_LINE:
-      valHLType_->SetLabel("vertical line");		
-      break;
-   case FC_HORIZ_LINE:
-      valHLType_->SetLabel("horizontal line");		
-      break;
-   case FC_SQUARE_BOX:
-      valHLType_->SetLabel("box");		
-      break;
-   case FC_LINE:
-      valHLType_->SetLabel("line");  		
-      break;
-  	case FC_CUSTOM:
-      valHLType_->SetLabel("custom");
-      break;
-   }
-
-   switch(nmxType_)
-   {
-   case FC_ELLIPSE:
-      valNmxType_->SetLabel("arc");
-      break;
-   case FC_VERT_LINE:
-      valNmxType_->SetLabel("vertical line");		
-      break;
-   case FC_HORIZ_LINE:
-      valNmxType_->SetLabel("horizontal line");		
-      break;
-   case FC_SQUARE_BOX:
-      valNmxType_->SetLabel("box");		
-      break;
-   case FC_LINE:
-      valNmxType_->SetLabel("line");  		
-      break;
-  	case FC_CUSTOM:
-      valNmxType_->SetLabel("custom");
-      break;
-   }   
-   wxString ts;
-   ts = wxString::Format("%d", nMin_);
-   valMinPt_->SetLabel(ts);
-   ts = wxString::Format("%d", kernelSize_);
-   valKernelSize_->SetLabel(ts);
-
-
-}
-
-void BgMdiEdgeChild::OnViewEdge(wxCommandEvent&  WXUNUSED(event))
-{
-   viewEdgeCheck_->SetValue(miViewEdge_->IsChecked());
-
-   if (hasEdge_ == false)
-      return;
-
-   if (miViewEdge_->IsChecked() == TRUE)
-   {
-      // show edges
-      origEdgeImage_->AddPointSet(&cbgPointSet_);
-
-   }
-   else
-   {
-      // hide edges
-      origEdgeImage_->RemovePointSet(&cbgPointSet_);
-   }
-
-}
-
-void BgMdiEdgeChild::OnViewOrig(wxCommandEvent&  WXUNUSED(event))
-{
-   viewOrigCheck_->SetValue(miViewOrig_->IsChecked());
-
-   if (hasImage_ == false)
-      return;
-
-   if (miViewOrig_->IsChecked() == TRUE)
-   {
-      // show edges
-      //canvas->AddPointSet(edgesSeq_[crtImage_]);
-      origEdgeImage_->ShowBitmap(true);
-   }
-   else
-   {
-      // hide edges
-      //canvas->RemovePointSet(edgesSeq_[crtImage_]);
-      origEdgeImage_->ShowBitmap(false);
-   }
-   origEdgeImage_->Refresh();
-
-}
-
-void BgMdiEdgeChild::OnCViewEdge(wxCommandEvent&  WXUNUSED(event))
-{
-   miViewEdge_->Check(viewEdgeCheck_->GetValue());
-   if (hasEdge_ == false)
-      return;
-
-   if (viewEdgeCheck_->GetValue() == TRUE)
-   {
-      // show edges
-      origEdgeImage_->AddPointSet(&cbgPointSet_);
-
-   }
-   else
-   {
-      // hide edges
-      origEdgeImage_->RemovePointSet(&cbgPointSet_);
-   }
-}
-
-void BgMdiEdgeChild::OnCViewOrig(wxCommandEvent&  WXUNUSED(event))
-{
-   miViewOrig_->Check(viewOrigCheck_->GetValue());
-
-   if (hasImage_ == false)
-      return;
-
-   if (viewOrigCheck_->GetValue() == TRUE)
-   {
-      // show edges
-      //canvas->AddPointSet(edgesSeq_[crtImage_]);
-      origEdgeImage_->ShowBitmap(true);
-   }
-   else
-   {
-      // hide edges
-      //canvas->RemovePointSet(edgesSeq_[crtImage_]);
-      origEdgeImage_->ShowBitmap(false);
-   }
-
-}
-
-
-void BgMdiEdgeChild::OnSize(wxSizeEvent& WXUNUSED(event))
-{
-   int w, h;
-   GetClientSize(&w, &h);
-   buttonPanel_->SetSize(0, 0, bpsize_, h);
-   imagePlotSplitter_->SetSize(bpsize_, 0, w-bpsize_, h);
-   plotSplitter_->SetSashPosition(h/2,TRUE);
-   h = w-bpsize_-rightsize_;
-   h = (h<0)? 0:h;
-   imagePlotSplitter_->SetSashPosition(h,TRUE);
-}
-
-void BgMdiEdgeChild::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-   Close(TRUE);
-}
-
-void BgMdiEdgeChild::OnClose(wxCloseEvent& event)
-{
-   gs_nFrames--;
-   //indicate that the window is closed (used by OnFocus)
-   window_open	= false;
-   //reset toolbar
-   if(gs_nFrames == 0) ResetToolBar();
-   event.Skip();
-}
-
-void BgMdiEdgeChild::OnFocus(wxFocusEvent& WXUNUSED(event))
-{
-	//update toolbar
-	if(!on_exit) UpdateToolBar();
-	return;
-}
-
-void BgMdiEdgeChild::ZoomWindow(void)
-{
-	//display zoom window
-	origEdgeImage_->zoom_window	= true;
-	origEdgeImage_->zoom_in		= false;
-	origEdgeImage_->zoom_out		= false;
-}
-
-void BgMdiEdgeChild::ZoomIn(void)
-{
-	//zoom into display image
-	origEdgeImage_->zoom_window	= false;
-	origEdgeImage_->zoom_in		= true;
-	origEdgeImage_->zoom_out		= false;
-	return;
-}
-
-void BgMdiEdgeChild::ZoomOut(void)
-{
-	//zoom out of display image
-	origEdgeImage_->zoom_window	= false;
-	origEdgeImage_->zoom_in		= false;
-	origEdgeImage_->zoom_out		= true;
-	return;
-}
-
-void BgMdiEdgeChild::NoZoom(void)
-{
-	//do not zoom display image
-	origEdgeImage_->zoom_window	= false;
-	origEdgeImage_->zoom_in		= false;
-	origEdgeImage_->zoom_out	= false;
-	return;
-}
-
-void BgMdiEdgeChild::UpdateZoomControl(void)
-{
-	//determine whether to enable zoom in control based on maximum zoom
-	if(maxZoom_ || minZoom_)
-		UpdateToolBar();
-	else
-	{
-//		toolbar->Realize();
-		toolbar->EnableTool(BG_ZOOM_IN, true);
-		toolbar->EnableTool(BG_ZOOM_OUT, true);
-	}
-}
-
-void BgMdiEdgeChild::RunEnable(void)
-{
-	edButton_->Enable(true);
-	wxMenuBar *menubar = GetMenuBar();
-	menubar->Enable(BG_EDGE_DETECT, true);
-}
-
-void BgMdiEdgeChild::SaveEnable(void)
-{
-//	toolbar->Realize();
-	toolbar->EnableTool(BG_SAVE_RESULT, true);
-}
-
-void BgMdiEdgeChild::UpdateToolBar(void)
-{
-	//update toolbar
-	if(window_open)
-	{
-		//determine whether to enable save based on whether segmentation
-		//has occurred
-		bool save_enable;
-		if(hasEdge_)
-			save_enable	= true;
-		else
-			save_enable	= false;
-
-		//determine whether to enable zoom controls based on whether image
-		//has been loaded
-		bool load_enable;
-		if(hasImage_)
-			load_enable	= true;
-		else
-			load_enable	= false;
-
-		//determine whether to enable zoom in control based on maximum zoom
-		bool max_zoom;
-		if(maxZoom_)
-			max_zoom	= true;
-		else
-			max_zoom	= false;
-
-		//determine whether to enable zoom out control based on minimum zoom
-		bool min_zoom;
-		if(minZoom_)
-			min_zoom	= true;
-		else
-			min_zoom	= false;
-
-		//adjust toolbar
-		toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to perform edge detection");
-		toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save edge map");
-		toolbar->EnableTool(BG_SAVE_RESULT, save_enable);
-		toolbar->EnableTool(BG_CROSS, load_enable);
-		toolbar->EnableTool(BG_ZOOM_IN, ((load_enable)&&(!max_zoom)));
-		toolbar->EnableTool(BG_ZOOM_OUT, ((load_enable)&&(!min_zoom)));
-		toolbar->EnableTool(BG_POINTER, true);
-
-		//set to no zoom
-		toolbar->ToggleTool(BG_CROSS, false);
-		toolbar->ToggleTool(BG_ZOOM_IN, false);
-		toolbar->ToggleTool(BG_ZOOM_OUT, false);
-		toolbar->ToggleTool(BG_POINTER, true);
-		origEdgeImage_->SetCursor(wxCURSOR_ARROW);
-		NoZoom();
-
-//		toolbar->Realize();
-	}
-	return;
-}
-
-void BgMdiEdgeChild::ResetToolBar(void)
-{
-	//update toolbar
-	toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to process");
-	toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save result");
-	toolbar->EnableTool(BG_SAVE_RESULT, false);
-	toolbar->EnableTool(BG_CROSS, false);
-	toolbar->EnableTool(BG_ZOOM_IN, false);
-	toolbar->EnableTool(BG_ZOOM_OUT, false);
-	toolbar->EnableTool(BG_POINTER, false);
-	toolbar->ToggleTool(BG_CROSS, false);
-	toolbar->ToggleTool(BG_ZOOM_IN, false);
-	toolbar->ToggleTool(BG_ZOOM_OUT, false);
-	toolbar->ToggleTool(BG_POINTER, false);
-//	toolbar->Realize();
-	return;
-}
-
-void BgMdiEdgeChild::ReadImage(char *pathname, char *filename)
-{
-	plotTotImage_->ClearData(1);
-	plotNmxImage_->ClearData(1);
-	
-	if (origEdgeImage_->SetImage(pathname) == 0)
-		return;
-	bgLog("Image %s loaded\n",pathname);
-
-	//obtain and store image filename
-	if(filename_)	delete [] filename_;
-	filename_	= new char [strlen(filename) + 1];
-	strcpy(filename_, filename);
-	
-	miViewOrig_->Check(TRUE);
-	viewOrigCheck_->SetValue(TRUE);
-	origEdgeImage_->showbitmap_ = true;
-	
-	if (hasEdge_ == 1)
-        origEdgeImage_->RemovePointSet(&cbgPointSet_);
-	// set cbgImage
-	cbgImage_->SetImageFromRGB(origEdgeImage_->pimage->GetData(), origEdgeImage_->pimage->GetWidth(), origEdgeImage_->pimage->GetHeight());
-	if (cbgEdgeDetect_ != 0)
-		delete cbgEdgeDetect_;
-	cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
-	hasImage_ = 1;
-	hasEdge_ = 0;
-	
-	//get image dimension
-	width_			= origEdgeImage_->pimage->GetWidth();
-	height_			= origEdgeImage_->pimage->GetHeight();
-	
-	//reset the zoom level of the original edge image
-	origEdgeImage_->Zoom(1);
-	
-	//reset max/min zoom flags
-	maxZoom_	= 0;
-	minZoom_	= 1;
-	
-	//update interface...
-	
-	/***********************************************/
-	
-	//enable run
-	RunEnable();
-	
-	//update the tool bar
-	UpdateToolBar();
-	
-	//set window title
-	wxString statusname;
-	statusname.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
-	SetTitle(statusname);
-	
-	/***********************************************/
-}
-
-void BgMdiEdgeChild::OnLoadImage(wxCommandEvent& WXUNUSED(event))
-{
-   // get the file name
-//   wxFileDialog filedialog(this,"Choose an image file","","",
-//      "All files (*.*)|*.*|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm",
-//      wxOPEN);
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-  wxFileDialog filedialog(this,"Choose an image file","","",
-			  "*",wxOPEN);
-#else
-   wxFileDialog filedialog(this,"Choose an image file","","",
-      "Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
-      wxOPEN);
-#endif
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-      plotTotImage_->ClearData(1);
-      plotNmxImage_->ClearData(1);
-
-      if (hasEdge_ == 1)
-        origEdgeImage_->RemovePointSet(&cbgPointSet_);
-
-      if (origEdgeImage_->SetImage(filedialog.GetPath().c_str()) == 0)
-         return;
-      bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
-
-	  //obtain and store image filename
-	  if(filename_)	delete [] filename_;
-	  filename_	= new char [strlen(filedialog.GetFilename().c_str()) + 1];
-	  strcpy(filename_, filedialog.GetFilename().c_str());
-
-      miViewOrig_->Check(TRUE);
-      viewOrigCheck_->SetValue(TRUE);
-      origEdgeImage_->showbitmap_ = true;
-
-      // set cbgImage
-      cbgImage_->SetImageFromRGB(origEdgeImage_->pimage->GetData(), origEdgeImage_->pimage->GetWidth(), origEdgeImage_->pimage->GetHeight());
-      if (cbgEdgeDetect_ != 0)
-         delete cbgEdgeDetect_;
-      cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
-      hasImage_ = 1;
-      hasEdge_ = 0;
-
-	  //get image dimension
-	  width_			= origEdgeImage_->pimage->GetWidth();
-	  height_			= origEdgeImage_->pimage->GetHeight();
-
-	  //reset the zoom level of the original edge image
-	  origEdgeImage_->Zoom(1);
-
-	  //reset max/min zoom flags
-	  maxZoom_	= 0;
-	  minZoom_	= 1;
-
-	  //update interface...
-
-	  /***********************************************/
-	  //enable run
-	  RunEnable();
-
-	  //update the tool bar
-	  UpdateToolBar();
-
-	  //set window title
-      wxString statusname;
-      statusname.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
-      SetTitle(statusname);
-
-	  /***********************************************/
-   }
-}
-
-void BgMdiEdgeChild::OnSaveEdgeMap(wxCommandEvent& WXUNUSED(event))
-{
-   if (hasEdge_ == 0)
-   {
-      bgLog("No edge map, run edge detection first!\n");
-      return;
-   }
-   // get the file name
-   wxFileDialog filedialog(this,"Choose an image file","","",
-      "PGM files (*.pgm)|*.pgm",
-      wxSAVE);
-
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-      BgImage tempImage(cbgImage_->x_, cbgImage_->y_);
-      cbgEdgeList_->SetBinImage(&tempImage);
-      write_pgm_image(filedialog.GetPath().c_str(), tempImage.im_, tempImage.y_, tempImage.x_, "", 255);
-      bgLog("Edge map saved in: %s\n",filedialog.GetPath().c_str());
-
-      char tch[100];
-      sprintf(tch,"%s.txt",filedialog.GetPath().c_str());
-      cbgEdgeList_->SaveEdgeList(tch);
-   }
-}
-
-void BgMdiEdgeChild::OnEdgeDetect(wxCommandEvent& WXUNUSED(event))
-{
-   // determine if we have image
-   if (cbgImage_->hasIm_ == false)
-   {
-      //no image loaded
-      bgLog("No image loaded!\n");
-      return;
-   }
-   if (hasEdge_ == 1)
-      origEdgeImage_->RemovePointSet(&cbgPointSet_);
-   
-   if (cbgEdgeList_ != 0)
-      delete cbgEdgeList_;
-   cbgEdgeList_ = new BgEdgeList();
-
-   // test if modif params
-   double tx[MAX_CUSTOM_NODES];
-   double ty[MAX_CUSTOM_NODES];
-   int ttype,i;
-   int npoints;
-
-   if (plotTotImage_->mouseModif_ == 1)
-   {
-      // get new nmx params
-      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         nmxType_ = ttype;
-         rankNmx_ = tx[0];
-         confNmx_ = ty[0];
-      }
-      plotTotImage_->mouseModif_ = 0;
-   }
-   if (plotNmxImage_->mouseModif_ == 1)
-   {
-      // get new hyst params
-      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystHighType_ = ttype;
-         rankH_ = tx[0];
-         confH_ = ty[0];
-      } else
-      {
-         hystHighType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custHx_[i] = tx[i];
-            custHy_[i] = ty[i];
-         }
-         nCustH_ = npoints;
-      }
-      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystLowType_ = ttype;
-         rankL_ = tx[0];
-         confL_ = ty[0];
-      } else
-      {
-         hystLowType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custLx_[i] = tx[i];
-            custLy_[i] = ty[i];
-         }
-         nCustL_ = npoints;
-      }
-      plotNmxImage_->mouseModif_ = 0;
-   }
-
-   if (hystHighType_ == FC_CUSTOM)
-      cbgEdgeDetect_->SetCustomHigh(custHx_, custHy_, nCustH_);
-   if (hystLowType_ == FC_CUSTOM)
-      cbgEdgeDetect_->SetCustomLow(custLx_, custLy_, nCustL_);
-
-   // determine if we have permanent data
-   if (cbgEdgeDetect_->havePerm_ == true) {
-      // compute only nmx and hyst
-      cbgEdgeDetect_->DoRecompute(cbgEdgeList_, rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_,
-         nMin_, nmxType_, hystHighType_, hystLowType_);
-      // set only nmx image
-      SetNmxImage();
-   }
-   else
-   {
-      // compute all steps
-      cbgEdgeDetect_->DoEdgeDetect(cbgImage_, cbgEdgeList_, rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_,
-         nMin_, nmxType_, hystHighType_, hystLowType_);
-      // set total and nmx image
-      SetTotalImage();
-      SetNmxImage();
-   }
-
-   // get binary edge image
-   BgImage tempImage(cbgImage_->x_, cbgImage_->y_);
-   cbgEdgeList_->SetBinImage(&tempImage);
-
-   int* edgex;
-   int* edgey;
-   int nEdgep;
-   edgex = new int[(cbgImage_->x_) * (cbgImage_->y_)];
-   edgey = new int[(cbgImage_->x_) * (cbgImage_->y_)];
-   cbgPointSet_.type_ = 1;
-
-   cbgEdgeList_->GetAllEdgePoints(edgex, edgey, &nEdgep);
-   cbgPointSet_.SetPoints(edgex, edgey, nEdgep);
-   hasEdge_ = 1;
-   delete [] edgey;
-   delete [] edgex;
-
-   // update image canvas
-   if (miViewEdge_->IsChecked())
-      origEdgeImage_->AddPointSet(&cbgPointSet_);
-
-   //active save tool
-   SaveEnable();
-
-   //update menu bar
-   wxMenuBar *menubar = GetMenuBar();
-   menubar->Enable(BG_EDGE_SAVE_MAP, true);
-
-}
-
-void BgMdiEdgeChild::SetTotalImage(void)
-{
-   unsigned char* buf;
-   int xsz = RANK_CONF_IMSIZEX;
-   int ysz = RANK_CONF_IMSIZEY;
-   int imsz = xsz*ysz;
-   buf = new unsigned char[imsz];
-   int i;
-   for (i=0; i<imsz; i++)
-      buf[i] = 255;
-
-   int l, c;
-   int xo = cbgEdgeDetect_->x_;
-   int yo = cbgEdgeDetect_->y_;
-   float* rank;
-   float* conf;
-   rank = cbgEdgeDetect_->permRank_;
-   conf = cbgEdgeDetect_->permConf_;
-   for (i=0; i<xo*yo; i++)
-   {
-      if (rank[i]>0 && conf[i]>0)
-      {
-         c = (int) (rank[i]*((double) xsz));
-         c = (c>=xsz) ? xsz-1 : c;
-         l = (int) (conf[i]*((double) ysz));
-         l = (l>=ysz) ? ysz-1 : l;
-         l = ysz-1-l;
-         buf[c+l*xsz]=80;
-      }
-   }
-
-   nmxCurve_.SetParamCurve(nmxType_, &rankNmx_, &confNmx_, 1, xsz, ysz);
-   plotTotImage_->SetImageFromGray(buf, xsz, ysz);
-   plotTotImage_->FillCurveClick();
-
-   delete [] buf;
-
-}
-
-void BgMdiEdgeChild::SetNmxImage(void)
-{
-   unsigned char* buf;
-   int xsz = RANK_CONF_IMSIZEX;
-   int ysz = RANK_CONF_IMSIZEY;
-   int imsz = xsz*ysz;
-   buf = new unsigned char[imsz];
-   int i;
-   for (i=0; i<imsz; i++)
-      buf[i] = 255;
-
-   int l, c;
-   int xo = cbgEdgeDetect_->x_;
-   int yo = cbgEdgeDetect_->y_;
-   float* rank;
-   float* conf;
-   rank = cbgEdgeDetect_->permNmxRank_;
-   conf = cbgEdgeDetect_->permNmxConf_;
-   for (i=0; i<xo*yo; i++)
-   {
-      if (rank[i]>0 && conf[i]>0)
-      {
-         c = (int) (rank[i]*((double) xsz));
-         c = (c>=xsz) ? xsz-1 : c;
-         l = (int) (conf[i]*((double) ysz));
-         l = (l>=ysz) ? ysz-1 : l;
-         l = ysz-1-l;
-         buf[c+l*xsz]=80;
-      }
-   }
-   
-   if (hystHighType_ != FC_CUSTOM)
-      highCurve_.SetParamCurve(hystHighType_, &rankH_, &confH_, 1, xsz, ysz);
-   else 
-   {
-      highCurve_.SetParamCurve(hystHighType_, custHx_, custHy_, nCustH_, xsz, ysz);
-   }
-   if (hystLowType_ != FC_CUSTOM)
-      lowCurve_.SetParamCurve(hystLowType_, &rankL_, &confL_, 1, xsz, ysz);
-   else 
-   {
-      lowCurve_.SetParamCurve(hystLowType_, custLx_, custLy_, nCustL_, xsz, ysz);
-   }
-   plotNmxImage_->SetImageFromGray(buf, xsz, ysz);
-   plotNmxImage_->FillCurveClick();
-
-   delete [] buf;
-
-}
-
-void BgMdiEdgeChild::OnChangeParam(wxCommandEvent& WXUNUSED(event))
-{
-   // show the parameters window and change it
-   double tx[20];
-   double ty[20];
-   int ttype,i;
-   int npoints;
-   if (plotTotImage_->mouseModif_ == 1)
-   {
-      // get new nmx params
-      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         nmxType_ = ttype;
-         rankNmx_ = tx[0];
-         confNmx_ = ty[0];
-      }
-      plotTotImage_->mouseModif_ = 0;
-   }
-   if (plotNmxImage_->mouseModif_ == 1)
-   {
-      // get new hyst params
-      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystHighType_ = ttype;
-         rankH_ = tx[0];
-         confH_ = ty[0];
-      } else
-      {
-         hystHighType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custHx_[i] = tx[i];
-            custHy_[i] = ty[i];
-         }
-         rankH_ = tx[npoints-1];
-         confH_ = ty[0];
-         nCustH_ = npoints;
-      }
-      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
-      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
-      {
-         hystLowType_ = ttype;
-         rankL_ = tx[0];
-         confL_ = ty[0];
-      } else
-      {
-         hystLowType_ = ttype;
-         for (i=0; i<npoints; i++)
-         {
-            custLx_[i] = tx[i];
-            custLy_[i] = ty[i];
-         }
-         rankL_ = tx[npoints-1];
-         confL_ = ty[0];
-         nCustL_ = npoints;
-      }
-      plotNmxImage_->mouseModif_ = 0;
-   }
-   BgParamDialog paramDialog(this, -1, "Change Parameters", wxDefaultPosition, wxSize(250,510),
-      wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL);
-   paramDialog.SetValues(rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_, nMin_,
-      nmxType_, hystHighType_, hystLowType_, kernelSize_);
-   if (paramDialog.ShowModal()==wxID_OK)
-   {
-      // do change param stuff
-      int tempKernelSize;
-      tempKernelSize = kernelSize_;
-      paramDialog.GetValues(rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_, nMin_,
-         nmxType_, hystHighType_, hystLowType_, tempKernelSize);
-      if (tempKernelSize != kernelSize_)
-      {
-         kernelSize_ = tempKernelSize;
-         if (cbgEdgeDetect_ != 0) {
-            delete cbgEdgeDetect_;
-            cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
-         }
-      }
-
-      // change image param
-      int xsz = RANK_CONF_IMSIZEX;
-      int ysz = RANK_CONF_IMSIZEY;
-      
-      if (hystHighType_ != FC_CUSTOM)
-         highCurve_.SetParamCurve(hystHighType_, &rankH_, &confH_, 1, xsz, ysz);
-      else 
-      {
-         highCurve_.SetParamCurve(hystHighType_, custHx_, custHy_, nCustH_, xsz, ysz);
-      }
-      if (hystLowType_ != FC_CUSTOM)
-         lowCurve_.SetParamCurve(hystLowType_, &rankL_, &confL_, 1, xsz, ysz);
-      else 
-      {
-         lowCurve_.SetParamCurve(hystLowType_, custLx_, custLy_, nCustL_, xsz, ysz);
-      }
-
-      nmxCurve_.SetParamCurve(nmxType_, &rankNmx_, &confNmx_, 1, xsz, ysz);
-
-      plotNmxImage_->FillCurveClick();
-      plotTotImage_->FillCurveClick();
-
-      SetParametersStr();
-      SetParametersNum();
-   }
-}
-
-
-// ---------------------------------------------------------------------------
-// BgParamDialog
-// ---------------------------------------------------------------------------
-
-BgParamDialog::BgParamDialog(wxWindow* parent, wxWindowID id, const wxString& title,
-      const wxPoint& pos, const wxSize& size,
-      long style, const wxString& name)
-: wxDialog(parent, id, title, pos, size, style, name)
-{
-   okButton_ = new wxButton(this, BG_PARAMD_OK, "Ok", wxPoint(20+C_PARAMX+10,450));
-   cancelButton_ = new wxButton(this, BG_PARAMD_CANCEL, "Cancel", wxPoint(20+C_PARAMX+10+C_PARAMDX+60,450));
-   
-   /*
-   txtNmxR_ = new wxStaticText(this, -1, "Nmx. rank: ", wxPoint(C_PARAMX,C_PARAMY+0*C_PARAMDY));
-   txtNmxC_ = new wxStaticText(this, -1, "Nmx. conf: ", wxPoint(C_PARAMX,C_PARAMY+1*C_PARAMDY));
-   txtHHR_ = new wxStaticText(this, -1, "Hyst. high rank: ", wxPoint(C_PARAMX,C_PARAMY+2*C_PARAMDY));
-   txtHHC_ = new wxStaticText(this, -1, "Hyst. high conf: ", wxPoint(C_PARAMX,C_PARAMY+3*C_PARAMDY));
-   txtHLR_ = new wxStaticText(this, -1, "Hyst. low rank: ", wxPoint(C_PARAMX,C_PARAMY+4*C_PARAMDY));
-   txtHLC_ = new wxStaticText(this, -1, "Hyst. low conf: ", wxPoint(C_PARAMX,C_PARAMY+5*C_PARAMDY));
-   txtMinPt_ = new wxStaticText(this, -1, "Min. points: ", wxPoint(C_PARAMX,C_PARAMY+6*C_PARAMDY));
-   txtNmxType_ = new wxStaticText(this, -1, "Nmx. type: ", wxPoint(C_PARAMX,C_PARAMY+7*C_PARAMDY));
-   txtHHType_ = new wxStaticText(this, -1, "Hyst. high type: ", wxPoint(C_PARAMX,C_PARAMY+8*C_PARAMDY));
-   txtHLType_ = new wxStaticText(this, -1, "Hyst. low: ", wxPoint(C_PARAMX,C_PARAMY+9*C_PARAMDY));
-   txtKernelSize_ = new wxStaticText(this, -1, "Kernel radius: ", wxPoint(C_PARAMX,C_PARAMY+10*C_PARAMDY));
-
-   valNmxR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+0*C_PARAMDY));
-   valNmxC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+1*C_PARAMDY));
-   valHHR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+2*C_PARAMDY));
-   valHHC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+3*C_PARAMDY));
-   valHLR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+4*C_PARAMDY));
-   valHLC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+5*C_PARAMDY));
-   valMinPt_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+6*C_PARAMDY));
-   valNmxType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+7*C_PARAMDY), wxDefaultSize);
-   valHHType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+8*C_PARAMDY), wxDefaultSize);
-   valHLType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+9*C_PARAMDY), wxDefaultSize);
-   valKernelSize_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+10*C_PARAMDY));
-   */
-
-   txtKernelSize_ = new wxStaticText(this, -1, "Grad Win.", wxPoint(20+C_PARAMX-5,0+C_PARAMY+0*C_PARAMDY));
-   valKernelSize_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX+35,0+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
-
-   txtMinPt_ = new wxStaticText(this, -1, "Min. length", wxPoint(20+C_PARAMX-5,0+C_PARAMY+1*C_PARAMDY));
-   valMinPt_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX+35,0+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
-
-   wxStaticBox* nmxSB = new wxStaticBox(this, -1, "Nonmaxima supp.", wxPoint(20+5, 80+0), wxSize(140,4*C_PARAMDY-5));
-   txtNmxType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX, 80+C_PARAMY+0*C_PARAMDY));
-   valNmxType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   txtNmxR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,80+C_PARAMY+1*C_PARAMDY));
-   valNmxR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   txtNmxC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,80+C_PARAMY+2*C_PARAMDY));
-   valNmxC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-
-   wxStaticBox* hhSB = new wxStaticBox(this, -1, "Hyst. High Tr.", wxPoint(20+5, 200+0), wxSize(140,4*C_PARAMDY-5));
-   txtHHType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX,200+C_PARAMY+0*C_PARAMDY));
-   txtHHR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,200+C_PARAMY+1*C_PARAMDY));
-   txtHHC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,200+C_PARAMY+2*C_PARAMDY));
-   valHHType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHHR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHHC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-
-   wxStaticBox* hlSB = new wxStaticBox(this, -1, "Hyst. Low Tr.", wxPoint(20+5, 320+0), wxSize(140, 4*C_PARAMDY-5));
-   txtHLType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX,320+C_PARAMY+0*C_PARAMDY));
-   txtHLR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,320+C_PARAMY+1*C_PARAMDY));
-   txtHLC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,320+C_PARAMY+2*C_PARAMDY));
-   valHLType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHLR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-   valHLC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
-
-
-
-   // put choices
-   valNmxType_->Append("Arc");
-   valNmxType_->Append("Vertical Line");
-   valNmxType_->Append("Horizontal Line");
-   valNmxType_->Append("Line");
-   valNmxType_->Append("Box");
-
-   valHHType_->Append("Arc");
-   valHHType_->Append("Vertical Line");
-   valHHType_->Append("Horizontal Line");
-   valHHType_->Append("Line");
-   valHHType_->Append("Box");
-   valHHType_->Append("Custom");
-
-   valHLType_->Append("Arc");
-   valHLType_->Append("Vertical Line");
-   valHLType_->Append("Horizontal Line");
-   valHLType_->Append("Line");
-   valHLType_->Append("Box");
-   valHLType_->Append("Custom");
-
-}
-
-BgParamDialog::~BgParamDialog()
-{
-   delete txtNmxR_;
-   delete txtNmxC_;
-   delete txtHHR_;
-   delete txtHHC_;
-   delete txtHLR_;
-   delete txtHLC_;
-   delete txtMinPt_;
-   delete txtNmxType_;
-   delete txtHHType_;
-   delete txtHLType_;
-   delete txtKernelSize_;
-
-   delete valNmxR_;
-   delete valNmxC_;
-   delete valHHR_;
-   delete valHHC_;
-   delete valHLR_;
-   delete valHLC_;
-   delete valMinPt_;
-   delete valNmxType_;
-   delete valHHType_;
-   delete valHLType_;
-   delete valKernelSize_;
-
-   delete okButton_;
-   delete cancelButton_;
-}
-
-void BgParamDialog::OnOk(wxCommandEvent& WXUNUSED(event))
-{
-   EndModal(wxID_OK);
-}
-
-void BgParamDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
-{
-   EndModal(wxID_CANCEL);
-}
-
-void BgParamDialog::SetValues(double nmxR, double nmxC, double hhR, double hhC, double hlR, double hlC,
-                              int nMin, int nmxT, int hhT, int hlT, int ks)
-{
-   wxString ts;
-   ts = wxString::Format("%.3g", nmxR);
-   valNmxR_->SetValue(ts);
-   ts = wxString::Format("%.3g", nmxC);
-   valNmxC_->SetValue(ts);
-   ts = wxString::Format("%.3g", hhR);
-   valHHR_->SetValue(ts);
-   ts = wxString::Format("%.3g", hhC);
-   valHHC_->SetValue(ts);
-   ts = wxString::Format("%.3g", hlR);
-   valHLR_->SetValue(ts);
-   ts = wxString::Format("%.3g", hlC);
-   valHLC_->SetValue(ts);
-   ts = wxString::Format("%d", nMin);
-   valMinPt_->SetValue(ts);
-   valNmxType_->SetSelection(nmxT);
-   valHHType_->SetSelection(hhT);
-   valHLType_->SetSelection(hlT);
-   ts = wxString::Format("%d", ks);
-   valKernelSize_->SetValue(ts);
-
-}
-
-void BgParamDialog::GetValues(double& nmxR, double& nmxC, double& hhR, double& hhC, double& hlR, double& hlC,
-                              int& nMin, int& nmxT, int& hhT, int& hlT, int& ks)
-{
-   double td;
-   long tl;
-   int ti;
-
-   td = -1;
-   tl = -1;
-   ti = -1;
-   if ((valNmxR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      nmxR = td;
-   else
-      bgLog("nmx. rank value out of range.\n");
-   
-   if ((valNmxC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      nmxC = td;
-   else
-      bgLog("nmx. conf. value out of range.\n");
-
-   if ((valHHR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      hhR = td;
-   else
-      bgLog("hyst. high rank value out of range.\n");
-
-   if ((valHHC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      hhC = td;
-   else
-      bgLog("hyst. high conf. value out of range.\n");
-
-   if ((valHLR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      hlR = td;
-   else
-      bgLog("hyst. low rank value out of range.\n");
-
-   if ((valHLC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
-      hlC = td;
-   else
-      bgLog("hyst. low conf. value out of range.\n");
-
-   if ((valMinPt_->GetValue().ToLong(&tl) == TRUE) && (tl>=0))
-      nMin = (int) tl;
-   else
-      bgLog("min. edge points value out of range.\n");
-
-   if ((ti=valNmxType_->GetSelection()) != -1)
-      nmxT = ti;
-
-   if ((ti=valHHType_->GetSelection()) != -1)
-      hhT = ti;
-
-   if ((ti=valHLType_->GetSelection()) != -1)
-      hlT = ti;
-
-   if ((valKernelSize_->GetValue().ToLong(&tl) == TRUE) && (tl>0) && ((2*tl+1)<=MAX_FILTS))
-      ks = (int) tl;
-   else
-      bgLog("kernel radius value out of range.\n");
-
-
-}
-
-// ---------------------------------------------------------------------------
-// BgSpeedSelect
-// ---------------------------------------------------------------------------
-
-BgSpeedSelect::BgSpeedSelect(wxWindow* parent, wxWindowID id, const wxString& title,
-      const wxPoint& pos, const wxSize& size,
-      long style, const wxString& name)
-: wxDialog(parent, id, title, pos, size, style, name)
-{
-   okButton_ = new wxButton(this, BG_SPEEDSEL_OK, "Ok", wxPoint(30,80));
-   cancelButton_ = new wxButton(this, BG_SPEEDSEL_CANCEL, "Cancel", wxPoint(120,80));
-   
-   txtQuality_ = new wxStaticText(this, -1, "Speed", wxPoint(160, 10));
-   txtSpeed_ = new wxStaticText(this, -1, "Quality", wxPoint(40, 10));
-
-   sldSpeed_ = new wxSlider(this, BG_SPEEDSEL_SLD, 0, 0, 100, wxPoint(18,40), wxSize(155,-1),
-                             wxSL_AUTOTICKS | wxSL_LABELS);
-   sldSpeed_->SetTickFreq(20, 0);
-}
-
-BgSpeedSelect::~BgSpeedSelect()
-{
-   delete sldSpeed_;
-
-   delete okButton_;
-   delete cancelButton_;
-}
-
-void BgSpeedSelect::OnOk(wxCommandEvent& WXUNUSED(event))
-{
-   EndModal(wxID_OK);
-}
-
-void BgSpeedSelect::OnCancel(wxCommandEvent& WXUNUSED(event))
-{
-   EndModal(wxID_CANCEL);
-}
-
-void BgSpeedSelect::SetSliderValue(float sliderV)
-{
-   sldSpeed_->SetValue((int) (sliderV*100));
-}
-
-void BgSpeedSelect::GetSliderValue(float& sliderV)
-{
-   sliderV = (float) (sldSpeed_->GetValue() / 100.0);
-}
-
-// ---------------------------------------------------------------------------
-// BgMdiSegmentChild
-// ---------------------------------------------------------------------------
-
-BgMdiSegmentChild::BgMdiSegmentChild(wxMDIParentFrame *parent, const wxString& title,
-                           const wxPoint& pos, const wxSize& size,
-                           const long style)
-                           : wxMDIChildFrame(parent, BG_SEGM_WINDOW, title, pos, size, style)
-{
-
-   //set window number
-   window_number_ = gs_nFrames;
-
-   //assume image is not yet loaded into segmentation window
-   filename_	= NULL;
-
-   //split window to display the segmented image on the left hand side,
-   //and the ph diagram on the right hand side
-   imagePlotSplitter_	= new wxSplitterWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   plotMapSplitter_		= new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-   mapSplitter_			= new wxSplitterWindow(plotMapSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
-
-   //create option panels
-   winPanel1_ = new BgMenuPanel(mapSplitter_, -1, BG_CANVAS_VIEW1_GRADMAP, BG_CANVAS_VIEW1_CONFMAP, BG_CANVAS_VIEW1_WEITMAP, BG_CANVAS_VIEW1_CUSTMAP,
-								                  BG_CANVAS_SAVE_GRADMAP, BG_CANVAS_SAVE_CONFMAP, BG_CANVAS_SAVE_WEITMAP);
-   winPanel2_ = new BgMenuPanel(mapSplitter_, -1, BG_CANVAS_VIEW2_GRADMAP, BG_CANVAS_VIEW2_CONFMAP, BG_CANVAS_VIEW2_WEITMAP, BG_CANVAS_VIEW2_CUSTMAP,
-								                  BG_CANVAS_SAVE_GRADMAP, BG_CANVAS_SAVE_CONFMAP, BG_CANVAS_SAVE_WEITMAP);
-   winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
-   winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
-   winPanel1_->CheckViewItem(BG_CANVAS_VIEW1_CONFMAP);
-   winPanel2_->CheckViewItem(BG_CANVAS_VIEW2_GRADMAP);
-   winPanel1_->EnableMenu(false);
-   winPanel2_->EnableMenu(false);
-
-   //define ph diagram and segmented display image
-   phDiagram_ = new BgImCanvas(this, plotMapSplitter_, wxDefaultPosition, wxDefaultSize);
-   phDiagram_->SetScrollbars(20, 20, 50, 50);
-   plotWindow1_ = new BgImCanvas(this, winPanel1_, wxPoint(0,PLOT_MENU_HEIGHT), wxDefaultSize);
-   plotWindow1_->SetScrollbars(20, 20, 50, 50);
-   plotWindow2_ = new BgImCanvas(this, winPanel2_, wxPoint(0,PLOT_MENU_HEIGHT), wxDefaultSize);
-   plotWindow2_->SetScrollbars(20, 20, 50, 50);
-   displayImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
-   displayImage_->SetScrollbars(20, 20, 50, 50);
-
-   //set the scroll window of each panel
-   winPanel1_->SetScrollWindow((wxWindow *) plotWindow1_);
-   winPanel2_->SetScrollWindow((wxWindow *) plotWindow2_);
-
-   //set lower bound zoom limit on display image
-   //to the size of the original image
-   displayImage_->SetMinZoomLevel(1);
-
-   //place each image object into their corresponding positions in the split
-   //window
-   imagePlotSplitter_->SplitVertically(displayImage_, plotMapSplitter_,256);
-   plotMapSplitter_->SplitHorizontally(phDiagram_, mapSplitter_, 256);
-   mapSplitter_->SplitVertically(winPanel1_, winPanel2_, 256);
-
-   //inititalize segmentation parameters
-   sigmaS		= 7;
-   sigmaR		= float(6.5);
-   aij			= float(0.3);
-   epsilon		= float(0.3);
-   minRegion	= 20;
-   kernelSize	= 2;
-	
-   //set text size
-   wxSize txtSize(50, 20);
-
-   //allocate memory for display images
-   cbgImage_			= new BgImage();
-   filtImage_			= new BgImage();
-   segmImage_			= new BgImage();
-   whiteImage_			= new BgImage();
-
-   //allocate memory to store boundary pixel locations
-   boundaries_			= new BgPointSet();
-
-   hasImage_		= 0;
-   hasFilter_		= 0;
-   hasSegment_		= 0;
-   hasBoundaries_	= 0;
-
-   //shut off text box monitoring
-   checkTextBoxes_	= false;
-
-   optionsPanel_	= new wxPanel(this, -1, wxPoint(0, 0), wxSize(BG_SEGM_OP_SIZEX, BG_SEGM_OP_SIZEY));
-
-   wxBoxSizer	*toplayout = new wxBoxSizer(wxVERTICAL);
-
-   loadButton_ = new wxButton(optionsPanel_, BG_SEGM_LOAD_IMAGE, "Load Image");
-   toplayout->Add(loadButton_, 0, wxCENTER | wxBOTTOM | wxTOP, 5);
-   
-   wxString operations[] = {"Segment", "Filter Only", "Fusion Only"};
-   operationRadio_ = new wxRadioBox(optionsPanel_, BG_SEGM_OPERATION, "Operation", wxDefaultPosition, wxSize(BG_SP_WIDTH, -1), 3, operations, 3 ,wxRA_SPECIFY_ROWS);
-   toplayout->Add(operationRadio_, 0, wxCENTER | wxBOTTOM, 5);
-
-   runButton_ = new wxButton(optionsPanel_, BG_SEGM_SEGMENT, "Run");
-   toplayout->Add(runButton_, 0, wxCENTER | wxBOTTOM, 5);
-
-   wxString choices[] = {"Original", "Filtered", "Segmented", "No Image"};
-   viewImSegRadio_ = new wxRadioBox(optionsPanel_, BG_SEGM_VIEW_IMSEG, "View Image", wxDefaultPosition, wxSize(BG_SP_WIDTH, -1), 4, choices, 4, wxRA_SPECIFY_ROWS);
-   toplayout->Add(viewImSegRadio_, 0, wxCENTER | wxBOTTOM, 5);
-
-   viewBoundariesCheck_ = new wxCheckBox(optionsPanel_, BG_SEGM_VIEW_EDGES, "Overlay Boundaries");
-   toplayout->Add(viewBoundariesCheck_, 0, wxALIGN_LEFT | wxLEFT | wxBOTTOM, 10);
-
-   //add bandwidth parameters...
-   subPanel1_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, BG_SP_HEIGHT));
-   subPanelBox1_	= new wxStaticBox(subPanel1_, -1, "Bandwidth", wxPoint(0, 0), wxSize(BG_SP_WIDTH, BG_SP_TOP_HEIGHT), wxSIMPLE_BORDER, "staticBox");
-   subPanelBox2_	= new wxStaticBox(subPanel1_, -1, "", wxPoint(0, BG_SP_TOP_HEIGHT-8), wxSize(BG_SP_WIDTH, BG_SP_HEIGHT-BG_SP_TOP_HEIGHT), wxSIMPLE_BORDER, "staticBox");
-   textSigmaS_		= new wxStaticText(subPanel1_, -1, "Spatial [2h+1]", wxPoint(BG_LEFT_CELL, 18));
-   txtSigmaS_		= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_SIGMAS, "7", wxPoint(BG_RIGHT_CELL, 15), txtSize);
-   textSigmaR_		= new wxStaticText(subPanel1_, -1, "Color [2h]", wxPoint(BG_LEFT_CELL, 43));
-   txtSigmaR_		= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_SIGMAR, "6.5", wxPoint(BG_RIGHT_CELL, 40), txtSize);
-   textMinRegion_	= new wxStaticText(subPanel1_, -1, "Minimum Region", wxPoint(BG_LEFT_CELL, 78));
-   txtMinRegion_	= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_MINREG, "20", wxPoint(BG_RIGHT_CELL, 75), txtSize);
-   toplayout->Add(subPanel1_, 0, wxCENTER | wxBOTTOM | wxTOP, 5);
-
-   useWeightMap_ = new wxCheckBox(optionsPanel_, BG_SEGM_USE_EDGE_MAP, "Use Weight Map");
-   toplayout->Add(useWeightMap_, 0, wxALIGN_LEFT | wxLEFT | wxBOTTOM, 10);
-
-   //add weight map parameters...
-   subPanel2_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, BG_SP_HEIGHT_2));
-   subPanelBox3_	= new wxStaticBox(subPanel2_, -1, "", wxPoint(0, 0), wxSize(BG_SP_WIDTH, BG_SP_HEIGHT_2), wxSIMPLE_BORDER, "staticBox");
-   textKernelSize_	= new wxStaticText(subPanel2_, -1, "Grad. Window (2n+1)", wxPoint(BG_LEFT_CELL, 18));
-   txtKernelSize_	= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_GRADWIN, "2", wxPoint(BG_RIGHT_CELL, 15), txtSize);
-   textA_			= new wxStaticText(subPanel2_, -1, "Mixture Parameter", wxPoint(BG_LEFT_CELL, 43));
-   txtA_			= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_AIJ, "0.3", wxPoint(BG_RIGHT_CELL, 40), txtSize);
-   textEpsilon_		= new wxStaticText(subPanel2_, -1, "Threshold", wxPoint(BG_LEFT_CELL, 68));
-   txtEpsilon_		= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_EPSILON, "0.3", wxPoint(BG_RIGHT_CELL, 65), txtSize);
-   toplayout->Add(subPanel2_, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP, 5);
-
-   //add parameter history control
-   subPanel3_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, 43));
-   subPanelBox4_	= new wxStaticBox(subPanel3_, -1, "", wxPoint(0, 0), wxSize(BG_SP_WIDTH, 43), wxSIMPLE_BORDER, "staticBox");
-   textParamBox_	= new wxStaticText(subPanel3_, -1, "History", wxPoint(BG_LEFT_CELL, 18));
-   paramComboBox_	= new BgParameterHistoryBox(subPanel3_, BG_SEGM_CHANGE_PARAMS, "", wxPoint(BG_RIGHT_CELL-50, 15), wxSize(100,20), 5, 0, wxDefaultValidator, "comboBox");
-   toplayout->Add(subPanel3_, 0, wxALIGN_CENTER | wxCENTER | wxBOTTOM, 10);
-    
-   optionsPanel_->SetAutoLayout(TRUE);
-   toplayout->Fit(optionsPanel_);
-   optionsPanel_->SetSizer(toplayout);
-
-   g_children.Append(this);
-
-   //set the size and sash position of the splitters
-   int w, h;
-   GetClientSize(&w, &h);
-   imagePlotSplitter_->SetSize(BG_SEGM_OP_SIZEX, 0, w-BG_SEGM_OP_SIZEX, h);
-   imagePlotSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/2, TRUE);
-   plotMapSplitter_->SetSashPosition(h/2, TRUE);
-   mapSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/4, TRUE);
-
-   //initalize edge maps...
-   customMap_	= (float *) NULL;
-   confMap_		= (float *) NULL;
-   gradMap_		= (float *) NULL;
-   weightMap_	= (float *) NULL;
-
-   //indicate that the edge parameters have not changed
-   edgeParamsHaveChanged_	= false;
-
-   //add margin to plots
-   phDiagram_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-   plotWindow1_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-   plotWindow2_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
-
-   //add title to each individual plot
-   BgText bgText(1,"      Diagram of Region Boundary Data Points", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
-   phDiagram_->AddText(&bgText);
-   bgText.SetText("Confidence Map");
-   plotWindow1_->AddText(&bgText);
-   bgText.SetText("Gradient Map");
-   plotWindow2_->AddText(&bgText);
-
-   //add x and y axis
-   phDiagram_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
-   phDiagram_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
-
-   //label x and y axis
-   bgText.SetText("Rank (   )");
-   phDiagram_->LabelHorizontalAxis(&bgText);
-   bgText.SetText("Confidence (  )");
-   phDiagram_->LabelVerticalAxis(&bgText);
-
-   //place greek symbols
-   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
-   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
-   phDiagram_->AddBitmap(&ro_bmp);
-   phDiagram_->AddBitmap(&eta_bmp);
-   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
-   ro_bmp.SetId(3);
-   phDiagram_->AddBitmap(&ro_bmp);
-   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
-   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
-   phDiagram_->AddBitmap(&rotated_eta_bmp);
-
-   //declare that segmentation window is open
-   window_open	= true;
-
-   //get parent tool bar and update it
-   toolbar	= parent->GetToolBar();
-   UpdateToolBar();
-
-   //disable confidence map text boxes
-   txtA_->Enable(false);
-   txtEpsilon_->Enable(false);
-   txtKernelSize_->Enable(false);
-   textA_->Enable(false);
-   textEpsilon_->Enable(false);
-   textKernelSize_->Enable(false);
-
-   //disable run button
-   runButton_->Enable(false);
-
-   //disable radio boxes
-   viewImSegRadio_->Enable(false);
-   operationRadio_->Enable(false);
-
-   //disable view boundaries check box
-   viewBoundariesCheck_->Enable(false);
-
-   //intialize parameter combo box
-   float *myParameters = new float [6];
-   myParameters[0]	= sigmaS;
-   myParameters[1]	= sigmaR;
-   myParameters[2]	= aij;
-   myParameters[3]	= epsilon;
-   myParameters[4]	= minRegion;
-   myParameters[5]	= kernelSize;
-   paramComboBox_->SetCurrentList((void *) myParameters, 6);
-   isCurrentHistory_	= true;
-
-   //turn on text box monitoring
-   checkTextBoxes_	= true;
-
-   //initialize speedup level to medium
-   speedUpLevel_	= MED_SPEEDUP;
-   speedUpThreshold_ = (float) 0.1;
-
-   //initialize max/min zoom
-   maxZoom_	= 0;
-   minZoom_	= 1;
-
-}
-
-
-BgMdiSegmentChild::~BgMdiSegmentChild()
-{
-   if (hasBoundaries_ == 1)
-     displayImage_->RemovePointSet(boundaries_);
-
-	if(filename_)	delete [] filename_;
-
-   delete optionsPanel_;
-   delete displayImage_;
-   
-   delete boundaries_;
-   delete whiteImage_;
-   delete segmImage_;
-   delete filtImage_;
-   delete cbgImage_;
-
-   if (customMap_)	delete [] customMap_;
-   if (confMap_)	delete [] confMap_;
-   if (gradMap_)	delete [] gradMap_;
-   if (weightMap_)	delete [] weightMap_;
-
-   g_children.DeleteObject(this);
-}
-
-void BgMdiSegmentChild::OnViewImSeg(wxCommandEvent&  WXUNUSED(event))
-{
-	//if an image has not been loaded then exit this method...
-	if (hasImage_ == 0)
-		return;
-	
-	switch(viewImSegRadio_->GetSelection())
-	{
-		
-	//view original image
-	case 0:
-		boundaries_->pen_.SetColour(*wxWHITE);
-		displayImage_->SetImage(cbgImage_->im_, cbgImage_->x_, cbgImage_->y_, cbgImage_->colorIm_);
-		break;
-		
-	//view filtered image
-	case 1:
-		if (hasFilter_ == 0)
-		{
-			viewImSegRadio_->SetSelection(0);
-			bgLog("Filter the image first!\n");
-			return;
-		} else
-		{
-			boundaries_->pen_.SetColour(*wxWHITE);
-			displayImage_->SetImage(filtImage_->im_, filtImage_->x_, filtImage_->y_, filtImage_->colorIm_);
-		}
-		break;
-		
-	//view segmented image
-	case 2:
-		if (hasSegment_ == 0)
-		{
-			viewImSegRadio_->SetSelection(0);
-			bgLog("Segment the image first!\n");
-			return;
-		} else
-		{
-			boundaries_->pen_.SetColour(*wxWHITE);
-			displayImage_->SetImage(segmImage_->im_, segmImage_->x_, segmImage_->y_, segmImage_->colorIm_);
-		}
-		break;
-		
-	//view boundaries
-	default:
-		if (hasBoundaries_ == 0)
-		{
-			viewImSegRadio_->SetSelection(0);
-			bgLog("Process the image first!\n");
-			return;
-		} else
-		{
-			boundaries_->pen_.SetColour(*wxBLACK);
-			displayImage_->SetImage(whiteImage_->im_, whiteImage_->x_, whiteImage_->y_, whiteImage_->colorIm_);
-		}
-	}
-}
-
-//specifies image operation(i.e. segment, filter or fuse regions)
-void BgMdiSegmentChild::OnChangeOperation(wxCommandEvent& WXUNUSED(event))
-{
-
-	wxMenuBar	*menubar	= GetMenuBar();
-	switch(operationRadio_->GetSelection())
-	{
-	//segment the image
-	case 0:
-		menubar->SetLabel(BG_SEGM_SEGMENT, "Segment Image\tShift-R");
-		break;
-	//filter the image
-	case 1:
-		menubar->SetLabel(BG_SEGM_SEGMENT, "Filter Image\tShift-R");
-		break;
-	//fuse regions
-	default:
-		menubar->SetLabel(BG_SEGM_SEGMENT, "Fuse Regions\tShift-R");
-		break;
-	}
-
-	//done.
-	return;
-
-}
-
-//changes the paramters depending on the parameter list
-void BgMdiSegmentChild::OnChangeParameters(wxCommandEvent& WXUNUSED(event))
-{
-	float	*myParameters;
-
-	//get current selection index...
-	int	selIndex	= paramComboBox_->GetSelection();
-
-	//aquire current parameters and store them in "current parameter" slot...
-	if(isCurrentHistory_)
-	{
-		int		csigmaS, cminRegion, ckernelSize;
-		float	csigmaR, caij, cepsilon;
-		GetParameters(csigmaS, csigmaR, caij, cepsilon, cminRegion, ckernelSize, 0);
-		myParameters	= (float *) paramComboBox_->GetCurrentListData();
-		myParameters[0]	= csigmaS;
-		myParameters[1]	= csigmaR;
-		myParameters[2]	= caij;
-		myParameters[3]	= cepsilon;
-		myParameters[4]	= cminRegion;
-		myParameters[5]	= ckernelSize;
-	}
-
-	//check to see if the "current parameter" slot has been selected,
-	//if so set the current history flag and use the parameters from
-	//current history slot
-	if(selIndex == 0)
-	{
-		isCurrentHistory_		= true;
-		myParameters			= (float *) paramComboBox_->GetCurrentListData();
-	}
-	//otherwise indicate that the current slot has not just been selected
-	//and get parameters from current parameter list
-	else
-	{
-		isCurrentHistory_		= false;
-		myParameters			= (float *) paramComboBox_->GetParameterListData(selIndex-1);
-	}
-
-	//set the text boxes...
-	char str[10];
-	checkTextBoxes_	= false;
-	sprintf(str, "%d", bgRoundSign(myParameters[0]));
-	txtSigmaS_->SetValue(str);
-	sprintf(str, "%3.1f", myParameters[1]);
-	txtSigmaR_->SetValue(str);
-	sprintf(str, "%3.1f", myParameters[2]);
-	txtA_->SetValue(str);
-	sprintf(str, "%3.1f", myParameters[3]);
-	txtEpsilon_->SetValue(str);
-	sprintf(str, "%d", bgRoundSign(myParameters[4]));
-	txtMinRegion_->SetValue(str);
-	sprintf(str, "%d", bgRoundSign(myParameters[5]));
-	txtKernelSize_->SetValue(str);
-	checkTextBoxes_	= true;
-
-}
-
-void BgMdiSegmentChild::OnUpdateTextBoxes(wxCommandEvent& event)
-{
-	//update parameter history....
-	if(checkTextBoxes_)
-	{
-		paramComboBox_->SetSelection(0);
-		isCurrentHistory_	= true;
-	}
-
-	//check if a edge parameter has been changed
-	int	id	= event.GetId();
-	if((id == BG_SEGM_TEXT_GRADWIN)||(id == BG_SEGM_TEXT_AIJ)||(id == BG_SEGM_TEXT_EPSILON))
-		edgeParamsHaveChanged_	= true;
-
-}
-
-void BgMdiSegmentChild::OnUpdateSpeedUpLevel(wxCommandEvent& event)
-{
-	long menuItemId			= event.GetId();
-	wxMenuBar*	myMenuBar	= GetMenuBar();
-	switch(menuItemId)
-	{
-	case BG_SEGM_SPEEDUP_MEDM:
-		speedUpLevel_	= MED_SPEEDUP;
-		myMenuBar->Check(BG_SEGM_SPEEDUP_NONE, false);
-		myMenuBar->Check(BG_SEGM_SPEEDUP_HIGH, false);
-		break;
-	case BG_SEGM_SPEEDUP_HIGH:
-		speedUpLevel_	= HIGH_SPEEDUP;
-		myMenuBar->Check(BG_SEGM_SPEEDUP_NONE, false);
-		myMenuBar->Check(BG_SEGM_SPEEDUP_MEDM, false);
-      {
-         BgSpeedSelect speedSelect(this, -1, "Select speed/quality", wxDefaultPosition, wxSize(220,150),
-            wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL);
-         speedSelect.SetSliderValue(speedUpThreshold_);
-         if (speedSelect.ShowModal()==wxID_OK)
-         {
-            speedSelect.GetSliderValue(speedUpThreshold_);
-         }
-      }
-
-		break;
-	default:
-		speedUpLevel_	= NO_SPEEDUP;
-		myMenuBar->Check(BG_SEGM_SPEEDUP_MEDM, false);
-		myMenuBar->Check(BG_SEGM_SPEEDUP_HIGH, false);
-	}
-}
-
-void BgMdiSegmentChild::OnViewBoundaries(wxCommandEvent&  WXUNUSED(event))
-{
-		
-	if (hasBoundaries_ == false)
-		return;
-
-	bool	isChecked;
-	isChecked = viewBoundariesCheck_->GetValue();
-	
-	if (isChecked)
-	{
-		// show edges
-		displayImage_->AddPointSet(boundaries_);
-		
-	}
-	else
-	{
-		// hide edges
-		displayImage_->RemovePointSet(boundaries_);
-	}
-
-}
-
-
-//activates/de-activates the text boxes used for
-//synergistic segmentation based on the use confidence
-//map checkbox
-void BgMdiSegmentChild::OnUseWeightMap(wxCommandEvent& WXUNUSED(event))
-{
-
-	//depending on use confidence map checkbox, activate/de-activate
-	//text boxes
-	if(useWeightMap_->GetValue())
-	{
-		//enable text boxes
-		txtA_->Enable(true);
-		txtEpsilon_->Enable(true);
-		txtKernelSize_->Enable(true);
-		textA_->Enable(true);
-		textEpsilon_->Enable(true);
-		textKernelSize_->Enable(true);
-	}
-	else
-	{
-		//disable text boxes
-		txtA_->Enable(false);
-		txtEpsilon_->Enable(false);
-		txtKernelSize_->Enable(false);
-		textA_->Enable(false);
-		textEpsilon_->Enable(false);
-		textKernelSize_->Enable(false);
-	}
-
-	//done.
-	return;
-}
-
-void BgMdiSegmentChild::OnUpdatePlotWindow1(wxCommandEvent& event)
-{
-	int menuItemId	= event.GetId();
-
-	//update checkmarks
-	winPanel1_->CheckViewItem(menuItemId);
-
-	//change plot...
-	int i;
-	int data_length	= width_*height_;
-	unsigned char *buffer = new unsigned char[data_length];
-	BgText bgText(1,"ConfidenceMap", *wxSWISS_FONT, 0, 0);
-	switch(menuItemId)
-	{
-	case BG_CANVAS_VIEW1_GRADMAP:
-		bgText.SetText("Gradient Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
-		plotWindow1_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*gradMap_[i] + 0.5);
-		plotWindow1_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW1_CONFMAP:
-		bgText.SetText("Confidence Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
-		plotWindow1_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*confMap_[i] + 0.5);
-		plotWindow1_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW1_WEITMAP:
-		bgText.SetText("Weight Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-35,RANK_CONF_MARGINY/2-10);
-		plotWindow1_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*weightMap_[i] + 0.5);
-		plotWindow1_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW1_CUSTMAP:
-		bgText.SetText("Custom Weight Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-60,RANK_CONF_MARGINY/2-10);
-		plotWindow1_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*customMap_[i] + 0.5);
-		plotWindow1_->SetImageFromGray(buffer, width_, height_);
-		break;
-	}
-	
-	//de-allocate memory used by conf/gradient map buffer
-	delete [] buffer;
-}
-
-void BgMdiSegmentChild::OnUpdatePlotWindow2(wxCommandEvent& event)
-{
-	int menuItemId	= event.GetId();
-
-	//update checkmarks
-	winPanel2_->CheckViewItem(menuItemId);
-
-	//change plot...
-	int i;
-	int data_length	= width_*height_;
-	unsigned char *buffer = new unsigned char[data_length];
-	BgText bgText(1,"ConfidenceMap", *wxSWISS_FONT, 0, 0);
-	switch(menuItemId)
-	{
-	case BG_CANVAS_VIEW2_GRADMAP:
-		bgText.SetText("Gradient Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
-		plotWindow2_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*gradMap_[i] + 0.5);
-		plotWindow2_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW2_CONFMAP:
-		bgText.SetText("Confidence Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
-		plotWindow2_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*confMap_[i] + 0.5);
-		plotWindow2_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW2_WEITMAP:
-		bgText.SetText("Weight Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-35,RANK_CONF_MARGINY/2-10);
-		plotWindow2_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*weightMap_[i] + 0.5);
-		plotWindow2_->SetImageFromGray(buffer, width_, height_);
-		break;
-	case BG_CANVAS_VIEW2_CUSTMAP:
-		bgText.SetText("Custom Weight Map");
-		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-60,RANK_CONF_MARGINY/2-10);
-		plotWindow2_->AddText(&bgText);
-		for(i = 0; i < data_length; i++)
-			buffer[i] = (unsigned char)(255*customMap_[i] + 0.5);
-		plotWindow2_->SetImageFromGray(buffer, width_, height_);
-		break;
-	}
-		
-	//de-allocate memory used by conf/gradient map buffer
-	delete [] buffer;
-}
-
-
-void BgMdiSegmentChild::OnSaveEdgeInformation(wxCommandEvent& event)
-{
-
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-	wxFileDialog filedialog(this,"Save Edge Information","","",
-		"*",wxSAVE);
-#else
-	wxFileDialog filedialog(this,"Save Edge Information","","",
-		"Matlab ASCII data files (*.dat)|*.dat|PGM Files (*.pgm)|*.pgm",
-		wxSAVE);
-#endif
-
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-
-	   //get the image type
-	   int dtype = filedialog.GetFilterIndex();
-
-	   //obtain pointer to data
-	   float	*myData;
-	   switch(event.GetId())
-	   {
-	   case BG_CANVAS_SAVE_GRADMAP:
-		   myData	= gradMap_;
-		   break;
-	   case BG_CANVAS_SAVE_CONFMAP:
-		   myData	= confMap_;
-		   break;
-	   case BG_CANVAS_SAVE_WEITMAP:
-		   myData	= weightMap_;
-		   break;
-	   }
-	   
-	   //get the filename and path
-	   char* path		= (char*) filedialog.GetPath().c_str();
-	   char* filename	= (char*) filedialog.GetFilename().c_str();
-	   
-	   //PGM Image
-	   if(dtype)
-	   {
-		   unsigned char *buf	= new unsigned char [height_*width_];
-		   int i;
-		   for(i = 0; i < height_*width_; i++)
-			   buf[i]	= myData[i]*255 + 0.5;
-		   write_pgm_image(path, buf, height_, width_, "", 255);
-		   delete [] buf;
-	   }
-	   else
-	   //Matlab Data File
-	   {
-		   write_MATLAB_ASCII(path, myData, height_, width_);
-	   }
-   }
-
-}
-
-void BgMdiSegmentChild::OnSize(wxSizeEvent& WXUNUSED(event))
-{
-   int w, h;
-   GetClientSize(&w, &h);
-   optionsPanel_->SetSize(0, 0, BG_SEGM_OP_SIZEX, h);
-   imagePlotSplitter_->SetSize(BG_SEGM_OP_SIZEX, 0, w-BG_SEGM_OP_SIZEX, h);
-   imagePlotSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/2, TRUE);
-   plotMapSplitter_->SetSashPosition(h/2, TRUE);
-   mapSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/4, TRUE);
-}
-
-//clears display of ph diagram and rank and confidence maps
-void BgMdiSegmentChild::ClearDisplay( void )
-{
-	phDiagram_->ClearDisplay();
-	plotWindow1_->ClearDisplay();
-	plotWindow2_->ClearDisplay();
-}
-
-//turns plotting capability on/off
-void BgMdiSegmentChild::UpdateDisplay(bool update)
-{
-	if(update)
-	{
-		phDiagram_->noUpdate_	= false;
-		plotWindow1_->noUpdate_	= false;
-		plotWindow2_->noUpdate_	= false;
-	}
-	else
-	{
-		phDiagram_->noUpdate_	= true;
-		plotWindow1_->noUpdate_	= true;
-		plotWindow2_->noUpdate_	= true;
-	}
-}
-
-void BgMdiSegmentChild::OnQuit(wxCommandEvent& WXUNUSED(event))
-{
-   Close(TRUE);
-}
-
-void BgMdiSegmentChild::OnClose(wxCloseEvent& event)
-{
-   //decrement global counter indicating number of frames open
-   gs_nFrames--;
-   //indicate that the window is now close (used by OnFocus)
-   window_open = false;
-   //reset the toolbar
-   if(gs_nFrames == 0) ResetToolBar();
-   event.Skip();
-}
-
-void BgMdiSegmentChild::OnFocus(wxFocusEvent& WXUNUSED(event))
-{
-	//update toolbar
-	if(!on_exit) UpdateToolBar();
-	return;
-}
-
-void BgMdiSegmentChild::ZoomWindow(void)
-{
-	//display zoom window
-	displayImage_->zoom_window	= true;
-	displayImage_->zoom_in		= false;
-	displayImage_->zoom_out		= false;
-}
-
-void BgMdiSegmentChild::ZoomIn(void)
-{
-	//zoom into display image
-	displayImage_->zoom_window	= false;
-	displayImage_->zoom_in		= true;
-	displayImage_->zoom_out		= false;
-	return;
-}
-
-void BgMdiSegmentChild::ZoomOut(void)
-{
-	//zoom out of display image
-	displayImage_->zoom_window	= false;
-	displayImage_->zoom_in		= false;
-	displayImage_->zoom_out		= true;
-	return;
-}
-
-void BgMdiSegmentChild::NoZoom(void)
-{
-	//do not zoom display image
-	displayImage_->zoom_window	= false;
-	displayImage_->zoom_in		= false;
-	displayImage_->zoom_out		= false;
-	return;
-}
-
-void BgMdiSegmentChild::UpdateZoomControl(void)
-{
-	//determine whether to enable zoom in control based on maximum zoom
-	if(maxZoom_ || minZoom_)
-		UpdateToolBar();
-	else
-	{
-		toolbar->EnableTool(BG_ZOOM_IN, true);
-		toolbar->EnableTool(BG_ZOOM_OUT, true);
-//		toolbar->Realize();
-	}
-}
-
-void BgMdiSegmentChild::RunEnable(void)
-{
-	wxMenuBar *menubar = GetMenuBar();
-	menubar->Enable(BG_SEGM_LOAD_MAP, true);
-	menubar->Enable(BG_SEGM_SEGMENT, true);
-	runButton_->Enable(true);
-	viewImSegRadio_->Enable(true);
-	viewImSegRadio_->Enable(1, false);
-	viewImSegRadio_->Enable(2, false);
-	viewImSegRadio_->Enable(3, false);
-}
-
-void BgMdiSegmentChild::SaveEnable(void)
-{
-	toolbar->EnableTool(BG_SAVE_RESULT, true);
-}
-
-void BgMdiSegmentChild::UpdateToolBar(void)
-{
-	//update toolbar (except during close)
-	if(window_open)
-	{
-		//determine whether to enable save based on whether segmentation
-		//has occurred
-		bool save_enable;
-		if(hasSegment_)
-			save_enable	= true;
-		else
-			save_enable	= false;
-
-		//determine whether to enable zoom controls based on whether image
-		//has been loaded
-		bool load_enable;
-		if(hasImage_)
-			load_enable	= true;
-		else
-			load_enable	= false;
-
-		//determine whether to enable zoom in control based on maximum zoom
-		bool max_zoom;
-		if(maxZoom_)
-			max_zoom	= true;
-		else
-			max_zoom	= false;
-
-		//determine whether to enable zoom out control based on minimum zoom
-		bool min_zoom;
-		if(minZoom_)
-			min_zoom	= true;
-		else
-			min_zoom	= false;
-
-		//adjust toolbar
-		toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to perform image segmentation");
-		toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save segmented image");
-		toolbar->EnableTool(BG_SAVE_RESULT, save_enable);
-		toolbar->EnableTool(BG_CROSS, load_enable);
-		toolbar->EnableTool(BG_ZOOM_IN, ((load_enable)&&(!max_zoom)));
-		toolbar->EnableTool(BG_ZOOM_OUT, ((load_enable)&&(!min_zoom)));
-		toolbar->EnableTool(BG_POINTER, true);
-
-		//set to no zoom
-		toolbar->ToggleTool(BG_CROSS, false);
-		toolbar->ToggleTool(BG_ZOOM_IN, false);
-		toolbar->ToggleTool(BG_ZOOM_OUT, false);
-		toolbar->ToggleTool(BG_POINTER, true);
-		displayImage_->SetCursor(wxCURSOR_ARROW);
-		NoZoom();
-	}
-	return;
-}
-
-void BgMdiSegmentChild::ResetToolBar(void)
-{
-	//update toolbar
-	toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to process");
-	toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save result");
-	toolbar->EnableTool(BG_SAVE_RESULT, false);
-	toolbar->EnableTool(BG_CROSS, false);
-	toolbar->EnableTool(BG_ZOOM_IN, false);
-	toolbar->EnableTool(BG_ZOOM_OUT, false);
-	toolbar->EnableTool(BG_POINTER, false);
-	toolbar->ToggleTool(BG_CROSS, false);
-	toolbar->ToggleTool(BG_ZOOM_IN, false);
-	toolbar->ToggleTool(BG_ZOOM_OUT, false);
-	toolbar->ToggleTool(BG_POINTER, false);
-	return;
-}
-
-void BgMdiSegmentChild::ReadImage(char *pathname, char *filename)
-{
-	//take away point set if boundaries have been calculated
-	if(hasBoundaries_)
-	{
-		hasBoundaries_ = false;
-		displayImage_->RemovePointSet(boundaries_);
-		boundaries_->CleanData();
-	}
-
-	if(displayImage_->SetImage(pathname) == 0)
-		return;
-
-	//obtain and store image filename
-	if(filename_)	delete [] filename_;
-	filename_	= new char [strlen(filename) + 1];
-	strcpy(filename_, filename);
-	
-	displayImage_->showbitmap_ = true;
-	
-	//set value of view boundaries control
-	viewBoundariesCheck_->SetValue(0);
-	
-	//set image view option to original
-	viewImSegRadio_->SetSelection(0);
-
-	//get image dimension
-	width_			= displayImage_->pimage->GetWidth();
-	height_			= displayImage_->pimage->GetHeight();
-	
-	//reset zoom level of display image
-	displayImage_->Zoom(1);
-	
-	//reset max/min zoom flags
-	maxZoom_	= 0;
-	minZoom_	= 1;
-	
-	//set cbgImage
-	cbgImage_->SetImageFromRGB(displayImage_->pimage->GetData(), width_, height_, true);
-	hasImage_		= 1;
-	hasSegment_		= 0;
-	hasBoundaries_	= 0;
-	
-	//adjust titles
-	BgText title(1, "Confidence Map", *wxSWISS_FONT, RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
-	plotWindow1_->AddText(&title);
-	title.SetText("Gradient Map");
-	title.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
-	plotWindow2_->AddText(&title);
-	
-	//add axis
-	plotWindow1_->ClearAxis();
-	plotWindow2_->ClearAxis();
-	plotWindow1_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
-	plotWindow1_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
-	plotWindow2_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
-	plotWindow2_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
-	
-	//label axis
-	BgText label(1, "x", *wxSWISS_FONT, 0, 0);
-	plotWindow1_->LabelHorizontalAxis(&label);
-	plotWindow2_->LabelHorizontalAxis(&label);
-	label.SetText("y");
-	plotWindow1_->LabelVerticalAxis(&label);
-	plotWindow2_->LabelVerticalAxis(&label);
-	plotWindow1_->RotateVerticalAxisLabel(-90);
-	plotWindow2_->RotateVerticalAxisLabel(-90);
-	
-	//set white image
-	unsigned char *img = new unsigned char [(width_)*(height_)*3];
-	memset(img, 255, (width_)*(height_)*3); 
-	whiteImage_->SetImageFromRGB(img, width_, height_, true);
-	delete [] img;
-	
-	//clear the plot window displays
-	ClearDisplay();
-
-	//do no update the plot windows
-	UpdateDisplay(false);
-	
-	//delete edge maps if they exists...
-	if(customMap_)	delete [] customMap_;
-	if(gradMap_  )	delete [] gradMap_;
-	if(confMap_  )	delete [] confMap_;
-	if(weightMap_)	delete [] weightMap_;
-	
-	//set edge maps to NULL...
-	customMap_	= (float *) NULL;
-	gradMap_	= (float *) NULL;
-	confMap_	= (float *) NULL;
-	weightMap_	= (float *) NULL;
-	
-	//update interface...
-	
-	/***********************************************/
-	
-	//enable run
-	RunEnable();
-	
-	//enable operations radio box
-	operationRadio_->Enable(true);
-	
-	//update the tool bar
-	UpdateToolBar();
-	
-	//set window title
-	wxString statusname;
-	statusname.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
-	SetTitle(statusname);
-	
-	//update the menubar
-	wxMenuBar	*menubar	= GetMenuBar();
-	menubar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
-	menubar->Enable(BG_SEGM_USE_MAP, false);
-	
-	//update window menus
-	winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
-	winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
-	winPanel1_->EnableMenu(false);
-	winPanel2_->EnableMenu(false);
-	
-	/***********************************************/
-
-}
-
-void BgMdiSegmentChild::OnLoadImage(wxCommandEvent& WXUNUSED(event))
-{
-// get the file name
-//   wxFileDialog filedialog(this,"Choose an image file","","",
-//      "All files (*.*)|*.*|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm",
-//      wxOPEN);
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-  wxFileDialog filedialog(this,"Choose an image file","","",
-			  "*",wxOPEN);
-#else
-   wxFileDialog filedialog(this,"Choose an image file","","",
-      "Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
-      wxOPEN);
-#endif
-
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-	  //take away point set if boundaries have been calculated
-	  if(hasBoundaries_)
-	  {
-		  hasBoundaries_ = false;
-		  displayImage_->RemovePointSet(boundaries_);
-		  boundaries_->CleanData();
-	  }
-
-      if (displayImage_->SetImage(filedialog.GetPath().c_str()) == 0)
-         return;
-      bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
-
-	  //obtain and store image filename
-	  if(filename_)	delete [] filename_;
-	  filename_	= new char [strlen(filedialog.GetFilename().c_str()) + 1];
-	  strcpy(filename_, filedialog.GetFilename().c_str());
-
-      displayImage_->showbitmap_ = true;
-
-	  //set value of view boundaries control
-	  viewBoundariesCheck_->SetValue(0);
-
-	  //set image view option to original
-	  viewImSegRadio_->SetSelection(0);
-
-	  //set operation option to segment
-	  operationRadio_->SetSelection(0);
-
-	  //get image dimension
-	  width_			= displayImage_->pimage->GetWidth();
-	  height_			= displayImage_->pimage->GetHeight();
-
-	  //reset zoom level of display image
-	  displayImage_->Zoom(1);
-
-	  //reset max/min zoom flags
-	  maxZoom_	= 0;
-	  minZoom_	= 1;
-
-      //set cbgImage
-      cbgImage_->SetImageFromRGB(displayImage_->pimage->GetData(), width_, height_, true);
-      hasImage_			= 1;
-	  hasFilter_		= 0;
-      hasSegment_		= 0;
-      hasBoundaries_	= 0;
-
-	  //adjust titles
-	  BgText title(1, "Confidence Map", *wxSWISS_FONT, RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
-	  plotWindow1_->AddText(&title);
-	  title.SetText("Gradient Map");
-	  title.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
-	  plotWindow2_->AddText(&title);
-
-	  //add axis
-	  plotWindow1_->ClearAxis();
-	  plotWindow2_->ClearAxis();
-	  plotWindow1_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
-	  plotWindow1_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
-	  plotWindow2_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
-	  plotWindow2_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
-
-	  //label axis
-	  BgText label(1, "x", *wxSWISS_FONT, 0, 0);
-	  plotWindow1_->LabelHorizontalAxis(&label);
-	  plotWindow2_->LabelHorizontalAxis(&label);
-	  label.SetText("y");
-	  plotWindow1_->LabelVerticalAxis(&label);
-	  plotWindow2_->LabelVerticalAxis(&label);
-	  plotWindow1_->RotateVerticalAxisLabel(-90);
-	  plotWindow2_->RotateVerticalAxisLabel(-90);
-
-	  //set white image
-	  unsigned char *img = new unsigned char [(width_)*(height_)*3];
-	  memset(img, 255, (width_)*(height_)*3); 
-	  whiteImage_->SetImageFromRGB(img, width_, height_, true);
-	  delete [] img;
-
-	  //clear the plot window displays
-	  ClearDisplay();
-	  
-	  //do not update plot windows
-	  UpdateDisplay(false);
-
-	  //delete edge maps if they exists...
-	  if(customMap_)	delete [] customMap_;
-	  if(gradMap_  )	delete [] gradMap_;
-	  if(confMap_  )	delete [] confMap_;
-	  if(weightMap_)	delete [] weightMap_;
-	  
-	  //set edge maps to NULL...
-	  customMap_	= (float *) NULL;
-	  gradMap_		= (float *) NULL;
-	  confMap_		= (float *) NULL;
-	  weightMap_	= (float *) NULL;
-
-	  //update interface...
-
-	  /***********************************************/
-
-	  //enable run
-	  RunEnable();
-
-	  //enable operations radio box
-	  operationRadio_->Enable(true);
-
-	  //update the tool bar
-	  UpdateToolBar();
-
-	  //set window title
-      wxString statusname;
-      statusname.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
-      SetTitle(statusname);
-
-	  //update the menubar
-	  wxMenuBar	*menubar	= GetMenuBar();
-	  menubar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
-	  menubar->Enable(BG_SEGM_USE_MAP, false);
-
-	  //update window menus
-	  winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
-	  winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
-	  winPanel1_->EnableMenu(false);
-	  winPanel2_->EnableMenu(false);
-
-	  /***********************************************/
-
-   }
-}
-
-
-void BgMdiSegmentChild::LoadCustomWeightMap(wxCommandEvent& WXUNUSED(event))
-{
-	
-	//make sure an image was read...
-	if(hasImage_ == 0)
-	{
-		bgLog("image has not been loaded, load image.\n");
-		return;
-	}
-	
-	//compute data length
-    int	xsz			= cbgImage_->x_, ysz = cbgImage_->y_;
-	int	data_length	= (xsz)*(ysz);
-
-// get the file name
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-  wxFileDialog filedialog(this,"Upload Custom Weight Map","","",
-			  "*",wxOPEN);
-#else
-   wxFileDialog filedialog(this,"Upload Custom Weight Map","","",
-      "Matlab ASCII data files (*.dat)|*.dat|All Files (*.*)|*.*",
-      wxOPEN);
-#endif
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-
-	   //de-allocate memory for customMap (if it exists)
-	   if(customMap_)	delete [] customMap_;
-	   
-	   //allocate memory for customMap
-	   customMap_				= new float [data_length];		
-	   
-	   //get data file name
-	   const char	*filename		= filedialog.GetPath().c_str();
-	   
-	   //attempt to read in data
-	   FILE	*fp = fopen(filename, "rb");
-	   int i;
-	   for(i = 0; i < data_length; i++)
-	   {
-		   if(!fscanf(fp, "%f", &customMap_[i]))
-		   {
-			   bgLog("Load Map Error: Data length does not match the size of the image.");
-			   delete [] customMap_;
-			   customMap_	= NULL;
-			   return;
-		   }
-	   }
-	   fclose(fp);
-
-	   //inform user of successful upload
-	   bgLog("Weight map '%s' successfully uploaded.\n", filename); 
-
-	   //enable use custom weight map menu items
-	   wxMenuBar* myMenuBar	= GetMenuBar();
-	   myMenuBar->Enable(BG_SEGM_USE_MAP, true);
-	   winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, true);
-	   winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, true);
-	   
-   }
-}
-
-void BgMdiSegmentChild::OnSaveSegmentedImage(wxCommandEvent& WXUNUSED(event))
-{
-   if ((hasSegment_ == 0)&&(hasFilter_ == 0))
-   {
-      bgLog("No result to save. Run segmenter.\n");
-      return;
-   }
-
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
-  wxFileDialog filedialog(this,"Choose an image file","","",
-			  "*",wxSAVE);
-#else
-   wxFileDialog filedialog(this,"Choose an image file","","",
-      "PNM files (*.pnm)|*.pnm|PNG files (*.png)|*.png|PCX files (*.pcx)|*.pcx|PGM files (*.pgm)|*.pgm|JPEG files (*.jpg) (not recommended)|*.jpg",
-      wxSAVE);
-#endif
-   if(filedialog.ShowModal()==wxID_OK)
-   {
-
-	   //get the image type
-	   int imtype;
-	   switch (filedialog.GetFilterIndex())
-	   {
-	   case 0:
-		   imtype = wxBITMAP_TYPE_PNM;
-		   break;
-	   case 1:
-		   imtype = wxBITMAP_TYPE_PNG;
-		   break;
-	   case 2:
-		   imtype = wxBITMAP_TYPE_PCX;
-		   break;
-	   case 3:
-		   imtype = wxBITMAP_TYPE_ANY;
-		   break;
-	   case 4:
-		   imtype = wxBITMAP_TYPE_JPEG;
-		   break;
-	   default:
-		   return;
-	   }
-	   
-	   //if the filtered image is available then save it...
-	   if(hasFilter_ == 1)
-	   {
-
-		   //get path and add extension
-		   char *path	= new char [strlen(filedialog.GetPath()) + 1];
-		   strcpy(path, filedialog.GetPath());
-		   BgAddExtension(&path, "_filt");
-		   
-		   //convert the image to wxImage format...
-		   wxImage tmpIm(filtImage_->x_, filtImage_->y_);
-		   unsigned char* tmpImData;
-		   tmpImData = tmpIm.GetData();
-		   filtImage_->GetImageColor(tmpImData);
-		   
-		   //save the image...
-		   tmpIm.SaveFile(path, imtype);
-		   bgLog("Filtered image saved to:\t'%s'.\n", path);
-
-		   //de-allocate memory
-		   delete path;
-
-	   }
-	   
-	   //if the segmented image is available then save it...
-	   if(hasSegment_ == 1)
-	   {
-		   
-		   //get path and add extension
-		   char *path	= new char [strlen(filedialog.GetPath()) + 1];
-		   strcpy(path, filedialog.GetPath());
-		   BgAddExtension(&path, "_segm");
-		   
-		   //convert the image to wxImage format...
-		   wxImage tmpIm(segmImage_->x_, segmImage_->y_);
-		   unsigned char* tmpImData;
-		   tmpImData = tmpIm.GetData();
-		   segmImage_->GetImageColor(tmpImData);
-		   
-		   //save the image...
-		   tmpIm.SaveFile(path, imtype);
-		   bgLog("Segmented image saved to:\t'%s'.\n", path);
-
-		   //de-allocate memory
-		   delete [] path;
-		   
-	   }
-	   
-	   //save boundaries
-	   OnSaveBoundaries((char*)filedialog.GetPath().c_str(), imtype);
-	   
-   }
-}
-
-//saves edge map
-void BgMdiSegmentChild::OnSaveBoundaries(char *filename, int imtype)
-{
-
-	//make sure boundaries exist before proceeding...
-	if(hasBoundaries_ == 0)
-		return;
-
-	//create edge map
-	int width = cbgImage_->x_, height = cbgImage_->y_;
-	wxImage tmpImg(width, height);
-	unsigned char *buf = tmpImg.GetData();
-	memset(buf, 255, width*height*3*sizeof(unsigned char));
-	int n = boundaries_->n_;
-	int i, dp, x, y;
-	for(i = 0; i < n; i++)
-	{
-		x			= boundaries_->x_[i];
-		y			= boundaries_->y_[i];
-		dp			= y*width+x;
-		buf[3*dp]	= buf[3*dp+1]	= buf[3*dp+2]	= 0;
-	}
-
-	//create new filename (add _em extension)
-	char *new_filename	= new char [strlen(filename) + 1];
-	strcpy(new_filename, filename);
-	BgAddExtension(&new_filename, "_bndy");
-
-	//save edgemap using specified filename and image format
-	tmpImg.SaveFile(new_filename, imtype);
-	bgLog("Boundaries saved to:\t'%s'.\n", new_filename);
-
-	//de-allocate memory
-	delete	[] new_filename;
-
-	//done.
-	return;
-
-}
-
-//construct a ph diagram using the boundary pixels
-//aquired from image segmentation (also outputs results
-//to 'xyrc.txt'
-void BgMdiSegmentChild::SetphDiagram(int width, float *confMap, float *rankMap)
-{
-   unsigned char* buf;
-   int xsz	= RANK_CONF_IMSIZEX;
-   int ysz	= RANK_CONF_IMSIZEY;
-   int imsz = xsz*ysz;
-   buf = new unsigned char[imsz];
-   int i;
-   for (i=0; i<imsz; i++)
-      buf[i] = 255;
-
-   int l, c, dpoint;
-   int n = boundaries_->n_;
-   int *xpos = boundaries_->x_, *ypos = boundaries_->y_;
-   for (i=0; i<n; i++)
-   {
-	  dpoint = (ypos[i])*width+xpos[i];
-      if ((rankMap[dpoint]>0) && (confMap[dpoint]>0))
-      {
-         c = (int) (rankMap[dpoint]*((double) xsz));
-         c = (c>=xsz) ? xsz-1 : c;
-         l = (int) (confMap[dpoint]*((double) ysz));
-         l = (l>=ysz) ? ysz-1 : l;
-         l = ysz-1-l;
-         buf[c+l*xsz]=80;
-
-      }
-   }
-
-   phDiagram_->SetImageFromGray(buf, xsz, ysz);
-
-   //adjust scroll bar...
-   phDiagram_->SetScrollbars(1, 1, xsz+2*RANK_CONF_MARGINX, ysz+2*RANK_CONF_MARGINY+40);
-   delete [] buf;
-}
-
-void mySegment(void *Object)
-{
-	BgMdiSegmentChild *segmObj	= (BgMdiSegmentChild *) Object;
-	segmObj->Segment();
-}
-
-void BgMdiSegmentChild::OnSegment(wxCommandEvent& WXUNUSED(event))
-{
-
-	//get parameters from GUI
-	int error = GetParameters(sigmaS, sigmaR, aij, epsilon, minRegion, kernelSize, 1);
-	if(error)
-		return;
-
-	//create the working thread
-	BgThread *workingThread	= new BgThread(wxTHREAD_DETACHED, mySegment, this);
-	stop_flag	= false;
-	workingThread->Create();
-	workingThread->Run();
-
-	//determine progress bar title and message
-	int	operation	= operationRadio_->GetSelection();
-	char myMessage[80], myTitle[80];
-	switch (operation)
-	{
-	//filter
-	case 1:
-		strcpy(myTitle,		"Image Filtering Progress");
-		strcpy(myMessage,	"Filtering Image...");
-		break;
-	//fuse regions
-	case 2:
-		strcpy(myTitle,		"Region Fusing Progress");
-		strcpy(myMessage,	"Fusing Image Regions...");
-		break;
-	//segment
-	default:
-		strcpy(myTitle,		"Image Segmentation Progress");
-		strcpy(myMessage,	"Segmenting Image...");
-		break;
-	}
-
-	//call progress dialog
-	bool	done;
-	percentDone	= 0;
-	wxProgressDialog progressDialog(myTitle, myMessage, 100, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
-	while((done = progressDialog.Update(percentDone))&&(percentDone != 100)) wxYield();
-	if(!done)	stop_flag	= true;	//if the algorithm is not done but the user aborted the operation
-									//then tell the thread to stop running
-
-	//if its succesfully completed update the parameter history box
-	if(done)
-	{
-		int	selIndex	= paramComboBox_->GetSelection();
-		if(selIndex)
-		{
-			paramComboBox_->UseParameterList(selIndex-1);
-		}
-		else
-		{
-			float *myParameters = new float [6];
-			myParameters[0]	= sigmaS;
-			myParameters[1]	= sigmaR;
-			myParameters[2]	= aij;
-			myParameters[3]	= epsilon;
-			myParameters[4]	= minRegion;
-			myParameters[5]	= kernelSize;
-			paramComboBox_->AddParameterList((void *) myParameters, 6);
-		}
-
-		//set the selection to the current parameter slot
-		paramComboBox_->SetSelection(0);
-		isCurrentHistory_	= true;
-	}
-	return;
-
-}
-
-void BgMdiSegmentChild::Segment( void )
-{
-	// parameters
-	//   sigma_s
-	//   sigma_r
-	//   a
-	//   epsilon
-	//   minRegion
-	//   kernel radius
-	//   filter
-	//   speedup level
-	
-	if (hasImage_ == 0)
-	{
-		bgLog("No image loaded!\n");
-		return;
-	}
-
-	//if image segmentaiton is not synergistic clear
-	//display and disable it, otherwise enable it
-	if(!useWeightMap_->GetValue())
-	{
-		ClearDisplay();
-		UpdateDisplay(false);
-	}
-	else
-	{
-		UpdateDisplay(true);
-	}
-	
-	//display parameters to the user
-	if(useWeightMap_->GetValue())
-	{
-		bgLog("Input parameters:\n");
-		bgLog("\tSpatial Bandwidth\t\t= %4d\n\tColor Bandwidth\t\t= %4.1f\n", sigmaS, sigmaR);
-		bgLog("\tMinimum Region\t\t= %4d\n", minRegion);
-		bgLog("\tGradient Window Radius\t= %4d\n", kernelSize);
-		bgLog("\tMixing Parameter\t\t= %4.1f\n", aij);
-		bgLog("\tThreshold\t\t\t= %4.1f\n", epsilon);
-	}
-	else
-	{
-		bgLog("Input parameters:\n");
-		bgLog("\tSpatial Bandwidth\t= %4d\n\tColor Bandwidth\t= %4.1f\n", sigmaS, sigmaR);
-		bgLog("\tMinimum Region\t= %4d\n", minRegion);
-	}
-	
-	//obtain image dimensions
-	int	width, height;
-	width = cbgImage_->x_;
-	height = cbgImage_->y_;
-
-	//obtain image type (color or grayscale)
-	imageType	gtype;
-	if(cbgImage_->colorIm_)
-		gtype = COLOR;
-	else
-		gtype = GRAYSCALE;
-
-	//if gradient and confidence maps are not defined, 
-	//and synergistic segmentation is requested, then compute them;
-	//also compute them if the parameters have changed
-	if(useWeightMap_->GetValue())
-	{
-		
-		//if the weight map has already been defined
-		//then find out if it needs to be recomputed
-		if((weightMap_)&&(edgeParamsHaveChanged_))
-		{
-			delete [] confMap_;
-			delete [] gradMap_;
-			delete [] weightMap_;
-			weightMap_	= (float *) NULL;
-			//indicate that the change has been recognized...
-			edgeParamsHaveChanged_	= false;
-		}
-		
-		//if the weight map has not been computed or discarded
-		//then recompute it...
-		if(!weightMap_)
-		{
-			
-			//allocate memory for gradient and confidence maps
-			confMap_	= new float[width*height];
-			gradMap_	= new float[width*height];
-			
-			//compute gradient and confidence maps
-			BgEdgeDetect	edgeDetector(kernelSize);
-			edgeDetector.ComputeEdgeInfo(cbgImage_, confMap_, gradMap_);
-			
-			//compute weight map...
-			
-			/******************************************************************/
-			
-			//allocate memory for weight map
-			weightMap_ = new float[width*height];
-			
-			//compute weight map using gradient and confidence maps
-			int i;
-			for (i=0; i<width*height; i++)
-			{
-				if (gradMap_[i] > 0.02)
-					weightMap_[i] = aij*gradMap_[i] + (1 - aij)*confMap_[i];
-				else
-					weightMap_[i] = 0;
-			}
-			
-			/******************************************************************/
-		}
-		
-	}
-	
-	//determine operation (filtering or segmentation)
-	int	operation	= operationRadio_->GetSelection();
-
-	//create instance of image processor class
-	msImageProcessor *iProc = new msImageProcessor();
-
-	//define an input image using the image under consideration
-	//(if filtering or segmentation has taken place, then use this
-	// result upon performing fusing...)
-	if((operation == 2)&&(hasFilter_))
-		iProc->DefineImage(filtImage_->im_, gtype, height, width);
-	else
-		iProc->DefineImage(cbgImage_->im_, gtype, height, width);
-
-	//determine if a custom weight map is to be used
-	wxMenuBar *menubar = GetMenuBar();
-	bool useCustomMap	= menubar->IsChecked(BG_SEGM_USE_MAP);
-
-	//set the weight map (if one was specified and a custom map is not being utilized)
-	if((useWeightMap_->GetValue())&&(weightMap_)&&(!useCustomMap))	iProc->SetWeightMap(weightMap_, epsilon);
-
-	//set the custom map (if one was provided)
-	if((useWeightMap_->GetValue())&&(customMap_)&&(useCustomMap))	iProc->SetWeightMap(customMap_, epsilon);
-	
-	//check for errors in image definition or in the setting
-	//of the confidence map...
-	if (iProc->ErrorStatus)
-	{
-		bgLog("%s\n", iProc->ErrorMessage);
-		return;
-	}
-
-	//perform image segmentation or filtering....
-	timer_start(); //start the timer
-   iProc->SetSpeedThreshold(speedUpThreshold_);
-	switch(operation)
-	{
-	//filter
-	case 1:
-
-		iProc->Filter(sigmaS, sigmaR, speedUpLevel_);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		} else if (iProc->ErrorStatus == EL_HALT)
-		{
-			break;
-		}
-
-		//obtain the filtered image....
-		filtImage_->Resize(width, height, cbgImage_->colorIm_);
-		iProc->GetResults(filtImage_->im_);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		}
-
-		//indicate that only the filtered image has been computed...
-		hasFilter_	= 1;
-		hasSegment_	= 0;
-		
-		break;
-
-	//fuse
-	case 2:
-
-		iProc->FuseRegions(sigmaR, minRegion);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		} else if (iProc->ErrorStatus == EL_HALT)
-		{
-			break;
-		}
-
-		//obtain the segmented image...
-		segmImage_->Resize(width, height, cbgImage_->colorIm_);
-		iProc->GetResults(segmImage_->im_);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		}
-
-		//indicate that the segmented image has been computed...
-		hasSegment_	= 1;
-
-		break;
-
-	//segment
-	default:
-
-		//filter the image...
-		iProc->Filter(sigmaS, sigmaR, speedUpLevel_);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		} else if (iProc->ErrorStatus == EL_HALT)
-		{
-			break;
-		}
-
-		//filter the image....
-		int dim;
-		if(cbgImage_->colorIm_)
-			dim = 3;
-		else
-			dim = 1;
-		unsigned char *tempImage = new unsigned char [dim*height*width];
-		iProc->GetResults(tempImage);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			delete [] tempImage;
-			return;
-		}
-		
-		//fuse regions...
-		iProc->FuseRegions(sigmaR, minRegion);
-		if (iProc->ErrorStatus == EL_ERROR)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			delete [] tempImage;
-			return;
-		} else if (iProc->ErrorStatus == EL_HALT)
-		{
-			delete [] tempImage;
-			break;
-		}
-
-		//obtain the segmented and filtered image...
-		filtImage_->Resize(width, height, cbgImage_->colorIm_);
-		memcpy(filtImage_->im_, tempImage, dim*height*width*sizeof(unsigned char));
-		delete [] tempImage;
-		segmImage_->Resize(width, height, cbgImage_->colorIm_);
-		iProc->GetResults(segmImage_->im_);
-		if (iProc->ErrorStatus)
-		{
-			bgLog("%s\n", iProc->ErrorMessage);
-			return;
-		}
-
-		//indicate that both the filtered and segmented image have been computed...
-		hasFilter_	= 1;
-		hasSegment_	= 1;
-
-	}
-
-	//check and see if the algorithm has been halted, if so
-	//then de-allocate the image processing object and
-	//indicate to the working thread that it is safe
-	//to exit at this point and exit
-	if(iProc->ErrorStatus == EL_HALT)
-	{
-		delete iProc;
-		stop_flag	= false;
-		bgLog("Operation Canceled.\n");
-		return;
-	}
-
-	//set has boundaries to true
-	hasBoundaries_	= true;
-	
-	//clean boundary data if any exists
-	boundaries_->CleanData();
-	
-	//get boundary indeces from region list object
-	//of the image processor object...
-	RegionList	*regionList			= iProc->GetBoundaries();
-	int			*regionIndeces		= regionList->GetRegionIndeces(0);
-	int			numRegions			= regionList->GetNumRegions();
-	int			boundaryPointCount	= 0;
-	
-	//calculate the number of boundary points stored by region list
-	//class
-	int i;
-	for(i = 0; i < numRegions; i++)
-		boundaryPointCount += regionList->GetRegionCount(i);
-	
-	//create a point set using calculated boundary point count...
-	boundaries_->x_	= new int [boundaryPointCount];
-	boundaries_->y_	= new int [boundaryPointCount];
-	boundaries_->n_	= boundaryPointCount;
-	for(i = 0; i < boundaryPointCount; i++)
-	{
-		boundaries_->x_[i]	= regionIndeces[i]%width;
-		boundaries_->y_[i]	= regionIndeces[i]/width;
-	}
-	
-	//set pen width, and style
-	boundaries_->pen_.SetWidth(1);
-	boundaries_->pen_.SetStyle(wxSOLID);
-	
-	//set point type to point (= 1)
-	boundaries_->type_	= 1;
-	
-	//construct the phDiagram
-	if(useWeightMap_->GetValue())	SetphDiagram(width, confMap_, gradMap_);
-	
-	//display the confidence and gradient maps respectively
-	if(useWeightMap_->GetValue())
-	{
-		wxCommandEvent myevent;
-		myevent.m_id = BG_CANVAS_VIEW1_CONFMAP;
-		OnUpdatePlotWindow1(myevent);
-		myevent.m_id = BG_CANVAS_VIEW2_GRADMAP;
-		OnUpdatePlotWindow2(myevent);
-	}
-
-	//delete the image processing object
-	delete iProc;
-
-	//done.
-
-	//stop the timer
-	timer_stop();
-
-	//update the GUI...
-
-	/**********************************************************************************/
-
-	//update the menu bar
-	menubar->Enable(BG_SEGM_SAVE_SEGMENTED, true);
-
-	//update tool bar
-	SaveEnable();
-
-	//update segmentation window....
-	switch(operation)
-	{
-
-	//the image has been filtered only....
-	case 1:
-		viewImSegRadio_->Enable(1, true);
-		viewImSegRadio_->Enable(2, false);
-		viewImSegRadio_->SetSelection(1);
-		break;
-
-	//the image has been segmented only...
-	case 2:
-		viewImSegRadio_->Enable(2, true);
-		viewImSegRadio_->SetSelection(2);
-		break;
-
-	//image has been filtered and segmented...
-	default:
-		viewImSegRadio_->Enable(1, true);
-		viewImSegRadio_->Enable(2, true);
-		viewImSegRadio_->SetSelection(2);
-		break;
-
-	}
-	viewImSegRadio_->Enable(3, true);
-	viewBoundariesCheck_->Enable(true);
-	wxCommandEvent zcev;
-	OnViewImSeg(zcev);
-
-	//update the menu bars...
-	winPanel1_->EnableMenu(useWeightMap_->GetValue());
-	winPanel2_->EnableMenu(useWeightMap_->GetValue());
-
-	/**********************************************************************************/
-
-	//set progress to 100% (need this for case of filtering)
-	percentDone = 100;
-	
-	//indicate that it is safe for the thread to stop executing
-	stop_flag	= false; 
-
-	//done.
-	return;
-
-}
-
-int BgMdiSegmentChild::GetParameters(int &sigmaS, float &sigmaR, float &aij, float &epsilon, int &minRegion, int &kernelSize, int dataEntryCheck)
-{
-
-   double	tempd;
-   char		str[10];
-
-   //do not perform data entry check
-   if(!dataEntryCheck)
-   {
-	   //sigmaS
-	   txtSigmaS_->GetValue().ToDouble(&tempd);
-	   sigmaS			= bgRoundSign(tempd);
-
-	   //sigmaR
-	   txtSigmaR_->GetValue().ToDouble(&tempd);
-	   sigmaR			= (float) tempd;
-
-	   //minRegion
-	   txtMinRegion_->GetValue().ToDouble(&tempd);
-	   minRegion		= bgRoundSign(tempd);
-
-	   //kernel size
-	   txtKernelSize_->GetValue().ToDouble(&tempd);
-	   kernelSize		= bgRoundSign(tempd);
-
-	   //aij
-	   txtA_->GetValue().ToDouble(&tempd);
-	   aij				= (float) tempd;
-
-	   //epsilon
-	   txtEpsilon_->GetValue().ToDouble(&tempd);
-	   epsilon			= (float) tempd;
-
-	   //done.
-	   return 0;
-   }
-   
-   //perform data entry check
-   if ((txtSigmaS_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
-   {
-	   sigmaS = (int)(tempd + 0.5);
-	   sprintf(str, "%d", sigmaS);
-	   txtSigmaS_->SetValue(str);
-   }
-   else
-   {
-	   bgLog("The value of the spatial bandwidth cannot be zero or negative.\n");
-	   return 1;
-   }
-   if ((txtSigmaR_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
-	   sigmaR = tempd;
-   else
-   {
-	   bgLog("The value of the range bandwidth cannot be zero or negative.\n");
-	   return 1;
-   }
-   if ((txtMinRegion_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0))
-   {
-	   minRegion = (int)(tempd + 0.5);
-	   sprintf(str, "%d", minRegion);
-	   txtMinRegion_->SetValue(str);
-   }
-   else
-   {
-	   bgLog("The value of minimum region cannot be negative.\n");
-	   return 1;
-   }
-   if ((txtKernelSize_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
-   {
-	   kernelSize = (int)(tempd + 0.5);
-	   sprintf(str, "%d", kernelSize);
-	   txtKernelSize_->SetValue(str);
-   }
-   else
-   {
-	   bgLog("The gradient window radius cannot be zero or negative.\n");
-	   return 1;
-   }
-   if ((txtA_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0) && (tempd <= 1))
-   {
-	   aij = tempd;
-	   if(aij < 0.01) txtA_->SetValue("0.0");
-   }
-   else
-   {
-	   bgLog("The value of the mixture parameter cannot be negative or greater than one.\n");
-	   return 1;
-   }
-   if ((txtEpsilon_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0) && (tempd <= 1))
-   {
-	   epsilon = tempd;
-	   if(epsilon < 0.01) txtEpsilon_->SetValue("0.0");
-   }
-   else
-   {
-	   bgLog("The threshold value cannot be negative or greater than one.\n");
-	   return 1;
-   }
-   return 0;
+/////////////////////////////////////////////////////////////////////////////
+// Name:        bgimsystem.cpp
+// Purpose:     Image processing system
+// Author:      Bogdan Georgescu, Chris M. Christoudias
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu, Chris M. Christoudias
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+   #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+   #include "wx/wx.h"
+#endif
+
+#include <wx/toolbar.h>
+#include <wx/progdlg.h>
+
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+   #include "icons/mondrian.xpm"
+   #include "icons/new.xpm"
+   #include "icons/open.xpm"
+   #include "icons/save.xpm"
+   #include "icons/copy.xpm"
+   #include "icons/cut.xpm"
+   #include "icons/paste.xpm"
+   #include "icons/print.xpm"
+   #include "icons/help.xpm"
+#endif
+
+#include <wx/html/htmlwin.h>
+
+#include "BgImagPGM.h"
+#include "BgImagPNM.h"
+
+// Edge detection include stuff
+#include <math.h>
+#include "BgImage.h"
+#include "BgEdge.h"
+#include "BgEdgeList.h"
+#include "BgEdgeDetect.h"
+#include "BgDefaults.h"
+
+#include "msImageProcessor.h"
+
+#include <stdio.h>
+#include <string.h>
+#include "bgimsystem.h"
+
+IMPLEMENT_APP(BgApp)
+// ---------------------------------------------------------------------------
+// global variables
+// ---------------------------------------------------------------------------
+
+BgMdiFrame *g_frame = (BgMdiFrame *) NULL;
+wxList g_children;
+
+// For drawing lines in a canvas
+static long g_xpos = -1;
+static long g_ypos = -1;
+
+static int	gs_nFrames	= 0;
+static bool	on_exit		= false;
+#define DEFAULT_LOG_SIZE 100
+
+// ---------------------------------------------------------------------------
+// event tables
+// ---------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(BgMdiFrame, wxMDIParentFrame)
+EVT_MENU(BG_ABOUT, BgMdiFrame::OnAbout)
+EVT_MENU(BG_HELP, BgMdiFrame::OnHelp)
+EVT_MENU(BG_QUIT, BgMdiFrame::OnQuit)
+EVT_MENU(BG_NEW_EDGE_WINDOW, BgMdiFrame::OnNewEdgeWindow)
+EVT_MENU(BG_NEW_SEGM_WINDOW, BgMdiFrame::OnNewSegmWindow)
+EVT_MENU(BG_LOAD_IMAGE, BgMdiFrame::OnLoadImage)
+EVT_MENU(BG_LOAD_IMAGE_EDGE, BgMdiFrame::OnLoadImageEdge)
+EVT_MENU(BG_SEGM_LOAD_IMAGE, BgMdiFrame::OnLoadImageSegm)
+EVT_MENU(BG_SAVE_RESULT, BgMdiFrame::OnSaveResult)
+EVT_MENU(BG_CROSS, BgMdiFrame::ZoomControl)
+EVT_MENU(BG_ZOOM_IN, BgMdiFrame::ZoomControl)
+EVT_MENU(BG_ZOOM_OUT, BgMdiFrame::ZoomControl)
+EVT_MENU(BG_POINTER, BgMdiFrame::ZoomControl)
+EVT_CLOSE(BgMdiFrame::OnClose)
+
+EVT_SIZE(BgMdiFrame::OnSize)
+END_EVENT_TABLE()
+
+// Note that BG_NEW_WINDOW and BG_ABOUT commands get passed
+// to the parent window for processing, so no need to
+// duplicate event handlers here.
+
+BEGIN_EVENT_TABLE(BgMdiEdgeChild, wxMDIChildFrame)
+EVT_MENU(BG_LOAD_IMAGE_EDGE, BgMdiEdgeChild::OnLoadImage)
+EVT_MENU(BG_EDGE_DETECT, BgMdiEdgeChild::OnEdgeDetect)
+EVT_MENU(BG_CHANGE_PARAM_EDGE, BgMdiEdgeChild::OnChangeParam)
+EVT_MENU(BG_CHILD_EDGE_QUIT, BgMdiEdgeChild::OnQuit)
+EVT_MENU(BG_EDGE_VIEW_ORIG, BgMdiEdgeChild::OnViewOrig)
+EVT_MENU(BG_EDGE_VIEW_EDGE, BgMdiEdgeChild::OnViewEdge)
+EVT_MENU(BG_EDGE_SAVE_MAP, BgMdiEdgeChild::OnSaveEdgeMap)
+
+EVT_SET_FOCUS(BgMdiEdgeChild::OnFocus)
+EVT_CLOSE(BgMdiEdgeChild::OnClose)
+EVT_SIZE(BgMdiEdgeChild::OnSize)
+
+EVT_BUTTON(BG_EDGE_DETECT, BgMdiEdgeChild::OnEdgeDetect)
+EVT_BUTTON(BG_CHANGE_PARAM_EDGE, BgMdiEdgeChild::OnChangeParam)
+EVT_CHECKBOX(BG_EDGE_CVIEW_ORIG, BgMdiEdgeChild::OnCViewOrig)
+EVT_CHECKBOX(BG_EDGE_CVIEW_EDGE, BgMdiEdgeChild::OnCViewEdge)
+
+EVT_COMMAND(BG_EVENT_UPDATE_ID, BG_EVENT_UPDATE, BgMdiEdgeChild::OnUpdateNum)
+
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgMdiSegmentChild, wxMDIChildFrame)
+EVT_MENU(BG_SEGM_LOAD_IMAGE, BgMdiSegmentChild::OnLoadImage)
+EVT_MENU(BG_SEGM_SAVE_SEGMENTED, BgMdiSegmentChild::OnSaveSegmentedImage)
+EVT_MENU(BG_SEGM_SAVE_EDGEMAP, BgMdiSegmentChild::OnSaveBoundaries)
+EVT_MENU(BG_CHILD_SEGM_QUIT, BgMdiSegmentChild::OnQuit)
+EVT_MENU(BG_SEGM_SEGMENT, BgMdiSegmentChild::OnSegment)
+EVT_MENU(BG_SEGM_LOAD_MAP, BgMdiSegmentChild::LoadCustomWeightMap)
+EVT_MENU(BG_SEGM_SPEEDUP_NONE, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
+EVT_MENU(BG_SEGM_SPEEDUP_MEDM, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
+EVT_MENU(BG_SEGM_SPEEDUP_HIGH, BgMdiSegmentChild::OnUpdateSpeedUpLevel)
+EVT_MENU(BG_CANVAS_VIEW1_GRADMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
+EVT_MENU(BG_CANVAS_VIEW1_CONFMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
+EVT_MENU(BG_CANVAS_VIEW1_WEITMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
+EVT_MENU(BG_CANVAS_VIEW1_CUSTMAP, BgMdiSegmentChild::OnUpdatePlotWindow1)
+EVT_MENU(BG_CANVAS_VIEW2_GRADMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
+EVT_MENU(BG_CANVAS_VIEW2_CONFMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
+EVT_MENU(BG_CANVAS_VIEW2_WEITMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
+EVT_MENU(BG_CANVAS_VIEW2_CUSTMAP, BgMdiSegmentChild::OnUpdatePlotWindow2)
+EVT_MENU(BG_CANVAS_SAVE_GRADMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
+EVT_MENU(BG_CANVAS_SAVE_CONFMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
+EVT_MENU(BG_CANVAS_SAVE_WEITMAP, BgMdiSegmentChild::OnSaveEdgeInformation)
+
+EVT_SET_FOCUS(BgMdiSegmentChild::OnFocus)
+EVT_CLOSE(BgMdiSegmentChild::OnClose)
+EVT_SIZE(BgMdiSegmentChild::OnSize)
+
+EVT_BUTTON(BG_SEGM_LOAD_IMAGE, BgMdiSegmentChild::OnLoadImage)
+EVT_BUTTON(BG_SEGM_SEGMENT, BgMdiSegmentChild::OnSegment)
+EVT_BUTTON(BG_SEGM_LOAD_MAP, BgMdiSegmentChild::LoadCustomWeightMap)
+EVT_RADIOBOX(BG_SEGM_VIEW_IMSEG, BgMdiSegmentChild::OnViewImSeg)
+EVT_RADIOBOX(BG_SEGM_OPERATION, BgMdiSegmentChild::OnChangeOperation)
+EVT_CHECKBOX(BG_SEGM_VIEW_EDGES, BgMdiSegmentChild::OnViewBoundaries)
+EVT_CHECKBOX(BG_SEGM_USE_EDGE_MAP, BgMdiSegmentChild::OnUseWeightMap)
+EVT_COMBOBOX(BG_SEGM_CHANGE_PARAMS, BgMdiSegmentChild::OnChangeParameters)
+
+EVT_TEXT(BG_SEGM_TEXT_SIGMAS, BgMdiSegmentChild::OnUpdateTextBoxes)
+EVT_TEXT(BG_SEGM_TEXT_SIGMAR, BgMdiSegmentChild::OnUpdateTextBoxes)
+EVT_TEXT(BG_SEGM_TEXT_MINREG, BgMdiSegmentChild::OnUpdateTextBoxes)
+EVT_TEXT(BG_SEGM_TEXT_GRADWIN, BgMdiSegmentChild::OnUpdateTextBoxes)
+EVT_TEXT(BG_SEGM_TEXT_AIJ, BgMdiSegmentChild::OnUpdateTextBoxes)
+EVT_TEXT(BG_SEGM_TEXT_EPSILON, BgMdiSegmentChild::OnUpdateTextBoxes)
+
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgImCanvas, wxScrolledWindow)
+EVT_RIGHT_DOWN(BgImCanvas::OnMouseRightDown)
+EVT_MOUSE_EVENTS(BgImCanvas::OnEvent)
+
+EVT_MENU(BG_IMC_ADDNODE, BgImCanvas::OnCustomAddNode)
+EVT_MENU(BG_IMC_DELETENODE, BgImCanvas::OnCustomDeleteNode)
+EVT_MENU(BG_IMC_SELTYPE_ELLIPSE, BgImCanvas::OnCTypeEllipse)
+EVT_MENU(BG_IMC_SELTYPE_VLINE, BgImCanvas::OnCTypeVLine)
+EVT_MENU(BG_IMC_SELTYPE_HLINE, BgImCanvas::OnCTypeHLine)
+EVT_MENU(BG_IMC_SELTYPE_LINE, BgImCanvas::OnCTypeLine)
+EVT_MENU(BG_IMC_SELTYPE_BOX, BgImCanvas::OnCTypeBox)
+EVT_MENU(BG_IMC_SELTYPE_CUSTOM, BgImCanvas::OnCTypeCustom)
+
+//EVT_SCROLLWIN(BgImCanvas::OnScroll)
+
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgParamDialog, wxDialog)
+EVT_BUTTON(BG_PARAMD_OK, BgParamDialog::OnOk)
+EVT_BUTTON(BG_PARAMD_CANCEL, BgParamDialog::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgSpeedSelect, wxDialog)
+EVT_BUTTON(BG_SPEEDSEL_OK, BgSpeedSelect::OnOk)
+EVT_BUTTON(BG_SPEEDSEL_CANCEL, BgSpeedSelect::OnCancel)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgDialog, wxDialog)
+EVT_BUTTON(BG_DIALOG_OK, BgDialog::OnExit)
+EVT_PAINT(BgDialog::OnPaint)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgHoverBar, wxWindow)
+EVT_BUTTON(BG_CANVAS_VIEW_BUTTON, BgHoverBar::ShowMenu)
+EVT_BUTTON(BG_CANVAS_SAVE_BUTTON, BgHoverBar::ShowMenu)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(BgMenuPanel, wxPanel)
+EVT_BUTTON(BG_CANVAS_VIEW_BUTTON, BgMenuPanel::ShowMenu)
+EVT_BUTTON(BG_CANVAS_SAVE_BUTTON, BgMenuPanel::ShowMenu)
+EVT_SIZE(BgMenuPanel::OnSize)
+END_EVENT_TABLE()
+
+// ===========================================================================
+// implementation
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+// Global Data used for Multi-Threaded Enviornment
+// ---------------------------------------------------------------------------
+
+bool	stop_flag;
+int		percentDone;
+
+// ---------------------------------------------------------------------------
+// Log function
+// ---------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// wxLogTextCtrl implementation
+// ----------------------------------------------------------------------------
+
+bgLogTextCtrl::bgLogTextCtrl(wxTextCtrl *pTextCtrl)
+{
+    m_pTextCtrl = pTextCtrl;
+}
+
+void bgLogTextCtrl::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
+{
+    wxString msg;
+    TimeStamp(&msg);
+    msg << szString;
+
+    m_pTextCtrl->AppendText(msg);
+}
+
+#define VAR_LOG_BUFFER_SIZE   (4096)
+
+static wxChar varszBuf[VAR_LOG_BUFFER_SIZE];
+
+FILE* glogfile;
+
+void bgLog(const char* szFormat, ...)
+{
+   va_list argptr;
+   va_start(argptr, szFormat);
+   wxVsnprintf(varszBuf, WXSIZEOF(varszBuf), szFormat, argptr);
+   va_end(argptr);
+   ::wxLogMessage(varszBuf);
+   bgLogFile(varszBuf);
+}
+
+void bgLogVar(const char* first, va_list alist)
+{
+//   va_start(alist, first);
+   wxVsnprintf(varszBuf, WXSIZEOF(varszBuf), first, alist);
+//   va_end(alist);
+   ::wxLogMessage(varszBuf);
+   bgLogFile(varszBuf);
+}
+
+void bgLogFile(const char* szFormat, ...)
+{
+   if (glogfile == 0)
+      glogfile = fopen("filelog.txt", "w");
+   va_list argptr;
+   va_start(argptr, szFormat);
+   vfprintf(glogfile, szFormat, argptr);
+   va_end(argptr);
+   fflush(glogfile);
+}
+
+inline int bgRound(double inline_x)
+{
+    return ((int) (inline_x+0.5));
+}
+
+// ---------------------------------------------------------------------------
+// BgApp
+// ---------------------------------------------------------------------------
+
+// Initialise this in OnInit, not statically
+bool BgApp::OnInit()
+{
+   // Create the main frame window
+   
+   g_frame = new BgMdiFrame((wxFrame *)NULL, -1, "Edge Detection and Image SegmentatiON System (EDISON)",
+      wxPoint(10, 10), wxSize(1024, 768),
+      wxDEFAULT_FRAME_STYLE | wxHSCROLL | wxVSCROLL);
+#ifdef __WXMSW__
+#if 0
+   // Experimental: change the window menu
+   wxMenu* windowMenu = new wxMenu;
+   windowMenu->Append(5000, "My menu item!");
+   frame->SetWindowMenu(windowMenu);
+#endif
+#endif
+   
+   // Give it an icon
+#ifdef __WXMSW__
+   g_frame->SetIcon(wxIcon("bg_icn"));
+#else
+   g_frame->SetIcon(wxIcon( mondrian_xpm ));
+#endif
+
+   // Make a menubar
+   wxMenu *file_menu = new wxMenu;
+   
+   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detect window");
+   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
+   file_menu->Append(BG_LOAD_IMAGE_EDGE, "&Load edge image\tCtrl-L", "Load a new image to perform edge detection");
+   file_menu->Append(BG_SEGM_LOAD_IMAGE, "&Load segment image\tShift-L", "Load a new image to perform segmentation");
+   file_menu->Append(BG_QUIT, "E&xit\tAlt-X", "Quit the program");
+   
+   wxMenu *help_menu = new wxMenu;
+   help_menu->Append(BG_ABOUT, "&About");
+   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
+   
+   wxMenuBar *menu_bar = new wxMenuBar;
+   
+   menu_bar->Append(file_menu, "&File");
+   menu_bar->Append(help_menu, "&Help");
+
+   // Associate the menu bar with the frame
+   g_frame->SetMenuBar(menu_bar);
+   
+   g_frame->CreateStatusBar();
+   
+   g_frame->Show(TRUE);
+   
+   SetTopWindow(g_frame);
+
+#if wxUSE_LIBPNG
+  wxImage::AddHandler( new wxPNGHandler );
+#endif
+
+#if wxUSE_LIBJPEG
+  wxImage::AddHandler( new wxJPEGHandler );
+#endif
+
+#if wxUSE_LIBTIFF
+  wxImage::AddHandler( new wxTIFFHandler );
+#endif
+
+#if wxUSE_GIF
+  wxImage::AddHandler( new wxGIFHandler );
+#endif
+
+#if wxUSE_PCX
+  wxImage::AddHandler( new wxPCXHandler );
+#endif
+
+  wxImage::AddHandler( new bgPNMHandler );
+  wxImage::AddHandler( new bgPGMHandler );
+   return TRUE;
+}
+
+// ---------------------------------------------------------------------------
+// BgMdiFrame
+// ---------------------------------------------------------------------------
+
+// Define my frame constructor
+BgMdiFrame::BgMdiFrame(wxWindow *parent,
+                       const wxWindowID id,
+                       const wxString& title,
+                       const wxPoint& pos,
+                       const wxSize& size,
+                       const long style)
+                       : wxMDIParentFrame(parent, id, title, pos, size, style)
+{
+    logtext_ = new wxTextCtrl(this, -1, "Log window.\n",
+                            wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY);
+    logtext_->SetBackgroundColour("wheat");
+     bglogctrl_ = new bgLogTextCtrl(logtext_);
+    logTargetOld_ = wxLog::SetActiveTarget(bglogctrl_);
+    logsize_ = DEFAULT_LOG_SIZE;
+
+   CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
+   InitToolBar(GetToolBar());
+   
+   //get program location directory
+   strcpy(programDir_, wxGetCwd());
+
+   //get help directory location
+   //(NOTE: This code must be altered to function properly in UNIX.)
+   strcpy(helpDir_, programDir_);
+   strcat(helpDir_, "\\doc\\help.html");
+
+   // Accelerators
+   wxAcceleratorEntry entries[13];
+   entries[0].Set(wxACCEL_ALT, (int) 'E', BG_NEW_EDGE_WINDOW);
+   entries[1].Set(wxACCEL_ALT, (int) 'S', BG_NEW_SEGM_WINDOW);
+   entries[2].Set(wxACCEL_ALT, (int) 'X', BG_QUIT);
+   entries[3].Set(wxACCEL_ALT, (int) 'C', BG_CHILD_EDGE_QUIT);
+   entries[4].Set(wxACCEL_SHIFT, (int) 'C', BG_CHILD_SEGM_QUIT);
+   entries[5].Set(wxACCEL_CTRL, (int) 'H', BG_HELP);
+   entries[6].Set(wxACCEL_CTRL, (int) 'S', BG_EDGE_SAVE_MAP);
+   entries[7].Set(wxACCEL_SHIFT, (int) 'S', BG_SEGM_SAVE_SEGMENTED);
+   entries[8].Set(wxACCEL_CTRL, (int) 'L', BG_LOAD_IMAGE_EDGE);
+   entries[9].Set(wxACCEL_SHIFT, (int) 'L', BG_SEGM_LOAD_IMAGE);
+   entries[10].Set(wxACCEL_SHIFT, (int) 'M', BG_SEGM_LOAD_MAP);
+   entries[11].Set(wxACCEL_CTRL, (int) 'R', BG_EDGE_DETECT);
+   entries[12].Set(wxACCEL_SHIFT, (int) 'R', BG_SEGM_SEGMENT);
+   wxAcceleratorTable accel(13, entries);
+   SetAcceleratorTable(accel);
+   
+   // bgFileLog
+   //glogfile = fopen("filelog.txt", "w");
+   glogfile = 0;
+}
+
+void BgMdiFrame::OnClose(wxCloseEvent& event)
+{
+   if ( event.CanVeto() && (gs_nFrames > 0) )
+   {
+      wxString msg;
+      if (gs_nFrames == 1)
+         msg.Printf(_T("%d window still open, close anyhow?"), gs_nFrames);
+      else
+         msg.Printf(_T("%d windows still open, close anyhow?"), gs_nFrames);
+      if ( wxMessageBox(msg, "Please confirm",
+         wxICON_QUESTION | wxYES_NO) != wxYES )
+      {
+         event.Veto();
+         
+         return;
+      }
+   }
+
+   //indicate that the system is exiting
+   on_exit	= true;
+
+   wxLog::SetActiveTarget(logTargetOld_);
+   delete bglogctrl_;
+   delete logtext_;
+
+   // bgFileLog
+   if (glogfile != 0)
+      fclose(glogfile);
+
+   event.Skip();
+}
+
+//sets the title of the active child frame
+void BgMdiFrame::SetChildTitle(wxMDIChildFrame *activeChild, int zconst, int maxZoom, int minZoom)
+{
+	wxString	title;
+	if(activeChild->GetId() == BG_EDGE_WINDOW)
+	{
+		BgMdiEdgeChild *edgeChild	= (BgMdiEdgeChild *) activeChild;
+		if(maxZoom)
+			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) x %d [Maximum Zoom]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_, zconst);
+		else if(minZoom)
+			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_);
+		else
+			title.Printf(_T("Edge Detection Frame %d - %s (%d x %d) x %d [Zoom]"), edgeChild->window_number_, edgeChild->filename_, edgeChild->width_, edgeChild->height_, zconst);
+	}
+	else if(activeChild->GetId() == BG_SEGM_WINDOW)
+	{
+		BgMdiSegmentChild *segmChild	= (BgMdiSegmentChild *) activeChild;
+		if(maxZoom)
+			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) x %d [Maximum Zoom]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_, zconst);
+		else if(minZoom)
+			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_);
+		else
+			title.Printf(_T("Segmentation Frame %d - %s (%d x %d) x %d [Zoom]"), segmChild->window_number_, segmChild->filename_, segmChild->width_, segmChild->height_, zconst);
+	}
+	activeChild->SetTitle(title);
+	return;
+}
+
+//updates toolbar when maximum zoom occurs
+void BgMdiFrame::UpdateZoomControl(wxMDIChildFrame *activeChild, int maxZoom, int minZoom)
+{
+	if(activeChild->GetId()	== BG_EDGE_WINDOW)
+	{
+		if(maxZoom)
+			((BgMdiEdgeChild *) activeChild)->maxZoom_	= true;
+		else
+			((BgMdiEdgeChild *) activeChild)->maxZoom_	= false;
+		if(minZoom)
+			((BgMdiEdgeChild *) activeChild)->minZoom_	= true;
+		else
+			((BgMdiEdgeChild *) activeChild)->minZoom_	= false;
+		((BgMdiEdgeChild *) activeChild)->UpdateZoomControl();
+	}
+	else if (activeChild->GetId() == BG_SEGM_WINDOW)
+	{
+		if(maxZoom)
+			((BgMdiSegmentChild *) activeChild)->maxZoom_	= true;
+		else
+			((BgMdiSegmentChild *) activeChild)->maxZoom_	= false;
+		if(minZoom)
+			((BgMdiSegmentChild *) activeChild)->minZoom_	= true;
+		else
+			((BgMdiSegmentChild *) activeChild)->minZoom_	= false;
+		((BgMdiSegmentChild *) activeChild)->UpdateZoomControl();
+	}
+}
+
+void BgMdiFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+   Close();
+}
+
+void BgMdiFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
+{
+	const int BG_DIALOG_INDENT = 30, BG_DIALOG_TOP_MARGIN = 15;
+	BgDialog aboutDialog(this, -1, "About EDISON", wxPoint(-1,-1), wxSize(450, 300), wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL | wxBORDER | wxSYSTEM_MENU, "aboutDialog");
+	wxFont	myFont(9, wxSWISS, wxNORMAL, wxBOLD, false);
+	BgText	bgText(0, "Edge Detection and Image SegmentatiON System (EDISON) v1.1", myFont, BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN);
+	aboutDialog.AddText(&bgText);
+	myFont.SetWeight(wxNORMAL);
+	myFont.SetUnderlined(true);
+	bgText.SetId(1);
+	bgText.SetFont(myFont);
+	bgText.SetText("Authors");
+	bgText.SetPlotLocation(BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN+15);
+	aboutDialog.AddText(&bgText);
+	myFont.SetUnderlined(false);
+	bgText.SetId(2);
+	bgText.SetFont(myFont);
+	bgText.SetText(": Bogdan Georgescu, Chris Christoudias (freeware) 2002");
+	bgText.SetPlotLocation(BG_DIALOG_INDENT+44, BG_DIALOG_TOP_MARGIN+15);
+	aboutDialog.AddText(&bgText);
+	bgText.SetId(3);
+	bgText.SetText("Center for Advanced Information Processing (CAIP), Rutgers University");
+	bgText.SetPlotLocation(BG_DIALOG_INDENT, BG_DIALOG_TOP_MARGIN+30);
+	aboutDialog.AddText(&bgText);
+	wxBitmap riul_logo("riul_logo", wxBITMAP_TYPE_RESOURCE), caip_logo("caip_logo", wxBITMAP_TYPE_RESOURCE), rutgers_logo("rutgers_logo", wxBITMAP_TYPE_RESOURCE);
+	BgBitmap myBitmap(&riul_logo, 0, BG_DIALOG_INDENT+20, BG_DIALOG_TOP_MARGIN+60);
+	aboutDialog.AddBitmap(&myBitmap);
+	myBitmap.SetId(1);
+	myBitmap.SetMap(&caip_logo);
+	myBitmap.SetPlotLocation(BG_DIALOG_INDENT+85, BG_DIALOG_TOP_MARGIN+170);
+	aboutDialog.AddBitmap(&myBitmap);
+	myBitmap.SetId(2);
+	myBitmap.SetMap(&rutgers_logo);
+	myBitmap.SetPlotLocation(BG_DIALOG_INDENT+145, BG_DIALOG_TOP_MARGIN+165);
+	aboutDialog.AddBitmap(&myBitmap);
+	aboutDialog.Centre(wxBOTH);
+	aboutDialog.ShowModal();
+}
+
+void BgMdiFrame::OnHelp(wxCommandEvent& WXUNUSED(event) )
+{  
+   wxDialog helpDialog(this, -1, "Help Window", wxPoint(10,10), wxSize(800,600), wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL | wxBORDER | wxSYSTEM_MENU);
+   wxHtmlWindow helpWind(&helpDialog, -1, wxPoint(10,10), wxSize(770,550));
+   helpWind.LoadPage(helpDir_);
+   helpDialog.ShowModal();
+   bgLog("\n");
+}
+
+void BgMdiFrame::OnLoadImage(wxCommandEvent& WXUNUSED(event))
+{
+
+	wxMDIChildFrame *activeChild = GetActiveChild();
+	wxCommandEvent zcev;
+	if(activeChild)
+	{
+		if(activeChild->GetId() == BG_EDGE_WINDOW)
+			((BgMdiEdgeChild*) activeChild)->OnLoadImage(zcev);
+		else if(activeChild->GetId() == BG_SEGM_WINDOW)
+			((BgMdiSegmentChild*) activeChild)->OnLoadImage(zcev);
+	} else
+	{
+		//read an image
+		char *pathname, *filename;
+		GetImageFileInfo(&pathname, &filename);
+		if(pathname)
+		{
+
+			//get current width and height of this window
+			int width, height;
+			GetSize(&width, &height);
+
+			//half window width
+			width = width/2;
+
+			//create an edge window
+			OnNewEdgeWindow(zcev);
+			
+			//load read image into edge window
+			activeChild = GetActiveChild();
+			((BgMdiEdgeChild*) activeChild)->ReadImage(pathname, filename);
+			((BgMdiEdgeChild*) activeChild)->RunEnable();
+			
+			//set position and size of edge detection window
+			activeChild->SetSize(0,-30,width,height);
+			
+			//create a segmentation window
+			OnNewSegmWindow(zcev);
+			
+			//load read image into segment window
+			activeChild = GetActiveChild();
+			((BgMdiSegmentChild*) activeChild)->ReadImage(pathname, filename);
+			((BgMdiSegmentChild*) activeChild)->RunEnable();
+
+			//set position and size of segmnetation window
+			activeChild->SetSize(width,-30,width,height);
+			
+			//de-allocate memory used by filename
+			delete [] filename;
+		}
+	}
+	
+}
+
+void BgMdiFrame::OnLoadImageEdge(wxCommandEvent& WXUNUSED(event))
+{
+   BgMdiEdgeChild* activeChild;
+   activeChild = 0;
+   activeChild = (BgMdiEdgeChild*) GetActiveChild();
+   wxCommandEvent zcev;
+   if (activeChild != 0)
+   {
+      activeChild->OnLoadImage(zcev);
+   } else
+   {
+      OnNewEdgeWindow(zcev);
+      activeChild = (BgMdiEdgeChild*) GetActiveChild();
+      activeChild->OnLoadImage(zcev);
+   }
+}
+
+void BgMdiFrame::OnLoadImageSegm(wxCommandEvent& WXUNUSED(event))
+{
+   BgMdiSegmentChild* activeChild;
+   activeChild = 0;
+   activeChild = (BgMdiSegmentChild*) GetActiveChild();
+   wxCommandEvent zcev;
+   if (activeChild != 0)
+   {
+      activeChild->OnLoadImage(zcev);
+   } else
+   {
+      OnNewSegmWindow(zcev);
+      activeChild = (BgMdiSegmentChild*) GetActiveChild();
+      activeChild->OnLoadImage(zcev);
+   }
+}
+
+void BgMdiFrame::OnSaveResult(wxCommandEvent& WXUNUSED(event))
+{
+	wxMDIChildFrame* activeChild = GetActiveChild();
+	if(activeChild)
+	{
+		wxCommandEvent zcev;
+		if (activeChild->GetId() == BG_EDGE_WINDOW)
+			((BgMdiEdgeChild *) activeChild)->OnSaveEdgeMap(zcev);
+		else if (activeChild->GetId() == BG_SEGM_WINDOW)
+			((BgMdiSegmentChild *) activeChild)->OnSaveSegmentedImage(zcev);
+	}
+}
+
+void BgMdiFrame::OnNewEdgeWindow(wxCommandEvent& WXUNUSED(event) )
+{
+
+   //indicate that another child frame will be created
+   gs_nFrames++;
+
+   // Make another frame, containing a edge processing window
+      BgMdiEdgeChild *subframe = new BgMdiEdgeChild(g_frame, "Edge Detection Frame",
+      wxPoint(-1, -1), wxSize(-1, -1),
+      wxDEFAULT_FRAME_STYLE);
+
+   wxString title;
+   title.Printf(_T("Edge Detection Frame %d"), gs_nFrames);
+   
+   subframe->SetTitle(title);
+   
+   // Give it an icon
+#ifdef __WXMSW__
+   subframe->SetIcon(wxIcon("chrt_icn"));
+#else
+   subframe->SetIcon(wxIcon( mondrian_xpm ));
+#endif
+   
+   // Make a menubar
+   wxMenu *file_menu = new wxMenu;
+   
+   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detection window");
+   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
+   file_menu->Append(BG_LOAD_IMAGE_EDGE, "&Load image\tCtrl-L", "Load image to perform edge detection");
+   file_menu->Append(BG_EDGE_SAVE_MAP, "&Save edge map\tCtrl-S");
+   file_menu->Append(BG_CHILD_EDGE_QUIT, "&Close edge window\tAlt-C", "Close this window");
+   file_menu->Append(BG_QUIT, "E&xit\tAlt-X");
+   
+   wxMenu *edge_menu = new wxMenu;
+   
+   edge_menu->Append(BG_EDGE_DETECT, "Edge Detect\tCtrl-R");
+   edge_menu->Append(BG_CHANGE_PARAM_EDGE, "Change Parameters...");
+
+   wxMenu *view_menu = new wxMenu;
+
+   subframe->miViewOrig_ = new wxMenuItem(view_menu, BG_EDGE_VIEW_ORIG, "Original", "View original", TRUE);
+   subframe->miViewEdge_ = new wxMenuItem(view_menu, BG_EDGE_VIEW_EDGE, "Edge map", "View edge map", TRUE);
+
+   view_menu->Append(subframe->miViewOrig_);
+   view_menu->Append(subframe->miViewEdge_);
+   
+   wxMenu *help_menu = new wxMenu;
+   help_menu->Append(BG_ABOUT, "&About");
+   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
+   
+   wxMenuBar *menu_bar = new wxMenuBar;
+   
+   menu_bar->Append(file_menu, "&File");
+   menu_bar->Append(edge_menu, "&Edge Detect");
+   menu_bar->Append(view_menu, "&View");
+   menu_bar->Append(help_menu, "&Help");
+
+   //disable items on menu bar
+   menu_bar->Enable(BG_EDGE_DETECT, false);
+   menu_bar->Enable(BG_EDGE_SAVE_MAP, false);
+   
+   // Associate the menu bar with the frame
+   subframe->SetMenuBar(menu_bar);
+   
+   subframe->CreateStatusBar();
+   subframe->SetStatusText(title);
+   
+   int width, height;
+   subframe->GetClientSize(&width, &height);
+   
+   subframe->Show(TRUE);
+   subframe->miViewOrig_->Check(TRUE);
+   subframe->miViewEdge_->Check(TRUE);
+}
+
+void BgMdiFrame::OnNewSegmWindow(wxCommandEvent& WXUNUSED(event) )
+{
+
+   //indicate that another child frame will be created
+   gs_nFrames++;
+
+   // Make another frame, containing a edge processing window
+      BgMdiSegmentChild *subframe = new BgMdiSegmentChild(g_frame, "Segmentation Frame",
+      wxPoint(-1, -1), wxSize(-1, -1),
+      wxDEFAULT_FRAME_STYLE);
+
+   wxString title;
+   title.Printf(_T("Segmentation Frame %d"), gs_nFrames);
+   
+   subframe->SetTitle(title);
+   
+   // Give it an icon
+#ifdef __WXMSW__
+   subframe->SetIcon(wxIcon("chrt_icn"));
+#else
+   subframe->SetIcon(wxIcon( mondrian_xpm ));
+#endif
+   
+   // Make a menubar
+   wxMenu *file_menu = new wxMenu;
+   file_menu->Append(BG_NEW_EDGE_WINDOW, "New &edge window\tAlt-E", "Create a new edge detection window");
+   file_menu->Append(BG_NEW_SEGM_WINDOW, "New &segment window\tAlt-S", "Create a new segmentation window");
+   file_menu->Append(BG_SEGM_LOAD_IMAGE, "&Load image\tShift-L", "Load image to perform segmentation");
+   file_menu->Append(BG_SEGM_SAVE_SEGMENTED, "&Save result\tShift-S");
+   file_menu->Append(BG_CHILD_SEGM_QUIT, "&Close window\tShift-C", "Close this window");
+   file_menu->Append(BG_QUIT, "E&xit\tAlt-X");
+   
+   wxMenu *segm_menu = new wxMenu;
+   segm_menu->Append(BG_SEGM_SEGMENT, "Segment Image\tShift-R");
+   segm_menu->AppendSeparator();
+   wxMenu *speedup_menu	= new wxMenu;
+   speedup_menu->Append(BG_SEGM_SPEEDUP_NONE, "&None", "", true);
+   speedup_menu->Append(BG_SEGM_SPEEDUP_MEDM, "&Medium", "", true);
+   speedup_menu->Append(BG_SEGM_SPEEDUP_HIGH, "&High", "", true);
+   wxMenuItem *segm_menu_item	= new wxMenuItem(segm_menu, BG_SEGM_SPEEDUP, "Speedup", "", false, speedup_menu);
+   segm_menu->Append(segm_menu_item);
+
+   wxMenu *weightmap_menu = new wxMenu;
+   weightmap_menu->Append(BG_SEGM_LOAD_MAP,  "Load custom weight &map\tShift-M", "Load map images to perform segmentation");
+   weightmap_menu->AppendSeparator();
+   weightmap_menu->Append(BG_SEGM_USE_MAP, "&Use custom weight map", "", true);
+   
+   wxMenu *help_menu = new wxMenu;
+   help_menu->Append(BG_ABOUT, "&About");
+   help_menu->Append(BG_HELP, "&Help\tCtrl-H");
+
+   wxMenuBar *menu_bar = new wxMenuBar;
+   menu_bar->Append(file_menu, "&File");
+   menu_bar->Append(segm_menu, "&Algorithm");
+   menu_bar->Append(weightmap_menu, "&Weight Map");
+   menu_bar->Append(help_menu, "&Help");
+
+   //disable items on menu bar
+   menu_bar->Enable(BG_SEGM_SEGMENT, false);
+   menu_bar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
+   menu_bar->Enable(BG_SEGM_LOAD_MAP, false);
+   menu_bar->Enable(BG_SEGM_USE_MAP, false);
+
+   //check speedup to medium
+   menu_bar->Check(BG_SEGM_SPEEDUP_MEDM, true);
+
+   // Associate the menu bar with the frame
+   subframe->SetMenuBar(menu_bar);
+   subframe->CreateStatusBar();
+   subframe->SetStatusText(title);
+  
+   subframe->Show(TRUE);
+   subframe->Fit();
+}
+
+void BgMdiFrame::GetImageFileInfo(char **pathname, char **filename)
+{
+
+// get the file name
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+	wxFileDialog filedialog(this,"Choose an image file","","",
+		"*",wxOPEN);
+#else
+	wxFileDialog filedialog(this,"Choose an image file","","",
+		"Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
+		wxOPEN);
+#endif
+
+	//retrieve and check filename
+	*filename = (char *) NULL;
+	*pathname = (char *) NULL;
+   	BgImCanvas *temp = new BgImCanvas(this, this, wxDefaultPosition, wxDefaultSize);
+	if(filedialog.ShowModal()==wxID_OK)
+	{
+		char* temp_str	= (char *) filedialog.GetPath().c_str();
+		*pathname	= new char [strlen(temp_str) + 1];
+		strcpy(*pathname, temp_str);
+		temp_str	= (char *) filedialog.GetFilename().c_str();
+		*filename	= new char [strlen(temp_str) + 1];
+		strcpy(*filename, temp_str);
+		if (temp->SetImage(*pathname) == 0)
+		{
+			delete [] *pathname;
+			delete [] *filename;
+			*pathname	= (char *) NULL;
+			*filename	= (char *) NULL;
+		}
+		else
+			bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
+	}
+
+	//de-allocate memory
+	delete temp;
+
+	//done.
+	return;
+}
+
+//manages toolbar zoom controls
+void BgMdiFrame::ZoomControl(wxCommandEvent& event)
+{
+	//set display
+	wxToolBar	*toolbar = GetToolBar();
+	switch (event.m_id)
+	{
+	case BG_CROSS:
+		toolbar->ToggleTool(BG_CROSS, true);
+		toolbar->ToggleTool(BG_ZOOM_IN, false);
+		toolbar->ToggleTool(BG_ZOOM_OUT, false);
+		toolbar->ToggleTool(BG_POINTER, false);
+		break;
+	case BG_ZOOM_IN:
+		toolbar->ToggleTool(BG_CROSS, false);
+		toolbar->ToggleTool(BG_ZOOM_IN, true);
+		toolbar->ToggleTool(BG_ZOOM_OUT, false);
+		toolbar->ToggleTool(BG_POINTER, false);
+		break;
+	case BG_ZOOM_OUT:
+		toolbar->ToggleTool(BG_CROSS, false);
+		toolbar->ToggleTool(BG_ZOOM_IN, false);
+		toolbar->ToggleTool(BG_ZOOM_OUT, true);
+		toolbar->ToggleTool(BG_POINTER, false);
+		break;
+		//BG_POINTER:
+	default:
+		toolbar->ToggleTool(BG_CROSS, false);
+		toolbar->ToggleTool(BG_ZOOM_IN, false);
+		toolbar->ToggleTool(BG_ZOOM_OUT, false);
+		toolbar->ToggleTool(BG_POINTER, true);
+		break;
+	}
+
+	//set zoom functionality
+	wxMDIChildFrame	*activeChild	= GetActiveChild();
+	if(activeChild->GetId()	== BG_EDGE_WINDOW)
+	{
+		switch (event.m_id)
+		{
+		case BG_CROSS:
+			((BgMdiEdgeChild *) activeChild)->ZoomWindow();
+			break;
+		case BG_ZOOM_IN:
+			((BgMdiEdgeChild *) activeChild)->ZoomIn();
+			break;
+		case BG_ZOOM_OUT:
+			((BgMdiEdgeChild *) activeChild)->ZoomOut();
+			break;
+			//BG_POINTER:
+		default:
+			((BgMdiEdgeChild *) activeChild)->NoZoom();
+			break;
+		}
+	}
+	else if(activeChild->GetId() == BG_SEGM_WINDOW)
+	{
+		switch (event.m_id)
+		{
+		case BG_CROSS:
+			((BgMdiSegmentChild *) activeChild)->ZoomWindow();
+			break;
+		case BG_ZOOM_IN:
+			((BgMdiSegmentChild *) activeChild)->ZoomIn();
+			break;
+		case BG_ZOOM_OUT:
+			((BgMdiSegmentChild *) activeChild)->ZoomOut();
+			break;
+			//BG_POINTER:
+		default:
+			((BgMdiSegmentChild *) activeChild)->NoZoom();
+			break;
+		}
+	}
+
+	return;
+		
+}
+
+
+void BgMdiFrame::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+   int w, h;
+   GetClientSize(&w, &h);
+   logtext_->SetSize(0, h-logsize_, w, logsize_);
+   GetClientWindow()->SetSize(0, 0, w, h-logsize_);
+}
+
+
+void BgMdiFrame::InitToolBar(wxToolBar* toolBar)
+{
+   const int	BITMAP_COUNT = 9;
+   wxBitmap* bitmaps[BITMAP_COUNT];
+   
+#ifdef __WXMSW__
+   bitmaps[0] = new wxBitmap( "icon1", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[1] = new wxBitmap( "icon7", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[2] = new wxBitmap( "icon8", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[3] = new wxBitmap( "icon2", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[4] = new wxBitmap( "icon3", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[5] = new wxBitmap( "icon9", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[6] = new wxBitmap("icon10", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[7] = new wxBitmap("icon11", wxBITMAP_TYPE_RESOURCE);
+   bitmaps[8] = new wxBitmap("icon12", wxBITMAP_TYPE_RESOURCE);
+#else
+   bitmaps[0] = new wxBitmap( bnew_xpm );
+   bitmaps[1] = new wxBitmap( bnsg_xpm );
+   bitmaps[2] = new wxBitmap( bhelp_xpm );
+   bitmaps[3] = new wxBitmap( bopen_xpm );
+   bitmaps[4] = new wxBitmap( bsave_xpm );
+   bitmaps[5] = new wxBitmap( bcros_xpm );
+   bitmaps[6] = new wxBitmap( bzin_xpm );
+   bitmaps[7] = new wxBitmap( bzout_xpm );
+   bitmaps[8] = new wxBitmap( bpoin_xpm );
+
+#endif
+   
+#ifdef __WXMSW__
+   int width = 24;
+#else
+   int width = 16;
+#endif
+   int currentX = 5;
+   
+   //add tools to tool bar
+   toolBar->AddTool( BG_NEW_EDGE_WINDOW, *(bitmaps[0]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "New edge window");
+   currentX += width + 5;
+   toolBar->AddTool( BG_NEW_SEGM_WINDOW, *(bitmaps[1]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "New segment window");
+   currentX += width + 5;
+   toolBar->AddTool( BG_LOAD_IMAGE, *(bitmaps[3]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Load image for processing");
+   currentX += width + 5;
+   toolBar->AddTool( BG_SAVE_RESULT, *(bitmaps[4]), wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Save result");
+   currentX += width + 5;
+   toolBar->AddSeparator();
+   toolBar->AddTool( BG_CROSS, *(bitmaps[5]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom Window");
+   currentX += width + 5;
+   toolBar->AddTool( BG_ZOOM_IN, *(bitmaps[6]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom In");
+   currentX += width + 5;
+   toolBar->AddTool( BG_ZOOM_OUT, *(bitmaps[7]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Zoom Out");
+   currentX += width + 5;
+   toolBar->AddTool( BG_POINTER, *(bitmaps[8]), wxNullBitmap, TRUE, currentX, -1, (wxObject *) NULL, "Select");
+   currentX += width + 5;
+   toolBar->AddSeparator();
+   toolBar->AddTool( BG_HELP, *bitmaps[2], wxNullBitmap, FALSE, currentX, -1, (wxObject *) NULL, "Help");
+   
+   //set bitmap size of controls buttons to 20x20
+   wxSize tool_size(20,20);
+   toolBar->SetToolBitmapSize(tool_size);
+
+   toolBar->Realize();
+
+   //disable certain tools
+   toolBar->EnableTool(BG_SAVE_RESULT, false);
+   toolBar->EnableTool(BG_CROSS, false);
+   toolBar->EnableTool(BG_ZOOM_IN, false);
+   toolBar->EnableTool(BG_ZOOM_OUT, false);
+   toolBar->EnableTool(BG_POINTER, false);
+   
+   int i;
+   for (i = 0; i < BITMAP_COUNT; i++)
+      delete bitmaps[i];
+}
+
+// ---------------------------------------------------------------------------
+// BgPointSet
+// ---------------------------------------------------------------------------
+
+BgPointSet::BgPointSet()
+{
+   x_ = y_ = 0;
+   n_ = 0;
+   type_ = 0;
+   pen_.SetColour(*wxBLUE);
+   //pen_.SetColour(*wxWHITE);
+   pen_.SetWidth(1);
+   pen_.SetStyle(wxSOLID);
+}
+
+BgPointSet::~BgPointSet()
+{
+   CleanData();
+}
+
+void BgPointSet::CleanData()
+{
+   if (n_ > 0)
+   {
+      delete [] x_;
+      delete [] y_;
+      x_ = y_ = 0;
+      n_ = 0;
+   }
+}
+
+void BgPointSet::SetPoints(int* x, int* y, int n)
+{
+   CleanData();
+   n_ = n;
+   x_ = new int[n_];
+   y_ = new int[n_];
+   for (int i=0; i<n; i++)
+   {
+      x_[i] = x[i];
+      y_[i] = y[i];
+   }
+}
+
+// ---------------------------------------------------------------------------
+// BgCurveSet
+// ---------------------------------------------------------------------------
+
+BgCurveSet::BgCurveSet()
+{
+   x_ = y_ = 0;
+   xs_ = ys_ = 0;
+   n_ = 0;
+   type_ = -1;
+   pen_.SetColour(*wxBLUE);
+   pen_.SetWidth(3);
+   pen_.SetStyle(wxSOLID);
+   isDragging_ = 0;
+}
+
+BgCurveSet::~BgCurveSet()
+{
+   CleanData();
+}
+
+void BgCurveSet::CleanData()
+{
+   if (n_ > 0)
+   {
+      delete [] x_;
+      delete [] y_;
+      x_ = y_ = 0;
+      n_ = 0;
+   }
+   type_ = -1;
+   xs_ = ys_ = 0;
+}
+
+void BgCurveSet::SetCurve(BgCurveSet* bgc)
+{
+   CleanData();
+   type_ = bgc->type_;
+   n_ = bgc->n_;
+   x_ = new int[n_];
+   y_ = new int[n_];
+   xs_ = bgc->xs_;
+   ys_ = bgc->ys_;
+   for (int i=0; i<n_; i++)
+   {
+      x_[i] = bgc->x_[i];
+      y_[i] = bgc->y_[i];
+   }
+}
+
+void BgCurveSet::SetParamCurve(int type, double* x, double* y, int n, int xs, int ys)
+{
+   CleanData();
+   type_ = type;
+   n_ = n;
+   x_ = new int[n_];
+   y_ = new int[n_];
+   xs_ = xs;
+   ys_ = ys;
+   for (int i=0; i<n; i++)
+   {
+      x_[i] = (int) (x[i]*xs);
+      y_[i] = (int) (ys-y[i]*ys);
+   }
+}
+
+void BgCurveSet::GetParamCurve(double* x, double* y, int& type, int& n)
+{
+   for (int i=0; i<n_; i++)
+   {
+      x[i] = ((double)x_[i])/xs_;
+      y[i] = ((double)(ys_-y_[i]))/ys_;
+   }
+   type = type_;
+   n = n_;
+}
+
+void BgCurveSet::DrawYourself(unsigned char* buf, int val)
+{
+   int j;
+   switch (type_)
+   {
+   case -1:
+      break;
+   case FC_ELLIPSE:
+      DrawEllipticArc(buf, val, -x_[0], y_[0], 2*x_[0], 2*(ys_-y_[0]), 0, 90);
+      break;
+   case FC_VERT_LINE:
+      DrawLine(buf, val, x_[0], 0, x_[0], ys_);
+      break;
+   case FC_HORIZ_LINE:
+      DrawLine(buf, val, 0, y_[0], xs_, y_[0]);
+      break;
+   case FC_LINE:
+      DrawLine(buf, val, 0, y_[0], x_[0], ys_);
+      break;
+   case FC_SQUARE_BOX:
+      DrawLine(buf, val, 0, y_[0], x_[0], y_[0]);
+      DrawLine(buf, val, x_[0], y_[0], x_[0], ys_);
+      break;
+   case FC_CUSTOM:
+      // lines
+      for (j=0; j<(n_-1); j++)
+         DrawLine(buf, val, x_[j], y_[j], x_[j+1], y_[j+1]);
+      // control points
+      for (j=0; j<n_; j++)
+         DrawPoint(buf, val ,x_[j], y_[j]);
+      break;
+   }
+   
+}
+
+void BgCurveSet::DrawPoint(unsigned char* buf, int val, int x, int y)
+{
+   int r, c;
+   int dx, dy;
+   for (dx=-2; dx<=2; dx++)
+   {
+      for (dy=-2; dy<=2; dy++)
+      {
+         c=x+dx;
+         r=y+dy;
+         if ((c>=0) && (c<xs_) && (r>=0) && (r<ys_) && ((abs(dx)+abs(dy))<4))
+            buf[c+r*ys_] = val;
+      }
+   }
+}
+
+void BgCurveSet::DrawLine(unsigned char* buf, int val, int xs, int ys, int xe, int ye)
+{
+   int r, c;
+   double dsx, dsy, dex, dey;
+   if (abs(xs-xe)>abs(ys-ye))
+   {
+      // x scan
+      if (xs > xe)
+      {
+         dsx = xe;
+         dsy = ye;
+         dex = xs;
+         dey = ys;
+      }
+      else 
+      {
+         dex = xe;
+         dey = ye;
+         dsx = xs;
+         dsy = ys;
+      }
+
+      for (c = (int) dsx; c<=(int)dex; c++)
+      {
+         if (c>=0 && c<xs_)
+         {
+            r = bgRound(dey-(dey-dsy)*(dex-c)/(dex-dsx));
+            if (r>=0 && r<ys_)
+            {
+               buf[c+r*xs_] = val;
+               // +/- 1
+               if ((r+1)<ys_) buf[c+(r+1)*xs_] = val;
+               if ((r-1)>=0) buf[c+(r-1)*xs_] = val;
+               // +/- 2
+               if ((r+2)<ys_) buf[c+(r+2)*xs_] = val;
+               if ((r-2)>=0) buf[c+(r-2)*xs_] = val;
+            }
+         }
+      }
+   }
+   else
+   {
+      // y scan
+      if (ys > ye)
+      {
+         dsx = xe;
+         dsy = ye;
+         dex = xs;
+         dey = ys;
+      }
+      else 
+      {
+         dex = xe;
+         dey = ye;
+         dsx = xs;
+         dsy = ys;
+      }
+      
+      // check bounds
+      
+      for (r = (int) dsy; r<=(int) dey; r++)
+      {
+         if (r>=0 && r<ys_)
+         {
+            c = bgRound(dex-(dex-dsx)*(dey-r)/(dey-dsy));
+            if (c>=0 && c<xs_)
+            {
+               buf[c+r*xs_] = val;
+               // +/- 1
+               if ((c+1)<xs_) buf[c+1+r*xs_] = val;
+               if ((c-1)>=0) buf[c-1+r*xs_] = val;
+               // +/- 2
+               if ((c+2)<xs_) buf[c+2+r*xs_] = val;
+               if ((c-2)>=0) buf[c-2+r*xs_] = val;
+            }
+         }
+      }
+   }
+}
+void BgCurveSet::DrawEllipticArc(unsigned char* buf, int val, int x, int y, int w, int h, int sa, int ea)
+{
+   double xc, yc, rx, ry;
+   rx = w/2;
+   ry = h/2;
+   xc = x+rx;
+   yc = y+ry;
+   int r, c;
+
+//   if (rx > ry)
+//   {
+      // x scan
+      for (c = (int) xc; c<=(int) (xc+rx); c++)
+      {
+         if (c>=0 && c<xs_)
+         {
+            r = bgRound(yc-ry*sqrt(1-(c-xc)*(c-xc)/(rx*rx)));
+            if (r>=0 && r<ys_)
+            {
+               buf[c+r*xs_] = val;
+               // +/- 1
+               if ((r+1)<ys_) buf[c+(r+1)*xs_] = val;
+               if ((r-1)>=0) buf[c+(r-1)*xs_] = val;
+               // +/- 2
+               if ((r+2)<ys_) buf[c+(r+2)*xs_] = val;
+               if ((r-2)>=0) buf[c+(r-2)*xs_] = val;
+            }
+         }
+      }
+//   }
+//   else
+//   {
+      // y scan
+      for (r = (int)(yc-ry); r<=(int) yc; r++)
+      {
+         if (r>=0 && r<ys_)
+         {
+            c = bgRound(xc+rx*sqrt(1-(r-yc)*(r-yc)/(ry*ry)));
+            if (c>=0 && c<xs_)
+            {
+               buf[c+r*xs_] = val;
+               // +/- 1
+               if ((c+1)<xs_) buf[c+1+r*xs_] = val;
+               if ((c-1)>=0) buf[c-1+r*xs_] = val;
+               // +/- 2
+               if ((c+2)<xs_) buf[c+2+r*xs_] = val;
+               if ((c-2)>=0) buf[c-2+r*xs_] = val;
+            }
+         }
+      }
+//   }
+}
+
+void BgCurveSet::StartDragging(int x, int y)
+{
+   isDragging_ = 1;
+   int j;
+   switch (type_)
+   {
+   case -1:
+      break;
+   case FC_ELLIPSE:
+      if (abs(x)<3)
+         ltodrag_ = 1;
+      else if (abs(y-ys_)<3)
+         ltodrag_ = 2;
+      else
+         ltodrag_ = 0;
+      break;
+   case FC_VERT_LINE:
+      ltodrag_ = 0;
+      break;
+   case FC_HORIZ_LINE:
+      ltodrag_ = 0;
+      break;
+   case FC_LINE:
+      if (abs(x)<3)
+         ltodrag_ = 1;
+      else if (abs(y-ys_)<3)
+         ltodrag_ = 2;
+      else
+         ltodrag_ = 0;
+      break;
+   case FC_SQUARE_BOX:
+      if (abs((abs(x-x_[0])-abs(y-y_[0])))<3)
+      {
+         // drag corner
+         ltodrag_ = 2;
+      }
+      else if (abs(x-x_[0])>abs(y-y_[0]))
+      {
+         // drag horizontal
+         ltodrag_ = 0;
+      }
+      else
+      {
+         // drag vertical
+         ltodrag_ = 1;
+      }
+      break;
+   case FC_CUSTOM:
+      // find point to drag
+      int mind = abs(x-x_[0]) + abs(y-y_[0]);
+      int cmind, mj;
+      mj = 0;
+      for (j=1; j<n_; j++)
+      {
+         cmind = abs(x-x_[j]) + abs(y-y_[j]);
+         if (cmind < mind)
+         {
+            mind = cmind;
+            mj = j;
+         }
+      }
+      ltodrag_ = mj;
+      break;
+   }
+}
+
+void BgCurveSet::DragTo(int x, int y)
+{
+   if ((x<0) || (y<0) || (x>=xs_) || (y>=ys_))
+      return;
+   double k, ry;
+   switch (type_)
+   {
+   case -1:
+      break;
+   case FC_ELLIPSE:
+      // modify ellipse to drag
+      if (ltodrag_ == 0)
+      {
+         k = ((double)x_[0])/(ys_-y_[0]);
+         ry = sqrt(((double)x*x)/(k*k)+(y-ys_)*(y-ys_));
+         x_[0] = bgRound(k*ry);
+         y_[0] = bgRound(ys_-ry);
+      }
+      else if (ltodrag_ == 1)
+      {
+         y_[0] = y;
+      }
+      else
+      {
+         x_[0] = x;
+      }
+      break;
+   case FC_VERT_LINE:
+      x_[0] = x;
+      break;
+   case FC_HORIZ_LINE:
+      y_[0] = y;
+      break;
+   case FC_LINE:
+      // modify line to drag
+      if (ltodrag_ == 0)
+      {
+         k = ((double) (ys_-y_[0])/x_[0]);
+         y_[0] = ys_-bgRound((double (ys_-y)+k*x));
+         x_[0] = bgRound((double (ys_-y)+k*x)/(k));
+      }
+      else if (ltodrag_ == 1)
+      {
+         y_[0] = y;
+      }
+      else
+      {
+         x_[0] = x;
+      }
+      break;
+   case FC_SQUARE_BOX:
+      if (ltodrag_ == 0)
+         y_[0] = y;
+      else if (ltodrag_ == 1)
+         x_[0] = x;
+      else
+      {
+         x_[0] = x;
+         y_[0] = y;
+      }
+      break;
+   case FC_CUSTOM:
+      // modify line to drag
+      if (ltodrag_ == 0)
+      {
+         y_[0] = y;
+      } else if (ltodrag_ == (n_-1))
+      {
+         x_[n_-1] = x;
+      } else
+      {
+         x_[ltodrag_] = x;
+         y_[ltodrag_] = y;
+      }
+      break;
+   }
+}
+
+void BgCurveSet::EndDragging(int x, int y)
+{
+   isDragging_ = 0;
+}
+
+// ---------------------------------------------------------------------------
+// BgParameterHistory
+// ---------------------------------------------------------------------------
+
+BgParameterHistory::BgParameterHistory( void )
+{
+	params_		= (void *) NULL;
+	listSize_	= 0;
+	next_		= (BgParameterHistory *) NULL;
+}
+
+BgParameterHistory::BgParameterHistory(void *parameters, int itemCount)
+{
+	params_		= parameters;
+	listSize_	= itemCount;
+	next_		= (BgParameterHistory *) NULL;
+}
+
+
+BgParameterHistory::~BgParameterHistory( void )
+{
+	if(params_) delete [] params_;
+}
+
+// ---------------------------------------------------------------------------
+// BgParameterHistoryBox
+// ---------------------------------------------------------------------------
+
+BgParameterHistoryBox::BgParameterHistoryBox(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, int n, long style, const wxValidator& validator, const wxString& name)
+                     : wxComboBox(parent, id, value, pos, size, 0, (wxString*) NULL, style, validator, name)
+{
+	//initialize history list
+	maxCount_		= n;
+	listCount_		= 0;
+	historyList_	= (BgParameterHistory *) NULL;
+
+	//initialize combo box
+	Append("Current");
+	SetSelection(0);
+}
+
+BgParameterHistoryBox::~BgParameterHistoryBox( void )
+{
+	//delete history...
+	BgParameterHistory	*temp;
+	while(historyList_)
+	{
+		temp			= historyList_;
+		historyList_	= historyList_->next_;
+		delete temp;
+	}
+}
+
+void BgParameterHistoryBox::AddParameterList(void *parameters, int itemCount)
+{
+	if(listCount_ < maxCount_)
+	{
+		BgParameterHistory	*newHistory	= new BgParameterHistory(parameters, itemCount);
+		newHistory->next_	= historyList_;
+		historyList_		= newHistory;
+		listCount_++;
+		char str[40];
+		sprintf(str, "Parameter List -%d", listCount_);
+		Append(str);
+	}
+	else
+	{
+		BgParameterHistory	*newHistory	= historyList_;
+		while(newHistory->next_->next_)	newHistory	= newHistory->next_;
+		if(newHistory->next_->params_) delete newHistory->next_->params_;
+		newHistory->next_->params_		= parameters;
+		newHistory->next_->listSize_	= itemCount;
+		newHistory->next_->next_		= historyList_;
+		historyList_					= newHistory->next_;
+		newHistory->next_				= (BgParameterHistory *) NULL;
+	}
+}
+
+void *BgParameterHistoryBox::GetParameterListData(int indexNumber)
+{
+	if(indexNumber < listCount_)
+	{
+		BgParameterHistory	*currentHistory	= historyList_;
+		int count = 0;
+		while(indexNumber != count)
+		{
+			currentHistory	= currentHistory->next_;
+			count++;
+		}
+		return currentHistory->params_;
+	}
+	return (void *) NULL;
+}
+
+int BgParameterHistoryBox::GetParameterListCount(int indexNumber)
+{
+	if(indexNumber < listCount_)
+	{
+		BgParameterHistory	*currentHistory	= historyList_;
+		int count = 0;
+		while(indexNumber != count)
+		{
+			currentHistory	= currentHistory->next_;
+			count++;
+		}
+		return currentHistory->listSize_;
+	}
+	return -1;
+}
+
+void BgParameterHistoryBox::UseParameterList(int indexNumber)
+{
+	if((indexNumber < listCount_) && (indexNumber != 0))
+	{
+		BgParameterHistory	*previousHistory	= historyList_;
+		int count = 0;
+		while(count != indexNumber - 1)
+		{
+			previousHistory	= previousHistory->next_;
+			count++;
+		}
+		BgParameterHistory	*currentHistory		= previousHistory->next_;
+		previousHistory->next_					= currentHistory->next_;
+		currentHistory->next_					= historyList_;
+		historyList_							= currentHistory;
+	}
+	return;
+}
+
+void BgParameterHistoryBox::SetCurrentList(void *parameters, int itemCount)
+{
+	currentList_.params_	= parameters;
+	currentList_.listSize_	= itemCount;
+}
+
+void *BgParameterHistoryBox::GetCurrentListData( void )
+{
+	return currentList_.params_;
+}
+
+int BgParameterHistoryBox::GetCurrentListCount( void )
+{
+	return currentList_.listSize_;
+}
+
+// ---------------------------------------------------------------------------
+// BgText
+// ---------------------------------------------------------------------------
+
+//default constructor
+BgText::BgText(void)
+{
+	text_	= (char *)	NULL;
+	font_	= (wxFont *)	NULL;
+	id_		= 0;
+	x_		= 0;
+	y_		= 0;
+}
+
+//overloaded constructor
+BgText::BgText(int id, char *text, wxFont font, int x, int y)
+{
+	text_		= new char [strlen(text) + 1];
+	strcpy(text_, text);
+	font_		= new wxFont;
+	(*font_)	= font;
+	id_			= id;
+	x_			= x;
+	y_			= y;
+}
+
+//destructor
+BgText::~BgText(void)
+{
+	delete text_;
+	delete font_;
+}
+
+//sets text string
+//pre : text is a character string used to set the text
+//      field of the text object
+//post: the text field of the text object has been set to text
+void BgText::SetText(char *text)
+{
+	if((text_)&&(strlen(text) > strlen(text_)))
+	{
+		delete [] text_;
+		text_	= new char [strlen(text) + 1];
+	}
+	strcpy(text_, text);
+	return;
+}
+
+//sets font of text
+//pre : font specifies the new font of the text object
+//post: the font of the text object has been changed to font
+void BgText::SetFont(wxFont font)
+{
+	if(!font_)	font_	= new wxFont;
+	(*font_)	= font;
+	return;
+}
+
+//sets id of text
+//pre : id is the new id of the text object
+//post: the id of the text object has been set to id
+void BgText::SetId(int id)
+{
+	id_	= id;
+}
+
+//sets plot location of text
+//pre : (x,y) determine the new plot location of the text object
+//post: the plot location of the text object has been set to (x,y)
+void BgText::SetPlotLocation(int x, int y)
+{
+	x_	= x;
+	y_	= y;
+}
+
+// ---------------------------------------------------------------------------
+// BgTextObj
+// ---------------------------------------------------------------------------
+
+//constructor
+BgTextObj::BgTextObj(BgText *text)
+{
+	text_	= new BgText(text->id_, text->text_, *(text->font_), text->x_, text->y_);
+	next_	= NULL;
+}
+
+//destructor
+BgTextObj::~BgTextObj(void)
+{
+	delete text_;
+}
+
+// ---------------------------------------------------------------------------
+// BgTextList
+// ---------------------------------------------------------------------------
+
+// *** public methods *** //
+
+//constructor
+BgTextList::BgTextList(void)
+{
+	head_		= cur_	= (BgTextObj *) NULL;
+	itemcount_	= 0;
+}
+
+//destructor
+BgTextList::~BgTextList(void)
+{
+	cur_ = head_;
+	while(cur_)
+		DeleteText();
+}
+
+//adds text object to list
+//pre : text is a text object to be added to the list
+//post: text has been added to the list
+int BgTextList::AddText(BgText *text)
+{
+	//search for existsing text object
+	int id	= text->id_;
+	cur_	= head_;
+	while((cur_)&&(cur_->text_->id_ != id))
+		cur_ = cur_->next_;
+
+	//if it exists change its contents
+	if(cur_)
+	{
+		BgText *tmp_text	= cur_->text_;
+		tmp_text->SetText(text->text_);
+		tmp_text->SetFont(*(text->font_));
+		tmp_text->SetPlotLocation(text->x_, text->y_);
+	}
+	//otherwise add it to existing list
+	else
+	{
+		BgTextObj	*temp;
+		if((temp = new BgTextObj(text)) == NULL)
+			return 1;
+		
+		temp->next_	= head_;
+		if(head_ == NULL)
+			cur_	= temp;
+		head_		= temp;
+		itemcount_++;
+	}
+
+	return 0;
+}		
+
+//removes text object from list
+//pre : textId is the id of the text to be removed from the
+//      list
+//post: text object having id textId has been removed from the
+//      list if it exists (1 is returned upon error)
+int BgTextList::RemoveText(int textId)
+{
+	cur_ = head_;
+	while((cur_)&&(cur_->text_->id_ != textId))
+		cur_	= cur_->next_;
+
+	if(cur_)
+	{
+		DeleteText();
+		return 0;
+	}
+	else
+		return 1;
+}
+
+//returns text object from text list
+//post: the text object pointed to by cur_ is returned
+BgText	*BgTextList::GetText(void)
+{
+	if(cur_)
+	{
+		BgText	*text;
+		text	= cur_->text_;
+		cur_	= cur_->next_;
+		return text;
+	}
+	else
+		return (BgText *) NULL;
+}
+
+//resets cur_ pointer to head of the list
+void BgTextList::ResetList(void)
+{
+	cur_	= head_;
+}
+
+//returns the number of text objects contained
+//within the list
+//post: count of text objects contained by list is returned
+int	BgTextList::GetTextCount(void)
+{
+	return itemcount_;
+}
+
+// *** private methods ***
+
+//deletes a text object node pointed to
+//by cur_
+//post: text object has been deleted from the text list
+void BgTextList::DeleteText(void)
+{
+	if(cur_ == head_)
+	{
+		head_	= head_->next_;
+		delete cur_;
+		cur_		= head_;
+	}
+	else
+	{
+		BgTextObj	*temp = cur_;
+		cur_	= cur_->next_;
+		if(!cur_)	cur_	= head_;
+		delete temp;
+	}
+}
+
+// ---------------------------------------------------------------------------
+// BgBitmap
+// ---------------------------------------------------------------------------
+
+//default constructor
+BgBitmap::BgBitmap(void)
+{
+	bitmap_		= (wxBitmap *) NULL;
+	location_x_	= location_y_	= 0;
+	id_			= 0;
+}
+
+//overloaded constructor
+BgBitmap::BgBitmap(wxBitmap *bitmap, int id, int location_x, int location_y)
+{
+	bitmap_		= new wxBitmap;
+	(*bitmap_)	= (*bitmap);
+	id_			= id;
+	location_x_	= location_x;
+	location_y_	= location_y;
+}
+
+//destructor
+BgBitmap::~BgBitmap(void)
+{
+	if(bitmap_)	delete bitmap_;
+}
+
+//set bitmap content
+//pre : bitmap is the new bitmap content
+//post: bitmap content has been changed to that of bitmap
+void BgBitmap::SetMap(wxBitmap *bitmap)
+{
+	if(!bitmap_)	bitmap_	= new wxBitmap;
+	(*bitmap_)	= (*bitmap);
+}
+
+//set plot location
+//pre : (location_x, location_y) define new plot location of bitmap
+//post: plot location of bitmap has been set to (location_x, location_y)
+void BgBitmap::SetPlotLocation(int location_x, int location_y)
+{
+	location_x_	= location_x;
+	location_y_	= location_y;
+}
+
+//set bitmap id
+//pre : id is the new bitmap id
+//post: the bitmap id has been set to id
+void BgBitmap::SetId(int id)
+{
+	id_	= id;
+}
+
+// ---------------------------------------------------------------------------
+// BgBitmapObj
+// ---------------------------------------------------------------------------
+
+//default constructor
+BgBitmapObj::BgBitmapObj(void)
+{
+	bitmap_	= (BgBitmap *) NULL;
+	next_	= (BgBitmapObj *) NULL;
+}
+
+//overloaded constructor
+BgBitmapObj::BgBitmapObj(BgBitmap* bitmap)
+{
+	bitmap_	= new BgBitmap(bitmap->bitmap_, bitmap->id_,
+						   bitmap->location_x_, bitmap->location_y_);
+	next_	= (BgBitmapObj *) NULL;
+}
+
+//destructor
+BgBitmapObj::~BgBitmapObj(void)
+{
+	if(bitmap_)	delete bitmap_;
+}
+
+// ---------------------------------------------------------------------------
+// BgBitmap
+// ---------------------------------------------------------------------------
+
+//constructor
+BgBitmapList::BgBitmapList(void)
+{
+	head_		= cur_	= (BgBitmapObj *) NULL;
+	itemcount_	= 0;
+}
+
+//destuctor
+BgBitmapList::~BgBitmapList(void)
+{
+	cur_ = head_;
+	while(cur_)
+		DeleteBitmap();
+}
+
+//add a bitmap object to the list
+//pre : bitmap is a bitmap object to be added to the list
+//post: bitmap has been added to the list
+int BgBitmapList::AddBitmap(BgBitmap *bitmap)
+{
+	BgBitmapObj	*temp;
+	if((temp = new BgBitmapObj(bitmap)) == NULL)
+		return 1;
+
+	temp->next_	= head_;
+	if(head_ == NULL)
+		cur_	= temp;
+	head_		= temp;
+	itemcount_++;
+
+	return 0;
+}		
+
+//remove bitmap from list
+//pre : bitmap is to be removed from list
+//post: bitmap has been removed from the list
+void BgBitmapList::RemoveBitmap(BgBitmap *bitmap)
+{
+	int	id	= bitmap->id_;
+	cur_	= head_;
+	while((cur_)&&(cur_->bitmap_->id_ != id))
+		cur_	= cur_->next_;
+	DeleteBitmap();
+}
+
+//get bitmap from the list pointed to by cur_
+//post: bitmap pointed to by cur_ has been returned
+//      and cur_ has been incremented to the next list
+//      item
+BgBitmap *BgBitmapList::GetBitmap(void)
+{
+	BgBitmap	*temp	= (BgBitmap *)	NULL;
+	if(cur_)
+	{
+		temp	= cur_->bitmap_;
+		cur_	= cur_->next_;
+	}
+
+	return temp;
+}
+
+//reset bitmap list cur_ pointer
+//post: cur_ has been set to the head of the list
+void BgBitmapList::ResetList(void)
+{
+	cur_	= head_;
+}
+
+//get the number of bitmaps stored by list
+//post: bitmap count has been returned
+int BgBitmapList::GetBitmapCount(void)
+{
+	return itemcount_;
+}
+
+//delete bitmap object from list
+//post: bitmap object pointed to by cur has been deleted
+void BgBitmapList::DeleteBitmap(void)
+{
+	if(cur_)
+	{
+		BgBitmapObj	*temp	= cur_;
+		cur_				= cur_->next_;
+		delete temp;
+		itemcount_--;
+	}
+}
+
+// ---------------------------------------------------------------------------
+// BgAxis
+// ---------------------------------------------------------------------------
+
+//default constructor
+BgAxis::BgAxis(void)
+{
+	start_x_	= 0; start_y_	= 0;
+	length_		= 0;
+	ticknum_	= 0;
+	direction_	= 0;
+	start_val_	= 0; stop_val_	= 0;
+	label_		= (BgText *) NULL;
+	rotation_	= 0;
+}
+
+//overloaded constructor
+BgAxis::BgAxis(int start_x, int start_y, int length, int ticknum, int direction, float start_val, float stop_val)
+{
+	start_x_	= start_x;
+	start_y_	= start_y;
+	length_		= length;
+	ticknum_	= ticknum;
+	direction_	= direction;
+	start_val_	= start_val;
+	stop_val_	= stop_val;
+	label_		= (BgText *) NULL;
+	rotation_	= 0;
+}
+
+//destuctor
+BgAxis::~BgAxis(void)
+{
+	if(label_)	delete label_;
+}
+
+//set plotting origin
+//pre : (start_x, start_y) specify the new axis plotting origin
+//post: axis plotting origin has been set to (start_x, start_y)
+void BgAxis::SetPlotOrigin(int start_x, int start_y)
+{
+	start_x_	= start_x;
+	start_y_	= start_y;
+}
+
+//set axis length
+//pre : length specifies the new length of the axis
+//post: the axis lengh has been set to length
+void BgAxis::SetLength(int length)
+{
+	length_		= length;
+}
+
+//set axis tick number
+//pre : ticknum is the new tick number of the axis
+//post: the axis tick number has been set to ticknum
+void BgAxis::SetTicknum(int ticknum)
+{
+	ticknum_	= ticknum;
+}
+
+//set axis boundaries
+//pre : (start_val, stop_val) define the new axis boundaries
+//post: the axis boundaries have been set to (start_val, stop_val)
+void BgAxis::SetBounds(float start_val, float stop_val)
+{
+	start_val_	= start_val;
+	stop_val_	= stop_val;
+}
+
+//add axis label
+//pre : label specifies the axis label
+//post: the axis has been labeled using label
+void BgAxis::Label(BgText *label)
+{
+	if(label_)	delete label_;
+	char *text	= label->text_;
+	int label_length	= 3*strlen(text);
+	//horizontal axis
+	if(direction_ == 0)
+	{
+		label_x_	= start_x_ + length_/2 - label_length;
+		label_y_	= start_y_ + 30;
+	}
+	//vertical axis
+	else
+	{
+		label_x_	= start_x_ - 60;
+		label_y_	= start_y_ - length_/2 + label_length;
+	}
+	label_	= new BgText(label->id_, text, *(label->font_), label_x_, label_y_);
+}
+
+//removes axis label
+//post: the axis label has been removed
+void BgAxis::RemoveLabel(void)
+{
+	if(label_)	delete label_;
+	label_	= (BgText *) NULL;
+}
+
+//sets label rotation
+//pre : rotation specifies clockwise label rotation (rotation = 0
+//      leaves the label parallel to the axis)
+//post: label rotation has been set to rotation
+void BgAxis::SetLabelRotation(int rotation)
+{
+	rotation_	= rotation;
+}
+
+//draw axis object
+//pre : dc is a dc object used to draw onto a window
+//post: the axis has been drawn onto the window using
+//      using the dc object
+void BgAxis::PlotAxis(wxDC *dc)
+{
+	//set tick length
+	int	ticklength = 8;
+
+	//calculate axis ending locations
+	int	end_x	= start_x_ + length_;
+	int	end_y	= start_y_ - length_;
+
+	//define shift in x and y direction
+	int	shift_x	= 5;
+	int	shift_y	= 5;
+
+	//create font
+	wxFont plotFont(7, wxSWISS, wxNORMAL, wxNORMAL, false, "", wxFONTENCODING_DEFAULT);
+
+	//plot axis line
+	//horizontal axis
+	if(direction_ == 0)
+	{
+		//draw axis line
+		dc->DrawLine(start_x_, start_y_, end_x, start_y_);
+		dc->DrawLine(start_x_, start_y_+1, end_x, start_y_+1);
+
+		//draw tick marks
+		int	increment	= length_/ticknum_;
+		if(length_%ticknum_ != 0)	increment++;
+		int	x_location	= start_x_;
+		while(x_location < end_x)
+		{
+			dc->DrawLine(x_location, start_y_, x_location, start_y_+ticklength);
+			dc->DrawLine(x_location+1, start_y_, x_location+1, start_y_+ticklength);
+			x_location	= x_location + increment;
+		}
+		dc->DrawLine(end_x-1, start_y_, end_x-1, start_y_+ticklength);
+		dc->DrawLine(end_x, start_y_, end_x, start_y_+ticklength);
+
+		//draw floating point axis markers
+		x_location	= start_x_ - shift_x;
+		float	marker_x			= start_val_;
+		float	marker_increment	= (stop_val_ - start_val_)/ticknum_;
+		char	marker_str[8];
+		int i	= 0, fixed_y	= start_y_ + 10;
+		char	align[6];
+		if(stop_val_ < 10)
+			strcpy(align, "%4.2f");
+		else
+		{
+			strcpy(align, "%4.0f");
+			x_location	= x_location - shift_x;
+			shift_x		= 2*shift_x;
+		}
+		dc->SetFont(plotFont);
+		for(i = 0; i < ticknum_; i++)
+		{
+			sprintf(marker_str, align, marker_x);
+			dc->DrawText(marker_str, x_location, fixed_y);
+			marker_x	+= marker_increment;
+			x_location	+= increment;
+		}
+		sprintf(marker_str, align, marker_x);
+		dc->DrawText(marker_str, end_x - shift_x, fixed_y);
+
+		//add label
+		if(label_)
+		{
+			dc->SetFont(*(label_->font_));
+			dc->DrawRotatedText(label_->text_, label_x_, label_y_, 0+rotation_);
+		}
+	}
+	//vertical axis
+	else
+	{
+		//draw axis line
+		dc->DrawLine(start_x_, start_y_, start_x_, end_y);
+		dc->DrawLine(start_x_-1, start_y_, start_x_-1, end_y);
+
+		//draw tick marks
+		int	increment	= length_/ticknum_;
+		if(length_%ticknum_ != 0)	increment++;
+		int	y_location	= end_y;
+		while(y_location < start_y_)
+		{
+			dc->DrawLine(start_x_, y_location, start_x_-ticklength, y_location);
+			dc->DrawLine(start_x_, y_location+1, start_x_-ticklength, y_location+1);
+			y_location	= y_location + increment;
+		}
+		dc->DrawLine(start_x_, start_y_, start_x_-ticklength, start_y_);
+		dc->DrawLine(start_x_, start_y_+1, start_x_-ticklength, start_y_+1);
+
+		//draw floating point axis markers
+		y_location	= start_y_;
+		float	marker_y			= start_val_;
+		float	marker_increment	= (stop_val_ - start_val_)/ticknum_;
+		char	marker_str[8];
+		int i	= 0, fixed_x = start_x_ - 30;
+		char	align[6];
+		if(stop_val_ < 10)
+			strcpy(align, "%4.2f");
+		else
+			strcpy(align, "%4.0f");
+		dc->SetFont(plotFont);
+		sprintf(marker_str, align, marker_y);
+		dc->DrawText(marker_str, fixed_x, y_location - shift_y);
+		marker_y	+= marker_increment;
+		y_location	-= increment;
+		for(i = 1; i < ticknum_; i++)
+		{
+			sprintf(marker_str, align, marker_y);
+			dc->DrawText(marker_str, fixed_x, y_location);
+			marker_y	+= marker_increment;
+			y_location	-= increment;
+		}
+		sprintf(marker_str, align, marker_y);
+		dc->DrawText(marker_str, fixed_x, end_y - shift_y);
+
+		//add label
+		if(label_)
+		{
+			dc->SetFont(*(label_->font_));
+			dc->DrawRotatedText(label_->text_, label_x_, label_y_, 90+rotation_);
+		}
+	}
+}
+
+// ---------------------------------------------------------------------------
+// BgThread
+// ---------------------------------------------------------------------------
+
+BgThread::BgThread(wxThreadKind kind, void foo(void*), void *Object) : wxThread(kind)
+{
+	function_	= foo;
+	Object_		= Object;
+}
+
+BgThread::~BgThread( void )
+{
+	function_	= NULL;
+	Object_		= NULL;
+}
+
+void *BgThread::Entry( void )
+{
+	function_(Object_);
+	return (void *) NULL;
+}
+
+// ---------------------------------------------------------------------------
+// BgDialog
+// ---------------------------------------------------------------------------
+
+BgDialog::BgDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
+		: wxDialog(parent, id, title, pos, size, style, name)
+{
+	
+	okButton_	= new wxButton(this, BG_DIALOG_OK, "OK", wxPoint(size.GetWidth()/2-40, size.GetHeight()-60));
+}
+
+BgDialog::~BgDialog( void )
+{
+	delete okButton_;
+}
+
+void BgDialog::AddText(BgText *text)
+{
+	tlist_.AddText(text);
+}
+
+void BgDialog::AddBitmap(BgBitmap *bitmap)
+{
+	blist_.AddBitmap(bitmap);
+}
+
+void BgDialog::RemoveText(int id)
+{
+	tlist_.RemoveText(id);
+}
+
+void BgDialog::RemoveBitmap(BgBitmap *bitmap)
+{
+	blist_.RemoveBitmap(bitmap);
+}
+
+void BgDialog::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+
+	wxPaintDC	dc(this);
+
+	//draw new text to the image from text object list
+	BgText	*bgText;
+	tlist_.ResetList();
+	while(bgText = tlist_.GetText())
+	{
+		dc.SetFont(*(bgText->font_));
+		dc.DrawText(bgText->text_, bgText->x_, bgText->y_);
+	}
+
+	//draw bitmaps
+	blist_.ResetList();
+	BgBitmap	*bitmap;
+	while(bitmap = blist_.GetBitmap())
+		dc.DrawBitmap(*(bitmap->bitmap_), bitmap->location_x_, bitmap->location_y_, true);
+
+}
+
+void BgDialog::OnExit(wxCommandEvent& WXUNUSED(event))
+{
+	EndModal(wxID_OK);
+}
+
+// ---------------------------------------------------------------------------
+// BgHoverBar
+// ---------------------------------------------------------------------------
+
+BgHoverBar::BgHoverBar(wxWindow* parent, wxWindowID id, int gradViewId, int confViewId, int weitViewId, int custViewId, int gradSaveId, int confSaveId, int weitSaveId)
+		  : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER)
+{
+	//set the size of the window
+	SetSize(120,30);
+
+	//place a button using a bitmap
+	menuButton1_	= new wxBitmapButton(this, BG_CANVAS_VIEW_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(33,2), wxSize(18,20));
+	menuButton2_	= new wxBitmapButton(this, BG_CANVAS_SAVE_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(92,2), wxSize(18,20));
+	menuText1_		= new wxStaticText(this, -1, "View", wxPoint(5,5), wxSize(25,20));
+	menuText2_		= new wxStaticText(this, -1, "Save", wxPoint(62,5), wxSize(25,20));
+
+	//get view menu identification constants
+	gradViewId_	= gradViewId;
+	confViewId_	= confViewId;
+	weitViewId_	= weitViewId;
+	custViewId_	= custViewId;
+	gradSaveId_	= gradSaveId;
+	confSaveId_	= confSaveId;
+	weitSaveId_	= weitSaveId;
+
+	//create view menu
+	view_menu = new wxMenu;
+	view_menu->Append(gradViewId_, "&Gradient Map", "", true);
+	view_menu->Append(confViewId_, "&Confidence Map", "", true);
+	view_menu->Append(weitViewId_, "&Weight Map", "", true);
+	view_menu->Append(custViewId_, "C&ustom Weight Map", "", true);
+
+	//create save menu
+	save_menu = new wxMenu;
+	save_menu->Append(gradSaveId_, "&Gradient Map");
+	save_menu->Append(confSaveId_, "&Confidence Map");
+	save_menu->Append(weitSaveId_, "&Weight Map");
+
+}
+
+BgHoverBar::~BgHoverBar( void )
+{
+	//de-allocate menus...
+	delete view_menu;
+	delete save_menu;
+}
+
+void BgHoverBar::ShowMenu(wxCommandEvent& event)
+{
+	int buttonId	= event.GetId();
+	if(buttonId	== BG_CANVAS_VIEW_BUTTON)
+	{
+		menuText1_->SetForegroundColour(wxColour(0,0,100));
+		menuText2_->SetForegroundColour(wxColour(0,0,0));
+		menuText1_->Refresh();
+		menuText2_->Refresh();
+		PopupMenu(view_menu, 0, 26);
+	}
+	else
+	{
+		menuText1_->SetForegroundColour(wxColour(0,0,0));
+		menuText2_->SetForegroundColour(wxColour(0,0,100));
+		menuText1_->Refresh();
+		menuText2_->Refresh();
+		PopupMenu(save_menu, 0, 26);
+	}
+	Update();
+}
+
+void BgHoverBar::CheckViewItem(long viewItemId)
+{
+	view_menu->Check(gradViewId_, false);
+	view_menu->Check(confViewId_, false);
+	view_menu->Check(weitViewId_, false);
+	view_menu->Check(custViewId_, false);
+	view_menu->Check(viewItemId, true);
+}
+
+void BgHoverBar::Update( void )
+{
+	menuText1_->SetForegroundColour(wxColour(0,0,0));
+	menuText2_->SetForegroundColour(wxColour(0,0,0));
+	menuText1_->Refresh();
+	menuText2_->Refresh();
+}
+
+// ---------------------------------------------------------------------------
+// BgMenuPanel
+// ---------------------------------------------------------------------------
+
+BgMenuPanel::BgMenuPanel(wxWindow* parent, wxWindowID id, int gradViewId, int confViewId, int weitViewId, int custViewId, int gradSaveId, int confSaveId, int weitSaveId)
+		   : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize)
+{
+	//keep pointer to scroll window
+	scrollWindow_	= (wxWindow *) NULL;
+
+	//set the position and size of the window
+	SetSize(0,0,120,30);
+
+	//place a button using a bitmap
+	menuButton1_	= new wxBitmapButton(this, BG_CANVAS_VIEW_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(33,2), wxSize(18,20));
+	menuButton2_	= new wxBitmapButton(this, BG_CANVAS_SAVE_BUTTON, wxBitmap("down_arrow", wxBITMAP_TYPE_RESOURCE), wxPoint(92,2), wxSize(18,20));
+	menuText1_		= new wxStaticText(this, -1, "View", wxPoint(5,5), wxSize(25,20));
+	menuText2_		= new wxStaticText(this, -1, "Save", wxPoint(62,5), wxSize(25,20));
+
+	//get view menu identification constants
+	gradViewId_	= gradViewId;
+	confViewId_	= confViewId;
+	weitViewId_	= weitViewId;
+	custViewId_	= custViewId;
+	gradSaveId_	= gradSaveId;
+	confSaveId_	= confSaveId;
+	weitSaveId_	= weitSaveId;
+
+	//create view menu
+	view_menu = new wxMenu;
+	view_menu->Append(gradViewId_, "&Gradient Map", "", true);
+	view_menu->Append(confViewId_, "&Confidence Map", "", true);
+	view_menu->Append(weitViewId_, "&Weight Map", "", true);
+	view_menu->Append(custViewId_, "C&ustom Weight Map", "", true);
+
+	//create save menu
+	save_menu = new wxMenu;
+	save_menu->Append(gradSaveId_, "&Gradient Map");
+	save_menu->Append(confSaveId_, "&Confidence Map");
+	save_menu->Append(weitSaveId_, "&Weight Map");
+
+}
+
+BgMenuPanel::~BgMenuPanel( void )
+{
+	//de-allocate menus...
+	delete view_menu;
+	delete save_menu;
+}
+
+void BgMenuPanel::ShowMenu(wxCommandEvent& event)
+{
+	int buttonId	= event.GetId();
+	if(buttonId	== BG_CANVAS_VIEW_BUTTON)
+	{
+		menuText1_->SetForegroundColour(wxColour(0,0,200));
+		menuText2_->SetForegroundColour(wxColour(0,0,0));
+		menuText1_->Refresh();
+		menuText2_->Refresh();
+		PopupMenu(view_menu, 0, 26);
+	}
+	else
+	{
+		menuText1_->SetForegroundColour(wxColour(0,0,0));
+		menuText2_->SetForegroundColour(wxColour(0,0,200));
+		menuText1_->Refresh();
+		menuText2_->Refresh();
+		PopupMenu(save_menu, 0, 26);
+	}
+	Update();
+}
+
+void BgMenuPanel::CheckViewItem(long viewItemId)
+{
+	view_menu->Check(gradViewId_, false);
+	view_menu->Check(confViewId_, false);
+	view_menu->Check(weitViewId_, false);
+	view_menu->Check(custViewId_, false);
+	view_menu->Check(viewItemId, true);
+}
+
+void BgMenuPanel::Update( void )
+{
+	menuText1_->SetForegroundColour(wxColour(0,0,0));
+	menuText2_->SetForegroundColour(wxColour(0,0,0));
+	menuText1_->Refresh();
+	menuText2_->Refresh();
+}
+
+void BgMenuPanel::EnableMenu(bool enable)
+{
+	menuText1_->Enable(enable);
+	menuText2_->Enable(enable);
+	menuButton1_->Enable(enable);
+	menuButton2_->Enable(enable);
+}
+
+//adjusts size of scroll window
+void BgMenuPanel::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+	if(scrollWindow_)
+	{
+		int w, h;
+		GetClientSize(&w, &h);
+		scrollWindow_->SetSize(0,PLOT_MENU_HEIGHT,w,h-PLOT_MENU_HEIGHT);
+	}
+}
+
+void BgMenuPanel::SetScrollWindow(wxWindow *scrollwindow)
+{
+	scrollWindow_	= scrollwindow;
+}
+
+// ---------------------------------------------------------------------------
+// BgLineSet
+// ---------------------------------------------------------------------------
+
+BgLineSet::BgLineSet()
+{
+   xs_ = ys_ = xe_ = ye_ = 0;
+   lineParam_ = 0;
+   n_ = 0;
+   pen_.SetColour(*wxRED);
+   //pen_.SetColour(*wxWHITE);
+   pen_.SetWidth(2);
+   pen_.SetStyle(wxSOLID);
+}
+
+BgLineSet::~BgLineSet()
+{
+   CleanData();
+}
+
+void BgLineSet::CleanData()
+{
+   if (n_ > 0)
+   {
+      delete [] xs_;
+      delete [] xe_;
+      delete [] ys_;
+      delete [] ye_;
+      delete [] lineParam_;
+      xs_ = ys_ = xe_ = ye_ = 0;
+      lineParam_ = 0;
+      n_ = 0;
+   }
+}
+
+void BgLineSet::SetLines(int* xs, int* xe, int* ys, int* ye, double* lineParam, int n)
+{
+   CleanData();
+   n_ = n;
+   xs_ = new int[n_];
+   xe_ = new int[n_];
+   ys_ = new int[n_];
+   ye_ = new int[n_];
+   lineParam_ = new double[n_*3];
+   int i;
+   for (i=0; i<n; i++)
+   {
+      xs_[i] = xs[i];
+      ys_[i] = ys[i];
+      xe_[i] = xe[i];
+      ye_[i] = ye[i];
+   }
+   for (i=0; i<(3*n); i++)
+      lineParam_[i] = lineParam[i];
+}
+
+void BgLineSet::SetLines(double* startp, double* endp, double* lineParam, int n)
+{
+   CleanData();
+   n_ = n;
+   xs_ = new int[n_];
+   xe_ = new int[n_];
+   ys_ = new int[n_];
+   ye_ = new int[n_];
+   lineParam_ = new double[n_*3];
+   int i;
+   for (i=0; i<n; i++)
+   {
+      xs_[i] = (int) startp[2*i];
+      ys_[i] = (int) startp[2*i+1];
+      xe_[i] = (int) endp[2*i];
+      ye_[i] = (int) endp[2*i+1];
+   }
+   for (i=0; i<(3*n); i++)
+      lineParam_[i] = lineParam[i];
+}
+
+// ---------------------------------------------------------------------------
+// BgImCanvas
+// ---------------------------------------------------------------------------
+
+// Define a constructor for my canvas
+BgImCanvas::BgImCanvas(wxWindow *child_frame, wxWindow *parent, const wxPoint& pos, const wxSize& size)
+: wxScrolledWindow(parent, -1, pos, size,
+                   wxSIMPLE_BORDER|wxVSCROLL|wxHSCROLL)
+{
+   SetBackgroundColour(wxColour("WHITE"));
+   pbitmap=(wxBitmap*) NULL;
+   pimage=(wxImage*) NULL;
+   hasbitmap=FALSE;
+   showbitmap_ = TRUE;
+   m_dirty = FALSE;
+   nLineSets_ = nPointSets_ = 0;
+
+   //set pointer to child frame (e.g. used to update window title)
+   child_frame_	= child_frame;
+
+   // clickable curve stuff
+   nCurveSets_ = 0;
+   ccx_ = RANK_CONF_IMSIZEX;
+   ccy_ = RANK_CONF_IMSIZEY;
+   curveClick_ = new unsigned char[ccx_*ccy_];
+   isDragging_ = 0;
+   FillCurveClick();
+   mouseModif_ = 0;
+   crossCursor_ = 0;
+   showtrack_ = 0;
+
+   //initialize window events
+   has_focus		= false;
+   leaving			= false;
+
+   //initialize plotting canvas
+   x_offset_		= 0;
+   y_offset_		= 0;
+   textObjectCount_	= 0;
+   xAxis			= (BgAxis *) NULL;
+   yAxis			= (BgAxis *) NULL;
+   clear_display_	= false;
+
+   //initializing zooming parameters
+   zoom_in			= false;
+   zoom_out			= false;
+   zoom_window		= false;
+   zoom_level		= 1;
+
+   //initialize empty zoom box and refresh box
+   zoombox			= (wxImage  *) NULL;
+   refresh_box		= (wxImage  *) NULL;
+
+   //initialize point map
+   point_map		= NULL;
+   point_colour		= (wxColour *) NULL;
+
+   //initialize zoomed image buffer
+   zImg				= NULL;
+
+   //initialize zoom window corner
+   cx				= 0;
+   cy				= 0;
+
+   //initialize mouse pointer location
+   m_x_	= 0;
+   m_y_	= 0;
+
+   //initialize zoom buffers
+   buf	= (unsigned char *) NULL;
+
+   //initialize hover window such that
+   //it does not popup
+   popup	= 0;
+
+   //initialize hover window
+   menuWindow	= (wxWindow *) NULL;
+
+   //pay attention to updates
+   noUpdate_	= false;
+
+   //construct zoom cursors
+   //??????????????????????????????
+   wxString str;
+   str.Printf(wxT("icon10"));
+   bgCURSOR_MAGNIFIER_PLUS	= new wxCursor(str, wxBITMAP_TYPE_CUR_RESOURCE);
+   //bgCURSOR_MAGNIFIER_PLUS	= new wxCursor("icon10", wxBITMAP_TYPE_RESOURCE, 0, 0);
+   str.Printf(wxT("icon11"));
+   bgCURSOR_MAGNIFIER_MINUS	= new wxCursor(str, wxBITMAP_TYPE_CUR_RESOURCE);
+   //bgCURSOR_MAGNIFIER_MINUS	= new wxCursor("icon11", wxBITMAP_TYPE_RESOURCE, 0, 0);
+
+   //build local menu
+   localMenu_ = new wxMenu();
+   localMenu_->Append(BG_IMC_ADDNODE,"Add node");
+   localMenu_->Append(BG_IMC_DELETENODE,"Delete node");
+   localMenu_->AppendSeparator();
+   localMenu_->Append(BG_IMC_SELTYPE_ELLIPSE,"Arc");
+   localMenu_->Append(BG_IMC_SELTYPE_VLINE,"Vertical line");
+   localMenu_->Append(BG_IMC_SELTYPE_HLINE,"Horizontal line");
+   localMenu_->Append(BG_IMC_SELTYPE_LINE,"Line");
+   localMenu_->Append(BG_IMC_SELTYPE_BOX,"Box");
+   localMenu_->Append(BG_IMC_SELTYPE_CUSTOM,"Custom");
+}
+
+BgImCanvas::~BgImCanvas()
+{
+   ClearData();
+   if(xAxis)	delete xAxis;
+   if(yAxis)	delete yAxis;
+   delete [] curveClick_;
+   delete localMenu_;
+   delete bgCURSOR_MAGNIFIER_PLUS;
+   delete bgCURSOR_MAGNIFIER_MINUS;
+}
+
+void BgImCanvas::OnCustomAddNode(wxCommandEvent& WXUNUSED(event))
+{
+   if ((lmEventCurve_ < 0) || (lmEventCurve_ >= nCurveSets_) ||
+      (curveSet_[lmEventCurve_]->type_!=FC_CUSTOM))
+   {
+      return;
+   }
+   int n, type;
+   n = curveSet_[lmEventCurve_]->n_;
+   double *tx, *ty;
+   tx = new double[n+1];
+   ty = new double[n+1];
+   curveSet_[lmEventCurve_]->GetParamCurve(tx, ty, type, n);
+   double x, y;
+   x = ((double) lmEventX_)/ccx_;
+   y = (ccy_ - ((double) lmEventY_))/ccy_;
+
+   // determine closest line
+   double cx, cy, cr, ax, ay, dx, dy;
+   double mny = 10;
+   int ci = -1;
+   int i;
+   for (i=0; i<(n-1); i++)
+   {
+      cx = tx[i+1]-tx[i];
+      cy = ty[i+1]-ty[i];
+      cr = sqrt(cx*cx+cy*cy);
+      if (cr <= 0)
+         continue;
+      ax = x-tx[i];
+      ay = y-ty[i];
+      dx = (cx*ax+cy*ay)/cr;
+      dy = fabs((-cy*ax+cx*ay)/cr);
+      if ((dx>=0) && (dx<=cr))
+      {
+         if (dy<mny)
+         {
+            mny = dy;
+            ci = i;
+         }
+      }
+   }
+   if (ci >= 0)
+   {
+      // modify curve
+      for (i=n; i>ci; i--)
+      {
+         tx[i] = tx[i-1];
+         ty[i] = ty[i-1];
+      }
+      tx[ci+1] = x;
+      ty[ci+1] = y;
+      curveSet_[lmEventCurve_]->SetParamCurve(type, tx, ty, n+1, ccx_, ccy_);
+   }
+      
+   delete [] ty;
+   delete [] tx;
+   mouseModif_ = 1;
+   AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+
+   FillCurveClick();
+   return;
+}
+void BgImCanvas::OnCustomDeleteNode(wxCommandEvent& WXUNUSED(event))
+{
+   if ((lmEventCurve_ < 0) || (lmEventCurve_ >= nCurveSets_) || 
+      (lmEventNode_ < 0) || (lmEventNode_ >= (curveSet_[lmEventCurve_]->n_-1)))
+   {
+      return;
+   }
+   if (lmEventNode_ == 0)
+   {
+      bgLog("Cannot delete first node.\n");
+      return;
+   }
+   if (lmEventNode_ == (curveSet_[lmEventCurve_]->n_-1))
+   {
+      bgLog("Cannot delete last node.\n");
+      return;
+   }
+   // delete the node
+   int i;
+   int n = curveSet_[lmEventCurve_]->n_;
+   int *tx, *ty;
+   tx = curveSet_[lmEventCurve_]->x_;
+   ty = curveSet_[lmEventCurve_]->y_;
+   for (i=lmEventNode_; i<(n-1); i++)
+   {
+      tx[i] = tx[i+1];
+      ty[i] = ty[i+1];
+   }
+   curveSet_[lmEventCurve_]->n_ = n-1;
+   mouseModif_ = 1;
+   AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+   FillCurveClick();
+   return;
+}
+void BgImCanvas::OnCTypeEllipse(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+      {
+         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
+         curveSet_[lmEventCurve_]->n_ = 1;
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_ELLIPSE;
+      FillCurveClick();
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+   }
+}
+void BgImCanvas::OnCTypeVLine(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+      {
+         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
+         curveSet_[lmEventCurve_]->n_ = 1;
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_VERT_LINE;
+      FillCurveClick();
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+   }
+}
+void BgImCanvas::OnCTypeHLine(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+      {
+         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
+         curveSet_[lmEventCurve_]->n_ = 1;
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_HORIZ_LINE;
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+      FillCurveClick();
+   }
+}
+void BgImCanvas::OnCTypeLine(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+      {
+         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
+         curveSet_[lmEventCurve_]->n_ = 1;
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_LINE;
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+      FillCurveClick();
+   }
+}
+void BgImCanvas::OnCTypeBox(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+      {
+         curveSet_[lmEventCurve_]->x_[0] = curveSet_[lmEventCurve_]->x_[curveSet_[lmEventCurve_]->n_-1];
+         curveSet_[lmEventCurve_]->n_ = 1;
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_SQUARE_BOX;
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+      FillCurveClick();
+   }
+}
+void BgImCanvas::OnCTypeCustom(wxCommandEvent& WXUNUSED(event))
+{
+   if (lmEventCurve_ < nCurveSets_)
+   {
+      if (curveSet_[lmEventCurve_]->type_ != FC_CUSTOM)
+      {
+         double x[3];
+         double y[3];
+         int n,type;
+         curveSet_[lmEventCurve_]->GetParamCurve(x,y,type,n);
+         n = 3;
+         type = FC_CUSTOM;
+         x[2] = x[0];
+         x[0] = 0;
+         y[2] = 0;
+         x[2] = (x[2]>1) ? 1:x[2];
+         x[2] = (x[2]<0) ? 0:x[2];
+         y[0] = (y[0]>1) ? 1:y[0];
+         y[0] = (y[0]<0) ? 0:y[0];
+         x[1] = (x[0]+x[2])*2.0/3.0;
+         y[1] = (y[0]+y[2])*2.0/3.0;
+         curveSet_[lmEventCurve_]->SetParamCurve(type, x, y, n, ccx_, ccy_);
+      }
+      curveSet_[lmEventCurve_]->type_ = FC_CUSTOM;
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+      FillCurveClick();
+   }
+}
+
+void BgImCanvas::AddPointSet(BgPointSet* ps)
+{
+   pointSet_[nPointSets_++] = ps;
+
+   //update point map if the point set consists
+   //of data points (not circles)
+   if((ps->type_	== 1)&&(hasbitmap))
+   {
+	   int nt, *tx, *ty;
+	   nt = ps->n_;
+	   tx = ps->x_;
+	   ty = ps->y_;
+	   int i, dp, width = pimage->GetWidth();
+	   for(i=0; i<nt; i++)
+	   {
+		   dp				= ty[i]*width+tx[i];
+		   point_map[dp]	= true;
+	   }
+   }
+
+   //define new pen colour is yet defined, define it
+   if(point_colour)	delete point_colour;
+   point_colour	= new wxColour(ps->pen_.GetColour());
+
+   //add point data to zoomed image (if it has been defined,
+   //i.e. an image has been loaded into the image canvas)
+   if(zImg)	AddPoints(zImg, ((pimage->GetWidth())*zoom_level));
+
+   Refresh();
+}
+
+void BgImCanvas::RemovePointSet(BgPointSet* ps)
+{
+   int i = 0;
+   while (i<nPointSets_ && pointSet_[i]!=ps)
+      i++;
+   if (i<nPointSets_)
+   {
+      i++;
+      while(i<nPointSets_)
+      {
+         pointSet_[i-1] = pointSet_[i];
+         i++;
+      }
+      nPointSets_--;
+   }
+
+   //adjust point map accordingly
+   if((point_map)&&(ps->type_	== 1))	//point
+   {
+	   int width = pimage->GetWidth();
+	   int nt, *tx, *ty;
+	   nt	= ps->n_;
+	   tx	= ps->x_;
+	   ty	= ps->y_;
+	   for(i=0; i<nt; i++)
+		   point_map[ty[i]*width+tx[i]] = false;
+   }
+
+   //delete pen colour if no more point sets exist
+   if(nPointSets_ == 0)
+   {
+	   delete point_colour;
+	   point_colour	= (wxColour *) NULL;
+   }
+
+   //remove this point set from the zoomed image...
+
+   /*********************************************************/
+
+   if(zImg)
+   {
+	   delete [] zImg;
+	   int width, height;
+	   width	= (pimage->GetWidth())*zoom_level;
+	   height	= (pimage->GetHeight())*zoom_level;
+	   zImg		= new unsigned char [3*width*height];
+	   if(zoom_level > 1)
+		   bgZoomIn(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), zoom_level, false);
+	   else if(zoom_level == 1)
+		   memcpy(zImg, pimage->GetData(), 3*width*height*sizeof(unsigned char));
+
+	   //add any other point sets that may exist
+	   AddPoints(zImg, width);
+   }
+
+   /*********************************************************/
+
+   Refresh(false);
+
+}
+
+void BgImCanvas::AddLineSet(BgLineSet* ls)
+{
+   lineSet_[nLineSets_++] = ls;
+   Refresh();
+}
+
+void BgImCanvas::AddTrackSet(int x, int y, int hx, int hy)
+{
+   trackval_[0] = x;
+   trackval_[1] = y;
+   hx_ = hx;
+   hy_ = hy;
+   showtrack_ = 1;
+   Refresh();
+
+}
+
+void BgImCanvas::RemoveTrackSet()
+{
+   showtrack_ = 0;
+   Refresh();
+}
+   
+
+void BgImCanvas::RemoveLineSet(BgLineSet* ls)
+{
+   int i = 0;
+   while (i<nLineSets_ && lineSet_[i]!=ls)
+      i++;
+   if (i<nLineSets_)
+   {
+      i++;
+      while(i<nLineSets_)
+      {
+         lineSet_[i-1] = lineSet_[i];
+         i++;
+      }
+      nLineSets_--;
+   }
+   Refresh();
+}
+
+void BgImCanvas::AddCurveSet(BgCurveSet* cs)
+{
+   curveSet_[nCurveSets_++] = cs;
+   Refresh();
+}
+
+void BgImCanvas::RemoveCurveSet(BgCurveSet* cs)
+{
+   int i = 0;
+   while (i<nCurveSets_ && curveSet_[i]!=cs)
+      i++;
+   if (i<nCurveSets_)
+   {
+      i++;
+      while(i<nCurveSets_)
+      {
+         curveSet_[i-1] = curveSet_[i];
+         i++;
+      }
+      nCurveSets_--;
+   }
+   Refresh();
+}
+
+//adds text object to be dran to the image
+//pre : bgText is the text object to be plotted
+//post: bgText has been added to the image
+void BgImCanvas::AddText(BgText *bgText)
+{
+	//add text to text list
+	if(tlist_.AddText(bgText))
+	{
+		bgLog("BgImCanvas::AddText Error: Out of memory.\n");
+		return;
+	}
+
+	//obtain new text object count
+	textObjectCount_	= tlist_.GetTextCount();
+}
+
+//clears all text object from text list
+void BgImCanvas::RemoveText(int text_id)
+{
+	tlist_.RemoveText(text_id);
+	return;
+}
+
+//adds horizontal axis
+void BgImCanvas::AddHorizontalAxis(int start_x, int start_y, int length, int ticknum, float start_val, float stop_val)
+{
+	if(xAxis)	delete xAxis;
+	xAxis	= new BgAxis(start_x, start_y, length, ticknum, 0, start_val, stop_val);
+}
+
+//adds horizontal axis
+void BgImCanvas::AddVerticalAxis(int start_x, int start_y, int length, int ticknum, float start_val, float stop_val)
+{
+	if(yAxis)	delete yAxis;
+	yAxis	= new BgAxis(start_x, start_y, length, ticknum, 1, start_val, stop_val);
+}
+
+//clears axis
+void BgImCanvas::ClearAxis( void )
+{
+	if(xAxis)	delete xAxis;
+	if(yAxis)	delete yAxis;
+	xAxis	= yAxis	= (BgAxis *) NULL;
+}
+
+//labels horizontal axis
+void BgImCanvas::LabelHorizontalAxis(BgText *bgText)
+{
+	if(xAxis)	xAxis->Label(bgText);
+}
+
+//labels vertical axis
+void BgImCanvas::LabelVerticalAxis(BgText *bgText)
+{
+	if(yAxis)	yAxis->Label(bgText);
+}
+
+//removes label on horizontal axis
+void BgImCanvas::RemoveHorizontalAxisLabel(void)
+{
+	if(xAxis)	xAxis->RemoveLabel();
+}
+
+//removes lable on vertical axis
+void BgImCanvas::RemoveVerticalAxisLabel(void)
+{
+	if(yAxis)	yAxis->RemoveLabel();
+}
+
+//rotates horizontal axis label clockwise from default position
+void BgImCanvas::RotateHorizontalAxisLabel(int rotation)
+{
+	if(xAxis)	xAxis->SetLabelRotation(rotation);
+}
+
+//rotates vertical axis label clockwise from default position
+void BgImCanvas::RotateVerticalAxisLabel(int rotation)
+{
+	if(yAxis)	yAxis->SetLabelRotation(rotation);
+}
+
+//plot bitmap at specified location
+void BgImCanvas::AddBitmap(BgBitmap *bitmap)
+{
+	blist_.AddBitmap(bitmap);
+}
+
+//remove bitmap from plot
+void BgImCanvas::RemoveBitmap(BgBitmap *bitmap)
+{
+	blist_.RemoveBitmap(bitmap);
+}
+
+//clears display
+void BgImCanvas::ClearDisplay(void)
+{
+	clear_display_	= true;
+	Refresh();
+}
+
+void BgImCanvas::ClearData(int refresh)
+{
+   if(hasbitmap==TRUE) {
+      delete pbitmap;
+      delete pimage;
+   }
+   if(zoombox)			delete zoombox;
+   if(refresh_box)		delete refresh_box;
+   if(zImg)				delete zImg;
+   if(point_map)		delete [] point_map;
+   if(buf)				delete [] buf;
+   hasbitmap=FALSE;
+   pbitmap=(wxBitmap*) NULL;
+   pimage=(wxImage*) NULL;
+   zoombox=(wxImage*) NULL;
+   refresh_box=(wxImage*) NULL;
+   zImg=NULL;
+   point_map=NULL;
+   showtrack_ = 0;
+   if (refresh > 0)
+      Refresh();
+}
+
+int BgImCanvas::SetImage(wxString imname)
+{
+   ClearData();
+   pimage=new wxImage();
+   if (!pimage->LoadFile(imname))
+   {
+      delete pimage;
+      wxLogError("Can't load image "+imname);
+      return 0;
+   }
+   else
+   {
+      SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
+#if wxCHECK_VERSION(2, 3, 0)
+      pbitmap = new wxBitmap(pimage);
+#else
+      pbitmap = new wxBitmap(pimage->ConvertToBitmap());
+#endif
+      hasbitmap=TRUE;
+      m_dirty=TRUE;
+
+	  //create point map
+	  CreatePointMap(pimage->GetWidth(), pimage->GetHeight());
+
+	  //take account for zoom (takes care of refresh)
+	  Zoom(zoom_level);
+   }
+   return 1;
+}
+
+void BgImCanvas::SetImage(wxImage& image)
+{
+   ClearData();
+   pimage=new wxImage();
+   *pimage = image;
+   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
+   
+#if wxCHECK_VERSION(2, 3, 0)
+      pbitmap = new wxBitmap(pimage);
+#else
+      pbitmap = new wxBitmap(pimage->ConvertToBitmap());
+#endif
+   hasbitmap=TRUE;
+   m_dirty=TRUE;
+
+   //create point map
+   CreatePointMap(image.GetWidth(), image.GetHeight());
+
+   //take account for zoom (takes care of refresh)
+   Zoom(zoom_level);
+   
+}
+
+void BgImCanvas::SetSameImage(wxImage& image)
+{
+   *pimage = image;
+#if wxCHECK_VERSION(2, 3, 0)
+   *pbitmap = wxBitmap(image);
+#else
+   *pbitmap = image.ConvertToBitmap();
+#endif
+
+   //create point map
+   CreatePointMap(image.GetWidth(), image.GetHeight());
+
+   //take account for zoom (takes care of refresh)
+   Zoom(zoom_level);
+}
+
+void BgImCanvas::SetImageFromGray(unsigned char* data, int w, int h)
+{
+   ClearData();
+   
+   pimage = new wxImage(w, h);
+
+   int i;
+   unsigned char* itTData;
+   itTData = pimage->GetData();
+
+   for (i=0; i<w*h; i++)
+   {
+      *(itTData++)=data[i];
+      *(itTData++)=data[i];
+      *(itTData++)=data[i];
+   }
+   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
+
+#if wxCHECK_VERSION(2, 3, 0)
+   pbitmap = new wxBitmap(pimage);
+#else
+   pbitmap = new wxBitmap(pimage->ConvertToBitmap());
+#endif
+   hasbitmap=TRUE;
+   m_dirty=TRUE;
+
+   //create point map
+   CreatePointMap(w, h);
+
+   //take account for zoom (takes care of refresh)
+   Zoom(zoom_level);
+}
+
+void BgImCanvas::SetImage(unsigned char* data, int w, int h, bool colorim)
+{
+   ClearData();
+   
+   pimage = new wxImage(w, h);
+
+   int i;
+   unsigned char* itTData;
+   itTData = pimage->GetData();
+
+   if (colorim == false)
+   {
+      for (i=0; i<w*h; i++)
+      {
+         *(itTData++)=data[i];
+         *(itTData++)=data[i];
+         *(itTData++)=data[i];
+      }
+   } else
+   {
+      for (i=0; i<(3*w*h); i++)
+      {
+         *(itTData++)=data[i];
+      }
+   }
+   SetScrollbars(1, 1, (pimage->GetWidth())/1, (pimage->GetHeight())/1);
+
+#if wxCHECK_VERSION(2, 3, 0)
+   pbitmap = new wxBitmap(pimage);
+#else
+   pbitmap = new wxBitmap(pimage->ConvertToBitmap());
+#endif
+   hasbitmap=TRUE;
+   m_dirty=TRUE;
+
+
+   //create point map
+   CreatePointMap(w, h);
+
+   //take account for zoom (takes care of refresh)
+   Zoom(zoom_level);
+}
+
+/*
+Still needs work!!!!!!
+*/
+
+void BgImCanvas::ShowBitmap(bool showbitmap)
+{
+	showbitmap_	= showbitmap;
+	if(hasbitmap)
+	{
+		//compute height and width of original image
+		int width	= pimage->GetWidth();
+		int height	= pimage->GetHeight();
+
+		//paint zoom image
+		if(!showbitmap_)
+			memset(zImg, 255, 3*zoom_level*zoom_level*width*height*sizeof(unsigned char));
+		else
+			bgZoomIn(&zImg, pimage->GetData(), width, height, zoom_level, false);
+
+		//plot points from point set onto zoom image
+		AddPoints(zImg, width*zoom_level);
+
+		//re-draw image onto canvas
+		Refresh();
+	}
+	return;
+}
+
+
+// Define the repainting behaviour
+void BgImCanvas::OnDraw(wxDC& dc)
+{
+	//clear the display
+	if(clear_display_)
+	{
+		clear_display_	= false;
+		dc.Clear();
+		return;
+	}
+
+	//do not update the display (good for keeping
+	//a display clear in light of onSize() events
+	//for example)
+	if(noUpdate_) return;
+
+	//catch leaving event
+	if((zoom_window)&&(leaving))
+	{
+		//if a refresh window remains, plot it and delete it
+		if(refresh_box)
+		{
+#if wxCHECK_VERSION(2, 3, 0)
+         dc.DrawBitmap(wxBitmap(refresh_box), cx, cy);
+#else
+			dc.DrawBitmap(refresh_box->ConvertToBitmap(), cx, cy);
+#endif
+			delete refresh_box;
+			refresh_box	= (wxImage*) NULL;
+		}
+		
+		//retrieve leaving event
+		leaving	= false;
+
+		//exit
+		return;
+	}
+
+
+	if (hasbitmap==false)
+	{
+		dc.Clear();
+		return;
+	}
+	//re-plot image bitmap
+	if(hasbitmap==true && showbitmap_==true)
+	{
+		if((!zoom_window)||(!has_focus))
+			dc.DrawBitmap(*pbitmap,0+x_offset_,0+y_offset_);
+	}
+	else if(!zoom_window)
+	{
+		dc.Clear();
+	}
+	if (showtrack_ == 1)
+	{
+		wxPen tPen=dc.GetPen();
+		dc.SetBrush(*wxTRANSPARENT_BRUSH);
+		dc.SetPen(*wxRED_PEN);
+		//+x_offset_+y_offset_
+		dc.DrawEllipse(trackval_[0]-2, trackval_[1]-2, 5,5);
+		dc.DrawEllipse(trackval_[0]-hx_, trackval_[1]-hy_, 2*hx_+1, 2*hy_+1);
+		dc.SetPen(tPen);
+		dc.SetBrush(wxNullBrush);
+	}
+	if ((nPointSets_ > 0)&&((!zoom_window)||(!has_focus)))
+	{
+		int i,j;
+		int* tx;
+		int* ty;
+		int x, xc;
+		int y, yc;
+		int nt;
+		wxPen tPen=dc.GetPen();
+		dc.SetBrush(*wxTRANSPARENT_BRUSH);
+		for (i=0; i<nPointSets_; i++)
+		{
+			dc.SetPen(pointSet_[i]->pen_);
+			nt = pointSet_[i]->n_;
+			tx = pointSet_[i]->x_;
+			ty = pointSet_[i]->y_;
+			if(pointSet_[i]->type_ == 0) // circle
+			{
+				for (j=0; j<nt; j++)
+				{
+					dc.DrawEllipse(tx[j]-2+x_offset_, ty[j]-2+y_offset_, 5,5);
+				}
+			}
+			else if(pointSet_[i]->type_ == 1) // point
+			{
+				for (j=0; j<nt; j++)
+				{
+					xc	= zoom_level*(tx[j] + x_offset_);
+					yc	= zoom_level*(ty[j] + y_offset_);
+					for(y=0; y<zoom_level; y++)
+					{
+						for(x=0; x<zoom_level; x++)
+						{
+							dc.DrawPoint(xc+x, yc+y);
+						}
+					}
+				}
+			}
+		}
+		dc.SetPen(tPen);
+		dc.SetBrush(wxNullBrush);
+	}
+	
+	if (nLineSets_ > 0)
+	{
+		int i,j;
+		int* tsx;
+		int* tsy;
+		int* tex;
+		int* tey;
+		int nt;
+		wxPen tPen=dc.GetPen();
+		dc.SetBrush(*wxTRANSPARENT_BRUSH);
+		for (i=0; i<nLineSets_; i++)
+		{
+			dc.SetPen(lineSet_[i]->pen_);
+			nt = lineSet_[i]->n_;
+			tsx = lineSet_[i]->xs_;
+			tsy = lineSet_[i]->ys_;
+			tex = lineSet_[i]->xe_;
+			tey = lineSet_[i]->ye_;
+			for (j=0; j<nt; j++)
+			{
+				dc.DrawLine(tsx[j]+x_offset_, tsy[j]+y_offset_, tex[j]+x_offset_, tey[j]+y_offset_);
+			}
+		}
+		dc.SetPen(tPen);
+		dc.SetBrush(wxNullBrush);
+	}
+	int txs,tys,txe,tye;
+	
+	if (nCurveSets_ > 0)
+	{
+		int i,j;
+		int* tx;
+		int* ty;
+		int xs, ys;
+		int nt;
+		wxPen tPen=dc.GetPen();
+		dc.SetBrush(*wxTRANSPARENT_BRUSH);
+		for (i=0; i<nCurveSets_; i++)
+		{
+			dc.SetPen(curveSet_[i]->pen_);
+			tx = curveSet_[i]->x_;
+			ty = curveSet_[i]->y_;
+			nt = curveSet_[i]->n_;
+			xs = curveSet_[i]->xs_;
+			ys = curveSet_[i]->ys_;
+			
+			switch (curveSet_[i]->type_)
+			{
+			case -1:
+				break;
+			case FC_ELLIPSE:
+				MyDrawEllipticArc(dc,-tx[0]+x_offset_, ty[0]+y_offset_, 2*tx[0], 2*(ys-ty[0]), 0, 90);
+				break;
+			case FC_VERT_LINE:
+				//            if ((tx[0]>=0) && (tx[0]<xs))
+				dc.DrawLine(tx[0]+x_offset_, 0+y_offset_, tx[0]+x_offset_, ys+y_offset_);
+				break;
+			case FC_HORIZ_LINE:
+				if ((ty[0]>=0) && (ty[0]<ys))
+					dc.DrawLine(0+x_offset_, ty[0]+y_offset_, xs+x_offset_, ty[0]+y_offset_);
+				break;
+			case FC_LINE:
+				// determine clipping
+				tye = ys;
+				txe = tx[0];
+				txe = (txe<=0)?1:txe;
+				txs = 0;
+				tys = ty[0];
+				tys = (tys>ys)?ys:tys;
+				if (txe>xs)
+				{
+					tye = ccy_-((ccy_-tys)*(txe-xs))/txe;
+					txe = xs;
+				}
+				if (tys<0)
+				{
+					txs= (txe*(-tys))/(tye-tys);
+					tys= 0;
+				}
+				
+				dc.DrawLine(0+x_offset_, ty[0]+y_offset_, tx[0]+x_offset_, ys+y_offset_);
+				break;
+			case FC_SQUARE_BOX:
+				txs = (tx[0]<0)?0:tx[0];
+				txs = (txs>=xs)?xs-1:txs;
+				tys = (ty[0]<0)?0:ty[0];
+				tys = (tys>=ys)?ys-1:tys;
+				dc.DrawLine(0+x_offset_, tys+y_offset_, txs+x_offset_, tys+y_offset_);
+				dc.DrawLine(txs+x_offset_, tys+y_offset_, txs+x_offset_, ys+y_offset_);
+				break;
+			case FC_CUSTOM:
+				for (j=0; j<(nt-1); j++)
+					dc.DrawLine(tx[j]+x_offset_, ty[j]+y_offset_, tx[j+1]+x_offset_, ty[j+1]+y_offset_);
+				break;
+			}
+			//         wxPen pPen=dc.GetPen();
+			//         pPen.SetWidth(17);
+			//         pPen.SetColour(64,64,64);
+			//         dc.SetPen(pPen);
+			switch (curveSet_[i]->type_)
+			{
+			case -1:
+				break;
+			case FC_ELLIPSE:
+			case FC_LINE:
+				//            dc.DrawPoint(0,ty[0]);
+				//            dc.DrawPoint(tx[0],ys);
+				dc.DrawRectangle(0-2+x_offset_,ty[0]-2+y_offset_,5,5);
+				dc.DrawRectangle(tx[0]-2+x_offset_,ys-2+y_offset_,5,5);
+				break;
+			case FC_SQUARE_BOX:
+				//            dc.DrawPoint(0,ty[0]);
+				//            dc.DrawPoint(tx[0],ys);
+				//            dc.DrawPoint(tx[0],ty[0]);
+				dc.DrawRectangle(0-2+x_offset_,ty[0]-2+y_offset_,5,5);
+				dc.DrawRectangle(tx[0]-2+x_offset_,ys-2+y_offset_,5,5);
+				dc.DrawRectangle(tx[0]-2+x_offset_,ty[0]-2+y_offset_,5,5);
+				break;
+			case FC_CUSTOM:
+				for (j=0; j<nt; j++)
+					dc.DrawRectangle(tx[j]-2+x_offset_,ty[j]-2+y_offset_,5,5);
+				//               dc.DrawPoint(tx[j],ty[j]);
+				break;
+			}
+		}
+		dc.SetPen(tPen);
+		dc.SetBrush(wxNullBrush);
+	}
+	
+	if (isDragging_ == 1)
+	{ 
+		int j;
+		int* tx;
+		int* ty;
+		int xs, ys;
+		int nt;
+		wxPen tPen=dc.GetPen();
+		dc.SetBrush(*wxTRANSPARENT_BRUSH);
+		dc.SetPen(dragCurve_.pen_);
+		tx = dragCurve_.x_;
+		ty = dragCurve_.y_;
+		nt = dragCurve_.n_;
+		xs = dragCurve_.xs_;
+		ys = dragCurve_.ys_;
+		
+		switch (dragCurve_.type_)
+		{
+		case -1:
+			break;
+		case FC_ELLIPSE:
+            MyDrawEllipticArc(dc,-tx[0]+x_offset_, ty[0]+y_offset_, 2*tx[0], 2*(ys-ty[0]), 0, 90);
+            break;
+		case FC_VERT_LINE:
+			//            if ((tx[0]>=0) && (tx[0]<xs))
+			dc.DrawLine(tx[0]+x_offset_, 0+y_offset_, tx[0]+x_offset_, ys+y_offset_);
+            break;
+		case FC_HORIZ_LINE:
+            if ((ty[0]>=0) && (ty[0]<ys))
+				dc.DrawLine(0+x_offset_, ty[0]+y_offset_, xs+x_offset_, ty[0]+y_offset_);
+            break;
+		case FC_LINE:
+            // determine clipping
+            tye = ys;
+            txe = tx[0];
+            txe = (txe<=0)?1:txe;
+            txs = 0;
+            tys = ty[0];
+            tys = (tys>ys)?ys:tys;
+            if (txe>xs)
+            {
+				tye = ccy_-((ccy_-tys)*(txe-xs))/txe;
+				txe = xs;
+            }
+            if (tys<0)
+            {
+				txs= (txe*(-tys))/(tye-tys);
+				tys= 0;
+            }
+			
+            dc.DrawLine(0+x_offset_, ty[0]+y_offset_, tx[0]+x_offset_, ys+y_offset_);
+            break;
+		case FC_SQUARE_BOX:
+            txs = (tx[0]<0)?0:tx[0];
+            txs = (txs>=xs)?xs-1:txs;
+            tys = (ty[0]<0)?0:ty[0];
+            tys = (tys>=ys)?ys-1:tys;
+            dc.DrawLine(0+x_offset_, tys+y_offset_, txs+x_offset_, tys+y_offset_);
+            dc.DrawLine(txs+x_offset_, tys+y_offset_, txs+x_offset_, ys+y_offset_);
+            break;
+		case FC_CUSTOM:
+            for (j=0; j<(nt-1); j++)
+				dc.DrawLine(tx[j]+x_offset_, ty[j]+y_offset_, tx[j+1]+x_offset_, ty[j+1]+y_offset_);
+            break;
+		}
+		
+		dc.SetPen(tPen);
+		dc.SetBrush(wxNullBrush);
+		
+	}
+	
+	//draw horizontal and vertical axis
+	if(xAxis)	xAxis->PlotAxis(&dc);
+	if(yAxis)	yAxis->PlotAxis(&dc);
+	
+	//draw new text to the image from text object list
+	BgText	*bgText;
+	tlist_.ResetList();
+	while(bgText = tlist_.GetText())
+	{
+		dc.SetFont(*(bgText->font_));
+		dc.DrawText(bgText->text_, bgText->x_, bgText->y_);
+	}
+	
+	//draw bitmaps
+	blist_.ResetList();
+	BgBitmap	*bitmap;
+	while(bitmap = blist_.GetBitmap())
+		dc.DrawBitmap(*(bitmap->bitmap_), bitmap->location_x_, bitmap->location_y_, true);
+
+	//draw zoom window box
+	if((zoom_window)&&(has_focus))
+	{
+		//draw refresh window
+#if wxCHECK_VERSION(2, 3, 0)
+      if(refresh_box)   dc.DrawBitmap(wxBitmap(refresh_box), cx, cy);
+#else
+		if(refresh_box)	dc.DrawBitmap(refresh_box->ConvertToBitmap(), cx, cy);
+#endif
+
+		//compute height and width of zoom box and window
+		int zWidth, zHeight;
+		int dWidth, dHeight;
+		zWidth	= zoombox->GetWidth();
+		zHeight	= zoombox->GetHeight();
+		GetSize(&dWidth, &dHeight);
+
+		//compute upper corner of window
+		cx = m_x_ - zWidth/2;
+		cy = m_y_ - zHeight/2;
+
+		//check bounds....
+		if(cx < 0)	cx = 0;
+		if(cy < 0)	cy = 0;
+		if(cx >= dWidth - zWidth)	cx	= dWidth  - zWidth - 1;
+		if(cy >= dHeight - zHeight)	cy	= dHeight - zHeight - 1;
+
+		//place in image coordinate frame
+		cx	= cx + GetScrollPos(wxHORIZONTAL);
+		cy	= cy + GetScrollPos(wxVERTICAL);
+
+		//check bounds		
+		int width	= pimage->GetWidth()*zoom_level, height	= pimage->GetHeight()*zoom_level;
+		if(cx >= width - zWidth)	cx	= width - zWidth - 1;
+		if(cy >= height - zHeight)	cy	= height - zHeight - 1;
+
+		//draw zoom window
+#if wxCHECK_VERSION(2, 3, 0)
+      dc.DrawBitmap(wxBitmap(zoombox), cx, cy);
+#else
+		dc.DrawBitmap(zoombox->ConvertToBitmap(), cx, cy);
+#endif
+
+		//create refresh box for next iteration
+		DefineRefreshBox();
+	}
+
+}
+
+//adds an image margin to the image
+//pre : (x_margin, y_margin) define the margins in the
+//      x and y direction respectively
+//post: an image margin has been added
+void BgImCanvas::AddMargin(int x_margin, int y_margin)
+{
+	//shift the image
+	x_offset_	= x_margin;
+	y_offset_	= y_margin;
+
+	//redraw the image
+	Refresh();
+
+}
+
+//overloaded zoom function that does not use current mouse position
+int BgImCanvas::Zoom(int zconst)
+{
+	return Zoom(zconst, 0, 0);
+}
+
+//allows one to zoom into/out of the image dispalyed by the image canvas
+//pre : zconst is the zoom constant
+//      (m_x, m_y) is the current position of the mouse
+//post: the image has been zoomed in by a factor of zconst
+//      returns 1 when zoom not possible due to image constraints,
+//		zoom at maximum or minimum image dimensions, or possible error
+int BgImCanvas::Zoom(int zconst, int m_x, int m_y)
+{
+	//must have bitmap to zoom
+	if(hasbitmap)
+	{
+		//determine zooming action
+		int	action;
+		if(zconst < zoom_level)
+			action	= ZOOM_OUT;
+		else if(zconst > zoom_level)
+			action	= ZOOM_IN;
+		
+		//check bounds
+		int	width	= pimage->GetWidth(), height	= pimage->GetHeight();
+		if(zconst < 0)
+		{
+			//take absolute value of zoom constant
+			int	pos_zc	= -zconst;
+
+			//compute new width
+			if(width%pos_zc)
+				width	= width/pos_zc+1;
+			else
+				width	/= pos_zc;
+
+			//compute new height
+			if(height%pos_zc)
+				height	= height/pos_zc+1;
+			else
+				height	/= -zconst;
+
+			//make sure width and height are above minimum
+			//before continuing
+			if((width < MIN_WIDTH)||(height < MIN_HEIGHT))
+				return 1;
+		}
+		else if (zconst > 0)
+		{
+			width	*= zconst;
+			height	*= zconst;
+			if((width > MAX_WIDTH)||(height > MAX_HEIGHT))
+				return 1;
+		}
+		else
+		{
+			//zconst equals zero (ambiguous so exit)
+			return 1;
+		}
+		
+		//set zoom_level
+		zoom_level	= zconst;
+
+		if(zoom_level == 1)
+		{
+			delete	pbitmap;
+#if wxCHECK_VERSION(2, 3, 0)
+         pbitmap = new wxBitmap(pimage);
+#else
+			pbitmap	= new wxBitmap(pimage->ConvertToBitmap());
+#endif
+			if(zImg)	delete zImg;
+			zImg	= new unsigned char [3*height*width];
+			memcpy(zImg, pimage->GetData(), 3*height*width);
+		}
+		else if(zoom_level > 1)
+		{
+			//zoom into image using zoom level
+			wxImage	tempIm(width, height);
+			if(zImg)	delete [] zImg;
+			zImg	= new unsigned char [3*width*height];
+			bgZoomIn(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), zoom_level, false);
+			memcpy(tempIm.GetData(), zImg, 3*width*height*sizeof(unsigned char));
+			
+			//reset the bitmap using zoomed image
+			delete pbitmap;
+#if wxCHECK_VERSION(2, 3, 0)
+         pbitmap = new wxBitmap(tempIm);
+#else
+			pbitmap = new wxBitmap(tempIm.ConvertToBitmap());
+#endif
+		}
+		else if(zoom_level < -1)
+		{
+			//zoom out of image using zoom level
+			wxImage	tempIm(width, height);
+			if(zImg)	delete [] zImg;
+			zImg	= new unsigned char [3*width*height];
+			bgZoomOut(&zImg, pimage->GetData(), pimage->GetWidth(), pimage->GetHeight(), (-zoom_level), false);
+			memcpy(tempIm.GetData(), zImg, 3*width*height*sizeof(unsigned char));
+			
+			//reset the bitmap using zoomed image
+			delete pbitmap;
+#if wxCHECK_VERSION(2, 3, 0)
+         pbitmap = new wxBitmap(tempIm);
+#else
+			pbitmap = new wxBitmap(tempIm.ConvertToBitmap());
+#endif
+		}
+
+		//if a bitmap is not to be shown, clear (make white) the
+		//zoomed image
+		if(!showbitmap_)
+			memset(zImg, 255, 3*width*height*sizeof(unsigned char));
+
+		//add point data to zoomed image
+		AddPoints(zImg, width);
+
+		//re-display image
+		Refresh();
+
+		//set scroll bars according to current mouse position and zooming action
+		AdjustScroll(m_x, m_y, action);
+
+		//return 1 when maximum or minimum image dimension has occured
+		if((width == MAX_WIDTH)||(width == MIN_WIDTH)||(height == MAX_HEIGHT)||(height == MIN_HEIGHT))
+			return 1;
+
+		//return 1 when close to maximum or minimum image dimension...
+		/*********************************************************************/
+
+		if(zconst > 0)
+		{
+			width	+= pimage->GetWidth();
+			height	+= pimage->GetHeight();
+			if((width > MAX_WIDTH)||(height > MAX_HEIGHT))
+				return 1;
+		}
+		else if(zconst < 0)
+		{
+			
+			//obtain width and height of original image
+			width	= pimage->GetWidth();
+			height	= pimage->GetHeight();
+			
+			//take absolute value of zoom constant
+			int	pos_zc	= -zconst;
+			
+			//compute new width
+			if(width%pos_zc)
+				width	= width/pos_zc+1;
+			else
+				width	/= pos_zc;
+			
+			//compute new height
+			if(height%pos_zc)
+				height	= height/pos_zc+1;
+			else
+				height	/= -zconst;
+			width	= (pimage->GetWidth());
+
+			//check image bounds...
+			if((width < MIN_WIDTH)||(height < MIN_HEIGHT))
+				return 1;
+		}
+
+		/*********************************************************************/
+	}
+
+	//done.
+	return 0;
+
+}
+
+//allows one to zoom into the image stored by the image canvas
+//pre : (m_x, m_y) is the current mouse position
+//post: the image has been zoomed in by a factor of zoom_level+1
+//      1 is returned when max zoom level is reached
+int BgImCanvas::ZoomIn(int m_x, int m_y)
+{
+	//must have bitmap to zoom into
+	if(hasbitmap)
+	{
+		//make sure zoom level is not at maximum before proceeding -
+		//max_zoom_level has value 0 when unspecified
+		if((max_zoom_level)&&(zoom_level == max_zoom_level))
+		{
+			wxWindow *parent	= child_frame_->GetParent();
+			((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, true, false);
+			return 1;
+		}
+
+		//zoom image
+		int zconst = zoom_level + 1;
+		if(zconst == -1) zconst = 1;
+		int	maxZoom	= Zoom(zconst, m_x, m_y);
+
+		//take into account maximum zoom level
+		maxZoom = (maxZoom || ((max_zoom_level)&&(zoom_level == max_zoom_level)));
+
+		//set title of child frame
+		wxWindow *parent	= child_frame_->GetParent();
+		((BgMdiFrame *) parent)->SetChildTitle((wxMDIChildFrame *) child_frame_, zoom_level, maxZoom, false);
+
+		//update zoom control of child frame
+		((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, maxZoom, false);
+
+		//indicate if max zoom has occured
+		return maxZoom;
+	}
+
+	//done.
+	return 0;
+}
+
+//allows one to zoom out of the image stored by the image canvas
+//pre : (m_x, m_y) is the current mouse position
+//post: the image has been zoomed out by a factor of zoom_level-1
+//      returns 1 if minimum zoom has occured
+int BgImCanvas::ZoomOut(int m_x, int m_y)
+{
+	//must have bitmap to zoom into
+	if(hasbitmap)
+	{
+		//make sure zoom level is not at minimum before proceeding -
+		//min_zoom_level has value 0 when unspecified
+		if((min_zoom_level)&&(zoom_level == min_zoom_level))
+		{
+			wxWindow *parent	= child_frame_->GetParent();
+			((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, false, true);
+			return 1;
+		}
+
+		//zoom image
+		int zconst = zoom_level - 1;
+		if(zconst == 0)	zconst = -2;
+		int	minZoom	= Zoom(zconst, m_x, m_y);
+
+		//take into account mininimum zoom level;
+		minZoom = (int)(minZoom ||((min_zoom_level)&&(zoom_level == min_zoom_level)));
+
+		//set title of child frame
+		wxWindow *parent	= child_frame_->GetParent();
+		((BgMdiFrame *) parent)->SetChildTitle((wxMDIChildFrame *) child_frame_, zoom_level, false, minZoom);
+
+		//update zoom control of child frame
+		((BgMdiFrame *) parent)->UpdateZoomControl((wxMDIChildFrame *) child_frame_, false, minZoom);
+
+		//indicate if min zoom has occured
+		return minZoom;
+	}
+
+	//done.
+	return 0;
+}
+
+//sets max zoom level
+void BgImCanvas::SetMaxZoomLevel(int mzl)
+{
+	max_zoom_level	= mzl;
+}
+
+//sets min zoom level
+void BgImCanvas::SetMinZoomLevel(int mzl)
+{
+	min_zoom_level	= mzl;
+}
+
+
+#define WIN_PERC 16
+
+void BgImCanvas::DefineZoomBox(int l_x, int h_x, int l_y, int h_y)
+{
+
+	//obtain image height and width
+	int	iWidth = pimage->GetWidth(), iHeight = pimage->GetHeight();
+
+	//calculate box height and width
+	static int bWidth = h_x-l_x+1, bHeight = h_y-l_y+1;
+
+	//allocate/deallocate memory
+	if((bWidth != h_x-l_x+1)||(!buf))
+	{
+		bWidth	= h_x-l_x+1;
+		bHeight	= h_y-l_y+1;
+		if(buf)	delete buf;
+		buf	= new unsigned char [3*bWidth*bHeight];
+	}
+
+	//get point pen colour
+	unsigned char r, g, b;
+	if(point_colour)
+	{
+		r	= point_colour->Red();
+		g	= point_colour->Green();
+		b	= point_colour->Blue();
+	}
+
+	//crop image data and store it into buf (if the bitmap is being displayed...)
+	unsigned char	*imData		= pimage->GetData();
+	int bx, by, ix, iy, idp, bdp;
+	if(showbitmap_)
+	{
+		for(by=0; by<bHeight; by++)
+		{
+			for(bx=0; bx<bWidth; bx++)
+			{
+				ix	= bx + l_x;
+				iy	= by + l_y;
+				idp	= 3*(iy*iWidth + ix);
+				bdp	= 3*(by*bWidth + bx);
+				buf[bdp  ]	= imData[idp  ];
+				buf[bdp+1]	= imData[idp+1];
+				buf[bdp+2]	= imData[idp+2];
+				
+				//account for point sets using point map
+				if(point_map[idp/3])
+				{
+					buf[bdp]	= r;
+					buf[bdp+1]	= g;
+					buf[bdp+2]	= b;
+				}
+			}
+		}
+	}
+	//create blank (white) image and plot point set onto it
+	//prior to zoom
+	else
+	{
+		memset(buf, 255, 3*bWidth*bHeight*sizeof(unsigned char));
+		for(by=0; by<bHeight; by++)
+		{
+			for(bx=0; bx<bWidth; bx++)
+			{
+				ix	= bx + l_x;
+				iy	= by + l_y;
+				idp	= 3*(iy*iWidth + ix);
+				bdp	= 3*(by*bWidth + bx);
+
+				//account for point sets using point map
+				if(point_map[idp/3])
+				{
+					buf[bdp]	= r;
+					buf[bdp+1]	= g;
+					buf[bdp+2]	= b;
+				}
+			}
+		}
+	}
+
+	//zoom the data in buf...
+
+	//set zoom window size and allocate memory
+	static int	zWidth	= bWidth*zoom_level*2;
+	static int	zHeight	= bHeight*zoom_level*2;
+	if((zWidth != bWidth*zoom_level*2)||(!zoombox))
+	{
+		zWidth	= bWidth*zoom_level*2;
+		zHeight	= bHeight*zoom_level*2;
+		if(zoombox)	delete zoombox;
+		zoombox	= new wxImage(zWidth, zHeight);
+
+	}
+
+	//create a zoom box image using buf
+	unsigned char	*zbData	= zoombox->GetData();
+	bgZoomIn(&zbData, buf, bWidth, bHeight, zoom_level*2, false);
+
+	//done.
+	return;
+}
+
+void BgImCanvas::DefineRefreshBox(void)
+{
+
+	//obtain image height and width
+	int	iWidth = pimage->GetWidth()*zoom_level, iHeight = pimage->GetHeight()*zoom_level;
+
+	//calculate box height and width
+	static int bWidth = zoombox->GetWidth(), bHeight = zoombox->GetHeight();
+
+	//allocate/de-allocate memory for refresh box
+	if((bWidth != zoombox->GetWidth())||(!refresh_box))
+	{
+		bWidth	= zoombox->GetWidth();
+		bHeight	= zoombox->GetHeight();
+		if(refresh_box)	delete [] refresh_box;
+		refresh_box	= new wxImage(bWidth, bHeight);
+	}
+	unsigned char *rBuf	= refresh_box->GetData();
+
+	//get point pen colour
+	unsigned char r, g, b;
+	if(point_colour)
+	{
+		r	= point_colour->Red();
+		g	= point_colour->Green();
+		b	= point_colour->Blue();
+	}
+
+	//define refresh box...
+
+	//crop image data and store it into rBuf...
+	unsigned char *imData	= pimage->GetData();
+	int bx, by, ix, iy, bdp, idp;
+	for(by=0; by<bHeight; by++)
+	{
+		for(bx=0; bx<bWidth; bx++)
+		{
+			ix	= bx + cx;
+			iy	= by + cy;
+			idp	= 3*(iy*iWidth + ix);
+			bdp	= 3*(by*bWidth + bx);
+			rBuf[bdp  ]	= zImg[idp  ];
+			rBuf[bdp+1]	= zImg[idp+1];
+			rBuf[bdp+2]	= zImg[idp+2];
+		}
+	}
+
+	//done.
+	return;
+}
+
+//creates point map used by zoom and refresh windows
+void BgImCanvas::CreatePointMap(int w, int h)
+{
+
+	//initialze point map
+	if(point_map)	delete [] point_map;
+	point_map	= new bool [w*h];
+	memset(point_map, 0, w*h*sizeof(bool));
+
+	//if point sets already exist then add the,
+	if (nPointSets_ > 0)
+	{
+		//adjust point pen colour to be that of the last
+		//point set added
+		if(point_colour)	delete point_colour;
+		point_colour	= new wxColour(pointSet_[nPointSets_-1]->pen_.GetColour());
+
+		int nt, *tx, *ty, i, j;
+		for (i=0; i<nPointSets_; i++)
+		{
+			nt = pointSet_[i]->n_;
+			tx = pointSet_[i]->x_;
+			ty = pointSet_[i]->y_;
+			if(pointSet_[i]->type_ == 1) // point
+			{
+				for(j=0; j<nt; j++)
+					point_map[ty[j]*w+tx[j]] = true;
+			}
+		}
+	}
+}
+
+//adds points from point sets onto specified image
+void BgImCanvas::AddPoints(unsigned char *im, int width)
+{
+	//if point sets have been defined add point data to image
+	if(nPointSets_	> 0)
+	{
+		unsigned char r, g, b;
+		wxColour	pen_colour;
+		int	nt, *tx, *ty, i, j, x, y, dp, offset;
+		for(i=0; i < nPointSets_; i++)
+		{
+			if(pointSet_[i]->type_ == 1) //point
+			{
+				//get pen colour
+				pen_colour	= pointSet_[i]->pen_.GetColour();
+				r	= pen_colour.Red();
+				g	= pen_colour.Green();
+				b	= pen_colour.Blue();
+
+				//place points
+				nt	= pointSet_[i]->n_;
+				tx	= pointSet_[i]->x_;
+				ty	= pointSet_[i]->y_;
+				for(j=0; j<nt; j++)
+				{
+					dp = 3*(ty[j]*width+tx[j])*zoom_level;
+					for(y=0; y<zoom_level; y++)
+					{
+						for(x=0; x<zoom_level; x++)
+						{
+							offset	= 3*(y*width+x);
+							im[dp+offset  ]	= r;
+							im[dp+offset+1]	= g;
+							im[dp+offset+2]	= b;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+//displays zoom window at cursor position
+void BgImCanvas::DisplayZoomWindow(int m_x, int m_y)
+{
+
+	//set mouse position...
+	m_x_	= m_x;
+	m_y_	= m_y;
+
+	//compute width and height of window....
+
+	/***********************************************************/
+
+	//obtain image height and width
+	int w = pimage->GetWidth(), h = pimage->GetHeight();
+
+	//take percentage of height and width to compute
+	//box half-width and half-height
+	int	hw, hh;
+	int	wp	= WIN_PERC;
+	if(w%wp)
+		hw	= w/wp + 1;
+	else
+		hw	= w/wp;
+
+	if(h%wp)
+		hh	= h/wp + 1;
+	else
+		hh	= h/wp;
+
+	/***********************************************************/
+
+	//normalize mouse coordinates to image coordinate frame
+
+	/***********************************************************/
+
+	if(zoom_level > 0)
+	{
+		m_x	= (m_x + GetScrollPos(wxHORIZONTAL))/zoom_level;
+		m_y	= (m_y + GetScrollPos(wxVERTICAL))/zoom_level;
+	}
+	else if(zoom_level < 0)
+	{
+		m_x	= (m_x + GetScrollPos(wxHORIZONTAL))*(-zoom_level);
+		m_y	= (m_y + GetScrollPos(wxVERTICAL))*(-zoom_level);
+	}
+
+	/***********************************************************/
+
+	//make sure x_m and y_m are with bounds before proceeding...
+
+	/***********************************************************/
+
+	if((m_x < 0)||(m_x >= w)||(m_y < 0)||(m_y >= h))
+		return;
+
+	/***********************************************************/
+
+	//compute zoom window bounds...
+
+	/***********************************************************/
+
+	//define window bounds based on current mouse position
+	int low_x, hi_x, low_y, hi_y;
+	if((low_x	= m_x - hw) <  0) low_x	= 0;
+	if((hi_x	= m_x + hw) >= w) hi_x	= w-1;
+	if((low_y	= m_y - hh) <  0) low_y	= 0;
+	if((hi_y	= m_y + hh) >= h) hi_y	= h-1;
+
+	//make window larger according to current mouse position	
+	if(m_x			<= hw) hi_x		+= hw-m_x;
+	if((w-m_x-1)	<= hw) low_x	-= hw-(w-m_x-1);
+	if(m_y			<= hh) hi_y		+= hh-m_y;
+	if((h-m_y-1)	<= hh) low_y	-= hh-(h-m_y-1);
+
+	/***********************************************************/
+
+	//define zoom box...
+
+	/***********************************************************/
+
+	DefineZoomBox(low_x, hi_x, low_y, hi_y);
+
+	/***********************************************************/
+
+	//display zoomed image over current mouse position...
+
+	/***********************************************************/
+
+	Refresh(false);
+
+	/***********************************************************/
+
+	//done.
+	return;
+
+}
+
+/*
+void BgImCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
+{
+}
+*/
+void BgImCanvas::FillCurveClick()
+{
+   int i;
+   for (i=0; i<ccx_*ccy_; i++)
+      curveClick_[i] = 0;
+   
+   for (i=0; i<nCurveSets_; i++)
+      curveSet_[i]->DrawYourself(curveClick_, i+1);
+
+   Refresh();
+//   write_pgm_image("curveclick.pgm", curveClick_, 256, 256, "", 4);
+}
+
+/*
+void BgImCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+   wxClientDC dc(this);
+   PrepareDC(dc);
+   if(hasbitmap==TRUE)
+   {
+      dc.DrawBitmap(*pbitmap,0,0);
+   }
+   else 
+   {
+      dc.Clear();
+   }
+}
+*/
+
+void BgImCanvas::MyDrawEllipticArc(wxDC& dc, int x, int y, int w, int h, int sa, int ea)
+{
+   double xc, yc, rx, ry;
+   rx = w/2;
+   ry = h/2;
+   xc = x+rx;
+   yc = y+ry;
+   int r, c;
+   int low_r = y_offset_;
+   int hig_r = ccy_+y_offset_;
+   int low_c = x_offset_;
+   int hig_c = ccx_+x_offset_;
+
+//   if (rx > ry)
+//   {
+      // x scan
+      for (c = (int) xc; c<=(int) (xc+rx); c++)
+      {
+         if (c>=low_c && c<hig_c)
+         {
+            r = bgRound(yc-ry*sqrt(1-(c-xc)*(c-xc)/(rx*rx)));
+            if (r>=low_r && r<hig_r)
+            {
+               dc.DrawPoint(c,r);
+               // +/- 1
+               if ((r+1)<hig_r) dc.DrawPoint(c,r+1);
+               if ((r-1)>=low_r) dc.DrawPoint(c,r-1);;
+            }
+         }
+      }
+//   }
+//   else
+//   {
+      // y scan
+      for (r = (int)(yc-ry); r<=(int) yc; r++)
+      {
+         if (r>=low_r && r<hig_r)
+         {
+            c = bgRound(xc+rx*sqrt(1-(r-yc)*(r-yc)/(ry*ry)));
+            if (c>=low_c && c<hig_c)
+            {
+               dc.DrawPoint(c,r);
+               // +/- 1
+               if ((c+1)<hig_c) dc.DrawPoint(c+1,r);
+               if ((c-1)>=low_c) dc.DrawPoint(c-1,r);;
+            }
+         }
+      }
+//   }
+}
+
+void BgImCanvas::OnMouseRightDown(wxMouseEvent& event)
+{
+   wxClientDC dc(this);
+   PrepareDC(dc);
+   wxPoint pt(event.GetLogicalPosition(dc));
+   static int x;
+   static int y;
+   x = pt.x-x_offset_;
+   y = pt.y-y_offset_;
+   if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
+   {
+      if (curveClick_[x+y*ccx_]>0)
+      {
+         lmEventCurve_ = curveClick_[x+y*ccx_] - 1;
+         if (curveSet_[lmEventCurve_]->type_ == FC_CUSTOM)
+         {
+            // determine if close to a node
+            int *tempx, *tempy, tempn;
+            double mindist, crtdist;
+            int i, minnode;
+            tempx = curveSet_[lmEventCurve_]->x_;
+            tempy = curveSet_[lmEventCurve_]->y_;
+            tempn = curveSet_[lmEventCurve_]->n_;
+            mindist = sqrt((x-tempx[0])*(x-tempx[0])+(y-tempy[0])*(y-tempy[0]));
+            minnode = 0;
+            for (i=1; i<tempn; i++)
+            {
+               crtdist = sqrt((x-tempx[i])*(x-tempx[i])+(y-tempy[i])*(y-tempy[i]));
+               if (crtdist < mindist)
+               {
+                  mindist = crtdist;
+                  minnode = i;
+               }
+            }
+            if (mindist <= 3)
+            {
+               // delete node option
+               lmEventNode_ = minnode;
+               localMenu_->Enable(BG_IMC_ADDNODE,FALSE);
+               localMenu_->Enable(BG_IMC_DELETENODE,TRUE);
+            } else
+            {
+               // add node option
+               localMenu_->Enable(BG_IMC_ADDNODE,TRUE);
+               localMenu_->Enable(BG_IMC_DELETENODE,FALSE);
+            }
+         }
+         else
+         {
+            localMenu_->Enable(BG_IMC_ADDNODE,FALSE);
+            localMenu_->Enable(BG_IMC_DELETENODE,FALSE);
+         }
+         lmEventX_ = x;//+x_offset_;
+         lmEventY_ = y;//+y_offset_;
+         PopupMenu(localMenu_, x+x_offset_, y+y_offset_);
+      }
+   }
+}
+
+/*
+//updates hover menu during scroll event
+void BgImCanvas::OnScroll(wxScrollWinEvent& event)
+{
+
+}
+*/
+
+//attemtps to adjust scroll position of window according
+//to current mouse position
+void BgImCanvas::AdjustScroll(int x, int y, int action)
+{
+	if(zoom_level > 1)
+	{
+
+		//get window width and height
+		int	winWidth, winHeight;
+		GetSize(&winWidth, &winHeight);
+
+		//get window vertical and horzontal scroll position
+		//and offset current mouse position to obtain mouse
+		//position relative to the image
+		x	= x + GetScrollPos(wxHORIZONTAL);
+		y	= y + GetScrollPos(wxVERTICAL);
+
+		//re-location mouse position relative to new image width
+		//and height
+		if(action == ZOOM_IN)
+		{
+			x	= zoom_level*(x/(zoom_level-1));
+			y	= zoom_level*(y/(zoom_level-1));
+		}
+		else if(action == ZOOM_OUT)
+		{
+			x	= zoom_level*(x/(zoom_level+1));
+			y	= zoom_level*(y/(zoom_level+1));
+		}
+
+		//resize scroll
+		int	width	= (pimage->GetHeight())*zoom_level;
+		int	height	= (pimage->GetWidth())*zoom_level;
+		SetScrollbars(1, 1, width, height);
+
+		//set scroll position according to x and y
+		int offset_x	= x/2;
+		int offset_y	= y/2;
+		SetScrollPos(wxHORIZONTAL, offset_x, true);
+		SetScrollPos(wxVERTICAL, offset_y, true);
+
+		//refresh window contents
+		Scroll(offset_x, offset_y);
+	}
+}
+
+void BgImCanvas::OnEvent(wxMouseEvent& event)
+{
+/*
+   wxClientDC dc(this);
+   PrepareDC(dc);
+   
+   wxPoint pt(event.GetLogicalPosition(dc));
+   
+   if (g_xpos > -1 && g_ypos > -1 && event.Dragging())
+   {
+      dc.SetPen(*wxBLACK_PEN);
+      dc.DrawLine(g_xpos, g_ypos, pt.x, pt.y);
+      
+      m_dirty = TRUE;
+   }
+   
+   g_xpos = pt.x;
+   g_ypos = pt.y;
+   */
+
+
+   //store mouse pointer location...
+   m_x_	= event.m_x;
+   m_y_	= event.m_y;
+
+   //keep track of menu window (hide/show)...
+   static bool hideWindow = true;
+   if((m_x_ >= menuXl_)&&(m_y_ >= menuYl_)&&(m_x_ <= menuXu_)&&(m_y_ <= menuYu_))
+	   hideWindow	= false;
+   else if(!event.Leaving())
+	   hideWindow	= true;
+
+   wxClientDC dc(this);
+   PrepareDC(dc);
+   wxPoint pt(event.GetLogicalPosition(dc));
+   static int x;
+   static int y;
+   static int curvedrag;
+   x = pt.x-x_offset_;
+   y = pt.y-y_offset_;
+//   x = event.GetX();
+//   y = event.GetY();
+
+   if (isDragging_ == 0 && event.LeftDown())
+   {
+      // check if over any line
+      if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
+      {
+         if (curveClick_[x+y*ccx_]>0)
+         {
+            isDragging_ = 1;
+            curvedrag = curveClick_[x+y*ccx_]-1;
+            dragCurve_.SetCurve(curveSet_[curveClick_[x+y*ccx_]-1]);
+            dragCurve_.pen_.SetColour(wxColour(128,128,128));
+            dragCurve_.StartDragging(x, y);
+            Refresh();
+         }
+      }
+   }
+   else if (isDragging_ == 1 && event.Dragging())
+   {
+      // modify curve to drag
+      dragCurve_.DragTo(x, y);
+      Refresh(false);
+   }
+   else if (isDragging_ == 1)// && event.LeftUp())
+   {
+      isDragging_ = 0;
+      dragCurve_.EndDragging(x, y);
+      curveSet_[curvedrag]->SetCurve(&dragCurve_);
+      FillCurveClick();
+      mouseModif_ = 1;
+      AddPendingEvent(wxCommandEvent(BG_EVENT_UPDATE, BG_EVENT_UPDATE_ID));
+      Refresh();
+   }
+   else if (isDragging_ == 0 && event.Moving())
+   {
+      // check if over any line
+      if (x>=0 && x<ccx_ && y>=0 && y<ccy_)
+      {
+         if (curveClick_[x+y*ccx_]>0 && crossCursor_ == 0)
+         {
+            crossCursor_ = 1;
+            SetCursor(*wxCROSS_CURSOR);
+         }
+         else if (crossCursor_ == 1)
+         {
+            SetCursor(*wxSTANDARD_CURSOR);
+            crossCursor_ = 0;
+         }
+      }
+   }
+
+   //if zoom is enabled, set the cursor to the zoom icon
+   //otherwise leave it as default
+   if(event.Entering())
+   {
+	   //when parent is not the active child frame, set the cursor
+	   //to wxCURSOR_ARROW
+	   bool	current_child	= false;
+	   wxMDIParentFrame *parent	= (wxMDIParentFrame *)(child_frame_->GetParent());
+	   wxMDIChildFrame	*activeChild	= parent->GetActiveChild();
+	   if(activeChild == (wxMDIChildFrame *) child_frame_)
+		   current_child	= true;
+
+	   if((zoom_out || zoom_in)&&(current_child))
+		   SetCursor(wxCURSOR_MAGNIFIER);
+	   else if((zoom_window)&&(current_child))
+		   SetCursor(wxCURSOR_CROSS);
+	   else
+		   SetCursor(wxCURSOR_ARROW);
+
+	   //indiciate that the window has acquired focus
+	   has_focus	= true;
+
+	   //show the menu window
+	   if((menuWindow)&&(popup))
+		   menuWindow->Show(TRUE);
+   }
+
+   //indicate that the window has lost focus
+   if(event.Leaving())
+   {
+	   //indicate that the window has lost focus
+	   has_focus	= false;
+
+	   //indicate that the mouse pointer is leaving
+	   //this window
+	   leaving		= true;
+
+	   //refresh canvas upon using a zoom window
+	   if(zoom_window)
+		Refresh(false);
+
+	   //hide the menu window
+	   if((hideWindow)&&(popup)&&(menuWindow))
+		   menuWindow->Show(FALSE);
+
+   }
+
+   //check if the left mouse button has been clicked and zoom is activated
+   //if so zoom the image
+   if(event.LeftDown()&&zoom_in)
+	   ZoomIn(m_x_, m_y_);
+
+   if((event.LeftDown())&&zoom_out)
+	   ZoomOut(m_x_, m_y_);
+
+   if(zoom_window)
+	   DisplayZoomWindow(m_x_, m_y_);
+
+}
+
+void BgImCanvas::AddHoverWindow(wxWindow* hoverWindow, int pp)
+{
+	popup		= pp;
+	menuWindow	= hoverWindow;
+	if(popup)	menuWindow->Show(FALSE);
+	else		menuWindow->Show(TRUE);
+	int width, height;
+	menuWindow->GetSize(&width, &height);
+	menuXl_	= HOVER_MENU_X - HOVER_MENU_BOUND;
+	menuYl_	= HOVER_MENU_Y - HOVER_MENU_BOUND;
+	menuXu_	= menuXl_ + width + HOVER_MENU_BOUND;
+	menuYu_	= menuXu_ + width + HOVER_MENU_BOUND;
+	menuWindow->SetSize(HOVER_MENU_X, HOVER_MENU_Y, width, height);
+}
+
+void BgImCanvas::SetHoverWindowLocation(int x, int y)
+{
+	int width, height;
+	menuWindow->GetSize(&width, &height);
+	if((x < 0)||(x >= width)||(y < 0)||(y >= height))	return;
+	menuWindow->SetSize(x, y, width, height);
+}
+
+// ---------------------------------------------------------------------------
+// BgMdiEdgeChild
+// ---------------------------------------------------------------------------
+
+BgMdiEdgeChild::BgMdiEdgeChild(wxMDIParentFrame *parent, const wxString& title,
+                           const wxPoint& pos, const wxSize& size,
+                           const long style)
+                           : wxMDIChildFrame(parent, BG_EDGE_WINDOW, title, pos, size, style)
+{
+
+   //set window number
+   window_number_ = gs_nFrames;
+
+   //assume image is not yet loaded into segmentation window
+   filename_	= NULL;
+
+   bpsize_ = 160;
+
+   imagePlotSplitter_ = new wxSplitterWindow(this, -1, wxPoint(bpsize_, 0), wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   plotSplitter_ = new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   origEdgeImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
+   origEdgeImage_->SetScrollbars(20, 20, 50, 50);
+   plotNmxImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
+
+   plotNmxImage_->SetScrollbars(20, 20, 50, 50);
+   plotTotImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
+
+   plotTotImage_->SetScrollbars(20, 20, 50, 50);
+   
+   g_children.Append(this);
+   //imagePlotSplitter_->SetClientSize(GetClientSize());
+   imagePlotSplitter_->SplitVertically(origEdgeImage_, plotSplitter_,256);
+   plotSplitter_->SplitHorizontally(plotNmxImage_, plotTotImage_,256);
+
+   // panel stuff
+   buttonPanel_ = new wxPanel(this, -1, wxPoint(0, 0));
+   edButton_ = new wxButton(buttonPanel_, BG_EDGE_DETECT, "Edge Detect", wxPoint(40,10));
+   cpButton_ = new wxButton(buttonPanel_, BG_CHANGE_PARAM_EDGE, "Change...", wxPoint(40,155));
+
+   wxStaticBox* viewSB = new wxStaticBox(buttonPanel_, -1, "View", wxPoint(35, 45), wxSize(85, 65)); 
+   viewOrigCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_ORIG, "Image", wxPoint(45,65));//, wxPoint(10,85));
+   viewEdgeCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_EDGE, "Edges", wxPoint(45,85));//, wxPoint(10,105));
+
+   int deltal = 45;
+   // put the parameters
+   wxStaticText* stParam = new wxStaticText(buttonPanel_, -1, "PARAMETERS:", wxPoint(C_PARAMX-5, 105 + C_PARAMY));
+
+   txtKernelSize_ = new wxStaticText(buttonPanel_, -1, "Grad Win.", wxPoint(C_PARAMX-5,deltal+125+C_PARAMY+0*C_PARAMDY));
+   valKernelSize_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX+35,deltal+125+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
+
+   txtMinPt_ = new wxStaticText(buttonPanel_, -1, "Min. length", wxPoint(C_PARAMX-5,deltal+125+C_PARAMY+1*C_PARAMDY));
+   valMinPt_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX+35,deltal+125+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
+
+   wxStaticBox* nmxSB = new wxStaticBox(buttonPanel_, -1, "Nonmaxima supp.", wxPoint(5, deltal+205+0), wxSize(140,4*C_PARAMDY-5));
+   txtNmxType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX, deltal+205+C_PARAMY+0*C_PARAMDY));
+   valNmxType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   txtNmxR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+205+C_PARAMY+1*C_PARAMDY));
+   valNmxR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   txtNmxC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+205+C_PARAMY+2*C_PARAMDY));
+   valNmxC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+205+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+
+   wxStaticBox* hhSB = new wxStaticBox(buttonPanel_, -1, "Hyst. High Tr.", wxPoint(5, deltal+325+0), wxSize(140,4*C_PARAMDY-5));
+   txtHHType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX,deltal+325+C_PARAMY+0*C_PARAMDY));
+   txtHHR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+325+C_PARAMY+1*C_PARAMDY));
+   txtHHC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+325+C_PARAMY+2*C_PARAMDY));
+   valHHType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHHR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHHC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+325+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+
+   wxStaticBox* hlSB = new wxStaticBox(buttonPanel_, -1, "Hyst. Low Tr.", wxPoint(5, deltal+445+0), wxSize(140, 4*C_PARAMDY-5));
+   txtHLType_ = new wxStaticText(buttonPanel_, -1, "Type", wxPoint(C_PARAMX,deltal+445+C_PARAMY+0*C_PARAMDY));
+   txtHLR_ = new wxStaticText(buttonPanel_, -1, "Rank", wxPoint(C_PARAMX,deltal+445+C_PARAMY+1*C_PARAMDY));
+   txtHLC_ = new wxStaticText(buttonPanel_, -1, "Conf", wxPoint(C_PARAMX,deltal+445+C_PARAMY+2*C_PARAMDY));
+   valHLType_ = new wxStaticText(buttonPanel_, -1, "NA    ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHLR_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHLC_ = new wxStaticText(buttonPanel_, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,deltal+445+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   
+
+   //set lower bound zoom limit on display image
+   //to the size of the original image
+   origEdgeImage_->SetMinZoomLevel(1);
+
+   // set default parameters for edge detection
+   rankNmx_ = RANK_NMX;
+   confNmx_ = CONF_NMX;
+   rankH_ = RANK_H;
+   confH_ = CONF_H;
+   rankL_ = RANK_L;
+   confL_ = CONF_L;
+   nMin_ = NMIN;
+   nmxType_ = FC_ELLIPSE;
+   hystHighType_ = FC_SQUARE_BOX;
+   hystLowType_ = FC_ELLIPSE;
+   kernelSize_ = KERNEL_SIZE;
+
+   //set params
+   SetParametersNum();
+   SetParametersStr();
+
+   // also default custom parameters
+   nCustH_ = 3;
+   nCustL_ = 3;
+   custHx_[0] = 0;
+   custHx_[1] = 0.7;
+   custHx_[2] = 1;
+   custHy_[0] = 1;
+   custHy_[1] = 0.7;
+   custHy_[2] = 0;
+
+   custLx_[0] = 0;
+   custLx_[1] = 0.5;
+   custLx_[2] = 0.7;
+   custLy_[0] = 0.7;
+   custLy_[1] = 0.5;
+   custLy_[2] = 0;
+
+   // set the values in the boxes
+
+//   cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
+   cbgEdgeDetect_ = 0;
+   cbgImage_ = new BgImage();
+   cbgEdgeList_ = 0;
+   hasEdge_ = 0;
+   hasImage_ = 0;
+
+   int w, h;
+   GetClientSize(&w, &h);
+   buttonPanel_->SetSize(0, 0, bpsize_, h);
+   imagePlotSplitter_->SetSize(bpsize_, 0, w-bpsize_, h);
+   imagePlotSplitter_->SetSashPosition(bpsize_+(w-bpsize_)/2,TRUE);
+   plotSplitter_->SetSashPosition(h/2,TRUE);
+   rightsize_ = (w-bpsize_)/2;
+   viewOrigCheck_->SetValue(TRUE);
+   viewEdgeCheck_->SetValue(TRUE);
+
+   plotTotImage_->AddCurveSet(&nmxCurve_);
+   plotNmxImage_->AddCurveSet(&highCurve_);
+   plotNmxImage_->AddCurveSet(&lowCurve_);
+   lowCurve_.pen_.SetColour(255,0,0);
+
+   //add margin to plots
+   plotNmxImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+   plotTotImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+
+   //add title to each individual plot
+   BgText bgText(1, "      Diagram after Non-Maxima Supression", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
+
+   plotNmxImage_->AddText(&bgText);
+   bgText.SetText("      Diagram before Non-Maxima Supression");
+   plotTotImage_->AddText(&bgText);
+
+   //add x and y axis
+   plotNmxImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
+   plotNmxImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
+   plotTotImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
+   plotTotImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
+
+   //label x and y axis
+   bgText.SetText("Rank (   )");
+   plotNmxImage_->LabelHorizontalAxis(&bgText);
+   plotTotImage_->LabelHorizontalAxis(&bgText);
+   bgText.SetText("Confidence (  )");
+   plotNmxImage_->LabelVerticalAxis(&bgText);
+   plotTotImage_->LabelVerticalAxis(&bgText);
+
+   //place greek symbols
+   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
+   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
+   plotNmxImage_->AddBitmap(&ro_bmp);
+   plotNmxImage_->AddBitmap(&eta_bmp);
+   plotTotImage_->AddBitmap(&ro_bmp);
+   plotTotImage_->AddBitmap(&eta_bmp);
+   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
+   ro_bmp.SetId(3);
+   plotNmxImage_->AddBitmap(&ro_bmp);
+   plotTotImage_->AddBitmap(&ro_bmp);
+   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
+   plotNmxImage_->AddBitmap(&rotated_eta_bmp);
+   plotTotImage_->AddBitmap(&rotated_eta_bmp);
+
+   //indicate that the edge window is now open
+   window_open	= true;
+
+   //disable edge detection button
+   edButton_->Enable(false);
+
+   //get parent tool bar and update it
+   toolbar	= parent->GetToolBar();
+   UpdateToolBar();
+
+   //set max/min zoom
+   maxZoom_	= 0;
+   minZoom_	= 1;
+
+}
+
+/*
+BgMdiEdgeChild::BgMdiEdgeChild(wxMDIParentFrame *parent, const wxString& title,
+                           const wxPoint& pos, const wxSize& size,
+                           const long style)
+                           : wxMDIChildFrame(parent, BG_EDGE_WINDOW, title, pos, size, style)
+{
+
+   //set window number
+   window_number_ = gs_nFrames;
+
+   //assume image is not yet loaded into segmentation window
+   filename_	= NULL;
+
+   bpsize_ = 100;
+   imagePlotSplitter_ = new wxSplitterWindow(this, -1,wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   plotSplitter_ = new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   origEdgeImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
+   origEdgeImage_->SetScrollbars(20, 20, 50, 50);
+   plotNmxImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
+
+   plotNmxImage_->SetScrollbars(20, 20, 50, 50);
+   plotTotImage_ = new BgImCanvas(this, plotSplitter_, wxDefaultPosition, wxDefaultSize);
+
+   plotTotImage_->SetScrollbars(20, 20, 50, 50);
+   
+   g_children.Append(this);
+   //imagePlotSplitter_->SetClientSize(GetClientSize());
+   imagePlotSplitter_->SplitVertically(origEdgeImage_, plotSplitter_,256);
+   plotSplitter_->SplitHorizontally(plotNmxImage_, plotTotImage_,256);
+   // panel stuff
+   buttonPanel_ = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize);
+   edButton_ = new wxButton(buttonPanel_, BG_EDGE_DETECT, "Edge Detect", wxPoint(10,10));
+   cpButton_ = new wxButton(buttonPanel_, BG_CHANGE_PARAM_EDGE, "Parameters...", wxPoint(10,45));
+   viewOrigCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_ORIG, "View Image", wxPoint(10,85));
+   viewEdgeCheck_ = new wxCheckBox(buttonPanel_, BG_EDGE_CVIEW_EDGE, "View Edges", wxPoint(10,105));
+
+   //set lower bound zoom limit on display image
+   //to the size of the original image
+   origEdgeImage_->SetMinZoomLevel(1);
+
+   // set default parameters for edge detection
+   rankNmx_ = RANK_NMX;
+   confNmx_ = CONF_NMX;
+   rankH_ = RANK_H;
+   confH_ = CONF_H;
+   rankL_ = RANK_L;
+   confL_ = CONF_L;
+   nMin_ = NMIN;
+   nmxType_ = FC_ELLIPSE;
+   hystHighType_ = FC_SQUARE_BOX;
+   hystLowType_ = FC_ELLIPSE;
+   kernelSize_ = KERNEL_SIZE;
+
+   // also default custom parameters
+   nCustH_ = 3;
+   nCustL_ = 3;
+   custHx_[0] = 0;
+   custHx_[1] = 0.7;
+   custHx_[2] = 1;
+   custHy_[0] = 1;
+   custHy_[1] = 0.7;
+   custHy_[2] = 0;
+
+   custLx_[0] = 0;
+   custLx_[1] = 0.5;
+   custLx_[2] = 0.7;
+   custLy_[0] = 0.7;
+   custLy_[1] = 0.5;
+   custLy_[2] = 0;
+
+
+
+//   cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
+   cbgEdgeDetect_ = 0;
+   cbgImage_ = new BgImage();
+   cbgEdgeList_ = 0;
+   hasEdge_ = 0;
+   hasImage_ = 0;
+
+   int w, h;
+   GetClientSize(&w, &h);
+   buttonPanel_->SetSize(w-bpsize_, 0, bpsize_, h);
+   imagePlotSplitter_->SetSize(0, 0, w-bpsize_, h);
+   imagePlotSplitter_->SetSashPosition((w-bpsize_)/2,TRUE);
+   plotSplitter_->SetSashPosition(h/2,TRUE);
+   rightsize_ = (w-bpsize_)/2;
+   viewOrigCheck_->SetValue(TRUE);
+   viewEdgeCheck_->SetValue(TRUE);
+
+   plotTotImage_->AddCurveSet(&nmxCurve_);
+   plotNmxImage_->AddCurveSet(&highCurve_);
+   plotNmxImage_->AddCurveSet(&lowCurve_);
+   lowCurve_.pen_.SetColour(255,0,0);
+
+   //add margin to plots
+   plotNmxImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+   plotTotImage_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+
+   //add title to each individual plot
+   BgText bgText(1, "      Diagram after Non-Maxima Supression", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
+
+   plotNmxImage_->AddText(&bgText);
+   bgText.SetText("      Diagram before Non-Maxima Supression");
+   plotTotImage_->AddText(&bgText);
+
+   //add x and y axis
+   plotNmxImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
+   plotNmxImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
+   plotTotImage_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
+   plotTotImage_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
+
+   //label x and y axis
+   bgText.SetText("Rank (   )");
+   plotNmxImage_->LabelHorizontalAxis(&bgText);
+   plotTotImage_->LabelHorizontalAxis(&bgText);
+   bgText.SetText("Confidence (  )");
+   plotNmxImage_->LabelVerticalAxis(&bgText);
+   plotTotImage_->LabelVerticalAxis(&bgText);
+
+   //place greek symbols
+   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
+   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
+   plotNmxImage_->AddBitmap(&ro_bmp);
+   plotNmxImage_->AddBitmap(&eta_bmp);
+   plotTotImage_->AddBitmap(&ro_bmp);
+   plotTotImage_->AddBitmap(&eta_bmp);
+   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
+   ro_bmp.SetId(3);
+   plotNmxImage_->AddBitmap(&ro_bmp);
+   plotTotImage_->AddBitmap(&ro_bmp);
+   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
+   plotNmxImage_->AddBitmap(&rotated_eta_bmp);
+   plotTotImage_->AddBitmap(&rotated_eta_bmp);
+
+   //indicate that the edge window is now open
+   window_open	= true;
+
+   //disable edge detection button
+   edButton_->Enable(false);
+
+   //get parent tool bar and update it
+   toolbar	= parent->GetToolBar();
+   UpdateToolBar();
+
+   //set max/min zoom
+   maxZoom_	= 0;
+   minZoom_	= 1;
+
+}
+*/
+
+BgMdiEdgeChild::~BgMdiEdgeChild()
+{
+   if(filename_)	delete [] filename_;
+
+   if (hasEdge_ == 1)
+     origEdgeImage_->RemovePointSet(&cbgPointSet_);
+
+   if (cbgEdgeList_ != 0)
+      delete cbgEdgeList_;
+   delete cbgImage_;
+   if (cbgEdgeDetect_ != 0)
+      delete cbgEdgeDetect_;
+
+   delete viewEdgeCheck_;
+   delete viewOrigCheck_;
+   delete cpButton_;
+   delete edButton_;
+   delete buttonPanel_;
+
+
+
+   delete origEdgeImage_;
+   delete plotNmxImage_;
+   delete plotTotImage_;
+
+   delete plotSplitter_;
+   delete imagePlotSplitter_;
+   g_children.DeleteObject(this);
+}
+
+void BgMdiEdgeChild::OnUpdateNum(wxCommandEvent& WXUNUSED(event))
+{
+   double tx[MAX_CUSTOM_NODES];
+   double ty[MAX_CUSTOM_NODES];
+   int ttype,i;
+   int npoints,modif=0;
+   if (plotNmxImage_->mouseModif_ == 1)
+   {
+      modif = 1;
+      // get new hyst params
+      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystHighType_ = ttype;
+         rankH_ = tx[0];
+         confH_ = ty[0];
+      } else
+      {
+         hystHighType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custHx_[i] = tx[i];
+            custHy_[i] = ty[i];
+         }
+         nCustH_ = npoints;
+      }
+      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystLowType_ = ttype;
+         rankL_ = tx[0];
+         confL_ = ty[0];
+      } else
+      {
+         hystLowType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custLx_[i] = tx[i];
+            custLy_[i] = ty[i];
+         }
+         nCustL_ = npoints;
+      }
+      plotNmxImage_->mouseModif_ = 0;
+   }
+   if (plotTotImage_->mouseModif_ == 1)
+   {
+      modif = 1;
+      // get new nmx params
+      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         nmxType_ = ttype;
+         rankNmx_ = tx[0];
+         confNmx_ = ty[0];
+      }
+      plotTotImage_->mouseModif_ = 0;
+   }
+   if (modif == 1)
+   {
+      SetParametersNum();
+      SetParametersStr();
+   }
+}
+
+void BgMdiEdgeChild::SetParametersNum()
+{
+   wxString ts;
+   ts = wxString::Format("%.3g", rankH_);
+   valHHR_->SetLabel(ts);
+   ts = wxString::Format("%.3g", confH_);
+   valHHC_->SetLabel(ts);
+   ts = wxString::Format("%.3g", rankL_);
+   valHLR_->SetLabel(ts);
+   ts = wxString::Format("%.3g", confL_);
+   valHLC_->SetLabel(ts);
+   ts = wxString::Format("%.3g", rankNmx_);
+   valNmxR_->SetLabel(ts);
+   ts = wxString::Format("%.3g", confNmx_);
+   valNmxC_->SetLabel(ts);
+}
+void BgMdiEdgeChild::SetParametersStr()
+{
+   switch(hystHighType_)
+   {
+   case FC_ELLIPSE:
+      valHHType_->SetLabel("arc");
+      break;
+   case FC_VERT_LINE:
+      valHHType_->SetLabel("vertical line");		
+      break;
+   case FC_HORIZ_LINE:
+      valHHType_->SetLabel("horizontal line");		
+      break;
+   case FC_SQUARE_BOX:
+      valHHType_->SetLabel("box");		
+      break;
+   case FC_LINE:
+      valHHType_->SetLabel("line");  		
+      break;
+  	case FC_CUSTOM:
+      valHHType_->SetLabel("custom");
+      break;
+   }
+
+   switch(hystLowType_)
+   {
+   case FC_ELLIPSE:
+      valHLType_->SetLabel("arc");
+      break;
+   case FC_VERT_LINE:
+      valHLType_->SetLabel("vertical line");		
+      break;
+   case FC_HORIZ_LINE:
+      valHLType_->SetLabel("horizontal line");		
+      break;
+   case FC_SQUARE_BOX:
+      valHLType_->SetLabel("box");		
+      break;
+   case FC_LINE:
+      valHLType_->SetLabel("line");  		
+      break;
+  	case FC_CUSTOM:
+      valHLType_->SetLabel("custom");
+      break;
+   }
+
+   switch(nmxType_)
+   {
+   case FC_ELLIPSE:
+      valNmxType_->SetLabel("arc");
+      break;
+   case FC_VERT_LINE:
+      valNmxType_->SetLabel("vertical line");		
+      break;
+   case FC_HORIZ_LINE:
+      valNmxType_->SetLabel("horizontal line");		
+      break;
+   case FC_SQUARE_BOX:
+      valNmxType_->SetLabel("box");		
+      break;
+   case FC_LINE:
+      valNmxType_->SetLabel("line");  		
+      break;
+  	case FC_CUSTOM:
+      valNmxType_->SetLabel("custom");
+      break;
+   }   
+   wxString ts;
+   ts = wxString::Format("%d", nMin_);
+   valMinPt_->SetLabel(ts);
+   ts = wxString::Format("%d", kernelSize_);
+   valKernelSize_->SetLabel(ts);
+
+
+}
+
+void BgMdiEdgeChild::OnViewEdge(wxCommandEvent&  WXUNUSED(event))
+{
+   viewEdgeCheck_->SetValue(miViewEdge_->IsChecked());
+
+   if (hasEdge_ == false)
+      return;
+
+   if (miViewEdge_->IsChecked() == TRUE)
+   {
+      // show edges
+      origEdgeImage_->AddPointSet(&cbgPointSet_);
+
+   }
+   else
+   {
+      // hide edges
+      origEdgeImage_->RemovePointSet(&cbgPointSet_);
+   }
+
+}
+
+void BgMdiEdgeChild::OnViewOrig(wxCommandEvent&  WXUNUSED(event))
+{
+   viewOrigCheck_->SetValue(miViewOrig_->IsChecked());
+
+   if (hasImage_ == false)
+      return;
+
+   if (miViewOrig_->IsChecked() == TRUE)
+   {
+      // show edges
+      //canvas->AddPointSet(edgesSeq_[crtImage_]);
+      origEdgeImage_->ShowBitmap(true);
+   }
+   else
+   {
+      // hide edges
+      //canvas->RemovePointSet(edgesSeq_[crtImage_]);
+      origEdgeImage_->ShowBitmap(false);
+   }
+   origEdgeImage_->Refresh();
+
+}
+
+void BgMdiEdgeChild::OnCViewEdge(wxCommandEvent&  WXUNUSED(event))
+{
+   miViewEdge_->Check(viewEdgeCheck_->GetValue());
+   if (hasEdge_ == false)
+      return;
+
+   if (viewEdgeCheck_->GetValue() == TRUE)
+   {
+      // show edges
+      origEdgeImage_->AddPointSet(&cbgPointSet_);
+
+   }
+   else
+   {
+      // hide edges
+      origEdgeImage_->RemovePointSet(&cbgPointSet_);
+   }
+}
+
+void BgMdiEdgeChild::OnCViewOrig(wxCommandEvent&  WXUNUSED(event))
+{
+   miViewOrig_->Check(viewOrigCheck_->GetValue());
+
+   if (hasImage_ == false)
+      return;
+
+   if (viewOrigCheck_->GetValue() == TRUE)
+   {
+      // show edges
+      //canvas->AddPointSet(edgesSeq_[crtImage_]);
+      origEdgeImage_->ShowBitmap(true);
+   }
+   else
+   {
+      // hide edges
+      //canvas->RemovePointSet(edgesSeq_[crtImage_]);
+      origEdgeImage_->ShowBitmap(false);
+   }
+
+}
+
+
+void BgMdiEdgeChild::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+   int w, h;
+   GetClientSize(&w, &h);
+   buttonPanel_->SetSize(0, 0, bpsize_, h);
+   imagePlotSplitter_->SetSize(bpsize_, 0, w-bpsize_, h);
+   plotSplitter_->SetSashPosition(h/2,TRUE);
+   h = w-bpsize_-rightsize_;
+   h = (h<0)? 0:h;
+   imagePlotSplitter_->SetSashPosition(h,TRUE);
+}
+
+void BgMdiEdgeChild::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+   Close(TRUE);
+}
+
+void BgMdiEdgeChild::OnClose(wxCloseEvent& event)
+{
+   gs_nFrames--;
+   //indicate that the window is closed (used by OnFocus)
+   window_open	= false;
+   //reset toolbar
+   if(gs_nFrames == 0) ResetToolBar();
+   event.Skip();
+}
+
+void BgMdiEdgeChild::OnFocus(wxFocusEvent& WXUNUSED(event))
+{
+	//update toolbar
+	if(!on_exit) UpdateToolBar();
+	return;
+}
+
+void BgMdiEdgeChild::ZoomWindow(void)
+{
+	//display zoom window
+	origEdgeImage_->zoom_window	= true;
+	origEdgeImage_->zoom_in		= false;
+	origEdgeImage_->zoom_out		= false;
+}
+
+void BgMdiEdgeChild::ZoomIn(void)
+{
+	//zoom into display image
+	origEdgeImage_->zoom_window	= false;
+	origEdgeImage_->zoom_in		= true;
+	origEdgeImage_->zoom_out		= false;
+	return;
+}
+
+void BgMdiEdgeChild::ZoomOut(void)
+{
+	//zoom out of display image
+	origEdgeImage_->zoom_window	= false;
+	origEdgeImage_->zoom_in		= false;
+	origEdgeImage_->zoom_out		= true;
+	return;
+}
+
+void BgMdiEdgeChild::NoZoom(void)
+{
+	//do not zoom display image
+	origEdgeImage_->zoom_window	= false;
+	origEdgeImage_->zoom_in		= false;
+	origEdgeImage_->zoom_out	= false;
+	return;
+}
+
+void BgMdiEdgeChild::UpdateZoomControl(void)
+{
+	//determine whether to enable zoom in control based on maximum zoom
+	if(maxZoom_ || minZoom_)
+		UpdateToolBar();
+	else
+	{
+//		toolbar->Realize();
+		toolbar->EnableTool(BG_ZOOM_IN, true);
+		toolbar->EnableTool(BG_ZOOM_OUT, true);
+	}
+}
+
+void BgMdiEdgeChild::RunEnable(void)
+{
+	edButton_->Enable(true);
+	wxMenuBar *menubar = GetMenuBar();
+	menubar->Enable(BG_EDGE_DETECT, true);
+}
+
+void BgMdiEdgeChild::SaveEnable(void)
+{
+//	toolbar->Realize();
+	toolbar->EnableTool(BG_SAVE_RESULT, true);
+}
+
+void BgMdiEdgeChild::UpdateToolBar(void)
+{
+	//update toolbar
+	if(window_open)
+	{
+		//determine whether to enable save based on whether segmentation
+		//has occurred
+		bool save_enable;
+		if(hasEdge_)
+			save_enable	= true;
+		else
+			save_enable	= false;
+
+		//determine whether to enable zoom controls based on whether image
+		//has been loaded
+		bool load_enable;
+		if(hasImage_)
+			load_enable	= true;
+		else
+			load_enable	= false;
+
+		//determine whether to enable zoom in control based on maximum zoom
+		bool max_zoom;
+		if(maxZoom_)
+			max_zoom	= true;
+		else
+			max_zoom	= false;
+
+		//determine whether to enable zoom out control based on minimum zoom
+		bool min_zoom;
+		if(minZoom_)
+			min_zoom	= true;
+		else
+			min_zoom	= false;
+
+		//adjust toolbar
+		toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to perform edge detection");
+		toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save edge map");
+		toolbar->EnableTool(BG_SAVE_RESULT, save_enable);
+		toolbar->EnableTool(BG_CROSS, load_enable);
+		toolbar->EnableTool(BG_ZOOM_IN, ((load_enable)&&(!max_zoom)));
+		toolbar->EnableTool(BG_ZOOM_OUT, ((load_enable)&&(!min_zoom)));
+		toolbar->EnableTool(BG_POINTER, true);
+
+		//set to no zoom
+		toolbar->ToggleTool(BG_CROSS, false);
+		toolbar->ToggleTool(BG_ZOOM_IN, false);
+		toolbar->ToggleTool(BG_ZOOM_OUT, false);
+		toolbar->ToggleTool(BG_POINTER, true);
+		origEdgeImage_->SetCursor(wxCURSOR_ARROW);
+		NoZoom();
+
+//		toolbar->Realize();
+	}
+	return;
+}
+
+void BgMdiEdgeChild::ResetToolBar(void)
+{
+	//update toolbar
+	toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to process");
+	toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save result");
+	toolbar->EnableTool(BG_SAVE_RESULT, false);
+	toolbar->EnableTool(BG_CROSS, false);
+	toolbar->EnableTool(BG_ZOOM_IN, false);
+	toolbar->EnableTool(BG_ZOOM_OUT, false);
+	toolbar->EnableTool(BG_POINTER, false);
+	toolbar->ToggleTool(BG_CROSS, false);
+	toolbar->ToggleTool(BG_ZOOM_IN, false);
+	toolbar->ToggleTool(BG_ZOOM_OUT, false);
+	toolbar->ToggleTool(BG_POINTER, false);
+//	toolbar->Realize();
+	return;
+}
+
+void BgMdiEdgeChild::ReadImage(char *pathname, char *filename)
+{
+	plotTotImage_->ClearData(1);
+	plotNmxImage_->ClearData(1);
+	
+	if (origEdgeImage_->SetImage(pathname) == 0)
+		return;
+	bgLog("Image %s loaded\n",pathname);
+
+	//obtain and store image filename
+	if(filename_)	delete [] filename_;
+	filename_	= new char [strlen(filename) + 1];
+	strcpy(filename_, filename);
+	
+	miViewOrig_->Check(TRUE);
+	viewOrigCheck_->SetValue(TRUE);
+	origEdgeImage_->showbitmap_ = true;
+	
+	if (hasEdge_ == 1)
+        origEdgeImage_->RemovePointSet(&cbgPointSet_);
+	// set cbgImage
+	cbgImage_->SetImageFromRGB(origEdgeImage_->pimage->GetData(), origEdgeImage_->pimage->GetWidth(), origEdgeImage_->pimage->GetHeight());
+	if (cbgEdgeDetect_ != 0)
+		delete cbgEdgeDetect_;
+	cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
+	hasImage_ = 1;
+	hasEdge_ = 0;
+	
+	//get image dimension
+	width_			= origEdgeImage_->pimage->GetWidth();
+	height_			= origEdgeImage_->pimage->GetHeight();
+	
+	//reset the zoom level of the original edge image
+	origEdgeImage_->Zoom(1);
+	
+	//reset max/min zoom flags
+	maxZoom_	= 0;
+	minZoom_	= 1;
+	
+	//update interface...
+	
+	/***********************************************/
+	
+	//enable run
+	RunEnable();
+	
+	//update the tool bar
+	UpdateToolBar();
+	
+	//set window title
+	wxString statusname;
+	statusname.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
+	SetTitle(statusname);
+	
+	/***********************************************/
+}
+
+void BgMdiEdgeChild::OnLoadImage(wxCommandEvent& WXUNUSED(event))
+{
+   // get the file name
+//   wxFileDialog filedialog(this,"Choose an image file","","",
+//      "All files (*.*)|*.*|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm",
+//      wxOPEN);
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+  wxFileDialog filedialog(this,"Choose an image file","","",
+			  "*",wxOPEN);
+#else
+   wxFileDialog filedialog(this,"Choose an image file","","",
+      "Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
+      wxOPEN);
+#endif
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+      plotTotImage_->ClearData(1);
+      plotNmxImage_->ClearData(1);
+
+      if (hasEdge_ == 1)
+        origEdgeImage_->RemovePointSet(&cbgPointSet_);
+
+      if (origEdgeImage_->SetImage(filedialog.GetPath().c_str()) == 0)
+         return;
+      bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
+
+	  //obtain and store image filename
+	  if(filename_)	delete [] filename_;
+	  filename_	= new char [strlen(filedialog.GetFilename().c_str()) + 1];
+	  strcpy(filename_, filedialog.GetFilename().c_str());
+
+      miViewOrig_->Check(TRUE);
+      viewOrigCheck_->SetValue(TRUE);
+      origEdgeImage_->showbitmap_ = true;
+
+      // set cbgImage
+      cbgImage_->SetImageFromRGB(origEdgeImage_->pimage->GetData(), origEdgeImage_->pimage->GetWidth(), origEdgeImage_->pimage->GetHeight());
+      if (cbgEdgeDetect_ != 0)
+         delete cbgEdgeDetect_;
+      cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
+      hasImage_ = 1;
+      hasEdge_ = 0;
+
+	  //get image dimension
+	  width_			= origEdgeImage_->pimage->GetWidth();
+	  height_			= origEdgeImage_->pimage->GetHeight();
+
+	  //reset the zoom level of the original edge image
+	  origEdgeImage_->Zoom(1);
+
+	  //reset max/min zoom flags
+	  maxZoom_	= 0;
+	  minZoom_	= 1;
+
+	  //update interface...
+
+	  /***********************************************/
+	  //enable run
+	  RunEnable();
+
+	  //update the tool bar
+	  UpdateToolBar();
+
+	  //set window title
+      wxString statusname;
+      statusname.Printf(_T("Edge Detection Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
+      SetTitle(statusname);
+
+	  /***********************************************/
+   }
+}
+
+void BgMdiEdgeChild::OnSaveEdgeMap(wxCommandEvent& WXUNUSED(event))
+{
+   if (hasEdge_ == 0)
+   {
+      bgLog("No edge map, run edge detection first!\n");
+      return;
+   }
+   // get the file name
+   wxFileDialog filedialog(this,"Choose an image file","","",
+      "PGM files (*.pgm)|*.pgm",
+      wxSAVE);
+
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+      BgImage tempImage(cbgImage_->x_, cbgImage_->y_);
+      cbgEdgeList_->SetBinImage(&tempImage);
+      write_pgm_image(filedialog.GetPath().c_str(), tempImage.im_, tempImage.y_, tempImage.x_, "", 255);
+      bgLog("Edge map saved in: %s\n",filedialog.GetPath().c_str());
+
+      char tch[100];
+      sprintf(tch,"%s.txt",filedialog.GetPath().c_str());
+      cbgEdgeList_->SaveEdgeList(tch);
+   }
+}
+
+void BgMdiEdgeChild::OnEdgeDetect(wxCommandEvent& WXUNUSED(event))
+{
+   // determine if we have image
+   if (cbgImage_->hasIm_ == false)
+   {
+      //no image loaded
+      bgLog("No image loaded!\n");
+      return;
+   }
+   if (hasEdge_ == 1)
+      origEdgeImage_->RemovePointSet(&cbgPointSet_);
+   
+   if (cbgEdgeList_ != 0)
+      delete cbgEdgeList_;
+   cbgEdgeList_ = new BgEdgeList();
+
+   // test if modif params
+   double tx[MAX_CUSTOM_NODES];
+   double ty[MAX_CUSTOM_NODES];
+   int ttype,i;
+   int npoints;
+
+   if (plotTotImage_->mouseModif_ == 1)
+   {
+      // get new nmx params
+      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         nmxType_ = ttype;
+         rankNmx_ = tx[0];
+         confNmx_ = ty[0];
+      }
+      plotTotImage_->mouseModif_ = 0;
+   }
+   if (plotNmxImage_->mouseModif_ == 1)
+   {
+      // get new hyst params
+      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystHighType_ = ttype;
+         rankH_ = tx[0];
+         confH_ = ty[0];
+      } else
+      {
+         hystHighType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custHx_[i] = tx[i];
+            custHy_[i] = ty[i];
+         }
+         nCustH_ = npoints;
+      }
+      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystLowType_ = ttype;
+         rankL_ = tx[0];
+         confL_ = ty[0];
+      } else
+      {
+         hystLowType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custLx_[i] = tx[i];
+            custLy_[i] = ty[i];
+         }
+         nCustL_ = npoints;
+      }
+      plotNmxImage_->mouseModif_ = 0;
+   }
+
+   if (hystHighType_ == FC_CUSTOM)
+      cbgEdgeDetect_->SetCustomHigh(custHx_, custHy_, nCustH_);
+   if (hystLowType_ == FC_CUSTOM)
+      cbgEdgeDetect_->SetCustomLow(custLx_, custLy_, nCustL_);
+
+   // determine if we have permanent data
+   if (cbgEdgeDetect_->havePerm_ == true) {
+      // compute only nmx and hyst
+      cbgEdgeDetect_->DoRecompute(cbgEdgeList_, rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_,
+         nMin_, nmxType_, hystHighType_, hystLowType_);
+      // set only nmx image
+      SetNmxImage();
+   }
+   else
+   {
+      // compute all steps
+      cbgEdgeDetect_->DoEdgeDetect(cbgImage_, cbgEdgeList_, rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_,
+         nMin_, nmxType_, hystHighType_, hystLowType_);
+      // set total and nmx image
+      SetTotalImage();
+      SetNmxImage();
+   }
+
+   // get binary edge image
+   BgImage tempImage(cbgImage_->x_, cbgImage_->y_);
+   cbgEdgeList_->SetBinImage(&tempImage);
+
+   int* edgex;
+   int* edgey;
+   int nEdgep;
+   edgex = new int[(cbgImage_->x_) * (cbgImage_->y_)];
+   edgey = new int[(cbgImage_->x_) * (cbgImage_->y_)];
+   cbgPointSet_.type_ = 1;
+
+   cbgEdgeList_->GetAllEdgePoints(edgex, edgey, &nEdgep);
+   cbgPointSet_.SetPoints(edgex, edgey, nEdgep);
+   hasEdge_ = 1;
+   delete [] edgey;
+   delete [] edgex;
+
+   // update image canvas
+   if (miViewEdge_->IsChecked())
+      origEdgeImage_->AddPointSet(&cbgPointSet_);
+
+   //active save tool
+   SaveEnable();
+
+   //update menu bar
+   wxMenuBar *menubar = GetMenuBar();
+   menubar->Enable(BG_EDGE_SAVE_MAP, true);
+
+}
+
+void BgMdiEdgeChild::SetTotalImage(void)
+{
+   unsigned char* buf;
+   int xsz = RANK_CONF_IMSIZEX;
+   int ysz = RANK_CONF_IMSIZEY;
+   int imsz = xsz*ysz;
+   buf = new unsigned char[imsz];
+   int i;
+   for (i=0; i<imsz; i++)
+      buf[i] = 255;
+
+   int l, c;
+   int xo = cbgEdgeDetect_->x_;
+   int yo = cbgEdgeDetect_->y_;
+   float* rank;
+   float* conf;
+   rank = cbgEdgeDetect_->permRank_;
+   conf = cbgEdgeDetect_->permConf_;
+   for (i=0; i<xo*yo; i++)
+   {
+      if (rank[i]>0 && conf[i]>0)
+      {
+         c = (int) (rank[i]*((double) xsz));
+         c = (c>=xsz) ? xsz-1 : c;
+         l = (int) (conf[i]*((double) ysz));
+         l = (l>=ysz) ? ysz-1 : l;
+         l = ysz-1-l;
+         buf[c+l*xsz]=80;
+      }
+   }
+
+   nmxCurve_.SetParamCurve(nmxType_, &rankNmx_, &confNmx_, 1, xsz, ysz);
+   plotTotImage_->SetImageFromGray(buf, xsz, ysz);
+   plotTotImage_->FillCurveClick();
+
+   delete [] buf;
+
+}
+
+void BgMdiEdgeChild::SetNmxImage(void)
+{
+   unsigned char* buf;
+   int xsz = RANK_CONF_IMSIZEX;
+   int ysz = RANK_CONF_IMSIZEY;
+   int imsz = xsz*ysz;
+   buf = new unsigned char[imsz];
+   int i;
+   for (i=0; i<imsz; i++)
+      buf[i] = 255;
+
+   int l, c;
+   int xo = cbgEdgeDetect_->x_;
+   int yo = cbgEdgeDetect_->y_;
+   float* rank;
+   float* conf;
+   rank = cbgEdgeDetect_->permNmxRank_;
+   conf = cbgEdgeDetect_->permNmxConf_;
+   for (i=0; i<xo*yo; i++)
+   {
+      if (rank[i]>0 && conf[i]>0)
+      {
+         c = (int) (rank[i]*((double) xsz));
+         c = (c>=xsz) ? xsz-1 : c;
+         l = (int) (conf[i]*((double) ysz));
+         l = (l>=ysz) ? ysz-1 : l;
+         l = ysz-1-l;
+         buf[c+l*xsz]=80;
+      }
+   }
+   
+   if (hystHighType_ != FC_CUSTOM)
+      highCurve_.SetParamCurve(hystHighType_, &rankH_, &confH_, 1, xsz, ysz);
+   else 
+   {
+      highCurve_.SetParamCurve(hystHighType_, custHx_, custHy_, nCustH_, xsz, ysz);
+   }
+   if (hystLowType_ != FC_CUSTOM)
+      lowCurve_.SetParamCurve(hystLowType_, &rankL_, &confL_, 1, xsz, ysz);
+   else 
+   {
+      lowCurve_.SetParamCurve(hystLowType_, custLx_, custLy_, nCustL_, xsz, ysz);
+   }
+   plotNmxImage_->SetImageFromGray(buf, xsz, ysz);
+   plotNmxImage_->FillCurveClick();
+
+   delete [] buf;
+
+}
+
+void BgMdiEdgeChild::OnChangeParam(wxCommandEvent& WXUNUSED(event))
+{
+   // show the parameters window and change it
+   double tx[20];
+   double ty[20];
+   int ttype,i;
+   int npoints;
+   if (plotTotImage_->mouseModif_ == 1)
+   {
+      // get new nmx params
+      nmxCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         nmxType_ = ttype;
+         rankNmx_ = tx[0];
+         confNmx_ = ty[0];
+      }
+      plotTotImage_->mouseModif_ = 0;
+   }
+   if (plotNmxImage_->mouseModif_ == 1)
+   {
+      // get new hyst params
+      highCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystHighType_ = ttype;
+         rankH_ = tx[0];
+         confH_ = ty[0];
+      } else
+      {
+         hystHighType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custHx_[i] = tx[i];
+            custHy_[i] = ty[i];
+         }
+         rankH_ = tx[npoints-1];
+         confH_ = ty[0];
+         nCustH_ = npoints;
+      }
+      lowCurve_.GetParamCurve(tx, ty, ttype,npoints);
+      if ((ttype!=FC_CUSTOM) && (ttype!=-1))
+      {
+         hystLowType_ = ttype;
+         rankL_ = tx[0];
+         confL_ = ty[0];
+      } else
+      {
+         hystLowType_ = ttype;
+         for (i=0; i<npoints; i++)
+         {
+            custLx_[i] = tx[i];
+            custLy_[i] = ty[i];
+         }
+         rankL_ = tx[npoints-1];
+         confL_ = ty[0];
+         nCustL_ = npoints;
+      }
+      plotNmxImage_->mouseModif_ = 0;
+   }
+   BgParamDialog paramDialog(this, -1, "Change Parameters", wxDefaultPosition, wxSize(250,510),
+      wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL);
+   paramDialog.SetValues(rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_, nMin_,
+      nmxType_, hystHighType_, hystLowType_, kernelSize_);
+   if (paramDialog.ShowModal()==wxID_OK)
+   {
+      // do change param stuff
+      int tempKernelSize;
+      tempKernelSize = kernelSize_;
+      paramDialog.GetValues(rankNmx_, confNmx_, rankH_, confH_, rankL_, confL_, nMin_,
+         nmxType_, hystHighType_, hystLowType_, tempKernelSize);
+      if (tempKernelSize != kernelSize_)
+      {
+         kernelSize_ = tempKernelSize;
+         if (cbgEdgeDetect_ != 0) {
+            delete cbgEdgeDetect_;
+            cbgEdgeDetect_ = new BgEdgeDetect(kernelSize_);
+         }
+      }
+
+      // change image param
+      int xsz = RANK_CONF_IMSIZEX;
+      int ysz = RANK_CONF_IMSIZEY;
+      
+      if (hystHighType_ != FC_CUSTOM)
+         highCurve_.SetParamCurve(hystHighType_, &rankH_, &confH_, 1, xsz, ysz);
+      else 
+      {
+         highCurve_.SetParamCurve(hystHighType_, custHx_, custHy_, nCustH_, xsz, ysz);
+      }
+      if (hystLowType_ != FC_CUSTOM)
+         lowCurve_.SetParamCurve(hystLowType_, &rankL_, &confL_, 1, xsz, ysz);
+      else 
+      {
+         lowCurve_.SetParamCurve(hystLowType_, custLx_, custLy_, nCustL_, xsz, ysz);
+      }
+
+      nmxCurve_.SetParamCurve(nmxType_, &rankNmx_, &confNmx_, 1, xsz, ysz);
+
+      plotNmxImage_->FillCurveClick();
+      plotTotImage_->FillCurveClick();
+
+      SetParametersStr();
+      SetParametersNum();
+   }
+}
+
+
+// ---------------------------------------------------------------------------
+// BgParamDialog
+// ---------------------------------------------------------------------------
+
+BgParamDialog::BgParamDialog(wxWindow* parent, wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      long style, const wxString& name)
+: wxDialog(parent, id, title, pos, size, style, name)
+{
+   okButton_ = new wxButton(this, BG_PARAMD_OK, "Ok", wxPoint(20+C_PARAMX+10,450));
+   cancelButton_ = new wxButton(this, BG_PARAMD_CANCEL, "Cancel", wxPoint(20+C_PARAMX+10+C_PARAMDX+60,450));
+   
+   /*
+   txtNmxR_ = new wxStaticText(this, -1, "Nmx. rank: ", wxPoint(C_PARAMX,C_PARAMY+0*C_PARAMDY));
+   txtNmxC_ = new wxStaticText(this, -1, "Nmx. conf: ", wxPoint(C_PARAMX,C_PARAMY+1*C_PARAMDY));
+   txtHHR_ = new wxStaticText(this, -1, "Hyst. high rank: ", wxPoint(C_PARAMX,C_PARAMY+2*C_PARAMDY));
+   txtHHC_ = new wxStaticText(this, -1, "Hyst. high conf: ", wxPoint(C_PARAMX,C_PARAMY+3*C_PARAMDY));
+   txtHLR_ = new wxStaticText(this, -1, "Hyst. low rank: ", wxPoint(C_PARAMX,C_PARAMY+4*C_PARAMDY));
+   txtHLC_ = new wxStaticText(this, -1, "Hyst. low conf: ", wxPoint(C_PARAMX,C_PARAMY+5*C_PARAMDY));
+   txtMinPt_ = new wxStaticText(this, -1, "Min. points: ", wxPoint(C_PARAMX,C_PARAMY+6*C_PARAMDY));
+   txtNmxType_ = new wxStaticText(this, -1, "Nmx. type: ", wxPoint(C_PARAMX,C_PARAMY+7*C_PARAMDY));
+   txtHHType_ = new wxStaticText(this, -1, "Hyst. high type: ", wxPoint(C_PARAMX,C_PARAMY+8*C_PARAMDY));
+   txtHLType_ = new wxStaticText(this, -1, "Hyst. low: ", wxPoint(C_PARAMX,C_PARAMY+9*C_PARAMDY));
+   txtKernelSize_ = new wxStaticText(this, -1, "Kernel radius: ", wxPoint(C_PARAMX,C_PARAMY+10*C_PARAMDY));
+
+   valNmxR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+0*C_PARAMDY));
+   valNmxC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+1*C_PARAMDY));
+   valHHR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+2*C_PARAMDY));
+   valHHC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+3*C_PARAMDY));
+   valHLR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+4*C_PARAMDY));
+   valHLC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+5*C_PARAMDY));
+   valMinPt_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+6*C_PARAMDY));
+   valNmxType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+7*C_PARAMDY), wxDefaultSize);
+   valHHType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+8*C_PARAMDY), wxDefaultSize);
+   valHLType_ = new wxChoice(this, -1, wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+9*C_PARAMDY), wxDefaultSize);
+   valKernelSize_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(C_PARAMX+C_PARAMDX,C_PARAMY+10*C_PARAMDY));
+   */
+
+   txtKernelSize_ = new wxStaticText(this, -1, "Grad Win.", wxPoint(20+C_PARAMX-5,0+C_PARAMY+0*C_PARAMDY));
+   valKernelSize_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX+35,0+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
+
+   txtMinPt_ = new wxStaticText(this, -1, "Min. length", wxPoint(20+C_PARAMX-5,0+C_PARAMY+1*C_PARAMDY));
+   valMinPt_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX+35,0+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX-20,C_PARAMSY));
+
+   wxStaticBox* nmxSB = new wxStaticBox(this, -1, "Nonmaxima supp.", wxPoint(20+5, 80+0), wxSize(140,4*C_PARAMDY-5));
+   txtNmxType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX, 80+C_PARAMY+0*C_PARAMDY));
+   valNmxType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   txtNmxR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,80+C_PARAMY+1*C_PARAMDY));
+   valNmxR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   txtNmxC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,80+C_PARAMY+2*C_PARAMDY));
+   valNmxC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,80+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+
+   wxStaticBox* hhSB = new wxStaticBox(this, -1, "Hyst. High Tr.", wxPoint(20+5, 200+0), wxSize(140,4*C_PARAMDY-5));
+   txtHHType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX,200+C_PARAMY+0*C_PARAMDY));
+   txtHHR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,200+C_PARAMY+1*C_PARAMDY));
+   txtHHC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,200+C_PARAMY+2*C_PARAMDY));
+   valHHType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHHR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHHC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,200+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+
+   wxStaticBox* hlSB = new wxStaticBox(this, -1, "Hyst. Low Tr.", wxPoint(20+5, 320+0), wxSize(140, 4*C_PARAMDY-5));
+   txtHLType_ = new wxStaticText(this, -1, "Type", wxPoint(20+C_PARAMX,320+C_PARAMY+0*C_PARAMDY));
+   txtHLR_ = new wxStaticText(this, -1, "Rank", wxPoint(20+C_PARAMX,320+C_PARAMY+1*C_PARAMDY));
+   txtHLC_ = new wxStaticText(this, -1, "Conf", wxPoint(20+C_PARAMX,320+C_PARAMY+2*C_PARAMDY));
+   valHLType_ = new wxChoice(this, -1, wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+0*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHLR_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+1*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+   valHLC_ = new wxTextCtrl(this, -1, "NA     ", wxPoint(20+C_PARAMX+C_PARAMDX,320+C_PARAMY+2*C_PARAMDY), wxSize(C_PARAMSX,C_PARAMSY));
+
+
+
+   // put choices
+   valNmxType_->Append("Arc");
+   valNmxType_->Append("Vertical Line");
+   valNmxType_->Append("Horizontal Line");
+   valNmxType_->Append("Line");
+   valNmxType_->Append("Box");
+
+   valHHType_->Append("Arc");
+   valHHType_->Append("Vertical Line");
+   valHHType_->Append("Horizontal Line");
+   valHHType_->Append("Line");
+   valHHType_->Append("Box");
+   valHHType_->Append("Custom");
+
+   valHLType_->Append("Arc");
+   valHLType_->Append("Vertical Line");
+   valHLType_->Append("Horizontal Line");
+   valHLType_->Append("Line");
+   valHLType_->Append("Box");
+   valHLType_->Append("Custom");
+
+}
+
+BgParamDialog::~BgParamDialog()
+{
+   delete txtNmxR_;
+   delete txtNmxC_;
+   delete txtHHR_;
+   delete txtHHC_;
+   delete txtHLR_;
+   delete txtHLC_;
+   delete txtMinPt_;
+   delete txtNmxType_;
+   delete txtHHType_;
+   delete txtHLType_;
+   delete txtKernelSize_;
+
+   delete valNmxR_;
+   delete valNmxC_;
+   delete valHHR_;
+   delete valHHC_;
+   delete valHLR_;
+   delete valHLC_;
+   delete valMinPt_;
+   delete valNmxType_;
+   delete valHHType_;
+   delete valHLType_;
+   delete valKernelSize_;
+
+   delete okButton_;
+   delete cancelButton_;
+}
+
+void BgParamDialog::OnOk(wxCommandEvent& WXUNUSED(event))
+{
+   EndModal(wxID_OK);
+}
+
+void BgParamDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+   EndModal(wxID_CANCEL);
+}
+
+void BgParamDialog::SetValues(double nmxR, double nmxC, double hhR, double hhC, double hlR, double hlC,
+                              int nMin, int nmxT, int hhT, int hlT, int ks)
+{
+   wxString ts;
+   ts = wxString::Format("%.3g", nmxR);
+   valNmxR_->SetValue(ts);
+   ts = wxString::Format("%.3g", nmxC);
+   valNmxC_->SetValue(ts);
+   ts = wxString::Format("%.3g", hhR);
+   valHHR_->SetValue(ts);
+   ts = wxString::Format("%.3g", hhC);
+   valHHC_->SetValue(ts);
+   ts = wxString::Format("%.3g", hlR);
+   valHLR_->SetValue(ts);
+   ts = wxString::Format("%.3g", hlC);
+   valHLC_->SetValue(ts);
+   ts = wxString::Format("%d", nMin);
+   valMinPt_->SetValue(ts);
+   valNmxType_->SetSelection(nmxT);
+   valHHType_->SetSelection(hhT);
+   valHLType_->SetSelection(hlT);
+   ts = wxString::Format("%d", ks);
+   valKernelSize_->SetValue(ts);
+
+}
+
+void BgParamDialog::GetValues(double& nmxR, double& nmxC, double& hhR, double& hhC, double& hlR, double& hlC,
+                              int& nMin, int& nmxT, int& hhT, int& hlT, int& ks)
+{
+   double td;
+   long tl;
+   int ti;
+
+   td = -1;
+   tl = -1;
+   ti = -1;
+   if ((valNmxR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      nmxR = td;
+   else
+      bgLog("nmx. rank value out of range.\n");
+   
+   if ((valNmxC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      nmxC = td;
+   else
+      bgLog("nmx. conf. value out of range.\n");
+
+   if ((valHHR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      hhR = td;
+   else
+      bgLog("hyst. high rank value out of range.\n");
+
+   if ((valHHC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      hhC = td;
+   else
+      bgLog("hyst. high conf. value out of range.\n");
+
+   if ((valHLR_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      hlR = td;
+   else
+      bgLog("hyst. low rank value out of range.\n");
+
+   if ((valHLC_->GetValue().ToDouble(&td) == TRUE) && (td>=0))
+      hlC = td;
+   else
+      bgLog("hyst. low conf. value out of range.\n");
+
+   if ((valMinPt_->GetValue().ToLong(&tl) == TRUE) && (tl>=0))
+      nMin = (int) tl;
+   else
+      bgLog("min. edge points value out of range.\n");
+
+   if ((ti=valNmxType_->GetSelection()) != -1)
+      nmxT = ti;
+
+   if ((ti=valHHType_->GetSelection()) != -1)
+      hhT = ti;
+
+   if ((ti=valHLType_->GetSelection()) != -1)
+      hlT = ti;
+
+   if ((valKernelSize_->GetValue().ToLong(&tl) == TRUE) && (tl>0) && ((2*tl+1)<=MAX_FILTS))
+      ks = (int) tl;
+   else
+      bgLog("kernel radius value out of range.\n");
+
+
+}
+
+// ---------------------------------------------------------------------------
+// BgSpeedSelect
+// ---------------------------------------------------------------------------
+
+BgSpeedSelect::BgSpeedSelect(wxWindow* parent, wxWindowID id, const wxString& title,
+      const wxPoint& pos, const wxSize& size,
+      long style, const wxString& name)
+: wxDialog(parent, id, title, pos, size, style, name)
+{
+   okButton_ = new wxButton(this, BG_SPEEDSEL_OK, "Ok", wxPoint(30,80));
+   cancelButton_ = new wxButton(this, BG_SPEEDSEL_CANCEL, "Cancel", wxPoint(120,80));
+   
+   txtQuality_ = new wxStaticText(this, -1, "Speed", wxPoint(160, 10));
+   txtSpeed_ = new wxStaticText(this, -1, "Quality", wxPoint(40, 10));
+
+   sldSpeed_ = new wxSlider(this, BG_SPEEDSEL_SLD, 0, 0, 100, wxPoint(18,40), wxSize(155,-1),
+                             wxSL_AUTOTICKS | wxSL_LABELS);
+   sldSpeed_->SetTickFreq(20, 0);
+}
+
+BgSpeedSelect::~BgSpeedSelect()
+{
+   delete sldSpeed_;
+
+   delete okButton_;
+   delete cancelButton_;
+}
+
+void BgSpeedSelect::OnOk(wxCommandEvent& WXUNUSED(event))
+{
+   EndModal(wxID_OK);
+}
+
+void BgSpeedSelect::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+   EndModal(wxID_CANCEL);
+}
+
+void BgSpeedSelect::SetSliderValue(float sliderV)
+{
+   sldSpeed_->SetValue((int) (sliderV*100));
+}
+
+void BgSpeedSelect::GetSliderValue(float& sliderV)
+{
+   sliderV = (float) (sldSpeed_->GetValue() / 100.0);
+}
+
+// ---------------------------------------------------------------------------
+// BgMdiSegmentChild
+// ---------------------------------------------------------------------------
+
+BgMdiSegmentChild::BgMdiSegmentChild(wxMDIParentFrame *parent, const wxString& title,
+                           const wxPoint& pos, const wxSize& size,
+                           const long style)
+                           : wxMDIChildFrame(parent, BG_SEGM_WINDOW, title, pos, size, style)
+{
+
+   //set window number
+   window_number_ = gs_nFrames;
+
+   //assume image is not yet loaded into segmentation window
+   filename_	= NULL;
+
+   //split window to display the segmented image on the left hand side,
+   //and the ph diagram on the right hand side
+   imagePlotSplitter_	= new wxSplitterWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   plotMapSplitter_		= new wxSplitterWindow(imagePlotSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+   mapSplitter_			= new wxSplitterWindow(plotMapSplitter_, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_3DSASH);
+
+   //create option panels
+   winPanel1_ = new BgMenuPanel(mapSplitter_, -1, BG_CANVAS_VIEW1_GRADMAP, BG_CANVAS_VIEW1_CONFMAP, BG_CANVAS_VIEW1_WEITMAP, BG_CANVAS_VIEW1_CUSTMAP,
+								                  BG_CANVAS_SAVE_GRADMAP, BG_CANVAS_SAVE_CONFMAP, BG_CANVAS_SAVE_WEITMAP);
+   winPanel2_ = new BgMenuPanel(mapSplitter_, -1, BG_CANVAS_VIEW2_GRADMAP, BG_CANVAS_VIEW2_CONFMAP, BG_CANVAS_VIEW2_WEITMAP, BG_CANVAS_VIEW2_CUSTMAP,
+								                  BG_CANVAS_SAVE_GRADMAP, BG_CANVAS_SAVE_CONFMAP, BG_CANVAS_SAVE_WEITMAP);
+   winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
+   winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
+   winPanel1_->CheckViewItem(BG_CANVAS_VIEW1_CONFMAP);
+   winPanel2_->CheckViewItem(BG_CANVAS_VIEW2_GRADMAP);
+   winPanel1_->EnableMenu(false);
+   winPanel2_->EnableMenu(false);
+
+   //define ph diagram and segmented display image
+   phDiagram_ = new BgImCanvas(this, plotMapSplitter_, wxDefaultPosition, wxDefaultSize);
+   phDiagram_->SetScrollbars(20, 20, 50, 50);
+   plotWindow1_ = new BgImCanvas(this, winPanel1_, wxPoint(0,PLOT_MENU_HEIGHT), wxDefaultSize);
+   plotWindow1_->SetScrollbars(20, 20, 50, 50);
+   plotWindow2_ = new BgImCanvas(this, winPanel2_, wxPoint(0,PLOT_MENU_HEIGHT), wxDefaultSize);
+   plotWindow2_->SetScrollbars(20, 20, 50, 50);
+   displayImage_ = new BgImCanvas(this, imagePlotSplitter_, wxDefaultPosition, wxDefaultSize);
+   displayImage_->SetScrollbars(20, 20, 50, 50);
+
+   //set the scroll window of each panel
+   winPanel1_->SetScrollWindow((wxWindow *) plotWindow1_);
+   winPanel2_->SetScrollWindow((wxWindow *) plotWindow2_);
+
+   //set lower bound zoom limit on display image
+   //to the size of the original image
+   displayImage_->SetMinZoomLevel(1);
+
+   //place each image object into their corresponding positions in the split
+   //window
+   imagePlotSplitter_->SplitVertically(displayImage_, plotMapSplitter_,256);
+   plotMapSplitter_->SplitHorizontally(phDiagram_, mapSplitter_, 256);
+   mapSplitter_->SplitVertically(winPanel1_, winPanel2_, 256);
+
+   //inititalize segmentation parameters
+   sigmaS		= 7;
+   sigmaR		= float(6.5);
+   aij			= float(0.3);
+   epsilon		= float(0.3);
+   minRegion	= 20;
+   kernelSize	= 2;
+	
+   //set text size
+   wxSize txtSize(50, 20);
+
+   //allocate memory for display images
+   cbgImage_			= new BgImage();
+   filtImage_			= new BgImage();
+   segmImage_			= new BgImage();
+   whiteImage_			= new BgImage();
+
+   //allocate memory to store boundary pixel locations
+   boundaries_			= new BgPointSet();
+
+   hasImage_		= 0;
+   hasFilter_		= 0;
+   hasSegment_		= 0;
+   hasBoundaries_	= 0;
+
+   //shut off text box monitoring
+   checkTextBoxes_	= false;
+
+   optionsPanel_	= new wxPanel(this, -1, wxPoint(0, 0), wxSize(BG_SEGM_OP_SIZEX, BG_SEGM_OP_SIZEY));
+
+   wxBoxSizer	*toplayout = new wxBoxSizer(wxVERTICAL);
+
+   loadButton_ = new wxButton(optionsPanel_, BG_SEGM_LOAD_IMAGE, "Load Image");
+   toplayout->Add(loadButton_, 0, wxCENTER | wxBOTTOM | wxTOP, 5);
+   
+   wxString operations[] = {"Segment", "Filter Only", "Fusion Only"};
+   operationRadio_ = new wxRadioBox(optionsPanel_, BG_SEGM_OPERATION, "Operation", wxDefaultPosition, wxSize(BG_SP_WIDTH, -1), 3, operations, 3 ,wxRA_SPECIFY_ROWS);
+   toplayout->Add(operationRadio_, 0, wxCENTER | wxBOTTOM, 5);
+
+   runButton_ = new wxButton(optionsPanel_, BG_SEGM_SEGMENT, "Run");
+   toplayout->Add(runButton_, 0, wxCENTER | wxBOTTOM, 5);
+
+   wxString choices[] = {"Original", "Filtered", "Segmented", "No Image"};
+   viewImSegRadio_ = new wxRadioBox(optionsPanel_, BG_SEGM_VIEW_IMSEG, "View Image", wxDefaultPosition, wxSize(BG_SP_WIDTH, -1), 4, choices, 4, wxRA_SPECIFY_ROWS);
+   toplayout->Add(viewImSegRadio_, 0, wxCENTER | wxBOTTOM, 5);
+
+   viewBoundariesCheck_ = new wxCheckBox(optionsPanel_, BG_SEGM_VIEW_EDGES, "Overlay Boundaries");
+   toplayout->Add(viewBoundariesCheck_, 0, wxALIGN_LEFT | wxLEFT | wxBOTTOM, 10);
+
+   //add bandwidth parameters...
+   subPanel1_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, BG_SP_HEIGHT));
+   subPanelBox1_	= new wxStaticBox(subPanel1_, -1, "Bandwidth", wxPoint(0, 0), wxSize(BG_SP_WIDTH, BG_SP_TOP_HEIGHT), wxSIMPLE_BORDER, "staticBox");
+   subPanelBox2_	= new wxStaticBox(subPanel1_, -1, "", wxPoint(0, BG_SP_TOP_HEIGHT-8), wxSize(BG_SP_WIDTH, BG_SP_HEIGHT-BG_SP_TOP_HEIGHT), wxSIMPLE_BORDER, "staticBox");
+   textSigmaS_		= new wxStaticText(subPanel1_, -1, "Spatial [2h+1]", wxPoint(BG_LEFT_CELL, 18));
+   txtSigmaS_		= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_SIGMAS, "7", wxPoint(BG_RIGHT_CELL, 15), txtSize);
+   textSigmaR_		= new wxStaticText(subPanel1_, -1, "Color [2h]", wxPoint(BG_LEFT_CELL, 43));
+   txtSigmaR_		= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_SIGMAR, "6.5", wxPoint(BG_RIGHT_CELL, 40), txtSize);
+   textMinRegion_	= new wxStaticText(subPanel1_, -1, "Minimum Region", wxPoint(BG_LEFT_CELL, 78));
+   txtMinRegion_	= new wxTextCtrl(subPanel1_, BG_SEGM_TEXT_MINREG, "20", wxPoint(BG_RIGHT_CELL, 75), txtSize);
+   toplayout->Add(subPanel1_, 0, wxCENTER | wxBOTTOM | wxTOP, 5);
+
+   useWeightMap_ = new wxCheckBox(optionsPanel_, BG_SEGM_USE_EDGE_MAP, "Use Weight Map");
+   toplayout->Add(useWeightMap_, 0, wxALIGN_LEFT | wxLEFT | wxBOTTOM, 10);
+
+   //add weight map parameters...
+   subPanel2_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, BG_SP_HEIGHT_2));
+   subPanelBox3_	= new wxStaticBox(subPanel2_, -1, "", wxPoint(0, 0), wxSize(BG_SP_WIDTH, BG_SP_HEIGHT_2), wxSIMPLE_BORDER, "staticBox");
+   textKernelSize_	= new wxStaticText(subPanel2_, -1, "Grad. Window (2n+1)", wxPoint(BG_LEFT_CELL, 18));
+   txtKernelSize_	= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_GRADWIN, "2", wxPoint(BG_RIGHT_CELL, 15), txtSize);
+   textA_			= new wxStaticText(subPanel2_, -1, "Mixture Parameter", wxPoint(BG_LEFT_CELL, 43));
+   txtA_			= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_AIJ, "0.3", wxPoint(BG_RIGHT_CELL, 40), txtSize);
+   textEpsilon_		= new wxStaticText(subPanel2_, -1, "Threshold", wxPoint(BG_LEFT_CELL, 68));
+   txtEpsilon_		= new wxTextCtrl(subPanel2_, BG_SEGM_TEXT_EPSILON, "0.3", wxPoint(BG_RIGHT_CELL, 65), txtSize);
+   toplayout->Add(subPanel2_, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP, 5);
+
+   //add parameter history control
+   subPanel3_		= new wxPanel(optionsPanel_, -1, wxDefaultPosition, wxSize(BG_SP_WIDTH, 43));
+   subPanelBox4_	= new wxStaticBox(subPanel3_, -1, "", wxPoint(0, 0), wxSize(BG_SP_WIDTH, 43), wxSIMPLE_BORDER, "staticBox");
+   textParamBox_	= new wxStaticText(subPanel3_, -1, "History", wxPoint(BG_LEFT_CELL, 18));
+   paramComboBox_	= new BgParameterHistoryBox(subPanel3_, BG_SEGM_CHANGE_PARAMS, "", wxPoint(BG_RIGHT_CELL-50, 15), wxSize(100,20), 5, 0, wxDefaultValidator, "comboBox");
+   toplayout->Add(subPanel3_, 0, wxALIGN_CENTER | wxCENTER | wxBOTTOM, 10);
+    
+   optionsPanel_->SetAutoLayout(TRUE);
+   toplayout->Fit(optionsPanel_);
+   optionsPanel_->SetSizer(toplayout);
+
+   g_children.Append(this);
+
+   //set the size and sash position of the splitters
+   int w, h;
+   GetClientSize(&w, &h);
+   imagePlotSplitter_->SetSize(BG_SEGM_OP_SIZEX, 0, w-BG_SEGM_OP_SIZEX, h);
+   imagePlotSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/2, TRUE);
+   plotMapSplitter_->SetSashPosition(h/2, TRUE);
+   mapSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/4, TRUE);
+
+   //initalize edge maps...
+   customMap_	= (float *) NULL;
+   confMap_		= (float *) NULL;
+   gradMap_		= (float *) NULL;
+   weightMap_	= (float *) NULL;
+
+   //indicate that the edge parameters have not changed
+   edgeParamsHaveChanged_	= false;
+
+   //add margin to plots
+   phDiagram_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+   plotWindow1_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+   plotWindow2_->AddMargin(RANK_CONF_MARGINX,RANK_CONF_MARGINY);
+
+   //add title to each individual plot
+   BgText bgText(1,"      Diagram of Region Boundary Data Points", *wxSWISS_FONT, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2-10);
+   phDiagram_->AddText(&bgText);
+   bgText.SetText("Confidence Map");
+   plotWindow1_->AddText(&bgText);
+   bgText.SetText("Gradient Map");
+   plotWindow2_->AddText(&bgText);
+
+   //add x and y axis
+   phDiagram_->AddHorizontalAxis(RANK_CONF_MARGINX-2,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX+2,10,0.0,1.0);
+   phDiagram_->AddVerticalAxis  (RANK_CONF_MARGINX-1,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY,RANK_CONF_IMSIZEX,10,0.0,1.0);
+
+   //label x and y axis
+   bgText.SetText("Rank (   )");
+   phDiagram_->LabelHorizontalAxis(&bgText);
+   bgText.SetText("Confidence (  )");
+   phDiagram_->LabelVerticalAxis(&bgText);
+
+   //place greek symbols
+   wxBitmap	ro("ro", wxBITMAP_TYPE_RESOURCE), eta("eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap	ro_bmp(&ro, 1, RANK_CONF_MARGINX - 10, RANK_CONF_MARGINY/2 - 3);
+   BgBitmap eta_bmp(&eta, 2, RANK_CONF_MARGINX, RANK_CONF_MARGINY/2 - 3);
+   phDiagram_->AddBitmap(&ro_bmp);
+   phDiagram_->AddBitmap(&eta_bmp);
+   ro_bmp.SetPlotLocation(RANK_CONF_MARGINX+137,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY+35);
+   ro_bmp.SetId(3);
+   phDiagram_->AddBitmap(&ro_bmp);
+   wxBitmap rotated_eta("rotated_eta", wxBITMAP_TYPE_RESOURCE);
+   BgBitmap rotated_eta_bmp(&rotated_eta, 4, RANK_CONF_MARGINX-55,RANK_CONF_IMSIZEY+RANK_CONF_MARGINY-162);
+   phDiagram_->AddBitmap(&rotated_eta_bmp);
+
+   //declare that segmentation window is open
+   window_open	= true;
+
+   //get parent tool bar and update it
+   toolbar	= parent->GetToolBar();
+   UpdateToolBar();
+
+   //disable confidence map text boxes
+   txtA_->Enable(false);
+   txtEpsilon_->Enable(false);
+   txtKernelSize_->Enable(false);
+   textA_->Enable(false);
+   textEpsilon_->Enable(false);
+   textKernelSize_->Enable(false);
+
+   //disable run button
+   runButton_->Enable(false);
+
+   //disable radio boxes
+   viewImSegRadio_->Enable(false);
+   operationRadio_->Enable(false);
+
+   //disable view boundaries check box
+   viewBoundariesCheck_->Enable(false);
+
+   //intialize parameter combo box
+   float *myParameters = new float [6];
+   myParameters[0]	= sigmaS;
+   myParameters[1]	= sigmaR;
+   myParameters[2]	= aij;
+   myParameters[3]	= epsilon;
+   myParameters[4]	= minRegion;
+   myParameters[5]	= kernelSize;
+   paramComboBox_->SetCurrentList((void *) myParameters, 6);
+   isCurrentHistory_	= true;
+
+   //turn on text box monitoring
+   checkTextBoxes_	= true;
+
+   //initialize speedup level to medium
+   speedUpLevel_	= MED_SPEEDUP;
+   speedUpThreshold_ = (float) 0.1;
+
+   //initialize max/min zoom
+   maxZoom_	= 0;
+   minZoom_	= 1;
+
+}
+
+
+BgMdiSegmentChild::~BgMdiSegmentChild()
+{
+   if (hasBoundaries_ == 1)
+     displayImage_->RemovePointSet(boundaries_);
+
+	if(filename_)	delete [] filename_;
+
+   delete optionsPanel_;
+   delete displayImage_;
+   
+   delete boundaries_;
+   delete whiteImage_;
+   delete segmImage_;
+   delete filtImage_;
+   delete cbgImage_;
+
+   if (customMap_)	delete [] customMap_;
+   if (confMap_)	delete [] confMap_;
+   if (gradMap_)	delete [] gradMap_;
+   if (weightMap_)	delete [] weightMap_;
+
+   g_children.DeleteObject(this);
+}
+
+void BgMdiSegmentChild::OnViewImSeg(wxCommandEvent&  WXUNUSED(event))
+{
+	//if an image has not been loaded then exit this method...
+	if (hasImage_ == 0)
+		return;
+	
+	switch(viewImSegRadio_->GetSelection())
+	{
+		
+	//view original image
+	case 0:
+		boundaries_->pen_.SetColour(*wxWHITE);
+		displayImage_->SetImage(cbgImage_->im_, cbgImage_->x_, cbgImage_->y_, cbgImage_->colorIm_);
+		break;
+		
+	//view filtered image
+	case 1:
+		if (hasFilter_ == 0)
+		{
+			viewImSegRadio_->SetSelection(0);
+			bgLog("Filter the image first!\n");
+			return;
+		} else
+		{
+			boundaries_->pen_.SetColour(*wxWHITE);
+			displayImage_->SetImage(filtImage_->im_, filtImage_->x_, filtImage_->y_, filtImage_->colorIm_);
+		}
+		break;
+		
+	//view segmented image
+	case 2:
+		if (hasSegment_ == 0)
+		{
+			viewImSegRadio_->SetSelection(0);
+			bgLog("Segment the image first!\n");
+			return;
+		} else
+		{
+			boundaries_->pen_.SetColour(*wxWHITE);
+			displayImage_->SetImage(segmImage_->im_, segmImage_->x_, segmImage_->y_, segmImage_->colorIm_);
+		}
+		break;
+		
+	//view boundaries
+	default:
+		if (hasBoundaries_ == 0)
+		{
+			viewImSegRadio_->SetSelection(0);
+			bgLog("Process the image first!\n");
+			return;
+		} else
+		{
+			boundaries_->pen_.SetColour(*wxBLACK);
+			displayImage_->SetImage(whiteImage_->im_, whiteImage_->x_, whiteImage_->y_, whiteImage_->colorIm_);
+		}
+	}
+}
+
+//specifies image operation(i.e. segment, filter or fuse regions)
+void BgMdiSegmentChild::OnChangeOperation(wxCommandEvent& WXUNUSED(event))
+{
+
+	wxMenuBar	*menubar	= GetMenuBar();
+	switch(operationRadio_->GetSelection())
+	{
+	//segment the image
+	case 0:
+		menubar->SetLabel(BG_SEGM_SEGMENT, "Segment Image\tShift-R");
+		break;
+	//filter the image
+	case 1:
+		menubar->SetLabel(BG_SEGM_SEGMENT, "Filter Image\tShift-R");
+		break;
+	//fuse regions
+	default:
+		menubar->SetLabel(BG_SEGM_SEGMENT, "Fuse Regions\tShift-R");
+		break;
+	}
+
+	//done.
+	return;
+
+}
+
+//changes the paramters depending on the parameter list
+void BgMdiSegmentChild::OnChangeParameters(wxCommandEvent& WXUNUSED(event))
+{
+	float	*myParameters;
+
+	//get current selection index...
+	int	selIndex	= paramComboBox_->GetSelection();
+
+	//aquire current parameters and store them in "current parameter" slot...
+	if(isCurrentHistory_)
+	{
+		int		csigmaS, cminRegion, ckernelSize;
+		float	csigmaR, caij, cepsilon;
+		GetParameters(csigmaS, csigmaR, caij, cepsilon, cminRegion, ckernelSize, 0);
+		myParameters	= (float *) paramComboBox_->GetCurrentListData();
+		myParameters[0]	= csigmaS;
+		myParameters[1]	= csigmaR;
+		myParameters[2]	= caij;
+		myParameters[3]	= cepsilon;
+		myParameters[4]	= cminRegion;
+		myParameters[5]	= ckernelSize;
+	}
+
+	//check to see if the "current parameter" slot has been selected,
+	//if so set the current history flag and use the parameters from
+	//current history slot
+	if(selIndex == 0)
+	{
+		isCurrentHistory_		= true;
+		myParameters			= (float *) paramComboBox_->GetCurrentListData();
+	}
+	//otherwise indicate that the current slot has not just been selected
+	//and get parameters from current parameter list
+	else
+	{
+		isCurrentHistory_		= false;
+		myParameters			= (float *) paramComboBox_->GetParameterListData(selIndex-1);
+	}
+
+	//set the text boxes...
+	char str[10];
+	checkTextBoxes_	= false;
+	sprintf(str, "%d", bgRoundSign(myParameters[0]));
+	txtSigmaS_->SetValue(str);
+	sprintf(str, "%3.1f", myParameters[1]);
+	txtSigmaR_->SetValue(str);
+	sprintf(str, "%3.1f", myParameters[2]);
+	txtA_->SetValue(str);
+	sprintf(str, "%3.1f", myParameters[3]);
+	txtEpsilon_->SetValue(str);
+	sprintf(str, "%d", bgRoundSign(myParameters[4]));
+	txtMinRegion_->SetValue(str);
+	sprintf(str, "%d", bgRoundSign(myParameters[5]));
+	txtKernelSize_->SetValue(str);
+	checkTextBoxes_	= true;
+
+}
+
+void BgMdiSegmentChild::OnUpdateTextBoxes(wxCommandEvent& event)
+{
+	//update parameter history....
+	if(checkTextBoxes_)
+	{
+		paramComboBox_->SetSelection(0);
+		isCurrentHistory_	= true;
+	}
+
+	//check if a edge parameter has been changed
+	int	id	= event.GetId();
+	if((id == BG_SEGM_TEXT_GRADWIN)||(id == BG_SEGM_TEXT_AIJ)||(id == BG_SEGM_TEXT_EPSILON))
+		edgeParamsHaveChanged_	= true;
+
+}
+
+void BgMdiSegmentChild::OnUpdateSpeedUpLevel(wxCommandEvent& event)
+{
+	long menuItemId			= event.GetId();
+	wxMenuBar*	myMenuBar	= GetMenuBar();
+	switch(menuItemId)
+	{
+	case BG_SEGM_SPEEDUP_MEDM:
+		speedUpLevel_	= MED_SPEEDUP;
+		myMenuBar->Check(BG_SEGM_SPEEDUP_NONE, false);
+		myMenuBar->Check(BG_SEGM_SPEEDUP_HIGH, false);
+		break;
+	case BG_SEGM_SPEEDUP_HIGH:
+		speedUpLevel_	= HIGH_SPEEDUP;
+		myMenuBar->Check(BG_SEGM_SPEEDUP_NONE, false);
+		myMenuBar->Check(BG_SEGM_SPEEDUP_MEDM, false);
+      {
+         BgSpeedSelect speedSelect(this, -1, "Select speed/quality", wxDefaultPosition, wxSize(220,150),
+            wxDEFAULT_DIALOG_STYLE | wxDIALOG_MODAL);
+         speedSelect.SetSliderValue(speedUpThreshold_);
+         if (speedSelect.ShowModal()==wxID_OK)
+         {
+            speedSelect.GetSliderValue(speedUpThreshold_);
+         }
+      }
+
+		break;
+	default:
+		speedUpLevel_	= NO_SPEEDUP;
+		myMenuBar->Check(BG_SEGM_SPEEDUP_MEDM, false);
+		myMenuBar->Check(BG_SEGM_SPEEDUP_HIGH, false);
+	}
+}
+
+void BgMdiSegmentChild::OnViewBoundaries(wxCommandEvent&  WXUNUSED(event))
+{
+		
+	if (hasBoundaries_ == false)
+		return;
+
+	bool	isChecked;
+	isChecked = viewBoundariesCheck_->GetValue();
+	
+	if (isChecked)
+	{
+		// show edges
+		displayImage_->AddPointSet(boundaries_);
+		
+	}
+	else
+	{
+		// hide edges
+		displayImage_->RemovePointSet(boundaries_);
+	}
+
+}
+
+
+//activates/de-activates the text boxes used for
+//synergistic segmentation based on the use confidence
+//map checkbox
+void BgMdiSegmentChild::OnUseWeightMap(wxCommandEvent& WXUNUSED(event))
+{
+
+	//depending on use confidence map checkbox, activate/de-activate
+	//text boxes
+	if(useWeightMap_->GetValue())
+	{
+		//enable text boxes
+		txtA_->Enable(true);
+		txtEpsilon_->Enable(true);
+		txtKernelSize_->Enable(true);
+		textA_->Enable(true);
+		textEpsilon_->Enable(true);
+		textKernelSize_->Enable(true);
+	}
+	else
+	{
+		//disable text boxes
+		txtA_->Enable(false);
+		txtEpsilon_->Enable(false);
+		txtKernelSize_->Enable(false);
+		textA_->Enable(false);
+		textEpsilon_->Enable(false);
+		textKernelSize_->Enable(false);
+	}
+
+	//done.
+	return;
+}
+
+void BgMdiSegmentChild::OnUpdatePlotWindow1(wxCommandEvent& event)
+{
+	int menuItemId	= event.GetId();
+
+	//update checkmarks
+	winPanel1_->CheckViewItem(menuItemId);
+
+	//change plot...
+	int i;
+	int data_length	= width_*height_;
+	unsigned char *buffer = new unsigned char[data_length];
+	BgText bgText(1,"ConfidenceMap", *wxSWISS_FONT, 0, 0);
+	switch(menuItemId)
+	{
+	case BG_CANVAS_VIEW1_GRADMAP:
+		bgText.SetText("Gradient Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
+		plotWindow1_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*gradMap_[i] + 0.5);
+		plotWindow1_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW1_CONFMAP:
+		bgText.SetText("Confidence Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
+		plotWindow1_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*confMap_[i] + 0.5);
+		plotWindow1_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW1_WEITMAP:
+		bgText.SetText("Weight Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-35,RANK_CONF_MARGINY/2-10);
+		plotWindow1_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*weightMap_[i] + 0.5);
+		plotWindow1_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW1_CUSTMAP:
+		bgText.SetText("Custom Weight Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-60,RANK_CONF_MARGINY/2-10);
+		plotWindow1_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*customMap_[i] + 0.5);
+		plotWindow1_->SetImageFromGray(buffer, width_, height_);
+		break;
+	}
+	
+	//de-allocate memory used by conf/gradient map buffer
+	delete [] buffer;
+}
+
+void BgMdiSegmentChild::OnUpdatePlotWindow2(wxCommandEvent& event)
+{
+	int menuItemId	= event.GetId();
+
+	//update checkmarks
+	winPanel2_->CheckViewItem(menuItemId);
+
+	//change plot...
+	int i;
+	int data_length	= width_*height_;
+	unsigned char *buffer = new unsigned char[data_length];
+	BgText bgText(1,"ConfidenceMap", *wxSWISS_FONT, 0, 0);
+	switch(menuItemId)
+	{
+	case BG_CANVAS_VIEW2_GRADMAP:
+		bgText.SetText("Gradient Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
+		plotWindow2_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*gradMap_[i] + 0.5);
+		plotWindow2_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW2_CONFMAP:
+		bgText.SetText("Confidence Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
+		plotWindow2_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*confMap_[i] + 0.5);
+		plotWindow2_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW2_WEITMAP:
+		bgText.SetText("Weight Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-35,RANK_CONF_MARGINY/2-10);
+		plotWindow2_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*weightMap_[i] + 0.5);
+		plotWindow2_->SetImageFromGray(buffer, width_, height_);
+		break;
+	case BG_CANVAS_VIEW2_CUSTMAP:
+		bgText.SetText("Custom Weight Map");
+		bgText.SetPlotLocation(RANK_CONF_MARGINX+width_/2-60,RANK_CONF_MARGINY/2-10);
+		plotWindow2_->AddText(&bgText);
+		for(i = 0; i < data_length; i++)
+			buffer[i] = (unsigned char)(255*customMap_[i] + 0.5);
+		plotWindow2_->SetImageFromGray(buffer, width_, height_);
+		break;
+	}
+		
+	//de-allocate memory used by conf/gradient map buffer
+	delete [] buffer;
+}
+
+
+void BgMdiSegmentChild::OnSaveEdgeInformation(wxCommandEvent& event)
+{
+
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+	wxFileDialog filedialog(this,"Save Edge Information","","",
+		"*",wxSAVE);
+#else
+	wxFileDialog filedialog(this,"Save Edge Information","","",
+		"Matlab ASCII data files (*.dat)|*.dat|PGM Files (*.pgm)|*.pgm",
+		wxSAVE);
+#endif
+
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+
+	   //get the image type
+	   int dtype = filedialog.GetFilterIndex();
+
+	   //obtain pointer to data
+	   float	*myData;
+	   switch(event.GetId())
+	   {
+	   case BG_CANVAS_SAVE_GRADMAP:
+		   myData	= gradMap_;
+		   break;
+	   case BG_CANVAS_SAVE_CONFMAP:
+		   myData	= confMap_;
+		   break;
+	   case BG_CANVAS_SAVE_WEITMAP:
+		   myData	= weightMap_;
+		   break;
+	   }
+	   
+	   //get the filename and path
+	   char* path		= (char*) filedialog.GetPath().c_str();
+	   char* filename	= (char*) filedialog.GetFilename().c_str();
+	   
+	   //PGM Image
+	   if(dtype)
+	   {
+		   unsigned char *buf	= new unsigned char [height_*width_];
+		   int i;
+		   for(i = 0; i < height_*width_; i++)
+			   buf[i]	= myData[i]*255 + 0.5;
+		   write_pgm_image(path, buf, height_, width_, "", 255);
+		   delete [] buf;
+	   }
+	   else
+	   //Matlab Data File
+	   {
+		   write_MATLAB_ASCII(path, myData, height_, width_);
+	   }
+   }
+
+}
+
+void BgMdiSegmentChild::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+   int w, h;
+   GetClientSize(&w, &h);
+   optionsPanel_->SetSize(0, 0, BG_SEGM_OP_SIZEX, h);
+   imagePlotSplitter_->SetSize(BG_SEGM_OP_SIZEX, 0, w-BG_SEGM_OP_SIZEX, h);
+   imagePlotSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/2, TRUE);
+   plotMapSplitter_->SetSashPosition(h/2, TRUE);
+   mapSplitter_->SetSashPosition((w-BG_SEGM_OP_SIZEX)/4, TRUE);
+}
+
+//clears display of ph diagram and rank and confidence maps
+void BgMdiSegmentChild::ClearDisplay( void )
+{
+	phDiagram_->ClearDisplay();
+	plotWindow1_->ClearDisplay();
+	plotWindow2_->ClearDisplay();
+}
+
+//turns plotting capability on/off
+void BgMdiSegmentChild::UpdateDisplay(bool update)
+{
+	if(update)
+	{
+		phDiagram_->noUpdate_	= false;
+		plotWindow1_->noUpdate_	= false;
+		plotWindow2_->noUpdate_	= false;
+	}
+	else
+	{
+		phDiagram_->noUpdate_	= true;
+		plotWindow1_->noUpdate_	= true;
+		plotWindow2_->noUpdate_	= true;
+	}
+}
+
+void BgMdiSegmentChild::OnQuit(wxCommandEvent& WXUNUSED(event))
+{
+   Close(TRUE);
+}
+
+void BgMdiSegmentChild::OnClose(wxCloseEvent& event)
+{
+   //decrement global counter indicating number of frames open
+   gs_nFrames--;
+   //indicate that the window is now close (used by OnFocus)
+   window_open = false;
+   //reset the toolbar
+   if(gs_nFrames == 0) ResetToolBar();
+   event.Skip();
+}
+
+void BgMdiSegmentChild::OnFocus(wxFocusEvent& WXUNUSED(event))
+{
+	//update toolbar
+	if(!on_exit) UpdateToolBar();
+	return;
+}
+
+void BgMdiSegmentChild::ZoomWindow(void)
+{
+	//display zoom window
+	displayImage_->zoom_window	= true;
+	displayImage_->zoom_in		= false;
+	displayImage_->zoom_out		= false;
+}
+
+void BgMdiSegmentChild::ZoomIn(void)
+{
+	//zoom into display image
+	displayImage_->zoom_window	= false;
+	displayImage_->zoom_in		= true;
+	displayImage_->zoom_out		= false;
+	return;
+}
+
+void BgMdiSegmentChild::ZoomOut(void)
+{
+	//zoom out of display image
+	displayImage_->zoom_window	= false;
+	displayImage_->zoom_in		= false;
+	displayImage_->zoom_out		= true;
+	return;
+}
+
+void BgMdiSegmentChild::NoZoom(void)
+{
+	//do not zoom display image
+	displayImage_->zoom_window	= false;
+	displayImage_->zoom_in		= false;
+	displayImage_->zoom_out		= false;
+	return;
+}
+
+void BgMdiSegmentChild::UpdateZoomControl(void)
+{
+	//determine whether to enable zoom in control based on maximum zoom
+	if(maxZoom_ || minZoom_)
+		UpdateToolBar();
+	else
+	{
+		toolbar->EnableTool(BG_ZOOM_IN, true);
+		toolbar->EnableTool(BG_ZOOM_OUT, true);
+//		toolbar->Realize();
+	}
+}
+
+void BgMdiSegmentChild::RunEnable(void)
+{
+	wxMenuBar *menubar = GetMenuBar();
+	menubar->Enable(BG_SEGM_LOAD_MAP, true);
+	menubar->Enable(BG_SEGM_SEGMENT, true);
+	runButton_->Enable(true);
+	viewImSegRadio_->Enable(true);
+	viewImSegRadio_->Enable(1, false);
+	viewImSegRadio_->Enable(2, false);
+	viewImSegRadio_->Enable(3, false);
+}
+
+void BgMdiSegmentChild::SaveEnable(void)
+{
+	toolbar->EnableTool(BG_SAVE_RESULT, true);
+}
+
+void BgMdiSegmentChild::UpdateToolBar(void)
+{
+	//update toolbar (except during close)
+	if(window_open)
+	{
+		//determine whether to enable save based on whether segmentation
+		//has occurred
+		bool save_enable;
+		if(hasSegment_)
+			save_enable	= true;
+		else
+			save_enable	= false;
+
+		//determine whether to enable zoom controls based on whether image
+		//has been loaded
+		bool load_enable;
+		if(hasImage_)
+			load_enable	= true;
+		else
+			load_enable	= false;
+
+		//determine whether to enable zoom in control based on maximum zoom
+		bool max_zoom;
+		if(maxZoom_)
+			max_zoom	= true;
+		else
+			max_zoom	= false;
+
+		//determine whether to enable zoom out control based on minimum zoom
+		bool min_zoom;
+		if(minZoom_)
+			min_zoom	= true;
+		else
+			min_zoom	= false;
+
+		//adjust toolbar
+		toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to perform image segmentation");
+		toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save segmented image");
+		toolbar->EnableTool(BG_SAVE_RESULT, save_enable);
+		toolbar->EnableTool(BG_CROSS, load_enable);
+		toolbar->EnableTool(BG_ZOOM_IN, ((load_enable)&&(!max_zoom)));
+		toolbar->EnableTool(BG_ZOOM_OUT, ((load_enable)&&(!min_zoom)));
+		toolbar->EnableTool(BG_POINTER, true);
+
+		//set to no zoom
+		toolbar->ToggleTool(BG_CROSS, false);
+		toolbar->ToggleTool(BG_ZOOM_IN, false);
+		toolbar->ToggleTool(BG_ZOOM_OUT, false);
+		toolbar->ToggleTool(BG_POINTER, true);
+		displayImage_->SetCursor(wxCURSOR_ARROW);
+		NoZoom();
+	}
+	return;
+}
+
+void BgMdiSegmentChild::ResetToolBar(void)
+{
+	//update toolbar
+	toolbar->SetToolShortHelp(BG_LOAD_IMAGE, "Load image to process");
+	toolbar->SetToolShortHelp(BG_SAVE_RESULT, "Save result");
+	toolbar->EnableTool(BG_SAVE_RESULT, false);
+	toolbar->EnableTool(BG_CROSS, false);
+	toolbar->EnableTool(BG_ZOOM_IN, false);
+	toolbar->EnableTool(BG_ZOOM_OUT, false);
+	toolbar->EnableTool(BG_POINTER, false);
+	toolbar->ToggleTool(BG_CROSS, false);
+	toolbar->ToggleTool(BG_ZOOM_IN, false);
+	toolbar->ToggleTool(BG_ZOOM_OUT, false);
+	toolbar->ToggleTool(BG_POINTER, false);
+	return;
+}
+
+void BgMdiSegmentChild::ReadImage(char *pathname, char *filename)
+{
+	//take away point set if boundaries have been calculated
+	if(hasBoundaries_)
+	{
+		hasBoundaries_ = false;
+		displayImage_->RemovePointSet(boundaries_);
+		boundaries_->CleanData();
+	}
+
+	if(displayImage_->SetImage(pathname) == 0)
+		return;
+
+	//obtain and store image filename
+	if(filename_)	delete [] filename_;
+	filename_	= new char [strlen(filename) + 1];
+	strcpy(filename_, filename);
+	
+	displayImage_->showbitmap_ = true;
+	
+	//set value of view boundaries control
+	viewBoundariesCheck_->SetValue(0);
+	
+	//set image view option to original
+	viewImSegRadio_->SetSelection(0);
+
+	//get image dimension
+	width_			= displayImage_->pimage->GetWidth();
+	height_			= displayImage_->pimage->GetHeight();
+	
+	//reset zoom level of display image
+	displayImage_->Zoom(1);
+	
+	//reset max/min zoom flags
+	maxZoom_	= 0;
+	minZoom_	= 1;
+	
+	//set cbgImage
+	cbgImage_->SetImageFromRGB(displayImage_->pimage->GetData(), width_, height_, true);
+	hasImage_		= 1;
+	hasSegment_		= 0;
+	hasBoundaries_	= 0;
+	
+	//adjust titles
+	BgText title(1, "Confidence Map", *wxSWISS_FONT, RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
+	plotWindow1_->AddText(&title);
+	title.SetText("Gradient Map");
+	title.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
+	plotWindow2_->AddText(&title);
+	
+	//add axis
+	plotWindow1_->ClearAxis();
+	plotWindow2_->ClearAxis();
+	plotWindow1_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
+	plotWindow1_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
+	plotWindow2_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
+	plotWindow2_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
+	
+	//label axis
+	BgText label(1, "x", *wxSWISS_FONT, 0, 0);
+	plotWindow1_->LabelHorizontalAxis(&label);
+	plotWindow2_->LabelHorizontalAxis(&label);
+	label.SetText("y");
+	plotWindow1_->LabelVerticalAxis(&label);
+	plotWindow2_->LabelVerticalAxis(&label);
+	plotWindow1_->RotateVerticalAxisLabel(-90);
+	plotWindow2_->RotateVerticalAxisLabel(-90);
+	
+	//set white image
+	unsigned char *img = new unsigned char [(width_)*(height_)*3];
+	memset(img, 255, (width_)*(height_)*3); 
+	whiteImage_->SetImageFromRGB(img, width_, height_, true);
+	delete [] img;
+	
+	//clear the plot window displays
+	ClearDisplay();
+
+	//do no update the plot windows
+	UpdateDisplay(false);
+	
+	//delete edge maps if they exists...
+	if(customMap_)	delete [] customMap_;
+	if(gradMap_  )	delete [] gradMap_;
+	if(confMap_  )	delete [] confMap_;
+	if(weightMap_)	delete [] weightMap_;
+	
+	//set edge maps to NULL...
+	customMap_	= (float *) NULL;
+	gradMap_	= (float *) NULL;
+	confMap_	= (float *) NULL;
+	weightMap_	= (float *) NULL;
+	
+	//update interface...
+	
+	/***********************************************/
+	
+	//enable run
+	RunEnable();
+	
+	//enable operations radio box
+	operationRadio_->Enable(true);
+	
+	//update the tool bar
+	UpdateToolBar();
+	
+	//set window title
+	wxString statusname;
+	statusname.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
+	SetTitle(statusname);
+	
+	//update the menubar
+	wxMenuBar	*menubar	= GetMenuBar();
+	menubar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
+	menubar->Enable(BG_SEGM_USE_MAP, false);
+	
+	//update window menus
+	winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
+	winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
+	winPanel1_->EnableMenu(false);
+	winPanel2_->EnableMenu(false);
+	
+	/***********************************************/
+
+}
+
+void BgMdiSegmentChild::OnLoadImage(wxCommandEvent& WXUNUSED(event))
+{
+// get the file name
+//   wxFileDialog filedialog(this,"Choose an image file","","",
+//      "All files (*.*)|*.*|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm",
+//      wxOPEN);
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+  wxFileDialog filedialog(this,"Choose an image file","","",
+			  "*",wxOPEN);
+#else
+   wxFileDialog filedialog(this,"Choose an image file","","",
+      "Common image files|*.png;*.bmp;*.gif;*.tif;*.tiff;*.jpg;*.pnm;*.pgm;*.ppm|PNG files (*.png)|*.png|BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif|TIFF files (*.tif)|*.tif|JPEG files (*.jpg)|*.jpg|PNM files (*.pnm)|*.pnm|PGM/PPM files (*.pgm,*.ppm)|*.pgm;*.ppm",
+      wxOPEN);
+#endif
+
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+	  //take away point set if boundaries have been calculated
+	  if(hasBoundaries_)
+	  {
+		  hasBoundaries_ = false;
+		  displayImage_->RemovePointSet(boundaries_);
+		  boundaries_->CleanData();
+	  }
+
+      if (displayImage_->SetImage(filedialog.GetPath().c_str()) == 0)
+         return;
+      bgLog("Image %s loaded\n",filedialog.GetPath().c_str());
+
+	  //obtain and store image filename
+	  if(filename_)	delete [] filename_;
+	  filename_	= new char [strlen(filedialog.GetFilename().c_str()) + 1];
+	  strcpy(filename_, filedialog.GetFilename().c_str());
+
+      displayImage_->showbitmap_ = true;
+
+	  //set value of view boundaries control
+	  viewBoundariesCheck_->SetValue(0);
+
+	  //set image view option to original
+	  viewImSegRadio_->SetSelection(0);
+
+	  //set operation option to segment
+	  operationRadio_->SetSelection(0);
+
+	  //get image dimension
+	  width_			= displayImage_->pimage->GetWidth();
+	  height_			= displayImage_->pimage->GetHeight();
+
+	  //reset zoom level of display image
+	  displayImage_->Zoom(1);
+
+	  //reset max/min zoom flags
+	  maxZoom_	= 0;
+	  minZoom_	= 1;
+
+      //set cbgImage
+      cbgImage_->SetImageFromRGB(displayImage_->pimage->GetData(), width_, height_, true);
+      hasImage_			= 1;
+	  hasFilter_		= 0;
+      hasSegment_		= 0;
+      hasBoundaries_	= 0;
+
+	  //adjust titles
+	  BgText title(1, "Confidence Map", *wxSWISS_FONT, RANK_CONF_MARGINX+width_/2-45,RANK_CONF_MARGINY/2-10);
+	  plotWindow1_->AddText(&title);
+	  title.SetText("Gradient Map");
+	  title.SetPlotLocation(RANK_CONF_MARGINX+width_/2-40,RANK_CONF_MARGINY/2-10);
+	  plotWindow2_->AddText(&title);
+
+	  //add axis
+	  plotWindow1_->ClearAxis();
+	  plotWindow2_->ClearAxis();
+	  plotWindow1_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
+	  plotWindow1_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
+	  plotWindow2_->AddHorizontalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, width_, 5, 0, width_-1);
+	  plotWindow2_->AddVerticalAxis(RANK_CONF_MARGINX, RANK_CONF_MARGINY+height_, height_, 5, 0, height_-1);
+
+	  //label axis
+	  BgText label(1, "x", *wxSWISS_FONT, 0, 0);
+	  plotWindow1_->LabelHorizontalAxis(&label);
+	  plotWindow2_->LabelHorizontalAxis(&label);
+	  label.SetText("y");
+	  plotWindow1_->LabelVerticalAxis(&label);
+	  plotWindow2_->LabelVerticalAxis(&label);
+	  plotWindow1_->RotateVerticalAxisLabel(-90);
+	  plotWindow2_->RotateVerticalAxisLabel(-90);
+
+	  //set white image
+	  unsigned char *img = new unsigned char [(width_)*(height_)*3];
+	  memset(img, 255, (width_)*(height_)*3); 
+	  whiteImage_->SetImageFromRGB(img, width_, height_, true);
+	  delete [] img;
+
+	  //clear the plot window displays
+	  ClearDisplay();
+	  
+	  //do not update plot windows
+	  UpdateDisplay(false);
+
+	  //delete edge maps if they exists...
+	  if(customMap_)	delete [] customMap_;
+	  if(gradMap_  )	delete [] gradMap_;
+	  if(confMap_  )	delete [] confMap_;
+	  if(weightMap_)	delete [] weightMap_;
+	  
+	  //set edge maps to NULL...
+	  customMap_	= (float *) NULL;
+	  gradMap_		= (float *) NULL;
+	  confMap_		= (float *) NULL;
+	  weightMap_	= (float *) NULL;
+
+	  //update interface...
+
+	  /***********************************************/
+
+	  //enable run
+	  RunEnable();
+
+	  //enable operations radio box
+	  operationRadio_->Enable(true);
+
+	  //update the tool bar
+	  UpdateToolBar();
+
+	  //set window title
+      wxString statusname;
+      statusname.Printf(_T("Segmentation Frame %d - %s (%d x %d) [Original Image]"), window_number_, filename_, width_, height_);
+      SetTitle(statusname);
+
+	  //update the menubar
+	  wxMenuBar	*menubar	= GetMenuBar();
+	  menubar->Enable(BG_SEGM_SAVE_SEGMENTED, false);
+	  menubar->Enable(BG_SEGM_USE_MAP, false);
+
+	  //update window menus
+	  winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, false);
+	  winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, false);
+	  winPanel1_->EnableMenu(false);
+	  winPanel2_->EnableMenu(false);
+
+	  /***********************************************/
+
+   }
+}
+
+
+void BgMdiSegmentChild::LoadCustomWeightMap(wxCommandEvent& WXUNUSED(event))
+{
+	
+	//make sure an image was read...
+	if(hasImage_ == 0)
+	{
+		bgLog("image has not been loaded, load image.\n");
+		return;
+	}
+	
+	//compute data length
+    int	xsz			= cbgImage_->x_, ysz = cbgImage_->y_;
+	int	data_length	= (xsz)*(ysz);
+
+// get the file name
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+  wxFileDialog filedialog(this,"Upload Custom Weight Map","","",
+			  "*",wxOPEN);
+#else
+   wxFileDialog filedialog(this,"Upload Custom Weight Map","","",
+      "Matlab ASCII data files (*.dat)|*.dat|All Files (*.*)|*.*",
+      wxOPEN);
+#endif
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+
+	   //de-allocate memory for customMap (if it exists)
+	   if(customMap_)	delete [] customMap_;
+	   
+	   //allocate memory for customMap
+	   customMap_				= new float [data_length];		
+	   
+	   //get data file name
+	   const char	*filename		= filedialog.GetPath().c_str();
+	   
+	   //attempt to read in data
+	   FILE	*fp = fopen(filename, "rb");
+	   int i;
+	   for(i = 0; i < data_length; i++)
+	   {
+		   if(!fscanf(fp, "%f", &customMap_[i]))
+		   {
+			   bgLog("Load Map Error: Data length does not match the size of the image.");
+			   delete [] customMap_;
+			   customMap_	= NULL;
+			   return;
+		   }
+	   }
+	   fclose(fp);
+
+	   //inform user of successful upload
+	   bgLog("Weight map '%s' successfully uploaded.\n", filename); 
+
+	   //enable use custom weight map menu items
+	   wxMenuBar* myMenuBar	= GetMenuBar();
+	   myMenuBar->Enable(BG_SEGM_USE_MAP, true);
+	   winPanel1_->view_menu->Enable(BG_CANVAS_VIEW1_CUSTMAP, true);
+	   winPanel2_->view_menu->Enable(BG_CANVAS_VIEW2_CUSTMAP, true);
+	   
+   }
+}
+
+void BgMdiSegmentChild::OnSaveSegmentedImage(wxCommandEvent& WXUNUSED(event))
+{
+   if ((hasSegment_ == 0)&&(hasFilter_ == 0))
+   {
+      bgLog("No result to save. Run segmenter.\n");
+      return;
+   }
+
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
+  wxFileDialog filedialog(this,"Choose an image file","","",
+			  "*",wxSAVE);
+#else
+   wxFileDialog filedialog(this,"Choose an image file","","",
+      "PNM files (*.pnm)|*.pnm|PNG files (*.png)|*.png|PCX files (*.pcx)|*.pcx|PGM files (*.pgm)|*.pgm|JPEG files (*.jpg) (not recommended)|*.jpg",
+      wxSAVE);
+#endif
+   if(filedialog.ShowModal()==wxID_OK)
+   {
+
+	   //get the image type
+	   int imtype;
+	   switch (filedialog.GetFilterIndex())
+	   {
+	   case 0:
+		   imtype = wxBITMAP_TYPE_PNM;
+		   break;
+	   case 1:
+		   imtype = wxBITMAP_TYPE_PNG;
+		   break;
+	   case 2:
+		   imtype = wxBITMAP_TYPE_PCX;
+		   break;
+	   case 3:
+		   imtype = wxBITMAP_TYPE_ANY;
+		   break;
+	   case 4:
+		   imtype = wxBITMAP_TYPE_JPEG;
+		   break;
+	   default:
+		   return;
+	   }
+	   
+	   //if the filtered image is available then save it...
+	   if(hasFilter_ == 1)
+	   {
+
+		   //get path and add extension
+		   char *path	= new char [strlen(filedialog.GetPath()) + 1];
+		   strcpy(path, filedialog.GetPath());
+		   BgAddExtension(&path, "_filt");
+		   
+		   //convert the image to wxImage format...
+		   wxImage tmpIm(filtImage_->x_, filtImage_->y_);
+		   unsigned char* tmpImData;
+		   tmpImData = tmpIm.GetData();
+		   filtImage_->GetImageColor(tmpImData);
+		   
+		   //save the image...
+		   tmpIm.SaveFile(path, imtype);
+		   bgLog("Filtered image saved to:\t'%s'.\n", path);
+
+		   //de-allocate memory
+		   delete path;
+
+	   }
+	   
+	   //if the segmented image is available then save it...
+	   if(hasSegment_ == 1)
+	   {
+		   
+		   //get path and add extension
+		   char *path	= new char [strlen(filedialog.GetPath()) + 1];
+		   strcpy(path, filedialog.GetPath());
+		   BgAddExtension(&path, "_segm");
+		   
+		   //convert the image to wxImage format...
+		   wxImage tmpIm(segmImage_->x_, segmImage_->y_);
+		   unsigned char* tmpImData;
+		   tmpImData = tmpIm.GetData();
+		   segmImage_->GetImageColor(tmpImData);
+		   
+		   //save the image...
+		   tmpIm.SaveFile(path, imtype);
+		   bgLog("Segmented image saved to:\t'%s'.\n", path);
+
+		   //de-allocate memory
+		   delete [] path;
+		   
+	   }
+	   
+	   //save boundaries
+	   OnSaveBoundaries((char*)filedialog.GetPath().c_str(), imtype);
+	   
+   }
+}
+
+//saves edge map
+void BgMdiSegmentChild::OnSaveBoundaries(char *filename, int imtype)
+{
+
+	//make sure boundaries exist before proceeding...
+	if(hasBoundaries_ == 0)
+		return;
+
+	//create edge map
+	int width = cbgImage_->x_, height = cbgImage_->y_;
+	wxImage tmpImg(width, height);
+	unsigned char *buf = tmpImg.GetData();
+	memset(buf, 255, width*height*3*sizeof(unsigned char));
+	int n = boundaries_->n_;
+	int i, dp, x, y;
+	for(i = 0; i < n; i++)
+	{
+		x			= boundaries_->x_[i];
+		y			= boundaries_->y_[i];
+		dp			= y*width+x;
+		buf[3*dp]	= buf[3*dp+1]	= buf[3*dp+2]	= 0;
+	}
+
+	//create new filename (add _em extension)
+	char *new_filename	= new char [strlen(filename) + 1];
+	strcpy(new_filename, filename);
+	BgAddExtension(&new_filename, "_bndy");
+
+	//save edgemap using specified filename and image format
+	tmpImg.SaveFile(new_filename, imtype);
+	bgLog("Boundaries saved to:\t'%s'.\n", new_filename);
+
+	//de-allocate memory
+	delete	[] new_filename;
+
+	//done.
+	return;
+
+}
+
+//construct a ph diagram using the boundary pixels
+//aquired from image segmentation (also outputs results
+//to 'xyrc.txt'
+void BgMdiSegmentChild::SetphDiagram(int width, float *confMap, float *rankMap)
+{
+   unsigned char* buf;
+   int xsz	= RANK_CONF_IMSIZEX;
+   int ysz	= RANK_CONF_IMSIZEY;
+   int imsz = xsz*ysz;
+   buf = new unsigned char[imsz];
+   int i;
+   for (i=0; i<imsz; i++)
+      buf[i] = 255;
+
+   int l, c, dpoint;
+   int n = boundaries_->n_;
+   int *xpos = boundaries_->x_, *ypos = boundaries_->y_;
+   for (i=0; i<n; i++)
+   {
+	  dpoint = (ypos[i])*width+xpos[i];
+      if ((rankMap[dpoint]>0) && (confMap[dpoint]>0))
+      {
+         c = (int) (rankMap[dpoint]*((double) xsz));
+         c = (c>=xsz) ? xsz-1 : c;
+         l = (int) (confMap[dpoint]*((double) ysz));
+         l = (l>=ysz) ? ysz-1 : l;
+         l = ysz-1-l;
+         buf[c+l*xsz]=80;
+
+      }
+   }
+
+   phDiagram_->SetImageFromGray(buf, xsz, ysz);
+
+   //adjust scroll bar...
+   phDiagram_->SetScrollbars(1, 1, xsz+2*RANK_CONF_MARGINX, ysz+2*RANK_CONF_MARGINY+40);
+   delete [] buf;
+}
+
+void mySegment(void *Object)
+{
+	BgMdiSegmentChild *segmObj	= (BgMdiSegmentChild *) Object;
+	segmObj->Segment();
+}
+
+void BgMdiSegmentChild::OnSegment(wxCommandEvent& WXUNUSED(event))
+{
+
+	//get parameters from GUI
+	int error = GetParameters(sigmaS, sigmaR, aij, epsilon, minRegion, kernelSize, 1);
+	if(error)
+		return;
+
+	//create the working thread
+	BgThread *workingThread	= new BgThread(wxTHREAD_DETACHED, mySegment, this);
+	stop_flag	= false;
+	workingThread->Create();
+	workingThread->Run();
+
+	//determine progress bar title and message
+	int	operation	= operationRadio_->GetSelection();
+	char myMessage[80], myTitle[80];
+	switch (operation)
+	{
+	//filter
+	case 1:
+		strcpy(myTitle,		"Image Filtering Progress");
+		strcpy(myMessage,	"Filtering Image...");
+		break;
+	//fuse regions
+	case 2:
+		strcpy(myTitle,		"Region Fusing Progress");
+		strcpy(myMessage,	"Fusing Image Regions...");
+		break;
+	//segment
+	default:
+		strcpy(myTitle,		"Image Segmentation Progress");
+		strcpy(myMessage,	"Segmenting Image...");
+		break;
+	}
+
+	//call progress dialog
+	bool	done;
+	percentDone	= 0;
+	wxProgressDialog progressDialog(myTitle, myMessage, 100, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
+	while((done = progressDialog.Update(percentDone))&&(percentDone != 100)) wxYield();
+	if(!done)	stop_flag	= true;	//if the algorithm is not done but the user aborted the operation
+									//then tell the thread to stop running
+
+	//if its succesfully completed update the parameter history box
+	if(done)
+	{
+		int	selIndex	= paramComboBox_->GetSelection();
+		if(selIndex)
+		{
+			paramComboBox_->UseParameterList(selIndex-1);
+		}
+		else
+		{
+			float *myParameters = new float [6];
+			myParameters[0]	= sigmaS;
+			myParameters[1]	= sigmaR;
+			myParameters[2]	= aij;
+			myParameters[3]	= epsilon;
+			myParameters[4]	= minRegion;
+			myParameters[5]	= kernelSize;
+			paramComboBox_->AddParameterList((void *) myParameters, 6);
+		}
+
+		//set the selection to the current parameter slot
+		paramComboBox_->SetSelection(0);
+		isCurrentHistory_	= true;
+	}
+	return;
+
+}
+
+void BgMdiSegmentChild::Segment( void )
+{
+	// parameters
+	//   sigma_s
+	//   sigma_r
+	//   a
+	//   epsilon
+	//   minRegion
+	//   kernel radius
+	//   filter
+	//   speedup level
+	
+	if (hasImage_ == 0)
+	{
+		bgLog("No image loaded!\n");
+		return;
+	}
+
+	//if image segmentaiton is not synergistic clear
+	//display and disable it, otherwise enable it
+	if(!useWeightMap_->GetValue())
+	{
+		ClearDisplay();
+		UpdateDisplay(false);
+	}
+	else
+	{
+		UpdateDisplay(true);
+	}
+	
+	//display parameters to the user
+	if(useWeightMap_->GetValue())
+	{
+		bgLog("Input parameters:\n");
+		bgLog("\tSpatial Bandwidth\t\t= %4d\n\tColor Bandwidth\t\t= %4.1f\n", sigmaS, sigmaR);
+		bgLog("\tMinimum Region\t\t= %4d\n", minRegion);
+		bgLog("\tGradient Window Radius\t= %4d\n", kernelSize);
+		bgLog("\tMixing Parameter\t\t= %4.1f\n", aij);
+		bgLog("\tThreshold\t\t\t= %4.1f\n", epsilon);
+	}
+	else
+	{
+		bgLog("Input parameters:\n");
+		bgLog("\tSpatial Bandwidth\t= %4d\n\tColor Bandwidth\t= %4.1f\n", sigmaS, sigmaR);
+		bgLog("\tMinimum Region\t= %4d\n", minRegion);
+	}
+	
+	//obtain image dimensions
+	int	width, height;
+	width = cbgImage_->x_;
+	height = cbgImage_->y_;
+
+	//obtain image type (color or grayscale)
+	imageType	gtype;
+	if(cbgImage_->colorIm_)
+		gtype = COLOR;
+	else
+		gtype = GRAYSCALE;
+
+	//if gradient and confidence maps are not defined, 
+	//and synergistic segmentation is requested, then compute them;
+	//also compute them if the parameters have changed
+	if(useWeightMap_->GetValue())
+	{
+		
+		//if the weight map has already been defined
+		//then find out if it needs to be recomputed
+		if((weightMap_)&&(edgeParamsHaveChanged_))
+		{
+			delete [] confMap_;
+			delete [] gradMap_;
+			delete [] weightMap_;
+			weightMap_	= (float *) NULL;
+			//indicate that the change has been recognized...
+			edgeParamsHaveChanged_	= false;
+		}
+		
+		//if the weight map has not been computed or discarded
+		//then recompute it...
+		if(!weightMap_)
+		{
+			
+			//allocate memory for gradient and confidence maps
+			confMap_	= new float[width*height];
+			gradMap_	= new float[width*height];
+			
+			//compute gradient and confidence maps
+			BgEdgeDetect	edgeDetector(kernelSize);
+			edgeDetector.ComputeEdgeInfo(cbgImage_, confMap_, gradMap_);
+			
+			//compute weight map...
+			
+			/******************************************************************/
+			
+			//allocate memory for weight map
+			weightMap_ = new float[width*height];
+			
+			//compute weight map using gradient and confidence maps
+			int i;
+			for (i=0; i<width*height; i++)
+			{
+				if (gradMap_[i] > 0.02)
+					weightMap_[i] = aij*gradMap_[i] + (1 - aij)*confMap_[i];
+				else
+					weightMap_[i] = 0;
+			}
+			
+			/******************************************************************/
+		}
+		
+	}
+	
+	//determine operation (filtering or segmentation)
+	int	operation	= operationRadio_->GetSelection();
+
+	//create instance of image processor class
+	msImageProcessor *iProc = new msImageProcessor();
+
+	//define an input image using the image under consideration
+	//(if filtering or segmentation has taken place, then use this
+	// result upon performing fusing...)
+	if((operation == 2)&&(hasFilter_))
+		iProc->DefineImage(filtImage_->im_, gtype, height, width);
+	else
+		iProc->DefineImage(cbgImage_->im_, gtype, height, width);
+
+	//determine if a custom weight map is to be used
+	wxMenuBar *menubar = GetMenuBar();
+	bool useCustomMap	= menubar->IsChecked(BG_SEGM_USE_MAP);
+
+	//set the weight map (if one was specified and a custom map is not being utilized)
+	if((useWeightMap_->GetValue())&&(weightMap_)&&(!useCustomMap))	iProc->SetWeightMap(weightMap_, epsilon);
+
+	//set the custom map (if one was provided)
+	if((useWeightMap_->GetValue())&&(customMap_)&&(useCustomMap))	iProc->SetWeightMap(customMap_, epsilon);
+	
+	//check for errors in image definition or in the setting
+	//of the confidence map...
+	if (iProc->ErrorStatus)
+	{
+		bgLog("%s\n", iProc->ErrorMessage);
+		return;
+	}
+
+	//perform image segmentation or filtering....
+	timer_start(); //start the timer
+   iProc->SetSpeedThreshold(speedUpThreshold_);
+	switch(operation)
+	{
+	//filter
+	case 1:
+
+		iProc->Filter(sigmaS, sigmaR, speedUpLevel_);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		} else if (iProc->ErrorStatus == EL_HALT)
+		{
+			break;
+		}
+
+		//obtain the filtered image....
+		filtImage_->Resize(width, height, cbgImage_->colorIm_);
+		iProc->GetResults(filtImage_->im_);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		}
+
+		//indicate that only the filtered image has been computed...
+		hasFilter_	= 1;
+		hasSegment_	= 0;
+		
+		break;
+
+	//fuse
+	case 2:
+
+		iProc->FuseRegions(sigmaR, minRegion);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		} else if (iProc->ErrorStatus == EL_HALT)
+		{
+			break;
+		}
+
+		//obtain the segmented image...
+		segmImage_->Resize(width, height, cbgImage_->colorIm_);
+		iProc->GetResults(segmImage_->im_);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		}
+
+		//indicate that the segmented image has been computed...
+		hasSegment_	= 1;
+
+		break;
+
+	//segment
+	default:
+
+		//filter the image...
+		iProc->Filter(sigmaS, sigmaR, speedUpLevel_);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		} else if (iProc->ErrorStatus == EL_HALT)
+		{
+			break;
+		}
+
+		//filter the image....
+		int dim;
+		if(cbgImage_->colorIm_)
+			dim = 3;
+		else
+			dim = 1;
+		unsigned char *tempImage = new unsigned char [dim*height*width];
+		iProc->GetResults(tempImage);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			delete [] tempImage;
+			return;
+		}
+		
+		//fuse regions...
+		iProc->FuseRegions(sigmaR, minRegion);
+		if (iProc->ErrorStatus == EL_ERROR)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			delete [] tempImage;
+			return;
+		} else if (iProc->ErrorStatus == EL_HALT)
+		{
+			delete [] tempImage;
+			break;
+		}
+
+		//obtain the segmented and filtered image...
+		filtImage_->Resize(width, height, cbgImage_->colorIm_);
+		memcpy(filtImage_->im_, tempImage, dim*height*width*sizeof(unsigned char));
+		delete [] tempImage;
+		segmImage_->Resize(width, height, cbgImage_->colorIm_);
+		iProc->GetResults(segmImage_->im_);
+		if (iProc->ErrorStatus)
+		{
+			bgLog("%s\n", iProc->ErrorMessage);
+			return;
+		}
+
+		//indicate that both the filtered and segmented image have been computed...
+		hasFilter_	= 1;
+		hasSegment_	= 1;
+
+	}
+
+	//check and see if the algorithm has been halted, if so
+	//then de-allocate the image processing object and
+	//indicate to the working thread that it is safe
+	//to exit at this point and exit
+	if(iProc->ErrorStatus == EL_HALT)
+	{
+		delete iProc;
+		stop_flag	= false;
+		bgLog("Operation Canceled.\n");
+		return;
+	}
+
+	//set has boundaries to true
+	hasBoundaries_	= true;
+	
+	//clean boundary data if any exists
+	boundaries_->CleanData();
+	
+	//get boundary indeces from region list object
+	//of the image processor object...
+	RegionList	*regionList			= iProc->GetBoundaries();
+	int			*regionIndeces		= regionList->GetRegionIndeces(0);
+	int			numRegions			= regionList->GetNumRegions();
+	int			boundaryPointCount	= 0;
+	
+	//calculate the number of boundary points stored by region list
+	//class
+	int i;
+	for(i = 0; i < numRegions; i++)
+		boundaryPointCount += regionList->GetRegionCount(i);
+	
+	//create a point set using calculated boundary point count...
+	boundaries_->x_	= new int [boundaryPointCount];
+	boundaries_->y_	= new int [boundaryPointCount];
+	boundaries_->n_	= boundaryPointCount;
+	for(i = 0; i < boundaryPointCount; i++)
+	{
+		boundaries_->x_[i]	= regionIndeces[i]%width;
+		boundaries_->y_[i]	= regionIndeces[i]/width;
+	}
+	
+	//set pen width, and style
+	boundaries_->pen_.SetWidth(1);
+	boundaries_->pen_.SetStyle(wxSOLID);
+	
+	//set point type to point (= 1)
+	boundaries_->type_	= 1;
+	
+	//construct the phDiagram
+	if(useWeightMap_->GetValue())	SetphDiagram(width, confMap_, gradMap_);
+	
+	//display the confidence and gradient maps respectively
+	if(useWeightMap_->GetValue())
+	{
+		wxCommandEvent myevent;
+		myevent.m_id = BG_CANVAS_VIEW1_CONFMAP;
+		OnUpdatePlotWindow1(myevent);
+		myevent.m_id = BG_CANVAS_VIEW2_GRADMAP;
+		OnUpdatePlotWindow2(myevent);
+	}
+
+	//delete the image processing object
+	delete iProc;
+
+	//done.
+
+	//stop the timer
+	timer_stop();
+
+	//update the GUI...
+
+	/**********************************************************************************/
+
+	//update the menu bar
+	menubar->Enable(BG_SEGM_SAVE_SEGMENTED, true);
+
+	//update tool bar
+	SaveEnable();
+
+	//update segmentation window....
+	switch(operation)
+	{
+
+	//the image has been filtered only....
+	case 1:
+		viewImSegRadio_->Enable(1, true);
+		viewImSegRadio_->Enable(2, false);
+		viewImSegRadio_->SetSelection(1);
+		break;
+
+	//the image has been segmented only...
+	case 2:
+		viewImSegRadio_->Enable(2, true);
+		viewImSegRadio_->SetSelection(2);
+		break;
+
+	//image has been filtered and segmented...
+	default:
+		viewImSegRadio_->Enable(1, true);
+		viewImSegRadio_->Enable(2, true);
+		viewImSegRadio_->SetSelection(2);
+		break;
+
+	}
+	viewImSegRadio_->Enable(3, true);
+	viewBoundariesCheck_->Enable(true);
+	wxCommandEvent zcev;
+	OnViewImSeg(zcev);
+
+	//update the menu bars...
+	winPanel1_->EnableMenu(useWeightMap_->GetValue());
+	winPanel2_->EnableMenu(useWeightMap_->GetValue());
+
+	/**********************************************************************************/
+
+	//set progress to 100% (need this for case of filtering)
+	percentDone = 100;
+	
+	//indicate that it is safe for the thread to stop executing
+	stop_flag	= false; 
+
+	//done.
+	return;
+
+}
+
+int BgMdiSegmentChild::GetParameters(int &sigmaS, float &sigmaR, float &aij, float &epsilon, int &minRegion, int &kernelSize, int dataEntryCheck)
+{
+
+   double	tempd;
+   char		str[10];
+
+   //do not perform data entry check
+   if(!dataEntryCheck)
+   {
+	   //sigmaS
+	   txtSigmaS_->GetValue().ToDouble(&tempd);
+	   sigmaS			= bgRoundSign(tempd);
+
+	   //sigmaR
+	   txtSigmaR_->GetValue().ToDouble(&tempd);
+	   sigmaR			= (float) tempd;
+
+	   //minRegion
+	   txtMinRegion_->GetValue().ToDouble(&tempd);
+	   minRegion		= bgRoundSign(tempd);
+
+	   //kernel size
+	   txtKernelSize_->GetValue().ToDouble(&tempd);
+	   kernelSize		= bgRoundSign(tempd);
+
+	   //aij
+	   txtA_->GetValue().ToDouble(&tempd);
+	   aij				= (float) tempd;
+
+	   //epsilon
+	   txtEpsilon_->GetValue().ToDouble(&tempd);
+	   epsilon			= (float) tempd;
+
+	   //done.
+	   return 0;
+   }
+   
+   //perform data entry check
+   if ((txtSigmaS_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
+   {
+	   sigmaS = (int)(tempd + 0.5);
+	   sprintf(str, "%d", sigmaS);
+	   txtSigmaS_->SetValue(str);
+   }
+   else
+   {
+	   bgLog("The value of the spatial bandwidth cannot be zero or negative.\n");
+	   return 1;
+   }
+   if ((txtSigmaR_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
+	   sigmaR = tempd;
+   else
+   {
+	   bgLog("The value of the range bandwidth cannot be zero or negative.\n");
+	   return 1;
+   }
+   if ((txtMinRegion_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0))
+   {
+	   minRegion = (int)(tempd + 0.5);
+	   sprintf(str, "%d", minRegion);
+	   txtMinRegion_->SetValue(str);
+   }
+   else
+   {
+	   bgLog("The value of minimum region cannot be negative.\n");
+	   return 1;
+   }
+   if ((txtKernelSize_->GetValue().ToDouble(&tempd) == TRUE) && (tempd > 0))
+   {
+	   kernelSize = (int)(tempd + 0.5);
+	   sprintf(str, "%d", kernelSize);
+	   txtKernelSize_->SetValue(str);
+   }
+   else
+   {
+	   bgLog("The gradient window radius cannot be zero or negative.\n");
+	   return 1;
+   }
+   if ((txtA_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0) && (tempd <= 1))
+   {
+	   aij = tempd;
+	   if(aij < 0.01) txtA_->SetValue("0.0");
+   }
+   else
+   {
+	   bgLog("The value of the mixture parameter cannot be negative or greater than one.\n");
+	   return 1;
+   }
+   if ((txtEpsilon_->GetValue().ToDouble(&tempd) == TRUE) && (tempd >= 0) && (tempd <= 1))
+   {
+	   epsilon = tempd;
+	   if(epsilon < 0.01) txtEpsilon_->SetValue("0.0");
+   }
+   else
+   {
+	   bgLog("The threshold value cannot be negative or greater than one.\n");
+	   return 1;
+   }
+   return 0;
 }
\ No newline at end of file
diff --git a/Utilities/otbedison/GUI/bgimsystem.h b/Utilities/otbedison/GUI/bgimsystem.h
old mode 100755
new mode 100644
index 0d64026bc3f484e5fc9dc7bacb0755472fa3b4f5..9f6d10b5a6b2651ee0ea08b43cdacf04cd78d406
--- a/Utilities/otbedison/GUI/bgimsystem.h
+++ b/Utilities/otbedison/GUI/bgimsystem.h
@@ -1,43 +1,43 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        bgimsystem.cpp
-// Purpose:     Image processing system
-// Author:      Bogdan Georgescu, Chris M. Christoudias
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu, Chris M. Christoudias
-// Version:     v0.1
 /////////////////////////////////////////////////////////////////////////////
-
+// Name:        bgimsystem.cpp
+// Purpose:     Image processing system
+// Author:      Bogdan Georgescu, Chris M. Christoudias
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu, Chris M. Christoudias
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
 #include <wx/toolbar.h>
 #include <wx/image.h>
 #include <wx/bitmap.h>
 #include <wx/splitter.h>
 #include <wx/textfile.h>
-#include <wx/textctrl.h>
+#include <wx/textctrl.h>
 #include <wx/spinctrl.h>
 #include <wx/log.h>
-
-// segmentation defaults
-#define BG_SEGM_OP_SIZEX	200
-#define BG_SEGM_OP_SIZEY	350
-#define BG_SP_WIDTH			170
-#define BG_SP_HEIGHT		110
-#define BG_SP_HEIGHT_2		93
-#define BG_SP_TOP_HEIGHT	70
-#define	BG_RIGHT_CELL		112
-#define BG_LEFT_CELL		8
-#define	HOVER_MENU_X		30
-#define	HOVER_MENU_Y		30
-#define HOVER_MENU_BOUND	10
-#define PLOT_MENU_HEIGHT	25
-
+
+// segmentation defaults
+#define BG_SEGM_OP_SIZEX	200
+#define BG_SEGM_OP_SIZEY	350
+#define BG_SP_WIDTH			170
+#define BG_SP_HEIGHT		110
+#define BG_SP_HEIGHT_2		93
+#define BG_SP_TOP_HEIGHT	70
+#define	BG_RIGHT_CELL		112
+#define BG_LEFT_CELL		8
+#define	HOVER_MENU_X		30
+#define	HOVER_MENU_Y		30
+#define HOVER_MENU_BOUND	10
+#define PLOT_MENU_HEIGHT	25
+
 // end segmentation defaults
 
 #define C_PARAMX 10
 #define C_PARAMDX 30
 #define C_PARAMY 20
-#define C_PARAMDY 30
-#define C_PARAMSX 90
+#define C_PARAMDY 30
+#define C_PARAMSX 90
 #define C_PARAMSY 20
 #define SEQ_PANEL_SIZE_X 200
 #define SEQ_PANEL_SIZE_Y 30
@@ -49,25 +49,25 @@
 #define MAX_CUSTOM_NODES 100
 
 #define RANK_CONF_IMSIZEX	256
-#define RANK_CONF_IMSIZEY	256
-#define RANK_CONF_MARGINX	70
+#define RANK_CONF_IMSIZEY	256
+#define RANK_CONF_MARGINX	70
 #define	RANK_CONF_MARGINY	40
-
-//window type identifier constants
-#define BG_EDGE_WINDOW 1
-#define BG_SEGM_WINDOW 2
-
-//max image size
-#define	MAX_WIDTH	1600
-#define	MAX_HEIGHT	1600
-
-//min image size
-#define	MIN_WIDTH	16
-#define	MIN_HEIGHT	16
-
-//determines zooming action
-#define ZOOM_OUT	0
-#define ZOOM_IN		1
+
+//window type identifier constants
+#define BG_EDGE_WINDOW 1
+#define BG_SEGM_WINDOW 2
+
+//max image size
+#define	MAX_WIDTH	1600
+#define	MAX_HEIGHT	1600
+
+//min image size
+#define	MIN_WIDTH	16
+#define	MIN_HEIGHT	16
+
+//determines zooming action
+#define ZOOM_OUT	0
+#define ZOOM_IN		1
 
 // log everything to a text window (GUI only of course)
 class bgLogTextCtrl : public wxLog
@@ -90,9 +90,9 @@ public:
    bool OnInit();
 };
 
-
-
-
+
+
+
 
 class BgPointSet
 {
@@ -156,233 +156,233 @@ public:
    void StartDragging(int, int);
    void DragTo(int, int);
    void EndDragging(int, int);
-};
-
-class BgText
-{
-public:
-	char	*text_;
-	wxFont	*font_;
-	int		x_, y_;
-	int		id_;
-	
-	BgText(void);
-	BgText(int,char*,wxFont,int,int);
-	~BgText(void);
-	void SetText(char*);
-	void SetFont(wxFont);
-	void SetId(int);
-	void SetPlotLocation(int,int);
-};
-
-class BgTextObj
-{
-public:
-	BgText *text_;
-	BgTextObj	*next_;
-
-	BgTextObj(void);
-	BgTextObj(BgText*);
-	~BgTextObj(void);
-};
-
-class BgTextList
-{
-public:
-	BgTextList(void);
-	~BgTextList(void);
-	int AddText (BgText*);
-	int RemoveText(int);
-	BgText *GetText(void);
-	int	GetTextCount(void);
-	void ResetList(void);
-
-private:
-	BgTextObj *head_, *cur_;
-	int	itemcount_;
-	void DeleteText(void);
-};
-
-class BgBitmap
-{
-public:
-	wxBitmap	*bitmap_;
-	int			location_x_, location_y_;
-	int			id_;
-
-	BgBitmap(void);
-	BgBitmap(wxBitmap*, int, int, int);
-	~BgBitmap(void);
-	void SetMap(wxBitmap*);
-	void SetPlotLocation(int,int);
-	void SetId(int);
-};
-
-class BgBitmapObj
-{
-public:
-	BgBitmap	*bitmap_;
-	BgBitmapObj	*next_;
-
-	BgBitmapObj(void);
-	BgBitmapObj(BgBitmap*);
-	~BgBitmapObj(void);
-};
-
-class BgBitmapList
-{
-public:
-	BgBitmapList(void);
-	~BgBitmapList(void);
-	int AddBitmap (BgBitmap*);
-	void RemoveBitmap(BgBitmap*);
-	BgBitmap *GetBitmap(void);
-	void ResetList(void);
-	int	GetBitmapCount(void);
-
-private:
-	BgBitmapObj *head_, *cur_;
-	int	itemcount_;
-	void DeleteBitmap(void);
-};
-
-class BgAxis
-{
-public:
-	int		start_x_, start_y_;		//plotting origin of axis
-	int		length_;				//axis length
-	int		direction_;				//0 - horizontal, 1 - vertical
-	int		ticknum_;				//number of ticks
-	float	start_val_, stop_val_;	//starting and stopping location of axis
-	BgText	*label_;				//axis label
-	int		label_x_, label_y_;		//axis label plot location
-	int		rotation_;				//sets rotation
-
-	BgAxis(void);
-	BgAxis(int, int, int, int, int, float, float);
-	~BgAxis(void);
-
-	void SetPlotOrigin(int, int);
-	void SetLength(int);
-	void SetDirection(int);
-	void SetTicknum(int);
-	void SetBounds(float,float);
-	void Label(BgText*);
-	void RemoveLabel(void);
-	void SetLabelRotation(int);
-	void PlotAxis(wxDC *dc);
-};
-
-class BgThread : public wxThread {
-public:
-	BgThread(wxThreadKind, void foo(void*), void*);
-	~BgThread( void );
-
-private:
-
-	//determines the entry point of the thread (foo)
-	void *Entry( void );
-
-	//pointer to the function foo and its corresponding object
-	void *Object_;
-	void (*function_)(void*);
-	
-};
-
-//Custom dialog box that allows for the addition of bitmaps
-//and bold text (etc)
-class BgDialog : public wxDialog {
-public:
-	BgDialog(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, long, const wxString&);
-	~BgDialog(void);
-
-	//add/remove objects....
-	void AddText(BgText *);
-	void RemoveText(int);
-	void AddBitmap(BgBitmap *);
-	void RemoveBitmap(BgBitmap *);
-
-	//paint/close dialog
-	virtual void OnPaint(wxPaintEvent& );
-	void OnExit(wxCommandEvent& );
-	wxButton* okButton_;
-
-	//declare an event table for this class
-	DECLARE_EVENT_TABLE();
-
-private:
-
-	//text/bitmap lists...
-	BgTextList		tlist_;
-	BgBitmapList	blist_;
-
-};
-
-class BgHoverBar : public wxWindow
-{
-public:
-	BgHoverBar(wxWindow*, wxWindowID, int, int, int, int, int, int, int);
-	~BgHoverBar( void );
-
-	wxBitmapButton* menuButton1_;
-	wxBitmapButton* menuButton2_;
-	wxStaticText* menuText1_;
-	wxStaticText* menuText2_;
-	wxMenu* view_menu;
-	wxMenu* save_menu;
-
-	void ShowMenu(wxCommandEvent& );
-	void CheckViewItem(long);
-	void Update( void );
-
-	int	gradViewId_, confViewId_, weitViewId_, custViewId_;
-	int	gradSaveId_, confSaveId_, weitSaveId_;
-
-	//declare an event table for this class
-	DECLARE_EVENT_TABLE();
-};
-
-class BgMenuPanel : public wxPanel
-{
-public:
-	BgMenuPanel(wxWindow*, wxWindowID, int, int, int, int, int, int, int);
-	~BgMenuPanel( void );
-
-	wxBitmapButton* menuButton1_;
-	wxBitmapButton* menuButton2_;
-	wxStaticText* menuText1_;
-	wxStaticText* menuText2_;
-	wxMenu* view_menu;
-	wxMenu* save_menu;
-	wxWindow* scrollWindow_;
-
-	void ShowMenu(wxCommandEvent& );
-	void CheckViewItem(long);
-	void Update( void );
-	void EnableMenu(bool);
-	void OnSize(wxSizeEvent& );
-	void SetScrollWindow(wxWindow*);
-
-	int	gradViewId_, confViewId_, weitViewId_, custViewId_;
-	int	gradSaveId_, confSaveId_, weitSaveId_;
-
-	//declare an event table for this class
-	DECLARE_EVENT_TABLE();
-};
+};
+
+class BgText
+{
+public:
+	char	*text_;
+	wxFont	*font_;
+	int		x_, y_;
+	int		id_;
+	
+	BgText(void);
+	BgText(int,char*,wxFont,int,int);
+	~BgText(void);
+	void SetText(char*);
+	void SetFont(wxFont);
+	void SetId(int);
+	void SetPlotLocation(int,int);
+};
+
+class BgTextObj
+{
+public:
+	BgText *text_;
+	BgTextObj	*next_;
+
+	BgTextObj(void);
+	BgTextObj(BgText*);
+	~BgTextObj(void);
+};
+
+class BgTextList
+{
+public:
+	BgTextList(void);
+	~BgTextList(void);
+	int AddText (BgText*);
+	int RemoveText(int);
+	BgText *GetText(void);
+	int	GetTextCount(void);
+	void ResetList(void);
+
+private:
+	BgTextObj *head_, *cur_;
+	int	itemcount_;
+	void DeleteText(void);
+};
+
+class BgBitmap
+{
+public:
+	wxBitmap	*bitmap_;
+	int			location_x_, location_y_;
+	int			id_;
+
+	BgBitmap(void);
+	BgBitmap(wxBitmap*, int, int, int);
+	~BgBitmap(void);
+	void SetMap(wxBitmap*);
+	void SetPlotLocation(int,int);
+	void SetId(int);
+};
+
+class BgBitmapObj
+{
+public:
+	BgBitmap	*bitmap_;
+	BgBitmapObj	*next_;
+
+	BgBitmapObj(void);
+	BgBitmapObj(BgBitmap*);
+	~BgBitmapObj(void);
+};
+
+class BgBitmapList
+{
+public:
+	BgBitmapList(void);
+	~BgBitmapList(void);
+	int AddBitmap (BgBitmap*);
+	void RemoveBitmap(BgBitmap*);
+	BgBitmap *GetBitmap(void);
+	void ResetList(void);
+	int	GetBitmapCount(void);
+
+private:
+	BgBitmapObj *head_, *cur_;
+	int	itemcount_;
+	void DeleteBitmap(void);
+};
+
+class BgAxis
+{
+public:
+	int		start_x_, start_y_;		//plotting origin of axis
+	int		length_;				//axis length
+	int		direction_;				//0 - horizontal, 1 - vertical
+	int		ticknum_;				//number of ticks
+	float	start_val_, stop_val_;	//starting and stopping location of axis
+	BgText	*label_;				//axis label
+	int		label_x_, label_y_;		//axis label plot location
+	int		rotation_;				//sets rotation
+
+	BgAxis(void);
+	BgAxis(int, int, int, int, int, float, float);
+	~BgAxis(void);
+
+	void SetPlotOrigin(int, int);
+	void SetLength(int);
+	void SetDirection(int);
+	void SetTicknum(int);
+	void SetBounds(float,float);
+	void Label(BgText*);
+	void RemoveLabel(void);
+	void SetLabelRotation(int);
+	void PlotAxis(wxDC *dc);
+};
+
+class BgThread : public wxThread {
+public:
+	BgThread(wxThreadKind, void foo(void*), void*);
+	~BgThread( void );
+
+private:
+
+	//determines the entry point of the thread (foo)
+	void *Entry( void );
+
+	//pointer to the function foo and its corresponding object
+	void *Object_;
+	void (*function_)(void*);
+	
+};
+
+//Custom dialog box that allows for the addition of bitmaps
+//and bold text (etc)
+class BgDialog : public wxDialog {
+public:
+	BgDialog(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, long, const wxString&);
+	~BgDialog(void);
+
+	//add/remove objects....
+	void AddText(BgText *);
+	void RemoveText(int);
+	void AddBitmap(BgBitmap *);
+	void RemoveBitmap(BgBitmap *);
+
+	//paint/close dialog
+	virtual void OnPaint(wxPaintEvent& );
+	void OnExit(wxCommandEvent& );
+	wxButton* okButton_;
+
+	//declare an event table for this class
+	DECLARE_EVENT_TABLE();
+
+private:
+
+	//text/bitmap lists...
+	BgTextList		tlist_;
+	BgBitmapList	blist_;
+
+};
+
+class BgHoverBar : public wxWindow
+{
+public:
+	BgHoverBar(wxWindow*, wxWindowID, int, int, int, int, int, int, int);
+	~BgHoverBar( void );
+
+	wxBitmapButton* menuButton1_;
+	wxBitmapButton* menuButton2_;
+	wxStaticText* menuText1_;
+	wxStaticText* menuText2_;
+	wxMenu* view_menu;
+	wxMenu* save_menu;
+
+	void ShowMenu(wxCommandEvent& );
+	void CheckViewItem(long);
+	void Update( void );
+
+	int	gradViewId_, confViewId_, weitViewId_, custViewId_;
+	int	gradSaveId_, confSaveId_, weitSaveId_;
+
+	//declare an event table for this class
+	DECLARE_EVENT_TABLE();
+};
+
+class BgMenuPanel : public wxPanel
+{
+public:
+	BgMenuPanel(wxWindow*, wxWindowID, int, int, int, int, int, int, int);
+	~BgMenuPanel( void );
+
+	wxBitmapButton* menuButton1_;
+	wxBitmapButton* menuButton2_;
+	wxStaticText* menuText1_;
+	wxStaticText* menuText2_;
+	wxMenu* view_menu;
+	wxMenu* save_menu;
+	wxWindow* scrollWindow_;
+
+	void ShowMenu(wxCommandEvent& );
+	void CheckViewItem(long);
+	void Update( void );
+	void EnableMenu(bool);
+	void OnSize(wxSizeEvent& );
+	void SetScrollWindow(wxWindow*);
+
+	int	gradViewId_, confViewId_, weitViewId_, custViewId_;
+	int	gradSaveId_, confSaveId_, weitSaveId_;
+
+	//declare an event table for this class
+	DECLARE_EVENT_TABLE();
+};
 
 class BgImCanvas : public wxScrolledWindow
 {
-public:
+public:
 
    BgImCanvas(wxWindow* child_frame, wxWindow *parent, const wxPoint& pos, const wxSize& size);
    ~BgImCanvas();
    virtual void OnDraw(wxDC& dc);
 //   void OnEraseBackground(wxEraseEvent& );
    bool IsDirty() const { return m_dirty; }
-
+
    void OnEvent(wxMouseEvent&);
-   void OnMouseRightDown(wxMouseEvent&);
-   //void OnScroll(wxScrollWinEvent&);
+   void OnMouseRightDown(wxMouseEvent&);
+   //void OnScroll(wxScrollWinEvent&);
    void AdjustScroll(int,int,int);
    
    wxBitmap *pbitmap;
@@ -416,87 +416,87 @@ public:
    int ccy_;
    void FillCurveClick();
    int mouseModif_;
-   int crossCursor_;
+   int crossCursor_;
    int m_x_, m_y_;
-
-   //keep track of certain the window events
-   bool	has_focus;
-   bool	leaving;
-
-   //text list object
-   BgTextList tlist_;
-
-   //keep track of the number of un-plotted
-   //text objects
+
+   //keep track of certain the window events
+   bool	has_focus;
+   bool	leaving;
+
+   //text list object
+   BgTextList tlist_;
+
+   //keep track of the number of un-plotted
+   //text objects
    int	textObjectCount_;
-
-   //x and y axis objects
-   BgAxis	*xAxis, *yAxis;
-
-   //list of bitmaps
-   BgBitmapList blist_;
-
-   //clear display
-   bool	clear_display_;
-
-   //do not update display
-   bool	noUpdate_;
-
-   //determines if zooming is requested
-   bool	zoom_in, zoom_out, zoom_window;
-
-   //zooming window parameters
-   int	zoom_level, max_zoom_level, min_zoom_level;
-
-   //zoom buffers
-   unsigned char *buf;
-
-   //zoom cursors
-   wxCursor	*bgCURSOR_MAGNIFIER_PLUS;
-   wxCursor *bgCURSOR_MAGNIFIER_MINUS;
-
-   //maintain copy of zoomed image
-   unsigned char *zImg;
-
-   //define zoom box image
-   wxImage	*zoombox;
-
-   //defein refresh box image
-   wxImage	*refresh_box;
-
-   //maintain point map for reconstruction
-   //of image boundaries
-   bool		*point_map;
-   wxColour	*point_colour;
-
-   //define upper corner of zoom and refresh box
-   int cx, cy;
-
-   //popup menu window
-   int	menuXl_, menuXu_, menuYl_, menuYu_;
-   int	popup;
-   wxWindow* menuWindow;
-
+
+   //x and y axis objects
+   BgAxis	*xAxis, *yAxis;
+
+   //list of bitmaps
+   BgBitmapList blist_;
+
+   //clear display
+   bool	clear_display_;
+
+   //do not update display
+   bool	noUpdate_;
+
+   //determines if zooming is requested
+   bool	zoom_in, zoom_out, zoom_window;
+
+   //zooming window parameters
+   int	zoom_level, max_zoom_level, min_zoom_level;
+
+   //zoom buffers
+   unsigned char *buf;
+
+   //zoom cursors
+   wxCursor	*bgCURSOR_MAGNIFIER_PLUS;
+   wxCursor *bgCURSOR_MAGNIFIER_MINUS;
+
+   //maintain copy of zoomed image
+   unsigned char *zImg;
+
+   //define zoom box image
+   wxImage	*zoombox;
+
+   //defein refresh box image
+   wxImage	*refresh_box;
+
+   //maintain point map for reconstruction
+   //of image boundaries
+   bool		*point_map;
+   wxColour	*point_colour;
+
+   //define upper corner of zoom and refresh box
+   int cx, cy;
+
+   //popup menu window
+   int	menuXl_, menuXu_, menuYl_, menuYu_;
+   int	popup;
+   wxWindow* menuWindow;
+
    void AddPointSet(BgPointSet*);
-   void RemovePointSet(BgPointSet*);
+   void RemovePointSet(BgPointSet*);
    void AddLineSet(BgLineSet*);
    void RemoveLineSet(BgLineSet*);
    void AddCurveSet(BgCurveSet*);
    void RemoveCurveSet(BgCurveSet*);
-   void AddText(BgText*);
-   void RemoveText(int);
-   void AddHorizontalAxis(int,int,int,int,float,float);
-   void AddVerticalAxis	 (int,int,int,int,float,float);
-   void ClearAxis();
-   void LabelHorizontalAxis(BgText*);
-   void LabelVerticalAxis(BgText*);
-   void RemoveHorizontalAxisLabel(void);
-   void RemoveVerticalAxisLabel(void);
-   void RotateHorizontalAxisLabel(int);
-   void RotateVerticalAxisLabel(int);
-   void AddBitmap(BgBitmap*);
-   void RemoveBitmap(BgBitmap*);
-   void ClearDisplay(void);
+   void AddText(BgText*);
+   void RemoveText(int);
+   void AddHorizontalAxis(int,int,int,int,float,float);
+   void AddVerticalAxis	 (int,int,int,int,float,float);
+   void ClearAxis();
+   void LabelHorizontalAxis(BgText*);
+   void LabelVerticalAxis(BgText*);
+   void RemoveHorizontalAxisLabel(void);
+   void RemoveVerticalAxisLabel(void);
+   void RotateHorizontalAxisLabel(int);
+   void RotateVerticalAxisLabel(int);
+   void AddBitmap(BgBitmap*);
+   void RemoveBitmap(BgBitmap*);
+   void ClearDisplay(void);
 
    void AddTrackSet(int, int, int, int);
    void RemoveTrackSet();
@@ -504,20 +504,20 @@ public:
    int	SetImage(wxString imname);
    void SetImage(wxImage& image);
    void SetSameImage(wxImage& image);
-   void SetImageFromGray(unsigned char* data, int w, int h);
-   void SetImage(unsigned char* data, int w, int h, bool color = false);
+   void SetImageFromGray(unsigned char* data, int w, int h);
+   void SetImage(unsigned char* data, int w, int h, bool color = false);
    void ShowBitmap(bool);
    void ClearData(int refresh=0);
-   void AddMargin(int, int);
-
-   int	Zoom(int);
-   int	Zoom(int,int,int);
-   int	ZoomIn(int, int);
-   int	ZoomOut(int, int);
-   void SetMaxZoomLevel(int);
-   void SetMinZoomLevel(int);
-   void DisplayZoomWindow(int,int);
-
+   void AddMargin(int, int);
+
+   int	Zoom(int);
+   int	Zoom(int,int,int);
+   int	ZoomIn(int, int);
+   int	ZoomOut(int, int);
+   void SetMaxZoomLevel(int);
+   void SetMinZoomLevel(int);
+   void DisplayZoomWindow(int,int);
+
    void OnCustomAddNode(wxCommandEvent&);
    void OnCustomDeleteNode(wxCommandEvent&);
    void OnCTypeEllipse(wxCommandEvent&);
@@ -525,68 +525,68 @@ public:
    void OnCTypeHLine(wxCommandEvent&);
    void OnCTypeLine(wxCommandEvent&);
    void OnCTypeBox(wxCommandEvent&);
-   void OnCTypeCustom(wxCommandEvent&);
-
-   void AddHoverWindow(wxWindow*, int);
-   void SetHoverWindowLocation(int, int);
-
-   //*************************
+   void OnCTypeCustom(wxCommandEvent&);
+
+   void AddHoverWindow(wxWindow*, int);
+   void SetHoverWindowLocation(int, int);
+
+   //*************************
 
 private:
    bool m_dirty;
-   int	x_offset_, y_offset_;
+   int	x_offset_, y_offset_;
    void MyDrawEllipticArc(wxDC& dc, int x, int y, int w, int h, int sa, int ea);
-   wxWindow	*child_frame_;
-
-   //used for zoom window
-   void DefineZoomBox(int,int,int,int);
-   void DefineRefreshBox(void);
-   void CreatePointMap(int,int);
-   void AddPoints(unsigned char*, int);
+   wxWindow	*child_frame_;
+
+   //used for zoom window
+   void DefineZoomBox(int,int,int,int);
+   void DefineRefreshBox(void);
+   void CreatePointMap(int,int);
+   void AddPoints(unsigned char*, int);
 
    DECLARE_EVENT_TABLE()
-};
-
-
-class BgParameterHistory {
-public:
-	BgParameterHistory( void );
-	BgParameterHistory(void*, int);
-	~BgParameterHistory();
-
-	void				*params_;
-	int					listSize_;
-	BgParameterHistory	*next_;
-};
-
-
-//parameter history box tool
-//IMPORTANT: WHEN ADDING A PARAMETER LIST, THIS OBJECT OBTAINS OWNERSHIP
-//			 OF THAT LIST (I.E. IT WILL DELETE THE MEMORY FOR YOU!!!!).
-class BgParameterHistoryBox : public wxComboBox {
-public:
-	BgParameterHistoryBox(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, int, long, const wxValidator&, const wxString&);
-	~BgParameterHistoryBox( void );
-
-	//add/get parameter lists
-	void AddParameterList(void*, int);
-	void *GetParameterListData(int);
-	int GetParameterListCount(int);
-
-	//keep track of parameter history
-	void SetCurrentList(void*, int);
-	void* GetCurrentListData( void );
-	int GetCurrentListCount( void );
-	void UseParameterList(int);
-
-private:
-
-	//paramter list array...
-	BgParameterHistory	*historyList_, currentList_;
-	int					listCount_, maxCount_;
-
-};
-
+};
+
+
+class BgParameterHistory {
+public:
+	BgParameterHistory( void );
+	BgParameterHistory(void*, int);
+	~BgParameterHistory();
+
+	void				*params_;
+	int					listSize_;
+	BgParameterHistory	*next_;
+};
+
+
+//parameter history box tool
+//IMPORTANT: WHEN ADDING A PARAMETER LIST, THIS OBJECT OBTAINS OWNERSHIP
+//			 OF THAT LIST (I.E. IT WILL DELETE THE MEMORY FOR YOU!!!!).
+class BgParameterHistoryBox : public wxComboBox {
+public:
+	BgParameterHistoryBox(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, int, long, const wxValidator&, const wxString&);
+	~BgParameterHistoryBox( void );
+
+	//add/get parameter lists
+	void AddParameterList(void*, int);
+	void *GetParameterListData(int);
+	int GetParameterListCount(int);
+
+	//keep track of parameter history
+	void SetCurrentList(void*, int);
+	void* GetCurrentListData( void );
+	int GetCurrentListCount( void );
+	void UseParameterList(int);
+
+private:
+
+	//paramter list array...
+	BgParameterHistory	*historyList_, currentList_;
+	int					listCount_, maxCount_;
+
+};
+
 
 // Define the parameter dialog box
 
@@ -634,29 +634,29 @@ public:
 DECLARE_EVENT_TABLE()
 };
 
-class BgSpeedSelect : public wxDialog
-{
-public:
-   BgSpeedSelect(wxWindow* parent, wxWindowID id, const wxString& title,
-      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
-      long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = "dialogBox");
-   ~BgSpeedSelect();
-   void OnOk(wxCommandEvent& );
-   void OnCancel(wxCommandEvent& );
-   void SetSliderValue(float);
-   void GetSliderValue(float&);
-
-   // dialog parameters
-   wxButton* okButton_;
-   wxButton* cancelButton_;
-
-   wxStaticText* txtQuality_;
-   wxStaticText* txtSpeed_;
-
-   wxSlider *sldSpeed_;
-DECLARE_EVENT_TABLE()
-};
-
+class BgSpeedSelect : public wxDialog
+{
+public:
+   BgSpeedSelect(wxWindow* parent, wxWindowID id, const wxString& title,
+      const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+      long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = "dialogBox");
+   ~BgSpeedSelect();
+   void OnOk(wxCommandEvent& );
+   void OnCancel(wxCommandEvent& );
+   void SetSliderValue(float);
+   void GetSliderValue(float&);
+
+   // dialog parameters
+   wxButton* okButton_;
+   wxButton* cancelButton_;
+
+   wxStaticText* txtQuality_;
+   wxStaticText* txtSpeed_;
+
+   wxSlider *sldSpeed_;
+DECLARE_EVENT_TABLE()
+};
+
 
 // Define a new frame
 class BgMdiFrame : public wxMDIParentFrame
@@ -667,30 +667,30 @@ public:
     wxTextCtrl    *logtext_;
     wxLog *logTargetOld_;
     int logsize_;
-   bgLogTextCtrl* bglogctrl_;
-   char programDir_[1000];
+   bgLogTextCtrl* bglogctrl_;
+   char programDir_[1000];
    char helpDir_[1000];
-
+
    BgMdiFrame(wxWindow *parent, const wxWindowID id, const wxString& title,
       const wxPoint& pos, const wxSize& size, const long style);
-
+
    void InitToolBar(wxToolBar* toolBar);
-   
-   void	GetImageFileInfo(char**, char**);
+   
+   void	GetImageFileInfo(char**, char**);
    void ZoomControl(wxCommandEvent& );
-   void OnSize(wxSizeEvent&);
+   void OnSize(wxSizeEvent&);
    void OnAbout(wxCommandEvent&);
-   void OnHelp(wxCommandEvent&);
-   void OnNewEdgeWindow(wxCommandEvent&);
-   void OnNewSegmWindow(wxCommandEvent&);
+   void OnHelp(wxCommandEvent&);
+   void OnNewEdgeWindow(wxCommandEvent&);
+   void OnNewSegmWindow(wxCommandEvent&);
    void OnLoadImage(wxCommandEvent&);
-   void OnLoadImageEdge(wxCommandEvent&);
+   void OnLoadImageEdge(wxCommandEvent&);
    void OnLoadImageSegm(wxCommandEvent&);
    void OnSaveResult(wxCommandEvent& WXUNUSED(event));
    void OnQuit(wxCommandEvent&);
-   void OnClose(wxCloseEvent&);
-   void SetChildTitle(wxMDIChildFrame*, int, int, int);
-   void UpdateZoomControl(wxMDIChildFrame*, int, int);
+   void OnClose(wxCloseEvent&);
+   void SetChildTitle(wxMDIChildFrame*, int, int, int);
+   void UpdateZoomControl(wxMDIChildFrame*, int, int);
 
    DECLARE_EVENT_TABLE()
 };
@@ -748,64 +748,64 @@ public:
    wxButton* edButton_;
    wxButton* cpButton_;
    wxCheckBox* viewOrigCheck_;
-   wxCheckBox* viewEdgeCheck_;
-
-   // more right panel stuff
-   wxStaticText* txtNmxR_;
-   wxStaticText* txtNmxC_;
-   wxStaticText* txtHHR_;
-   wxStaticText* txtHHC_;
-   wxStaticText* txtHLR_;
-   wxStaticText* txtHLC_;
-   wxStaticText* txtMinPt_;
-   wxStaticText* txtNmxType_;
-   wxStaticText* txtHHType_;
-   wxStaticText* txtHLType_;
-   wxStaticText* txtKernelSize_;
-
-   wxStaticText* valNmxR_;
-   wxStaticText* valNmxC_;
-   wxStaticText* valHHR_;
-   wxStaticText* valHHC_;
-   wxStaticText* valHLR_;
-   wxStaticText* valHLC_;
-   wxStaticText* valMinPt_;
-   wxStaticText* valNmxType_;
-   wxStaticText* valHHType_;
-   wxStaticText* valHLType_;
-   wxStaticText* valKernelSize_;
-
-   int loopset_;
-   //parent toolbar
-   wxToolBar *toolbar;
-
-   //keep track of current number of frames open
-   bool window_open;
-
-   //keep track of max/min zoom
-   bool	maxZoom_, minZoom_;
-
-   //keep track of filename and window number
-   char *filename_;
-   int	window_number_;
-
-   //keep track of display image width, height, and zoom level
-   int	width_, height_;
+   wxCheckBox* viewEdgeCheck_;
+
+   // more right panel stuff
+   wxStaticText* txtNmxR_;
+   wxStaticText* txtNmxC_;
+   wxStaticText* txtHHR_;
+   wxStaticText* txtHHC_;
+   wxStaticText* txtHLR_;
+   wxStaticText* txtHLC_;
+   wxStaticText* txtMinPt_;
+   wxStaticText* txtNmxType_;
+   wxStaticText* txtHHType_;
+   wxStaticText* txtHLType_;
+   wxStaticText* txtKernelSize_;
+
+   wxStaticText* valNmxR_;
+   wxStaticText* valNmxC_;
+   wxStaticText* valHHR_;
+   wxStaticText* valHHC_;
+   wxStaticText* valHLR_;
+   wxStaticText* valHLC_;
+   wxStaticText* valMinPt_;
+   wxStaticText* valNmxType_;
+   wxStaticText* valHHType_;
+   wxStaticText* valHLType_;
+   wxStaticText* valKernelSize_;
+
+   int loopset_;
+   //parent toolbar
+   wxToolBar *toolbar;
+
+   //keep track of current number of frames open
+   bool window_open;
+
+   //keep track of max/min zoom
+   bool	maxZoom_, minZoom_;
+
+   //keep track of filename and window number
+   char *filename_;
+   int	window_number_;
+
+   //keep track of display image width, height, and zoom level
+   int	width_, height_;
 
    BgMdiEdgeChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
    ~BgMdiEdgeChild();
    void OnQuit(wxCommandEvent& );
-   void OnClose(wxCloseEvent& );
-   void OnFocus(wxFocusEvent& );
-   void NoZoom(void);
-   void ZoomWindow(void);
-   void ZoomIn(void);
-   void ZoomOut(void);
-   void UpdateZoomControl(void);
-   void RunEnable(void);
-   void SaveEnable(void);
-   void UpdateToolBar(void);
-   void ResetToolBar(void);
+   void OnClose(wxCloseEvent& );
+   void OnFocus(wxFocusEvent& );
+   void NoZoom(void);
+   void ZoomWindow(void);
+   void ZoomIn(void);
+   void ZoomOut(void);
+   void UpdateZoomControl(void);
+   void RunEnable(void);
+   void SaveEnable(void);
+   void UpdateToolBar(void);
+   void ResetToolBar(void);
    void ReadImage(char*, char*);
    void OnLoadImage(wxCommandEvent& );
    void OnSaveEdgeMap(wxCommandEvent& );
@@ -817,177 +817,177 @@ public:
    void OnCViewEdge(wxCommandEvent& );
    void OnSize(wxSizeEvent& );
    void SetTotalImage(void);
-   void SetNmxImage(void);
-
-   // param events
-   void SetParametersNum(void);
-   void SetParametersStr(void);
-   void OnUpdateNum(wxCommandEvent& );
-
+   void SetNmxImage(void);
+
+   // param events
+   void SetParametersNum(void);
+   void SetParametersStr(void);
+   void OnUpdateNum(wxCommandEvent& );
+
    DECLARE_EVENT_TABLE()
 };
 
-class BgMdiSegmentChild: public wxMDIChildFrame
-{
-public:
-   BgImage* cbgImage_;
-   BgImage* filtImage_;
-   BgImage* segmImage_;
-   BgImage* whiteImage_;
-
-   //segmemtation parameters
-   int		sigmaS, minRegion, kernelSize;
-   float	sigmaR, aij, epsilon, *gradMap_, *confMap_, *weightMap_, *customMap_;
-   bool		edgeParamsHaveChanged_;
-   SpeedUpLevel	speedUpLevel_;
-   float speedUpThreshold_;
-
-   //point set used to draw boundaries
-   BgPointSet* boundaries_;
-
-   //window stuff
-   BgImCanvas* displayImage_;
-
-   //confidence map image
-   BgImCanvas* plotWindow1_;
-
-   //rank map image
-   BgImCanvas* plotWindow2_;
-
-   //ph diagram
-   BgImCanvas* phDiagram_;
-
-   int hasBoundaries_;
-   int hasImage_;
-   int hasFilter_;
-   int hasSegment_;
-
-   // left panel stuff
-   wxPanel*	optionsPanel_;
-   wxPanel* subPanel1_;
-   wxPanel* subPanel2_;
-   wxPanel* subPanel3_;
-   BgMenuPanel*	winPanel1_;
-   BgMenuPanel* winPanel2_;
-   wxStaticBox* subPanelBox1_;
-   wxStaticBox* subPanelBox2_;
-   wxStaticBox* subPanelBox3_;
-   wxStaticBox* subPanelBox4_;
-
-   wxButton* runButton_;
-   wxButton* loadButton_;
-
-   wxRadioBox* viewImSegRadio_;
-   wxRadioBox* operationRadio_;
-   wxCheckBox* viewBoundariesCheck_;
-
-   wxStaticText* textKernelSize_;
-   wxTextCtrl* txtKernelSize_;
-
-   wxStaticText* textSigmaR_;
-   wxTextCtrl* txtSigmaR_;
-
-   wxStaticText* textSigmaS_;
-   wxTextCtrl* txtSigmaS_;
-
-   wxStaticText* textA_;
-   wxTextCtrl* txtA_;
-
-   wxStaticText* textEpsilon_;
-   wxTextCtrl* txtEpsilon_;
-
-   wxStaticText* textMinRegion_;
-   wxTextCtrl* txtMinRegion_;
-
-   bool	isCurrentHistory_;
-   bool checkTextBoxes_;
-   wxStaticText* textParamBox_;
-   BgParameterHistoryBox*	paramComboBox_;
-
-   wxCheckBox* useWeightMap_;
-
-   //used to split the window to display ph diagram
-   wxSplitterWindow* imagePlotSplitter_;
-   wxSplitterWindow* plotMapSplitter_;
-   wxSplitterWindow* mapSplitter_;
-
-   //store pointer to parent frame toolbar
-   wxToolBar *toolbar;
-
-   //keep track of current number of frames open
-   bool window_open;
-
-   //keep track of filename and window number
-   char *filename_;
-   int	window_number_;
-
-   //keep track of display image width, height, and zoom level
-   int	width_, height_;
-
-   //keep track if max/min zoom occurred
-   int	maxZoom_, minZoom_;
-
-   BgMdiSegmentChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
-   ~BgMdiSegmentChild();
-
-   void OnQuit(wxCommandEvent& );
-   void OnClose(wxCloseEvent& );
-   void OnFocus(wxFocusEvent& );
-   void ZoomWindow(void);
-   void ZoomIn(void);
-   void ZoomOut(void);
-   void NoZoom(void);
-   void UpdateZoomControl(void);
-   void RunEnable(void);
-   void SaveEnable(void);
-   void UpdateToolBar(void);
-   void ResetToolBar(void);
-   void ReadImage(char*, char*);
-   void OnLoadImage(wxCommandEvent& );
-   void LoadCustomWeightMap(wxCommandEvent&);
-   void OnSaveSegmentedImage(wxCommandEvent& );
-   void OnSaveBoundaries(char*, int);
-   void OnSegment(wxCommandEvent& );
-   void Segment(void);
-   void SetphDiagram(int, float*, float*);
-   void OnViewImSeg(wxCommandEvent& );
-   void OnChangeOperation(wxCommandEvent& );
-   void OnChangeParameters(wxCommandEvent& );
-   void	OnUpdateTextBoxes(wxCommandEvent& );
-   void OnUpdateSpeedUpLevel(wxCommandEvent& );
-   void OnViewBoundaries(wxCommandEvent& );
-   void OnUseWeightMap(wxCommandEvent& );
-   void OnUpdatePlotWindow1(wxCommandEvent& );
-   void OnUpdatePlotWindow2(wxCommandEvent& );
-   void OnSaveEdgeInformation(wxCommandEvent& );
-   //void OnChangeView
-   void OnSize(wxSizeEvent& );
-   void ClearDisplay( void );
-   void UpdateDisplay(bool);
-   int  GetParameters(int&, float&, float&, float&, int&, int&, int);
-   DECLARE_EVENT_TABLE()
-};
+class BgMdiSegmentChild: public wxMDIChildFrame
+{
+public:
+   BgImage* cbgImage_;
+   BgImage* filtImage_;
+   BgImage* segmImage_;
+   BgImage* whiteImage_;
+
+   //segmemtation parameters
+   int		sigmaS, minRegion, kernelSize;
+   float	sigmaR, aij, epsilon, *gradMap_, *confMap_, *weightMap_, *customMap_;
+   bool		edgeParamsHaveChanged_;
+   SpeedUpLevel	speedUpLevel_;
+   float speedUpThreshold_;
+
+   //point set used to draw boundaries
+   BgPointSet* boundaries_;
+
+   //window stuff
+   BgImCanvas* displayImage_;
+
+   //confidence map image
+   BgImCanvas* plotWindow1_;
+
+   //rank map image
+   BgImCanvas* plotWindow2_;
+
+   //ph diagram
+   BgImCanvas* phDiagram_;
+
+   int hasBoundaries_;
+   int hasImage_;
+   int hasFilter_;
+   int hasSegment_;
+
+   // left panel stuff
+   wxPanel*	optionsPanel_;
+   wxPanel* subPanel1_;
+   wxPanel* subPanel2_;
+   wxPanel* subPanel3_;
+   BgMenuPanel*	winPanel1_;
+   BgMenuPanel* winPanel2_;
+   wxStaticBox* subPanelBox1_;
+   wxStaticBox* subPanelBox2_;
+   wxStaticBox* subPanelBox3_;
+   wxStaticBox* subPanelBox4_;
+
+   wxButton* runButton_;
+   wxButton* loadButton_;
+
+   wxRadioBox* viewImSegRadio_;
+   wxRadioBox* operationRadio_;
+   wxCheckBox* viewBoundariesCheck_;
+
+   wxStaticText* textKernelSize_;
+   wxTextCtrl* txtKernelSize_;
+
+   wxStaticText* textSigmaR_;
+   wxTextCtrl* txtSigmaR_;
+
+   wxStaticText* textSigmaS_;
+   wxTextCtrl* txtSigmaS_;
+
+   wxStaticText* textA_;
+   wxTextCtrl* txtA_;
+
+   wxStaticText* textEpsilon_;
+   wxTextCtrl* txtEpsilon_;
+
+   wxStaticText* textMinRegion_;
+   wxTextCtrl* txtMinRegion_;
+
+   bool	isCurrentHistory_;
+   bool checkTextBoxes_;
+   wxStaticText* textParamBox_;
+   BgParameterHistoryBox*	paramComboBox_;
+
+   wxCheckBox* useWeightMap_;
+
+   //used to split the window to display ph diagram
+   wxSplitterWindow* imagePlotSplitter_;
+   wxSplitterWindow* plotMapSplitter_;
+   wxSplitterWindow* mapSplitter_;
+
+   //store pointer to parent frame toolbar
+   wxToolBar *toolbar;
+
+   //keep track of current number of frames open
+   bool window_open;
+
+   //keep track of filename and window number
+   char *filename_;
+   int	window_number_;
+
+   //keep track of display image width, height, and zoom level
+   int	width_, height_;
+
+   //keep track if max/min zoom occurred
+   int	maxZoom_, minZoom_;
+
+   BgMdiSegmentChild(wxMDIParentFrame *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
+   ~BgMdiSegmentChild();
+
+   void OnQuit(wxCommandEvent& );
+   void OnClose(wxCloseEvent& );
+   void OnFocus(wxFocusEvent& );
+   void ZoomWindow(void);
+   void ZoomIn(void);
+   void ZoomOut(void);
+   void NoZoom(void);
+   void UpdateZoomControl(void);
+   void RunEnable(void);
+   void SaveEnable(void);
+   void UpdateToolBar(void);
+   void ResetToolBar(void);
+   void ReadImage(char*, char*);
+   void OnLoadImage(wxCommandEvent& );
+   void LoadCustomWeightMap(wxCommandEvent&);
+   void OnSaveSegmentedImage(wxCommandEvent& );
+   void OnSaveBoundaries(char*, int);
+   void OnSegment(wxCommandEvent& );
+   void Segment(void);
+   void SetphDiagram(int, float*, float*);
+   void OnViewImSeg(wxCommandEvent& );
+   void OnChangeOperation(wxCommandEvent& );
+   void OnChangeParameters(wxCommandEvent& );
+   void	OnUpdateTextBoxes(wxCommandEvent& );
+   void OnUpdateSpeedUpLevel(wxCommandEvent& );
+   void OnViewBoundaries(wxCommandEvent& );
+   void OnUseWeightMap(wxCommandEvent& );
+   void OnUpdatePlotWindow1(wxCommandEvent& );
+   void OnUpdatePlotWindow2(wxCommandEvent& );
+   void OnSaveEdgeInformation(wxCommandEvent& );
+   //void OnChangeView
+   void OnSize(wxSizeEvent& );
+   void ClearDisplay( void );
+   void UpdateDisplay(bool);
+   int  GetParameters(int&, float&, float&, float&, int&, int&, int);
+   DECLARE_EVENT_TABLE()
+};
 
 // menu items ids
 enum
 {
-   BG_QUIT = 100,
-	  BG_MENU_WINDOW,
-      BG_DIALOG_OK,
-	  BG_CANVAS_VIEW1_GRADMAP,
-	  BG_CANVAS_VIEW1_CONFMAP,
-	  BG_CANVAS_VIEW1_WEITMAP,
-	  BG_CANVAS_VIEW1_CUSTMAP,
-	  BG_CANVAS_VIEW2_GRADMAP,
-	  BG_CANVAS_VIEW2_CONFMAP,
-	  BG_CANVAS_VIEW2_WEITMAP,
-	  BG_CANVAS_VIEW2_CUSTMAP,
-	  BG_CANVAS_VIEW_BUTTON,
-	  BG_CANVAS_SAVE_GRADMAP,
-	  BG_CANVAS_SAVE_CONFMAP,
-	  BG_CANVAS_SAVE_WEITMAP,
-	  BG_CANVAS_SAVE_BUTTON,
-      BG_NEW_EDGE_WINDOW,
+   BG_QUIT = 100,
+	  BG_MENU_WINDOW,
+      BG_DIALOG_OK,
+	  BG_CANVAS_VIEW1_GRADMAP,
+	  BG_CANVAS_VIEW1_CONFMAP,
+	  BG_CANVAS_VIEW1_WEITMAP,
+	  BG_CANVAS_VIEW1_CUSTMAP,
+	  BG_CANVAS_VIEW2_GRADMAP,
+	  BG_CANVAS_VIEW2_CONFMAP,
+	  BG_CANVAS_VIEW2_WEITMAP,
+	  BG_CANVAS_VIEW2_CUSTMAP,
+	  BG_CANVAS_VIEW_BUTTON,
+	  BG_CANVAS_SAVE_GRADMAP,
+	  BG_CANVAS_SAVE_CONFMAP,
+	  BG_CANVAS_SAVE_WEITMAP,
+	  BG_CANVAS_SAVE_BUTTON,
+      BG_NEW_EDGE_WINDOW,
       BG_NEW_SEGM_WINDOW,
       BG_LOAD_IMAGE_EDGE,
       BG_LOAD_IMAGE_IMAGE,
@@ -996,19 +996,19 @@ enum
       BG_EDGE_VIEW_ORIG,
       BG_EDGE_VIEW_EDGE,
       BG_EDGE_CVIEW_ORIG,
-      BG_EDGE_CVIEW_EDGE,
-      BG_EDGE_PARAM_HHR,
+      BG_EDGE_CVIEW_EDGE,
+      BG_EDGE_PARAM_HHR,
       BG_CHANGE_PARAM_EDGE,
       BG_REFRESH,
       BG_CHANGE_TITLE,
-      BG_CHILD_EDGE_QUIT,
+      BG_CHILD_EDGE_QUIT,
       BG_CHILD_SEGM_QUIT,
       BG_ABOUT,
       BG_HELP,
       BG_PARAMD_OK,
-      BG_PARAMD_CANCEL,
-      BG_SPEEDSEL_OK,
-      BG_SPEEDSEL_CANCEL,
+      BG_PARAMD_CANCEL,
+      BG_SPEEDSEL_OK,
+      BG_SPEEDSEL_CANCEL,
       BG_SPEEDSEL_SLD,
       BG_IMC_ADDNODE,
       BG_IMC_DELETENODE,
@@ -1017,34 +1017,34 @@ enum
       BG_IMC_SELTYPE_HLINE,
       BG_IMC_SELTYPE_LINE,
       BG_IMC_SELTYPE_BOX,
-      BG_IMC_SELTYPE_CUSTOM,
-	  BG_SEGM_SPEEDUP,
-	  BG_SEGM_SPEEDUP_NONE,
-	  BG_SEGM_SPEEDUP_MEDM,
-	  BG_SEGM_SPEEDUP_HIGH,
-      BG_SEGM_LOAD_IMAGE,
-	  BG_SEGM_LOAD_MAP,
-	  BG_SEGM_USE_MAP,
-      BG_SEGM_SAVE_SEGMENTED,
-      BG_SEGM_SAVE_EDGEMAP,
-      BG_SEGM_SEGMENT,
-      BG_SEGM_VIEW_IMSEG,
-      BG_SEGM_VIEW_EDGES,
-	  BG_SEGM_OPERATION,
-	  BG_SEGM_USE_EDGE_MAP,
-	  BG_SEGM_CHANGE_PARAMS,
-	  BG_SEGM_TEXT_SIGMAS,
-	  BG_SEGM_TEXT_SIGMAR,
-	  BG_SEGM_TEXT_MINREG,
-	  BG_SEGM_TEXT_GRADWIN,
-	  BG_SEGM_TEXT_AIJ,
-	  BG_SEGM_TEXT_EPSILON,
-	  BG_LOAD_IMAGE,
-	  BG_SAVE_RESULT,
-	  BG_CROSS,
-	  BG_ZOOM_IN,
-	  BG_ZOOM_OUT,
-	  BG_POINTER,
-     BG_EVENT_UPDATE,
-     BG_EVENT_UPDATE_ID
+      BG_IMC_SELTYPE_CUSTOM,
+	  BG_SEGM_SPEEDUP,
+	  BG_SEGM_SPEEDUP_NONE,
+	  BG_SEGM_SPEEDUP_MEDM,
+	  BG_SEGM_SPEEDUP_HIGH,
+      BG_SEGM_LOAD_IMAGE,
+	  BG_SEGM_LOAD_MAP,
+	  BG_SEGM_USE_MAP,
+      BG_SEGM_SAVE_SEGMENTED,
+      BG_SEGM_SAVE_EDGEMAP,
+      BG_SEGM_SEGMENT,
+      BG_SEGM_VIEW_IMSEG,
+      BG_SEGM_VIEW_EDGES,
+	  BG_SEGM_OPERATION,
+	  BG_SEGM_USE_EDGE_MAP,
+	  BG_SEGM_CHANGE_PARAMS,
+	  BG_SEGM_TEXT_SIGMAS,
+	  BG_SEGM_TEXT_SIGMAR,
+	  BG_SEGM_TEXT_MINREG,
+	  BG_SEGM_TEXT_GRADWIN,
+	  BG_SEGM_TEXT_AIJ,
+	  BG_SEGM_TEXT_EPSILON,
+	  BG_LOAD_IMAGE,
+	  BG_SAVE_RESULT,
+	  BG_CROSS,
+	  BG_ZOOM_IN,
+	  BG_ZOOM_OUT,
+	  BG_POINTER,
+     BG_EVENT_UPDATE,
+     BG_EVENT_UPDATE_ID
 };
diff --git a/Utilities/otbedison/edge/BgDefaults.h b/Utilities/otbedison/edge/BgDefaults.h
old mode 100755
new mode 100644
index a0d11475b8f56ab8f7ce0841a4a69ee0c48dd2a2..c50bbe4fcf4ed3e4bef5b70e4cf80c29ba02b6d4
--- a/Utilities/otbedison/edge/BgDefaults.h
+++ b/Utilities/otbedison/edge/BgDefaults.h
@@ -1,70 +1,70 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        BGDefaults.h
-// Purpose:     Defines some program constants
-// Author:      Bogdan Georgescu
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu
-// Version:     v0.1
-/////////////////////////////////////////////////////////////////////////////
-
-#define PI 3.1415926535
-#define GTRESH PI/6
-#define GTRESH_2 PI/4
-#define RTRESH 7.0
-#define RTRESH_2 20
-#define DF_SIGMA 1.0
-#define DF_HIGH 0.9
-#define DF_LOW 0.5
-#define DF_MINN 5
-
-#define FC_ELLIPSE 0
-#define FC_VERT_LINE 1
-#define FC_HORIZ_LINE 2
-#define FC_LINE 3
-#define FC_SQUARE_BOX 4
-#define FC_CUSTOM 5
-
-// Line detection
-#define NE_TRESH 5
-#define MIN_DIST 30
-#define DMAX 9
-#define DMAX2 DMAX*DMAX
-#define DMIN2 (DMAX-2)*(DMAX-2)
-#define ALPHA_MAX 160.0*PI/180.0
-
-#define MIN_LINE_REZID 1.2
-//#define MIN_LINE_INLIER 7
-#define MIN_LINE_INLIER 15
-
-#define M_FRM_NO_POINT -10000000
-
-#define AUGMENT_MIN_CORN 25
-#define AUGMENT_LINE_STEP 10
-
-extern double bgSign(double);
-extern int bgSolveCubic(double, double, double, double, double&, double&, double&);
-extern inline int bgRound(double);
-extern inline int bgRoundSign(double);
-extern double bgMedian(double*, int, double);
-extern inline double bgMedianToSigmaGaussian(double);
-extern void bgSort(double*, int);
-
-//image sampling functions
-extern void bgZoomIn(unsigned char**, unsigned char*, int, int, int, bool);
-extern void bgZoomOut(unsigned char**, unsigned char*, int, int, int, bool);
-
-//file extension function
-extern void BgAddExtension(char**, char*);
-
-extern void bgLog(const char*, ...);
-extern void bgLogFile(const char*, ...);
-extern int write_pgm_image(const char *outfilename, unsigned char *image, int rows,
-    int cols, char *comment, int maxval);
-extern void write_MATLAB_ASCII(char *filename, float *data, int rows, int cols);
-extern "C" int lmdif(int m, int n,double x[], double fvec[] , double ftol, double xtol, double gtol, int maxfev,
-						 double epsfcn,double diag[],int mode, double factor, int nprint, int *info, int *nfev,
-						 double fjac[],int ldfjac, int ipvt[], double qtf[], double wa1[], double wa2[] ,
-						 double wa3[], double wa4[]);
-extern void timer_start();
-extern void timer_stop();
+/////////////////////////////////////////////////////////////////////////////
+// Name:        BGDefaults.h
+// Purpose:     Defines some program constants
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+#define PI 3.1415926535
+#define GTRESH PI/6
+#define GTRESH_2 PI/4
+#define RTRESH 7.0
+#define RTRESH_2 20
+#define DF_SIGMA 1.0
+#define DF_HIGH 0.9
+#define DF_LOW 0.5
+#define DF_MINN 5
+
+#define FC_ELLIPSE 0
+#define FC_VERT_LINE 1
+#define FC_HORIZ_LINE 2
+#define FC_LINE 3
+#define FC_SQUARE_BOX 4
+#define FC_CUSTOM 5
+
+// Line detection
+#define NE_TRESH 5
+#define MIN_DIST 30
+#define DMAX 9
+#define DMAX2 DMAX*DMAX
+#define DMIN2 (DMAX-2)*(DMAX-2)
+#define ALPHA_MAX 160.0*PI/180.0
+
+#define MIN_LINE_REZID 1.2
+//#define MIN_LINE_INLIER 7
+#define MIN_LINE_INLIER 15
+
+#define M_FRM_NO_POINT -10000000
+
+#define AUGMENT_MIN_CORN 25
+#define AUGMENT_LINE_STEP 10
+
+extern double bgSign(double);
+extern int bgSolveCubic(double, double, double, double, double&, double&, double&);
+extern inline int bgRound(double);
+extern inline int bgRoundSign(double);
+extern double bgMedian(double*, int, double);
+extern inline double bgMedianToSigmaGaussian(double);
+extern void bgSort(double*, int);
+
+//image sampling functions
+extern void bgZoomIn(unsigned char**, unsigned char*, int, int, int, bool);
+extern void bgZoomOut(unsigned char**, unsigned char*, int, int, int, bool);
+
+//file extension function
+extern void BgAddExtension(char**, char*);
+
+extern void bgLog(const char*, ...);
+extern void bgLogFile(const char*, ...);
+extern int write_pgm_image(const char *outfilename, unsigned char *image, int rows,
+    int cols, char *comment, int maxval);
+extern void write_MATLAB_ASCII(char *filename, float *data, int rows, int cols);
+extern "C" int lmdif(int m, int n,double x[], double fvec[] , double ftol, double xtol, double gtol, int maxfev,
+						 double epsfcn,double diag[],int mode, double factor, int nprint, int *info, int *nfev,
+						 double fjac[],int ldfjac, int ipvt[], double qtf[], double wa1[], double wa2[] ,
+						 double wa3[], double wa4[]);
+extern void timer_start();
+extern void timer_stop();
diff --git a/Utilities/otbedison/edge/BgEdge.cpp b/Utilities/otbedison/edge/BgEdge.cpp
old mode 100755
new mode 100644
index 4b2742cc4740f2b91628a2b1fd3df441258d7fdf..c05c2276be48bbf16dd11e603f31c8d9109f5fbe
--- a/Utilities/otbedison/edge/BgEdge.cpp
+++ b/Utilities/otbedison/edge/BgEdge.cpp
@@ -1,4 +1,4 @@
-/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
 // Name:        BgEdge.cpp
 // Purpose:     BGEdge class functions
 // Author:      Bogdan Georgescu
diff --git a/Utilities/otbedison/edge/BgEdge.h b/Utilities/otbedison/edge/BgEdge.h
old mode 100755
new mode 100644
index 81e655b5182eff8d363ebcf40edaed6f2b68caff..5504b370d110820bc44b7eab4155f915ec4832a0
--- a/Utilities/otbedison/edge/BgEdge.h
+++ b/Utilities/otbedison/edge/BgEdge.h
@@ -7,7 +7,7 @@
 // Copyright:   (c) Bogdan Georgescu
 // Version:     v0.1
 /////////////////////////////////////////////////////////////////////////////
-
+
 // 8-connected neighbour
 static const int gNb8[8][2]=
 {
@@ -20,7 +20,7 @@ static const int gNb8[8][2]=
   -1, 0,
   -1, 1
 };
-
+
 class BgEdge
 {
 public:
@@ -31,7 +31,7 @@ public:
    unsigned char* mark_;
    int nPoints_;
    BgEdge* next_;
-
+
    BgEdge();
    ~BgEdge();
    void SetPoints(float*, int);
diff --git a/Utilities/otbedison/edge/BgEdgeDetect.cpp b/Utilities/otbedison/edge/BgEdgeDetect.cpp
old mode 100755
new mode 100644
index cb5264196d78b5f451319599f83827c16216da26..1b7b8e9f6d757ba4802de020010be6dc2391af65
--- a/Utilities/otbedison/edge/BgEdgeDetect.cpp
+++ b/Utilities/otbedison/edge/BgEdgeDetect.cpp
@@ -1,1601 +1,1601 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        BgEdgeDetect.cpp
-// Purpose:     BgEdgeDetect class functions
-// Author:      Bogdan Georgescu
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu
-// Version:     v0.1
-/////////////////////////////////////////////////////////////////////////////
-
-#include <math.h>
-#include "BgImage.h"
-#include "BgEdge.h"
-#include "BgEdgeList.h"
-#include "BgEdgeDetect.h"
-#include "BgDefaults.h"
-#include <stdio.h>
-
-#define TOL_E 2.2e-8
-//#define TOL_E 0.05
-#define SIGN(x) (x<0)? -1:1;
-
-static int my_sign(double val)
-{
-   if(val>TOL_E)
-      return 1;
-   if(val<-TOL_E)
-      return -1;
-   return 0;
-}
-
-extern double factorial(double);
-
-BgEdgeDetect::BgEdgeDetect(int filtDim)
-{
-   havePerm_ = false;
-   WL_ = filtDim;
-   WW_ = 2*WL_+1;
-   nhcust_ = 0;
-   nlcust_ = 0;
-   tcustx_ = new float[MAX_CUSTT];
-   tcusty_ = new float[MAX_CUSTT];
-   CreateFilters();
-   CreateLookTable();
-}
-
-BgEdgeDetect::~BgEdgeDetect()
-{
-   if (havePerm_==true)
-   {
-      delete [] permGx_;
-      delete [] permGy_;
-      delete [] permConf_;
-      delete [] permRank_;
-      delete [] permNmxRank_;
-      delete [] permNmxConf_;
-   }
-   if (nhcust_>0)
-   {
-      delete [] hcustx_;
-      delete [] hcusty_;
-   }
-   if (nlcust_>0)
-   {
-      delete [] lcustx_;
-      delete [] lcusty_;
-   }
-   delete [] tcustx_;
-   delete [] tcusty_;
-   DeleteLookTable();
-}
-
-void BgEdgeDetect::IsGood(void)
-{
-   if (havePerm_==true)
-      bgLog("good\n");
-   else
-      bgLog("bad\n");
-}
-
-
-float BgEdgeDetect::EllipseEval(float x, float y)
-{
-   return ((x*x)/(rankTr_*rankTr_)+(y*y)/(confTr_*confTr_)-1);
-}
-
-float BgEdgeDetect::EllipseComp(float x0, float y0, float x, float y)
-{
-//   return (EllipseEval(x,y)-EllipseEval(x0,y0));
-   return ((x*x-x0*x0)/(rankTr_*rankTr_)+(y*y-y0*y0)/(confTr_*confTr_));
-}
-
-float BgEdgeDetect::LineEval(float x, float y)
-{
-   return (confTr_*x+rankTr_*y-confTr_*rankTr_);
-}
-
-float BgEdgeDetect::LineComp(float x0, float y0, float x, float y)
-{
-//   return (LineEval(x,y)-LineEval(x0,y0));
-   return (confTr_*(x-x0)+rankTr_*(y-y0));
-}
-
-float BgEdgeDetect::VerticalLineEval(float x, float y)
-{
-   return (x-rankTr_);
-}
-
-float BgEdgeDetect::VerticalLineComp(float x0, float y0, float x, float y)
-{
-//   return (VerticalLineEval(x,y)-VerticalLineEval(x0,y0));
-   return (x-x0);
-
-}
-
-float BgEdgeDetect::HorizontalLineEval(float x, float y)
-{
-   return(y-confTr_);
-}
-
-float BgEdgeDetect::HorizontalLineComp(float x0, float y0, float x, float y)
-{
-//   return (HorizontalLineEval(x,y)-HorizontalLineEval(x0,y0));
-   return (y-y0);
-}
-
-float BgEdgeDetect::SquareEval(float x, float y)
-{
-   if ((x/rankTr_)>(y/confTr_))
-      return(x-rankTr_);
-   else
-      return(y-confTr_);
-}
-
-float BgEdgeDetect::SquareComp(float x0, float y0, float x, float y)
-{
-//   return(SquareEval(x,y)-SquareEval(x0,y0));
-   static float tret;
-   tret = ((x/rankTr_)>(y/confTr_)) ? x-rankTr_ : y-confTr_;
-   tret -= ((x0/rankTr_)>(y0/confTr_)) ? x0-rankTr_ : y0-confTr_;
-   return tret;
-}
-
-float BgEdgeDetect::CustomRegionEval(float r,float c)
-{
-   //evaluate user region function
-   //returns -1 if inside +1 if outside
-   
-   if ((r+c)<=ZERO_TRESH)
-      return -1;
-   int i;
-   int crossings=0;
-   float x;
-   
-   //shift to origin
-   for (i=0; i<ncust_; i++)
-   {
-      tcustx_[i]=custx_[i]-r;
-      tcusty_[i]=custy_[i]-c;
-   }
-   
-   for (i=0; i<(ncust_-1); i++)
-   {
-      if ( (tcusty_[i]  >0 && tcusty_[i+1]<=0) ||
-           (tcusty_[i+1]>0 && tcusty_[i]  <=0) )
-      {
-         x = (tcustx_[i]*tcusty_[i+1]-tcustx_[i+1]*tcusty_[i])/(tcusty_[i+1]-tcusty_[i]);
-         if (x>0)
-            crossings++;
-      }	   
-   }		
-   
-   if ((crossings % 2) ==1)
-      return -1;
-   else
-      return 1;
-}
-
-float BgEdgeDetect::CustomRegionComp(float r0, float c0, float r, float c)
-{
-   return 0;
-}
-
-void BgEdgeDetect::GenerateMaskAngle(double* a,double theta) {
-   static int sflag;
-   static int i,j,k;
-   static double cval[4];
-   static double corner[2][4];
-   static double sinv,cosv;
-   static double intrs[2][4];
-   static int scor[4],nscor[4];
-   static int sind,rowind,colind;
-   static double cordi[2][4];
-   static int lsigind,corin;
-   static int sigind[4];
-   static double diffin[2];
-   static double comcoor;
-
-   theta = theta*PI/180.0;
-   sinv = sin(theta);
-   cosv = cos(theta);
-   
-   for (i=0; i<WW_*WW_; i++)
-      a[i]=0;
-   
-   for (i=WL_; i>=-WL_; i--)
-   {
-      for(j=-WL_; j<=WL_; j++)
-      {
-         corner[0][0] = j-0.5;
-         corner[0][1] = j+0.5;
-         corner[0][2] = j+0.5;
-         corner[0][3] = j-0.5;
-         
-         corner[1][0] = i+0.5;
-         corner[1][1] = i+0.5;
-         corner[1][2] = i-0.5;
-         corner[1][3] = i-0.5;
-         
-         cval[0] = -sinv*corner[0][0]+cosv*corner[1][0];
-         cval[1] = -sinv*corner[0][1]+cosv*corner[1][1];
-         cval[2] = -sinv*corner[0][2]+cosv*corner[1][2];
-         cval[3] = -sinv*corner[0][3]+cosv*corner[1][3];
-         
-         scor[0] = my_sign(cval[0]);
-         scor[1] = my_sign(cval[1]);
-         scor[2] = my_sign(cval[2]);
-         scor[3] = my_sign(cval[3]);
-         
-         sind = 0;
-         if (scor[0]!=0)
-            nscor[sind++] = scor[0];
-         if (scor[1]!=0)
-            nscor[sind++] = scor[1];
-         if (scor[2]!=0)
-            nscor[sind++] = scor[2];
-         if (scor[3]!=0)
-            nscor[sind++] = scor[3];
-         
-         sflag = 0;
-         for (k=1;k<sind;k++)
-         {
-            if (nscor[k]!=nscor[0])
-               sflag++;
-         }
-         
-         rowind = i+WL_;
-         colind = j+WL_;
-         
-         if (sflag==0)
-         {
-            if (nscor[0]==1)
-               a[colind+rowind*WW_] = 1.0;
-            else
-               a[colind+rowind*WW_] = 0.0;
-         }
-         
-         if (sflag!=0)
-         {
-            for (k=0; k<4; k++)
-               intrs[0][k] = intrs[1][k] = 0.0;
-            
-            if(scor[0]==0)
-            {
-               intrs[0][0] = corner[0][0];
-               intrs[1][0] = corner[1][0];
-            }
-            if (scor[0]*scor[1]<0)
-            {
-               intrs[0][0] = corner[1][0]*cosv/sinv;
-               intrs[1][0] = corner[1][0];
-            }
-            if (scor[1]==0)
-            {
-               intrs[0][1] = corner[0][1];
-               intrs[1][1] = corner[1][1];
-            }
-            if (scor[1]*scor[2]<0)
-            {
-               intrs[0][1] = corner[0][1];
-               intrs[1][1] = corner[0][1]*sinv/cosv;
-            }
-            if (scor[2]==0)
-            {
-               intrs[0][2] = corner[0][2];
-               intrs[1][2] = corner[1][2];
-            }
-            if (scor[2]*scor[3]<0)
-            {
-               intrs[0][2] = corner[1][2]*cosv/sinv;
-               intrs[1][2] = corner[1][2];
-            }
-            if (scor[3]==0)
-            {
-               intrs[0][3] = corner[0][3];
-               intrs[1][3] = corner[1][3];
-            }
-            if (scor[3]*scor[0]<0)
-            {
-               intrs[0][3] = corner[0][3];
-               intrs[1][3] = corner[0][3]*sinv/cosv;
-            }
-            
-            corin = 0;
-            if (fabs(intrs[0][0])>TOL_E || fabs(intrs[1][0])>TOL_E)
-            {
-               cordi[0][corin] = intrs[0][0];
-               cordi[1][corin++] = intrs[1][0];
-            }
-            if (fabs(intrs[0][1])>TOL_E || fabs(intrs[1][1])>TOL_E)
-            {
-               cordi[0][corin] = intrs[0][1];
-               cordi[1][corin++] = intrs[1][1];
-            }
-            if (fabs(intrs[0][2])>TOL_E || fabs(intrs[1][2])>TOL_E)
-            {
-               cordi[0][corin] = intrs[0][2];
-               cordi[1][corin++] = intrs[1][2];
-            }
-            if (fabs(intrs[0][3])>TOL_E || fabs(intrs[1][3])>TOL_E)
-            {
-               cordi[0][corin] = intrs[0][3];
-               cordi[1][corin++] = intrs[1][3];
-            }
-            
-            lsigind=0;
-            if (scor[0]>0)
-               sigind[lsigind++] = 0;
-            if (scor[1]>0)
-               sigind[lsigind++] = 1;
-            if (scor[2]>0)
-               sigind[lsigind++] = 2;
-            if (scor[3]>0)
-               sigind[lsigind++] = 3;
-            
-            if (lsigind==1)
-            {
-               a[colind+rowind*WW_] = 0.5*fabs(cordi[0][0]-cordi[0][1])*fabs(cordi[1][0]-cordi[1][1]);
-            }
-            if (lsigind==2)
-            {
-               diffin[0] = (int) fabs(cordi[0][0]-cordi[0][1]);
-               diffin[1] = (int) fabs(cordi[1][0]-cordi[1][1]);
-               if (diffin[0]==1)
-               {
-                  comcoor = corner[1][sigind[0]];
-                  a[colind+rowind*WW_] = 0.5*(fabs(comcoor-cordi[1][0])+fabs(comcoor-cordi[1][1]));
-               }
-               if (diffin[1]==1)
-               {
-                  comcoor = corner[0][sigind[0]];
-                  a[colind+rowind*WW_] = 0.5*(fabs(comcoor-cordi[0][0])+fabs(comcoor-cordi[0][1]));
-               }
-            }
-            if(lsigind==3)
-            {
-               a[colind+rowind*WW_] = 1.0-0.5*fabs(cordi[0][0]-cordi[0][1])*fabs(cordi[1][0]-cordi[1][1]);
-            }
-         }
-      }
-   }
-   
-   //A=A-mean(mean(A));
-   comcoor = 0;
-   for (i=0; i<WW_*WW_; i++)
-      comcoor += a[i];
-   comcoor /= WW_*WW_;
-   for (i=0; i<WW_*WW_; i++)
-      a[i] -= comcoor;
-   
-   //A=A/norm(A,'fro')
-   comcoor = 0;
-   for (i=0; i<WW_*WW_; i++)
-      comcoor += a[i]*a[i];
-   comcoor = sqrt(comcoor);
-   for (i=0; i<WW_*WW_; i++)
-      a[i] /= comcoor;
-}
-
-void BgEdgeDetect::CreateFilters(void)
-{
-   int i,j;
-   double w;
-   for (i=-WL_; i<=WL_; i++)
-   {
-      w = pow(2,(-2*WL_))*factorial(2*WL_)/(factorial(WL_-i)*factorial(WL_+i));
-      smofil_[i+WL_] = w;
-      diffil_[i+WL_] = (2*i*w)/WL_;
-   }
-   for (j=0; j<WW_; j++)
-   {
-      for (i=0; i<WW_; i++)
-      {
-         wdy_[j+i*WW_] = wdx_[i+j*WW_] = smofil_[j]*diffil_[i];
-      }
-   }
-   
-   double norms = 0;
-   double normd = 0;
-   for (i=0; i<WW_; i++)
-   {
-      norms += smofil_[i]*smofil_[i];
-      normd += diffil_[i]*diffil_[i];
-   }
-   
-   for (j=0; j<WW_; j++)
-   {
-      for (i=0; i<WW_; i++)
-      {
-         mQ_[i][j] = (smofil_[j]*smofil_[i])/norms + (diffil_[j]*diffil_[i])/normd;
-         mN_[i][j] = (i==j) ? 1-mQ_[i][j] : -mQ_[i][j];
-      }
-   }
-}
-
-void BgEdgeDetect::CreateLookTable()
-{
-   bgLog("Creating angle lookup table\n");
-   int i;
-   for (i=-180; i<=180; i++)
-   {
-      lookTable_[i+180] = new double[WW_*WW_];
-      GenerateMaskAngle(lookTable_[i+180], (double) i);
-   }
-}
-
-void BgEdgeDetect::DeleteLookTable()
-{
-   int i;
-   for (i=0; i<NO_ANGLES; i++)
-   {
-      delete [] lookTable_[i];
-   }
-}
-
-void BgEdgeDetect::GetPixels(int* nopix, int* pixx, int* pixy, double x1, double x2, double y1, double y2)
-{
-   double minx,maxx,miny,maxy;
-   
-   if (x1<x2)
-   {
-      minx = x1;
-      maxx = x2;
-   }
-   else
-   {
-      minx = x2;
-      maxx = x1;
-   }
-   
-   if (y1<y2)
-   {
-      miny = y1;
-      maxy = y2;
-   }
-   else
-   {
-      miny = y2;
-      maxy = y1;
-   }
-   
-   int i,j,npix;
-   npix = 0;
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++)
-      {
-         if (permRank_[i+j*x_]<maxx && permRank_[i+j*x_]>minx &&
-             permConf_[i+j*x_]<maxy && permConf_[i+j*x_]>miny)
-         {
-            pixx[npix] = i;
-            pixy[npix++] = j;
-         }
-      }
-   }
-   *nopix = npix;
-}
-
-void BgEdgeDetect::GetNmxPixels(int* nopix, int* pixx, int* pixy, double x1, double x2, double y1, double y2)
-{
-   double minx,maxx,miny,maxy;
-   if (x1<x2)
-   {
-      minx = x1;
-      maxx = x2;
-   }
-   else
-   {
-      minx = x2;
-      maxx = x1;
-   }
-   
-   if (y1<y2)
-   {
-      miny = y1;
-      maxy = y2;
-   }
-   else
-   {
-      miny = y2;
-      maxy = y1;
-   }
-   
-   int i,j,npix;
-   npix = 0;
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++)
-      {
-         if (permNmxRank_[i+j*x_]<maxx && permNmxRank_[i+j*x_]>minx &&
-             permNmxConf_[i+j*x_]<maxy && permNmxConf_[i+j*x_]>miny)
-         {
-            pixx[npix] = i;
-            pixy[npix++] = j;
-         }
-      }
-   }
-   *nopix = npix;
-}
-
-void BgEdgeDetect::DoRecompute(BgEdgeList* cel, double nmxr, double nmxc,
-                               double rh, double ch, double rl, double cl,
-                               int nMin, int nmxType, int hystTypeHigh, int hystTypeLow)
-{
-   float *tr, *tc, *tdh, *tdl;
-   bgLog("Start edge detection...\n");
-   tr = new float[x_*y_];
-   tc = new float[x_*y_];
-   tdh = new float[x_*y_];
-   tdl = new float[x_*y_];
-   
-   //Nonmaximum supression
-   bgLog("...nonmaxima supression: ");
-
-   float (BgEdgeDetect::*fcomp)(float,float,float,float);
-   float (BgEdgeDetect::*feval)(float,float);
-   
-   switch(nmxType)
-   {
-   case FC_ELLIPSE:
-      fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc\n");
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line\n");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line\n");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box\n");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line\n");
-      break;
-  	default:
-      bgLog("Type not known\n");
-      return;
-   }
-   confTr_ = (float) nmxc;
-   rankTr_ = (float) nmxr;
-   
-   NewNonMaxSupress(permRank_,permConf_,permGx_,permGy_,permNmxRank_,permNmxConf_,fcomp);
-   bgLog("...hysteresis thresholding, high: ");
-   
-   switch(hystTypeHigh)
-   {
-   case FC_ELLIPSE:
-     	fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc");		
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line");  		
-      break;
-  	case FC_CUSTOM:
-      custx_ = hcustx_;
-      custy_ = hcusty_;
-      ncust_ = nhcust_;
-      fcomp = &BgEdgeDetect::CustomRegionComp;
-      feval = &BgEdgeDetect::CustomRegionEval;
-      bgLog("custom");
-      break;
-   }  
-   confTr_ = (float) ch;
-   rankTr_ = (float) rh;
-   StrConfEstim(permNmxRank_, permNmxConf_, tdh, feval);
-
-   bgLog("  low: ");
-   
-   switch(hystTypeLow) {
-   case FC_ELLIPSE:
-     	fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc\n");
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line\n");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line\n");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box\n");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line\n");  		
-      break;
-  	case FC_CUSTOM:
-      custx_ = lcustx_;
-      custy_ = lcusty_;
-      ncust_ = nlcust_;
-  	   fcomp = &BgEdgeDetect::CustomRegionComp;
-  	   feval = &BgEdgeDetect::CustomRegionEval;
-  	   bgLog("custom\n");
-  	   break;  		
-   } 
-   confTr_ = (float) cl;
-   rankTr_ = (float) rl;
-   StrConfEstim(permNmxRank_, permNmxConf_, tdl, feval);
-
-  //hysteresis thresholding
-
-   grx_ = permGx_;
-   gry_ = permGy_;
-   int minpt = nMin;
-   NewHysteresisTr(tdh, tdl, cel, minpt, tr, tc);
-   bgLog("Done edge detection.\n");
-   
-   delete [] tdl;
-   delete [] tdh;
-   delete [] tr;
-   delete [] tc;
-}
-
-void BgEdgeDetect::SaveNmxValues()
-{
-   FILE* fd;
-   int i,j;
-   
-   fd = fopen("ranknmx.dat", "w");
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++)
-      {
-         fprintf(fd, "%f ", *(permNmxRank_+j*x_+i));
-      }
-      fprintf(fd, "\n");
-   }
-   fclose(fd);
-   
-   fd=fopen("confnmx.dat", "w");
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++)
-      {
-         fprintf(fd, "%f ", *(permNmxConf_+j*x_+i));
-      }
-      fprintf(fd, "\n");
-   }
-   fclose(fd);
-}
-
-//Computes confedence map and rank
-//Pre : cim is an image
-//Post: confidence map and rank has been computed for cim
-//      and stored into confMap and rank respectively
-void BgEdgeDetect::ComputeEdgeInfo(BgImage* cim, float* confMap, float *rank)
-{
-   x_ = cim->x_;
-   y_ = cim->y_;
-   bgLog("Computing confidence map...\n");   
-   float *pGx, *pGy, *pTemp;
-   BgImage tcim(x_, y_);
-   if (cim->colorIm_==1)
-   {
-	   tcim.SetImageFromRGB(cim->im_, x_, y_, false);
-   } else
-   {
-	   tcim = *cim;
-   }
-
-   pGx = new float[x_*y_];
-   pGy = new float[x_*y_];   
-   pTemp = new float[x_*y_];
-   
-   // compute gradient images
-   bgLog("...smooth-differentiation filtering\n");
-   GaussDiffFilter(&tcim, pGx, pGy, pTemp);   
-
-   // compute confidences (subspace estimate)
-   bgLog("...subspace estimate\n");
-   SubspaceEstim(pTemp, pGx, pGy, confMap);
-
-   // compute edge strength from gradient image
-   bgLog("...edge strengths\n");
-   Strength(pGx, pGy, pTemp);
-   
-   // compute ranks of the strengths
-   bgLog("...computing ranks\n");
-   CompRanks(pTemp, rank);
- 
-   //de-allocate memory
-   delete [] pTemp;
-   delete [] pGy;
-   delete [] pGx;
-}
-/*
-void BgEdgeDetect::ComputeConfidenceMap1(BgImage* cim, float* confMap)
-{
-	ComputeConfidenceMap(cim, confMap);
-	BgEdgeList el;
-	DoEdgeDetect(cim, &el, RANK_NMX, CONF_NMX, RANK_H, CONF_H, RANK_L, CONF_L,
-		NMIN, FC_ELLIPSE, FC_SQUARE_BOX, FC_ELLIPSE);
-   BgImage tempImage(cim->x_, cim->y_);
-   el.SetBinImage(&tempImage);
-   int i;
-   for (i=0; i<(cim->x_*cim->y_); i++)
-	   if (tempImage.im_[i] == 0)
-		   confMap[i] = 0;
-}
-*/
-void BgEdgeDetect::DoEdgeDetect(BgImage* cim, BgEdgeList* cel, double nmxr, double nmxc,
-                                double rh, double ch, double rl, double cl,
-                                int nMin, int nmxType, int hystTypeHigh, int hystTypeLow)
-{
-   x_ = cim->x_;
-   y_ = cim->y_;
-   bgLog("Start edge detection...\n");   
-   permGx_ = new float[x_*y_];
-   permGy_ = new float[x_*y_];
-   permConf_ = new float[x_*y_];
-   permRank_ = new float[x_*y_];
-   permNmxRank_ = new float[x_*y_];
-   permNmxConf_ = new float[x_*y_];
-   havePerm_ = true;
-   float* tr;
-   float* tc;
-   float* tdh;
-   float* tdl;
-   
-   tr = new float[x_*y_];
-   tc = new float[x_*y_];
-   tdh = new float[x_*y_];
-   tdl = new float[x_*y_];
-   
-   // compute gradient images
-   bgLog("...smooth-differentiation filtering\n");
-   GaussDiffFilter(cim, permGx_, permGy_, tr);   
-
-   // compute confidences (subspace estimate)
-   bgLog("...subspace estimate\n");
-   SubspaceEstim(tr, permGx_, permGy_, permConf_);
-   
-   // compute edge strength from gradient image
-   bgLog("...edge strengths\n");
-   Strength(permGx_, permGy_, tr);
-   
-   // compute ranks of the strengths
-   bgLog("...computing ranks\n");
-   CompRanks(tr, permRank_);
-   
-   // new nonmaxima supression
-   bgLog("...nonmaxima supression: ");
-
-   // select appropriate function
-   float (BgEdgeDetect::*fcomp)(float,float,float,float);
-   float (BgEdgeDetect::*feval)(float,float);
-   switch(nmxType)
-   {
-   case FC_ELLIPSE:
-     	fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc\n");
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line\n");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line\n");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box\n");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line\n");
-      break;
-  	default:
-      bgLog("Type not known\n");
-      return;
-   }
-
-   confTr_ = (float) nmxc;
-   rankTr_ = (float) nmxr;
-   NewNonMaxSupress(permRank_, permConf_, permGx_, permGy_, permNmxRank_, permNmxConf_, fcomp);
-
-   // new hysteresis thresholding
-   bgLog("...hysteresis thresholding, high: ");
-
-   // select function, high curve
-   switch(hystTypeHigh)
-   {
-   case FC_ELLIPSE:
-     	fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc");		
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line");  		
-      break;
-  	case FC_CUSTOM:
-      custx_ = hcustx_;
-      custy_ = hcusty_;
-      ncust_ = nhcust_;
-      fcomp = &BgEdgeDetect::CustomRegionComp;
-      feval = &BgEdgeDetect::CustomRegionEval;
-      bgLog("custom");
-      break;
-   }  
-
-   confTr_ = (float) ch;
-   rankTr_ = (float) rh;
-   StrConfEstim(permNmxRank_, permNmxConf_, tdh, feval);
-
-   bgLog("  low: ");
-
-   // select function, low curve
-   switch(hystTypeLow)
-   {
-   case FC_ELLIPSE:
-     	fcomp = &BgEdgeDetect::EllipseComp;
-      feval = &BgEdgeDetect::EllipseEval;
-      bgLog("arc\n");
-      break;
-   case FC_VERT_LINE:
-      fcomp = &BgEdgeDetect::VerticalLineComp;
-      feval = &BgEdgeDetect::VerticalLineEval;
-      bgLog("vertical line\n");		
-      break;
-   case FC_HORIZ_LINE:
-      fcomp = &BgEdgeDetect::HorizontalLineComp;
-      feval = &BgEdgeDetect::HorizontalLineEval;
-      bgLog("horizontal line\n");		
-      break;
-   case FC_SQUARE_BOX:
-      fcomp = &BgEdgeDetect::SquareComp;
-      feval = &BgEdgeDetect::SquareEval;
-      bgLog("box\n");		
-      break;
-   case FC_LINE:
-      fcomp = &BgEdgeDetect::LineComp;
-      feval = &BgEdgeDetect::LineEval;		
-      bgLog("line\n");  		
-      break;
-  	case FC_CUSTOM:
-      custx_ = lcustx_;
-      custy_ = lcusty_;
-      ncust_ = nlcust_;
-  	   fcomp = &BgEdgeDetect::CustomRegionComp;
-  	   feval = &BgEdgeDetect::CustomRegionEval;
-  	   bgLog("custom\n");
-  	   break;  		
-   } 
-   confTr_ = (float) cl;
-   rankTr_ = (float) rl;
-
-   StrConfEstim(permNmxRank_, permNmxConf_, tdl, feval);
-
-   grx_ = permGx_;
-   gry_ = permGy_;
-   
-   NewHysteresisTr(tdh, tdl, cel, nMin, tr, tc);
-
-   bgLog("Done edge detection.\n");
-
-   delete [] tdl;
-   delete [] tdh;
-   delete [] tr;
-   delete [] tc;
-}
-
-void BgEdgeDetect::SubspaceEstim(float* im, float* grx, float* gry, float* cee)
-{
-   // im original image
-   // grx, gry gradient of image
-   // cee confidence edge estimate
-   
-   float* itim;
-   float* itgx;
-   float* itgy;
-   float* itcee;
-   itim = im;
-   itgx = grx;
-   itgy = gry;
-   itcee = cee;
-
-   double* tae;
-   double* ti;
-
-   ti = new double[WW_*WW_];
-
-   int i,j,l,c;
-   double v1;
-   double angleEdge;
-   int WW2 = WW_*WW_;
-   
-   itim += WL_*x_;
-   itgx += WL_*x_;
-   itgy += WL_*x_;
-   itcee += WL_*x_;
-
-   for (j=WL_; j<(y_-WL_); j++)
-   {
-      for (i=0; i<WL_; i++)
-         itcee[i] = 0;
-      itim += WL_;
-      itgx += WL_;
-      itgy += WL_;
-      itcee += WL_;
-
-
-      for (i=WL_; i<(x_-WL_); i++, itim++, itgx++, itgy++, itcee++)
-      {
-         if ((fabs(*itgx)+fabs(*itgy))>TOL_E)
-         {
-            angleEdge = (-atan2(*itgx, *itgy))*180.0/PI;
-            tae = lookTable_[(int) (angleEdge+180.49)];
-            
-            //A=A-mean(A)
-            v1=0;
-            for (l=0; l<WW_; l++)
-            {
-               for (c=0; c<WW_; c++)
-               {
-                  v1 += ti[l*WW_+c] = *(itim+(l-WL_)*x_+c-WL_);
-               }
-            }
-            v1 /= WW2;
-            for (l=0; l<WW2; l++)
-               ti[l] -= v1;
-            
-            //A/norm(A,'fro')
-            v1 = 0;
-            for (l=0; l<WW2; l++)
-               v1 += ti[l]*ti[l];
-            v1 = sqrt(v1);
-            for (l=0; l<WW2; l++)
-               ti[l] /= v1;
-
-            //global
-            v1 = 0;
-            for (l=0; l<WW2; l++)
-               v1 += tae[l]*ti[l];
-            v1 = fabs(v1);
-            *itcee = (float) v1;
-         }
-         else
-         {
-            *itcee = 0;
-         }
-      }
-      for (i=0; i<WL_; i++)
-         itcee[i] = 0;
-      itim += WL_;
-      itgx += WL_;
-      itgy += WL_;
-      itcee += WL_;
-   }
-   WW2 = x_*y_;
-   for (j=0; j<(WL_*x_); j++)
-   {
-      cee[j] = 0;
-      cee[WW2-j-1] = 0;
-   }   
-
-   
-   delete [] ti;
-}
-
-void BgEdgeDetect::GaussFilter(BgImage* cim, float* fim, double sigma, int width)
-{
-   double* filter;
-   unsigned char* im;
-   double* tim;
-   double sum = 0;
-   double sum1 = 0;
-   int i,ii,jj,j,k;
-
-   im = cim->im_;
-   if (width==-2)
-   {
-      for (i=0; i<x_*y_;i++)
-         fim[i] = im[i];
-      return;
-   }
-
-   if (width<3)
-      width = (int) (1+2*ceil(2.5*sigma));
-   int tail = width/2;
-   width = 2*tail+1;
-
-   //create kernel
-   filter = new double[width];
-   for (i=-tail; i<=tail; i++)
-      sum += filter[i+tail] = exp(-i*i/(2*sigma*sigma));
-   for (i=0; i<width; i++)
-      filter[i] /= sum;
-
-   //filter image
-   im = cim->im_;
-   tim = new double[x_*y_];
-   for (j=0; j<y_; j++)
-   {
-      for (i=tail; i<(x_-tail); i++)
-      {
-         sum=0;
-         for (k=-tail; k<=tail; k++)
-            sum += im[j*x_+i+k]*filter[k+tail];
-         tim[j*x_+i] = sum;
-      }
-      
-      for (i=0; i<tail; i++)
-      {
-         tim[j*x_+i] = 0;
-         tim[j*x_+x_-i-1] = 0;
-         for (k=-tail; k<=tail; k++)
-         {
-            ii = (k+i)>=0 ? k+i : 0;
-            tim[j*x_+i] += im[j*x_+ii]*filter[k+tail];
-            ii = (x_-i-1+k)<x_ ? x_-i-1+k : x_-1;
-            tim[j*x_+x_-i-1] += im[j*x_+ii]*filter[k+tail];
-         }
-      }
-   }
-
-   for (i=0; i<x_; i++)
-   {
-      for (j=tail; j<(y_-tail); j++)
-      {
-         sum=0;
-         for (k=-tail; k<=tail; k++)
-            sum += tim[(j+k)*x_+i]*filter[k+tail];
-         fim[j*x_+i] = (float) (sum);
-      }
-      for (j=0; j<tail; j++)
-      {
-         sum = 0;
-         sum1 = 0;
-         for (k=-tail; k<=tail; k++)
-         {
-            jj = (k+j)>=0 ? k+j : 0;
-            sum += tim[jj*x_+i]*filter[k+tail];
-            jj = (y_-j-1+k)<y_ ? y_-j-1+k : y_-1;
-            sum1 += tim[jj*x_+i]*filter[k+tail];
-         }
-         fim[j*x_+i] = (float) (sum);
-         fim[(y_-j-1)*x_+i] = (float) (sum1);
-      }
-   }
-   delete [] filter;
-   delete [] tim;
-}
-
-void BgEdgeDetect::GaussDiffFilter(BgImage* cim, float* grx, float* gry, float* rezIm)
-{
-   
-   double* sf; //smooth filter
-   double* df; //diff filter
-   unsigned char* im;
-   
-   double* tim;
-   double sum = 0;
-   double sum1 = 0;
-   int i, j, k;
-   
-   //create kernels
-   sf = smofil_;
-   df = diffil_;
-   
-   im = cim->im_;
-   tim = new double[x_*y_];
-   for (i=0; i<x_*y_; i++)
-   {
-      grx[i] = gry[i] = 0;
-      tim[i] = 0;
-      rezIm[i] = im[i];
-   }
-   
-   //filter image x
-   //smooth on y
-   for (i=0; i<x_; i++)
-   {
-      for (j=WL_; j<(y_-WL_); j++)
-      {
-         sum = 0;
-         for (k=-WL_; k<=WL_; k++)
-            sum += im[(j+k)*x_+i]*sf[k+WL_];
-         tim[j*x_+i] = sum;
-      }
-   }
-   //diff on x
-   for (j=0; j<y_; j++)
-   {
-      for (i=WL_; i<(x_-WL_); i++)
-      {
-         sum = 0;
-         for (k=-WL_; k<=WL_; k++)
-            sum += tim[j*x_+i+k]*df[k+WL_];
-         grx[j*x_+i] = (float) (sum);
-      }
-   }
-
-   //filter image y
-   for (i=0; i<x_*y_;i++)
-      tim[i] = 0;
-   im = cim->im_;
-   //smooth on x
-   for (j=0; j<y_; j++)
-   {
-      for (i=WL_; i<(x_-WL_); i++)
-      {
-         sum = 0;
-         for (k=-WL_; k<=WL_; k++)
-            sum += im[j*x_+i+k]*sf[k+WL_];
-         tim[j*x_+i] = sum;
-      }
-   }
-   //diff on y
-   for (i=0; i<x_; i++)
-   {
-      for (j=WL_; j<(y_-WL_); j++)
-      {
-         sum = 0;
-         for (k=-WL_; k<=WL_; k++)
-            sum += tim[(j+k)*x_+i]*df[k+WL_];
-         gry[j*x_+i] = (float) (sum);
-      }
-   }
-   delete [] tim;
-}
-
-void BgEdgeDetect::CompRanks(float* strength, float* ranks)
-{
-   int* index;
-   float* ra;
-   ra = new float[x_*y_];
-   index = new int[x_*y_];
-   int ii;
-   
-   for (ii=0; ii<x_*y_; ii++)
-   {
-      index[ii] = ii;
-      ranks[ii] = 0;
-      ra[ii] = strength[ii];
-   }
-
-   //heap sort with ranks (from numerical recipies)
-   unsigned long i, ir, j, l;
-   unsigned long n;
-   n = x_*y_;
-   float rra;
-   int irra;
-
-   if (n<2)
-      return;
-   l = (n>>1)+1;
-   ir = n;
-   for (;;)
-   {
-      if (l>1)
-      {
-         rra = ra[--l-1];
-         irra = index[l-1];
-      }
-      else
-      {
-         rra = ra[ir-1];
-         irra = index[ir-1];
-         ra[ir-1] = ra[1-1];
-         index[ir-1] = index[1-1];
-         if (--ir==1)
-         {
-            ra[1-1] = rra;
-            index[1-1] = irra;
-            break;
-         }
-      }
-      i = l;
-      j = l+l;
-      while (j<=ir)
-      {
-         if (j<ir && ra[j-1]<ra[j+1-1])
-            j++;
-         if (rra<ra[j-1])
-         {
-            ra[i-1] = ra[j-1];
-            index[i-1] = index[j-1];
-            i = j;
-            j <<= 1;
-         }
-         else
-            j = ir+1;
-      }
-      ra[i-1] = rra;
-      index[i-1] = irra;
-   }
-   
-   //setranks
-   irra = 1;
-   for (ii=1; ii<x_*y_; ii++)
-   {
-      if (ra[ii]>ZERO_TRESH)
-      {
-         ranks[index[ii]] = (float) irra;
-         if (ra[ii]>ra[ii-1])
-            irra++;
-      }
-   }
-   irra--;
-   for (ii=0; ii<x_*y_; ii++) 
-      ranks[ii] /= irra;
-
-  delete [] index;
-  delete [] ra;
-}
-
-void BgEdgeDetect::StrConfEstim(float* ranks, float* confidence, float* rezult,
-                                float (BgEdgeDetect::*feval)(float,float))
-{
-   int i;
-   for (i=0; i<x_*y_; i++)
-   {
-      rezult[i] = (this->*feval)(ranks[i], confidence[i]);
-   }
-}
-
-void BgEdgeDetect::Strength(float* grx, float* gry, float* strength)
-{
-   int i,j;
-   float* itgx;
-   float* itgy;
-   float* its;
-   double val;
-   itgx = grx;
-   itgy = gry;
-   its = strength;
-   for (j=0; j<y_; j++)
-      for(i=0; i<x_; i++)
-      {
-         val = sqrt(((double) (*itgx*(*(itgx++))))+((double) (*itgy*(*(itgy++)))));
-         *(its++)=(float) (val);
-      }
-}
-
-void BgEdgeDetect::NewNonMaxSupress(float* rank, float* conf, float* grx, float* gry, float* nmxRank, float* nmxConf,
-                                    float (BgEdgeDetect::*feval)(float, float, float, float))
-{
-   int i,j;
-   float* itr;
-   float* itc;
-   float* itgx;
-   float* itgy;
-   float* itnmxr;
-   float* itnmxc;
-   float alpha,r1,c1,r2,c2,lambda;
-   itr = rank;
-   itc = conf;
-   itgx = grx;
-   itgy = gry;
-   itnmxr = nmxRank;
-   itnmxc = nmxConf;
-   
-   for (i=0; i<x_*y_; i++)
-   {
-      itnmxr[i] = itnmxc[i] = 0;
-   }
-   for(i=0; i<x_; i++)
-   {
-      itr[i] = itc[i] = 0;
-      itr[(y_-1)*x_+i] = itc[(y_-1)*x_+i] = 0;
-   }
-   for(j=0; j<y_; j++)
-   {
-      itr[j*x_] = itc[j*x_] = 0;
-      itr[j*x_+x_-1] = itc[j*x_+x_-1] = 0;
-   }
-
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++, itr++, itc++, itgx++, itgy++, itnmxr++, itnmxc++)
-      {
-         if (*itr>0 && *itc>0)
-         {
-            alpha = (float) atan2(*itgy, *itgx);
-            alpha = (alpha<0) ? alpha+(float)PI : alpha;
-            if (alpha<=PI/4)
-            {
-               lambda = (float) tan(alpha);
-               r1 = (1-lambda)*(*(itr+1))+lambda*(*(itr+x_+1));
-               c1 = (1-lambda)*(*(itc+1))+lambda*(*(itc+x_+1));
-               r2 = (1-lambda)*(*(itr-1))+lambda*(*(itr-x_-1));
-               c2 = (1-lambda)*(*(itc-1))+lambda*(*(itc-x_-1));
-               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
-               {
-                  *itnmxr = *itr;
-                  *itnmxc = *itc;
-               }
-            }
-            else if (alpha<=PI/2)
-            {
-               lambda = (float) tan(PI/2-alpha);
-               r1 = (1-lambda)*(*(itr+x_))+lambda*(*(itr+x_+1));
-               c1 = (1-lambda)*(*(itc+x_))+lambda*(*(itc+x_+1));
-               r2 = (1-lambda)*(*(itr-x_))+lambda*(*(itr-x_-1));
-               c2 = (1-lambda)*(*(itc-x_))+lambda*(*(itc-x_-1));
-               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
-               {
-                  *itnmxr = *itr;
-                  *itnmxc = *itc;
-               }
-               
-            }
-            else if(alpha<=3*PI/4)
-            {
-               lambda = (float) tan(alpha-PI/2);
-               r1 = (1-lambda)*(*(itr+x_))+lambda*(*(itr+x_-1));
-               c1 = (1-lambda)*(*(itc+x_))+lambda*(*(itc+x_-1));
-               r2 = (1-lambda)*(*(itr-x_))+lambda*(*(itr-x_+1));
-               c2 = (1-lambda)*(*(itc-x_))+lambda*(*(itc-x_+1));
-               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
-               {
-                  *itnmxr = *itr;
-                  *itnmxc = *itc;
-               }
-            }
-            else
-            {
-               lambda = (float) tan(PI-alpha);
-               r1 = (1-lambda)*(*(itr-1))+lambda*(*(itr+x_-1));
-               c1 = (1-lambda)*(*(itc-1))+lambda*(*(itc+x_-1));
-               r2 = (1-lambda)*(*(itr+1))+lambda*(*(itr-x_+1));
-               c2 = (1-lambda)*(*(itc+1))+lambda*(*(itc-x_+1));
-               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
-               {
-                  *itnmxr = *itr;
-                  *itnmxc = *itc;
-               }
-            }
-         }
-      }
-   }
-}
-
-void BgEdgeDetect::NewHysteresisTr(float* edge, float* low, BgEdgeList* cel, int nMin, float* mark, float* coord)
-{
-   float* tm;
-   float* te;
-   float* tl;
-   int i,j,n;
-   
-   n=0;
-   for (i=0, tm=mark; i<x_*y_; i++,tm++)
-      *tm=0;
-   
-   te_ = te = edge;
-   tm_ = tm = mark;
-   tl_ = tl = low;
-   
-   for (j=0; j<y_; j++)
-   {
-      for (i=0; i<x_; i++, tm++, te++)
-      {
-         if ((*tm==0) && ((*te)>HYST_LOW_CUT))
-         {
-            //found an edge start
-            npt_ = 0;
-            *tm = 1;
-            tc_ = coord;
-            NewEdgeFollow(i, j);
-            //store the edge
-            if (npt_>=nMin) cel->AddEdge(coord, npt_);
-         }
-      }
-   }
-}
-
-void BgEdgeDetect::NewEdgeFollow(int ii,int jj)
-{
-   int i;
-   int iin, jjn;
-   for (i=0; i<8; i++)
-   {
-      iin = ii+gNb[i][0];
-      jjn = jj+gNb[i][1];
-      if ((tm_[jjn*x_+iin]==0) && ((tl_[jjn*x_+iin])>0))
-      {
-         tm_[jjn*x_+iin] = 1;
-         NewEdgeFollow(iin, jjn);
-      }
-   }
-   *(tc_++) = (float) ii;
-   *(tc_++) = (float) jj;
-   npt_++;
-}
-
-void BgEdgeDetect::SetCustomHigh(int* x, int* y, int n, int sx, int sy)
-{
-   if (nhcust_>0)
-   {
-      delete [] hcustx_;
-      delete [] hcusty_;
-   }
-   nhcust_ = 0;
-   hcustx_ = hcusty_ = 0;   
-   nhcust_ = n+2;
-   hcustx_ = new float[nhcust_];
-   hcusty_ = new float[nhcust_];
-   
-   int idx,i;
-   idx = 0;
-   hcustx_[idx] = 0;
-   hcusty_[idx++] = 0;
-   for (i=0; i<n; i++)
-   {
-      hcustx_[idx] = ((float) x[i])/sx;
-      hcusty_[idx++] = (float)(1.0-((float) y[i])/sy);
-   }   
-   hcustx_[idx] = 0;
-   hcusty_[idx++] = 0;
-   
-   bgLog(" hyst high custom x: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", hcustx_[i]);
-   bgLog("\n");
-   bgLog(" hist high custom y: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", hcusty_[i]);
-   bgLog("\n");   
-}
-
-void BgEdgeDetect::SetCustomHigh(double* x, double* y, int n)
-{
-   if (nhcust_>0)
-   {
-      delete [] hcustx_;
-      delete [] hcusty_;
-   }
-   nhcust_ = 0;
-   hcustx_ = hcusty_ = 0;
-   nhcust_ = n+2;
-   hcustx_ = new float[nhcust_];
-   hcusty_ = new float[nhcust_];
-   
-   int idx,i;
-   idx = 0;
-   hcustx_[idx] = 0;
-   hcusty_[idx++] = 0;
-   for (i=0; i<n; i++)
-   {
-      hcustx_[idx] = (float) x[i];
-      hcusty_[idx++] = (float) y[i];
-   }   
-   hcustx_[idx] = 0;
-   hcusty_[idx++] = 0;
-   
-   bgLog(" hyst high custom x: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", hcustx_[i]);
-   bgLog("\n");
-   bgLog(" hist high custom y: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", hcusty_[i]);
-   bgLog("\n");   
-}
-
-void BgEdgeDetect::SetCustomLow(int* x, int* y, int n, int sx, int sy)
-{
-   if(nlcust_>0)
-   {
-      delete [] lcustx_;
-      delete [] lcusty_;
-   }
-   nlcust_ = 0;
-   lcustx_ = lcusty_ = 0;   
-   nlcust_ = n+2;
-   lcustx_ = new float[nlcust_];
-   lcusty_ = new float[nlcust_];
-   
-   int idx,i;
-   idx = 0;
-   lcustx_[idx] = 0;
-   lcusty_[idx++] = 0;
-   for (i=0; i<n; i++)
-   {
-      lcustx_[idx] = ((float) x[i])/sx;
-      lcusty_[idx++] = (float)(1.0-((float) y[i])/sy);
-   }   
-   lcustx_[idx] = 0;
-   lcusty_[idx++] = 0;
-   bgLog(" hyst low custom x: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", lcustx_[i]);
-   bgLog("\n");
-   bgLog(" low custom y: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", lcusty_[i]);
-   bgLog("\n");   
-}
-
-void BgEdgeDetect::SetCustomLow(double* x, double* y, int n)
-{
-   if(nlcust_>0)
-   {
-      delete [] lcustx_;
-      delete [] lcusty_;
-   }
-   nlcust_ = 0;
-   lcustx_ = lcusty_ = 0;   
-   nlcust_ = n+2;
-   lcustx_ = new float[nlcust_];
-   lcusty_ = new float[nlcust_];
-   
-   int idx,i;
-   idx = 0;
-   lcustx_[idx] = 0;
-   lcusty_[idx++] = 0;
-   for (i=0; i<n; i++)
-   {
-      lcustx_[idx] = (float) x[i];
-      lcusty_[idx++] = (float) y[i];
-   }   
-   lcustx_[idx] = 0;
-   lcusty_[idx++] = 0;
-   bgLog(" hyst low custom x: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", lcustx_[i]);
-   bgLog("\n");
-   bgLog(" low custom y: ");
-   for (i=0; i<=n; i++)
-      bgLog(" %f", lcusty_[i]);
-   bgLog("\n");   
-}
+/////////////////////////////////////////////////////////////////////////////
+// Name:        BgEdgeDetect.cpp
+// Purpose:     BgEdgeDetect class functions
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+#include <math.h>
+#include "BgImage.h"
+#include "BgEdge.h"
+#include "BgEdgeList.h"
+#include "BgEdgeDetect.h"
+#include "BgDefaults.h"
+#include <stdio.h>
+
+#define TOL_E 2.2e-8
+//#define TOL_E 0.05
+#define SIGN(x) (x<0)? -1:1;
+
+static int my_sign(double val)
+{
+   if(val>TOL_E)
+      return 1;
+   if(val<-TOL_E)
+      return -1;
+   return 0;
+}
+
+extern double factorial(double);
+
+BgEdgeDetect::BgEdgeDetect(int filtDim)
+{
+   havePerm_ = false;
+   WL_ = filtDim;
+   WW_ = 2*WL_+1;
+   nhcust_ = 0;
+   nlcust_ = 0;
+   tcustx_ = new float[MAX_CUSTT];
+   tcusty_ = new float[MAX_CUSTT];
+   CreateFilters();
+   CreateLookTable();
+}
+
+BgEdgeDetect::~BgEdgeDetect()
+{
+   if (havePerm_==true)
+   {
+      delete [] permGx_;
+      delete [] permGy_;
+      delete [] permConf_;
+      delete [] permRank_;
+      delete [] permNmxRank_;
+      delete [] permNmxConf_;
+   }
+   if (nhcust_>0)
+   {
+      delete [] hcustx_;
+      delete [] hcusty_;
+   }
+   if (nlcust_>0)
+   {
+      delete [] lcustx_;
+      delete [] lcusty_;
+   }
+   delete [] tcustx_;
+   delete [] tcusty_;
+   DeleteLookTable();
+}
+
+void BgEdgeDetect::IsGood(void)
+{
+   if (havePerm_==true)
+      bgLog("good\n");
+   else
+      bgLog("bad\n");
+}
+
+
+float BgEdgeDetect::EllipseEval(float x, float y)
+{
+   return ((x*x)/(rankTr_*rankTr_)+(y*y)/(confTr_*confTr_)-1);
+}
+
+float BgEdgeDetect::EllipseComp(float x0, float y0, float x, float y)
+{
+//   return (EllipseEval(x,y)-EllipseEval(x0,y0));
+   return ((x*x-x0*x0)/(rankTr_*rankTr_)+(y*y-y0*y0)/(confTr_*confTr_));
+}
+
+float BgEdgeDetect::LineEval(float x, float y)
+{
+   return (confTr_*x+rankTr_*y-confTr_*rankTr_);
+}
+
+float BgEdgeDetect::LineComp(float x0, float y0, float x, float y)
+{
+//   return (LineEval(x,y)-LineEval(x0,y0));
+   return (confTr_*(x-x0)+rankTr_*(y-y0));
+}
+
+float BgEdgeDetect::VerticalLineEval(float x, float y)
+{
+   return (x-rankTr_);
+}
+
+float BgEdgeDetect::VerticalLineComp(float x0, float y0, float x, float y)
+{
+//   return (VerticalLineEval(x,y)-VerticalLineEval(x0,y0));
+   return (x-x0);
+
+}
+
+float BgEdgeDetect::HorizontalLineEval(float x, float y)
+{
+   return(y-confTr_);
+}
+
+float BgEdgeDetect::HorizontalLineComp(float x0, float y0, float x, float y)
+{
+//   return (HorizontalLineEval(x,y)-HorizontalLineEval(x0,y0));
+   return (y-y0);
+}
+
+float BgEdgeDetect::SquareEval(float x, float y)
+{
+   if ((x/rankTr_)>(y/confTr_))
+      return(x-rankTr_);
+   else
+      return(y-confTr_);
+}
+
+float BgEdgeDetect::SquareComp(float x0, float y0, float x, float y)
+{
+//   return(SquareEval(x,y)-SquareEval(x0,y0));
+   static float tret;
+   tret = ((x/rankTr_)>(y/confTr_)) ? x-rankTr_ : y-confTr_;
+   tret -= ((x0/rankTr_)>(y0/confTr_)) ? x0-rankTr_ : y0-confTr_;
+   return tret;
+}
+
+float BgEdgeDetect::CustomRegionEval(float r,float c)
+{
+   //evaluate user region function
+   //returns -1 if inside +1 if outside
+   
+   if ((r+c)<=ZERO_TRESH)
+      return -1;
+   int i;
+   int crossings=0;
+   float x;
+   
+   //shift to origin
+   for (i=0; i<ncust_; i++)
+   {
+      tcustx_[i]=custx_[i]-r;
+      tcusty_[i]=custy_[i]-c;
+   }
+   
+   for (i=0; i<(ncust_-1); i++)
+   {
+      if ( (tcusty_[i]  >0 && tcusty_[i+1]<=0) ||
+           (tcusty_[i+1]>0 && tcusty_[i]  <=0) )
+      {
+         x = (tcustx_[i]*tcusty_[i+1]-tcustx_[i+1]*tcusty_[i])/(tcusty_[i+1]-tcusty_[i]);
+         if (x>0)
+            crossings++;
+      }	   
+   }		
+   
+   if ((crossings % 2) ==1)
+      return -1;
+   else
+      return 1;
+}
+
+float BgEdgeDetect::CustomRegionComp(float r0, float c0, float r, float c)
+{
+   return 0;
+}
+
+void BgEdgeDetect::GenerateMaskAngle(double* a,double theta) {
+   static int sflag;
+   static int i,j,k;
+   static double cval[4];
+   static double corner[2][4];
+   static double sinv,cosv;
+   static double intrs[2][4];
+   static int scor[4],nscor[4];
+   static int sind,rowind,colind;
+   static double cordi[2][4];
+   static int lsigind,corin;
+   static int sigind[4];
+   static double diffin[2];
+   static double comcoor;
+
+   theta = theta*PI/180.0;
+   sinv = sin(theta);
+   cosv = cos(theta);
+   
+   for (i=0; i<WW_*WW_; i++)
+      a[i]=0;
+   
+   for (i=WL_; i>=-WL_; i--)
+   {
+      for(j=-WL_; j<=WL_; j++)
+      {
+         corner[0][0] = j-0.5;
+         corner[0][1] = j+0.5;
+         corner[0][2] = j+0.5;
+         corner[0][3] = j-0.5;
+         
+         corner[1][0] = i+0.5;
+         corner[1][1] = i+0.5;
+         corner[1][2] = i-0.5;
+         corner[1][3] = i-0.5;
+         
+         cval[0] = -sinv*corner[0][0]+cosv*corner[1][0];
+         cval[1] = -sinv*corner[0][1]+cosv*corner[1][1];
+         cval[2] = -sinv*corner[0][2]+cosv*corner[1][2];
+         cval[3] = -sinv*corner[0][3]+cosv*corner[1][3];
+         
+         scor[0] = my_sign(cval[0]);
+         scor[1] = my_sign(cval[1]);
+         scor[2] = my_sign(cval[2]);
+         scor[3] = my_sign(cval[3]);
+         
+         sind = 0;
+         if (scor[0]!=0)
+            nscor[sind++] = scor[0];
+         if (scor[1]!=0)
+            nscor[sind++] = scor[1];
+         if (scor[2]!=0)
+            nscor[sind++] = scor[2];
+         if (scor[3]!=0)
+            nscor[sind++] = scor[3];
+         
+         sflag = 0;
+         for (k=1;k<sind;k++)
+         {
+            if (nscor[k]!=nscor[0])
+               sflag++;
+         }
+         
+         rowind = i+WL_;
+         colind = j+WL_;
+         
+         if (sflag==0)
+         {
+            if (nscor[0]==1)
+               a[colind+rowind*WW_] = 1.0;
+            else
+               a[colind+rowind*WW_] = 0.0;
+         }
+         
+         if (sflag!=0)
+         {
+            for (k=0; k<4; k++)
+               intrs[0][k] = intrs[1][k] = 0.0;
+            
+            if(scor[0]==0)
+            {
+               intrs[0][0] = corner[0][0];
+               intrs[1][0] = corner[1][0];
+            }
+            if (scor[0]*scor[1]<0)
+            {
+               intrs[0][0] = corner[1][0]*cosv/sinv;
+               intrs[1][0] = corner[1][0];
+            }
+            if (scor[1]==0)
+            {
+               intrs[0][1] = corner[0][1];
+               intrs[1][1] = corner[1][1];
+            }
+            if (scor[1]*scor[2]<0)
+            {
+               intrs[0][1] = corner[0][1];
+               intrs[1][1] = corner[0][1]*sinv/cosv;
+            }
+            if (scor[2]==0)
+            {
+               intrs[0][2] = corner[0][2];
+               intrs[1][2] = corner[1][2];
+            }
+            if (scor[2]*scor[3]<0)
+            {
+               intrs[0][2] = corner[1][2]*cosv/sinv;
+               intrs[1][2] = corner[1][2];
+            }
+            if (scor[3]==0)
+            {
+               intrs[0][3] = corner[0][3];
+               intrs[1][3] = corner[1][3];
+            }
+            if (scor[3]*scor[0]<0)
+            {
+               intrs[0][3] = corner[0][3];
+               intrs[1][3] = corner[0][3]*sinv/cosv;
+            }
+            
+            corin = 0;
+            if (fabs(intrs[0][0])>TOL_E || fabs(intrs[1][0])>TOL_E)
+            {
+               cordi[0][corin] = intrs[0][0];
+               cordi[1][corin++] = intrs[1][0];
+            }
+            if (fabs(intrs[0][1])>TOL_E || fabs(intrs[1][1])>TOL_E)
+            {
+               cordi[0][corin] = intrs[0][1];
+               cordi[1][corin++] = intrs[1][1];
+            }
+            if (fabs(intrs[0][2])>TOL_E || fabs(intrs[1][2])>TOL_E)
+            {
+               cordi[0][corin] = intrs[0][2];
+               cordi[1][corin++] = intrs[1][2];
+            }
+            if (fabs(intrs[0][3])>TOL_E || fabs(intrs[1][3])>TOL_E)
+            {
+               cordi[0][corin] = intrs[0][3];
+               cordi[1][corin++] = intrs[1][3];
+            }
+            
+            lsigind=0;
+            if (scor[0]>0)
+               sigind[lsigind++] = 0;
+            if (scor[1]>0)
+               sigind[lsigind++] = 1;
+            if (scor[2]>0)
+               sigind[lsigind++] = 2;
+            if (scor[3]>0)
+               sigind[lsigind++] = 3;
+            
+            if (lsigind==1)
+            {
+               a[colind+rowind*WW_] = 0.5*fabs(cordi[0][0]-cordi[0][1])*fabs(cordi[1][0]-cordi[1][1]);
+            }
+            if (lsigind==2)
+            {
+               diffin[0] = (int) fabs(cordi[0][0]-cordi[0][1]);
+               diffin[1] = (int) fabs(cordi[1][0]-cordi[1][1]);
+               if (diffin[0]==1)
+               {
+                  comcoor = corner[1][sigind[0]];
+                  a[colind+rowind*WW_] = 0.5*(fabs(comcoor-cordi[1][0])+fabs(comcoor-cordi[1][1]));
+               }
+               if (diffin[1]==1)
+               {
+                  comcoor = corner[0][sigind[0]];
+                  a[colind+rowind*WW_] = 0.5*(fabs(comcoor-cordi[0][0])+fabs(comcoor-cordi[0][1]));
+               }
+            }
+            if(lsigind==3)
+            {
+               a[colind+rowind*WW_] = 1.0-0.5*fabs(cordi[0][0]-cordi[0][1])*fabs(cordi[1][0]-cordi[1][1]);
+            }
+         }
+      }
+   }
+   
+   //A=A-mean(mean(A));
+   comcoor = 0;
+   for (i=0; i<WW_*WW_; i++)
+      comcoor += a[i];
+   comcoor /= WW_*WW_;
+   for (i=0; i<WW_*WW_; i++)
+      a[i] -= comcoor;
+   
+   //A=A/norm(A,'fro')
+   comcoor = 0;
+   for (i=0; i<WW_*WW_; i++)
+      comcoor += a[i]*a[i];
+   comcoor = sqrt(comcoor);
+   for (i=0; i<WW_*WW_; i++)
+      a[i] /= comcoor;
+}
+
+void BgEdgeDetect::CreateFilters(void)
+{
+   int i,j;
+   double w;
+   for (i=-WL_; i<=WL_; i++)
+   {
+      w = pow(2,(-2*WL_))*factorial(2*WL_)/(factorial(WL_-i)*factorial(WL_+i));
+      smofil_[i+WL_] = w;
+      diffil_[i+WL_] = (2*i*w)/WL_;
+   }
+   for (j=0; j<WW_; j++)
+   {
+      for (i=0; i<WW_; i++)
+      {
+         wdy_[j+i*WW_] = wdx_[i+j*WW_] = smofil_[j]*diffil_[i];
+      }
+   }
+   
+   double norms = 0;
+   double normd = 0;
+   for (i=0; i<WW_; i++)
+   {
+      norms += smofil_[i]*smofil_[i];
+      normd += diffil_[i]*diffil_[i];
+   }
+   
+   for (j=0; j<WW_; j++)
+   {
+      for (i=0; i<WW_; i++)
+      {
+         mQ_[i][j] = (smofil_[j]*smofil_[i])/norms + (diffil_[j]*diffil_[i])/normd;
+         mN_[i][j] = (i==j) ? 1-mQ_[i][j] : -mQ_[i][j];
+      }
+   }
+}
+
+void BgEdgeDetect::CreateLookTable()
+{
+   bgLog("Creating angle lookup table\n");
+   int i;
+   for (i=-180; i<=180; i++)
+   {
+      lookTable_[i+180] = new double[WW_*WW_];
+      GenerateMaskAngle(lookTable_[i+180], (double) i);
+   }
+}
+
+void BgEdgeDetect::DeleteLookTable()
+{
+   int i;
+   for (i=0; i<NO_ANGLES; i++)
+   {
+      delete [] lookTable_[i];
+   }
+}
+
+void BgEdgeDetect::GetPixels(int* nopix, int* pixx, int* pixy, double x1, double x2, double y1, double y2)
+{
+   double minx,maxx,miny,maxy;
+   
+   if (x1<x2)
+   {
+      minx = x1;
+      maxx = x2;
+   }
+   else
+   {
+      minx = x2;
+      maxx = x1;
+   }
+   
+   if (y1<y2)
+   {
+      miny = y1;
+      maxy = y2;
+   }
+   else
+   {
+      miny = y2;
+      maxy = y1;
+   }
+   
+   int i,j,npix;
+   npix = 0;
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++)
+      {
+         if (permRank_[i+j*x_]<maxx && permRank_[i+j*x_]>minx &&
+             permConf_[i+j*x_]<maxy && permConf_[i+j*x_]>miny)
+         {
+            pixx[npix] = i;
+            pixy[npix++] = j;
+         }
+      }
+   }
+   *nopix = npix;
+}
+
+void BgEdgeDetect::GetNmxPixels(int* nopix, int* pixx, int* pixy, double x1, double x2, double y1, double y2)
+{
+   double minx,maxx,miny,maxy;
+   if (x1<x2)
+   {
+      minx = x1;
+      maxx = x2;
+   }
+   else
+   {
+      minx = x2;
+      maxx = x1;
+   }
+   
+   if (y1<y2)
+   {
+      miny = y1;
+      maxy = y2;
+   }
+   else
+   {
+      miny = y2;
+      maxy = y1;
+   }
+   
+   int i,j,npix;
+   npix = 0;
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++)
+      {
+         if (permNmxRank_[i+j*x_]<maxx && permNmxRank_[i+j*x_]>minx &&
+             permNmxConf_[i+j*x_]<maxy && permNmxConf_[i+j*x_]>miny)
+         {
+            pixx[npix] = i;
+            pixy[npix++] = j;
+         }
+      }
+   }
+   *nopix = npix;
+}
+
+void BgEdgeDetect::DoRecompute(BgEdgeList* cel, double nmxr, double nmxc,
+                               double rh, double ch, double rl, double cl,
+                               int nMin, int nmxType, int hystTypeHigh, int hystTypeLow)
+{
+   float *tr, *tc, *tdh, *tdl;
+   bgLog("Start edge detection...\n");
+   tr = new float[x_*y_];
+   tc = new float[x_*y_];
+   tdh = new float[x_*y_];
+   tdl = new float[x_*y_];
+   
+   //Nonmaximum supression
+   bgLog("...nonmaxima supression: ");
+
+   float (BgEdgeDetect::*fcomp)(float,float,float,float);
+   float (BgEdgeDetect::*feval)(float,float);
+   
+   switch(nmxType)
+   {
+   case FC_ELLIPSE:
+      fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc\n");
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line\n");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line\n");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box\n");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line\n");
+      break;
+  	default:
+      bgLog("Type not known\n");
+      return;
+   }
+   confTr_ = (float) nmxc;
+   rankTr_ = (float) nmxr;
+   
+   NewNonMaxSupress(permRank_,permConf_,permGx_,permGy_,permNmxRank_,permNmxConf_,fcomp);
+   bgLog("...hysteresis thresholding, high: ");
+   
+   switch(hystTypeHigh)
+   {
+   case FC_ELLIPSE:
+     	fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc");		
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line");  		
+      break;
+  	case FC_CUSTOM:
+      custx_ = hcustx_;
+      custy_ = hcusty_;
+      ncust_ = nhcust_;
+      fcomp = &BgEdgeDetect::CustomRegionComp;
+      feval = &BgEdgeDetect::CustomRegionEval;
+      bgLog("custom");
+      break;
+   }  
+   confTr_ = (float) ch;
+   rankTr_ = (float) rh;
+   StrConfEstim(permNmxRank_, permNmxConf_, tdh, feval);
+
+   bgLog("  low: ");
+   
+   switch(hystTypeLow) {
+   case FC_ELLIPSE:
+     	fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc\n");
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line\n");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line\n");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box\n");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line\n");  		
+      break;
+  	case FC_CUSTOM:
+      custx_ = lcustx_;
+      custy_ = lcusty_;
+      ncust_ = nlcust_;
+  	   fcomp = &BgEdgeDetect::CustomRegionComp;
+  	   feval = &BgEdgeDetect::CustomRegionEval;
+  	   bgLog("custom\n");
+  	   break;  		
+   } 
+   confTr_ = (float) cl;
+   rankTr_ = (float) rl;
+   StrConfEstim(permNmxRank_, permNmxConf_, tdl, feval);
+
+  //hysteresis thresholding
+
+   grx_ = permGx_;
+   gry_ = permGy_;
+   int minpt = nMin;
+   NewHysteresisTr(tdh, tdl, cel, minpt, tr, tc);
+   bgLog("Done edge detection.\n");
+   
+   delete [] tdl;
+   delete [] tdh;
+   delete [] tr;
+   delete [] tc;
+}
+
+void BgEdgeDetect::SaveNmxValues()
+{
+   FILE* fd;
+   int i,j;
+   
+   fd = fopen("ranknmx.dat", "w");
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++)
+      {
+         fprintf(fd, "%f ", *(permNmxRank_+j*x_+i));
+      }
+      fprintf(fd, "\n");
+   }
+   fclose(fd);
+   
+   fd=fopen("confnmx.dat", "w");
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++)
+      {
+         fprintf(fd, "%f ", *(permNmxConf_+j*x_+i));
+      }
+      fprintf(fd, "\n");
+   }
+   fclose(fd);
+}
+
+//Computes confedence map and rank
+//Pre : cim is an image
+//Post: confidence map and rank has been computed for cim
+//      and stored into confMap and rank respectively
+void BgEdgeDetect::ComputeEdgeInfo(BgImage* cim, float* confMap, float *rank)
+{
+   x_ = cim->x_;
+   y_ = cim->y_;
+   bgLog("Computing confidence map...\n");   
+   float *pGx, *pGy, *pTemp;
+   BgImage tcim(x_, y_);
+   if (cim->colorIm_==1)
+   {
+	   tcim.SetImageFromRGB(cim->im_, x_, y_, false);
+   } else
+   {
+	   tcim = *cim;
+   }
+
+   pGx = new float[x_*y_];
+   pGy = new float[x_*y_];   
+   pTemp = new float[x_*y_];
+   
+   // compute gradient images
+   bgLog("...smooth-differentiation filtering\n");
+   GaussDiffFilter(&tcim, pGx, pGy, pTemp);   
+
+   // compute confidences (subspace estimate)
+   bgLog("...subspace estimate\n");
+   SubspaceEstim(pTemp, pGx, pGy, confMap);
+
+   // compute edge strength from gradient image
+   bgLog("...edge strengths\n");
+   Strength(pGx, pGy, pTemp);
+   
+   // compute ranks of the strengths
+   bgLog("...computing ranks\n");
+   CompRanks(pTemp, rank);
+ 
+   //de-allocate memory
+   delete [] pTemp;
+   delete [] pGy;
+   delete [] pGx;
+}
+/*
+void BgEdgeDetect::ComputeConfidenceMap1(BgImage* cim, float* confMap)
+{
+	ComputeConfidenceMap(cim, confMap);
+	BgEdgeList el;
+	DoEdgeDetect(cim, &el, RANK_NMX, CONF_NMX, RANK_H, CONF_H, RANK_L, CONF_L,
+		NMIN, FC_ELLIPSE, FC_SQUARE_BOX, FC_ELLIPSE);
+   BgImage tempImage(cim->x_, cim->y_);
+   el.SetBinImage(&tempImage);
+   int i;
+   for (i=0; i<(cim->x_*cim->y_); i++)
+	   if (tempImage.im_[i] == 0)
+		   confMap[i] = 0;
+}
+*/
+void BgEdgeDetect::DoEdgeDetect(BgImage* cim, BgEdgeList* cel, double nmxr, double nmxc,
+                                double rh, double ch, double rl, double cl,
+                                int nMin, int nmxType, int hystTypeHigh, int hystTypeLow)
+{
+   x_ = cim->x_;
+   y_ = cim->y_;
+   bgLog("Start edge detection...\n");   
+   permGx_ = new float[x_*y_];
+   permGy_ = new float[x_*y_];
+   permConf_ = new float[x_*y_];
+   permRank_ = new float[x_*y_];
+   permNmxRank_ = new float[x_*y_];
+   permNmxConf_ = new float[x_*y_];
+   havePerm_ = true;
+   float* tr;
+   float* tc;
+   float* tdh;
+   float* tdl;
+   
+   tr = new float[x_*y_];
+   tc = new float[x_*y_];
+   tdh = new float[x_*y_];
+   tdl = new float[x_*y_];
+   
+   // compute gradient images
+   bgLog("...smooth-differentiation filtering\n");
+   GaussDiffFilter(cim, permGx_, permGy_, tr);   
+
+   // compute confidences (subspace estimate)
+   bgLog("...subspace estimate\n");
+   SubspaceEstim(tr, permGx_, permGy_, permConf_);
+   
+   // compute edge strength from gradient image
+   bgLog("...edge strengths\n");
+   Strength(permGx_, permGy_, tr);
+   
+   // compute ranks of the strengths
+   bgLog("...computing ranks\n");
+   CompRanks(tr, permRank_);
+   
+   // new nonmaxima supression
+   bgLog("...nonmaxima supression: ");
+
+   // select appropriate function
+   float (BgEdgeDetect::*fcomp)(float,float,float,float);
+   float (BgEdgeDetect::*feval)(float,float);
+   switch(nmxType)
+   {
+   case FC_ELLIPSE:
+     	fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc\n");
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line\n");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line\n");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box\n");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line\n");
+      break;
+  	default:
+      bgLog("Type not known\n");
+      return;
+   }
+
+   confTr_ = (float) nmxc;
+   rankTr_ = (float) nmxr;
+   NewNonMaxSupress(permRank_, permConf_, permGx_, permGy_, permNmxRank_, permNmxConf_, fcomp);
+
+   // new hysteresis thresholding
+   bgLog("...hysteresis thresholding, high: ");
+
+   // select function, high curve
+   switch(hystTypeHigh)
+   {
+   case FC_ELLIPSE:
+     	fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc");		
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line");  		
+      break;
+  	case FC_CUSTOM:
+      custx_ = hcustx_;
+      custy_ = hcusty_;
+      ncust_ = nhcust_;
+      fcomp = &BgEdgeDetect::CustomRegionComp;
+      feval = &BgEdgeDetect::CustomRegionEval;
+      bgLog("custom");
+      break;
+   }  
+
+   confTr_ = (float) ch;
+   rankTr_ = (float) rh;
+   StrConfEstim(permNmxRank_, permNmxConf_, tdh, feval);
+
+   bgLog("  low: ");
+
+   // select function, low curve
+   switch(hystTypeLow)
+   {
+   case FC_ELLIPSE:
+     	fcomp = &BgEdgeDetect::EllipseComp;
+      feval = &BgEdgeDetect::EllipseEval;
+      bgLog("arc\n");
+      break;
+   case FC_VERT_LINE:
+      fcomp = &BgEdgeDetect::VerticalLineComp;
+      feval = &BgEdgeDetect::VerticalLineEval;
+      bgLog("vertical line\n");		
+      break;
+   case FC_HORIZ_LINE:
+      fcomp = &BgEdgeDetect::HorizontalLineComp;
+      feval = &BgEdgeDetect::HorizontalLineEval;
+      bgLog("horizontal line\n");		
+      break;
+   case FC_SQUARE_BOX:
+      fcomp = &BgEdgeDetect::SquareComp;
+      feval = &BgEdgeDetect::SquareEval;
+      bgLog("box\n");		
+      break;
+   case FC_LINE:
+      fcomp = &BgEdgeDetect::LineComp;
+      feval = &BgEdgeDetect::LineEval;		
+      bgLog("line\n");  		
+      break;
+  	case FC_CUSTOM:
+      custx_ = lcustx_;
+      custy_ = lcusty_;
+      ncust_ = nlcust_;
+  	   fcomp = &BgEdgeDetect::CustomRegionComp;
+  	   feval = &BgEdgeDetect::CustomRegionEval;
+  	   bgLog("custom\n");
+  	   break;  		
+   } 
+   confTr_ = (float) cl;
+   rankTr_ = (float) rl;
+
+   StrConfEstim(permNmxRank_, permNmxConf_, tdl, feval);
+
+   grx_ = permGx_;
+   gry_ = permGy_;
+   
+   NewHysteresisTr(tdh, tdl, cel, nMin, tr, tc);
+
+   bgLog("Done edge detection.\n");
+
+   delete [] tdl;
+   delete [] tdh;
+   delete [] tr;
+   delete [] tc;
+}
+
+void BgEdgeDetect::SubspaceEstim(float* im, float* grx, float* gry, float* cee)
+{
+   // im original image
+   // grx, gry gradient of image
+   // cee confidence edge estimate
+   
+   float* itim;
+   float* itgx;
+   float* itgy;
+   float* itcee;
+   itim = im;
+   itgx = grx;
+   itgy = gry;
+   itcee = cee;
+
+   double* tae;
+   double* ti;
+
+   ti = new double[WW_*WW_];
+
+   int i,j,l,c;
+   double v1;
+   double angleEdge;
+   int WW2 = WW_*WW_;
+   
+   itim += WL_*x_;
+   itgx += WL_*x_;
+   itgy += WL_*x_;
+   itcee += WL_*x_;
+
+   for (j=WL_; j<(y_-WL_); j++)
+   {
+      for (i=0; i<WL_; i++)
+         itcee[i] = 0;
+      itim += WL_;
+      itgx += WL_;
+      itgy += WL_;
+      itcee += WL_;
+
+
+      for (i=WL_; i<(x_-WL_); i++, itim++, itgx++, itgy++, itcee++)
+      {
+         if ((fabs(*itgx)+fabs(*itgy))>TOL_E)
+         {
+            angleEdge = (-atan2(*itgx, *itgy))*180.0/PI;
+            tae = lookTable_[(int) (angleEdge+180.49)];
+            
+            //A=A-mean(A)
+            v1=0;
+            for (l=0; l<WW_; l++)
+            {
+               for (c=0; c<WW_; c++)
+               {
+                  v1 += ti[l*WW_+c] = *(itim+(l-WL_)*x_+c-WL_);
+               }
+            }
+            v1 /= WW2;
+            for (l=0; l<WW2; l++)
+               ti[l] -= v1;
+            
+            //A/norm(A,'fro')
+            v1 = 0;
+            for (l=0; l<WW2; l++)
+               v1 += ti[l]*ti[l];
+            v1 = sqrt(v1);
+            for (l=0; l<WW2; l++)
+               ti[l] /= v1;
+
+            //global
+            v1 = 0;
+            for (l=0; l<WW2; l++)
+               v1 += tae[l]*ti[l];
+            v1 = fabs(v1);
+            *itcee = (float) v1;
+         }
+         else
+         {
+            *itcee = 0;
+         }
+      }
+      for (i=0; i<WL_; i++)
+         itcee[i] = 0;
+      itim += WL_;
+      itgx += WL_;
+      itgy += WL_;
+      itcee += WL_;
+   }
+   WW2 = x_*y_;
+   for (j=0; j<(WL_*x_); j++)
+   {
+      cee[j] = 0;
+      cee[WW2-j-1] = 0;
+   }   
+
+   
+   delete [] ti;
+}
+
+void BgEdgeDetect::GaussFilter(BgImage* cim, float* fim, double sigma, int width)
+{
+   double* filter;
+   unsigned char* im;
+   double* tim;
+   double sum = 0;
+   double sum1 = 0;
+   int i,ii,jj,j,k;
+
+   im = cim->im_;
+   if (width==-2)
+   {
+      for (i=0; i<x_*y_;i++)
+         fim[i] = im[i];
+      return;
+   }
+
+   if (width<3)
+      width = (int) (1+2*ceil(2.5*sigma));
+   int tail = width/2;
+   width = 2*tail+1;
+
+   //create kernel
+   filter = new double[width];
+   for (i=-tail; i<=tail; i++)
+      sum += filter[i+tail] = exp(-i*i/(2*sigma*sigma));
+   for (i=0; i<width; i++)
+      filter[i] /= sum;
+
+   //filter image
+   im = cim->im_;
+   tim = new double[x_*y_];
+   for (j=0; j<y_; j++)
+   {
+      for (i=tail; i<(x_-tail); i++)
+      {
+         sum=0;
+         for (k=-tail; k<=tail; k++)
+            sum += im[j*x_+i+k]*filter[k+tail];
+         tim[j*x_+i] = sum;
+      }
+      
+      for (i=0; i<tail; i++)
+      {
+         tim[j*x_+i] = 0;
+         tim[j*x_+x_-i-1] = 0;
+         for (k=-tail; k<=tail; k++)
+         {
+            ii = (k+i)>=0 ? k+i : 0;
+            tim[j*x_+i] += im[j*x_+ii]*filter[k+tail];
+            ii = (x_-i-1+k)<x_ ? x_-i-1+k : x_-1;
+            tim[j*x_+x_-i-1] += im[j*x_+ii]*filter[k+tail];
+         }
+      }
+   }
+
+   for (i=0; i<x_; i++)
+   {
+      for (j=tail; j<(y_-tail); j++)
+      {
+         sum=0;
+         for (k=-tail; k<=tail; k++)
+            sum += tim[(j+k)*x_+i]*filter[k+tail];
+         fim[j*x_+i] = (float) (sum);
+      }
+      for (j=0; j<tail; j++)
+      {
+         sum = 0;
+         sum1 = 0;
+         for (k=-tail; k<=tail; k++)
+         {
+            jj = (k+j)>=0 ? k+j : 0;
+            sum += tim[jj*x_+i]*filter[k+tail];
+            jj = (y_-j-1+k)<y_ ? y_-j-1+k : y_-1;
+            sum1 += tim[jj*x_+i]*filter[k+tail];
+         }
+         fim[j*x_+i] = (float) (sum);
+         fim[(y_-j-1)*x_+i] = (float) (sum1);
+      }
+   }
+   delete [] filter;
+   delete [] tim;
+}
+
+void BgEdgeDetect::GaussDiffFilter(BgImage* cim, float* grx, float* gry, float* rezIm)
+{
+   
+   double* sf; //smooth filter
+   double* df; //diff filter
+   unsigned char* im;
+   
+   double* tim;
+   double sum = 0;
+   double sum1 = 0;
+   int i, j, k;
+   
+   //create kernels
+   sf = smofil_;
+   df = diffil_;
+   
+   im = cim->im_;
+   tim = new double[x_*y_];
+   for (i=0; i<x_*y_; i++)
+   {
+      grx[i] = gry[i] = 0;
+      tim[i] = 0;
+      rezIm[i] = im[i];
+   }
+   
+   //filter image x
+   //smooth on y
+   for (i=0; i<x_; i++)
+   {
+      for (j=WL_; j<(y_-WL_); j++)
+      {
+         sum = 0;
+         for (k=-WL_; k<=WL_; k++)
+            sum += im[(j+k)*x_+i]*sf[k+WL_];
+         tim[j*x_+i] = sum;
+      }
+   }
+   //diff on x
+   for (j=0; j<y_; j++)
+   {
+      for (i=WL_; i<(x_-WL_); i++)
+      {
+         sum = 0;
+         for (k=-WL_; k<=WL_; k++)
+            sum += tim[j*x_+i+k]*df[k+WL_];
+         grx[j*x_+i] = (float) (sum);
+      }
+   }
+
+   //filter image y
+   for (i=0; i<x_*y_;i++)
+      tim[i] = 0;
+   im = cim->im_;
+   //smooth on x
+   for (j=0; j<y_; j++)
+   {
+      for (i=WL_; i<(x_-WL_); i++)
+      {
+         sum = 0;
+         for (k=-WL_; k<=WL_; k++)
+            sum += im[j*x_+i+k]*sf[k+WL_];
+         tim[j*x_+i] = sum;
+      }
+   }
+   //diff on y
+   for (i=0; i<x_; i++)
+   {
+      for (j=WL_; j<(y_-WL_); j++)
+      {
+         sum = 0;
+         for (k=-WL_; k<=WL_; k++)
+            sum += tim[(j+k)*x_+i]*df[k+WL_];
+         gry[j*x_+i] = (float) (sum);
+      }
+   }
+   delete [] tim;
+}
+
+void BgEdgeDetect::CompRanks(float* strength, float* ranks)
+{
+   int* index;
+   float* ra;
+   ra = new float[x_*y_];
+   index = new int[x_*y_];
+   int ii;
+   
+   for (ii=0; ii<x_*y_; ii++)
+   {
+      index[ii] = ii;
+      ranks[ii] = 0;
+      ra[ii] = strength[ii];
+   }
+
+   //heap sort with ranks (from numerical recipies)
+   unsigned long i, ir, j, l;
+   unsigned long n;
+   n = x_*y_;
+   float rra;
+   int irra;
+
+   if (n<2)
+      return;
+   l = (n>>1)+1;
+   ir = n;
+   for (;;)
+   {
+      if (l>1)
+      {
+         rra = ra[--l-1];
+         irra = index[l-1];
+      }
+      else
+      {
+         rra = ra[ir-1];
+         irra = index[ir-1];
+         ra[ir-1] = ra[1-1];
+         index[ir-1] = index[1-1];
+         if (--ir==1)
+         {
+            ra[1-1] = rra;
+            index[1-1] = irra;
+            break;
+         }
+      }
+      i = l;
+      j = l+l;
+      while (j<=ir)
+      {
+         if (j<ir && ra[j-1]<ra[j+1-1])
+            j++;
+         if (rra<ra[j-1])
+         {
+            ra[i-1] = ra[j-1];
+            index[i-1] = index[j-1];
+            i = j;
+            j <<= 1;
+         }
+         else
+            j = ir+1;
+      }
+      ra[i-1] = rra;
+      index[i-1] = irra;
+   }
+   
+   //setranks
+   irra = 1;
+   for (ii=1; ii<x_*y_; ii++)
+   {
+      if (ra[ii]>ZERO_TRESH)
+      {
+         ranks[index[ii]] = (float) irra;
+         if (ra[ii]>ra[ii-1])
+            irra++;
+      }
+   }
+   irra--;
+   for (ii=0; ii<x_*y_; ii++) 
+      ranks[ii] /= irra;
+
+  delete [] index;
+  delete [] ra;
+}
+
+void BgEdgeDetect::StrConfEstim(float* ranks, float* confidence, float* rezult,
+                                float (BgEdgeDetect::*feval)(float,float))
+{
+   int i;
+   for (i=0; i<x_*y_; i++)
+   {
+      rezult[i] = (this->*feval)(ranks[i], confidence[i]);
+   }
+}
+
+void BgEdgeDetect::Strength(float* grx, float* gry, float* strength)
+{
+   int i,j;
+   float* itgx;
+   float* itgy;
+   float* its;
+   double val;
+   itgx = grx;
+   itgy = gry;
+   its = strength;
+   for (j=0; j<y_; j++)
+      for(i=0; i<x_; i++)
+      {
+         val = sqrt(((double) (*itgx*(*(itgx++))))+((double) (*itgy*(*(itgy++)))));
+         *(its++)=(float) (val);
+      }
+}
+
+void BgEdgeDetect::NewNonMaxSupress(float* rank, float* conf, float* grx, float* gry, float* nmxRank, float* nmxConf,
+                                    float (BgEdgeDetect::*feval)(float, float, float, float))
+{
+   int i,j;
+   float* itr;
+   float* itc;
+   float* itgx;
+   float* itgy;
+   float* itnmxr;
+   float* itnmxc;
+   float alpha,r1,c1,r2,c2,lambda;
+   itr = rank;
+   itc = conf;
+   itgx = grx;
+   itgy = gry;
+   itnmxr = nmxRank;
+   itnmxc = nmxConf;
+   
+   for (i=0; i<x_*y_; i++)
+   {
+      itnmxr[i] = itnmxc[i] = 0;
+   }
+   for(i=0; i<x_; i++)
+   {
+      itr[i] = itc[i] = 0;
+      itr[(y_-1)*x_+i] = itc[(y_-1)*x_+i] = 0;
+   }
+   for(j=0; j<y_; j++)
+   {
+      itr[j*x_] = itc[j*x_] = 0;
+      itr[j*x_+x_-1] = itc[j*x_+x_-1] = 0;
+   }
+
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++, itr++, itc++, itgx++, itgy++, itnmxr++, itnmxc++)
+      {
+         if (*itr>0 && *itc>0)
+         {
+            alpha = (float) atan2(*itgy, *itgx);
+            alpha = (alpha<0) ? alpha+(float)PI : alpha;
+            if (alpha<=PI/4)
+            {
+               lambda = (float) tan(alpha);
+               r1 = (1-lambda)*(*(itr+1))+lambda*(*(itr+x_+1));
+               c1 = (1-lambda)*(*(itc+1))+lambda*(*(itc+x_+1));
+               r2 = (1-lambda)*(*(itr-1))+lambda*(*(itr-x_-1));
+               c2 = (1-lambda)*(*(itc-1))+lambda*(*(itc-x_-1));
+               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
+               {
+                  *itnmxr = *itr;
+                  *itnmxc = *itc;
+               }
+            }
+            else if (alpha<=PI/2)
+            {
+               lambda = (float) tan(PI/2-alpha);
+               r1 = (1-lambda)*(*(itr+x_))+lambda*(*(itr+x_+1));
+               c1 = (1-lambda)*(*(itc+x_))+lambda*(*(itc+x_+1));
+               r2 = (1-lambda)*(*(itr-x_))+lambda*(*(itr-x_-1));
+               c2 = (1-lambda)*(*(itc-x_))+lambda*(*(itc-x_-1));
+               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
+               {
+                  *itnmxr = *itr;
+                  *itnmxc = *itc;
+               }
+               
+            }
+            else if(alpha<=3*PI/4)
+            {
+               lambda = (float) tan(alpha-PI/2);
+               r1 = (1-lambda)*(*(itr+x_))+lambda*(*(itr+x_-1));
+               c1 = (1-lambda)*(*(itc+x_))+lambda*(*(itc+x_-1));
+               r2 = (1-lambda)*(*(itr-x_))+lambda*(*(itr-x_+1));
+               c2 = (1-lambda)*(*(itc-x_))+lambda*(*(itc-x_+1));
+               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
+               {
+                  *itnmxr = *itr;
+                  *itnmxc = *itc;
+               }
+            }
+            else
+            {
+               lambda = (float) tan(PI-alpha);
+               r1 = (1-lambda)*(*(itr-1))+lambda*(*(itr+x_-1));
+               c1 = (1-lambda)*(*(itc-1))+lambda*(*(itc+x_-1));
+               r2 = (1-lambda)*(*(itr+1))+lambda*(*(itr-x_+1));
+               c2 = (1-lambda)*(*(itc+1))+lambda*(*(itc-x_+1));
+               if ((this->*feval)(*itr, *itc, r1, c1)<0 && (this->*feval)(*itr, *itc, r2, c2)<=0)
+               {
+                  *itnmxr = *itr;
+                  *itnmxc = *itc;
+               }
+            }
+         }
+      }
+   }
+}
+
+void BgEdgeDetect::NewHysteresisTr(float* edge, float* low, BgEdgeList* cel, int nMin, float* mark, float* coord)
+{
+   float* tm;
+   float* te;
+   float* tl;
+   int i,j,n;
+   
+   n=0;
+   for (i=0, tm=mark; i<x_*y_; i++,tm++)
+      *tm=0;
+   
+   te_ = te = edge;
+   tm_ = tm = mark;
+   tl_ = tl = low;
+   
+   for (j=0; j<y_; j++)
+   {
+      for (i=0; i<x_; i++, tm++, te++)
+      {
+         if ((*tm==0) && ((*te)>HYST_LOW_CUT))
+         {
+            //found an edge start
+            npt_ = 0;
+            *tm = 1;
+            tc_ = coord;
+            NewEdgeFollow(i, j);
+            //store the edge
+            if (npt_>=nMin) cel->AddEdge(coord, npt_);
+         }
+      }
+   }
+}
+
+void BgEdgeDetect::NewEdgeFollow(int ii,int jj)
+{
+   int i;
+   int iin, jjn;
+   for (i=0; i<8; i++)
+   {
+      iin = ii+gNb[i][0];
+      jjn = jj+gNb[i][1];
+      if ((tm_[jjn*x_+iin]==0) && ((tl_[jjn*x_+iin])>0))
+      {
+         tm_[jjn*x_+iin] = 1;
+         NewEdgeFollow(iin, jjn);
+      }
+   }
+   *(tc_++) = (float) ii;
+   *(tc_++) = (float) jj;
+   npt_++;
+}
+
+void BgEdgeDetect::SetCustomHigh(int* x, int* y, int n, int sx, int sy)
+{
+   if (nhcust_>0)
+   {
+      delete [] hcustx_;
+      delete [] hcusty_;
+   }
+   nhcust_ = 0;
+   hcustx_ = hcusty_ = 0;   
+   nhcust_ = n+2;
+   hcustx_ = new float[nhcust_];
+   hcusty_ = new float[nhcust_];
+   
+   int idx,i;
+   idx = 0;
+   hcustx_[idx] = 0;
+   hcusty_[idx++] = 0;
+   for (i=0; i<n; i++)
+   {
+      hcustx_[idx] = ((float) x[i])/sx;
+      hcusty_[idx++] = (float)(1.0-((float) y[i])/sy);
+   }   
+   hcustx_[idx] = 0;
+   hcusty_[idx++] = 0;
+   
+   bgLog(" hyst high custom x: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", hcustx_[i]);
+   bgLog("\n");
+   bgLog(" hist high custom y: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", hcusty_[i]);
+   bgLog("\n");   
+}
+
+void BgEdgeDetect::SetCustomHigh(double* x, double* y, int n)
+{
+   if (nhcust_>0)
+   {
+      delete [] hcustx_;
+      delete [] hcusty_;
+   }
+   nhcust_ = 0;
+   hcustx_ = hcusty_ = 0;
+   nhcust_ = n+2;
+   hcustx_ = new float[nhcust_];
+   hcusty_ = new float[nhcust_];
+   
+   int idx,i;
+   idx = 0;
+   hcustx_[idx] = 0;
+   hcusty_[idx++] = 0;
+   for (i=0; i<n; i++)
+   {
+      hcustx_[idx] = (float) x[i];
+      hcusty_[idx++] = (float) y[i];
+   }   
+   hcustx_[idx] = 0;
+   hcusty_[idx++] = 0;
+   
+   bgLog(" hyst high custom x: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", hcustx_[i]);
+   bgLog("\n");
+   bgLog(" hist high custom y: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", hcusty_[i]);
+   bgLog("\n");   
+}
+
+void BgEdgeDetect::SetCustomLow(int* x, int* y, int n, int sx, int sy)
+{
+   if(nlcust_>0)
+   {
+      delete [] lcustx_;
+      delete [] lcusty_;
+   }
+   nlcust_ = 0;
+   lcustx_ = lcusty_ = 0;   
+   nlcust_ = n+2;
+   lcustx_ = new float[nlcust_];
+   lcusty_ = new float[nlcust_];
+   
+   int idx,i;
+   idx = 0;
+   lcustx_[idx] = 0;
+   lcusty_[idx++] = 0;
+   for (i=0; i<n; i++)
+   {
+      lcustx_[idx] = ((float) x[i])/sx;
+      lcusty_[idx++] = (float)(1.0-((float) y[i])/sy);
+   }   
+   lcustx_[idx] = 0;
+   lcusty_[idx++] = 0;
+   bgLog(" hyst low custom x: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", lcustx_[i]);
+   bgLog("\n");
+   bgLog(" low custom y: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", lcusty_[i]);
+   bgLog("\n");   
+}
+
+void BgEdgeDetect::SetCustomLow(double* x, double* y, int n)
+{
+   if(nlcust_>0)
+   {
+      delete [] lcustx_;
+      delete [] lcusty_;
+   }
+   nlcust_ = 0;
+   lcustx_ = lcusty_ = 0;   
+   nlcust_ = n+2;
+   lcustx_ = new float[nlcust_];
+   lcusty_ = new float[nlcust_];
+   
+   int idx,i;
+   idx = 0;
+   lcustx_[idx] = 0;
+   lcusty_[idx++] = 0;
+   for (i=0; i<n; i++)
+   {
+      lcustx_[idx] = (float) x[i];
+      lcusty_[idx++] = (float) y[i];
+   }   
+   lcustx_[idx] = 0;
+   lcusty_[idx++] = 0;
+   bgLog(" hyst low custom x: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", lcustx_[i]);
+   bgLog("\n");
+   bgLog(" low custom y: ");
+   for (i=0; i<=n; i++)
+      bgLog(" %f", lcusty_[i]);
+   bgLog("\n");   
+}
diff --git a/Utilities/otbedison/edge/BgEdgeDetect.h b/Utilities/otbedison/edge/BgEdgeDetect.h
old mode 100755
new mode 100644
index c07689d601a96d10f846e0a26e733d83aaa643cf..5824179f40875f96dd977065074ede16df37ea6a
--- a/Utilities/otbedison/edge/BgEdgeDetect.h
+++ b/Utilities/otbedison/edge/BgEdgeDetect.h
@@ -7,10 +7,10 @@
 // Copyright:   (c) Bogdan Georgescu
 // Version:     v0.1
 /////////////////////////////////////////////////////////////////////////////
-
+
 #define PI 3.1415926535
 #define ZERO_TRESH 0.0000000001
-
+
 // default values for edge detection
 #define CONF_NMX 0.5
 #define RANK_NMX 0.5
@@ -20,14 +20,14 @@
 #define RANK_L 0.99
 #define NMIN 5
 #define KERNEL_SIZE 2
-
+
 #define HYST_LOW_CUT 0.0
 #define MAX_CUSTT 30
 #define MAX_FILTS 31
 #define NO_ANGLES 361
-
+
 #define ALF_TRESH PI/4
-
+
 static const int gNb[8][2]=
 {
    1, 0,
@@ -39,7 +39,7 @@ static const int gNb[8][2]=
   -1, 1,
   -1,-1
 };
-
+
 static const double gAlpha[8][2]=
 {
      PI/2,   PI/2,
@@ -51,12 +51,12 @@ static const double gAlpha[8][2]=
    3*PI/4, 3*PI/4,
      PI/4,   PI/4
 };
-
+
 // main class, edge detection
 class BgEdgeDetect
 {
 public:
-
+
    // main function for edge detection
    // cim input image
    // cel edge list (will be filled with pixels on edges)
@@ -66,22 +66,22 @@ public:
    // nMin, min number of pixels on an edge
    // nmxType, hystTypeHigh, hystTypeLow, type of nmx curve, hyst. high curve, hyst low curve
    //  in (FC_ELLIPSE, FC_VERT_LINE, FC_HORIZ_LINE, FC_LINE, FC_SQUARE_BOX, FC_CUSTOM)
-
+
    void DoEdgeDetect(BgImage* cim, BgEdgeList* cel, double nmxr, double nmxc,
                      double rh, double ch, double rl, double cl,
-                     int nMin, int nmxType, int hystTypeHigh, int hystTypeLow);
-
-   // computes confidence map and rank information of sepcified image
+                     int nMin, int nmxType, int hystTypeHigh, int hystTypeLow);
+
+   // computes confidence map and rank information of sepcified image
    void ComputeEdgeInfo(BgImage*, float*, float*);
-//   void ComputeConfidenceMap1(BgImage*, float*);
+//   void ComputeConfidenceMap1(BgImage*, float*);
    // if have permanent data, call this function (compute only last two steps is same kernel size)
    void DoRecompute(BgEdgeList*, double, double, double, double, double, double, int, int, int, int);
-
+
    BgEdgeDetect(int filtDim);
    ~BgEdgeDetect();
-
+
    void SaveNmxValues();
-
+
    float EllipseEval(float, float);
    float EllipseComp(float, float, float, float);
    float LineEval(float, float);
@@ -94,12 +94,12 @@ public:
    float SquareComp(float, float, float, float);
    float CustomRegionEval(float, float);
    float CustomRegionComp(float, float, float, float);
-
+
    void SetCustomHigh(int*, int*, int, int, int);
    void SetCustomLow(int*, int*, int, int, int);
    void SetCustomHigh(double*, double*, int);
    void SetCustomLow(double*, double*, int);
-
+
    void IsGood(void);
    void GetPixels(int*, int*, int*, double, double, double, double);
    void GetNmxPixels(int*, int*, int*, double, double, double, double);
@@ -111,25 +111,25 @@ public:
    double mN_[MAX_FILTS][MAX_FILTS];
    double mQ_[MAX_FILTS][MAX_FILTS];
    double* lookTable_[NO_ANGLES];
-
+
    int WW_;
    int WL_;
    float confTr_;
    float rankTr_;
-
+
    float* custx_;
    float* custy_;
    float* tcustx_;
    float* tcusty_;
    int ncust_;
-
+
    float* hcustx_;
    float* hcusty_;
    int nhcust_;
    float* lcustx_;
    float* lcusty_;
    int nlcust_;   
-
+
    int x_;
    int y_;
    float* permConf_;
@@ -137,9 +137,9 @@ public:
    float* permNmxRank_;
    float* permNmxConf_;
    bool havePerm_;
-
+
 protected:
-
+
    void GenerateMaskAngle(double*, double);
    void CreateFilters(void);	
    void CreateLookTable(void);
@@ -154,14 +154,14 @@ protected:
    void NewHysteresisTr(float*, float*, BgEdgeList*, int, float*, float*);
    void NewEdgeFollow(int, int);
    void SubspaceEstim(float*, float*, float*, float*);
-
+
    float* te_;
    float* tm_;
    double low_;
    float* tc_;
    float* tl_;
    int npt_;
-
+
    float* grx_;
    float* gry_;
    float* permGx_;
diff --git a/Utilities/otbedison/edge/BgEdgeList.cpp b/Utilities/otbedison/edge/BgEdgeList.cpp
old mode 100755
new mode 100644
index 7dcdbfea2b02fb377cfb21ad799f0d1a055cc1a5..f79ca455e90f5410c73905659a3390e537d486c4
--- a/Utilities/otbedison/edge/BgEdgeList.cpp
+++ b/Utilities/otbedison/edge/BgEdgeList.cpp
@@ -1,225 +1,225 @@
-/////////////////////////////////////////////////////////////////////////////

-// Name:        BgEdgeList.cpp

-// Purpose:     BgEdgeList class functions

-// Author:      Bogdan Georgescu

-// Modified by:

-// Created:     06/22/2000

-// Copyright:   (c) Bogdan Georgescu

-// Version:     v0.1

-/////////////////////////////////////////////////////////////////////////////

-

-#include <stdio.h>

-#include <stdlib.h>

-#include <math.h>

-#include "BgDefaults.h"

-#include "BgImage.h"

-#include "BgEdge.h"

-#include "BgEdgeList.h"

-

-BgEdgeList::BgEdgeList()

-{

-   nEdges_ = 0;

-   edgelist_ = 0;

-   crtedge_ = 0;

-}

-

-BgEdgeList::~BgEdgeList()

-{

-   if (nEdges_>0)

-   {

-      BgEdge* edge;

-      for (int i=0; i<nEdges_; i++)

-      {

-         edge = edgelist_->next_;

-         delete edgelist_;

-         edgelist_=edge;

-      }

-   }

-}

-

-void BgEdgeList::AddEdge(float* edge, int nPoints)

-{

-   BgEdge* tedge;

-   tedge = new BgEdge();

-   tedge->SetPoints(edge, nPoints);

-   if (nEdges_==0)

-   {

-      nEdges_ = 1;

-      edgelist_ = tedge;

-      crtedge_ = tedge;

-   }

-   else

-   {

-      nEdges_++;

-      crtedge_->next_ = tedge;

-      crtedge_ = tedge;

-   }

-}

-

-void BgEdgeList::AddEdge(int* edge, int nPoints)

-{

-   BgEdge* tedge;

-   tedge = new BgEdge();

-   tedge->SetPoints(edge, nPoints);

-   if (nEdges_==0)

-   {

-      nEdges_ = 1;

-      edgelist_ = tedge;

-      crtedge_ = tedge;

-   }

-   else

-   {

-      nEdges_++;

-      crtedge_->next_ = tedge;

-      crtedge_ = tedge;

-   }

-}

-

-void BgEdgeList::SetGradient(float* grx, float* gry, float* mark, int ncol)

-{

-   BgEdge* it;

-   int i;

-

-   it=edgelist_;

-   for (i=0; i<nEdges_; i++)

-   {

-      it->SetGradient(grx, gry, mark, ncol);

-      it = it->next_;

-   }

-}

-

-void BgEdgeList::RemoveShortEdges(int minp)

-{

-   if (nEdges_==0)

-      return;

-

-   int nEdges=nEdges_;

-   BgEdge* it1;

-   BgEdge* it2;

-   it1 = edgelist_;

-   it2 = it1->next_;

-

-   for (int i=1; i<nEdges_; i++)

-   {

-      if (it2->nPoints_ < minp)

-      {

-         it1->next_ = it2->next_;

-         delete it2;

-         it2 = it1->next_;

-         nEdges--;

-      }

-      else

-      {

-         it1 = it2;

-         it2 = it1->next_;

-      }

-   }

-

-   if (edgelist_->nPoints_ < minp)

-   {

-      it1 = edgelist_;

-      edgelist_ = edgelist_->next_;

-      delete it1;

-      nEdges--;

-   }

-   nEdges_=nEdges;

-}

-

-void BgEdgeList::SetBinImage(BgImage* image)

-{

-   int i, j;

-   int ix, iy;

-   int x, y;

-   

-   x = image->x_;

-   y = image->y_;

-   unsigned char* im=image->im_;

-   

-   for (i=0; i<x; i++)

-   {

-      for (j=0;j<y;j++)

-      {

-         *(im++) = 0;

-      }

-   }

-   

-   im = image->im_;

-   int* ite;

-   crtedge_=edgelist_;

-   for (i=0; i<nEdges_; i++)

-   {

-      ite = crtedge_->edge_;

-      for (j=0; j<crtedge_->nPoints_; j++)

-      {

-         ix = *(ite++);

-         iy = *(ite++);

-         *(im+iy*x+ix) = 255;

-      }

-      crtedge_=crtedge_->next_;

-   }

-}

-

-bool BgEdgeList::SaveEdgeList(char* edgeFile)

-{

-   int length;

-   int i,j;

-   BgEdge *crtedge;

-   

-   FILE* fp;

-   fp=fopen(edgeFile,"wb");

-   crtedge = edgelist_;

-   for (i=0; i<nEdges_; i++)

-   {

-      length = crtedge->nPoints_;

-      for (j=0; j<length; j++)

-      {

-         fprintf(fp, "%d %d %d\n", *((crtedge->edge_)+2*j), *((crtedge->edge_)+2*j+1), i);

-      }

-      crtedge = crtedge->next_;

-   }

-   fclose(fp);

-   return true;

-}

-

-void BgEdgeList::GetAllEdgePoints(int* x, int* y, int* n)

-{

-   int length;

-   int i,j;

-   BgEdge *crtedge;

-   int *edgep;

-   

-   crtedge = edgelist_;

-   *n = 0;

-   for (i=0; i<nEdges_; i++)

-   {

-      length = crtedge->nPoints_;

-      edgep = crtedge->edge_;

-      for (j=0; j<length; j++)

-      {

-         x[*n] = edgep[2*j];

-         y[*n] = edgep[2*j+1];

-         (*n)++;

-      }

-      crtedge = crtedge->next_;

-   }

-}

-

-void BgEdgeList::SetNoMark(void)

-{

-   int length;

-   int i,j;

-   BgEdge* crtedge;

-   unsigned char* mark;

-   crtedge = edgelist_;

-   for (i=0; i<nEdges_; i++)

-   {

-      length = crtedge->nPoints_;

-      mark = crtedge->mark_ = new unsigned char[length];

-      crtedge->isMarkSet_ = true;

-      for (j=0; j<length; j++)

-      {

-         *(mark+j) = 0;

-      }

-      crtedge = crtedge->next_;

-   }

-}

+/////////////////////////////////////////////////////////////////////////////
+// Name:        BgEdgeList.cpp
+// Purpose:     BgEdgeList class functions
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "BgDefaults.h"
+#include "BgImage.h"
+#include "BgEdge.h"
+#include "BgEdgeList.h"
+
+BgEdgeList::BgEdgeList()
+{
+   nEdges_ = 0;
+   edgelist_ = 0;
+   crtedge_ = 0;
+}
+
+BgEdgeList::~BgEdgeList()
+{
+   if (nEdges_>0)
+   {
+      BgEdge* edge;
+      for (int i=0; i<nEdges_; i++)
+      {
+         edge = edgelist_->next_;
+         delete edgelist_;
+         edgelist_=edge;
+      }
+   }
+}
+
+void BgEdgeList::AddEdge(float* edge, int nPoints)
+{
+   BgEdge* tedge;
+   tedge = new BgEdge();
+   tedge->SetPoints(edge, nPoints);
+   if (nEdges_==0)
+   {
+      nEdges_ = 1;
+      edgelist_ = tedge;
+      crtedge_ = tedge;
+   }
+   else
+   {
+      nEdges_++;
+      crtedge_->next_ = tedge;
+      crtedge_ = tedge;
+   }
+}
+
+void BgEdgeList::AddEdge(int* edge, int nPoints)
+{
+   BgEdge* tedge;
+   tedge = new BgEdge();
+   tedge->SetPoints(edge, nPoints);
+   if (nEdges_==0)
+   {
+      nEdges_ = 1;
+      edgelist_ = tedge;
+      crtedge_ = tedge;
+   }
+   else
+   {
+      nEdges_++;
+      crtedge_->next_ = tedge;
+      crtedge_ = tedge;
+   }
+}
+
+void BgEdgeList::SetGradient(float* grx, float* gry, float* mark, int ncol)
+{
+   BgEdge* it;
+   int i;
+
+   it=edgelist_;
+   for (i=0; i<nEdges_; i++)
+   {
+      it->SetGradient(grx, gry, mark, ncol);
+      it = it->next_;
+   }
+}
+
+void BgEdgeList::RemoveShortEdges(int minp)
+{
+   if (nEdges_==0)
+      return;
+
+   int nEdges=nEdges_;
+   BgEdge* it1;
+   BgEdge* it2;
+   it1 = edgelist_;
+   it2 = it1->next_;
+
+   for (int i=1; i<nEdges_; i++)
+   {
+      if (it2->nPoints_ < minp)
+      {
+         it1->next_ = it2->next_;
+         delete it2;
+         it2 = it1->next_;
+         nEdges--;
+      }
+      else
+      {
+         it1 = it2;
+         it2 = it1->next_;
+      }
+   }
+
+   if (edgelist_->nPoints_ < minp)
+   {
+      it1 = edgelist_;
+      edgelist_ = edgelist_->next_;
+      delete it1;
+      nEdges--;
+   }
+   nEdges_=nEdges;
+}
+
+void BgEdgeList::SetBinImage(BgImage* image)
+{
+   int i, j;
+   int ix, iy;
+   int x, y;
+   
+   x = image->x_;
+   y = image->y_;
+   unsigned char* im=image->im_;
+   
+   for (i=0; i<x; i++)
+   {
+      for (j=0;j<y;j++)
+      {
+         *(im++) = 0;
+      }
+   }
+   
+   im = image->im_;
+   int* ite;
+   crtedge_=edgelist_;
+   for (i=0; i<nEdges_; i++)
+   {
+      ite = crtedge_->edge_;
+      for (j=0; j<crtedge_->nPoints_; j++)
+      {
+         ix = *(ite++);
+         iy = *(ite++);
+         *(im+iy*x+ix) = 255;
+      }
+      crtedge_=crtedge_->next_;
+   }
+}
+
+bool BgEdgeList::SaveEdgeList(char* edgeFile)
+{
+   int length;
+   int i,j;
+   BgEdge *crtedge;
+   
+   FILE* fp;
+   fp=fopen(edgeFile,"wb");
+   crtedge = edgelist_;
+   for (i=0; i<nEdges_; i++)
+   {
+      length = crtedge->nPoints_;
+      for (j=0; j<length; j++)
+      {
+         fprintf(fp, "%d %d %d\n", *((crtedge->edge_)+2*j), *((crtedge->edge_)+2*j+1), i);
+      }
+      crtedge = crtedge->next_;
+   }
+   fclose(fp);
+   return true;
+}
+
+void BgEdgeList::GetAllEdgePoints(int* x, int* y, int* n)
+{
+   int length;
+   int i,j;
+   BgEdge *crtedge;
+   int *edgep;
+   
+   crtedge = edgelist_;
+   *n = 0;
+   for (i=0; i<nEdges_; i++)
+   {
+      length = crtedge->nPoints_;
+      edgep = crtedge->edge_;
+      for (j=0; j<length; j++)
+      {
+         x[*n] = edgep[2*j];
+         y[*n] = edgep[2*j+1];
+         (*n)++;
+      }
+      crtedge = crtedge->next_;
+   }
+}
+
+void BgEdgeList::SetNoMark(void)
+{
+   int length;
+   int i,j;
+   BgEdge* crtedge;
+   unsigned char* mark;
+   crtedge = edgelist_;
+   for (i=0; i<nEdges_; i++)
+   {
+      length = crtedge->nPoints_;
+      mark = crtedge->mark_ = new unsigned char[length];
+      crtedge->isMarkSet_ = true;
+      for (j=0; j<length; j++)
+      {
+         *(mark+j) = 0;
+      }
+      crtedge = crtedge->next_;
+   }
+}
diff --git a/Utilities/otbedison/edge/BgEdgeList.h b/Utilities/otbedison/edge/BgEdgeList.h
old mode 100755
new mode 100644
index d20c462b9c4b38aaf9abf97ba9c63e5a03724bc4..92f34f00f4876a57d5a266cfa4fec531462a48f9
--- a/Utilities/otbedison/edge/BgEdgeList.h
+++ b/Utilities/otbedison/edge/BgEdgeList.h
@@ -1,29 +1,29 @@
-/////////////////////////////////////////////////////////////////////////////

-// Name:        BgEdgeList.h

-// Purpose:     BgEdgeList class

-// Author:      Bogdan Georgescu

-// Modified by:

-// Created:     06/22/2000

-// Copyright:   (c) Bogdan Georgescu

-// Version:     v0.1

-/////////////////////////////////////////////////////////////////////////////

-

-class BgEdgeList

-{

-public:

-   int nEdges_;

-   BgEdge* edgelist_;

-   BgEdge* crtedge_;

-   

-   BgEdgeList();

-   ~BgEdgeList();

-   void AddEdge(float*, int);

-   void AddEdge(int*, int nPoints);

-   void RemoveShortEdges(int);

-   void SetBinImage(BgImage*);

-   bool SaveEdgeList(char*);

-   void SetGradient(float*, float*, float*, int);

-   void SetNoMark(void);

-   void GetAllEdgePoints(int*, int*, int*);

-

-};

+/////////////////////////////////////////////////////////////////////////////
+// Name:        BgEdgeList.h
+// Purpose:     BgEdgeList class
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+class BgEdgeList
+{
+public:
+   int nEdges_;
+   BgEdge* edgelist_;
+   BgEdge* crtedge_;
+   
+   BgEdgeList();
+   ~BgEdgeList();
+   void AddEdge(float*, int);
+   void AddEdge(int*, int nPoints);
+   void RemoveShortEdges(int);
+   void SetBinImage(BgImage*);
+   bool SaveEdgeList(char*);
+   void SetGradient(float*, float*, float*, int);
+   void SetNoMark(void);
+   void GetAllEdgePoints(int*, int*, int*);
+
+};
diff --git a/Utilities/otbedison/edge/BgGlobalFc.cpp b/Utilities/otbedison/edge/BgGlobalFc.cpp
old mode 100755
new mode 100644
index c94c6f143abe94e6eaef13801b04c42303f8b7b4..f2fcf3b284566f1aca56e709821ca8c1ac2eefdf
--- a/Utilities/otbedison/edge/BgGlobalFc.cpp
+++ b/Utilities/otbedison/edge/BgGlobalFc.cpp
@@ -7,29 +7,29 @@
 // Copyright:   (c) Bogdan Georgescu
 // Version:     v0.1
 /////////////////////////////////////////////////////////////////////////////
-
+
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
 #include "BgDefaults.h"
-// !!! only MSV
-#include <sys/timeb.h>
-#include <time.h>
-
+// !!! only MSV
+#include <sys/timeb.h>
+#include <time.h>
+
 double bgSign(double x)
 {
    if (x>=0)
       return 1.0;
    return -1.0;
 }
-
+
 double factorial(double num)
 {
    if (num==0 || num==1)
       return 1;
    return (num * factorial(num - 1));
 }
-
+
 // return 0 - error
 // return 1 - one real solution
 // return 3 - three real solutions
@@ -37,18 +37,18 @@ int bgSolveCubic(double a, double b, double c, double d, double& s1, double& s2,
 {
    double p, q;
    double r, s, t, z;
-
+
    // convert to canonical form
    r = b/a;
    s = c/a;
    t = d/a;
    p = s-(r*r)/3.0;
    q = (2*r*r*r)/27.0-(r*s)/3.0+t;
-
+
    double D, phi, R;
    R = bgSign(q)*sqrt(fabs(p)/3.0);
    D = pow(p/3.0,3)+pow(q/2,2);
-
+
    if (p<0)
    {
       if (D<=0)
@@ -73,18 +73,18 @@ int bgSolveCubic(double a, double b, double c, double d, double& s1, double& s2,
       phi = log(z+sqrt(z*z+1));
       s1 = -2*R*sinh(phi/3)-r/3;
       return 1;
-   }
+   }
 
    return 0;
 }
-
 
-
+
+
 inline int bgRound(double in_x)
 {
   return int(floor(in_x + 0.5));
 }
-
+
 inline int bgRoundSign(double in_x)
 {
    if (in_x>=0)
@@ -96,7 +96,7 @@ inline int bgRoundSign(double in_x)
       return ((int) (in_x - 0.5));
    }
 }
-
+
 void bgSort(double* ra, int nVec)
 {
    unsigned long n, l, ir, i, j;
@@ -105,7 +105,7 @@ void bgSort(double* ra, int nVec)
    
    if (n<2)
       return;
-
+
    l = (n>>1)+1;
    ir = n;
    for (;;)
@@ -142,7 +142,7 @@ void bgSort(double* ra, int nVec)
       ra[i-1] = rra;
    }
 }
-
+
 // rank in 0-1 range, 0 min, 1 max
 // inplace sort vec
 double bgMedian(double* vec, int nVec, double rank)
@@ -153,22 +153,22 @@ double bgMedian(double* vec, int nVec, double rank)
       krank = nVec-1;
    return vec[krank];
 }
-
+
 double bgMedianToSigmaGaussian(double med)
 {
   return med * 1.482602219;
 }
-
+
 int write_pgm_image(const char *outfilename, unsigned char *image, int rows,
     int cols, char *comment, int maxval)
 {
    FILE *fp;
-
+
    /***************************************************************************
    * Open the output image file for writing if a filename was given. If no
    * filename was provided, set fp to write to standard output.
    ***************************************************************************/
-
+
    if(outfilename == NULL) fp = stdout;
    else{
       if((fp = fopen(outfilename, "wb")) == NULL){
@@ -177,291 +177,291 @@ int write_pgm_image(const char *outfilename, unsigned char *image, int rows,
          return(0);
       }
    }
-
+
    /***************************************************************************
    * Write the header information to the PGM file.
    ***************************************************************************/
-
+
    fprintf(fp, "P5\n%d %d\n", cols, rows);
    if(comment != NULL)
       if(strlen(comment) <= 70) fprintf(fp, "# %s\n", comment);
    fprintf(fp, "%d\n", maxval);
-
+
    /***************************************************************************
    * Write the image data to the file.
    ***************************************************************************/
-
+
    if(rows != fwrite(image, cols, rows, fp)){
       fprintf(stderr, "Error writing the image data in write_pgm_image().\n");
       if(fp != stdout) fclose(fp);
       return(0);
    }
-
+
    if(fp != stdout) fclose(fp);
    return(1);
-}
-
-
-void write_MATLAB_ASCII(char *filename, float *data, int rows, int cols)
-{
-	FILE *fp	= fopen(filename, "wb");
-	int i,j;
-	for(i = 0; i < rows; i++)
-	{
-		for(j = 0; j < cols-1; j++)
-		{
-			fprintf(fp, "%10.6f ", data[i*rows+j]);
-		}
-		fprintf(fp, "%10.6f\n", data[i*rows+cols-1]);
-	}
-	fclose(fp);
-}
-
-/*
-struct _timeb timestart;
-struct _timeb timeend;
-void timer_start()
-{
-   _ftime( &timestart );
-   bgLog("timer start...\n");
-}
-void timer_stop()
-{
-   _ftime( &timeend );
-
-   unsigned long seconds;
-   unsigned long milliseconds;
-   seconds = timeend.time - timestart.time;
-   long msdif;
-   msdif = timeend.millitm - timestart.millitm;
-   if (msdif > 0)
-      milliseconds = msdif;
-   else
-   {
-      seconds--;
-      milliseconds = (timeend.millitm + 1000) - timestart.millitm;
-   }
-
-   bgLog("timer stop, elapsed %d.%d seconds.\n", seconds, milliseconds);
-}
-*/
-time_t timestart;
-time_t timeend;
-void timer_start()
-{
-   timestart = clock();
-   bgLog("timer start...\n");
-}
-void timer_stop()
-{
-   timeend = clock();
-   unsigned long seconds, milliseconds;
-   seconds = (timeend-timestart)/CLOCKS_PER_SEC;
-   milliseconds = ((100*(timeend-timestart))/CLOCKS_PER_SEC) - 100*seconds;
-   bgLog("timer stop, elapsed %d.%d seconds.\n", seconds, milliseconds);
-}
-
-
-/********************************************/
-/*				Image Sampling				*/
-/********************************************/
-
-//zooms into an image
-//pre : 
-//		- dest is the pre-allocated destination color image
-//		- src is the (w x h) source color image
-//		- zconst is an integer zoom constant from that is >= 1
-//		- interpolate is a flag that determines if interpolation
-//		  should occur
-//post: the src image has been zoomed by (zconst)x and stored into dest
-void bgZoomIn(unsigned char **dest, unsigned char *src, int w, int h, int zconst, bool interpolate)
-{
-
-	//if dest or src is NULL or zconst is < 1 exit
-	if((!(*dest))||(!src)||(zconst < 1))
-		return;
-
-	//if zconst = 1 then copy the image contents and return
-	if(zconst == 1)
-	{
-		memcpy(*dest, src, 3*w*h*sizeof(unsigned char));
-		return;
-	}
-
-	//calculate new image dimension
-	w	*= zconst;
-	h	*= zconst;
-
-	//copy image data from source image to destination image
-
-	//******************************************************//
-
-	unsigned char *dptr	= (*dest);
-
-	int i, j, x, y, dp, offset, factor, index;
-	index = 0;
-	//zconst does not divide evenly into image width
-	if(factor = w%zconst)
-	{
-		for(j=0; j<(h-zconst); j+=zconst)
-		{
-			for(i=0; i<(w-zconst); i+=zconst)
-			{
-				dp	= 3*(j*w+i);
-				for(y=0; y<zconst; y++)
-				{
-					for(x=0; x<zconst; x++)
-					{
-						offset	= 3*(y*w+x);
-						dptr[dp+offset  ]	= src[index  ];
-						dptr[dp+offset+1]	= src[index+1];
-						dptr[dp+offset+2]	= src[index+2];
-					}
-				}
-
-				//next data point
-				index	+= 3;
-			}
-
-			dp	= 3*(j*w+i);
-			for(y=0; y<(zconst-factor-1); y++)
-			{
-				for(x=0; x<(zconst-factor-1); x++)
-				{
-					offset	= 3*(y*w+x);
-					dptr[dp+offset  ]	= src[index  ];
-					dptr[dp+offset+1]	= src[index+1];
-					dptr[dp+offset+2]	= src[index+2];
-				}
-			}
-
-			//next data point
-			index	+= 3;
-		}
-	}
-	//zconst does divide evenly into image width
-	else
-	{
-		for(j=0; j<(h-zconst); j+=zconst)
-		{
-			for(i=0; i<(w); i+=zconst)
-			{
-				dp	= 3*(j*w+i);
-				for(y=0; y<zconst; y++)
-				{
-					for(x=0; x<zconst; x++)
-					{
-						offset	= 3*(y*w+x);
-						dptr[dp+offset  ]	= src[index  ];
-						dptr[dp+offset+1]	= src[index+1];
-						dptr[dp+offset+2]	= src[index+2];
-					}
-				}
-
-				//next data point
-				index	+= 3;
-			}
-		}
-	}
-
-	//consider last row of image
-	factor	= h%zconst;
-	dp		= 3*(h-zconst)*(w);
-	for(i=0; i<(w); i+=zconst)
-	{
-		for(y=0; y<(zconst-factor); y++)
-		{
-			for(x=0; x<(zconst-factor); x++)
-			{
-				offset	= 3*(y*w+x);
-				dptr[dp+offset  ]	= src[index  ];
-				dptr[dp+offset+1]	= src[index+1];
-				dptr[dp+offset+2]	= src[index+2];
-			}
-		}
-		//next data point
-		dp		+= zconst*3;
-		index	+= 3;
-	}
-
-	//******************************************************//
-
-	//done.
-	return;
-
-}
-
-//zooms out of an image
-//pre : 
-//		- dest is the pre-allocated destination color image
-//		- src is the (w x h) source color image
-//		- zconst is an integer zoom constant from that is >= 1
-//		- interpolate is a flag that determines if interpolation
-//		  should occur
-//post: the src image has been zoomed by (1/zconst)x and stored into dest
-void bgZoomOut(unsigned char **dest, unsigned char *src, int w, int h, int zconst, bool interpolate)
-{
-
-	//if dest or src is NULL or zconst is <= 1 exit
-	if((!(*dest))||(!src)||(zconst <= 1))
-		return;
-
-	//copy image data from source image to destination image
-
-	//******************************************************//
-
-	unsigned char *dptr	= (*dest);
-
-	int i, j, dp, index;
-	index = 0;
-	for(j=0; j<h; j+=zconst)
-	{
-		for(i=0; i<w; i+=zconst)
-		{
-			dp	= 3*(j*w+i);
-			dptr[index  ]	= src[dp  ];
-			dptr[index+1]	= src[dp+1];
-			dptr[index+2]	= src[dp+2];
-		
-			//next data point
-			index	+= 3;
-		}
-	}
-
-	//******************************************************//
-
-	//done.
-	return;
-
-}
-
-/************************************/
-/*       Filename Manipulation      */
-/************************************/
-
-//adds an extension (label) to a filename
-void BgAddExtension(char **filename, char *label)
-{
-	//allocate memory for new filename
-	char *new_filename	= new char [strlen(*filename) + strlen(label) + 1], ext[5];
-
-	//copy filename
-	strcpy(new_filename, *filename);
-
-	//get extension of filename (e.g. '.txt')
-	char *pdest = strchr(new_filename, '.');
-	strcpy(ext, pdest);
-
-	//place filename label at the end of the filename
-	//followed by extension...
-	strcpy(pdest, label);
-	strcat(new_filename, ext);
-
-	//delete old filename and replace it with new one...
-	delete *filename;
-	(*filename)	= new_filename;
-
-	//done.
-	return;
-}
-
+}
+
+
+void write_MATLAB_ASCII(char *filename, float *data, int rows, int cols)
+{
+	FILE *fp	= fopen(filename, "wb");
+	int i,j;
+	for(i = 0; i < rows; i++)
+	{
+		for(j = 0; j < cols-1; j++)
+		{
+			fprintf(fp, "%10.6f ", data[i*rows+j]);
+		}
+		fprintf(fp, "%10.6f\n", data[i*rows+cols-1]);
+	}
+	fclose(fp);
+}
+
+/*
+struct _timeb timestart;
+struct _timeb timeend;
+void timer_start()
+{
+   _ftime( &timestart );
+   bgLog("timer start...\n");
+}
+void timer_stop()
+{
+   _ftime( &timeend );
+
+   unsigned long seconds;
+   unsigned long milliseconds;
+   seconds = timeend.time - timestart.time;
+   long msdif;
+   msdif = timeend.millitm - timestart.millitm;
+   if (msdif > 0)
+      milliseconds = msdif;
+   else
+   {
+      seconds--;
+      milliseconds = (timeend.millitm + 1000) - timestart.millitm;
+   }
+
+   bgLog("timer stop, elapsed %d.%d seconds.\n", seconds, milliseconds);
+}
+*/
+time_t timestart;
+time_t timeend;
+void timer_start()
+{
+   timestart = clock();
+   bgLog("timer start...\n");
+}
+void timer_stop()
+{
+   timeend = clock();
+   unsigned long seconds, milliseconds;
+   seconds = (timeend-timestart)/CLOCKS_PER_SEC;
+   milliseconds = ((100*(timeend-timestart))/CLOCKS_PER_SEC) - 100*seconds;
+   bgLog("timer stop, elapsed %d.%d seconds.\n", seconds, milliseconds);
+}
+
+
+/********************************************/
+/*				Image Sampling				*/
+/********************************************/
+
+//zooms into an image
+//pre : 
+//		- dest is the pre-allocated destination color image
+//		- src is the (w x h) source color image
+//		- zconst is an integer zoom constant from that is >= 1
+//		- interpolate is a flag that determines if interpolation
+//		  should occur
+//post: the src image has been zoomed by (zconst)x and stored into dest
+void bgZoomIn(unsigned char **dest, unsigned char *src, int w, int h, int zconst, bool interpolate)
+{
+
+	//if dest or src is NULL or zconst is < 1 exit
+	if((!(*dest))||(!src)||(zconst < 1))
+		return;
+
+	//if zconst = 1 then copy the image contents and return
+	if(zconst == 1)
+	{
+		memcpy(*dest, src, 3*w*h*sizeof(unsigned char));
+		return;
+	}
+
+	//calculate new image dimension
+	w	*= zconst;
+	h	*= zconst;
+
+	//copy image data from source image to destination image
+
+	//******************************************************//
+
+	unsigned char *dptr	= (*dest);
+
+	int i, j, x, y, dp, offset, factor, index;
+	index = 0;
+	//zconst does not divide evenly into image width
+	if(factor = w%zconst)
+	{
+		for(j=0; j<(h-zconst); j+=zconst)
+		{
+			for(i=0; i<(w-zconst); i+=zconst)
+			{
+				dp	= 3*(j*w+i);
+				for(y=0; y<zconst; y++)
+				{
+					for(x=0; x<zconst; x++)
+					{
+						offset	= 3*(y*w+x);
+						dptr[dp+offset  ]	= src[index  ];
+						dptr[dp+offset+1]	= src[index+1];
+						dptr[dp+offset+2]	= src[index+2];
+					}
+				}
+
+				//next data point
+				index	+= 3;
+			}
+
+			dp	= 3*(j*w+i);
+			for(y=0; y<(zconst-factor-1); y++)
+			{
+				for(x=0; x<(zconst-factor-1); x++)
+				{
+					offset	= 3*(y*w+x);
+					dptr[dp+offset  ]	= src[index  ];
+					dptr[dp+offset+1]	= src[index+1];
+					dptr[dp+offset+2]	= src[index+2];
+				}
+			}
+
+			//next data point
+			index	+= 3;
+		}
+	}
+	//zconst does divide evenly into image width
+	else
+	{
+		for(j=0; j<(h-zconst); j+=zconst)
+		{
+			for(i=0; i<(w); i+=zconst)
+			{
+				dp	= 3*(j*w+i);
+				for(y=0; y<zconst; y++)
+				{
+					for(x=0; x<zconst; x++)
+					{
+						offset	= 3*(y*w+x);
+						dptr[dp+offset  ]	= src[index  ];
+						dptr[dp+offset+1]	= src[index+1];
+						dptr[dp+offset+2]	= src[index+2];
+					}
+				}
+
+				//next data point
+				index	+= 3;
+			}
+		}
+	}
+
+	//consider last row of image
+	factor	= h%zconst;
+	dp		= 3*(h-zconst)*(w);
+	for(i=0; i<(w); i+=zconst)
+	{
+		for(y=0; y<(zconst-factor); y++)
+		{
+			for(x=0; x<(zconst-factor); x++)
+			{
+				offset	= 3*(y*w+x);
+				dptr[dp+offset  ]	= src[index  ];
+				dptr[dp+offset+1]	= src[index+1];
+				dptr[dp+offset+2]	= src[index+2];
+			}
+		}
+		//next data point
+		dp		+= zconst*3;
+		index	+= 3;
+	}
+
+	//******************************************************//
+
+	//done.
+	return;
+
+}
+
+//zooms out of an image
+//pre : 
+//		- dest is the pre-allocated destination color image
+//		- src is the (w x h) source color image
+//		- zconst is an integer zoom constant from that is >= 1
+//		- interpolate is a flag that determines if interpolation
+//		  should occur
+//post: the src image has been zoomed by (1/zconst)x and stored into dest
+void bgZoomOut(unsigned char **dest, unsigned char *src, int w, int h, int zconst, bool interpolate)
+{
+
+	//if dest or src is NULL or zconst is <= 1 exit
+	if((!(*dest))||(!src)||(zconst <= 1))
+		return;
+
+	//copy image data from source image to destination image
+
+	//******************************************************//
+
+	unsigned char *dptr	= (*dest);
+
+	int i, j, dp, index;
+	index = 0;
+	for(j=0; j<h; j+=zconst)
+	{
+		for(i=0; i<w; i+=zconst)
+		{
+			dp	= 3*(j*w+i);
+			dptr[index  ]	= src[dp  ];
+			dptr[index+1]	= src[dp+1];
+			dptr[index+2]	= src[dp+2];
+		
+			//next data point
+			index	+= 3;
+		}
+	}
+
+	//******************************************************//
+
+	//done.
+	return;
+
+}
+
+/************************************/
+/*       Filename Manipulation      */
+/************************************/
+
+//adds an extension (label) to a filename
+void BgAddExtension(char **filename, char *label)
+{
+	//allocate memory for new filename
+	char *new_filename	= new char [strlen(*filename) + strlen(label) + 1], ext[5];
+
+	//copy filename
+	strcpy(new_filename, *filename);
+
+	//get extension of filename (e.g. '.txt')
+	char *pdest = strchr(new_filename, '.');
+	strcpy(ext, pdest);
+
+	//place filename label at the end of the filename
+	//followed by extension...
+	strcpy(pdest, label);
+	strcat(new_filename, ext);
+
+	//delete old filename and replace it with new one...
+	delete *filename;
+	(*filename)	= new_filename;
+
+	//done.
+	return;
+}
+
diff --git a/Utilities/otbedison/edge/BgImage.cpp b/Utilities/otbedison/edge/BgImage.cpp
old mode 100755
new mode 100644
index b206d7dac9580867d3a4d307fc074602b018e5aa..009774ed39f950bfd71705d83e1d4aab89679882
--- a/Utilities/otbedison/edge/BgImage.cpp
+++ b/Utilities/otbedison/edge/BgImage.cpp
@@ -1,373 +1,373 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        BgImage.cpp
-// Purpose:     BgImage class functions
-// Author:      Bogdan Georgescu
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu
-// Version:     v0.1
-/////////////////////////////////////////////////////////////////////////////
-
-#include "BgImage.h"
-
-BgImage::BgImage()
-{
-   hasIm_ = false;
-   colorIm_ = false;
-   im_ = 0;
-}
-
-BgImage::BgImage(int x,int y, bool colorIm)
-{
-   colorIm_ = colorIm;
-   if (colorIm_ == false)
-      im_ = new unsigned char[x*y];
-   else
-      im_ = new unsigned char[x*y*3];
-   x_ = x;
-   y_ = y;
-   hasIm_ = true;
-}
-
-BgImage::~BgImage()
-{
-   CleanData();
-}
-
-void BgImage::CleanData()
-{
-   if (hasIm_)
-   {
-      delete [] im_;
-      x_ = y_ = 0;
-      hasIm_ = false;
-      colorIm_ = false;
-   }
-}
-
-void BgImage::SetImage(unsigned char* im, int x, int y, bool colorIm)
-{
-   CleanData();
-   colorIm_ = colorIm;
-   if (colorIm_ == false)
-      im_ = new unsigned char[x*y];
-   else
-      im_ = new unsigned char[x*y*3];
-   x_ = x;
-   y_ = y;
-   hasIm_ = true;
-
-   int i;
-   unsigned char *its, *itd;
-   if (colorIm_ == false)
-   {
-      for (i=0, its=im, itd=im_; i<x*y; i++)
-      {
-         *(itd++) = *(its++);
-      }
-   }
-   else
-   {
-      for (i=0, its=im, itd=im_; i<x*y*3; i++)
-      {
-         *(itd++) = *(its++);
-      }
-   }
-
-}
-
-void BgImage::SetImageFromRGB(unsigned char* im, int x, int y, bool colorIm)
-{
-   PrivateResize(x, y, colorIm);
-
-   int i;
-   unsigned char *its, *itd;
-   if (colorIm_ == false)
-   {
-      for (i=0, its=im, itd=im_; i<x*y; i++, itd++, its+=3)
-	  {
-		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
-	  }
-   }
-   else
-   {
-      for (i=0, its=im, itd=im_; i<x*y*3; i++)
-         *(itd++) = *(its++);
-   }
-}
-
-void BgImage::SetSameImageFromRGB(unsigned char* im)
-{
-   int i;
-   unsigned char *its, *itd;
-   if (colorIm_ == false)
-   {
-      for (i=0, its=im, itd=im_; i<x_*y_; i++, itd++, its+=3)
-		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
-   }
-   else
-   {
-      for (i=0, its=im, itd=im_; i<x_*y_*3; i++)
-         *(itd++) = *(its++);
-   }
-}
-
-void BgImage::SetImage(short* im, int x, int y, bool colorIm)
-{
-   CleanData();
-   colorIm_ = colorIm;
-   if (colorIm_ == false)
-      im_ = new unsigned char[x*y];
-   else
-      im_ = new unsigned char[x*y*3];
-   x_ = x;
-   y_ = y;
-   hasIm_ = true;
-
-   int i;
-   unsigned char *itd;
-   short* its;
-   if (colorIm_ == false)
-   {
-      for (i=0, its=im, itd=im_; i<x*y; i++)
-      {
-         *(itd++) = (unsigned char) *(its++);
-      }
-   }
-   else
-   {
-      for (i=0, its=im, itd=im_; i<x*y*3; i++)
-      {
-         *(itd++) = (unsigned char) *(its++);
-      }
-   }
-}
-
-void BgImage::GetImage(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-         *(itd++) = *(its++);
-   }
-   else
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_*3; i++)
-         *(itd++) = *(its++);
-   }
-}
-
-void BgImage::GetImageColor(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-      {
-         *(itd++) = *its;
-         *(itd++) = *its;
-         *(itd++) = *(its++);
-      }
-   }
-   else
-   {
-      for(i=0, its=im_, itd=im; i<(x_*y_*3); i++)
-         *(itd++) = *(its++);
-   }
-}
-
-void BgImage::GetImageBW(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-         *(itd++) = *(its++);
-   }
-   else
-   {
-      for (i=0, its=im_, itd=im; i<x_*y_; i++, itd++, its+=3)
-		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
-   }
-}
-
-void BgImage::GetImageR(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-         *(itd++) = *(its++);
-   }
-   else
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-      {
-         *(itd++) = *its;
-         its += 3;
-      }
-   }
-}
-
-void BgImage::GetImageG(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-         *(itd++) = *(its++);
-   }
-   else
-   {
-      for(i=0, its=im_+1, itd=im; i<x_*y_; i++)
-      {
-         *(itd++) = *its;
-         its += 3;
-      }
-   }
-}
-
-void BgImage::GetImageB(unsigned char* im)
-{
-   unsigned char *its, *itd;
-   int i;
-   if (colorIm_ == false)
-   {
-      for(i=0, its=im_, itd=im; i<x_*y_; i++)
-         *(itd++) = *(its++);
-   }
-   else
-   {
-      for(i=0, its=im_+2, itd=im; i<x_*y_; i++)
-      {
-         *(itd++) = *its;
-         its += 3;
-      }
-   }
-}
-
-inline unsigned char BgImage::operator()(int r, int c) const
-{
-   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
-   return im_[c+r*x_];
-}
-
-inline unsigned char& BgImage::operator()(int r, int c)
-{
-   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
-   return im_[c+r*x_];
-}
-
-unsigned char BgImage::PixelValue(int r, int c)
-{
-   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
-   return im_[c+r*x_];
-}
-
-inline unsigned char gBgImPt(BgImage* in_im, int in_r, int in_c)
-{
-   assert(in_im->hasIm_ && (in_r >= 0) && (in_r < in_im->y_) && (in_c >= 0) && (in_c < in_im->x_));
-   return in_im->im_[in_c+in_r*in_im->x_];
-}
-
-bool BgImage::ValidCoord(int in_x, int in_y)
-{
-   return ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_));
-}
-
-int BgImage::ValidReturnBW(int in_x, int in_y, int& cval)
-{
-   if ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_)) 
-   {
-      cval = im_[in_x+in_y*x_];
-      return 1;
-   } else
-   {
-      cval = -1;
-      return 0;
-   }
-}
-int BgImage::ValidReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval)
-{
-   if ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_)) 
-   {
-      rval = im_[in_x*3+0+in_y*(x_*3)];
-      gval = im_[in_x*3+1+in_y*(x_*3)];
-      bval = im_[in_x*3+2+in_y*(x_*3)];
-
-      return 1;
-   } else
-   {
-      rval = gval = bval = -1;
-      return 0;
-   }
-}
-
-int BgImage::ReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval)
-{
-   rval = im_[in_x*3+0+in_y*(x_*3)];
-   gval = im_[in_x*3+1+in_y*(x_*3)];
-   bval = im_[in_x*3+2+in_y*(x_*3)];
-   return 1;
-}
-
-bool BgImage::IsAllocated(void) const
-{
-   return hasIm_;
-}
-
-const BgImage& BgImage::operator=(const BgImage& im)
-{
-   if (this == &im)
-      return *this;
-   
-   if (!im.IsAllocated())
-   {
-      CleanData();
-      return *this;
-   }
-   
-   PrivateCopyToThis(im);
-   return *this;
-}
-
-void BgImage::PrivateCopyToThis(const BgImage& im)
-{
-   PrivateResize(im.x_, im.y_, im.colorIm_);
-   int ncopy, i;
-   ncopy = x_*y_;
-   if (colorIm_ == true)
-      ncopy *= 3;
-
-   unsigned char *src;
-   src = im.im_;
-   for (i=0; i<ncopy; i++)
-      im_[i] = src[i];
-}
-
-void BgImage::PrivateResize(int width, int height, bool color)
-{
-   if ((hasIm_ == false) || (width != x_) || (height != y_) || (color != colorIm_))
-   {
-      CleanData();
-      x_ = width;
-      y_ = height;
-      colorIm_ = color;
-      if (color == false)
-         im_ = new unsigned char[x_*y_];
-      else
-         im_ = new unsigned char[x_*y_*3];
-      hasIm_ = true;
-   }
-}
-
-void BgImage::Resize(int width, int height, bool color)
-{
-   PrivateResize(width, height, color);
-}
+/////////////////////////////////////////////////////////////////////////////
+// Name:        BgImage.cpp
+// Purpose:     BgImage class functions
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+#include "BgImage.h"
+
+BgImage::BgImage()
+{
+   hasIm_ = false;
+   colorIm_ = false;
+   im_ = 0;
+}
+
+BgImage::BgImage(int x,int y, bool colorIm)
+{
+   colorIm_ = colorIm;
+   if (colorIm_ == false)
+      im_ = new unsigned char[x*y];
+   else
+      im_ = new unsigned char[x*y*3];
+   x_ = x;
+   y_ = y;
+   hasIm_ = true;
+}
+
+BgImage::~BgImage()
+{
+   CleanData();
+}
+
+void BgImage::CleanData()
+{
+   if (hasIm_)
+   {
+      delete [] im_;
+      x_ = y_ = 0;
+      hasIm_ = false;
+      colorIm_ = false;
+   }
+}
+
+void BgImage::SetImage(unsigned char* im, int x, int y, bool colorIm)
+{
+   CleanData();
+   colorIm_ = colorIm;
+   if (colorIm_ == false)
+      im_ = new unsigned char[x*y];
+   else
+      im_ = new unsigned char[x*y*3];
+   x_ = x;
+   y_ = y;
+   hasIm_ = true;
+
+   int i;
+   unsigned char *its, *itd;
+   if (colorIm_ == false)
+   {
+      for (i=0, its=im, itd=im_; i<x*y; i++)
+      {
+         *(itd++) = *(its++);
+      }
+   }
+   else
+   {
+      for (i=0, its=im, itd=im_; i<x*y*3; i++)
+      {
+         *(itd++) = *(its++);
+      }
+   }
+
+}
+
+void BgImage::SetImageFromRGB(unsigned char* im, int x, int y, bool colorIm)
+{
+   PrivateResize(x, y, colorIm);
+
+   int i;
+   unsigned char *its, *itd;
+   if (colorIm_ == false)
+   {
+      for (i=0, its=im, itd=im_; i<x*y; i++, itd++, its+=3)
+	  {
+		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
+	  }
+   }
+   else
+   {
+      for (i=0, its=im, itd=im_; i<x*y*3; i++)
+         *(itd++) = *(its++);
+   }
+}
+
+void BgImage::SetSameImageFromRGB(unsigned char* im)
+{
+   int i;
+   unsigned char *its, *itd;
+   if (colorIm_ == false)
+   {
+      for (i=0, its=im, itd=im_; i<x_*y_; i++, itd++, its+=3)
+		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
+   }
+   else
+   {
+      for (i=0, its=im, itd=im_; i<x_*y_*3; i++)
+         *(itd++) = *(its++);
+   }
+}
+
+void BgImage::SetImage(short* im, int x, int y, bool colorIm)
+{
+   CleanData();
+   colorIm_ = colorIm;
+   if (colorIm_ == false)
+      im_ = new unsigned char[x*y];
+   else
+      im_ = new unsigned char[x*y*3];
+   x_ = x;
+   y_ = y;
+   hasIm_ = true;
+
+   int i;
+   unsigned char *itd;
+   short* its;
+   if (colorIm_ == false)
+   {
+      for (i=0, its=im, itd=im_; i<x*y; i++)
+      {
+         *(itd++) = (unsigned char) *(its++);
+      }
+   }
+   else
+   {
+      for (i=0, its=im, itd=im_; i<x*y*3; i++)
+      {
+         *(itd++) = (unsigned char) *(its++);
+      }
+   }
+}
+
+void BgImage::GetImage(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+         *(itd++) = *(its++);
+   }
+   else
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_*3; i++)
+         *(itd++) = *(its++);
+   }
+}
+
+void BgImage::GetImageColor(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+      {
+         *(itd++) = *its;
+         *(itd++) = *its;
+         *(itd++) = *(its++);
+      }
+   }
+   else
+   {
+      for(i=0, its=im_, itd=im; i<(x_*y_*3); i++)
+         *(itd++) = *(its++);
+   }
+}
+
+void BgImage::GetImageBW(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+         *(itd++) = *(its++);
+   }
+   else
+   {
+      for (i=0, its=im_, itd=im; i<x_*y_; i++, itd++, its+=3)
+		 *itd = (int) (its[0]*RED_WEIGHT + its[1]*GREEN_WEIGHT + its[2]*BLUE_WEIGHT);
+   }
+}
+
+void BgImage::GetImageR(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+         *(itd++) = *(its++);
+   }
+   else
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+      {
+         *(itd++) = *its;
+         its += 3;
+      }
+   }
+}
+
+void BgImage::GetImageG(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+         *(itd++) = *(its++);
+   }
+   else
+   {
+      for(i=0, its=im_+1, itd=im; i<x_*y_; i++)
+      {
+         *(itd++) = *its;
+         its += 3;
+      }
+   }
+}
+
+void BgImage::GetImageB(unsigned char* im)
+{
+   unsigned char *its, *itd;
+   int i;
+   if (colorIm_ == false)
+   {
+      for(i=0, its=im_, itd=im; i<x_*y_; i++)
+         *(itd++) = *(its++);
+   }
+   else
+   {
+      for(i=0, its=im_+2, itd=im; i<x_*y_; i++)
+      {
+         *(itd++) = *its;
+         its += 3;
+      }
+   }
+}
+
+inline unsigned char BgImage::operator()(int r, int c) const
+{
+   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
+   return im_[c+r*x_];
+}
+
+inline unsigned char& BgImage::operator()(int r, int c)
+{
+   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
+   return im_[c+r*x_];
+}
+
+unsigned char BgImage::PixelValue(int r, int c)
+{
+   assert(hasIm_ && (r >= 0) && (r < y_) && (c >= 0) && (c < x_));
+   return im_[c+r*x_];
+}
+
+inline unsigned char gBgImPt(BgImage* in_im, int in_r, int in_c)
+{
+   assert(in_im->hasIm_ && (in_r >= 0) && (in_r < in_im->y_) && (in_c >= 0) && (in_c < in_im->x_));
+   return in_im->im_[in_c+in_r*in_im->x_];
+}
+
+bool BgImage::ValidCoord(int in_x, int in_y)
+{
+   return ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_));
+}
+
+int BgImage::ValidReturnBW(int in_x, int in_y, int& cval)
+{
+   if ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_)) 
+   {
+      cval = im_[in_x+in_y*x_];
+      return 1;
+   } else
+   {
+      cval = -1;
+      return 0;
+   }
+}
+int BgImage::ValidReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval)
+{
+   if ((in_x>=0) && (in_x<x_) && (in_y>=0) && (in_y<y_)) 
+   {
+      rval = im_[in_x*3+0+in_y*(x_*3)];
+      gval = im_[in_x*3+1+in_y*(x_*3)];
+      bval = im_[in_x*3+2+in_y*(x_*3)];
+
+      return 1;
+   } else
+   {
+      rval = gval = bval = -1;
+      return 0;
+   }
+}
+
+int BgImage::ReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval)
+{
+   rval = im_[in_x*3+0+in_y*(x_*3)];
+   gval = im_[in_x*3+1+in_y*(x_*3)];
+   bval = im_[in_x*3+2+in_y*(x_*3)];
+   return 1;
+}
+
+bool BgImage::IsAllocated(void) const
+{
+   return hasIm_;
+}
+
+const BgImage& BgImage::operator=(const BgImage& im)
+{
+   if (this == &im)
+      return *this;
+   
+   if (!im.IsAllocated())
+   {
+      CleanData();
+      return *this;
+   }
+   
+   PrivateCopyToThis(im);
+   return *this;
+}
+
+void BgImage::PrivateCopyToThis(const BgImage& im)
+{
+   PrivateResize(im.x_, im.y_, im.colorIm_);
+   int ncopy, i;
+   ncopy = x_*y_;
+   if (colorIm_ == true)
+      ncopy *= 3;
+
+   unsigned char *src;
+   src = im.im_;
+   for (i=0; i<ncopy; i++)
+      im_[i] = src[i];
+}
+
+void BgImage::PrivateResize(int width, int height, bool color)
+{
+   if ((hasIm_ == false) || (width != x_) || (height != y_) || (color != colorIm_))
+   {
+      CleanData();
+      x_ = width;
+      y_ = height;
+      colorIm_ = color;
+      if (color == false)
+         im_ = new unsigned char[x_*y_];
+      else
+         im_ = new unsigned char[x_*y_*3];
+      hasIm_ = true;
+   }
+}
+
+void BgImage::Resize(int width, int height, bool color)
+{
+   PrivateResize(width, height, color);
+}
diff --git a/Utilities/otbedison/edge/BgImage.h b/Utilities/otbedison/edge/BgImage.h
old mode 100755
new mode 100644
index bf62e303886fcd1038d9fd23c20517372d5a90ae..127aea8759086c242ea37b170fbb2ea6666ba012
--- a/Utilities/otbedison/edge/BgImage.h
+++ b/Utilities/otbedison/edge/BgImage.h
@@ -1,74 +1,74 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        BgImage.h
-// Purpose:     BgImage class
-// Author:      Bogdan Georgescu
-// Modified by:
-// Created:     06/22/2000
-// Copyright:   (c) Bogdan Georgescu
-// Version:     v0.1
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef _BG_IMAGE_H
-#define _BG_IMAGE_H
-
-#include <assert.h>
-
-#define RED_WEIGHT 0.299
-#define GREEN_WEIGHT 0.587
-#define BLUE_WEIGHT 0.114
-
-class BgImage
-{
-public:
-   int x_;
-   int y_;
-   unsigned char* im_;
-   bool hasIm_;
-   bool colorIm_; // false - bw image
-                  // true  - color RGB image
-
-   BgImage();
-   BgImage(int, int, bool colorIm = false);
-   ~BgImage();
-
-   void SetImage(unsigned char*, int, int, bool colorIm = false);
-   void SetImageFromRGB(unsigned char*, int, int, bool colorIm = false);
-   void SetSameImageFromRGB(unsigned char*);
-   void SetImage(short*, int, int, bool colorIm = false);
-   void GetImage(unsigned char*);
-   void GetImageBW(unsigned char*);
-   void GetImageColor(unsigned char*);
-   void GetImageR(unsigned char*);
-   void GetImageG(unsigned char*);
-   void GetImageB(unsigned char*);
-   bool ValidCoord(int, int);
-   int ValidReturnBW(int in_x, int in_y, int& cval);
-   int ValidReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval);
-   int ReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval);
-
-   inline int GetWidth() {return x_;};
-   inline int GetHeight() {return y_;};
-
-
-   const BgImage& operator=(const BgImage& im);
-   bool IsAllocated(void) const;
-
-   void CleanData();
-   inline unsigned char operator()(int, int) const;
-   inline unsigned char& operator()(int, int);
-   unsigned char PixelValue(int, int);
-
-   void Resize(int width, int height, bool color);
-
-private:
-   void PrivateCopyToThis(const BgImage& im);
-   void PrivateResize(int width, int height, bool color);
-
-
-};
-extern inline unsigned char gBgImPt(BgImage*, int, int);
-
-#endif
-
-
-
+/////////////////////////////////////////////////////////////////////////////
+// Name:        BgImage.h
+// Purpose:     BgImage class
+// Author:      Bogdan Georgescu
+// Modified by:
+// Created:     06/22/2000
+// Copyright:   (c) Bogdan Georgescu
+// Version:     v0.1
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _BG_IMAGE_H
+#define _BG_IMAGE_H
+
+#include <assert.h>
+
+#define RED_WEIGHT 0.299
+#define GREEN_WEIGHT 0.587
+#define BLUE_WEIGHT 0.114
+
+class BgImage
+{
+public:
+   int x_;
+   int y_;
+   unsigned char* im_;
+   bool hasIm_;
+   bool colorIm_; // false - bw image
+                  // true  - color RGB image
+
+   BgImage();
+   BgImage(int, int, bool colorIm = false);
+   ~BgImage();
+
+   void SetImage(unsigned char*, int, int, bool colorIm = false);
+   void SetImageFromRGB(unsigned char*, int, int, bool colorIm = false);
+   void SetSameImageFromRGB(unsigned char*);
+   void SetImage(short*, int, int, bool colorIm = false);
+   void GetImage(unsigned char*);
+   void GetImageBW(unsigned char*);
+   void GetImageColor(unsigned char*);
+   void GetImageR(unsigned char*);
+   void GetImageG(unsigned char*);
+   void GetImageB(unsigned char*);
+   bool ValidCoord(int, int);
+   int ValidReturnBW(int in_x, int in_y, int& cval);
+   int ValidReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval);
+   int ReturnCol(int in_x, int in_y, int& rval, int& gval, int& bval);
+
+   inline int GetWidth() {return x_;};
+   inline int GetHeight() {return y_;};
+
+
+   const BgImage& operator=(const BgImage& im);
+   bool IsAllocated(void) const;
+
+   void CleanData();
+   inline unsigned char operator()(int, int) const;
+   inline unsigned char& operator()(int, int);
+   unsigned char PixelValue(int, int);
+
+   void Resize(int width, int height, bool color);
+
+private:
+   void PrivateCopyToThis(const BgImage& im);
+   void PrivateResize(int width, int height, bool color);
+
+
+};
+extern inline unsigned char gBgImPt(BgImage*, int, int);
+
+#endif
+
+
+
diff --git a/Utilities/otbedison/prompt/defs.h b/Utilities/otbedison/prompt/defs.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/edison.cpp b/Utilities/otbedison/prompt/edison.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/edison.h b/Utilities/otbedison/prompt/edison.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/error.h b/Utilities/otbedison/prompt/error.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/flags.h b/Utilities/otbedison/prompt/flags.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/globalFnc.cpp b/Utilities/otbedison/prompt/globalFnc.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/imfilt.h b/Utilities/otbedison/prompt/imfilt.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/libppm.cpp b/Utilities/otbedison/prompt/libppm.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/libppm.h b/Utilities/otbedison/prompt/libppm.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/main.cpp b/Utilities/otbedison/prompt/main.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/parser.cpp b/Utilities/otbedison/prompt/parser.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/prompt/parser.h b/Utilities/otbedison/prompt/parser.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/segm/RAList.cpp b/Utilities/otbedison/segm/RAList.cpp
old mode 100755
new mode 100644
index eda5ddf02d0098bba36dd08de364c46a4f1b05b6..b5abe87552d64782fc7795e5a1829ad2380ce55c
--- a/Utilities/otbedison/segm/RAList.cpp
+++ b/Utilities/otbedison/segm/RAList.cpp
@@ -1,172 +1,172 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Region Adjacency List:
-  =====================
-
-	The Region Adjacency List class is used by the Image 
-	Processor class in the construction of a Region Adjacency
-	Matrix, used by	this class to applying transitive closure
-	and to prune spurious regions during image segmentation.
-
-	The definition of the RAList class is provided below. Its
-	prototype is provided in "RAList.h".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-//include Region Adjacency List class prototype
-#include	"RAList.h"
-
-//include needed libraries
-#include	<stdio.h>
-#include	<assert.h>
-#include	<stdlib.h>
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/* Class Constructor and Destructor */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Class Constructor                                    */
-/*******************************************************/
-/*Constructs a RAList object.                          */
-/*******************************************************/
-/*Post:                                                */
-/*      - a RAlist object has been properly constru-   */
-/*        cted.                                        */
-/*******************************************************/
-
-RAList::RAList( void )
-{
-	//initialize label and link
-	label			= -1;
-	next			= NULL;
-
-	//initialize edge strenght weight and count
-	edgeStrength	= 0;
-	edgePixelCount	= 0;
-}
-
-/*******************************************************/
-/*Class Destructor                                     */
-/*******************************************************/
-/*Destructrs a RAList object.                          */
-/*******************************************************/
-/*Post:                                                */
-/*      - the RAList object has been properly dest-    */
-/*        ructed.                                      */
-/*******************************************************/
-
-RAList::~RAList( void )
-{
-	//do nothing
-}
-
-/*******************************************************/
-/*Insert                                               */
-/*******************************************************/
-/*Insert a region node into the region adjacency list. */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - entry is a node representing a connected re- */
-/*        gion                                         */
-/*Post:                                                */
-/*      - entry has been inserted into the region adj- */
-/*        acency list if it does not already exist     */
-/*        there.                                       */
-/*      - if the entry already exists in the region    */
-/*        adjacency list 1 is returned otherwise 0 is  */
-/*        returned.                                    */
-/*******************************************************/
-
-int RAList::Insert(RAList *entry)
-{
-
-	//if the list contains only one element
-	//then insert this element into next
-	if(!next)
-	{
-		//insert entry
-		next		= entry;
-		entry->next = NULL;
-
-		//done
-		return 0;
-	}
-
-	//traverse the list until either:
-
-	//(a) entry's label already exists - do nothing
-	//(b) the list ends or the current label is
-	//    greater than entry's label, thus insert the entry
-	//    at this location
-
-	//check first entry
-	if(next->label > entry->label)
-	{
-		//insert entry into the list at this location
-		entry->next	= next;
-		next		= entry;
-
-		//done
-		return 0;
-	}
-
-	//check the rest of the list...
-	exists	= 0;
-	cur		= next;
-	while(cur)
-	{
-		if(entry->label == cur->label)
-		{
-			//node already exists
-			exists = 1;
-			break;
-		}
-		else if((!(cur->next))||(cur->next->label > entry->label))
-		{
-			//insert entry into the list at this location
-			entry->next	= cur->next;
-			cur->next	= entry;
-			break;
-		}
-
-		//traverse the region adjacency list
-		cur = cur->next;
-	}
-
-	//done. Return exists indicating whether or not a new node was
-	//      actually inserted into the region adjacency list.
-	return (int)(exists);
-
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Region Adjacency List:
+  =====================
+
+	The Region Adjacency List class is used by the Image 
+	Processor class in the construction of a Region Adjacency
+	Matrix, used by	this class to applying transitive closure
+	and to prune spurious regions during image segmentation.
+
+	The definition of the RAList class is provided below. Its
+	prototype is provided in "RAList.h".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+//include Region Adjacency List class prototype
+#include	"RAList.h"
+
+//include needed libraries
+#include	<stdio.h>
+#include	<assert.h>
+#include	<stdlib.h>
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/* Class Constructor and Destructor */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Class Constructor                                    */
+/*******************************************************/
+/*Constructs a RAList object.                          */
+/*******************************************************/
+/*Post:                                                */
+/*      - a RAlist object has been properly constru-   */
+/*        cted.                                        */
+/*******************************************************/
+
+RAList::RAList( void )
+{
+	//initialize label and link
+	label			= -1;
+	next			= NULL;
+
+	//initialize edge strenght weight and count
+	edgeStrength	= 0;
+	edgePixelCount	= 0;
+}
+
+/*******************************************************/
+/*Class Destructor                                     */
+/*******************************************************/
+/*Destructrs a RAList object.                          */
+/*******************************************************/
+/*Post:                                                */
+/*      - the RAList object has been properly dest-    */
+/*        ructed.                                      */
+/*******************************************************/
+
+RAList::~RAList( void )
+{
+	//do nothing
+}
+
+/*******************************************************/
+/*Insert                                               */
+/*******************************************************/
+/*Insert a region node into the region adjacency list. */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - entry is a node representing a connected re- */
+/*        gion                                         */
+/*Post:                                                */
+/*      - entry has been inserted into the region adj- */
+/*        acency list if it does not already exist     */
+/*        there.                                       */
+/*      - if the entry already exists in the region    */
+/*        adjacency list 1 is returned otherwise 0 is  */
+/*        returned.                                    */
+/*******************************************************/
+
+int RAList::Insert(RAList *entry)
+{
+
+	//if the list contains only one element
+	//then insert this element into next
+	if(!next)
+	{
+		//insert entry
+		next		= entry;
+		entry->next = NULL;
+
+		//done
+		return 0;
+	}
+
+	//traverse the list until either:
+
+	//(a) entry's label already exists - do nothing
+	//(b) the list ends or the current label is
+	//    greater than entry's label, thus insert the entry
+	//    at this location
+
+	//check first entry
+	if(next->label > entry->label)
+	{
+		//insert entry into the list at this location
+		entry->next	= next;
+		next		= entry;
+
+		//done
+		return 0;
+	}
+
+	//check the rest of the list...
+	exists	= 0;
+	cur		= next;
+	while(cur)
+	{
+		if(entry->label == cur->label)
+		{
+			//node already exists
+			exists = 1;
+			break;
+		}
+		else if((!(cur->next))||(cur->next->label > entry->label))
+		{
+			//insert entry into the list at this location
+			entry->next	= cur->next;
+			cur->next	= entry;
+			break;
+		}
+
+		//traverse the region adjacency list
+		cur = cur->next;
+	}
+
+	//done. Return exists indicating whether or not a new node was
+	//      actually inserted into the region adjacency list.
+	return (int)(exists);
+
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
diff --git a/Utilities/otbedison/segm/RAList.h b/Utilities/otbedison/segm/RAList.h
old mode 100755
new mode 100644
index 203d5cf81bf7aca114452a0308b2b47f12be5945..2c37fcff60cf9d26806bb5fed72ffc5cdebbd21b
--- a/Utilities/otbedison/segm/RAList.h
+++ b/Utilities/otbedison/segm/RAList.h
@@ -1,92 +1,92 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Region Adjacency List:
-  =====================
-
-	The Region Adjacency List class is used by the Image 
-	Processor class in the construction of a Region Adjacency
-	Matrix, used by	this class to applying transitive closure
-	and to prune spurious regions during image segmentation.
-
-	The prototype for the RAList class is provided below. Its
-	defition is provided in "RAList.cc".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-#ifndef RALIST_H
-#define RALIST_H
-
-//define Region Adjacency List class prototype
-class RAList {
-
-public:
-
-	//============================
-	// *** Public Data Members ***
-	//============================
-
-	////////////RAM Label//////////
-	int		label;
-
-	////////////RAM Weight/////////
-	float	edgeStrength;
-	int		edgePixelCount;
-
-	////////////RAM Link///////////
-	RAList	*next;
-
-	//=======================
-	// *** Public Methods ***
-	//=======================
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/* Class Constructor and Destructor */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-	//***Class Constrcutor***
-	RAList( void );
-
-	//***Class Destructor***
-	~RAList( void );
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/*  RAM List Manipulation */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-	//Usage: Insert(entry)
-	int Insert(RAList*);		//Insert a region node into the region adjecency list
-
-private:
-
-	//=============================
-	// *** Private Data Members ***
-	//=============================
-
-	///////current and previous pointer/////
-	RAList	*cur, *prev;
-
-	////////flag///////////
-	unsigned char exists;
-
-};
-
-#endif
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Region Adjacency List:
+  =====================
+
+	The Region Adjacency List class is used by the Image 
+	Processor class in the construction of a Region Adjacency
+	Matrix, used by	this class to applying transitive closure
+	and to prune spurious regions during image segmentation.
+
+	The prototype for the RAList class is provided below. Its
+	defition is provided in "RAList.cc".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+#ifndef RALIST_H
+#define RALIST_H
+
+//define Region Adjacency List class prototype
+class RAList {
+
+public:
+
+	//============================
+	// *** Public Data Members ***
+	//============================
+
+	////////////RAM Label//////////
+	int		label;
+
+	////////////RAM Weight/////////
+	float	edgeStrength;
+	int		edgePixelCount;
+
+	////////////RAM Link///////////
+	RAList	*next;
+
+	//=======================
+	// *** Public Methods ***
+	//=======================
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/* Class Constructor and Destructor */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+	//***Class Constrcutor***
+	RAList( void );
+
+	//***Class Destructor***
+	~RAList( void );
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/*  RAM List Manipulation */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+	//Usage: Insert(entry)
+	int Insert(RAList*);		//Insert a region node into the region adjecency list
+
+private:
+
+	//=============================
+	// *** Private Data Members ***
+	//=============================
+
+	///////current and previous pointer/////
+	RAList	*cur, *prev;
+
+	////////flag///////////
+	unsigned char exists;
+
+};
+
+#endif
diff --git a/Utilities/otbedison/segm/ms.cpp b/Utilities/otbedison/segm/ms.cpp
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/segm/ms.h b/Utilities/otbedison/segm/ms.h
old mode 100755
new mode 100644
diff --git a/Utilities/otbedison/segm/msImageProcessor.cpp b/Utilities/otbedison/segm/msImageProcessor.cpp
old mode 100755
new mode 100644
index ad7ac24016121a7b202105718323f07c9bf050d4..88d30e2c6c9bcfffb78f7db350ad597e7afce3ab
--- a/Utilities/otbedison/segm/msImageProcessor.cpp
+++ b/Utilities/otbedison/segm/msImageProcessor.cpp
@@ -1,4669 +1,4669 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Mean Shift Image Processor Class:
-  ================================
-
-	The following class inherits from the mean shift library
-	in order to perform the specialized tasks of image
-	segmentation and filtering.
-	
-	The definition of the Mean Shift Image Processor Class
-	is provided below. Its prototype is provided in
-	'msImageProcessor.h'.
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-//include image processor class prototype
-#include	"msImageProcessor.h"
-
-//include needed libraries
-#include	<math.h>
-#include	<stdio.h>
-#include	<assert.h>
-#include	<string.h>
-#include	<stdlib.h>
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /* Constructor/Destructor */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Class Constructor                                    */
-/*******************************************************/
-/*Post:                                                */
-/*      The msImageProcessor class has been properly   */
-/*      initialized.                                   */
-/*******************************************************/
-
-msImageProcessor::msImageProcessor( void )
-{
-
-	//intialize basin of attraction structure
-	//used by the filtering algorithm
-	modeTable			= NULL;
-	pointList			= NULL;
-	pointCount			= 0;
-
-	//initialize region list
-	regionList			= NULL;
-
-	//initialize output structures...
-	msRawData			= NULL;
-	labels				= NULL;
-	modes				= NULL;
-	modePointCounts		= NULL;
-	regionCount			= 0;
-
-	//intialize temporary buffers used for
-	//performing connected components
-	indexTable			= NULL;
-	LUV_data			= NULL;
-
-	//initialize region adjacency matrix
-	raList				= NULL;
-	freeRAList			= NULL;
-	raPool				= NULL;
-
-	//intialize visit table to having NULL entries
-	visitTable			= NULL;
-
-	//initialize epsilon such that transitive closure
-	//does not take edge strength into consideration when
-	//fusing regions of similar color
-	epsilon				= 1.0;
-
-	//initialize class state to indicate that
-	//an output data structure has not yet been
-	//created...
-	class_state.OUTPUT_DEFINED	= false;
-
-
-   LUV_treshold = 1.0;
-}
-
-/*******************************************************/
-/*Class Destructor                                     */
-/*******************************************************/
-/*Post:                                                */
-/*      The msImageProcessor class has been properly   */
-/*      destroyed.                                     */
-/*******************************************************/
-
-msImageProcessor::~msImageProcessor( void )
-{
-
-	//de-allocate memory
-	if(class_state.OUTPUT_DEFINED)	DestroyOutput();
-	if(regionList)					delete regionList;
-	regionList = NULL;
-
-	//done.
-
-}
-
- /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/
- /*  Input Image Declaration */
- /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Define Image                                         */
-/*******************************************************/
-/*Uploads an image into the image segmenter class to   */
-/*be segmented.                                        */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - data_ is a one dimensional array of unsigned */
-/*        char RGB vectors                             */
-/*      - type is the type of the image: COLOR or      */
-/*        GREYSCALE                                    */
-/*      - height_ and width_ define the dimension of   */
-/*        the image                                    */
-/*      - if the image is of type GREYSCALE then       */
-/*        data containes only one number per pixel     */
-/*        location, where a pixel location is defined  */
-/*        by the index into the data array             */
-/*Post:                                                */
-/*      - the image specified has been uploaded into   */
-/*        the image segmenter class to be segmented.   */
-/*******************************************************/
-
-void msImageProcessor::DefineImage(byte *data_, imageType type, int height_, int width_)
-{
-
-	//obtain image dimension from image type
-	int dim;
-	if(type == COLOR)
-		dim	= 3;
-	else
-		dim = 1;
-
-	//perfor rgb to luv conversion
-	int		i;
-	float	*luv	= new float [height_*width_*dim];
-	if(dim == 1)
-	{
-		for(i = 0; i < height_*width_; i++)
-			luv[i]	= (float)(data_[i]);
-	}
-	else
-	{
-		for(i = 0; i < height_*width_; i++)
-			RGBtoLUV(&data_[dim*i], &luv[dim*i]);
-	}
-
-	//define input defined on a lattice using mean shift base class
-	DefineLInput(luv, height_, width_, dim);
-
-	//Define a default kernel if it has not been already
-	//defined by user
-	if(!h)
-	{
-		//define default kernel paramerters...
-		kernelType	k[2]		= {Uniform, Uniform};
-		int			P[2]		= {2, N};
-		float		tempH[2]	= {1.0 , 1.0};
-
-		//define default kernel in mean shift base class
-		DefineKernel(k, tempH, P, 2);
-	}
-
-	//de-allocate memory
-	delete [] luv;
-
-	//done.
-	return;
-
-}
-
-void msImageProcessor::DefineBgImage(byte* data_, imageType type, int height_, int width_)
-{
-
-	//obtain image dimension from image type
-	int dim;
-	if(type == COLOR)
-		dim	= 3;
-	else
-		dim = 1;
-
-	//perform texton classification
-	int		i;
-	float	*luv	= new float [height_*width_*dim];
-	if(dim == 1)
-	{
-		for(i = 0; i < height_*width_; i++)
-			luv[i]	= (float)(data_[i]);
-	}
-	else
-	{
-		for(i = 0; i < height_*width_; i++)
-			RGBtoLUV(&data_[dim*i], &luv[dim*i]);
-	}
-
-	//define input defined on a lattice using mean shift base class
-	DefineLInput(luv, height_, width_, dim);
-
-	//Define a default kernel if it has not been already
-	//defined by user
-	if(!h)
-	{
-		//define default kernel paramerters...
-		kernelType	k[2]		= {Uniform, Uniform};
-		int			P[2]		= {2, N};
-		float		tempH[2]	= {1.0 , 1.0};
-
-		//define default kernel in mean shift base class
-		DefineKernel(k, tempH, P, 2);
-	}
-
-	//de-allocate memory
-	delete [] luv;
-
-	//done.
-	return;
-
-}
-
- /*/\/\/\/\/\/\/\/\*/
- /*   Weight Map   */
- /*\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Set Weight Map                                       */
-/*******************************************************/
-/*Populates the weight map with specified edge         */
-/*strengths.                                           */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - wm is a floating point array of size         */
-/*        (height x width) specifying for each pixel   */
-/*        edge strength.                               */
-/*      - eps is a threshold used to fuse similar      */
-/*        regions during transitive closure.           */
-/*Post:                                                */
-/*      - wm has been used to populate the weight      */
-/*        map.                                         */
-/*      - the threshold used during transitive closure */
-/*        is taken as eps.                             */
-/*******************************************************/
-
-void msImageProcessor::SetWeightMap(float *wm, float eps)
-{
-
-	//initlaize confmap using wm
-	SetLatticeWeightMap(wm);
-
-	//set threshold value
-	if((epsilon = eps) < 0)
-		ErrorHandler("msImageProcessor", "SetWeightMap", "Threshold is negative.");
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Remove Weight Map                                    */
-/*******************************************************/
-/*Removes the weight map.                              */
-/*******************************************************/
-/*Post:                                                */
-/*      - the weight map has been removed.             */
-/*      - if a weight map did not exist NO error       */
-/*        is flagged.                                  */
-/*******************************************************/
-
-void msImageProcessor::RemoveWeightMap( void )
-{
-
-	//remove confmap
-	RemoveLatticeWeightMap();
-
-	//set threshold value to zero
-	epsilon	= 0;
-
-	//done.
-	return;
-
-}
-
- /*/\/\/\/\/\/\/\/\/\*/
- /* Image Filtering  */
- /*\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Filter                                               */
-/*******************************************************/
-/*Performs mean shift filtering on the specified input */
-/*image using a user defined kernel.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the user defined kernel used to apply mean   */
-/*        shift filtering to the defined input image   */
-/*        has spatial bandwidth sigmaS and range band- */
-/*        width sigmaR                                 */
-/*      - speedUpLevel determines whether or not the   */
-/*        filtering should be optimized for faster     */
-/*        execution: a value of NO_SPEEDUP turns this  */
-/*        optimization off and a value SPEEDUP turns   */
-/*        this optimization on                         */
-/*      - a data set has been defined                  */
-/*      - the height and width of the lattice has been */
-/*        specified using method DefineLattice()       */
-/*Post:                                                */
-/*      - mean shift filtering has been applied to the */
-/*        input image using a user defined kernel      */
-/*      - the filtered image is stored in the private  */
-/*        data members of the msImageProcessor class.  */
-/*******************************************************/
-
-void msImageProcessor::Filter(int sigmaS, float sigmaR, SpeedUpLevel speedUpLevel)
-{
-
-	//Check Class consistency...
-
-	//check:
-	// (1) if this operation is consistent
-	// (2) if kernel was created
-	// (3) if data set is defined
-	// (4) if the dimension of the kernel agrees with that
-	//     of the defined data set
-	// if not ... flag an error!
-	classConsistencyCheck(N+2, true);
-	if(ErrorStatus == EL_ERROR)
-		return;
-
-	//If the algorithm has been halted, then exit
-	if((ErrorStatus = msSys.Progress((float)(0.0))) == EL_HALT)
-	{
-		return;
-	}
-	
-	//If the image has just been read then allocate memory
-	//for and initialize output data structure used to store
-	//image modes and their corresponding regions...
-	if(class_state.OUTPUT_DEFINED == false)
-	{
-		InitializeOutput();
-
-		//check for errors...
-		if(ErrorStatus == EL_ERROR)
-			return;
-	}
-
-	//****************** Allocate Memory ******************
-
-	//Allocate memory for basin of attraction mode structure...
-	if((!(modeTable = new unsigned char [L]))||(!(pointList = new int [L])))
-	{
-		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
-		return;
-	}
-
-	//start timer
-#ifdef PROMPT
-	double timer;
-	msSys.StartTimer();
-#endif
-
-	//*****************************************************
-
-	//filter image according to speedup level...
-	switch(speedUpLevel)
-	{
-	//no speedup...
-	case NO_SPEEDUP:	
-      //NonOptimizedFilter((float)(sigmaS), sigmaR);	break;
-      NewNonOptimizedFilter((float)(sigmaS), sigmaR);	break;
-	//medium speedup
-	case MED_SPEEDUP:	
-      //OptimizedFilter1((float)(sigmaS), sigmaR);		break;
-      NewOptimizedFilter1((float)(sigmaS), sigmaR);		break;
-	//high speedup
-	case HIGH_SPEEDUP: 
-      //OptimizedFilter2((float)(sigmaS), sigmaR);		break;
-      NewOptimizedFilter2((float)(sigmaS), sigmaR);		break;
-   // new speedup
-	}
-
-	//****************** Deallocate Memory ******************
-
-	//de-allocate memory used by basin of attraction mode structure
-	delete [] modeTable;
-	delete [] pointList;
-
-	//re-initialize structure
-	modeTable	= NULL;
-	pointList	= NULL;
-	pointCount	= 0;
-
-	//*******************************************************
-
-	//If the algorithm has been halted, then de-allocate the output
-	//and exit
-	if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT)
-	{
-		DestroyOutput();
-		return;
-	}
-
-	//Label image regions, also if segmentation is not to be
-	//performed use the resulting classification structure to
-	//calculate the image boundaries...
-
-   /*
-	//copy msRawData into LUV_data, rounding each component of each
-	//LUV value stored by msRawData to the nearest integer
-	int	i;
-	for(i = 0; i < L*N; i++)
-	{
-		if(msRawData[i] < 0)
-			LUV_data[i] = (int)(msRawData[i] - 0.5);
-		else
-			LUV_data[i] = (int)(msRawData[i] + 0.5);
-	}
-   */
-   int i;
-   for (i=0; i<L*N; i++)
-   {
-      LUV_data[i] = msRawData[i];
-   }
-
-
-#ifdef PROMPT
-	timer	= msSys.ElapsedTime();
-	msSys.Prompt("(%6.2f sec)\nConnecting regions         ...", timer);
-	msSys.StartTimer();
-#endif
-	
-	//Perform connecting (label image regions) using LUV_data
-	Connect();
-	
-#ifdef PROMPT
-	timer	= msSys.ElapsedTime();
-	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
-	msSys.StartTimer();
-#endif
-
-	//done.
-	return;
-
-}
-
- /*/\/\/\/\/\/\/\/\/\/\/\*/
- /* Image Region Fusing  */
- /*\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Fuse Regions                                         */
-/*******************************************************/
-/*Fuses the regions of a filtered image.               */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the range radius is specified by sigmaR      */
-/*      - minRegion is the minimum point density that  */
-/*        a region may have in the resulting segment-  */
-/*        ed image                                     */
-/*      - a data set has been defined                  */
-/*      - the height and width of the lattice has been */
-/*        specified using method DefineLattice()       */
-/*Post:                                                */
-/*      - the image regions have been fused.           */
-/*      - if an result is stored by this class then    */
-/*        this result is used as input to this method. */
-/*      - if no result is stored by this class,        */
-/*        the input image defined by calling the       */
-/*        method DefineImage is used.                  */
-/*******************************************************/
-
-void msImageProcessor::FuseRegions(float sigmaS, int minRegion)
-{
-
-	//Check Class consistency...
-
-	//check:
-	// (1) if this operation is consistent
-	// (2) if kernel was created
-	// (3) if data set is defined
-	// (4) if the dimension of the kernel agrees with that
-	//     of the defined data set
-	// if not ... flag an error!
-	classConsistencyCheck(N+2, true);
-	if(ErrorStatus == EL_ERROR)
-		return;
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and exit
-	if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT)
-	{
-		if(class_state.OUTPUT_DEFINED)	DestroyOutput();
-		return;
-	}
-
-	//obtain sigmaS (make sure it is not zero or negative, if not
-	//flag an error)
-	if((h[1] = sigmaS) <= 0)
-	{
-		ErrorHandler("msImageProcessor", "FuseRegions", "The feature radius must be greater than or equal to zero.");
-		return;
-	}
-
-	//if output has not yet been generated then classify the input
-	//image regions to be fused...
-	if(!(class_state.OUTPUT_DEFINED))
-	{
-
-		//Initialize output data structure used to store
-		//image modes and their corresponding regions...
-		InitializeOutput();
-		
-		//check for errors...
-		if(ErrorStatus == EL_ERROR)
-			return;
-
-		//copy data into LUV_data used to classify
-		//image regions
-      /*
-		int i;
-		for(i = 0; i < L*N; i++)
-		{
-			if(data[i] < 0)
-				LUV_data[i] = (int)(data[i] - 0.5);
-			else
-				LUV_data[i] = (int)(data[i] + 0.5);
-		}
-      */
-      int i;
-      for (i=0; i<L*N; i++)
-      {
-         LUV_data[i] = data[i];
-      }
-		
-#ifdef PROMPT
-		msSys.Prompt("Connecting regions         ...");
-		msSys.StartTimer();
-#endif
-
-		//Perform connecting (label image regions) using LUV_data
-		Connect();
-		
-		//check for errors
-		if(ErrorStatus == EL_ERROR)
-			return;
-		
-#ifdef PROMPT
-		double timer	= msSys.ElapsedTime();
-		msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
-#endif
-		
-	}
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and exit
-	if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT)
-	{
-		DestroyOutput();
-		return;
-	}
-
-#ifdef PROMPT
-	msSys.Prompt("Applying transitive closure...");
-	msSys.StartTimer();
-#endif
-
-	//allocate memory visit table
-	visitTable = new unsigned char [L];
-
-	//Apply transitive closure iteratively to the regions classified
-	//by the RAM updating labels and modes until the color of each neighboring
-	//region is within sqrt(rR2) of one another.
-	rR2 = (float)(h[1]*h[1]*0.25);
-	TransitiveClosure();
-	int oldRC = regionCount;
-	int deltaRC, counter = 0;
-	do {
-		TransitiveClosure();
-		deltaRC = oldRC-regionCount;
-		oldRC = regionCount;
-		counter++;
-	} while ((deltaRC <= 0)&&(counter < 10));
-
-	//de-allocate memory for visit table
-	delete [] visitTable;
-	visitTable	= NULL;
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and region adjacency matrix and exit
-	if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT)
-	{
-		DestroyRAM();
-		DestroyOutput();
-		return;
-	}
-
-#ifdef PROMPT
-	double timer	= msSys.ElapsedTime();
-	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions   ...", timer, regionCount);
-	msSys.StartTimer();
-#endif
-
-	//Prune spurious regions (regions whose area is under
-	//minRegion) using RAM
-	Prune(minRegion);
-
-#ifdef PROMPT
-	timer	= msSys.ElapsedTime();
-	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
-	msSys.StartTimer();
-#endif
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and region adjacency matrix and exit
-	if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT)
-	{
-		DestroyRAM();
-		DestroyOutput();
-		return;
-	}
-
-	//de-allocate memory for region adjacency matrix
-	DestroyRAM();
-
-	//output to msRawData
-	int i, j, label;
-	for(i = 0; i < L; i++)
-	{
-		label	= labels[i];
-		for(j = 0; j < N; j++)
-			{
-				msRawData[N*i+j] = modes[N*label+j];
-			}
-	}
-
-	//done.
-	return;
-
-}
-
-  /*/\/\/\/\/\/\/\/\/\/\*/
-  /* Image Segmentation */
-  /*\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Segment                                              */
-/*******************************************************/
-/*Segments the defined image.                          */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - sigmaS and sigmaR are the spatial and range  */
-/*        radii of the search window respectively      */
-/*      - minRegion is the minimum point density that  */
-/*        a region may have in the resulting segment-  */
-/*        ed image                                     */
-/*      - speedUpLevel determines whether or not the   */
-/*        filtering should be optimized for faster     */
-/*        execution: a value of NO_SPEEDUP turns this  */
-/*        optimization off and a value SPEEDUP turns   */
-/*        this optimization on                         */
-/*Post:                                                */
-/*      - the defined image is segmented and the       */
-/*        resulting segmented image is stored in the   */
-/*        private data members of the image segmenter  */
-/*        class.                                       */
-/*      - any regions whose point densities are less   */
-/*        than or equal to minRegion have been pruned  */
-/*        from the segmented image.                    */
-/*******************************************************/
-
-void msImageProcessor::Segment(int sigmaS, float sigmaR, int minRegion, SpeedUpLevel speedUpLevel)
-{
-
-	//make sure kernel is properly defined...
-	if((!h)||(kp < 2))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "Kernel corrupt or undefined.");
-		return;
-	}
-
-	//Apply mean shift to data set using sigmaS and sigmaR...
-	Filter(sigmaS, sigmaR, speedUpLevel);
-
-	//check for errors
-	if(ErrorStatus == EL_ERROR)
-		return;
-
-	//check to see if the system has been halted, if so exit
-	if(ErrorStatus == EL_HALT)
-		return;
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and exit
-	if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT)
-	{
-		DestroyOutput();
-		return;
-	}
-
-#ifdef PROMPT
-	msSys.Prompt("Applying transitive closure...");
-	msSys.StartTimer();
-#endif
-
-	//allocate memory visit table
-	visitTable = new unsigned char [L];
-
-	//Apply transitive closure iteratively to the regions classified
-	//by the RAM updating labels and modes until the color of each neighboring
-	//region is within sqrt(rR2) of one another.
-	rR2 = (float)(h[1]*h[1]*0.25);
-	TransitiveClosure();
-	int oldRC = regionCount;
-	int deltaRC, counter = 0;
-	do {
-		TransitiveClosure();
-		deltaRC = oldRC-regionCount;
-		oldRC = regionCount;
-		counter++;
-	} while ((deltaRC <= 0)&&(counter < 10));
-
-	//de-allocate memory for visit table
-	delete [] visitTable;
-	visitTable	= NULL;
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and regions adjacency matrix and exit
-	if((ErrorStatus = msSys.Progress((float)(0.95))) == EL_HALT)
-	{
-		DestroyRAM();
-		DestroyOutput();
-		return;
-	}
-
-#ifdef PROMPT
-	double timer	= msSys.ElapsedTime();
-	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d).\nPruning spurious regions\t... ", timer, regionCount);
-	msSys.StartTimer();
-#endif
-
-	//Prune spurious regions (regions whose area is under
-	//minRegion) using RAM
-	Prune(minRegion);
-
-#ifdef PROMPT
-	timer	= msSys.ElapsedTime();
-	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions    ...", timer, regionCount);
-	msSys.StartTimer();
-#endif
-
-	//Check to see if the algorithm is to be halted, if so then
-	//destroy output and regions adjacency matrix and exit
-	if((ErrorStatus = msSys.Progress(1.0)) == EL_HALT)
-	{
-		DestroyRAM();
-		DestroyOutput();
-		return;
-	}
-
-	//de-allocate memory for region adjacency matrix
-	DestroyRAM();
-
-	//output to msRawData
-	int j, i, label;
-	for(i = 0; i < L; i++)
-	{
-		label	= labels[i];
-		for(j = 0; j < N; j++)
-			{
-				msRawData[N*i+j] = modes[N*label+j];
-			}
-	}
-
-	//done.
-	return;
-
-}
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Data Space Conversion */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*RGB To LUV                                           */
-/*******************************************************/
-/*Converts an RGB vector to LUV.                       */
-/*                                                     */
-/*See:                                                 */
-/*   G. Wyszecki and W.S. Stiles: Color Science:       */
-/*   Concepts and Methods, Quantitative Data and       */
-/*   Formulae, Wiley, New York, 1982.                  */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - rgbVal is an unsigned char array containing  */
-/*        the RGB vector                               */
-/*      - luvVal is a floating point array containing  */
-/*        the resulting LUV vector                     */
-/*Post:                                                */
-/*      - rgbVal has been converted to LUV and the     */
-/*        result has been stored in luvVal.            */
-/*******************************************************/
-
-void msImageProcessor::RGBtoLUV(byte *rgbVal, float *luvVal)
-{
-
-	//delcare variables
-	double	x, y, z, L0, u_prime, v_prime, constant;
-
-	//convert RGB to XYZ...
-	x		= XYZ[0][0]*rgbVal[0] + XYZ[0][1]*rgbVal[1] + XYZ[0][2]*rgbVal[2];
-	y		= XYZ[1][0]*rgbVal[0] + XYZ[1][1]*rgbVal[1] + XYZ[1][2]*rgbVal[2];
-	z		= XYZ[2][0]*rgbVal[0] + XYZ[2][1]*rgbVal[1] + XYZ[2][2]*rgbVal[2];
-
-	//convert XYZ to LUV...
-
-	//compute L*
-	L0		= y / (255.0 * Yn);
-	if(L0 > Lt)
-		luvVal[0]	= (float)(116.0 * (pow(L0, 1.0/3.0)) - 16.0);
-	else
-		luvVal[0]	= (float)(903.3 * L0);
-
-	//compute u_prime and v_prime
-	constant	= x + 15 * y + 3 * z;
-	if(constant != 0)
-	{
-		u_prime	= (4 * x) / constant;
-		v_prime = (9 * y) / constant;
-	}
-	else
-	{
-		u_prime	= 4.0;
-		v_prime	= 9.0/15.0;
-	}
-
-	//compute u* and v*
-    luvVal[1] = (float) (13 * luvVal[0] * (u_prime - Un_prime));
-    luvVal[2] = (float) (13 * luvVal[0] * (v_prime - Vn_prime));
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*LUV To RGB                                           */
-/*******************************************************/
-/*Converts an LUV vector to RGB.                       */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - luvVal is a floating point array containing  */
-/*        the LUV vector                               */
-/*      - rgbVal is an unsigned char array containing  */
-/*        the resulting RGB vector                     */
-/*Post:                                                */
-/*      - luvVal has been converted to RGB and the     */
-/*        result has been stored in rgbVal.            */
-/*******************************************************/
-
-//define inline rounding function...
-inline int my_round(double in_x)
-{
-	if (in_x < 0)
-		return (int)(in_x - 0.5);
-	else
-		return (int)(in_x + 0.5);
-}
-
-void msImageProcessor::LUVtoRGB(float *luvVal, byte *rgbVal)
-{
-
-	//declare variables...
-	int		r, g, b;
-	double	x, y, z, u_prime, v_prime;
-
-	//perform conversion
-	if(luvVal[0] < 0.1)
-		r = g = b = 0;
-	else
-	{
-		//convert luv to xyz...
-		if(luvVal[0] < 8.0)
-			y	= Yn * luvVal[0] / 903.3;
-		else
-		{
-			y	= (luvVal[0] + 16.0) / 116.0;
-			y  *= Yn * y * y;
-		}
-
-		u_prime	= luvVal[1] / (13 * luvVal[0]) + Un_prime;
-		v_prime	= luvVal[2] / (13 * luvVal[0]) + Vn_prime;
-
-		x		= 9 * u_prime * y / (4 * v_prime);
-		z		= (12 - 3 * u_prime - 20 * v_prime) * y / (4 * v_prime);
-
-		//convert xyz to rgb...
-		//[r, g, b] = RGB*[x, y, z]*255.0
-		r		= my_round((RGB[0][0]*x + RGB[0][1]*y + RGB[0][2]*z)*255.0);
-		g		= my_round((RGB[1][0]*x + RGB[1][1]*y + RGB[1][2]*z)*255.0);
-		b		= my_round((RGB[2][0]*x + RGB[2][1]*y + RGB[2][2]*z)*255.0);
-
-		//check bounds...
-		if(r < 0)	r = 0; if(r > 255)	r = 255;
-		if(g < 0)	g = 0; if(g > 255)	g = 255;
-		if(b < 0)	b = 0; if(b > 255)	b = 255;
-
-	}
-
-	//assign rgb values to rgb vector rgbVal
-	rgbVal[0]	= r;
-	rgbVal[1]	= g;
-	rgbVal[2]	= b;
-
-	//done.
-	return;
-
-}
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Filtered and Segmented Image Output */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Get Raw Data                                         */
-/*******************************************************/
-/*The output image data is returned.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - outputImageData is a pre-allocated floating  */
-/*        point array used to store the filtered or    */
-/*        segmented image pixels.                      */
-/*Post:                                                */
-/*      - the filtered or segmented image data is      */
-/*        stored by outputImageData.                   */
-/*******************************************************/
-
-void msImageProcessor::GetRawData(float *outputImageData)
-{
-	//make sure that outputImageData is not NULL
-	if(!outputImageData)
-	{
-		ErrorHandler("msImageProcessor", "GetRawData", "Output image data buffer is NULL.");
-		return;
-	}
-
-	//copy msRawData to outputImageData
-	int i;
-	for(i = 0; i < L*N; i++)
-		outputImageData[i] = msRawData[i];
-
-	//done.
-	return;
-}
-
-/*******************************************************/
-/*Get Results                                          */
-/*******************************************************/
-/*The output image is returned.                        */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - outputImage is a pre-allocated unsinged char */
-/*        array used to store the filtered or segment- */
-/*        ed image pixels                              */
-/*Post:                                                */
-/*      - the filtered or segmented image is stored by */
-/*        outputImage.                                 */
-/*******************************************************/
-
-void msImageProcessor::GetResults(byte *outputImage)
-{
-
-	//make sure that outpuImage is not NULL
-	if(!outputImage)
-	{
-		ErrorHandler("msImageProcessor", "GetResults", "Output image buffer is NULL.");
-		return;
-	}
-
-	//if the image type is GREYSCALE simply
-	//copy it over to the segmentedImage
-	if(N == 1)
-	{
-		//copy over msRawData to segmentedImage checking
-		//bounds
-		int i, pxValue;
-		for(i = 0; i < L; i++)
-		{
-
-			//get value
-			pxValue = (int)(msRawData[i]+0.5);
-			
-			//store into segmented image checking bounds...
-			if(pxValue < 0)
-				outputImage[i] = (byte)(0);
-			else if(pxValue > 255)
-				outputImage[i] = (byte)(255);
-			else
-				outputImage[i] = (byte)(pxValue);
-
-		}
-
-	}
-	else if (N == 3)
-	{
-		
-		//otherwise convert msRawData from LUV to RGB
-		//storing the result in segmentedImage
-		int i;
-		for(i = 0; i < L; i++)
-			LUVtoRGB(&msRawData[N*i], &outputImage[N*i]);
-
-	}
-	else
-		//Unknown image type: should use MeanShift::GetRawData()...
-		ErrorHandler("msImageProcessor", "GetResults", "Unknown image type. Try using MeanShift::GetRawData().");
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Get Boundaries                                       */
-/*******************************************************/
-/*A region list containing the boundary locations for  */
-/*each region is returned.                             */
-/*******************************************************/
-/*Post:                                                */
-/*      - a region list object containing the boundary */
-/*        locations for each region is constructed     */
-/*      - the region list is returned                  */
-/*      - NULL is returned if the image has not been   */
-/*        filtered or segmented                        */
-/*******************************************************/
-
-RegionList *msImageProcessor::GetBoundaries( void )
-{
-
-	//define bounds using label information
-	if(class_state.OUTPUT_DEFINED)
-		DefineBoundaries();
-
-	//return region list structure
-	return regionList;
-
-}
- 
-/*******************************************************/
-/*Get Regions                                          */
-/*******************************************************/
-/*Returns the regions of the processed image.          */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - labels_out is an integer array of size       */
-/*        height*width that stores for each pixel a    */
-/*        label relating that pixel to a corresponding */
-/*        region in the image                          */
-/*      - modes_out is floating point array of size    */
-/*        regionCount*N storing the feature component  */
-/*        of each region, and indexed by region label  */
-/*      - modePointCounts is an integer array of size  */
-/*        regionCount, indexed by region label, that   */
-/*        stores the area of each region in pixels.    */
-/*Post:                                                */
-/*      If an input image was defined and processed,   */
-/*      - memory has been allocated for labels_out,    */
-/*        modes_out and MPC_out.                       */
-/*      - labels_out, modes_out, and MPC_out have been */
-/*        populated.                                   */
-/*      - the number of regions contained by the segm- */
-/*        ented image has been returned.               */
-/*      If the image has not been defined or processed */
-/*      or if there is in-sufficient memory,           */
-/*      - no memory has been allocated for labels_out, */
-/*        modes_out, and MPC_out.                      */
-/*      - -1 is returned for regionCount.              */
-/*******************************************************/
-
-int msImageProcessor::GetRegions(int **labels_out, float **modes_out, int **MPC_out)
-{
-	//check to see if output has been defined for the given input image...
-	if(class_state.OUTPUT_DEFINED == false)
-		return -1;
-
-	//allocate memory for labels_out, modes_out and MPC_out based
-	//on output storage structure
-	int		*labels_	= *labels_out, *MPC_out_ = *MPC_out;
-	float	*modes_		= *modes_out; 
-	if(!(labels_ = new int [L]))
-	{
-		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
-		return -1;
-	}
-	if(!(modes_	= new float [regionCount*N]))
-	{
-		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
-		return -1;
-	}
-	if(!(MPC_out_ = new int [regionCount]))
-	{
-		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
-		return -1;
-	}
-
-	//populate labels_out with image labels
-	int	i;
-	for(i = 0; i < L; i++)
-		labels_[i] = labels[i];
-
-	//populate modes_out and MPC_out with the color and point
-	//count of each region
-	for(i = 0; i < regionCount*N; i++)
-		modes_[i]	= modes[i];
-	for(i = 0; i < regionCount; i++)
-		MPC_out_[i]	= modePointCounts[i];
-
-	//done. Return the number of regions resulting from filtering or segmentation.
-	return regionCount;
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     PRIVATE METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-	/*/\/\/\/\/\/\/\/\/\*/
-	/*  Image Filtering */
-	/*\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Non Optimized Filter                                 */
-/*******************************************************/
-/*Performs mean shift filtering on the specified input */
-/*image using a user defined kernel.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the user defined kernel used to apply mean   */
-/*        shift filtering to the defined input image   */
-/*        has spatial bandwidth sigmaS and range band- */
-/*        width sigmaR                                 */
-/*      - a data set has been defined                  */
-/*      - the height and width of the lattice has been */
-/*        specified using method DefineLattice()       */
-/*Post:                                                */
-/*      - mean shift filtering has been applied to the */
-/*        input image using a user defined kernel      */
-/*      - the filtered image is stored in the private  */
-/*        data members of the msImageProcessor class.  */
-/*******************************************************/
-
-void msImageProcessor::NonOptimizedFilter(float sigmaS, float sigmaR)
-{
-
-	// Declare Variables
-	int   iterationCount, i, j;
-	double mvAbs;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-	for(i = 0; i < L; i++)
-	{
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-		yk[0] = i%width;
-		yk[1] = i/width;
-		for(j = 0; j < N; j++)
-			yk[j+2] = data[N*i+j];
-		
-		// Calculate the mean shift vector using the lattice
-		LatticeMSVector(Mh, yk);
-		
-		// Calculate its magnitude squared
-		mvAbs = 0;
-		for(j = 0; j < lN; j++)
-			mvAbs += Mh[j]*Mh[j];
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// Calculate the mean shift vector at the new
-			// window location using lattice
-			LatticeMSVector(Mh, yk);
-			
-			// Calculate its magnitude squared
-			mvAbs = 0;
-			for(j = 0; j < lN; j++)
-				mvAbs += Mh[j]*Mh[j];
-
-			// Increment interation count
-			iterationCount++;
-			
-		}
-
-		// Shift window location
-		for(j = 0; j < lN; j++)
-			yk[j] += Mh[j];
-		
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	
-	// de-allocate memory
-	delete [] yk;
-	delete [] Mh;
-
-	// done.
-	return;
-
-}
-
-
-
-/*******************************************************/
-/*Optimized Filter 1                                   */
-/*******************************************************/
-/*Performs mean shift filtering on the specified input */
-/*image using a user defined kernel. Previous mode     */
-/*information is used to avoid re-applying mean shift  */
-/*on certain data points to improve performance.       */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the user defined kernel used to apply mean   */
-/*        shift filtering to the defined input image   */
-/*        has spatial bandwidth sigmaS and range band- */
-/*        width sigmaR                                 */
-/*      - a data set has been defined                  */
-/*      - the height and width of the lattice has been */
-/*        specified using method DefineLattice()       */
-/*Post:                                                */
-/*      - mean shift filtering has been applied to the */
-/*        input image using a user defined kernel      */
-/*      - the filtered image is stored in the private  */
-/*        data members of the msImageProcessor class.  */
-/*******************************************************/
-
-void msImageProcessor::OptimizedFilter1(float sigmaS, float sigmaR)
-{
-
-	// Declare Variables
-	int		iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
-	float	*modeCandidatePoint;
-	double	mvAbs, diff, el;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-	
-	// Initialize mode table used for basin of attraction
-	memset(modeTable, 0, width*height);
-
-	// Allocate memory mode candidate data point...
-	//floating point version
-	modeCandidatePoint	= new float	[N];
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-
-	for(i = 0; i < L; i++)
-	{
-		// if a mode was already assigned to this data point
-		// then skip this point, otherwise proceed to
-		// find its mode by applying mean shift...
-		if (modeTable[i] == 1)
-			continue;
-
-		// initialize point list...
-		pointCount = 0;
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-		yk[0] = i%width;
-		yk[1] = i/width;
-		for(j = 0; j < N; j++)
-			yk[j+2] = data[N*i+j];
-		
-		// Calculate the mean shift vector using the lattice
-		LatticeMSVector(Mh, yk);
-		
-		// Calculate its magnitude squared
-		mvAbs = 0;
-		for(j = 0; j < lN; j++)
-			mvAbs += Mh[j]*Mh[j];
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// check to see if the current mode location is in the
-			// basin of attraction...
-
-			// calculate the location of yk on the lattice
-			modeCandidateX	= (int) (yk[0]+0.5);
-			modeCandidateY	= (int) (yk[1]+0.5);
-			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
-
-			// if mvAbs != 0 (yk did indeed move) then check
-			// location basin_i in the mode table to see if
-			// this data point either:
-			
-			// (1) has not been associated with a mode yet
-			//     (modeTable[basin_i] = 0), so associate
-			//     it with this one
-			//
-			// (2) it has been associated with a mode other
-			//     than the one that this data point is converging
-			//     to (modeTable[basin_i] = 1), so assign to
-			//     this data point the same mode as that of basin_i
-
-			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
-			{
-				// obtain the data point at basin_i to
-				// see if it is within h*TC_DIST_FACTOR of
-				// of yk
-				for (j = 0; j < N; j++)
-					modeCandidatePoint[j] = data[N*modeCandidate_i + j];
-				
-				// check basin on non-spatial data spaces only
-				k = 1;
-				s = 0;
-				diff = 0;
-				while ((diff < TC_DIST_FACTOR) && (k<kp))
-				{
-					diff = 0;
-					for (p=0; p<P[k]; p++)
-					{
-						el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
-						diff += el*el;
-					}
-					s+=P[k];
-					k++;
-				}
-
-				// if the data point at basin_i is within
-				// a distance of h*TC_DIST_FACTOR of yk
-				// then depending on modeTable[basin_i] perform
-				// either (1) or (2)
-				if (diff < TC_DIST_FACTOR)
-				{
-					// if the data point at basin_i has not
-					// been associated to a mode then associate
-					// it with the mode that this one will converge
-					// to
-					if (modeTable[modeCandidate_i] == 0)
-					{
-						// no mode associated yet so associate
-						// it with this one...
-						pointList[pointCount++]		= modeCandidate_i;
-						modeTable[modeCandidate_i]	= 2;
-
-					} else
-					{
-
-						// the mode has already been associated with
-						// another mode, thererfore associate this one
-						// mode and the modes in the point list with
-						// the mode associated with data[basin_i]...
-
-						// store the mode info into yk using msRawData...
-						for (j = 0; j < N; j++)
-							yk[j+2] = msRawData[modeCandidate_i*N+j];
-
-						// update mode table for this data point
-						// indicating that a mode has been associated
-						// with it
-						modeTable[i] = 1;
-
-                  // indicate that a mode has been associated
-						// to this data point (data[i])
-						mvAbs = -1;
-
-						// stop mean shift calculation...
-						break;
-					}
-				}
-			}
-			
-			// Calculate the mean shift vector at the new
-			// window location using lattice
-			LatticeMSVector(Mh, yk);
-			
-			// Calculate its magnitude squared
-			mvAbs = 0;
-			for(j = 0; j < lN; j++)
-				mvAbs += Mh[j]*Mh[j];
-
-			// Increment iteration count
-			iterationCount++;
-			
-		}
-
-		// if a mode was not associated with this data point
-		// yet associate it with yk...
-		if (mvAbs >= 0)
-		{
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// update mode table for this data point
-			// indicating that a mode has been associated
-			// with it
-			modeTable[i] = 1;
-		}
-		
-		// associate the data point indexed by
-		// the point list with the mode stored
-		// by yk
-		for (j = 0; j < pointCount; j++)
-		{
-			// obtain the point location from the
-			// point list
-			modeCandidate_i = pointList[j];
-
-			// update the mode table for this point
-			modeTable[modeCandidate_i] = 1;
-
-			//store result into msRawData...
-			for(k = 0; k < N; k++)
-				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
-		}
-
-
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;		
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	
-	// de-allocate memory
-	delete [] modeCandidatePoint;
-	delete [] yk;
-	delete [] Mh;
-	
-	// done.
-	return;
-
-}
-
-/*******************************************************/
-/*Optimized Filter 2                                   */
-/*******************************************************/
-/*Performs mean shift filtering on the specified input */
-/*image using a user defined kernel. Previous mode     */
-/*information is used to avoid re-applying mean shift  */
-/*on certain data points to improve performance. To    */
-/*further improve perfmance (during segmentation) poi- */
-/*nts within h of a window center during the window    */
-/*center's traversal to a mode are associated with the */
-/*mode that the window converges to.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the user defined kernel used to apply mean   */
-/*        shift filtering to the defined input image   */
-/*        has spatial bandwidth sigmaS and range band- */
-/*        width sigmaR                                 */
-/*      - a data set has been defined                  */
-/*      - the height and width of the lattice has been */
-/*        specified using method DefineLattice()       */
-/*Post:                                                */
-/*      - mean shift filtering has been applied to the */
-/*        input image using a user defined kernel      */
-/*      - the filtered image is stored in the private  */
-/*        data members of the msImageProcessor class.  */
-/*******************************************************/
-
-void msImageProcessor::OptimizedFilter2(float sigmaS, float sigmaR)
-{
-
-	//if confidence map is null set it to zero
-	if(!weightMap)
-	{
-		weightMap = new float [L];
-		int i;
-		for(i = 0; i < L; i++)
-			weightMap[i] = 0;
-	}
-
-	// Declare Variables
-	int		iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
-	float	*modeCandidatePoint;
-	double	mvAbs, diff, el;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-	
-	// Initialize mode table used for basin of attraction
-	memset(modeTable, 0, width*height);
-
-	// Allocate memory mode candidate data point...
-	//floating point version
-	modeCandidatePoint	= new float	[N];
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-	for(i = 0; i < L; i++)
-	{
-		// if a mode was already assigned to this data point
-		// then skip this point, otherwise proceed to
-		// find its mode by applying mean shift...
-		if (modeTable[i] == 1)
-			continue;
-
-		// initialize point list...
-		pointCount = 0;
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-		yk[0] = i%width;
-		yk[1] = i/width;
-		for(j = 0; j < N; j++)
-			yk[j+2] = data[N*i+j];
-		
-		// Calculate the mean shift vector using the lattice
-		OptLatticeMSVector(Mh, yk);
-		
-		// Calculate its magnitude squared
-		mvAbs = 0;
-		for(j = 0; j < lN; j++)
-			mvAbs += Mh[j]*Mh[j];
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// check to see if the current mode location is in the
-			// basin of attraction...
-
-			// calculate the location of yk on the lattice
-			modeCandidateX	= (int) (yk[0]+0.5);
-			modeCandidateY	= (int) (yk[1]+0.5);
-			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
-
-			// if mvAbs != 0 (yk did indeed move) then check
-			// location basin_i in the mode table to see if
-			// this data point either:
-			
-			// (1) has not been associated with a mode yet
-			//     (modeTable[basin_i] = 0), so associate
-			//     it with this one
-			//
-			// (2) it has been associated with a mode other
-			//     than the one that this data point is converging
-			//     to (modeTable[basin_i] = 1), so assign to
-			//     this data point the same mode as that of basin_i
-
-			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
-			{
-				// obtain the data point at basin_i to
-				// see if it is within h*TC_DIST_FACTOR of
-				// of yk
-				for (j = 0; j < N; j++)
-					modeCandidatePoint[j] = data[N*modeCandidate_i + j];
-				
-				// check basin on non-spatial data spaces only
-				k = 1;
-				s = 0;
-				diff = 0;
-				while ((diff < TC_DIST_FACTOR) && (k<kp))
-				{
-					diff = 0;
-					for (p=0; p<P[k]; p++)
-					{
-						el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
-						diff += el*el;
-					}
-					s+=P[k];
-					k++;
-				}
-
-				// if the data point at basin_i is within
-				// a distance of h*TC_DIST_FACTOR of yk
-				// then depending on modeTable[basin_i] perform
-				// either (1) or (2)
-				if (diff < TC_DIST_FACTOR)
-				{
-					// if the data point at basin_i has not
-					// been associated to a mode then associate
-					// it with the mode that this one will converge
-					// to
-					if (modeTable[modeCandidate_i] == 0)
-					{
-						// no mode associated yet so associate
-						// it with this one...
-						pointList[pointCount++]		= modeCandidate_i;
-						modeTable[modeCandidate_i]	= 2;
-
-					} else
-					{
-
-						// the mode has already been associated with
-						// another mode, thererfore associate this one
-						// mode and the modes in the point list with
-						// the mode associated with data[basin_i]...
-
-						// store the mode infor int yk using msRawData...
-						for (j = 0; j < N; j++)
-							yk[j+2] = msRawData[modeCandidate_i*N+j];
-
-						// update mode table for this data point
-						// indicating that a mode has been associated
-						// with it
-						modeTable[i] = 1;
-
-                  // indicate that a mode has been associated
-						// to this data point (data[i])
-						mvAbs = -1;
-
-						// stop mean shift calculation...
-						break;
-					}
-				}
-			}
-			
-			// Calculate the mean shift vector at the new
-			// window location using lattice
-			OptLatticeMSVector(Mh, yk);
-			
-			// Calculate its magnitude squared
-			mvAbs = 0;
-			for(j = 0; j < lN; j++)
-				mvAbs += Mh[j]*Mh[j];
-
-			// Increment interation count
-			iterationCount++;
-			
-		}
-
-		// if a mode was not associated with this data point
-		// yet then perform a shift the window center yk one
-		// last time using the mean shift vector...
-		if (mvAbs >= 0)
-		{
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-
-         // update mode table for this data point
-		   // indicating that a mode has been associated
-   		// with it
-			modeTable[i] = 1;
-		}
-		
-		// associate the data point indexed by
-		// the point list with the mode stored
-		// by yk
-		for (j = 0; j < pointCount; j++)
-		{
-			// obtain the point location from the
-			// point list
-			modeCandidate_i = pointList[j];
-
-			// update the mode table for this point
-			modeTable[modeCandidate_i] = 1;
-
-			//store result into msRawData...
-			for(k = 0; k < N; k++)
-				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
-		}
-
-
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;
-		
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	
-	// de-allocate memory
-	delete [] modeCandidatePoint;
-	delete [] yk;
-	delete [] Mh;
-	
-	// done.
-	return;
-
-}
-
-	/*/\/\/\/\/\/\/\/\/\/\/\*/
-	/* Image Classification */
-	/*\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Connect                                              */
-/*******************************************************/
-/*Classifies the regions of the mean shift filtered    */
-/*image.                                               */
-/*******************************************************/
-/*Post:                                                */
-/*      - the regions of the mean shift image have been*/
-/*        classified using the private classification  */
-/*        structure of the msImageProcessor Class.     */
-/*        Namely, each region uniquely identified by   */
-/*        its LUV color  (stored by LUV_data) and loc- */
-/*        ation has been labeled and its area computed */
-/*        via an eight-connected fill.                 */
-/*******************************************************/
-
-void msImageProcessor::Connect( void )
-{
-
-	//define eight connected neighbors
-	neigh[0]	= 1;
-	neigh[1]	= 1-width;
-	neigh[2]	= -width;
-	neigh[3]	= -(1+width);
-	neigh[4]	= -1;
-	neigh[5]	= width-1;
-	neigh[6]	= width;
-	neigh[7]	= width+1;
-
-	//initialize labels and modePointCounts
-	int i;
-	for(i = 0; i < width*height; i++)
-	{
-		labels[i]			= -1;
-		modePointCounts[i]	=  0;
-	}
-
-	//Traverse the image labeling each new region encountered
-	int k, label = -1;
-	for(i = 0; i < height*width; i++)
-	{
-		//if this region has not yet been labeled - label it
-		if(labels[i] < 0)
-		{
-			//assign new label to this region
-			labels[i] = ++label;
-
-			//copy region color into modes
-			for(k = 0; k < N; k++)
-            modes[(N*label)+k] = LUV_data[(N*i)+k];
-//				modes[(N*label)+k]	= (float)(LUV_data[(N*i)+k]);
-
-			//populate labels with label for this specified region
-			//calculating modePointCounts[label]...
-			Fill(i, label);
-		}
-	}
-
-	//calculate region count using label
-	regionCount	= label+1;
-
-	//done.
-	return;
-}
-
-/*******************************************************/
-/*Fill                                                 */
-/*******************************************************/
-/*Given a region seed and a region label, Fill uses    */
-/*the region seed to perform an eight-connected fill   */
-/*for the specified region, labeling all pixels con-   */
-/*tained by the region with the specified label:       */
-/*label.                                               */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - regionLoc is a region seed - a pixel that is */
-/*        identified as being part of the region       */
-/*        labled using the label, label.               */
-/*Post:                                                */
-/*      - all pixels belonging to the region specified */
-/*        by regionLoc (having the same integer LUV    */
-/*        value specified by LUV_data) are classified  */
-/*        as one region by labeling each pixel in the  */
-/*        image clasification structure using label    */
-/*        via an eight-connected fill.                 */
-/*******************************************************/
-
-void msImageProcessor::Fill(int regionLoc, int label)
-{
-
-	//declare variables
-	int	i, k, neighLoc, neighborsFound, imageSize	= width*height;
-
-	//Fill region starting at region location
-	//using labels...
-
-	//initialzie indexTable
-	int	index		= 0;
-	indexTable[0]	= regionLoc;
-
-	//increment mode point counts for this region to
-	//indicate that one pixel belongs to this region
-	modePointCounts[label]++;
-
-	while(true)
-	{
-
-		//assume no neighbors will be found
-		neighborsFound	= 0;
-
-		//check the eight connected neighbors at regionLoc -
-		//if a pixel has similar color to that located at 
-		//regionLoc then declare it as part of this region
-		for(i = 0; i < 8; i++)
-		{
-         // no need
-         /*
-			//if at boundary do not check certain neighbors because
-			//they do not exist...
-			if((regionLoc%width == 0)&&((i == 3)||(i == 4)||(i == 5)))
-				continue;
-			if((regionLoc%(width-1) == 0)&&((i == 0)||(i == 1)||(i == 7)))
-				continue;
-         */   
-
-			//check bounds and if neighbor has been already labeled
-			neighLoc			= regionLoc + neigh[i];
-			if((neighLoc >= 0)&&(neighLoc < imageSize)&&(labels[neighLoc] < 0))
-			{
-				for(k = 0; k < N; k++)
-				{
-//					if(LUV_data[(regionLoc*N)+k] != LUV_data[(neighLoc*N)+k])
-               if (fabs(LUV_data[(regionLoc*N)+k]-LUV_data[(neighLoc*N)+k])>=LUV_treshold)
-						break;
-				}
-				
-				//neighbor i belongs to this region so label it and
-				//place it onto the index table buffer for further
-				//processing
-				if(k == N)
-				{
-					//assign label to neighbor i
-					labels[neighLoc]	= label;
-					
-					//increment region point count
-					modePointCounts[label]++;
-					
-					//place index of neighbor i onto the index tabel buffer
-					indexTable[++index]	= neighLoc;
-					
-					//indicate that a neighboring region pixel was
-					//identified
-					neighborsFound	= 1;
-				}
-			}
-		}
-
-		//check the indexTable to see if there are any more
-		//entries to be explored - if so explore them, otherwise
-		//exit the loop - we are finished
-		if(neighborsFound)
-			regionLoc	= indexTable[index];
-		else if (index > 1)
-			regionLoc	= indexTable[--index];
-		else
-			break; //fill complete
-	}
-
-	//done.
-	return;
-
-}
-
-	/*/\/\/\/\/\/\/\/\*/
-	/*  Image Pruning */
-	/*\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Build Region Adjacency Matrix                        */
-/*******************************************************/
-/*Constructs a region adjacency matrix.                */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the classification data structure has been   */
-/*        constructed.                                 */
-/*Post:                                                */
-/*      - a region adjacency matrix has been built     */
-/*        using the classification data structure.     */
-/*******************************************************/
-
-void msImageProcessor::BuildRAM( void )
-{
-
-	//Allocate memory for region adjacency matrix if it hasn't already been allocated
-	if((!raList)&&((!(raList = new RAList [regionCount]))||(!(raPool = new RAList [NODE_MULTIPLE*regionCount]))))
-	{
-		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
-		return;
-	}
-
-	//initialize the region adjacency list
-	int i;
-	for(i = 0; i < regionCount; i++)
-	{
-		raList[i].edgeStrength		= 0;
-		raList[i].edgePixelCount	= 0;
-		raList[i].label				= i;
-		raList[i].next				= NULL;
-	}
-
-	//initialize RAM free list
-	freeRAList	= raPool;
-	for(i = 0; i < NODE_MULTIPLE*regionCount-1; i++)
-	{
-		raPool[i].edgeStrength		= 0;
-		raPool[i].edgePixelCount	= 0;
-		raPool[i].next = &raPool[i+1];
-	}
-	raPool[NODE_MULTIPLE*regionCount-1].next	= NULL;
-
-	//traverse the labeled image building
-	//the RAM by looking to the right of
-	//and below the current pixel location thus
-	//determining if a given region is adjacent
-	//to another
-	int		j, curLabel, rightLabel, bottomLabel, exists;
-	RAList	*raNode1, *raNode2, *oldRAFreeList;
-	for(i = 0; i < height - 1; i++)
-	{
-		//check the right and below neighbors
-		//for pixel locations whose x < width - 1
-		for(j = 0; j < width - 1; j++)
-		{
-			//calculate pixel labels
-			curLabel	= labels[i*width+j    ];	//current pixel
-			rightLabel	= labels[i*width+j+1  ];	//right   pixel
-			bottomLabel	= labels[(i+1)*width+j];	//bottom  pixel
-
-			//check to the right, if the label of
-			//the right pixel is not the same as that
-			//of the current one then region[j] and region[j+1]
-			//are adjacent to one another - update the RAM
-			if(curLabel != rightLabel)
-			{
-				//obtain RAList object from region adjacency free
-				//list
-				raNode1			= freeRAList;
-				raNode2			= freeRAList->next;
-
-				//keep a pointer to the old region adj. free
-				//list just in case nodes already exist in respective
-				//region lists
-				oldRAFreeList	= freeRAList;
-
-				//update region adjacency free list
-				freeRAList		= freeRAList->next->next;
-
-				//populate RAList nodes
-				raNode1->label	= curLabel;
-				raNode2->label	= rightLabel;
-
-				//insert nodes into the RAM
-				exists			= 0;
-				raList[curLabel  ].Insert(raNode2);
-				exists			= raList[rightLabel].Insert(raNode1);
-
-				//if the node already exists then place
-				//nodes back onto the region adjacency
-				//free list
-				if(exists)
-					freeRAList = oldRAFreeList;
-
-			}
-
-			//check below, if the label of
-			//the bottom pixel is not the same as that
-			//of the current one then region[j] and region[j+width]
-			//are adjacent to one another - update the RAM
-			if(curLabel != bottomLabel)
-			{
-				//obtain RAList object from region adjacency free
-				//list
-				raNode1			= freeRAList;
-				raNode2			= freeRAList->next;
-
-				//keep a pointer to the old region adj. free
-				//list just in case nodes already exist in respective
-				//region lists
-				oldRAFreeList	= freeRAList;
-
-				//update region adjacency free list
-				freeRAList		= freeRAList->next->next;
-
-				//populate RAList nodes
-				raNode1->label	= curLabel;
-				raNode2->label	= bottomLabel;
-
-				//insert nodes into the RAM
-				exists			= 0;
-				raList[curLabel  ].Insert(raNode2);
-				exists			= raList[bottomLabel].Insert(raNode1);
-
-				//if the node already exists then place
-				//nodes back onto the region adjacency
-				//free list
-				if(exists)
-					freeRAList = oldRAFreeList;
-
-			}
-
-		}
-
-		//check only to the bottom neighbors of the right boundary
-		//pixels...
-
-		//calculate pixel locations (j = width-1)
-		curLabel	= labels[i*width+j    ];	//current pixel
-		bottomLabel = labels[(i+1)*width+j];	//bottom  pixel
-
-		//check below, if the label of
-		//the bottom pixel is not the same as that
-		//of the current one then region[j] and region[j+width]
-		//are adjacent to one another - update the RAM
-		if(curLabel != bottomLabel)
-		{
-			//obtain RAList object from region adjacency free
-			//list
-			raNode1			= freeRAList;
-			raNode2			= freeRAList->next;
-			
-			//keep a pointer to the old region adj. free
-			//list just in case nodes already exist in respective
-			//region lists
-			oldRAFreeList	= freeRAList;
-			
-			//update region adjacency free list
-			freeRAList		= freeRAList->next->next;
-			
-			//populate RAList nodes
-			raNode1->label	= curLabel;
-			raNode2->label	= bottomLabel;
-			
-			//insert nodes into the RAM
-			exists			= 0;
-			raList[curLabel  ].Insert(raNode2);
-			exists			= raList[bottomLabel].Insert(raNode1);
-			
-			//if the node already exists then place
-			//nodes back onto the region adjacency
-			//free list
-			if(exists)
-				freeRAList = oldRAFreeList;
-
-		}
-	}
-
-	//check only to the right neighbors of the bottom boundary
-	//pixels...
-
-	//check the right for pixel locations whose x < width - 1
-	for(j = 0; j < width - 1; j++)
-	{
-		//calculate pixel labels (i = height-1)
-		curLabel	= labels[i*width+j    ];	//current pixel
-		rightLabel	= labels[i*width+j+1  ];	//right   pixel
-		
-		//check to the right, if the label of
-		//the right pixel is not the same as that
-		//of the current one then region[j] and region[j+1]
-		//are adjacent to one another - update the RAM
-		if(curLabel != rightLabel)
-		{
-			//obtain RAList object from region adjacency free
-			//list
-			raNode1			= freeRAList;
-			raNode2			= freeRAList->next;
-
-			//keep a pointer to the old region adj. free
-			//list just in case nodes already exist in respective
-			//region lists
-			oldRAFreeList	= freeRAList;
-			
-			//update region adjacency free list
-			freeRAList		= freeRAList->next->next;
-			
-			//populate RAList nodes
-			raNode1->label	= curLabel;
-			raNode2->label	= rightLabel;
-			
-			//insert nodes into the RAM
-			exists			= 0;
-			raList[curLabel  ].Insert(raNode2);
-			exists			= raList[rightLabel].Insert(raNode1);
-			
-			//if the node already exists then place
-			//nodes back onto the region adjacency
-			//free list
-			if(exists)
-				freeRAList = oldRAFreeList;
-
-		}
-
-	}
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Destroy Region Adjacency Matrix                      */
-/*******************************************************/
-/*Destroy a region adjacency matrix.                   */
-/*******************************************************/
-/*Post:                                                */
-/*      - the region adjacency matrix has been destr-  */
-/*        oyed: (1) its memory has been de-allocated,  */
-/*        (2) the RAM structure has been initialize    */
-/*        for re-use.                                  */
-/*******************************************************/
-
-void msImageProcessor::DestroyRAM( void )
-{
-
-	//de-allocate memory for region adjaceny list
-	if (raList)				delete [] raList;
-	if (raPool)				delete [] raPool;
-
-	//initialize region adjacency matrix
-	raList				= NULL;
-	freeRAList			= NULL;
-	raPool				= NULL;
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Transitive Closure                                   */
-/*******************************************************/
-/*Applies transitive closure to the RAM updating       */
-/*labels, modes and modePointCounts to reflect the new */
-/*set of merged regions resulting from transitive clo- */
-/*sure.                                                */
-/*******************************************************/
-/*Post:                                                */
-/*      - transitive closure has been applied to the   */
-/*        regions classified by the RAM and labels,    */
-/*        modes and modePointCounts have been updated  */
-/*        to reflect the new set of mergd regions res- */
-/*        ulting from transitive closure.              */
-/*******************************************************/
-
-void msImageProcessor::TransitiveClosure( void )
-{
-
-	//Step (1):
-
-	// Build RAM using classifiction structure originally
-	// generated by the method GridTable::Connect()
-	BuildRAM();
-
-	//Step (1a):
-	//Compute weights of weight graph using confidence map
-	//(if defined)
-	if(weightMapDefined)	ComputeEdgeStrengths();
-
-	//Step (2):
-
-	//Treat each region Ri as a disjoint set:
-
-	// - attempt to join Ri and Rj for all i != j that are neighbors and
-	//   whose associated modes are a normalized distance of < 0.5 from one
-	//   another
-
-	// - the label of each region in the raList is treated as a pointer to the
-	//   canonical element of that region (e.g. raList[i], initially has raList[i].label = i,
-	//   namely each region is initialized to have itself as its canonical element).
-
-	//Traverse RAM attempting to join raList[i] with its neighbors...
-	int		i, iCanEl, neighCanEl;
-	float	threshold;
-	RAList	*neighbor;
-	for(i = 0; i < regionCount; i++)
-	{
-		//aquire first neighbor in region adjacency list pointed to
-		//by raList[i]
-		neighbor	= raList[i].next;
-
-		//compute edge strenght threshold using global and local
-		//epsilon
-		if(epsilon > raList[i].edgeStrength)
-			threshold   = epsilon;
-		else
-			threshold   = raList[i].edgeStrength;
-
-		//traverse region adjacency list of region i, attempting to join
-		//it with regions whose mode is a normalized distance < 0.5 from
-		//that of region i...
-		while(neighbor)
-		{
-			//attempt to join region and neighbor...
-			if((InWindow(i, neighbor->label))&&(neighbor->edgeStrength < epsilon))
-			{
-				//region i and neighbor belong together so join them
-				//by:
-
-				// (1) find the canonical element of region i
-				iCanEl		= i;
-				while(raList[iCanEl].label != iCanEl)
-					iCanEl		= raList[iCanEl].label;
-
-				// (2) find the canonical element of neighboring region
-				neighCanEl	= neighbor->label;
-				while(raList[neighCanEl].label != neighCanEl)
-					neighCanEl	= raList[neighCanEl].label;
-
-				// if the canonical elements of are not the same then assign
-				// the canonical element having the smaller label to be the parent
-				// of the other region...
-				if(iCanEl < neighCanEl)
-					raList[neighCanEl].label	= iCanEl;
-				else
-				{
-					//must replace the canonical element of previous
-					//parent as well
-					raList[raList[iCanEl].label].label	= neighCanEl;
-
-					//re-assign canonical element
-					raList[iCanEl].label				= neighCanEl;
-				}
-			}
-
-			//check the next neighbor...
-			neighbor	= neighbor->next;
-
-		}
-	}
-
-	// Step (3):
-
-	// Level binary trees formed by canonical elements
-	for(i = 0; i < regionCount; i++)
-	{
-		iCanEl	= i;
-		while(raList[iCanEl].label != iCanEl)
-			iCanEl	= raList[iCanEl].label;
-		raList[i].label	= iCanEl;
-	}
-
-	// Step (4):
-
-	//Traverse joint sets, relabeling image.
-
-	// (a)
-
-	// Accumulate modes and re-compute point counts using canonical
-	// elements generated by step 2.
-
-	//allocate memory for mode and point count temporary buffers...
-	float	*modes_buffer	= new float	[N*regionCount];
-	int		*MPC_buffer		= new int	[regionCount];
-
-	//initialize buffers to zero
-	for(i = 0; i < regionCount; i++)
-		MPC_buffer[i]	= 0;
-	for(i = 0; i < N*regionCount; i++)
-		modes_buffer[i]	= 0;
-
-	//traverse raList accumulating modes and point counts
-	//using canoncial element information...
-	int k, iMPC;
-	for(i = 0; i < regionCount; i++)
-	{
-
-		//obtain canonical element of region i
-		iCanEl	= raList[i].label;
-
-		//obtain mode point count of region i
-		iMPC	= modePointCounts[i];
-
-		//accumulate modes_buffer[iCanEl]
-		for(k = 0; k < N; k++)
-			modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
-
-		//accumulate MPC_buffer[iCanEl]
-		MPC_buffer[iCanEl] += iMPC;
-
-	}
-
-	// (b)
-
-	// Re-label new regions of the image using the canonical
-	// element information generated by step (2)
-
-	// Also use this information to compute the modes of the newly
-	// defined regions, and to assign new region point counts in
-	// a consecute manner to the modePointCounts array
-
-	//allocate memory for label buffer
-	int	*label_buffer	= new int [regionCount];
-
-	//initialize label buffer to -1
-	for(i = 0; i < regionCount; i++)
-		label_buffer[i]	= -1;
-
-	//traverse raList re-labeling the regions
-	int	label = -1;
-	for(i = 0; i < regionCount; i++)
-	{
-		//obtain canonical element of region i
-		iCanEl	= raList[i].label;
-		if(label_buffer[iCanEl] < 0)
-		{
-			//assign a label to the new region indicated by canonical
-			//element of i
-			label_buffer[iCanEl]	= ++label;
-
-			//recompute mode storing the result in modes[label]...
-			iMPC	= MPC_buffer[iCanEl];
-			for(k = 0; k < N; k++)
-				modes[(N*label)+k]	= (modes_buffer[(N*iCanEl)+k])/(iMPC);
-
-			//assign a corresponding mode point count for this region into
-			//the mode point counts array using the MPC buffer...
-			modePointCounts[label]	= MPC_buffer[iCanEl];
-		}
-	}
-
-	//re-assign region count using label counter
-	int	oldRegionCount	= regionCount;
-	regionCount	= label+1;
-
-	// (c)
-
-	// Use the label buffer to reconstruct the label map, which specified
-	// the new image given its new regions calculated above
-
-	for(i = 0; i < height*width; i++)
-		labels[i]	= label_buffer[raList[labels[i]].label];
-
-	//de-allocate memory
-	delete [] modes_buffer;
-	delete [] MPC_buffer;
-	delete [] label_buffer;
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Compute Edge Strengths                               */
-/*******************************************************/
-/*Computes the a weight for each link in the region    */
-/*graph maintined by the RAM, resulting in a weighted  */
-/*graph in which the weights consist of a confidence   */
-/*between zero and one indicating if the regions are   */
-/*separated by a strong or weak edge.                  */
-/*******************************************************/
-/*Post:                                                */
-/*      - an edge strength has been computed between   */
-/*        each region of the image and placed as a     */
-/*        weight in the RAM to be used during transi-  */
-/*        tive closure.                                */
-/*******************************************************/
-
-void msImageProcessor::ComputeEdgeStrengths( void )
-{
-
-	//initialize visit table - used to keep track
-	//of which pixels have already been visited such
-	//as not to contribute their strength value to
-	//a boundary sum multiple times...
-	memset(visitTable, 0, L*sizeof(unsigned char));
-
-	//traverse labeled image computing edge strengths
-	//(excluding image boundary)...
-	int    x, y, dp, curLabel, rightLabel, bottomLabel;
-	RAList *curRegion;
-	for(y = 1; y < height-1; y++)
-	{
-		for(x = 1; x < width-1; x++)
-		{
-			//compute data point location using x and y
-			dp = y*width + x;
-
-			//obtain labels at different pixel locations
-			curLabel	= labels[dp      ];	//current pixel
-			rightLabel	= labels[dp+1    ];	//right   pixel
-			bottomLabel	= labels[dp+width];	//bottom  pixel
-
-			//check right and bottom neighbor to see if there is a
-			//change in label then we are at an edge therefore record
-			//the edge strength at this edge accumulating its value
-			//in the RAM...
-			if(curLabel != rightLabel)
-			{
-				//traverse into RAM...
-				curRegion = &raList[curLabel];
-				while((curRegion)&&(curRegion->label != rightLabel))
-					curRegion = curRegion->next;
-
-				//this should not occur...
-				assert(curRegion);
-
-				//accumulate edge strength
-				curRegion->edgeStrength   += weightMap[dp] + weightMap[dp+1];
-				curRegion->edgePixelCount += 2;
-			}
-
-			if(curLabel != bottomLabel)
-			{
-				//traverse into RAM...
-				curRegion = &raList[curLabel];
-				while((curRegion)&&(curRegion->label != bottomLabel))
-					curRegion = curRegion->next;
-
-				//this should not occur...
-				assert(curRegion);
-
-				//accumulate edge strength
-				if(curLabel == rightLabel)
-				{
-					curRegion->edgeStrength   += weightMap[dp] + weightMap[dp+width];
-					curRegion->edgePixelCount += 2;
-				} 
-				else
-				{
-					curRegion->edgeStrength	  += weightMap[dp+width];
-					curRegion->edgePixelCount += 1;
-				}
-
-			}
-		}
-	}
-
-	//compute strengths using accumulated strengths obtained above...
-	RAList *neighborRegion;
-	float	edgeStrength;
-	int		edgePixelCount;
-	for(x = 0; x < regionCount; x++)
-	{
-		//traverse the region list of the current region
-		curRegion	= &raList[x];
-		curRegion	= curRegion->next;
-		while(curRegion)
-		{
-			//with the assumption that regions having a smaller
-			//label in the current region list have already
-			//had their edge strengths computed, only compute
-			//edge strengths for the regions whose label is greater
-			//than x, the current region (region list) under
-			//consideration...
-			curLabel = curRegion->label;
-			if(curLabel > x)
-			{
-				//obtain pointer to the element identifying the
-				//current region in the neighbors region list...
-				neighborRegion = &raList[curLabel];
-				while((neighborRegion)&&(neighborRegion->label != x))
-					neighborRegion = neighborRegion->next;
-				
-				//this should not occur...
-				assert(neighborRegion);
-				
-				//compute edge strengths using accumulated confidence
-				//value and pixel count
-				if((edgePixelCount = curRegion->edgePixelCount + neighborRegion->edgePixelCount) != 0)
-				{
-					//compute edge strength
-					edgeStrength	= curRegion->edgeStrength + neighborRegion->edgeStrength;
-					edgeStrength	/= edgePixelCount;
-					
-					//store edge strength and pixel count for corresponding regions
-					curRegion->edgeStrength		= neighborRegion->edgeStrength		= edgeStrength;
-					curRegion->edgePixelCount	= neighborRegion->edgePixelCount	= edgePixelCount;
-				}
-			}
-
-			//traverse to the next region in the region adjacency list
-			//of the current region x
-			curRegion = curRegion->next;
-
-		}
-	}
-
-	//compute average edge strength amongst the edges connecting
-	//it to each of its neighbors
-	int numNeighbors;
-	for(x = 0; x < regionCount; x++)
-	{
-		//traverse the region list of the current region
-		//accumulating weights
-		curRegion		= &raList[x];
-		curRegion		= curRegion->next;
-		edgeStrength	= 0;
-		numNeighbors	= 0;
-		while(curRegion)
-		{
-			numNeighbors++;
-			edgeStrength   += curRegion->edgeStrength;
-			curRegion		= curRegion->next;
-		}
-
-		//divide by the number of regions connected
-		//to the current region
-		if(numNeighbors) edgeStrength /= numNeighbors;
-
-		//store the result in the raList for region
-		//x
-		raList[x].edgeStrength = edgeStrength;
-	}
-
-	//traverse raList and output the resulting list
-	//to a file
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Prune                                                */
-/*******************************************************/
-/*Prunes regions from the image whose pixel density    */
-/*is less than a specified threshold.                  */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - minRegion is the minimum allowable pixel de- */
-/*        nsity a region may have without being pruned */
-/*        from the image                               */
-/*Post:                                                */
-/*      - regions whose pixel density is less than     */
-/*        or equal to minRegion have been pruned from  */
-/*        the image.                                   */
-/*******************************************************/
-
-void msImageProcessor::Prune(int minRegion)
-{
-	
-	//Allocate Memory for temporary buffers...
-	
-	//allocate memory for mode and point count temporary buffers...
-	float	*modes_buffer	= new float	[N*regionCount];
-	int		*MPC_buffer		= new int	[regionCount];
-	
-	//allocate memory for label buffer
-	int	*label_buffer		= new int	[regionCount];
-	
-	//Declare variables
-	int		i, k, candidate, iCanEl, neighCanEl, iMPC, label, oldRegionCount, minRegionCount;
-	double	minSqDistance, neighborDistance;
-	RAList	*neighbor;
-	
-	//Apply pruning algorithm to classification structure, removing all regions whose area
-	//is under the threshold area minRegion (pixels)
-	do
-	{
-		//Assume that no region has area under threshold area  of 
-		minRegionCount	= 0;		
-
-		//Step (1):
-		
-		// Build RAM using classifiction structure originally
-		// generated by the method GridTable::Connect()
-		BuildRAM();
-		
-		// Step (2):
-		
-		// Traverse the RAM joining regions whose area is less than minRegion (pixels)
-		// with its respective candidate region.
-		
-		// A candidate region is a region that displays the following properties:
-		
-		//	- it is adjacent to the region being pruned
-		
-		//  - the distance of its mode is a minimum to that of the region being pruned
-		//    such that or it is the only adjacent region having an area greater than
-		//    minRegion
-		
-		for(i = 0; i < regionCount; i++)
-		{
-			//if the area of the ith region is less than minRegion
-			//join it with its candidate region...
-
-			//*******************************************************************************
-
-			//Note: Adjust this if statement if a more sophisticated pruning criterion
-			//      is desired. Basically in this step a region whose area is less than
-			//      minRegion is pruned by joining it with its "closest" neighbor (in color).
-			//      Therefore, by placing a different criterion for fusing a region the
-			//      pruning method may be altered to implement a more sophisticated algorithm.
-
-			//*******************************************************************************
-
-			if(modePointCounts[i] < minRegion)
-			{
-				//update minRegionCount to indicate that a region
-				//having area less than minRegion was found
-				minRegionCount++;
-
-				//obtain a pointer to the first region in the
-				//region adjacency list of the ith region...
-				neighbor	= raList[i].next;
-				
-				//calculate the distance between the mode of the ith
-				//region and that of the neighboring region...
-				candidate		= neighbor->label;
-				minSqDistance	= SqDistance(i, candidate);
-				
-				//traverse region adjacency list of region i and select
-				//a candidate region
-				neighbor	= neighbor->next;
-				while(neighbor)
-				{
-
-					//calculate the square distance between region i
-					//and current neighbor...
-					neighborDistance = SqDistance(i, neighbor->label);
-
-					//if this neighbors square distance to region i is less
-					//than minSqDistance, then select this neighbor as the
-					//candidate region for region i
-					if(neighborDistance < minSqDistance)
-					{
-						minSqDistance	= neighborDistance;
-						candidate		= neighbor->label;
-					}
-
-					//traverse region list of region i
-					neighbor	= neighbor->next;
-
-				}
-
-				//join region i with its candidate region:
-
-				// (1) find the canonical element of region i
-				iCanEl		= i;
-				while(raList[iCanEl].label != iCanEl)
-					iCanEl		= raList[iCanEl].label;
-
-				// (2) find the canonical element of neighboring region
-				neighCanEl	= candidate;
-				while(raList[neighCanEl].label != neighCanEl)
-					neighCanEl	= raList[neighCanEl].label;
-
-				// if the canonical elements of are not the same then assign
-				// the canonical element having the smaller label to be the parent
-				// of the other region...
-				if(iCanEl < neighCanEl)
-					raList[neighCanEl].label	= iCanEl;
-				else
-				{
-					//must replace the canonical element of previous
-					//parent as well
-					raList[raList[iCanEl].label].label	= neighCanEl;
-
-					//re-assign canonical element
-					raList[iCanEl].label				= neighCanEl;
-				}
-			}
-		}
-
-		// Step (3):
-		
-		// Level binary trees formed by canonical elements
-		for(i = 0; i < regionCount; i++)
-		{
-			iCanEl	= i;
-			while(raList[iCanEl].label != iCanEl)
-				iCanEl	= raList[iCanEl].label;
-			raList[i].label	= iCanEl;
-		}
-		
-		// Step (4):
-		
-		//Traverse joint sets, relabeling image.
-		
-		// Accumulate modes and re-compute point counts using canonical
-		// elements generated by step 2.
-		
-		//initialize buffers to zero
-		for(i = 0; i < regionCount; i++)
-			MPC_buffer[i]	= 0;
-		for(i = 0; i < N*regionCount; i++)
-			modes_buffer[i]	= 0;
-		
-		//traverse raList accumulating modes and point counts
-		//using canoncial element information...
-		for(i = 0; i < regionCount; i++)
-		{
-			
-			//obtain canonical element of region i
-			iCanEl	= raList[i].label;
-			
-			//obtain mode point count of region i
-			iMPC	= modePointCounts[i];
-			
-			//accumulate modes_buffer[iCanEl]
-			for(k = 0; k < N; k++)
-				modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
-			
-			//accumulate MPC_buffer[iCanEl]
-			MPC_buffer[iCanEl] += iMPC;
-			
-		}
-		
-		// (b)
-		
-		// Re-label new regions of the image using the canonical
-		// element information generated by step (2)
-		
-		// Also use this information to compute the modes of the newly
-		// defined regions, and to assign new region point counts in
-		// a consecute manner to the modePointCounts array
-		
-		//initialize label buffer to -1
-		for(i = 0; i < regionCount; i++)
-			label_buffer[i]	= -1;
-		
-		//traverse raList re-labeling the regions
-		label = -1;
-		for(i = 0; i < regionCount; i++)
-		{
-			//obtain canonical element of region i
-			iCanEl	= raList[i].label;
-			if(label_buffer[iCanEl] < 0)
-			{
-				//assign a label to the new region indicated by canonical
-				//element of i
-				label_buffer[iCanEl]	= ++label;
-				
-				//recompute mode storing the result in modes[label]...
-				iMPC	= MPC_buffer[iCanEl];
-				for(k = 0; k < N; k++)
-					modes[(N*label)+k]	= (modes_buffer[(N*iCanEl)+k])/(iMPC);
-				
-				//assign a corresponding mode point count for this region into
-				//the mode point counts array using the MPC buffer...
-				modePointCounts[label]	= MPC_buffer[iCanEl];
-			}
-		}
-		
-		//re-assign region count using label counter
-		oldRegionCount	= regionCount;
-		regionCount		= label+1;
-		
-		// (c)
-		
-		// Use the label buffer to reconstruct the label map, which specified
-		// the new image given its new regions calculated above
-		
-		for(i = 0; i < height*width; i++)
-			labels[i]	= label_buffer[raList[labels[i]].label];
-
-		
-	}	while(minRegionCount > 0);
-
-	//de-allocate memory
-	delete [] modes_buffer;
-	delete [] MPC_buffer;
-	delete [] label_buffer;
-	
-	//done.
-	return;
-	
-}
-
-/*******************************************************/
-/*Define Boundaries                                    */
-/*******************************************************/
-/*Defines the boundaries for each region of the segm-  */
-/*ented image storing the result into a region list    */
-/*object.                                              */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - the image has been segmented and a classifi- */
-/*        cation structure has been created for this   */
-/*        image                                        */
-/*Post:                                                */
-/*      - the boundaries of the segmented image have   */
-/*        been defined and the boundaries of each reg- */
-/*        ion has been stored into a region list obj-  */
-/*        ect.                                         */
-/*******************************************************/
-
-void msImageProcessor::DefineBoundaries( void )
-{
-
-	//declare and allocate memory for boundary map and count
-	int	*boundaryMap,	*boundaryCount;
-	if((!(boundaryMap = new int [L]))||(!(boundaryCount = new int [regionCount])))
-		ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory.");
-
-	//initialize boundary map and count
-	int i;
-	for(i = 0; i < L; i++)
-		boundaryMap[i]		= -1;
-	for(i = 0; i < regionCount; i++)
-		boundaryCount[i]	=  0;
-
-	//initialize and declare total boundary count -
-	//the total number of boundary pixels present in
-	//the segmented image
-	int	totalBoundaryCount	= 0;
-
-	//traverse the image checking the right and bottom
-	//four connected neighbors of each pixel marking
-	//boundary map with the boundaries of each region and
-	//incrementing boundaryCount using the label information
-
-	//***********************************************************************
-	//***********************************************************************
-
-	int		j, label, dataPoint;
-
-	//first row (every pixel is a boundary pixel)
-	for(i = 0; i < width; i++)
-	{
-			boundaryMap[i]		= label	= labels[i];
-			boundaryCount[label]++;
-			totalBoundaryCount++;
-	}
-
-	//define boundaries for all rows except for the first
-	//and last one...
-	for(i = 1; i < height - 1; i++)
-	{
-		//mark the first pixel in an image row as an image boundary...
-		dataPoint				= i*width;
-		boundaryMap[dataPoint]	= label	= labels[dataPoint];
-		boundaryCount[label]++;
-		totalBoundaryCount++;
-
-		for(j = 1; j < width - 1; j++)
-		{
-			//define datapoint and its right and bottom
-			//four connected neighbors
-			dataPoint		= i*width+j;
-
-			//check four connected neighbors if they are
-			//different this pixel is a boundary pixel
-			label	= labels[dataPoint];
-			if((label != labels[dataPoint-1])    ||(label != labels[dataPoint+1])||
-			   (label != labels[dataPoint-width])||(label != labels[dataPoint+width]))
-			{
-				boundaryMap[dataPoint]		= label	= labels[dataPoint];
-				boundaryCount[label]++;
-				totalBoundaryCount++;
-			}
-		}
-
-		//mark the last pixel in an image row as an image boundary...
-		dataPoint				= (i+1)*width-1;
-		boundaryMap[dataPoint]	= label	= labels[dataPoint];
-		boundaryCount[label]++;
-		totalBoundaryCount++;
-
-	}
-
-	//last row (every pixel is a boundary pixel) (i = height-1)
-	register int	start	= (height-1)*width, stop = height*width;
-	for(i = start; i < stop; i++)
-	{
-		boundaryMap[i]		= label	= labels[i];
-		boundaryCount[label]++;
-		totalBoundaryCount++;
-	}
-
-	//***********************************************************************
-	//***********************************************************************
-
-	//store boundary locations into a boundary buffer using
-	//boundary map and count
-
-	//***********************************************************************
-	//***********************************************************************
-
-	int	*boundaryBuffer	= new int [totalBoundaryCount], *boundaryIndex	= new int [regionCount];
-
-	//use boundary count to initialize boundary index...
-	int counter = 0;
-	for(i = 0; i < regionCount; i++)
-	{
-		boundaryIndex[i]	= counter;
-		counter			   += boundaryCount[i];
-	}
-
-	//traverse boundary map placing the boundary pixel
-	//locations into the boundaryBuffer
-	for(i = 0; i < L; i++)
-	{
-		//if its a boundary pixel store it into
-		//the boundary buffer
-		if((label = boundaryMap[i]) >= 0)
-		{
-			boundaryBuffer[boundaryIndex[label]] = i;
-			boundaryIndex[label]++;
-		}
-	}
-
-	//***********************************************************************
-	//***********************************************************************
-
-	//store the boundary locations stored by boundaryBuffer into
-	//the region list for each region
-
-	//***********************************************************************
-	//***********************************************************************
-
-	//destroy the old region list
-	if(regionList)	delete regionList;
-
-	//create a new region list
-	if(!(regionList	= new RegionList(regionCount, totalBoundaryCount, N)))
-		ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory.");
-
-	//add boundary locations for each region using the boundary
-	//buffer and boundary counts
-	counter	= 0;
-	for(i = 0; i < regionCount; i++)
-	{
-		regionList->AddRegion(i, boundaryCount[i], &boundaryBuffer[counter]);
-		counter += boundaryCount[i];
-	}
-
-	//***********************************************************************
-	//***********************************************************************
-
-   // dealocate local used memory
- 	delete [] boundaryMap;
-   delete [] boundaryCount;
-	delete [] boundaryBuffer;
-   delete [] boundaryIndex;
-
-	//done.
-	return;
-
-}
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/*  Image Data Searching/Distance Calculation */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-		
-/*******************************************************/
-/*In Window                                            */
-/*******************************************************/
-/*Returns true if the two specified data points are    */
-/*within rR of each other.                             */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - mode1 and mode2 are indeces into msRawData   */
-/*        specifying the modes of the pixels having    */
-/*        these indeces.                               */
-/*Post:                                                */
-/*      - true is returned if mode1 and mode2 are wi-  */
-/*        thin rR of one another, false is returned    */
-/*        otherwise.                                   */
-/*******************************************************/
-
-bool msImageProcessor::InWindow(int mode1, int mode2)
-{
-	int		k		= 1, s	= 0, p;
-	double	diff	= 0, el;
-	while((diff < 0.25)&&(k != kp)) // Partial Distortion Search
-	{
-		//Calculate distance squared of sub-space s	
-		diff = 0;
-		for(p = 0; p < P[k]; p++)
-		{
-			el    = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
-			if((!p)&&(k == 1)&&(modes[mode1*N] > 80))
-				diff += 4*el*el;
-			else
-				diff += el*el;
-		}
-		
-		//next subspace
-		s += P[k];
-		k++;
-	}
-	return (bool)(diff < 0.25);
-}
-
-/*******************************************************/
-/*Square Distance                                      */
-/*******************************************************/
-/*Computs the normalized square distance between two   */
-/*modes.                                               */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - mode1 and mode2 are indeces into the modes   */
-/*        array specifying two modes of the image      */
-/*Post:                                                */
-/*      - the normalized square distance between modes */
-/*        indexed by mode1 and mode2 has been calc-    */
-/*        ulated and the result has been returned.     */
-/*******************************************************/
-
-float msImageProcessor::SqDistance(int mode1, int mode2)
-{
-
-	int		k		= 1, s	= 0, p;
-	float	dist	= 0, el;
-	for(k = 1; k < kp; k++)
-	{
-		//Calculate distance squared of sub-space s	
-		for(p = 0; p < P[k]; p++)
-		{
-			el    = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
-			dist += el*el;
-		}
-		
-		//next subspace
-		s += P[k];
-		k++;
-	}
-
-	//return normalized square distance between modes
-	//1 and 2
-	return dist;
-
-}
-
-	/*/\/\/\/\/\/\/\/\/\/\*/
-	/*  Memory Management */
-	/*\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Initialize Output                                    */
-/*******************************************************/
-/*Allocates memory needed by the mean shift image pro- */
-/*cessor class output storage data structure.          */
-/*******************************************************/
-/*Post:                                                */
-/*      - the memory needed by the output storage      */
-/*        structure of this class has been (re-)allo-  */
-/*        cated.                                       */
-/*******************************************************/
-
-void msImageProcessor::InitializeOutput( void )
-{
-
-	//De-allocate memory if output was defined for previous image
-	DestroyOutput();
-
-	//Allocate memory for msRawData (filtered image output)
-	if(!(msRawData = new float [L*N]))
-	{
-		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
-		return;
-	}
-
-	//Allocate memory used to store image modes and their corresponding regions...
-	if((!(modes = new float [L*(N+2)]))||(!(labels = new int [L]))||(!(modePointCounts = new int [L]))||(!(indexTable	= new int [L])))
-	{
-		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory");
-		return;
-	}
-
-	//Allocate memory for integer modes used to perform connected components
-	//(image labeling)...
-//	if(!(LUV_data = new	int [N*L]))
-   if (!(LUV_data = new float[N*L]))
-	{
-		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory");
-		return;
-	}
-
-	//indicate that the class output storage structure has been defined
-	class_state.OUTPUT_DEFINED	= true;
-
-}
-
-/*******************************************************/
-/*Destroy Output                                       */
-/*******************************************************/
-/*De-allocates memory needed by the mean shift image   */
-/*processor class output storage data structure.       */
-/*******************************************************/
-/*Post:                                                */
-/*      - the memory needed by the output storage      */
-/*        structure of this class has been de-alloc-   */
-/*        ated.                                        */
-/*      - the output storage structure has been init-  */
-/*        ialized for re-use.                          */
-/*******************************************************/
-
-void msImageProcessor::DestroyOutput( void )
-{
-
-	//de-allocate memory for msRawData (filtered image output)
-	if (msRawData)			delete [] msRawData;
-
-	//de-allocate memory used by output storage and image
-	//classification structure
-	if (modes)				delete [] modes;
-	if (labels)				delete [] labels;
-	if (modePointCounts)	delete [] modePointCounts;
-	if (indexTable)			delete [] indexTable;
-	
-	//de-allocate memory for LUV_data
-	if (LUV_data)			delete [] LUV_data;
-		
-	//initialize data members for re-use...
-
-	//initialize output structures...
-	msRawData			= NULL;
-
-	//re-initialize classification structure
-	modes						= NULL;
-	labels						= NULL;
-	modePointCounts				= NULL;
-	regionCount					= 0;
-
-	//indicate that the output has been destroyed
-	class_state.OUTPUT_DEFINED	= false;
-
-	//done.
-	return;
-
-}
-
-// NEW
-void msImageProcessor::NewOptimizedFilter1(float sigmaS, float sigmaR)
-{
-	// Declare Variables
-	int		iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
-	double	mvAbs, diff, el;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-
-   // let's use some temporary data
-   float* sdata;
-   sdata = new float[lN*L];
-
-   // copy the scaled data
-   int idxs, idxd;
-   idxs = idxd = 0;
-   if (N==3)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else if (N==1)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         for (j=0; j<N; j++)
-            sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   }
-   // index the data in the 3d buckets (x, y, L)
-   int* buckets;
-   int* slist;
-   slist = new int[L];
-   int bucNeigh[27];
-
-   float sMins; // just for L
-   float sMaxs[3]; // for all
-   sMaxs[0] = width/sigmaS;
-   sMaxs[1] = height/sigmaS;
-   sMins = sMaxs[2] = sdata[2];
-   idxs = 2;
-   float cval;
-   for(i=0; i<L; i++)
-   {
-      cval = sdata[idxs];
-      if (cval < sMins)
-         sMins = cval;
-      else if (cval > sMaxs[2])
-         sMaxs[2] = cval;
-
-      idxs += lN;
-   }
-
-   int nBuck1, nBuck2, nBuck3;
-   int cBuck1, cBuck2, cBuck3, cBuck;
-   nBuck1 = (int) (sMaxs[0] + 3);
-   nBuck2 = (int) (sMaxs[1] + 3);
-   nBuck3 = (int) (sMaxs[2] - sMins + 3);
-   buckets = new int[nBuck1*nBuck2*nBuck3];
-   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
-      buckets[i] = -1;
-
-   idxs = 0;
-   for(i=0; i<L; i++)
-   {
-      // find bucket for current data and add it to the list
-      cBuck1 = (int) sdata[idxs] + 1;
-      cBuck2 = (int) sdata[idxs+1] + 1;
-      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-
-      slist[i] = buckets[cBuck];
-      buckets[cBuck] = i;
-
-      idxs += lN;
-   }
-   // init bucNeigh
-   idxd = 0;
-   for (cBuck1=-1; cBuck1<=1; cBuck1++)
-   {
-      for (cBuck2=-1; cBuck2<=1; cBuck2++)
-      {
-         for (cBuck3=-1; cBuck3<=1; cBuck3++)
-         {
-            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         }
-      }
-   }
-   double wsuml, weight;
-   double hiLTr = 80.0/sigmaR;
-   // done indexing/hashing
-
-	
-	// Initialize mode table used for basin of attraction
-	memset(modeTable, 0, width*height);
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-
-	for(i = 0; i < L; i++)
-	{
-		// if a mode was already assigned to this data point
-		// then skip this point, otherwise proceed to
-		// find its mode by applying mean shift...
-		if (modeTable[i] == 1)
-			continue;
-
-		// initialize point list...
-		pointCount = 0;
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-      idxs = i*lN;
-      for (j=0; j<lN; j++)
-         yk[j] = sdata[idxs+j];
-		
-		// Calculate the mean shift vector using the lattice
-		// LatticeMSVector(Mh, yk); // modify to new
-      /*****************************************************/
-   	// Initialize mean shift vector
-	   for(j = 0; j < lN; j++)
-   		Mh[j] = 0;
-   	wsuml = 0;
-      // uniformLSearch(Mh, yk_ptr); // modify to new
-      // find bucket of yk
-      cBuck1 = (int) yk[0] + 1;
-      cBuck2 = (int) yk[1] + 1;
-      cBuck3 = (int) (yk[2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-      for (j=0; j<27; j++)
-      {
-         idxd = buckets[cBuck+bucNeigh[j]];
-         // list parse, crt point is cHeadList
-         while (idxd>=0)
-         {
-            idxs = lN*idxd;
-            // determine if inside search window
-            el = sdata[idxs+0]-yk[0];
-            diff = el*el;
-            el = sdata[idxs+1]-yk[1];
-            diff += el*el;
-
-            if (diff < 1.0)
-            {
-               el = sdata[idxs+2]-yk[2];
-               if (yk[2] > hiLTr)
-                  diff = 4*el*el;
-               else
-                  diff = el*el;
-
-               if (N>1)
-               {
-                  el = sdata[idxs+3]-yk[3];
-                  diff += el*el;
-                  el = sdata[idxs+4]-yk[4];
-                  diff += el*el;
-               }
-
-               if (diff < 1.0)
-               {
-                  weight = 1-weightMap[idxd];
-                  for (k=0; k<lN; k++)
-                     Mh[k] += weight*sdata[idxs+k];
-                  wsuml += weight;
-               }
-            }
-            idxd = slist[idxd];
-         }
-      }
-   	if (wsuml > 0)
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = Mh[j]/wsuml - yk[j];
-   	}
-   	else
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = 0;
-   	}
-      /*****************************************************/
-   	// Calculate its magnitude squared
-		//mvAbs = 0;
-		//for(j = 0; j < lN; j++)
-		//	mvAbs += Mh[j]*Mh[j];
-      mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
-      if (N==3)
-         mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
-      else
-         mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
-
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// check to see if the current mode location is in the
-			// basin of attraction...
-
-			// calculate the location of yk on the lattice
-			modeCandidateX	= (int) (sigmaS*yk[0]+0.5);
-			modeCandidateY	= (int) (sigmaS*yk[1]+0.5);
-			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
-
-			// if mvAbs != 0 (yk did indeed move) then check
-			// location basin_i in the mode table to see if
-			// this data point either:
-			
-			// (1) has not been associated with a mode yet
-			//     (modeTable[basin_i] = 0), so associate
-			//     it with this one
-			//
-			// (2) it has been associated with a mode other
-			//     than the one that this data point is converging
-			//     to (modeTable[basin_i] = 1), so assign to
-			//     this data point the same mode as that of basin_i
-
-			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
-			{
-				// obtain the data point at basin_i to
-				// see if it is within h*TC_DIST_FACTOR of
-				// of yk
-            diff = 0;
-            idxs = lN*modeCandidate_i;
-            for (k=2; k<lN; k++)
-            {
-               el = sdata[idxs+k] - yk[k];
-               diff += el*el;
-            }
-
-				// if the data point at basin_i is within
-				// a distance of h*TC_DIST_FACTOR of yk
-				// then depending on modeTable[basin_i] perform
-				// either (1) or (2)
-				if (diff < TC_DIST_FACTOR)
-				{
-					// if the data point at basin_i has not
-					// been associated to a mode then associate
-					// it with the mode that this one will converge
-					// to
-					if (modeTable[modeCandidate_i] == 0)
-					{
-						// no mode associated yet so associate
-						// it with this one...
-						pointList[pointCount++]		= modeCandidate_i;
-						modeTable[modeCandidate_i]	= 2;
-
-					} else
-					{
-
-						// the mode has already been associated with
-						// another mode, thererfore associate this one
-						// mode and the modes in the point list with
-						// the mode associated with data[basin_i]...
-
-						// store the mode info into yk using msRawData...
-						for (j = 0; j < N; j++)
-							yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
-
-						// update mode table for this data point
-						// indicating that a mode has been associated
-						// with it
-						modeTable[i] = 1;
-
-						// indicate that a mode has been associated
-						// to this data point (data[i])
-						mvAbs = -1;
-
-						// stop mean shift calculation...
-						break;
-					}
-				}
-			}
-			
-         // Calculate the mean shift vector at the new
-         // window location using lattice
-         // Calculate the mean shift vector using the lattice
-         // LatticeMSVector(Mh, yk); // modify to new
-         /*****************************************************/
-         // Initialize mean shift vector
-         for(j = 0; j < lN; j++)
-            Mh[j] = 0;
-         wsuml = 0;
-         // uniformLSearch(Mh, yk_ptr); // modify to new
-         // find bucket of yk
-         cBuck1 = (int) yk[0] + 1;
-         cBuck2 = (int) yk[1] + 1;
-         cBuck3 = (int) (yk[2] - sMins) + 1;
-         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         for (j=0; j<27; j++)
-         {
-            idxd = buckets[cBuck+bucNeigh[j]];
-            // list parse, crt point is cHeadList
-            while (idxd>=0)
-            {
-               idxs = lN*idxd;
-               // determine if inside search window
-               el = sdata[idxs+0]-yk[0];
-               diff = el*el;
-               el = sdata[idxs+1]-yk[1];
-               diff += el*el;
-               
-               if (diff < 1.0)
-               {
-                  el = sdata[idxs+2]-yk[2];
-                  if (yk[2] > hiLTr)
-                     diff = 4*el*el;
-                  else
-                     diff = el*el;
-                  
-                  if (N>1)
-                  {
-                     el = sdata[idxs+3]-yk[3];
-                     diff += el*el;
-                     el = sdata[idxs+4]-yk[4];
-                     diff += el*el;
-                  }
-                  
-                  if (diff < 1.0)
-                  {
-                     weight = 1-weightMap[idxd];
-                     for (k=0; k<lN; k++)
-                        Mh[k] += weight*sdata[idxs+k];
-                     wsuml += weight;
-                  }
-               }
-               idxd = slist[idxd];
-            }
-         }
-         if (wsuml > 0)
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = Mh[j]/wsuml - yk[j];
-         }
-         else
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = 0;
-         }
-         /*****************************************************/
-			
-			// Calculate its magnitude squared
-			//mvAbs = 0;
-			//for(j = 0; j < lN; j++)
-			//	mvAbs += Mh[j]*Mh[j];
-         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
-         if (N==3)
-            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
-         else
-            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
-
-			// Increment iteration count
-			iterationCount++;
-			
-		}
-
-		// if a mode was not associated with this data point
-		// yet associate it with yk...
-		if (mvAbs >= 0)
-		{
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// update mode table for this data point
-			// indicating that a mode has been associated
-			// with it
-			modeTable[i] = 1;
-
-		}
-		
-      for (k=0; k<N; k++)
-         yk[k+2] *= sigmaR;
-
-		// associate the data point indexed by
-		// the point list with the mode stored
-		// by yk
-		for (j = 0; j < pointCount; j++)
-		{
-			// obtain the point location from the
-			// point list
-			modeCandidate_i = pointList[j];
-
-			// update the mode table for this point
-			modeTable[modeCandidate_i] = 1;
-
-			//store result into msRawData...
-			for(k = 0; k < N; k++)
-				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
-		}
-
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;		
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	// de-allocate memory
-   delete [] buckets;
-   delete [] slist;
-   delete [] sdata;
-
-	delete [] yk;
-	delete [] Mh;
-	
-	// done.
-	return;
-
-}
-
-// NEW
-void msImageProcessor::NewOptimizedFilter2(float sigmaS, float sigmaR)
-{
-	// Declare Variables
-	int		iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
-	double	mvAbs, diff, el;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-
-   // let's use some temporary data
-   float* sdata;
-   sdata = new float[lN*L];
-
-   // copy the scaled data
-   int idxs, idxd;
-   idxs = idxd = 0;
-   if (N==3)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else if (N==1)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         for (j=0; j<N; j++)
-            sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   }
-   // index the data in the 3d buckets (x, y, L)
-   int* buckets;
-   int* slist;
-   slist = new int[L];
-   int bucNeigh[27];
-
-   float sMins; // just for L
-   float sMaxs[3]; // for all
-   sMaxs[0] = width/sigmaS;
-   sMaxs[1] = height/sigmaS;
-   sMins = sMaxs[2] = sdata[2];
-   idxs = 2;
-   float cval;
-   for(i=0; i<L; i++)
-   {
-      cval = sdata[idxs];
-      if (cval < sMins)
-         sMins = cval;
-      else if (cval > sMaxs[2])
-         sMaxs[2] = cval;
-
-      idxs += lN;
-   }
-
-   int nBuck1, nBuck2, nBuck3;
-   int cBuck1, cBuck2, cBuck3, cBuck;
-   nBuck1 = (int) (sMaxs[0] + 3);
-   nBuck2 = (int) (sMaxs[1] + 3);
-   nBuck3 = (int) (sMaxs[2] - sMins + 3);
-   buckets = new int[nBuck1*nBuck2*nBuck3];
-   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
-      buckets[i] = -1;
-
-   idxs = 0;
-   for(i=0; i<L; i++)
-   {
-      // find bucket for current data and add it to the list
-      cBuck1 = (int) sdata[idxs] + 1;
-      cBuck2 = (int) sdata[idxs+1] + 1;
-      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-
-      slist[i] = buckets[cBuck];
-      buckets[cBuck] = i;
-
-      idxs += lN;
-   }
-   // init bucNeigh
-   idxd = 0;
-   for (cBuck1=-1; cBuck1<=1; cBuck1++)
-   {
-      for (cBuck2=-1; cBuck2<=1; cBuck2++)
-      {
-         for (cBuck3=-1; cBuck3<=1; cBuck3++)
-         {
-            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         }
-      }
-   }
-   double wsuml, weight;
-   double hiLTr = 80.0/sigmaR;
-   // done indexing/hashing
-
-	
-	// Initialize mode table used for basin of attraction
-	memset(modeTable, 0, width*height);
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-
-	for(i = 0; i < L; i++)
-	{
-		// if a mode was already assigned to this data point
-		// then skip this point, otherwise proceed to
-		// find its mode by applying mean shift...
-		if (modeTable[i] == 1)
-			continue;
-
-		// initialize point list...
-		pointCount = 0;
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-      idxs = i*lN;
-      for (j=0; j<lN; j++)
-         yk[j] = sdata[idxs+j];
-		
-		// Calculate the mean shift vector using the lattice
-		// LatticeMSVector(Mh, yk); // modify to new
-      /*****************************************************/
-   	// Initialize mean shift vector
-	   for(j = 0; j < lN; j++)
-   		Mh[j] = 0;
-   	wsuml = 0;
-      // uniformLSearch(Mh, yk_ptr); // modify to new
-      // find bucket of yk
-      cBuck1 = (int) yk[0] + 1;
-      cBuck2 = (int) yk[1] + 1;
-      cBuck3 = (int) (yk[2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-      for (j=0; j<27; j++)
-      {
-         idxd = buckets[cBuck+bucNeigh[j]];
-         // list parse, crt point is cHeadList
-         while (idxd>=0)
-         {
-            idxs = lN*idxd;
-            // determine if inside search window
-            el = sdata[idxs+0]-yk[0];
-            diff = el*el;
-            el = sdata[idxs+1]-yk[1];
-            diff += el*el;
-
-            if (diff < 1.0)
-            {
-               el = sdata[idxs+2]-yk[2];
-               if (yk[2] > hiLTr)
-                  diff = 4*el*el;
-               else
-                  diff = el*el;
-
-               if (N>1)
-               {
-                  el = sdata[idxs+3]-yk[3];
-                  diff += el*el;
-                  el = sdata[idxs+4]-yk[4];
-                  diff += el*el;
-               }
-
-               if (diff < 1.0)
-               {
-                  weight = 1-weightMap[idxd];
-                  for (k=0; k<lN; k++)
-                     Mh[k] += weight*sdata[idxs+k];
-                  wsuml += weight;
-
-      				//set basin of attraction mode table
-                  if (diff < speedThreshold)
-                  {
-				         if(modeTable[idxd] == 0)
-				         {
-         					pointList[pointCount++]	= idxd;
-					         modeTable[idxd]	= 2;
-      				   }
-                  }
-               }
-            }
-            idxd = slist[idxd];
-         }
-      }
-   	if (wsuml > 0)
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = Mh[j]/wsuml - yk[j];
-   	}
-   	else
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = 0;
-   	}
-      /*****************************************************/
-   	// Calculate its magnitude squared
-		//mvAbs = 0;
-		//for(j = 0; j < lN; j++)
-		//	mvAbs += Mh[j]*Mh[j];
-      mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
-      if (N==3)
-         mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
-      else
-         mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
-
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// check to see if the current mode location is in the
-			// basin of attraction...
-
-			// calculate the location of yk on the lattice
-			modeCandidateX	= (int) (sigmaS*yk[0]+0.5);
-			modeCandidateY	= (int) (sigmaS*yk[1]+0.5);
-			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
-
-			// if mvAbs != 0 (yk did indeed move) then check
-			// location basin_i in the mode table to see if
-			// this data point either:
-			
-			// (1) has not been associated with a mode yet
-			//     (modeTable[basin_i] = 0), so associate
-			//     it with this one
-			//
-			// (2) it has been associated with a mode other
-			//     than the one that this data point is converging
-			//     to (modeTable[basin_i] = 1), so assign to
-			//     this data point the same mode as that of basin_i
-
-			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
-			{
-				// obtain the data point at basin_i to
-				// see if it is within h*TC_DIST_FACTOR of
-				// of yk
-            diff = 0;
-            idxs = lN*modeCandidate_i;
-            for (k=2; k<lN; k++)
-            {
-               el = sdata[idxs+k] - yk[k];
-               diff += el*el;
-            }
-
-				// if the data point at basin_i is within
-				// a distance of h*TC_DIST_FACTOR of yk
-				// then depending on modeTable[basin_i] perform
-				// either (1) or (2)
-				if (diff < speedThreshold)
-				{
-					// if the data point at basin_i has not
-					// been associated to a mode then associate
-					// it with the mode that this one will converge
-					// to
-					if (modeTable[modeCandidate_i] == 0)
-					{
-						// no mode associated yet so associate
-						// it with this one...
-						pointList[pointCount++]		= modeCandidate_i;
-						modeTable[modeCandidate_i]	= 2;
-
-					} else
-					{
-
-						// the mode has already been associated with
-						// another mode, thererfore associate this one
-						// mode and the modes in the point list with
-						// the mode associated with data[basin_i]...
-
-						// store the mode info into yk using msRawData...
-						for (j = 0; j < N; j++)
-							yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
-
-						// update mode table for this data point
-						// indicating that a mode has been associated
-						// with it
-						modeTable[i] = 1;
-
-						// indicate that a mode has been associated
-						// to this data point (data[i])
-						mvAbs = -1;
-
-						// stop mean shift calculation...
-						break;
-					}
-				}
-			}
-			
-         // Calculate the mean shift vector at the new
-         // window location using lattice
-         // Calculate the mean shift vector using the lattice
-         // LatticeMSVector(Mh, yk); // modify to new
-         /*****************************************************/
-         // Initialize mean shift vector
-         for(j = 0; j < lN; j++)
-            Mh[j] = 0;
-         wsuml = 0;
-         // uniformLSearch(Mh, yk_ptr); // modify to new
-         // find bucket of yk
-         cBuck1 = (int) yk[0] + 1;
-         cBuck2 = (int) yk[1] + 1;
-         cBuck3 = (int) (yk[2] - sMins) + 1;
-         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         for (j=0; j<27; j++)
-         {
-            idxd = buckets[cBuck+bucNeigh[j]];
-            // list parse, crt point is cHeadList
-            while (idxd>=0)
-            {
-               idxs = lN*idxd;
-               // determine if inside search window
-               el = sdata[idxs+0]-yk[0];
-               diff = el*el;
-               el = sdata[idxs+1]-yk[1];
-               diff += el*el;
-               
-               if (diff < 1.0)
-               {
-                  el = sdata[idxs+2]-yk[2];
-                  if (yk[2] > hiLTr)
-                     diff = 4*el*el;
-                  else
-                     diff = el*el;
-                  
-                  if (N>1)
-                  {
-                     el = sdata[idxs+3]-yk[3];
-                     diff += el*el;
-                     el = sdata[idxs+4]-yk[4];
-                     diff += el*el;
-                  }
-                  
-                  if (diff < 1.0)
-                  {
-                     weight = 1-weightMap[idxd];
-                     for (k=0; k<lN; k++)
-                        Mh[k] += weight*sdata[idxs+k];
-                     wsuml += weight;
-
-         				//set basin of attraction mode table
-                     if (diff < speedThreshold)
-                     {
-   				         if(modeTable[idxd] == 0)
-				            {
-            					pointList[pointCount++]	= idxd;
-					            modeTable[idxd]	= 2;
-      				      }
-                     }
-
-                  }
-               }
-               idxd = slist[idxd];
-            }
-         }
-         if (wsuml > 0)
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = Mh[j]/wsuml - yk[j];
-         }
-         else
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = 0;
-         }
-         /*****************************************************/
-			
-			// Calculate its magnitude squared
-			//mvAbs = 0;
-			//for(j = 0; j < lN; j++)
-			//	mvAbs += Mh[j]*Mh[j];
-         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
-         if (N==3)
-            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
-         else
-            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
-
-			// Increment iteration count
-			iterationCount++;
-			
-		}
-
-		// if a mode was not associated with this data point
-		// yet associate it with yk...
-		if (mvAbs >= 0)
-		{
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// update mode table for this data point
-			// indicating that a mode has been associated
-			// with it
-			modeTable[i] = 1;
-
-		}
-		
-      for (k=0; k<N; k++)
-         yk[k+2] *= sigmaR;
-
-		// associate the data point indexed by
-		// the point list with the mode stored
-		// by yk
-		for (j = 0; j < pointCount; j++)
-		{
-			// obtain the point location from the
-			// point list
-			modeCandidate_i = pointList[j];
-
-			// update the mode table for this point
-			modeTable[modeCandidate_i] = 1;
-
-			//store result into msRawData...
-			for(k = 0; k < N; k++)
-				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
-		}
-
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;		
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	// de-allocate memory
-   delete [] buckets;
-   delete [] slist;
-   delete [] sdata;
-
-	delete [] yk;
-	delete [] Mh;
-	
-	// done.
-	return;
-
-}
-
-void msImageProcessor::NewNonOptimizedFilter(float sigmaS, float sigmaR)
-{
-
-	// Declare Variables
-	int   iterationCount, i, j, k;
-	double mvAbs, diff, el;
-	
-	//make sure that a lattice height and width have
-	//been defined...
-	if(!height)
-	{
-		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
-		return;
-	}
-
-	//re-assign bandwidths to sigmaS and sigmaR
-	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
-	{
-		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
-		return;
-	}
-	
-	//define input data dimension with lattice
-	int lN	= N + 2;
-	
-	// Traverse each data point applying mean shift
-	// to each data point
-	
-	// Allcocate memory for yk
-	double	*yk		= new double [lN];
-	
-	// Allocate memory for Mh
-	double	*Mh		= new double [lN];
-
-   // let's use some temporary data
-   double* sdata;
-   sdata = new double[lN*L];
-
-   // copy the scaled data
-   int idxs, idxd;
-   idxs = idxd = 0;
-   if (N==3)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else if (N==1)
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i/width)/sigmaS;
-         sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   } else
-   {
-      for(i=0; i<L; i++)
-      {
-         sdata[idxs++] = (i%width)/sigmaS;
-         sdata[idxs++] = (i%width)/sigmaS;
-         for (j=0; j<N; j++)
-            sdata[idxs++] = data[idxd++]/sigmaR;
-      }
-   }
-   // index the data in the 3d buckets (x, y, L)
-   int* buckets;
-   int* slist;
-   slist = new int[L];
-   int bucNeigh[27];
-
-   double sMins; // just for L
-   double sMaxs[3]; // for all
-   sMaxs[0] = width/sigmaS;
-   sMaxs[1] = height/sigmaS;
-   sMins = sMaxs[2] = sdata[2];
-   idxs = 2;
-   double cval;
-   for(i=0; i<L; i++)
-   {
-      cval = sdata[idxs];
-      if (cval < sMins)
-         sMins = cval;
-      else if (cval > sMaxs[2])
-         sMaxs[2] = cval;
-
-      idxs += lN;
-   }
-
-   int nBuck1, nBuck2, nBuck3;
-   int cBuck1, cBuck2, cBuck3, cBuck;
-   nBuck1 = (int) (sMaxs[0] + 3);
-   nBuck2 = (int) (sMaxs[1] + 3);
-   nBuck3 = (int) (sMaxs[2] - sMins + 3);
-   buckets = new int[nBuck1*nBuck2*nBuck3];
-   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
-      buckets[i] = -1;
-
-   idxs = 0;
-   for(i=0; i<L; i++)
-   {
-      // find bucket for current data and add it to the list
-      cBuck1 = (int) sdata[idxs] + 1;
-      cBuck2 = (int) sdata[idxs+1] + 1;
-      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-
-      slist[i] = buckets[cBuck];
-      buckets[cBuck] = i;
-
-      idxs += lN;
-   }
-   // init bucNeigh
-   idxd = 0;
-   for (cBuck1=-1; cBuck1<=1; cBuck1++)
-   {
-      for (cBuck2=-1; cBuck2<=1; cBuck2++)
-      {
-         for (cBuck3=-1; cBuck3<=1; cBuck3++)
-         {
-            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         }
-      }
-   }
-   double wsuml, weight;
-   double hiLTr = 80.0/sigmaR;
-   // done indexing/hashing
-	
-	// proceed ...
-#ifdef PROMPT
-	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\n 0%%");
-#endif
-#endif
-
-	for(i = 0; i < L; i++)
-	{
-
-		// Assign window center (window centers are
-		// initialized by createLattice to be the point
-		// data[i])
-      idxs = i*lN;
-      for (j=0; j<lN; j++)
-         yk[j] = sdata[idxs+j];
-		
-		// Calculate the mean shift vector using the lattice
-		// LatticeMSVector(Mh, yk);
-      /*****************************************************/
-   	// Initialize mean shift vector
-	   for(j = 0; j < lN; j++)
-   		Mh[j] = 0;
-   	wsuml = 0;
-      // uniformLSearch(Mh, yk_ptr); // modify to new
-      // find bucket of yk
-      cBuck1 = (int) yk[0] + 1;
-      cBuck2 = (int) yk[1] + 1;
-      cBuck3 = (int) (yk[2] - sMins) + 1;
-      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-      for (j=0; j<27; j++)
-      {
-         idxd = buckets[cBuck+bucNeigh[j]];
-         // list parse, crt point is cHeadList
-         while (idxd>=0)
-         {
-            idxs = lN*idxd;
-            // determine if inside search window
-            el = sdata[idxs+0]-yk[0];
-            diff = el*el;
-            el = sdata[idxs+1]-yk[1];
-            diff += el*el;
-
-            if (diff < 1.0)
-            {
-               el = sdata[idxs+2]-yk[2];
-               if (yk[2] > hiLTr)
-                  diff = 4*el*el;
-               else
-                  diff = el*el;
-
-               if (N>1)
-               {
-                  el = sdata[idxs+3]-yk[3];
-                  diff += el*el;
-                  el = sdata[idxs+4]-yk[4];
-                  diff += el*el;
-               }
-
-               if (diff < 1.0)
-               {
-                  weight = 1-weightMap[idxd];
-                  for (k=0; k<lN; k++)
-                     Mh[k] += weight*sdata[idxs+k];
-                  wsuml += weight;
-               }
-            }
-            idxd = slist[idxd];
-         }
-      }
-   	if (wsuml > 0)
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = Mh[j]/wsuml - yk[j];
-   	}
-   	else
-   	{
-		   for(j = 0; j < lN; j++)
-   			Mh[j] = 0;
-   	}
-      /*****************************************************/
-		
-		// Calculate its magnitude squared
-		mvAbs = 0;
-		for(j = 0; j < lN; j++)
-			mvAbs += Mh[j]*Mh[j];
-		
-		// Keep shifting window center until the magnitude squared of the
-		// mean shift vector calculated at the window center location is
-		// under a specified threshold (Epsilon)
-		
-		// NOTE: iteration count is for speed up purposes only - it
-		//       does not have any theoretical importance
-		iterationCount = 1;
-		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
-		{
-			
-			// Shift window location
-			for(j = 0; j < lN; j++)
-				yk[j] += Mh[j];
-			
-			// Calculate the mean shift vector at the new
-			// window location using lattice
-			// LatticeMSVector(Mh, yk);
-         /*****************************************************/
-         // Initialize mean shift vector
-         for(j = 0; j < lN; j++)
-            Mh[j] = 0;
-         wsuml = 0;
-         // uniformLSearch(Mh, yk_ptr); // modify to new
-         // find bucket of yk
-         cBuck1 = (int) yk[0] + 1;
-         cBuck2 = (int) yk[1] + 1;
-         cBuck3 = (int) (yk[2] - sMins) + 1;
-         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
-         for (j=0; j<27; j++)
-         {
-            idxd = buckets[cBuck+bucNeigh[j]];
-            // list parse, crt point is cHeadList
-            while (idxd>=0)
-            {
-               idxs = lN*idxd;
-               // determine if inside search window
-               el = sdata[idxs+0]-yk[0];
-               diff = el*el;
-               el = sdata[idxs+1]-yk[1];
-               diff += el*el;
-               
-               if (diff < 1.0)
-               {
-                  el = sdata[idxs+2]-yk[2];
-                  if (yk[2] > hiLTr)
-                     diff = 4*el*el;
-                  else
-                     diff = el*el;
-                  
-                  if (N>1)
-                  {
-                     el = sdata[idxs+3]-yk[3];
-                     diff += el*el;
-                     el = sdata[idxs+4]-yk[4];
-                     diff += el*el;
-                  }
-                  
-                  if (diff < 1.0)
-                  {
-                     weight = 1-weightMap[idxd];
-                     for (k=0; k<lN; k++)
-                        Mh[k] += weight*sdata[idxs+k];
-                     wsuml += weight;
-                  }
-               }
-               idxd = slist[idxd];
-            }
-         }
-         if (wsuml > 0)
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = Mh[j]/wsuml - yk[j];
-         }
-         else
-         {
-            for(j = 0; j < lN; j++)
-               Mh[j] = 0;
-         }
-         /*****************************************************/
-			
-			// Calculate its magnitude squared
-			//mvAbs = 0;
-			//for(j = 0; j < lN; j++)
-			//	mvAbs += Mh[j]*Mh[j];
-         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
-         if (N==3)
-            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
-         else
-            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
-
-			// Increment interation count
-			iterationCount++;
-		}
-
-		// Shift window location
-		for(j = 0; j < lN; j++)
-			yk[j] += Mh[j];
-		
-		//store result into msRawData...
-		for(j = 0; j < N; j++)
-			msRawData[N*i+j] = (float)(yk[j+2]*sigmaR);
-
-		// Prompt user on progress
-#ifdef SHOW_PROGRESS
-		percent_complete = (float)(i/(float)(L))*100;
-		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
-#endif
-	
-		// Check to see if the algorithm has been halted
-		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
-			break;
-	}
-	
-	// Prompt user that filtering is completed
-#ifdef PROMPT
-#ifdef SHOW_PROGRESS
-	msSys.Prompt("\r");
-#endif
-	msSys.Prompt("done.");
-#endif
-	
-	// de-allocate memory
-   delete [] buckets;
-   delete [] slist;
-   delete [] sdata;
-
-	delete [] yk;
-	delete [] Mh;
-
-	// done.
-	return;
-
-}
-
-void msImageProcessor::SetSpeedThreshold(float speedUpThreshold)
-{
-   speedThreshold = speedUpThreshold;
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Mean Shift Image Processor Class:
+  ================================
+
+	The following class inherits from the mean shift library
+	in order to perform the specialized tasks of image
+	segmentation and filtering.
+	
+	The definition of the Mean Shift Image Processor Class
+	is provided below. Its prototype is provided in
+	'msImageProcessor.h'.
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+//include image processor class prototype
+#include	"msImageProcessor.h"
+
+//include needed libraries
+#include	<math.h>
+#include	<stdio.h>
+#include	<assert.h>
+#include	<string.h>
+#include	<stdlib.h>
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /* Constructor/Destructor */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Class Constructor                                    */
+/*******************************************************/
+/*Post:                                                */
+/*      The msImageProcessor class has been properly   */
+/*      initialized.                                   */
+/*******************************************************/
+
+msImageProcessor::msImageProcessor( void )
+{
+
+	//intialize basin of attraction structure
+	//used by the filtering algorithm
+	modeTable			= NULL;
+	pointList			= NULL;
+	pointCount			= 0;
+
+	//initialize region list
+	regionList			= NULL;
+
+	//initialize output structures...
+	msRawData			= NULL;
+	labels				= NULL;
+	modes				= NULL;
+	modePointCounts		= NULL;
+	regionCount			= 0;
+
+	//intialize temporary buffers used for
+	//performing connected components
+	indexTable			= NULL;
+	LUV_data			= NULL;
+
+	//initialize region adjacency matrix
+	raList				= NULL;
+	freeRAList			= NULL;
+	raPool				= NULL;
+
+	//intialize visit table to having NULL entries
+	visitTable			= NULL;
+
+	//initialize epsilon such that transitive closure
+	//does not take edge strength into consideration when
+	//fusing regions of similar color
+	epsilon				= 1.0;
+
+	//initialize class state to indicate that
+	//an output data structure has not yet been
+	//created...
+	class_state.OUTPUT_DEFINED	= false;
+
+
+   LUV_treshold = 1.0;
+}
+
+/*******************************************************/
+/*Class Destructor                                     */
+/*******************************************************/
+/*Post:                                                */
+/*      The msImageProcessor class has been properly   */
+/*      destroyed.                                     */
+/*******************************************************/
+
+msImageProcessor::~msImageProcessor( void )
+{
+
+	//de-allocate memory
+	if(class_state.OUTPUT_DEFINED)	DestroyOutput();
+	if(regionList)					delete regionList;
+	regionList = NULL;
+
+	//done.
+
+}
+
+ /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+ /*  Input Image Declaration */
+ /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Define Image                                         */
+/*******************************************************/
+/*Uploads an image into the image segmenter class to   */
+/*be segmented.                                        */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - data_ is a one dimensional array of unsigned */
+/*        char RGB vectors                             */
+/*      - type is the type of the image: COLOR or      */
+/*        GREYSCALE                                    */
+/*      - height_ and width_ define the dimension of   */
+/*        the image                                    */
+/*      - if the image is of type GREYSCALE then       */
+/*        data containes only one number per pixel     */
+/*        location, where a pixel location is defined  */
+/*        by the index into the data array             */
+/*Post:                                                */
+/*      - the image specified has been uploaded into   */
+/*        the image segmenter class to be segmented.   */
+/*******************************************************/
+
+void msImageProcessor::DefineImage(byte *data_, imageType type, int height_, int width_)
+{
+
+	//obtain image dimension from image type
+	int dim;
+	if(type == COLOR)
+		dim	= 3;
+	else
+		dim = 1;
+
+	//perfor rgb to luv conversion
+	int		i;
+	float	*luv	= new float [height_*width_*dim];
+	if(dim == 1)
+	{
+		for(i = 0; i < height_*width_; i++)
+			luv[i]	= (float)(data_[i]);
+	}
+	else
+	{
+		for(i = 0; i < height_*width_; i++)
+			RGBtoLUV(&data_[dim*i], &luv[dim*i]);
+	}
+
+	//define input defined on a lattice using mean shift base class
+	DefineLInput(luv, height_, width_, dim);
+
+	//Define a default kernel if it has not been already
+	//defined by user
+	if(!h)
+	{
+		//define default kernel paramerters...
+		kernelType	k[2]		= {Uniform, Uniform};
+		int			P[2]		= {2, N};
+		float		tempH[2]	= {1.0 , 1.0};
+
+		//define default kernel in mean shift base class
+		DefineKernel(k, tempH, P, 2);
+	}
+
+	//de-allocate memory
+	delete [] luv;
+
+	//done.
+	return;
+
+}
+
+void msImageProcessor::DefineBgImage(byte* data_, imageType type, int height_, int width_)
+{
+
+	//obtain image dimension from image type
+	int dim;
+	if(type == COLOR)
+		dim	= 3;
+	else
+		dim = 1;
+
+	//perform texton classification
+	int		i;
+	float	*luv	= new float [height_*width_*dim];
+	if(dim == 1)
+	{
+		for(i = 0; i < height_*width_; i++)
+			luv[i]	= (float)(data_[i]);
+	}
+	else
+	{
+		for(i = 0; i < height_*width_; i++)
+			RGBtoLUV(&data_[dim*i], &luv[dim*i]);
+	}
+
+	//define input defined on a lattice using mean shift base class
+	DefineLInput(luv, height_, width_, dim);
+
+	//Define a default kernel if it has not been already
+	//defined by user
+	if(!h)
+	{
+		//define default kernel paramerters...
+		kernelType	k[2]		= {Uniform, Uniform};
+		int			P[2]		= {2, N};
+		float		tempH[2]	= {1.0 , 1.0};
+
+		//define default kernel in mean shift base class
+		DefineKernel(k, tempH, P, 2);
+	}
+
+	//de-allocate memory
+	delete [] luv;
+
+	//done.
+	return;
+
+}
+
+ /*/\/\/\/\/\/\/\/\*/
+ /*   Weight Map   */
+ /*\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Set Weight Map                                       */
+/*******************************************************/
+/*Populates the weight map with specified edge         */
+/*strengths.                                           */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - wm is a floating point array of size         */
+/*        (height x width) specifying for each pixel   */
+/*        edge strength.                               */
+/*      - eps is a threshold used to fuse similar      */
+/*        regions during transitive closure.           */
+/*Post:                                                */
+/*      - wm has been used to populate the weight      */
+/*        map.                                         */
+/*      - the threshold used during transitive closure */
+/*        is taken as eps.                             */
+/*******************************************************/
+
+void msImageProcessor::SetWeightMap(float *wm, float eps)
+{
+
+	//initlaize confmap using wm
+	SetLatticeWeightMap(wm);
+
+	//set threshold value
+	if((epsilon = eps) < 0)
+		ErrorHandler("msImageProcessor", "SetWeightMap", "Threshold is negative.");
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Remove Weight Map                                    */
+/*******************************************************/
+/*Removes the weight map.                              */
+/*******************************************************/
+/*Post:                                                */
+/*      - the weight map has been removed.             */
+/*      - if a weight map did not exist NO error       */
+/*        is flagged.                                  */
+/*******************************************************/
+
+void msImageProcessor::RemoveWeightMap( void )
+{
+
+	//remove confmap
+	RemoveLatticeWeightMap();
+
+	//set threshold value to zero
+	epsilon	= 0;
+
+	//done.
+	return;
+
+}
+
+ /*/\/\/\/\/\/\/\/\/\*/
+ /* Image Filtering  */
+ /*\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Filter                                               */
+/*******************************************************/
+/*Performs mean shift filtering on the specified input */
+/*image using a user defined kernel.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the user defined kernel used to apply mean   */
+/*        shift filtering to the defined input image   */
+/*        has spatial bandwidth sigmaS and range band- */
+/*        width sigmaR                                 */
+/*      - speedUpLevel determines whether or not the   */
+/*        filtering should be optimized for faster     */
+/*        execution: a value of NO_SPEEDUP turns this  */
+/*        optimization off and a value SPEEDUP turns   */
+/*        this optimization on                         */
+/*      - a data set has been defined                  */
+/*      - the height and width of the lattice has been */
+/*        specified using method DefineLattice()       */
+/*Post:                                                */
+/*      - mean shift filtering has been applied to the */
+/*        input image using a user defined kernel      */
+/*      - the filtered image is stored in the private  */
+/*        data members of the msImageProcessor class.  */
+/*******************************************************/
+
+void msImageProcessor::Filter(int sigmaS, float sigmaR, SpeedUpLevel speedUpLevel)
+{
+
+	//Check Class consistency...
+
+	//check:
+	// (1) if this operation is consistent
+	// (2) if kernel was created
+	// (3) if data set is defined
+	// (4) if the dimension of the kernel agrees with that
+	//     of the defined data set
+	// if not ... flag an error!
+	classConsistencyCheck(N+2, true);
+	if(ErrorStatus == EL_ERROR)
+		return;
+
+	//If the algorithm has been halted, then exit
+	if((ErrorStatus = msSys.Progress((float)(0.0))) == EL_HALT)
+	{
+		return;
+	}
+	
+	//If the image has just been read then allocate memory
+	//for and initialize output data structure used to store
+	//image modes and their corresponding regions...
+	if(class_state.OUTPUT_DEFINED == false)
+	{
+		InitializeOutput();
+
+		//check for errors...
+		if(ErrorStatus == EL_ERROR)
+			return;
+	}
+
+	//****************** Allocate Memory ******************
+
+	//Allocate memory for basin of attraction mode structure...
+	if((!(modeTable = new unsigned char [L]))||(!(pointList = new int [L])))
+	{
+		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
+		return;
+	}
+
+	//start timer
+#ifdef PROMPT
+	double timer;
+	msSys.StartTimer();
+#endif
+
+	//*****************************************************
+
+	//filter image according to speedup level...
+	switch(speedUpLevel)
+	{
+	//no speedup...
+	case NO_SPEEDUP:	
+      //NonOptimizedFilter((float)(sigmaS), sigmaR);	break;
+      NewNonOptimizedFilter((float)(sigmaS), sigmaR);	break;
+	//medium speedup
+	case MED_SPEEDUP:	
+      //OptimizedFilter1((float)(sigmaS), sigmaR);		break;
+      NewOptimizedFilter1((float)(sigmaS), sigmaR);		break;
+	//high speedup
+	case HIGH_SPEEDUP: 
+      //OptimizedFilter2((float)(sigmaS), sigmaR);		break;
+      NewOptimizedFilter2((float)(sigmaS), sigmaR);		break;
+   // new speedup
+	}
+
+	//****************** Deallocate Memory ******************
+
+	//de-allocate memory used by basin of attraction mode structure
+	delete [] modeTable;
+	delete [] pointList;
+
+	//re-initialize structure
+	modeTable	= NULL;
+	pointList	= NULL;
+	pointCount	= 0;
+
+	//*******************************************************
+
+	//If the algorithm has been halted, then de-allocate the output
+	//and exit
+	if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT)
+	{
+		DestroyOutput();
+		return;
+	}
+
+	//Label image regions, also if segmentation is not to be
+	//performed use the resulting classification structure to
+	//calculate the image boundaries...
+
+   /*
+	//copy msRawData into LUV_data, rounding each component of each
+	//LUV value stored by msRawData to the nearest integer
+	int	i;
+	for(i = 0; i < L*N; i++)
+	{
+		if(msRawData[i] < 0)
+			LUV_data[i] = (int)(msRawData[i] - 0.5);
+		else
+			LUV_data[i] = (int)(msRawData[i] + 0.5);
+	}
+   */
+   int i;
+   for (i=0; i<L*N; i++)
+   {
+      LUV_data[i] = msRawData[i];
+   }
+
+
+#ifdef PROMPT
+	timer	= msSys.ElapsedTime();
+	msSys.Prompt("(%6.2f sec)\nConnecting regions         ...", timer);
+	msSys.StartTimer();
+#endif
+	
+	//Perform connecting (label image regions) using LUV_data
+	Connect();
+	
+#ifdef PROMPT
+	timer	= msSys.ElapsedTime();
+	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
+	msSys.StartTimer();
+#endif
+
+	//done.
+	return;
+
+}
+
+ /*/\/\/\/\/\/\/\/\/\/\/\*/
+ /* Image Region Fusing  */
+ /*\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Fuse Regions                                         */
+/*******************************************************/
+/*Fuses the regions of a filtered image.               */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the range radius is specified by sigmaR      */
+/*      - minRegion is the minimum point density that  */
+/*        a region may have in the resulting segment-  */
+/*        ed image                                     */
+/*      - a data set has been defined                  */
+/*      - the height and width of the lattice has been */
+/*        specified using method DefineLattice()       */
+/*Post:                                                */
+/*      - the image regions have been fused.           */
+/*      - if an result is stored by this class then    */
+/*        this result is used as input to this method. */
+/*      - if no result is stored by this class,        */
+/*        the input image defined by calling the       */
+/*        method DefineImage is used.                  */
+/*******************************************************/
+
+void msImageProcessor::FuseRegions(float sigmaS, int minRegion)
+{
+
+	//Check Class consistency...
+
+	//check:
+	// (1) if this operation is consistent
+	// (2) if kernel was created
+	// (3) if data set is defined
+	// (4) if the dimension of the kernel agrees with that
+	//     of the defined data set
+	// if not ... flag an error!
+	classConsistencyCheck(N+2, true);
+	if(ErrorStatus == EL_ERROR)
+		return;
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and exit
+	if((ErrorStatus = msSys.Progress((float)(0.8))) == EL_HALT)
+	{
+		if(class_state.OUTPUT_DEFINED)	DestroyOutput();
+		return;
+	}
+
+	//obtain sigmaS (make sure it is not zero or negative, if not
+	//flag an error)
+	if((h[1] = sigmaS) <= 0)
+	{
+		ErrorHandler("msImageProcessor", "FuseRegions", "The feature radius must be greater than or equal to zero.");
+		return;
+	}
+
+	//if output has not yet been generated then classify the input
+	//image regions to be fused...
+	if(!(class_state.OUTPUT_DEFINED))
+	{
+
+		//Initialize output data structure used to store
+		//image modes and their corresponding regions...
+		InitializeOutput();
+		
+		//check for errors...
+		if(ErrorStatus == EL_ERROR)
+			return;
+
+		//copy data into LUV_data used to classify
+		//image regions
+      /*
+		int i;
+		for(i = 0; i < L*N; i++)
+		{
+			if(data[i] < 0)
+				LUV_data[i] = (int)(data[i] - 0.5);
+			else
+				LUV_data[i] = (int)(data[i] + 0.5);
+		}
+      */
+      int i;
+      for (i=0; i<L*N; i++)
+      {
+         LUV_data[i] = data[i];
+      }
+		
+#ifdef PROMPT
+		msSys.Prompt("Connecting regions         ...");
+		msSys.StartTimer();
+#endif
+
+		//Perform connecting (label image regions) using LUV_data
+		Connect();
+		
+		//check for errors
+		if(ErrorStatus == EL_ERROR)
+			return;
+		
+#ifdef PROMPT
+		double timer	= msSys.ElapsedTime();
+		msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
+#endif
+		
+	}
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and exit
+	if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT)
+	{
+		DestroyOutput();
+		return;
+	}
+
+#ifdef PROMPT
+	msSys.Prompt("Applying transitive closure...");
+	msSys.StartTimer();
+#endif
+
+	//allocate memory visit table
+	visitTable = new unsigned char [L];
+
+	//Apply transitive closure iteratively to the regions classified
+	//by the RAM updating labels and modes until the color of each neighboring
+	//region is within sqrt(rR2) of one another.
+	rR2 = (float)(h[1]*h[1]*0.25);
+	TransitiveClosure();
+	int oldRC = regionCount;
+	int deltaRC, counter = 0;
+	do {
+		TransitiveClosure();
+		deltaRC = oldRC-regionCount;
+		oldRC = regionCount;
+		counter++;
+	} while ((deltaRC <= 0)&&(counter < 10));
+
+	//de-allocate memory for visit table
+	delete [] visitTable;
+	visitTable	= NULL;
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and region adjacency matrix and exit
+	if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT)
+	{
+		DestroyRAM();
+		DestroyOutput();
+		return;
+	}
+
+#ifdef PROMPT
+	double timer	= msSys.ElapsedTime();
+	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions   ...", timer, regionCount);
+	msSys.StartTimer();
+#endif
+
+	//Prune spurious regions (regions whose area is under
+	//minRegion) using RAM
+	Prune(minRegion);
+
+#ifdef PROMPT
+	timer	= msSys.ElapsedTime();
+	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\n", timer, regionCount);
+	msSys.StartTimer();
+#endif
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and region adjacency matrix and exit
+	if((ErrorStatus = msSys.Progress((float)(1.0))) == EL_HALT)
+	{
+		DestroyRAM();
+		DestroyOutput();
+		return;
+	}
+
+	//de-allocate memory for region adjacency matrix
+	DestroyRAM();
+
+	//output to msRawData
+	int i, j, label;
+	for(i = 0; i < L; i++)
+	{
+		label	= labels[i];
+		for(j = 0; j < N; j++)
+			{
+				msRawData[N*i+j] = modes[N*label+j];
+			}
+	}
+
+	//done.
+	return;
+
+}
+
+  /*/\/\/\/\/\/\/\/\/\/\*/
+  /* Image Segmentation */
+  /*\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Segment                                              */
+/*******************************************************/
+/*Segments the defined image.                          */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - sigmaS and sigmaR are the spatial and range  */
+/*        radii of the search window respectively      */
+/*      - minRegion is the minimum point density that  */
+/*        a region may have in the resulting segment-  */
+/*        ed image                                     */
+/*      - speedUpLevel determines whether or not the   */
+/*        filtering should be optimized for faster     */
+/*        execution: a value of NO_SPEEDUP turns this  */
+/*        optimization off and a value SPEEDUP turns   */
+/*        this optimization on                         */
+/*Post:                                                */
+/*      - the defined image is segmented and the       */
+/*        resulting segmented image is stored in the   */
+/*        private data members of the image segmenter  */
+/*        class.                                       */
+/*      - any regions whose point densities are less   */
+/*        than or equal to minRegion have been pruned  */
+/*        from the segmented image.                    */
+/*******************************************************/
+
+void msImageProcessor::Segment(int sigmaS, float sigmaR, int minRegion, SpeedUpLevel speedUpLevel)
+{
+
+	//make sure kernel is properly defined...
+	if((!h)||(kp < 2))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "Kernel corrupt or undefined.");
+		return;
+	}
+
+	//Apply mean shift to data set using sigmaS and sigmaR...
+	Filter(sigmaS, sigmaR, speedUpLevel);
+
+	//check for errors
+	if(ErrorStatus == EL_ERROR)
+		return;
+
+	//check to see if the system has been halted, if so exit
+	if(ErrorStatus == EL_HALT)
+		return;
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and exit
+	if((ErrorStatus = msSys.Progress((float)(0.85))) == EL_HALT)
+	{
+		DestroyOutput();
+		return;
+	}
+
+#ifdef PROMPT
+	msSys.Prompt("Applying transitive closure...");
+	msSys.StartTimer();
+#endif
+
+	//allocate memory visit table
+	visitTable = new unsigned char [L];
+
+	//Apply transitive closure iteratively to the regions classified
+	//by the RAM updating labels and modes until the color of each neighboring
+	//region is within sqrt(rR2) of one another.
+	rR2 = (float)(h[1]*h[1]*0.25);
+	TransitiveClosure();
+	int oldRC = regionCount;
+	int deltaRC, counter = 0;
+	do {
+		TransitiveClosure();
+		deltaRC = oldRC-regionCount;
+		oldRC = regionCount;
+		counter++;
+	} while ((deltaRC <= 0)&&(counter < 10));
+
+	//de-allocate memory for visit table
+	delete [] visitTable;
+	visitTable	= NULL;
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and regions adjacency matrix and exit
+	if((ErrorStatus = msSys.Progress((float)(0.95))) == EL_HALT)
+	{
+		DestroyRAM();
+		DestroyOutput();
+		return;
+	}
+
+#ifdef PROMPT
+	double timer	= msSys.ElapsedTime();
+	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d).\nPruning spurious regions\t... ", timer, regionCount);
+	msSys.StartTimer();
+#endif
+
+	//Prune spurious regions (regions whose area is under
+	//minRegion) using RAM
+	Prune(minRegion);
+
+#ifdef PROMPT
+	timer	= msSys.ElapsedTime();
+	msSys.Prompt("done. (%6.2f seconds, numRegions = %6d)\nPruning spurious regions    ...", timer, regionCount);
+	msSys.StartTimer();
+#endif
+
+	//Check to see if the algorithm is to be halted, if so then
+	//destroy output and regions adjacency matrix and exit
+	if((ErrorStatus = msSys.Progress(1.0)) == EL_HALT)
+	{
+		DestroyRAM();
+		DestroyOutput();
+		return;
+	}
+
+	//de-allocate memory for region adjacency matrix
+	DestroyRAM();
+
+	//output to msRawData
+	int j, i, label;
+	for(i = 0; i < L; i++)
+	{
+		label	= labels[i];
+		for(j = 0; j < N; j++)
+			{
+				msRawData[N*i+j] = modes[N*label+j];
+			}
+	}
+
+	//done.
+	return;
+
+}
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Data Space Conversion */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*RGB To LUV                                           */
+/*******************************************************/
+/*Converts an RGB vector to LUV.                       */
+/*                                                     */
+/*See:                                                 */
+/*   G. Wyszecki and W.S. Stiles: Color Science:       */
+/*   Concepts and Methods, Quantitative Data and       */
+/*   Formulae, Wiley, New York, 1982.                  */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - rgbVal is an unsigned char array containing  */
+/*        the RGB vector                               */
+/*      - luvVal is a floating point array containing  */
+/*        the resulting LUV vector                     */
+/*Post:                                                */
+/*      - rgbVal has been converted to LUV and the     */
+/*        result has been stored in luvVal.            */
+/*******************************************************/
+
+void msImageProcessor::RGBtoLUV(byte *rgbVal, float *luvVal)
+{
+
+	//delcare variables
+	double	x, y, z, L0, u_prime, v_prime, constant;
+
+	//convert RGB to XYZ...
+	x		= XYZ[0][0]*rgbVal[0] + XYZ[0][1]*rgbVal[1] + XYZ[0][2]*rgbVal[2];
+	y		= XYZ[1][0]*rgbVal[0] + XYZ[1][1]*rgbVal[1] + XYZ[1][2]*rgbVal[2];
+	z		= XYZ[2][0]*rgbVal[0] + XYZ[2][1]*rgbVal[1] + XYZ[2][2]*rgbVal[2];
+
+	//convert XYZ to LUV...
+
+	//compute L*
+	L0		= y / (255.0 * Yn);
+	if(L0 > Lt)
+		luvVal[0]	= (float)(116.0 * (pow(L0, 1.0/3.0)) - 16.0);
+	else
+		luvVal[0]	= (float)(903.3 * L0);
+
+	//compute u_prime and v_prime
+	constant	= x + 15 * y + 3 * z;
+	if(constant != 0)
+	{
+		u_prime	= (4 * x) / constant;
+		v_prime = (9 * y) / constant;
+	}
+	else
+	{
+		u_prime	= 4.0;
+		v_prime	= 9.0/15.0;
+	}
+
+	//compute u* and v*
+    luvVal[1] = (float) (13 * luvVal[0] * (u_prime - Un_prime));
+    luvVal[2] = (float) (13 * luvVal[0] * (v_prime - Vn_prime));
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*LUV To RGB                                           */
+/*******************************************************/
+/*Converts an LUV vector to RGB.                       */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - luvVal is a floating point array containing  */
+/*        the LUV vector                               */
+/*      - rgbVal is an unsigned char array containing  */
+/*        the resulting RGB vector                     */
+/*Post:                                                */
+/*      - luvVal has been converted to RGB and the     */
+/*        result has been stored in rgbVal.            */
+/*******************************************************/
+
+//define inline rounding function...
+inline int my_round(double in_x)
+{
+	if (in_x < 0)
+		return (int)(in_x - 0.5);
+	else
+		return (int)(in_x + 0.5);
+}
+
+void msImageProcessor::LUVtoRGB(float *luvVal, byte *rgbVal)
+{
+
+	//declare variables...
+	int		r, g, b;
+	double	x, y, z, u_prime, v_prime;
+
+	//perform conversion
+	if(luvVal[0] < 0.1)
+		r = g = b = 0;
+	else
+	{
+		//convert luv to xyz...
+		if(luvVal[0] < 8.0)
+			y	= Yn * luvVal[0] / 903.3;
+		else
+		{
+			y	= (luvVal[0] + 16.0) / 116.0;
+			y  *= Yn * y * y;
+		}
+
+		u_prime	= luvVal[1] / (13 * luvVal[0]) + Un_prime;
+		v_prime	= luvVal[2] / (13 * luvVal[0]) + Vn_prime;
+
+		x		= 9 * u_prime * y / (4 * v_prime);
+		z		= (12 - 3 * u_prime - 20 * v_prime) * y / (4 * v_prime);
+
+		//convert xyz to rgb...
+		//[r, g, b] = RGB*[x, y, z]*255.0
+		r		= my_round((RGB[0][0]*x + RGB[0][1]*y + RGB[0][2]*z)*255.0);
+		g		= my_round((RGB[1][0]*x + RGB[1][1]*y + RGB[1][2]*z)*255.0);
+		b		= my_round((RGB[2][0]*x + RGB[2][1]*y + RGB[2][2]*z)*255.0);
+
+		//check bounds...
+		if(r < 0)	r = 0; if(r > 255)	r = 255;
+		if(g < 0)	g = 0; if(g > 255)	g = 255;
+		if(b < 0)	b = 0; if(b > 255)	b = 255;
+
+	}
+
+	//assign rgb values to rgb vector rgbVal
+	rgbVal[0]	= r;
+	rgbVal[1]	= g;
+	rgbVal[2]	= b;
+
+	//done.
+	return;
+
+}
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Filtered and Segmented Image Output */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Get Raw Data                                         */
+/*******************************************************/
+/*The output image data is returned.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - outputImageData is a pre-allocated floating  */
+/*        point array used to store the filtered or    */
+/*        segmented image pixels.                      */
+/*Post:                                                */
+/*      - the filtered or segmented image data is      */
+/*        stored by outputImageData.                   */
+/*******************************************************/
+
+void msImageProcessor::GetRawData(float *outputImageData)
+{
+	//make sure that outputImageData is not NULL
+	if(!outputImageData)
+	{
+		ErrorHandler("msImageProcessor", "GetRawData", "Output image data buffer is NULL.");
+		return;
+	}
+
+	//copy msRawData to outputImageData
+	int i;
+	for(i = 0; i < L*N; i++)
+		outputImageData[i] = msRawData[i];
+
+	//done.
+	return;
+}
+
+/*******************************************************/
+/*Get Results                                          */
+/*******************************************************/
+/*The output image is returned.                        */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - outputImage is a pre-allocated unsinged char */
+/*        array used to store the filtered or segment- */
+/*        ed image pixels                              */
+/*Post:                                                */
+/*      - the filtered or segmented image is stored by */
+/*        outputImage.                                 */
+/*******************************************************/
+
+void msImageProcessor::GetResults(byte *outputImage)
+{
+
+	//make sure that outpuImage is not NULL
+	if(!outputImage)
+	{
+		ErrorHandler("msImageProcessor", "GetResults", "Output image buffer is NULL.");
+		return;
+	}
+
+	//if the image type is GREYSCALE simply
+	//copy it over to the segmentedImage
+	if(N == 1)
+	{
+		//copy over msRawData to segmentedImage checking
+		//bounds
+		int i, pxValue;
+		for(i = 0; i < L; i++)
+		{
+
+			//get value
+			pxValue = (int)(msRawData[i]+0.5);
+			
+			//store into segmented image checking bounds...
+			if(pxValue < 0)
+				outputImage[i] = (byte)(0);
+			else if(pxValue > 255)
+				outputImage[i] = (byte)(255);
+			else
+				outputImage[i] = (byte)(pxValue);
+
+		}
+
+	}
+	else if (N == 3)
+	{
+		
+		//otherwise convert msRawData from LUV to RGB
+		//storing the result in segmentedImage
+		int i;
+		for(i = 0; i < L; i++)
+			LUVtoRGB(&msRawData[N*i], &outputImage[N*i]);
+
+	}
+	else
+		//Unknown image type: should use MeanShift::GetRawData()...
+		ErrorHandler("msImageProcessor", "GetResults", "Unknown image type. Try using MeanShift::GetRawData().");
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Get Boundaries                                       */
+/*******************************************************/
+/*A region list containing the boundary locations for  */
+/*each region is returned.                             */
+/*******************************************************/
+/*Post:                                                */
+/*      - a region list object containing the boundary */
+/*        locations for each region is constructed     */
+/*      - the region list is returned                  */
+/*      - NULL is returned if the image has not been   */
+/*        filtered or segmented                        */
+/*******************************************************/
+
+RegionList *msImageProcessor::GetBoundaries( void )
+{
+
+	//define bounds using label information
+	if(class_state.OUTPUT_DEFINED)
+		DefineBoundaries();
+
+	//return region list structure
+	return regionList;
+
+}
+ 
+/*******************************************************/
+/*Get Regions                                          */
+/*******************************************************/
+/*Returns the regions of the processed image.          */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - labels_out is an integer array of size       */
+/*        height*width that stores for each pixel a    */
+/*        label relating that pixel to a corresponding */
+/*        region in the image                          */
+/*      - modes_out is floating point array of size    */
+/*        regionCount*N storing the feature component  */
+/*        of each region, and indexed by region label  */
+/*      - modePointCounts is an integer array of size  */
+/*        regionCount, indexed by region label, that   */
+/*        stores the area of each region in pixels.    */
+/*Post:                                                */
+/*      If an input image was defined and processed,   */
+/*      - memory has been allocated for labels_out,    */
+/*        modes_out and MPC_out.                       */
+/*      - labels_out, modes_out, and MPC_out have been */
+/*        populated.                                   */
+/*      - the number of regions contained by the segm- */
+/*        ented image has been returned.               */
+/*      If the image has not been defined or processed */
+/*      or if there is in-sufficient memory,           */
+/*      - no memory has been allocated for labels_out, */
+/*        modes_out, and MPC_out.                      */
+/*      - -1 is returned for regionCount.              */
+/*******************************************************/
+
+int msImageProcessor::GetRegions(int **labels_out, float **modes_out, int **MPC_out)
+{
+	//check to see if output has been defined for the given input image...
+	if(class_state.OUTPUT_DEFINED == false)
+		return -1;
+
+	//allocate memory for labels_out, modes_out and MPC_out based
+	//on output storage structure
+	int		*labels_	= *labels_out, *MPC_out_ = *MPC_out;
+	float	*modes_		= *modes_out; 
+	if(!(labels_ = new int [L]))
+	{
+		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
+		return -1;
+	}
+	if(!(modes_	= new float [regionCount*N]))
+	{
+		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
+		return -1;
+	}
+	if(!(MPC_out_ = new int [regionCount]))
+	{
+		ErrorHandler("msImageProcessor", "GetRegions", "Not enough memory.");
+		return -1;
+	}
+
+	//populate labels_out with image labels
+	int	i;
+	for(i = 0; i < L; i++)
+		labels_[i] = labels[i];
+
+	//populate modes_out and MPC_out with the color and point
+	//count of each region
+	for(i = 0; i < regionCount*N; i++)
+		modes_[i]	= modes[i];
+	for(i = 0; i < regionCount; i++)
+		MPC_out_[i]	= modePointCounts[i];
+
+	//done. Return the number of regions resulting from filtering or segmentation.
+	return regionCount;
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     PRIVATE METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+	/*/\/\/\/\/\/\/\/\/\*/
+	/*  Image Filtering */
+	/*\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Non Optimized Filter                                 */
+/*******************************************************/
+/*Performs mean shift filtering on the specified input */
+/*image using a user defined kernel.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the user defined kernel used to apply mean   */
+/*        shift filtering to the defined input image   */
+/*        has spatial bandwidth sigmaS and range band- */
+/*        width sigmaR                                 */
+/*      - a data set has been defined                  */
+/*      - the height and width of the lattice has been */
+/*        specified using method DefineLattice()       */
+/*Post:                                                */
+/*      - mean shift filtering has been applied to the */
+/*        input image using a user defined kernel      */
+/*      - the filtered image is stored in the private  */
+/*        data members of the msImageProcessor class.  */
+/*******************************************************/
+
+void msImageProcessor::NonOptimizedFilter(float sigmaS, float sigmaR)
+{
+
+	// Declare Variables
+	int   iterationCount, i, j;
+	double mvAbs;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+	for(i = 0; i < L; i++)
+	{
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+		yk[0] = i%width;
+		yk[1] = i/width;
+		for(j = 0; j < N; j++)
+			yk[j+2] = data[N*i+j];
+		
+		// Calculate the mean shift vector using the lattice
+		LatticeMSVector(Mh, yk);
+		
+		// Calculate its magnitude squared
+		mvAbs = 0;
+		for(j = 0; j < lN; j++)
+			mvAbs += Mh[j]*Mh[j];
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// Calculate the mean shift vector at the new
+			// window location using lattice
+			LatticeMSVector(Mh, yk);
+			
+			// Calculate its magnitude squared
+			mvAbs = 0;
+			for(j = 0; j < lN; j++)
+				mvAbs += Mh[j]*Mh[j];
+
+			// Increment interation count
+			iterationCount++;
+			
+		}
+
+		// Shift window location
+		for(j = 0; j < lN; j++)
+			yk[j] += Mh[j];
+		
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	
+	// de-allocate memory
+	delete [] yk;
+	delete [] Mh;
+
+	// done.
+	return;
+
+}
+
+
+
+/*******************************************************/
+/*Optimized Filter 1                                   */
+/*******************************************************/
+/*Performs mean shift filtering on the specified input */
+/*image using a user defined kernel. Previous mode     */
+/*information is used to avoid re-applying mean shift  */
+/*on certain data points to improve performance.       */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the user defined kernel used to apply mean   */
+/*        shift filtering to the defined input image   */
+/*        has spatial bandwidth sigmaS and range band- */
+/*        width sigmaR                                 */
+/*      - a data set has been defined                  */
+/*      - the height and width of the lattice has been */
+/*        specified using method DefineLattice()       */
+/*Post:                                                */
+/*      - mean shift filtering has been applied to the */
+/*        input image using a user defined kernel      */
+/*      - the filtered image is stored in the private  */
+/*        data members of the msImageProcessor class.  */
+/*******************************************************/
+
+void msImageProcessor::OptimizedFilter1(float sigmaS, float sigmaR)
+{
+
+	// Declare Variables
+	int		iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
+	float	*modeCandidatePoint;
+	double	mvAbs, diff, el;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+	
+	// Initialize mode table used for basin of attraction
+	memset(modeTable, 0, width*height);
+
+	// Allocate memory mode candidate data point...
+	//floating point version
+	modeCandidatePoint	= new float	[N];
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+
+	for(i = 0; i < L; i++)
+	{
+		// if a mode was already assigned to this data point
+		// then skip this point, otherwise proceed to
+		// find its mode by applying mean shift...
+		if (modeTable[i] == 1)
+			continue;
+
+		// initialize point list...
+		pointCount = 0;
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+		yk[0] = i%width;
+		yk[1] = i/width;
+		for(j = 0; j < N; j++)
+			yk[j+2] = data[N*i+j];
+		
+		// Calculate the mean shift vector using the lattice
+		LatticeMSVector(Mh, yk);
+		
+		// Calculate its magnitude squared
+		mvAbs = 0;
+		for(j = 0; j < lN; j++)
+			mvAbs += Mh[j]*Mh[j];
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// check to see if the current mode location is in the
+			// basin of attraction...
+
+			// calculate the location of yk on the lattice
+			modeCandidateX	= (int) (yk[0]+0.5);
+			modeCandidateY	= (int) (yk[1]+0.5);
+			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
+
+			// if mvAbs != 0 (yk did indeed move) then check
+			// location basin_i in the mode table to see if
+			// this data point either:
+			
+			// (1) has not been associated with a mode yet
+			//     (modeTable[basin_i] = 0), so associate
+			//     it with this one
+			//
+			// (2) it has been associated with a mode other
+			//     than the one that this data point is converging
+			//     to (modeTable[basin_i] = 1), so assign to
+			//     this data point the same mode as that of basin_i
+
+			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
+			{
+				// obtain the data point at basin_i to
+				// see if it is within h*TC_DIST_FACTOR of
+				// of yk
+				for (j = 0; j < N; j++)
+					modeCandidatePoint[j] = data[N*modeCandidate_i + j];
+				
+				// check basin on non-spatial data spaces only
+				k = 1;
+				s = 0;
+				diff = 0;
+				while ((diff < TC_DIST_FACTOR) && (k<kp))
+				{
+					diff = 0;
+					for (p=0; p<P[k]; p++)
+					{
+						el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
+						diff += el*el;
+					}
+					s+=P[k];
+					k++;
+				}
+
+				// if the data point at basin_i is within
+				// a distance of h*TC_DIST_FACTOR of yk
+				// then depending on modeTable[basin_i] perform
+				// either (1) or (2)
+				if (diff < TC_DIST_FACTOR)
+				{
+					// if the data point at basin_i has not
+					// been associated to a mode then associate
+					// it with the mode that this one will converge
+					// to
+					if (modeTable[modeCandidate_i] == 0)
+					{
+						// no mode associated yet so associate
+						// it with this one...
+						pointList[pointCount++]		= modeCandidate_i;
+						modeTable[modeCandidate_i]	= 2;
+
+					} else
+					{
+
+						// the mode has already been associated with
+						// another mode, thererfore associate this one
+						// mode and the modes in the point list with
+						// the mode associated with data[basin_i]...
+
+						// store the mode info into yk using msRawData...
+						for (j = 0; j < N; j++)
+							yk[j+2] = msRawData[modeCandidate_i*N+j];
+
+						// update mode table for this data point
+						// indicating that a mode has been associated
+						// with it
+						modeTable[i] = 1;
+
+                  // indicate that a mode has been associated
+						// to this data point (data[i])
+						mvAbs = -1;
+
+						// stop mean shift calculation...
+						break;
+					}
+				}
+			}
+			
+			// Calculate the mean shift vector at the new
+			// window location using lattice
+			LatticeMSVector(Mh, yk);
+			
+			// Calculate its magnitude squared
+			mvAbs = 0;
+			for(j = 0; j < lN; j++)
+				mvAbs += Mh[j]*Mh[j];
+
+			// Increment iteration count
+			iterationCount++;
+			
+		}
+
+		// if a mode was not associated with this data point
+		// yet associate it with yk...
+		if (mvAbs >= 0)
+		{
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// update mode table for this data point
+			// indicating that a mode has been associated
+			// with it
+			modeTable[i] = 1;
+		}
+		
+		// associate the data point indexed by
+		// the point list with the mode stored
+		// by yk
+		for (j = 0; j < pointCount; j++)
+		{
+			// obtain the point location from the
+			// point list
+			modeCandidate_i = pointList[j];
+
+			// update the mode table for this point
+			modeTable[modeCandidate_i] = 1;
+
+			//store result into msRawData...
+			for(k = 0; k < N; k++)
+				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
+		}
+
+
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;		
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	
+	// de-allocate memory
+	delete [] modeCandidatePoint;
+	delete [] yk;
+	delete [] Mh;
+	
+	// done.
+	return;
+
+}
+
+/*******************************************************/
+/*Optimized Filter 2                                   */
+/*******************************************************/
+/*Performs mean shift filtering on the specified input */
+/*image using a user defined kernel. Previous mode     */
+/*information is used to avoid re-applying mean shift  */
+/*on certain data points to improve performance. To    */
+/*further improve perfmance (during segmentation) poi- */
+/*nts within h of a window center during the window    */
+/*center's traversal to a mode are associated with the */
+/*mode that the window converges to.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the user defined kernel used to apply mean   */
+/*        shift filtering to the defined input image   */
+/*        has spatial bandwidth sigmaS and range band- */
+/*        width sigmaR                                 */
+/*      - a data set has been defined                  */
+/*      - the height and width of the lattice has been */
+/*        specified using method DefineLattice()       */
+/*Post:                                                */
+/*      - mean shift filtering has been applied to the */
+/*        input image using a user defined kernel      */
+/*      - the filtered image is stored in the private  */
+/*        data members of the msImageProcessor class.  */
+/*******************************************************/
+
+void msImageProcessor::OptimizedFilter2(float sigmaS, float sigmaR)
+{
+
+	//if confidence map is null set it to zero
+	if(!weightMap)
+	{
+		weightMap = new float [L];
+		int i;
+		for(i = 0; i < L; i++)
+			weightMap[i] = 0;
+	}
+
+	// Declare Variables
+	int		iterationCount, i, j, k, s, p, modeCandidateX, modeCandidateY, modeCandidate_i;
+	float	*modeCandidatePoint;
+	double	mvAbs, diff, el;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+	
+	// Initialize mode table used for basin of attraction
+	memset(modeTable, 0, width*height);
+
+	// Allocate memory mode candidate data point...
+	//floating point version
+	modeCandidatePoint	= new float	[N];
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+	for(i = 0; i < L; i++)
+	{
+		// if a mode was already assigned to this data point
+		// then skip this point, otherwise proceed to
+		// find its mode by applying mean shift...
+		if (modeTable[i] == 1)
+			continue;
+
+		// initialize point list...
+		pointCount = 0;
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+		yk[0] = i%width;
+		yk[1] = i/width;
+		for(j = 0; j < N; j++)
+			yk[j+2] = data[N*i+j];
+		
+		// Calculate the mean shift vector using the lattice
+		OptLatticeMSVector(Mh, yk);
+		
+		// Calculate its magnitude squared
+		mvAbs = 0;
+		for(j = 0; j < lN; j++)
+			mvAbs += Mh[j]*Mh[j];
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// check to see if the current mode location is in the
+			// basin of attraction...
+
+			// calculate the location of yk on the lattice
+			modeCandidateX	= (int) (yk[0]+0.5);
+			modeCandidateY	= (int) (yk[1]+0.5);
+			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
+
+			// if mvAbs != 0 (yk did indeed move) then check
+			// location basin_i in the mode table to see if
+			// this data point either:
+			
+			// (1) has not been associated with a mode yet
+			//     (modeTable[basin_i] = 0), so associate
+			//     it with this one
+			//
+			// (2) it has been associated with a mode other
+			//     than the one that this data point is converging
+			//     to (modeTable[basin_i] = 1), so assign to
+			//     this data point the same mode as that of basin_i
+
+			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
+			{
+				// obtain the data point at basin_i to
+				// see if it is within h*TC_DIST_FACTOR of
+				// of yk
+				for (j = 0; j < N; j++)
+					modeCandidatePoint[j] = data[N*modeCandidate_i + j];
+				
+				// check basin on non-spatial data spaces only
+				k = 1;
+				s = 0;
+				diff = 0;
+				while ((diff < TC_DIST_FACTOR) && (k<kp))
+				{
+					diff = 0;
+					for (p=0; p<P[k]; p++)
+					{
+						el = (modeCandidatePoint[p+s]-yk[p+s+2])/h[k];
+						diff += el*el;
+					}
+					s+=P[k];
+					k++;
+				}
+
+				// if the data point at basin_i is within
+				// a distance of h*TC_DIST_FACTOR of yk
+				// then depending on modeTable[basin_i] perform
+				// either (1) or (2)
+				if (diff < TC_DIST_FACTOR)
+				{
+					// if the data point at basin_i has not
+					// been associated to a mode then associate
+					// it with the mode that this one will converge
+					// to
+					if (modeTable[modeCandidate_i] == 0)
+					{
+						// no mode associated yet so associate
+						// it with this one...
+						pointList[pointCount++]		= modeCandidate_i;
+						modeTable[modeCandidate_i]	= 2;
+
+					} else
+					{
+
+						// the mode has already been associated with
+						// another mode, thererfore associate this one
+						// mode and the modes in the point list with
+						// the mode associated with data[basin_i]...
+
+						// store the mode infor int yk using msRawData...
+						for (j = 0; j < N; j++)
+							yk[j+2] = msRawData[modeCandidate_i*N+j];
+
+						// update mode table for this data point
+						// indicating that a mode has been associated
+						// with it
+						modeTable[i] = 1;
+
+                  // indicate that a mode has been associated
+						// to this data point (data[i])
+						mvAbs = -1;
+
+						// stop mean shift calculation...
+						break;
+					}
+				}
+			}
+			
+			// Calculate the mean shift vector at the new
+			// window location using lattice
+			OptLatticeMSVector(Mh, yk);
+			
+			// Calculate its magnitude squared
+			mvAbs = 0;
+			for(j = 0; j < lN; j++)
+				mvAbs += Mh[j]*Mh[j];
+
+			// Increment interation count
+			iterationCount++;
+			
+		}
+
+		// if a mode was not associated with this data point
+		// yet then perform a shift the window center yk one
+		// last time using the mean shift vector...
+		if (mvAbs >= 0)
+		{
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+
+         // update mode table for this data point
+		   // indicating that a mode has been associated
+   		// with it
+			modeTable[i] = 1;
+		}
+		
+		// associate the data point indexed by
+		// the point list with the mode stored
+		// by yk
+		for (j = 0; j < pointCount; j++)
+		{
+			// obtain the point location from the
+			// point list
+			modeCandidate_i = pointList[j];
+
+			// update the mode table for this point
+			modeTable[modeCandidate_i] = 1;
+
+			//store result into msRawData...
+			for(k = 0; k < N; k++)
+				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
+		}
+
+
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;
+		
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	
+	// de-allocate memory
+	delete [] modeCandidatePoint;
+	delete [] yk;
+	delete [] Mh;
+	
+	// done.
+	return;
+
+}
+
+	/*/\/\/\/\/\/\/\/\/\/\/\*/
+	/* Image Classification */
+	/*\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Connect                                              */
+/*******************************************************/
+/*Classifies the regions of the mean shift filtered    */
+/*image.                                               */
+/*******************************************************/
+/*Post:                                                */
+/*      - the regions of the mean shift image have been*/
+/*        classified using the private classification  */
+/*        structure of the msImageProcessor Class.     */
+/*        Namely, each region uniquely identified by   */
+/*        its LUV color  (stored by LUV_data) and loc- */
+/*        ation has been labeled and its area computed */
+/*        via an eight-connected fill.                 */
+/*******************************************************/
+
+void msImageProcessor::Connect( void )
+{
+
+	//define eight connected neighbors
+	neigh[0]	= 1;
+	neigh[1]	= 1-width;
+	neigh[2]	= -width;
+	neigh[3]	= -(1+width);
+	neigh[4]	= -1;
+	neigh[5]	= width-1;
+	neigh[6]	= width;
+	neigh[7]	= width+1;
+
+	//initialize labels and modePointCounts
+	int i;
+	for(i = 0; i < width*height; i++)
+	{
+		labels[i]			= -1;
+		modePointCounts[i]	=  0;
+	}
+
+	//Traverse the image labeling each new region encountered
+	int k, label = -1;
+	for(i = 0; i < height*width; i++)
+	{
+		//if this region has not yet been labeled - label it
+		if(labels[i] < 0)
+		{
+			//assign new label to this region
+			labels[i] = ++label;
+
+			//copy region color into modes
+			for(k = 0; k < N; k++)
+            modes[(N*label)+k] = LUV_data[(N*i)+k];
+//				modes[(N*label)+k]	= (float)(LUV_data[(N*i)+k]);
+
+			//populate labels with label for this specified region
+			//calculating modePointCounts[label]...
+			Fill(i, label);
+		}
+	}
+
+	//calculate region count using label
+	regionCount	= label+1;
+
+	//done.
+	return;
+}
+
+/*******************************************************/
+/*Fill                                                 */
+/*******************************************************/
+/*Given a region seed and a region label, Fill uses    */
+/*the region seed to perform an eight-connected fill   */
+/*for the specified region, labeling all pixels con-   */
+/*tained by the region with the specified label:       */
+/*label.                                               */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - regionLoc is a region seed - a pixel that is */
+/*        identified as being part of the region       */
+/*        labled using the label, label.               */
+/*Post:                                                */
+/*      - all pixels belonging to the region specified */
+/*        by regionLoc (having the same integer LUV    */
+/*        value specified by LUV_data) are classified  */
+/*        as one region by labeling each pixel in the  */
+/*        image clasification structure using label    */
+/*        via an eight-connected fill.                 */
+/*******************************************************/
+
+void msImageProcessor::Fill(int regionLoc, int label)
+{
+
+	//declare variables
+	int	i, k, neighLoc, neighborsFound, imageSize	= width*height;
+
+	//Fill region starting at region location
+	//using labels...
+
+	//initialzie indexTable
+	int	index		= 0;
+	indexTable[0]	= regionLoc;
+
+	//increment mode point counts for this region to
+	//indicate that one pixel belongs to this region
+	modePointCounts[label]++;
+
+	while(true)
+	{
+
+		//assume no neighbors will be found
+		neighborsFound	= 0;
+
+		//check the eight connected neighbors at regionLoc -
+		//if a pixel has similar color to that located at 
+		//regionLoc then declare it as part of this region
+		for(i = 0; i < 8; i++)
+		{
+         // no need
+         /*
+			//if at boundary do not check certain neighbors because
+			//they do not exist...
+			if((regionLoc%width == 0)&&((i == 3)||(i == 4)||(i == 5)))
+				continue;
+			if((regionLoc%(width-1) == 0)&&((i == 0)||(i == 1)||(i == 7)))
+				continue;
+         */   
+
+			//check bounds and if neighbor has been already labeled
+			neighLoc			= regionLoc + neigh[i];
+			if((neighLoc >= 0)&&(neighLoc < imageSize)&&(labels[neighLoc] < 0))
+			{
+				for(k = 0; k < N; k++)
+				{
+//					if(LUV_data[(regionLoc*N)+k] != LUV_data[(neighLoc*N)+k])
+               if (fabs(LUV_data[(regionLoc*N)+k]-LUV_data[(neighLoc*N)+k])>=LUV_treshold)
+						break;
+				}
+				
+				//neighbor i belongs to this region so label it and
+				//place it onto the index table buffer for further
+				//processing
+				if(k == N)
+				{
+					//assign label to neighbor i
+					labels[neighLoc]	= label;
+					
+					//increment region point count
+					modePointCounts[label]++;
+					
+					//place index of neighbor i onto the index tabel buffer
+					indexTable[++index]	= neighLoc;
+					
+					//indicate that a neighboring region pixel was
+					//identified
+					neighborsFound	= 1;
+				}
+			}
+		}
+
+		//check the indexTable to see if there are any more
+		//entries to be explored - if so explore them, otherwise
+		//exit the loop - we are finished
+		if(neighborsFound)
+			regionLoc	= indexTable[index];
+		else if (index > 1)
+			regionLoc	= indexTable[--index];
+		else
+			break; //fill complete
+	}
+
+	//done.
+	return;
+
+}
+
+	/*/\/\/\/\/\/\/\/\*/
+	/*  Image Pruning */
+	/*\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Build Region Adjacency Matrix                        */
+/*******************************************************/
+/*Constructs a region adjacency matrix.                */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the classification data structure has been   */
+/*        constructed.                                 */
+/*Post:                                                */
+/*      - a region adjacency matrix has been built     */
+/*        using the classification data structure.     */
+/*******************************************************/
+
+void msImageProcessor::BuildRAM( void )
+{
+
+	//Allocate memory for region adjacency matrix if it hasn't already been allocated
+	if((!raList)&&((!(raList = new RAList [regionCount]))||(!(raPool = new RAList [NODE_MULTIPLE*regionCount]))))
+	{
+		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
+		return;
+	}
+
+	//initialize the region adjacency list
+	int i;
+	for(i = 0; i < regionCount; i++)
+	{
+		raList[i].edgeStrength		= 0;
+		raList[i].edgePixelCount	= 0;
+		raList[i].label				= i;
+		raList[i].next				= NULL;
+	}
+
+	//initialize RAM free list
+	freeRAList	= raPool;
+	for(i = 0; i < NODE_MULTIPLE*regionCount-1; i++)
+	{
+		raPool[i].edgeStrength		= 0;
+		raPool[i].edgePixelCount	= 0;
+		raPool[i].next = &raPool[i+1];
+	}
+	raPool[NODE_MULTIPLE*regionCount-1].next	= NULL;
+
+	//traverse the labeled image building
+	//the RAM by looking to the right of
+	//and below the current pixel location thus
+	//determining if a given region is adjacent
+	//to another
+	int		j, curLabel, rightLabel, bottomLabel, exists;
+	RAList	*raNode1, *raNode2, *oldRAFreeList;
+	for(i = 0; i < height - 1; i++)
+	{
+		//check the right and below neighbors
+		//for pixel locations whose x < width - 1
+		for(j = 0; j < width - 1; j++)
+		{
+			//calculate pixel labels
+			curLabel	= labels[i*width+j    ];	//current pixel
+			rightLabel	= labels[i*width+j+1  ];	//right   pixel
+			bottomLabel	= labels[(i+1)*width+j];	//bottom  pixel
+
+			//check to the right, if the label of
+			//the right pixel is not the same as that
+			//of the current one then region[j] and region[j+1]
+			//are adjacent to one another - update the RAM
+			if(curLabel != rightLabel)
+			{
+				//obtain RAList object from region adjacency free
+				//list
+				raNode1			= freeRAList;
+				raNode2			= freeRAList->next;
+
+				//keep a pointer to the old region adj. free
+				//list just in case nodes already exist in respective
+				//region lists
+				oldRAFreeList	= freeRAList;
+
+				//update region adjacency free list
+				freeRAList		= freeRAList->next->next;
+
+				//populate RAList nodes
+				raNode1->label	= curLabel;
+				raNode2->label	= rightLabel;
+
+				//insert nodes into the RAM
+				exists			= 0;
+				raList[curLabel  ].Insert(raNode2);
+				exists			= raList[rightLabel].Insert(raNode1);
+
+				//if the node already exists then place
+				//nodes back onto the region adjacency
+				//free list
+				if(exists)
+					freeRAList = oldRAFreeList;
+
+			}
+
+			//check below, if the label of
+			//the bottom pixel is not the same as that
+			//of the current one then region[j] and region[j+width]
+			//are adjacent to one another - update the RAM
+			if(curLabel != bottomLabel)
+			{
+				//obtain RAList object from region adjacency free
+				//list
+				raNode1			= freeRAList;
+				raNode2			= freeRAList->next;
+
+				//keep a pointer to the old region adj. free
+				//list just in case nodes already exist in respective
+				//region lists
+				oldRAFreeList	= freeRAList;
+
+				//update region adjacency free list
+				freeRAList		= freeRAList->next->next;
+
+				//populate RAList nodes
+				raNode1->label	= curLabel;
+				raNode2->label	= bottomLabel;
+
+				//insert nodes into the RAM
+				exists			= 0;
+				raList[curLabel  ].Insert(raNode2);
+				exists			= raList[bottomLabel].Insert(raNode1);
+
+				//if the node already exists then place
+				//nodes back onto the region adjacency
+				//free list
+				if(exists)
+					freeRAList = oldRAFreeList;
+
+			}
+
+		}
+
+		//check only to the bottom neighbors of the right boundary
+		//pixels...
+
+		//calculate pixel locations (j = width-1)
+		curLabel	= labels[i*width+j    ];	//current pixel
+		bottomLabel = labels[(i+1)*width+j];	//bottom  pixel
+
+		//check below, if the label of
+		//the bottom pixel is not the same as that
+		//of the current one then region[j] and region[j+width]
+		//are adjacent to one another - update the RAM
+		if(curLabel != bottomLabel)
+		{
+			//obtain RAList object from region adjacency free
+			//list
+			raNode1			= freeRAList;
+			raNode2			= freeRAList->next;
+			
+			//keep a pointer to the old region adj. free
+			//list just in case nodes already exist in respective
+			//region lists
+			oldRAFreeList	= freeRAList;
+			
+			//update region adjacency free list
+			freeRAList		= freeRAList->next->next;
+			
+			//populate RAList nodes
+			raNode1->label	= curLabel;
+			raNode2->label	= bottomLabel;
+			
+			//insert nodes into the RAM
+			exists			= 0;
+			raList[curLabel  ].Insert(raNode2);
+			exists			= raList[bottomLabel].Insert(raNode1);
+			
+			//if the node already exists then place
+			//nodes back onto the region adjacency
+			//free list
+			if(exists)
+				freeRAList = oldRAFreeList;
+
+		}
+	}
+
+	//check only to the right neighbors of the bottom boundary
+	//pixels...
+
+	//check the right for pixel locations whose x < width - 1
+	for(j = 0; j < width - 1; j++)
+	{
+		//calculate pixel labels (i = height-1)
+		curLabel	= labels[i*width+j    ];	//current pixel
+		rightLabel	= labels[i*width+j+1  ];	//right   pixel
+		
+		//check to the right, if the label of
+		//the right pixel is not the same as that
+		//of the current one then region[j] and region[j+1]
+		//are adjacent to one another - update the RAM
+		if(curLabel != rightLabel)
+		{
+			//obtain RAList object from region adjacency free
+			//list
+			raNode1			= freeRAList;
+			raNode2			= freeRAList->next;
+
+			//keep a pointer to the old region adj. free
+			//list just in case nodes already exist in respective
+			//region lists
+			oldRAFreeList	= freeRAList;
+			
+			//update region adjacency free list
+			freeRAList		= freeRAList->next->next;
+			
+			//populate RAList nodes
+			raNode1->label	= curLabel;
+			raNode2->label	= rightLabel;
+			
+			//insert nodes into the RAM
+			exists			= 0;
+			raList[curLabel  ].Insert(raNode2);
+			exists			= raList[rightLabel].Insert(raNode1);
+			
+			//if the node already exists then place
+			//nodes back onto the region adjacency
+			//free list
+			if(exists)
+				freeRAList = oldRAFreeList;
+
+		}
+
+	}
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Destroy Region Adjacency Matrix                      */
+/*******************************************************/
+/*Destroy a region adjacency matrix.                   */
+/*******************************************************/
+/*Post:                                                */
+/*      - the region adjacency matrix has been destr-  */
+/*        oyed: (1) its memory has been de-allocated,  */
+/*        (2) the RAM structure has been initialize    */
+/*        for re-use.                                  */
+/*******************************************************/
+
+void msImageProcessor::DestroyRAM( void )
+{
+
+	//de-allocate memory for region adjaceny list
+	if (raList)				delete [] raList;
+	if (raPool)				delete [] raPool;
+
+	//initialize region adjacency matrix
+	raList				= NULL;
+	freeRAList			= NULL;
+	raPool				= NULL;
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Transitive Closure                                   */
+/*******************************************************/
+/*Applies transitive closure to the RAM updating       */
+/*labels, modes and modePointCounts to reflect the new */
+/*set of merged regions resulting from transitive clo- */
+/*sure.                                                */
+/*******************************************************/
+/*Post:                                                */
+/*      - transitive closure has been applied to the   */
+/*        regions classified by the RAM and labels,    */
+/*        modes and modePointCounts have been updated  */
+/*        to reflect the new set of mergd regions res- */
+/*        ulting from transitive closure.              */
+/*******************************************************/
+
+void msImageProcessor::TransitiveClosure( void )
+{
+
+	//Step (1):
+
+	// Build RAM using classifiction structure originally
+	// generated by the method GridTable::Connect()
+	BuildRAM();
+
+	//Step (1a):
+	//Compute weights of weight graph using confidence map
+	//(if defined)
+	if(weightMapDefined)	ComputeEdgeStrengths();
+
+	//Step (2):
+
+	//Treat each region Ri as a disjoint set:
+
+	// - attempt to join Ri and Rj for all i != j that are neighbors and
+	//   whose associated modes are a normalized distance of < 0.5 from one
+	//   another
+
+	// - the label of each region in the raList is treated as a pointer to the
+	//   canonical element of that region (e.g. raList[i], initially has raList[i].label = i,
+	//   namely each region is initialized to have itself as its canonical element).
+
+	//Traverse RAM attempting to join raList[i] with its neighbors...
+	int		i, iCanEl, neighCanEl;
+	float	threshold;
+	RAList	*neighbor;
+	for(i = 0; i < regionCount; i++)
+	{
+		//aquire first neighbor in region adjacency list pointed to
+		//by raList[i]
+		neighbor	= raList[i].next;
+
+		//compute edge strenght threshold using global and local
+		//epsilon
+		if(epsilon > raList[i].edgeStrength)
+			threshold   = epsilon;
+		else
+			threshold   = raList[i].edgeStrength;
+
+		//traverse region adjacency list of region i, attempting to join
+		//it with regions whose mode is a normalized distance < 0.5 from
+		//that of region i...
+		while(neighbor)
+		{
+			//attempt to join region and neighbor...
+			if((InWindow(i, neighbor->label))&&(neighbor->edgeStrength < epsilon))
+			{
+				//region i and neighbor belong together so join them
+				//by:
+
+				// (1) find the canonical element of region i
+				iCanEl		= i;
+				while(raList[iCanEl].label != iCanEl)
+					iCanEl		= raList[iCanEl].label;
+
+				// (2) find the canonical element of neighboring region
+				neighCanEl	= neighbor->label;
+				while(raList[neighCanEl].label != neighCanEl)
+					neighCanEl	= raList[neighCanEl].label;
+
+				// if the canonical elements of are not the same then assign
+				// the canonical element having the smaller label to be the parent
+				// of the other region...
+				if(iCanEl < neighCanEl)
+					raList[neighCanEl].label	= iCanEl;
+				else
+				{
+					//must replace the canonical element of previous
+					//parent as well
+					raList[raList[iCanEl].label].label	= neighCanEl;
+
+					//re-assign canonical element
+					raList[iCanEl].label				= neighCanEl;
+				}
+			}
+
+			//check the next neighbor...
+			neighbor	= neighbor->next;
+
+		}
+	}
+
+	// Step (3):
+
+	// Level binary trees formed by canonical elements
+	for(i = 0; i < regionCount; i++)
+	{
+		iCanEl	= i;
+		while(raList[iCanEl].label != iCanEl)
+			iCanEl	= raList[iCanEl].label;
+		raList[i].label	= iCanEl;
+	}
+
+	// Step (4):
+
+	//Traverse joint sets, relabeling image.
+
+	// (a)
+
+	// Accumulate modes and re-compute point counts using canonical
+	// elements generated by step 2.
+
+	//allocate memory for mode and point count temporary buffers...
+	float	*modes_buffer	= new float	[N*regionCount];
+	int		*MPC_buffer		= new int	[regionCount];
+
+	//initialize buffers to zero
+	for(i = 0; i < regionCount; i++)
+		MPC_buffer[i]	= 0;
+	for(i = 0; i < N*regionCount; i++)
+		modes_buffer[i]	= 0;
+
+	//traverse raList accumulating modes and point counts
+	//using canoncial element information...
+	int k, iMPC;
+	for(i = 0; i < regionCount; i++)
+	{
+
+		//obtain canonical element of region i
+		iCanEl	= raList[i].label;
+
+		//obtain mode point count of region i
+		iMPC	= modePointCounts[i];
+
+		//accumulate modes_buffer[iCanEl]
+		for(k = 0; k < N; k++)
+			modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
+
+		//accumulate MPC_buffer[iCanEl]
+		MPC_buffer[iCanEl] += iMPC;
+
+	}
+
+	// (b)
+
+	// Re-label new regions of the image using the canonical
+	// element information generated by step (2)
+
+	// Also use this information to compute the modes of the newly
+	// defined regions, and to assign new region point counts in
+	// a consecute manner to the modePointCounts array
+
+	//allocate memory for label buffer
+	int	*label_buffer	= new int [regionCount];
+
+	//initialize label buffer to -1
+	for(i = 0; i < regionCount; i++)
+		label_buffer[i]	= -1;
+
+	//traverse raList re-labeling the regions
+	int	label = -1;
+	for(i = 0; i < regionCount; i++)
+	{
+		//obtain canonical element of region i
+		iCanEl	= raList[i].label;
+		if(label_buffer[iCanEl] < 0)
+		{
+			//assign a label to the new region indicated by canonical
+			//element of i
+			label_buffer[iCanEl]	= ++label;
+
+			//recompute mode storing the result in modes[label]...
+			iMPC	= MPC_buffer[iCanEl];
+			for(k = 0; k < N; k++)
+				modes[(N*label)+k]	= (modes_buffer[(N*iCanEl)+k])/(iMPC);
+
+			//assign a corresponding mode point count for this region into
+			//the mode point counts array using the MPC buffer...
+			modePointCounts[label]	= MPC_buffer[iCanEl];
+		}
+	}
+
+	//re-assign region count using label counter
+	int	oldRegionCount	= regionCount;
+	regionCount	= label+1;
+
+	// (c)
+
+	// Use the label buffer to reconstruct the label map, which specified
+	// the new image given its new regions calculated above
+
+	for(i = 0; i < height*width; i++)
+		labels[i]	= label_buffer[raList[labels[i]].label];
+
+	//de-allocate memory
+	delete [] modes_buffer;
+	delete [] MPC_buffer;
+	delete [] label_buffer;
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Compute Edge Strengths                               */
+/*******************************************************/
+/*Computes the a weight for each link in the region    */
+/*graph maintined by the RAM, resulting in a weighted  */
+/*graph in which the weights consist of a confidence   */
+/*between zero and one indicating if the regions are   */
+/*separated by a strong or weak edge.                  */
+/*******************************************************/
+/*Post:                                                */
+/*      - an edge strength has been computed between   */
+/*        each region of the image and placed as a     */
+/*        weight in the RAM to be used during transi-  */
+/*        tive closure.                                */
+/*******************************************************/
+
+void msImageProcessor::ComputeEdgeStrengths( void )
+{
+
+	//initialize visit table - used to keep track
+	//of which pixels have already been visited such
+	//as not to contribute their strength value to
+	//a boundary sum multiple times...
+	memset(visitTable, 0, L*sizeof(unsigned char));
+
+	//traverse labeled image computing edge strengths
+	//(excluding image boundary)...
+	int    x, y, dp, curLabel, rightLabel, bottomLabel;
+	RAList *curRegion;
+	for(y = 1; y < height-1; y++)
+	{
+		for(x = 1; x < width-1; x++)
+		{
+			//compute data point location using x and y
+			dp = y*width + x;
+
+			//obtain labels at different pixel locations
+			curLabel	= labels[dp      ];	//current pixel
+			rightLabel	= labels[dp+1    ];	//right   pixel
+			bottomLabel	= labels[dp+width];	//bottom  pixel
+
+			//check right and bottom neighbor to see if there is a
+			//change in label then we are at an edge therefore record
+			//the edge strength at this edge accumulating its value
+			//in the RAM...
+			if(curLabel != rightLabel)
+			{
+				//traverse into RAM...
+				curRegion = &raList[curLabel];
+				while((curRegion)&&(curRegion->label != rightLabel))
+					curRegion = curRegion->next;
+
+				//this should not occur...
+				assert(curRegion);
+
+				//accumulate edge strength
+				curRegion->edgeStrength   += weightMap[dp] + weightMap[dp+1];
+				curRegion->edgePixelCount += 2;
+			}
+
+			if(curLabel != bottomLabel)
+			{
+				//traverse into RAM...
+				curRegion = &raList[curLabel];
+				while((curRegion)&&(curRegion->label != bottomLabel))
+					curRegion = curRegion->next;
+
+				//this should not occur...
+				assert(curRegion);
+
+				//accumulate edge strength
+				if(curLabel == rightLabel)
+				{
+					curRegion->edgeStrength   += weightMap[dp] + weightMap[dp+width];
+					curRegion->edgePixelCount += 2;
+				} 
+				else
+				{
+					curRegion->edgeStrength	  += weightMap[dp+width];
+					curRegion->edgePixelCount += 1;
+				}
+
+			}
+		}
+	}
+
+	//compute strengths using accumulated strengths obtained above...
+	RAList *neighborRegion;
+	float	edgeStrength;
+	int		edgePixelCount;
+	for(x = 0; x < regionCount; x++)
+	{
+		//traverse the region list of the current region
+		curRegion	= &raList[x];
+		curRegion	= curRegion->next;
+		while(curRegion)
+		{
+			//with the assumption that regions having a smaller
+			//label in the current region list have already
+			//had their edge strengths computed, only compute
+			//edge strengths for the regions whose label is greater
+			//than x, the current region (region list) under
+			//consideration...
+			curLabel = curRegion->label;
+			if(curLabel > x)
+			{
+				//obtain pointer to the element identifying the
+				//current region in the neighbors region list...
+				neighborRegion = &raList[curLabel];
+				while((neighborRegion)&&(neighborRegion->label != x))
+					neighborRegion = neighborRegion->next;
+				
+				//this should not occur...
+				assert(neighborRegion);
+				
+				//compute edge strengths using accumulated confidence
+				//value and pixel count
+				if((edgePixelCount = curRegion->edgePixelCount + neighborRegion->edgePixelCount) != 0)
+				{
+					//compute edge strength
+					edgeStrength	= curRegion->edgeStrength + neighborRegion->edgeStrength;
+					edgeStrength	/= edgePixelCount;
+					
+					//store edge strength and pixel count for corresponding regions
+					curRegion->edgeStrength		= neighborRegion->edgeStrength		= edgeStrength;
+					curRegion->edgePixelCount	= neighborRegion->edgePixelCount	= edgePixelCount;
+				}
+			}
+
+			//traverse to the next region in the region adjacency list
+			//of the current region x
+			curRegion = curRegion->next;
+
+		}
+	}
+
+	//compute average edge strength amongst the edges connecting
+	//it to each of its neighbors
+	int numNeighbors;
+	for(x = 0; x < regionCount; x++)
+	{
+		//traverse the region list of the current region
+		//accumulating weights
+		curRegion		= &raList[x];
+		curRegion		= curRegion->next;
+		edgeStrength	= 0;
+		numNeighbors	= 0;
+		while(curRegion)
+		{
+			numNeighbors++;
+			edgeStrength   += curRegion->edgeStrength;
+			curRegion		= curRegion->next;
+		}
+
+		//divide by the number of regions connected
+		//to the current region
+		if(numNeighbors) edgeStrength /= numNeighbors;
+
+		//store the result in the raList for region
+		//x
+		raList[x].edgeStrength = edgeStrength;
+	}
+
+	//traverse raList and output the resulting list
+	//to a file
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Prune                                                */
+/*******************************************************/
+/*Prunes regions from the image whose pixel density    */
+/*is less than a specified threshold.                  */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - minRegion is the minimum allowable pixel de- */
+/*        nsity a region may have without being pruned */
+/*        from the image                               */
+/*Post:                                                */
+/*      - regions whose pixel density is less than     */
+/*        or equal to minRegion have been pruned from  */
+/*        the image.                                   */
+/*******************************************************/
+
+void msImageProcessor::Prune(int minRegion)
+{
+	
+	//Allocate Memory for temporary buffers...
+	
+	//allocate memory for mode and point count temporary buffers...
+	float	*modes_buffer	= new float	[N*regionCount];
+	int		*MPC_buffer		= new int	[regionCount];
+	
+	//allocate memory for label buffer
+	int	*label_buffer		= new int	[regionCount];
+	
+	//Declare variables
+	int		i, k, candidate, iCanEl, neighCanEl, iMPC, label, oldRegionCount, minRegionCount;
+	double	minSqDistance, neighborDistance;
+	RAList	*neighbor;
+	
+	//Apply pruning algorithm to classification structure, removing all regions whose area
+	//is under the threshold area minRegion (pixels)
+	do
+	{
+		//Assume that no region has area under threshold area  of 
+		minRegionCount	= 0;		
+
+		//Step (1):
+		
+		// Build RAM using classifiction structure originally
+		// generated by the method GridTable::Connect()
+		BuildRAM();
+		
+		// Step (2):
+		
+		// Traverse the RAM joining regions whose area is less than minRegion (pixels)
+		// with its respective candidate region.
+		
+		// A candidate region is a region that displays the following properties:
+		
+		//	- it is adjacent to the region being pruned
+		
+		//  - the distance of its mode is a minimum to that of the region being pruned
+		//    such that or it is the only adjacent region having an area greater than
+		//    minRegion
+		
+		for(i = 0; i < regionCount; i++)
+		{
+			//if the area of the ith region is less than minRegion
+			//join it with its candidate region...
+
+			//*******************************************************************************
+
+			//Note: Adjust this if statement if a more sophisticated pruning criterion
+			//      is desired. Basically in this step a region whose area is less than
+			//      minRegion is pruned by joining it with its "closest" neighbor (in color).
+			//      Therefore, by placing a different criterion for fusing a region the
+			//      pruning method may be altered to implement a more sophisticated algorithm.
+
+			//*******************************************************************************
+
+			if(modePointCounts[i] < minRegion)
+			{
+				//update minRegionCount to indicate that a region
+				//having area less than minRegion was found
+				minRegionCount++;
+
+				//obtain a pointer to the first region in the
+				//region adjacency list of the ith region...
+				neighbor	= raList[i].next;
+				
+				//calculate the distance between the mode of the ith
+				//region and that of the neighboring region...
+				candidate		= neighbor->label;
+				minSqDistance	= SqDistance(i, candidate);
+				
+				//traverse region adjacency list of region i and select
+				//a candidate region
+				neighbor	= neighbor->next;
+				while(neighbor)
+				{
+
+					//calculate the square distance between region i
+					//and current neighbor...
+					neighborDistance = SqDistance(i, neighbor->label);
+
+					//if this neighbors square distance to region i is less
+					//than minSqDistance, then select this neighbor as the
+					//candidate region for region i
+					if(neighborDistance < minSqDistance)
+					{
+						minSqDistance	= neighborDistance;
+						candidate		= neighbor->label;
+					}
+
+					//traverse region list of region i
+					neighbor	= neighbor->next;
+
+				}
+
+				//join region i with its candidate region:
+
+				// (1) find the canonical element of region i
+				iCanEl		= i;
+				while(raList[iCanEl].label != iCanEl)
+					iCanEl		= raList[iCanEl].label;
+
+				// (2) find the canonical element of neighboring region
+				neighCanEl	= candidate;
+				while(raList[neighCanEl].label != neighCanEl)
+					neighCanEl	= raList[neighCanEl].label;
+
+				// if the canonical elements of are not the same then assign
+				// the canonical element having the smaller label to be the parent
+				// of the other region...
+				if(iCanEl < neighCanEl)
+					raList[neighCanEl].label	= iCanEl;
+				else
+				{
+					//must replace the canonical element of previous
+					//parent as well
+					raList[raList[iCanEl].label].label	= neighCanEl;
+
+					//re-assign canonical element
+					raList[iCanEl].label				= neighCanEl;
+				}
+			}
+		}
+
+		// Step (3):
+		
+		// Level binary trees formed by canonical elements
+		for(i = 0; i < regionCount; i++)
+		{
+			iCanEl	= i;
+			while(raList[iCanEl].label != iCanEl)
+				iCanEl	= raList[iCanEl].label;
+			raList[i].label	= iCanEl;
+		}
+		
+		// Step (4):
+		
+		//Traverse joint sets, relabeling image.
+		
+		// Accumulate modes and re-compute point counts using canonical
+		// elements generated by step 2.
+		
+		//initialize buffers to zero
+		for(i = 0; i < regionCount; i++)
+			MPC_buffer[i]	= 0;
+		for(i = 0; i < N*regionCount; i++)
+			modes_buffer[i]	= 0;
+		
+		//traverse raList accumulating modes and point counts
+		//using canoncial element information...
+		for(i = 0; i < regionCount; i++)
+		{
+			
+			//obtain canonical element of region i
+			iCanEl	= raList[i].label;
+			
+			//obtain mode point count of region i
+			iMPC	= modePointCounts[i];
+			
+			//accumulate modes_buffer[iCanEl]
+			for(k = 0; k < N; k++)
+				modes_buffer[(N*iCanEl)+k] += iMPC*modes[(N*i)+k];
+			
+			//accumulate MPC_buffer[iCanEl]
+			MPC_buffer[iCanEl] += iMPC;
+			
+		}
+		
+		// (b)
+		
+		// Re-label new regions of the image using the canonical
+		// element information generated by step (2)
+		
+		// Also use this information to compute the modes of the newly
+		// defined regions, and to assign new region point counts in
+		// a consecute manner to the modePointCounts array
+		
+		//initialize label buffer to -1
+		for(i = 0; i < regionCount; i++)
+			label_buffer[i]	= -1;
+		
+		//traverse raList re-labeling the regions
+		label = -1;
+		for(i = 0; i < regionCount; i++)
+		{
+			//obtain canonical element of region i
+			iCanEl	= raList[i].label;
+			if(label_buffer[iCanEl] < 0)
+			{
+				//assign a label to the new region indicated by canonical
+				//element of i
+				label_buffer[iCanEl]	= ++label;
+				
+				//recompute mode storing the result in modes[label]...
+				iMPC	= MPC_buffer[iCanEl];
+				for(k = 0; k < N; k++)
+					modes[(N*label)+k]	= (modes_buffer[(N*iCanEl)+k])/(iMPC);
+				
+				//assign a corresponding mode point count for this region into
+				//the mode point counts array using the MPC buffer...
+				modePointCounts[label]	= MPC_buffer[iCanEl];
+			}
+		}
+		
+		//re-assign region count using label counter
+		oldRegionCount	= regionCount;
+		regionCount		= label+1;
+		
+		// (c)
+		
+		// Use the label buffer to reconstruct the label map, which specified
+		// the new image given its new regions calculated above
+		
+		for(i = 0; i < height*width; i++)
+			labels[i]	= label_buffer[raList[labels[i]].label];
+
+		
+	}	while(minRegionCount > 0);
+
+	//de-allocate memory
+	delete [] modes_buffer;
+	delete [] MPC_buffer;
+	delete [] label_buffer;
+	
+	//done.
+	return;
+	
+}
+
+/*******************************************************/
+/*Define Boundaries                                    */
+/*******************************************************/
+/*Defines the boundaries for each region of the segm-  */
+/*ented image storing the result into a region list    */
+/*object.                                              */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - the image has been segmented and a classifi- */
+/*        cation structure has been created for this   */
+/*        image                                        */
+/*Post:                                                */
+/*      - the boundaries of the segmented image have   */
+/*        been defined and the boundaries of each reg- */
+/*        ion has been stored into a region list obj-  */
+/*        ect.                                         */
+/*******************************************************/
+
+void msImageProcessor::DefineBoundaries( void )
+{
+
+	//declare and allocate memory for boundary map and count
+	int	*boundaryMap,	*boundaryCount;
+	if((!(boundaryMap = new int [L]))||(!(boundaryCount = new int [regionCount])))
+		ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory.");
+
+	//initialize boundary map and count
+	int i;
+	for(i = 0; i < L; i++)
+		boundaryMap[i]		= -1;
+	for(i = 0; i < regionCount; i++)
+		boundaryCount[i]	=  0;
+
+	//initialize and declare total boundary count -
+	//the total number of boundary pixels present in
+	//the segmented image
+	int	totalBoundaryCount	= 0;
+
+	//traverse the image checking the right and bottom
+	//four connected neighbors of each pixel marking
+	//boundary map with the boundaries of each region and
+	//incrementing boundaryCount using the label information
+
+	//***********************************************************************
+	//***********************************************************************
+
+	int		j, label, dataPoint;
+
+	//first row (every pixel is a boundary pixel)
+	for(i = 0; i < width; i++)
+	{
+			boundaryMap[i]		= label	= labels[i];
+			boundaryCount[label]++;
+			totalBoundaryCount++;
+	}
+
+	//define boundaries for all rows except for the first
+	//and last one...
+	for(i = 1; i < height - 1; i++)
+	{
+		//mark the first pixel in an image row as an image boundary...
+		dataPoint				= i*width;
+		boundaryMap[dataPoint]	= label	= labels[dataPoint];
+		boundaryCount[label]++;
+		totalBoundaryCount++;
+
+		for(j = 1; j < width - 1; j++)
+		{
+			//define datapoint and its right and bottom
+			//four connected neighbors
+			dataPoint		= i*width+j;
+
+			//check four connected neighbors if they are
+			//different this pixel is a boundary pixel
+			label	= labels[dataPoint];
+			if((label != labels[dataPoint-1])    ||(label != labels[dataPoint+1])||
+			   (label != labels[dataPoint-width])||(label != labels[dataPoint+width]))
+			{
+				boundaryMap[dataPoint]		= label	= labels[dataPoint];
+				boundaryCount[label]++;
+				totalBoundaryCount++;
+			}
+		}
+
+		//mark the last pixel in an image row as an image boundary...
+		dataPoint				= (i+1)*width-1;
+		boundaryMap[dataPoint]	= label	= labels[dataPoint];
+		boundaryCount[label]++;
+		totalBoundaryCount++;
+
+	}
+
+	//last row (every pixel is a boundary pixel) (i = height-1)
+	register int	start	= (height-1)*width, stop = height*width;
+	for(i = start; i < stop; i++)
+	{
+		boundaryMap[i]		= label	= labels[i];
+		boundaryCount[label]++;
+		totalBoundaryCount++;
+	}
+
+	//***********************************************************************
+	//***********************************************************************
+
+	//store boundary locations into a boundary buffer using
+	//boundary map and count
+
+	//***********************************************************************
+	//***********************************************************************
+
+	int	*boundaryBuffer	= new int [totalBoundaryCount], *boundaryIndex	= new int [regionCount];
+
+	//use boundary count to initialize boundary index...
+	int counter = 0;
+	for(i = 0; i < regionCount; i++)
+	{
+		boundaryIndex[i]	= counter;
+		counter			   += boundaryCount[i];
+	}
+
+	//traverse boundary map placing the boundary pixel
+	//locations into the boundaryBuffer
+	for(i = 0; i < L; i++)
+	{
+		//if its a boundary pixel store it into
+		//the boundary buffer
+		if((label = boundaryMap[i]) >= 0)
+		{
+			boundaryBuffer[boundaryIndex[label]] = i;
+			boundaryIndex[label]++;
+		}
+	}
+
+	//***********************************************************************
+	//***********************************************************************
+
+	//store the boundary locations stored by boundaryBuffer into
+	//the region list for each region
+
+	//***********************************************************************
+	//***********************************************************************
+
+	//destroy the old region list
+	if(regionList)	delete regionList;
+
+	//create a new region list
+	if(!(regionList	= new RegionList(regionCount, totalBoundaryCount, N)))
+		ErrorHandler("msImageProcessor", "DefineBoundaries", "Not enough memory.");
+
+	//add boundary locations for each region using the boundary
+	//buffer and boundary counts
+	counter	= 0;
+	for(i = 0; i < regionCount; i++)
+	{
+		regionList->AddRegion(i, boundaryCount[i], &boundaryBuffer[counter]);
+		counter += boundaryCount[i];
+	}
+
+	//***********************************************************************
+	//***********************************************************************
+
+   // dealocate local used memory
+ 	delete [] boundaryMap;
+   delete [] boundaryCount;
+	delete [] boundaryBuffer;
+   delete [] boundaryIndex;
+
+	//done.
+	return;
+
+}
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/*  Image Data Searching/Distance Calculation */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+		
+/*******************************************************/
+/*In Window                                            */
+/*******************************************************/
+/*Returns true if the two specified data points are    */
+/*within rR of each other.                             */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - mode1 and mode2 are indeces into msRawData   */
+/*        specifying the modes of the pixels having    */
+/*        these indeces.                               */
+/*Post:                                                */
+/*      - true is returned if mode1 and mode2 are wi-  */
+/*        thin rR of one another, false is returned    */
+/*        otherwise.                                   */
+/*******************************************************/
+
+bool msImageProcessor::InWindow(int mode1, int mode2)
+{
+	int		k		= 1, s	= 0, p;
+	double	diff	= 0, el;
+	while((diff < 0.25)&&(k != kp)) // Partial Distortion Search
+	{
+		//Calculate distance squared of sub-space s	
+		diff = 0;
+		for(p = 0; p < P[k]; p++)
+		{
+			el    = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
+			if((!p)&&(k == 1)&&(modes[mode1*N] > 80))
+				diff += 4*el*el;
+			else
+				diff += el*el;
+		}
+		
+		//next subspace
+		s += P[k];
+		k++;
+	}
+	return (bool)(diff < 0.25);
+}
+
+/*******************************************************/
+/*Square Distance                                      */
+/*******************************************************/
+/*Computs the normalized square distance between two   */
+/*modes.                                               */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - mode1 and mode2 are indeces into the modes   */
+/*        array specifying two modes of the image      */
+/*Post:                                                */
+/*      - the normalized square distance between modes */
+/*        indexed by mode1 and mode2 has been calc-    */
+/*        ulated and the result has been returned.     */
+/*******************************************************/
+
+float msImageProcessor::SqDistance(int mode1, int mode2)
+{
+
+	int		k		= 1, s	= 0, p;
+	float	dist	= 0, el;
+	for(k = 1; k < kp; k++)
+	{
+		//Calculate distance squared of sub-space s	
+		for(p = 0; p < P[k]; p++)
+		{
+			el    = (modes[mode1*N+p+s]-modes[mode2*N+p+s])/(h[k]*offset[k]);
+			dist += el*el;
+		}
+		
+		//next subspace
+		s += P[k];
+		k++;
+	}
+
+	//return normalized square distance between modes
+	//1 and 2
+	return dist;
+
+}
+
+	/*/\/\/\/\/\/\/\/\/\/\*/
+	/*  Memory Management */
+	/*\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Initialize Output                                    */
+/*******************************************************/
+/*Allocates memory needed by the mean shift image pro- */
+/*cessor class output storage data structure.          */
+/*******************************************************/
+/*Post:                                                */
+/*      - the memory needed by the output storage      */
+/*        structure of this class has been (re-)allo-  */
+/*        cated.                                       */
+/*******************************************************/
+
+void msImageProcessor::InitializeOutput( void )
+{
+
+	//De-allocate memory if output was defined for previous image
+	DestroyOutput();
+
+	//Allocate memory for msRawData (filtered image output)
+	if(!(msRawData = new float [L*N]))
+	{
+		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory.");
+		return;
+	}
+
+	//Allocate memory used to store image modes and their corresponding regions...
+	if((!(modes = new float [L*(N+2)]))||(!(labels = new int [L]))||(!(modePointCounts = new int [L]))||(!(indexTable	= new int [L])))
+	{
+		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory");
+		return;
+	}
+
+	//Allocate memory for integer modes used to perform connected components
+	//(image labeling)...
+//	if(!(LUV_data = new	int [N*L]))
+   if (!(LUV_data = new float[N*L]))
+	{
+		ErrorHandler("msImageProcessor", "Allocate", "Not enough memory");
+		return;
+	}
+
+	//indicate that the class output storage structure has been defined
+	class_state.OUTPUT_DEFINED	= true;
+
+}
+
+/*******************************************************/
+/*Destroy Output                                       */
+/*******************************************************/
+/*De-allocates memory needed by the mean shift image   */
+/*processor class output storage data structure.       */
+/*******************************************************/
+/*Post:                                                */
+/*      - the memory needed by the output storage      */
+/*        structure of this class has been de-alloc-   */
+/*        ated.                                        */
+/*      - the output storage structure has been init-  */
+/*        ialized for re-use.                          */
+/*******************************************************/
+
+void msImageProcessor::DestroyOutput( void )
+{
+
+	//de-allocate memory for msRawData (filtered image output)
+	if (msRawData)			delete [] msRawData;
+
+	//de-allocate memory used by output storage and image
+	//classification structure
+	if (modes)				delete [] modes;
+	if (labels)				delete [] labels;
+	if (modePointCounts)	delete [] modePointCounts;
+	if (indexTable)			delete [] indexTable;
+	
+	//de-allocate memory for LUV_data
+	if (LUV_data)			delete [] LUV_data;
+		
+	//initialize data members for re-use...
+
+	//initialize output structures...
+	msRawData			= NULL;
+
+	//re-initialize classification structure
+	modes						= NULL;
+	labels						= NULL;
+	modePointCounts				= NULL;
+	regionCount					= 0;
+
+	//indicate that the output has been destroyed
+	class_state.OUTPUT_DEFINED	= false;
+
+	//done.
+	return;
+
+}
+
+// NEW
+void msImageProcessor::NewOptimizedFilter1(float sigmaS, float sigmaR)
+{
+	// Declare Variables
+	int		iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
+	double	mvAbs, diff, el;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+
+   // let's use some temporary data
+   float* sdata;
+   sdata = new float[lN*L];
+
+   // copy the scaled data
+   int idxs, idxd;
+   idxs = idxd = 0;
+   if (N==3)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else if (N==1)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         for (j=0; j<N; j++)
+            sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   }
+   // index the data in the 3d buckets (x, y, L)
+   int* buckets;
+   int* slist;
+   slist = new int[L];
+   int bucNeigh[27];
+
+   float sMins; // just for L
+   float sMaxs[3]; // for all
+   sMaxs[0] = width/sigmaS;
+   sMaxs[1] = height/sigmaS;
+   sMins = sMaxs[2] = sdata[2];
+   idxs = 2;
+   float cval;
+   for(i=0; i<L; i++)
+   {
+      cval = sdata[idxs];
+      if (cval < sMins)
+         sMins = cval;
+      else if (cval > sMaxs[2])
+         sMaxs[2] = cval;
+
+      idxs += lN;
+   }
+
+   int nBuck1, nBuck2, nBuck3;
+   int cBuck1, cBuck2, cBuck3, cBuck;
+   nBuck1 = (int) (sMaxs[0] + 3);
+   nBuck2 = (int) (sMaxs[1] + 3);
+   nBuck3 = (int) (sMaxs[2] - sMins + 3);
+   buckets = new int[nBuck1*nBuck2*nBuck3];
+   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
+      buckets[i] = -1;
+
+   idxs = 0;
+   for(i=0; i<L; i++)
+   {
+      // find bucket for current data and add it to the list
+      cBuck1 = (int) sdata[idxs] + 1;
+      cBuck2 = (int) sdata[idxs+1] + 1;
+      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+
+      slist[i] = buckets[cBuck];
+      buckets[cBuck] = i;
+
+      idxs += lN;
+   }
+   // init bucNeigh
+   idxd = 0;
+   for (cBuck1=-1; cBuck1<=1; cBuck1++)
+   {
+      for (cBuck2=-1; cBuck2<=1; cBuck2++)
+      {
+         for (cBuck3=-1; cBuck3<=1; cBuck3++)
+         {
+            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         }
+      }
+   }
+   double wsuml, weight;
+   double hiLTr = 80.0/sigmaR;
+   // done indexing/hashing
+
+	
+	// Initialize mode table used for basin of attraction
+	memset(modeTable, 0, width*height);
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+
+	for(i = 0; i < L; i++)
+	{
+		// if a mode was already assigned to this data point
+		// then skip this point, otherwise proceed to
+		// find its mode by applying mean shift...
+		if (modeTable[i] == 1)
+			continue;
+
+		// initialize point list...
+		pointCount = 0;
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+      idxs = i*lN;
+      for (j=0; j<lN; j++)
+         yk[j] = sdata[idxs+j];
+		
+		// Calculate the mean shift vector using the lattice
+		// LatticeMSVector(Mh, yk); // modify to new
+      /*****************************************************/
+   	// Initialize mean shift vector
+	   for(j = 0; j < lN; j++)
+   		Mh[j] = 0;
+   	wsuml = 0;
+      // uniformLSearch(Mh, yk_ptr); // modify to new
+      // find bucket of yk
+      cBuck1 = (int) yk[0] + 1;
+      cBuck2 = (int) yk[1] + 1;
+      cBuck3 = (int) (yk[2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+      for (j=0; j<27; j++)
+      {
+         idxd = buckets[cBuck+bucNeigh[j]];
+         // list parse, crt point is cHeadList
+         while (idxd>=0)
+         {
+            idxs = lN*idxd;
+            // determine if inside search window
+            el = sdata[idxs+0]-yk[0];
+            diff = el*el;
+            el = sdata[idxs+1]-yk[1];
+            diff += el*el;
+
+            if (diff < 1.0)
+            {
+               el = sdata[idxs+2]-yk[2];
+               if (yk[2] > hiLTr)
+                  diff = 4*el*el;
+               else
+                  diff = el*el;
+
+               if (N>1)
+               {
+                  el = sdata[idxs+3]-yk[3];
+                  diff += el*el;
+                  el = sdata[idxs+4]-yk[4];
+                  diff += el*el;
+               }
+
+               if (diff < 1.0)
+               {
+                  weight = 1-weightMap[idxd];
+                  for (k=0; k<lN; k++)
+                     Mh[k] += weight*sdata[idxs+k];
+                  wsuml += weight;
+               }
+            }
+            idxd = slist[idxd];
+         }
+      }
+   	if (wsuml > 0)
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = Mh[j]/wsuml - yk[j];
+   	}
+   	else
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = 0;
+   	}
+      /*****************************************************/
+   	// Calculate its magnitude squared
+		//mvAbs = 0;
+		//for(j = 0; j < lN; j++)
+		//	mvAbs += Mh[j]*Mh[j];
+      mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
+      if (N==3)
+         mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
+      else
+         mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
+
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// check to see if the current mode location is in the
+			// basin of attraction...
+
+			// calculate the location of yk on the lattice
+			modeCandidateX	= (int) (sigmaS*yk[0]+0.5);
+			modeCandidateY	= (int) (sigmaS*yk[1]+0.5);
+			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
+
+			// if mvAbs != 0 (yk did indeed move) then check
+			// location basin_i in the mode table to see if
+			// this data point either:
+			
+			// (1) has not been associated with a mode yet
+			//     (modeTable[basin_i] = 0), so associate
+			//     it with this one
+			//
+			// (2) it has been associated with a mode other
+			//     than the one that this data point is converging
+			//     to (modeTable[basin_i] = 1), so assign to
+			//     this data point the same mode as that of basin_i
+
+			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
+			{
+				// obtain the data point at basin_i to
+				// see if it is within h*TC_DIST_FACTOR of
+				// of yk
+            diff = 0;
+            idxs = lN*modeCandidate_i;
+            for (k=2; k<lN; k++)
+            {
+               el = sdata[idxs+k] - yk[k];
+               diff += el*el;
+            }
+
+				// if the data point at basin_i is within
+				// a distance of h*TC_DIST_FACTOR of yk
+				// then depending on modeTable[basin_i] perform
+				// either (1) or (2)
+				if (diff < TC_DIST_FACTOR)
+				{
+					// if the data point at basin_i has not
+					// been associated to a mode then associate
+					// it with the mode that this one will converge
+					// to
+					if (modeTable[modeCandidate_i] == 0)
+					{
+						// no mode associated yet so associate
+						// it with this one...
+						pointList[pointCount++]		= modeCandidate_i;
+						modeTable[modeCandidate_i]	= 2;
+
+					} else
+					{
+
+						// the mode has already been associated with
+						// another mode, thererfore associate this one
+						// mode and the modes in the point list with
+						// the mode associated with data[basin_i]...
+
+						// store the mode info into yk using msRawData...
+						for (j = 0; j < N; j++)
+							yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
+
+						// update mode table for this data point
+						// indicating that a mode has been associated
+						// with it
+						modeTable[i] = 1;
+
+						// indicate that a mode has been associated
+						// to this data point (data[i])
+						mvAbs = -1;
+
+						// stop mean shift calculation...
+						break;
+					}
+				}
+			}
+			
+         // Calculate the mean shift vector at the new
+         // window location using lattice
+         // Calculate the mean shift vector using the lattice
+         // LatticeMSVector(Mh, yk); // modify to new
+         /*****************************************************/
+         // Initialize mean shift vector
+         for(j = 0; j < lN; j++)
+            Mh[j] = 0;
+         wsuml = 0;
+         // uniformLSearch(Mh, yk_ptr); // modify to new
+         // find bucket of yk
+         cBuck1 = (int) yk[0] + 1;
+         cBuck2 = (int) yk[1] + 1;
+         cBuck3 = (int) (yk[2] - sMins) + 1;
+         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         for (j=0; j<27; j++)
+         {
+            idxd = buckets[cBuck+bucNeigh[j]];
+            // list parse, crt point is cHeadList
+            while (idxd>=0)
+            {
+               idxs = lN*idxd;
+               // determine if inside search window
+               el = sdata[idxs+0]-yk[0];
+               diff = el*el;
+               el = sdata[idxs+1]-yk[1];
+               diff += el*el;
+               
+               if (diff < 1.0)
+               {
+                  el = sdata[idxs+2]-yk[2];
+                  if (yk[2] > hiLTr)
+                     diff = 4*el*el;
+                  else
+                     diff = el*el;
+                  
+                  if (N>1)
+                  {
+                     el = sdata[idxs+3]-yk[3];
+                     diff += el*el;
+                     el = sdata[idxs+4]-yk[4];
+                     diff += el*el;
+                  }
+                  
+                  if (diff < 1.0)
+                  {
+                     weight = 1-weightMap[idxd];
+                     for (k=0; k<lN; k++)
+                        Mh[k] += weight*sdata[idxs+k];
+                     wsuml += weight;
+                  }
+               }
+               idxd = slist[idxd];
+            }
+         }
+         if (wsuml > 0)
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = Mh[j]/wsuml - yk[j];
+         }
+         else
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = 0;
+         }
+         /*****************************************************/
+			
+			// Calculate its magnitude squared
+			//mvAbs = 0;
+			//for(j = 0; j < lN; j++)
+			//	mvAbs += Mh[j]*Mh[j];
+         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
+         if (N==3)
+            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
+         else
+            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
+
+			// Increment iteration count
+			iterationCount++;
+			
+		}
+
+		// if a mode was not associated with this data point
+		// yet associate it with yk...
+		if (mvAbs >= 0)
+		{
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// update mode table for this data point
+			// indicating that a mode has been associated
+			// with it
+			modeTable[i] = 1;
+
+		}
+		
+      for (k=0; k<N; k++)
+         yk[k+2] *= sigmaR;
+
+		// associate the data point indexed by
+		// the point list with the mode stored
+		// by yk
+		for (j = 0; j < pointCount; j++)
+		{
+			// obtain the point location from the
+			// point list
+			modeCandidate_i = pointList[j];
+
+			// update the mode table for this point
+			modeTable[modeCandidate_i] = 1;
+
+			//store result into msRawData...
+			for(k = 0; k < N; k++)
+				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
+		}
+
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;		
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	// de-allocate memory
+   delete [] buckets;
+   delete [] slist;
+   delete [] sdata;
+
+	delete [] yk;
+	delete [] Mh;
+	
+	// done.
+	return;
+
+}
+
+// NEW
+void msImageProcessor::NewOptimizedFilter2(float sigmaS, float sigmaR)
+{
+	// Declare Variables
+	int		iterationCount, i, j, k, modeCandidateX, modeCandidateY, modeCandidate_i;
+	double	mvAbs, diff, el;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+
+   // let's use some temporary data
+   float* sdata;
+   sdata = new float[lN*L];
+
+   // copy the scaled data
+   int idxs, idxd;
+   idxs = idxd = 0;
+   if (N==3)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else if (N==1)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         for (j=0; j<N; j++)
+            sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   }
+   // index the data in the 3d buckets (x, y, L)
+   int* buckets;
+   int* slist;
+   slist = new int[L];
+   int bucNeigh[27];
+
+   float sMins; // just for L
+   float sMaxs[3]; // for all
+   sMaxs[0] = width/sigmaS;
+   sMaxs[1] = height/sigmaS;
+   sMins = sMaxs[2] = sdata[2];
+   idxs = 2;
+   float cval;
+   for(i=0; i<L; i++)
+   {
+      cval = sdata[idxs];
+      if (cval < sMins)
+         sMins = cval;
+      else if (cval > sMaxs[2])
+         sMaxs[2] = cval;
+
+      idxs += lN;
+   }
+
+   int nBuck1, nBuck2, nBuck3;
+   int cBuck1, cBuck2, cBuck3, cBuck;
+   nBuck1 = (int) (sMaxs[0] + 3);
+   nBuck2 = (int) (sMaxs[1] + 3);
+   nBuck3 = (int) (sMaxs[2] - sMins + 3);
+   buckets = new int[nBuck1*nBuck2*nBuck3];
+   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
+      buckets[i] = -1;
+
+   idxs = 0;
+   for(i=0; i<L; i++)
+   {
+      // find bucket for current data and add it to the list
+      cBuck1 = (int) sdata[idxs] + 1;
+      cBuck2 = (int) sdata[idxs+1] + 1;
+      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+
+      slist[i] = buckets[cBuck];
+      buckets[cBuck] = i;
+
+      idxs += lN;
+   }
+   // init bucNeigh
+   idxd = 0;
+   for (cBuck1=-1; cBuck1<=1; cBuck1++)
+   {
+      for (cBuck2=-1; cBuck2<=1; cBuck2++)
+      {
+         for (cBuck3=-1; cBuck3<=1; cBuck3++)
+         {
+            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         }
+      }
+   }
+   double wsuml, weight;
+   double hiLTr = 80.0/sigmaR;
+   // done indexing/hashing
+
+	
+	// Initialize mode table used for basin of attraction
+	memset(modeTable, 0, width*height);
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice) ... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+
+	for(i = 0; i < L; i++)
+	{
+		// if a mode was already assigned to this data point
+		// then skip this point, otherwise proceed to
+		// find its mode by applying mean shift...
+		if (modeTable[i] == 1)
+			continue;
+
+		// initialize point list...
+		pointCount = 0;
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+      idxs = i*lN;
+      for (j=0; j<lN; j++)
+         yk[j] = sdata[idxs+j];
+		
+		// Calculate the mean shift vector using the lattice
+		// LatticeMSVector(Mh, yk); // modify to new
+      /*****************************************************/
+   	// Initialize mean shift vector
+	   for(j = 0; j < lN; j++)
+   		Mh[j] = 0;
+   	wsuml = 0;
+      // uniformLSearch(Mh, yk_ptr); // modify to new
+      // find bucket of yk
+      cBuck1 = (int) yk[0] + 1;
+      cBuck2 = (int) yk[1] + 1;
+      cBuck3 = (int) (yk[2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+      for (j=0; j<27; j++)
+      {
+         idxd = buckets[cBuck+bucNeigh[j]];
+         // list parse, crt point is cHeadList
+         while (idxd>=0)
+         {
+            idxs = lN*idxd;
+            // determine if inside search window
+            el = sdata[idxs+0]-yk[0];
+            diff = el*el;
+            el = sdata[idxs+1]-yk[1];
+            diff += el*el;
+
+            if (diff < 1.0)
+            {
+               el = sdata[idxs+2]-yk[2];
+               if (yk[2] > hiLTr)
+                  diff = 4*el*el;
+               else
+                  diff = el*el;
+
+               if (N>1)
+               {
+                  el = sdata[idxs+3]-yk[3];
+                  diff += el*el;
+                  el = sdata[idxs+4]-yk[4];
+                  diff += el*el;
+               }
+
+               if (diff < 1.0)
+               {
+                  weight = 1-weightMap[idxd];
+                  for (k=0; k<lN; k++)
+                     Mh[k] += weight*sdata[idxs+k];
+                  wsuml += weight;
+
+      				//set basin of attraction mode table
+                  if (diff < speedThreshold)
+                  {
+				         if(modeTable[idxd] == 0)
+				         {
+         					pointList[pointCount++]	= idxd;
+					         modeTable[idxd]	= 2;
+      				   }
+                  }
+               }
+            }
+            idxd = slist[idxd];
+         }
+      }
+   	if (wsuml > 0)
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = Mh[j]/wsuml - yk[j];
+   	}
+   	else
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = 0;
+   	}
+      /*****************************************************/
+   	// Calculate its magnitude squared
+		//mvAbs = 0;
+		//for(j = 0; j < lN; j++)
+		//	mvAbs += Mh[j]*Mh[j];
+      mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
+      if (N==3)
+         mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
+      else
+         mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
+
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// check to see if the current mode location is in the
+			// basin of attraction...
+
+			// calculate the location of yk on the lattice
+			modeCandidateX	= (int) (sigmaS*yk[0]+0.5);
+			modeCandidateY	= (int) (sigmaS*yk[1]+0.5);
+			modeCandidate_i	= modeCandidateY*width + modeCandidateX;
+
+			// if mvAbs != 0 (yk did indeed move) then check
+			// location basin_i in the mode table to see if
+			// this data point either:
+			
+			// (1) has not been associated with a mode yet
+			//     (modeTable[basin_i] = 0), so associate
+			//     it with this one
+			//
+			// (2) it has been associated with a mode other
+			//     than the one that this data point is converging
+			//     to (modeTable[basin_i] = 1), so assign to
+			//     this data point the same mode as that of basin_i
+
+			if ((modeTable[modeCandidate_i] != 2) && (modeCandidate_i != i))
+			{
+				// obtain the data point at basin_i to
+				// see if it is within h*TC_DIST_FACTOR of
+				// of yk
+            diff = 0;
+            idxs = lN*modeCandidate_i;
+            for (k=2; k<lN; k++)
+            {
+               el = sdata[idxs+k] - yk[k];
+               diff += el*el;
+            }
+
+				// if the data point at basin_i is within
+				// a distance of h*TC_DIST_FACTOR of yk
+				// then depending on modeTable[basin_i] perform
+				// either (1) or (2)
+				if (diff < speedThreshold)
+				{
+					// if the data point at basin_i has not
+					// been associated to a mode then associate
+					// it with the mode that this one will converge
+					// to
+					if (modeTable[modeCandidate_i] == 0)
+					{
+						// no mode associated yet so associate
+						// it with this one...
+						pointList[pointCount++]		= modeCandidate_i;
+						modeTable[modeCandidate_i]	= 2;
+
+					} else
+					{
+
+						// the mode has already been associated with
+						// another mode, thererfore associate this one
+						// mode and the modes in the point list with
+						// the mode associated with data[basin_i]...
+
+						// store the mode info into yk using msRawData...
+						for (j = 0; j < N; j++)
+							yk[j+2] = msRawData[modeCandidate_i*N+j]/sigmaR;
+
+						// update mode table for this data point
+						// indicating that a mode has been associated
+						// with it
+						modeTable[i] = 1;
+
+						// indicate that a mode has been associated
+						// to this data point (data[i])
+						mvAbs = -1;
+
+						// stop mean shift calculation...
+						break;
+					}
+				}
+			}
+			
+         // Calculate the mean shift vector at the new
+         // window location using lattice
+         // Calculate the mean shift vector using the lattice
+         // LatticeMSVector(Mh, yk); // modify to new
+         /*****************************************************/
+         // Initialize mean shift vector
+         for(j = 0; j < lN; j++)
+            Mh[j] = 0;
+         wsuml = 0;
+         // uniformLSearch(Mh, yk_ptr); // modify to new
+         // find bucket of yk
+         cBuck1 = (int) yk[0] + 1;
+         cBuck2 = (int) yk[1] + 1;
+         cBuck3 = (int) (yk[2] - sMins) + 1;
+         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         for (j=0; j<27; j++)
+         {
+            idxd = buckets[cBuck+bucNeigh[j]];
+            // list parse, crt point is cHeadList
+            while (idxd>=0)
+            {
+               idxs = lN*idxd;
+               // determine if inside search window
+               el = sdata[idxs+0]-yk[0];
+               diff = el*el;
+               el = sdata[idxs+1]-yk[1];
+               diff += el*el;
+               
+               if (diff < 1.0)
+               {
+                  el = sdata[idxs+2]-yk[2];
+                  if (yk[2] > hiLTr)
+                     diff = 4*el*el;
+                  else
+                     diff = el*el;
+                  
+                  if (N>1)
+                  {
+                     el = sdata[idxs+3]-yk[3];
+                     diff += el*el;
+                     el = sdata[idxs+4]-yk[4];
+                     diff += el*el;
+                  }
+                  
+                  if (diff < 1.0)
+                  {
+                     weight = 1-weightMap[idxd];
+                     for (k=0; k<lN; k++)
+                        Mh[k] += weight*sdata[idxs+k];
+                     wsuml += weight;
+
+         				//set basin of attraction mode table
+                     if (diff < speedThreshold)
+                     {
+   				         if(modeTable[idxd] == 0)
+				            {
+            					pointList[pointCount++]	= idxd;
+					            modeTable[idxd]	= 2;
+      				      }
+                     }
+
+                  }
+               }
+               idxd = slist[idxd];
+            }
+         }
+         if (wsuml > 0)
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = Mh[j]/wsuml - yk[j];
+         }
+         else
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = 0;
+         }
+         /*****************************************************/
+			
+			// Calculate its magnitude squared
+			//mvAbs = 0;
+			//for(j = 0; j < lN; j++)
+			//	mvAbs += Mh[j]*Mh[j];
+         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
+         if (N==3)
+            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
+         else
+            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
+
+			// Increment iteration count
+			iterationCount++;
+			
+		}
+
+		// if a mode was not associated with this data point
+		// yet associate it with yk...
+		if (mvAbs >= 0)
+		{
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// update mode table for this data point
+			// indicating that a mode has been associated
+			// with it
+			modeTable[i] = 1;
+
+		}
+		
+      for (k=0; k<N; k++)
+         yk[k+2] *= sigmaR;
+
+		// associate the data point indexed by
+		// the point list with the mode stored
+		// by yk
+		for (j = 0; j < pointCount; j++)
+		{
+			// obtain the point location from the
+			// point list
+			modeCandidate_i = pointList[j];
+
+			// update the mode table for this point
+			modeTable[modeCandidate_i] = 1;
+
+			//store result into msRawData...
+			for(k = 0; k < N; k++)
+				msRawData[N*modeCandidate_i+k] = (float)(yk[k+2]);
+		}
+
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;		
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	// de-allocate memory
+   delete [] buckets;
+   delete [] slist;
+   delete [] sdata;
+
+	delete [] yk;
+	delete [] Mh;
+	
+	// done.
+	return;
+
+}
+
+void msImageProcessor::NewNonOptimizedFilter(float sigmaS, float sigmaR)
+{
+
+	// Declare Variables
+	int   iterationCount, i, j, k;
+	double mvAbs, diff, el;
+	
+	//make sure that a lattice height and width have
+	//been defined...
+	if(!height)
+	{
+		ErrorHandler("msImageProcessor", "LFilter", "Lattice height and width are undefined.");
+		return;
+	}
+
+	//re-assign bandwidths to sigmaS and sigmaR
+	if(((h[0] = sigmaS) <= 0)||((h[1] = sigmaR) <= 0))
+	{
+		ErrorHandler("msImageProcessor", "Segment", "sigmaS and/or sigmaR is zero or negative.");
+		return;
+	}
+	
+	//define input data dimension with lattice
+	int lN	= N + 2;
+	
+	// Traverse each data point applying mean shift
+	// to each data point
+	
+	// Allcocate memory for yk
+	double	*yk		= new double [lN];
+	
+	// Allocate memory for Mh
+	double	*Mh		= new double [lN];
+
+   // let's use some temporary data
+   double* sdata;
+   sdata = new double[lN*L];
+
+   // copy the scaled data
+   int idxs, idxd;
+   idxs = idxd = 0;
+   if (N==3)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else if (N==1)
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i/width)/sigmaS;
+         sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   } else
+   {
+      for(i=0; i<L; i++)
+      {
+         sdata[idxs++] = (i%width)/sigmaS;
+         sdata[idxs++] = (i%width)/sigmaS;
+         for (j=0; j<N; j++)
+            sdata[idxs++] = data[idxd++]/sigmaR;
+      }
+   }
+   // index the data in the 3d buckets (x, y, L)
+   int* buckets;
+   int* slist;
+   slist = new int[L];
+   int bucNeigh[27];
+
+   double sMins; // just for L
+   double sMaxs[3]; // for all
+   sMaxs[0] = width/sigmaS;
+   sMaxs[1] = height/sigmaS;
+   sMins = sMaxs[2] = sdata[2];
+   idxs = 2;
+   double cval;
+   for(i=0; i<L; i++)
+   {
+      cval = sdata[idxs];
+      if (cval < sMins)
+         sMins = cval;
+      else if (cval > sMaxs[2])
+         sMaxs[2] = cval;
+
+      idxs += lN;
+   }
+
+   int nBuck1, nBuck2, nBuck3;
+   int cBuck1, cBuck2, cBuck3, cBuck;
+   nBuck1 = (int) (sMaxs[0] + 3);
+   nBuck2 = (int) (sMaxs[1] + 3);
+   nBuck3 = (int) (sMaxs[2] - sMins + 3);
+   buckets = new int[nBuck1*nBuck2*nBuck3];
+   for(i=0; i<(nBuck1*nBuck2*nBuck3); i++)
+      buckets[i] = -1;
+
+   idxs = 0;
+   for(i=0; i<L; i++)
+   {
+      // find bucket for current data and add it to the list
+      cBuck1 = (int) sdata[idxs] + 1;
+      cBuck2 = (int) sdata[idxs+1] + 1;
+      cBuck3 = (int) (sdata[idxs+2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+
+      slist[i] = buckets[cBuck];
+      buckets[cBuck] = i;
+
+      idxs += lN;
+   }
+   // init bucNeigh
+   idxd = 0;
+   for (cBuck1=-1; cBuck1<=1; cBuck1++)
+   {
+      for (cBuck2=-1; cBuck2<=1; cBuck2++)
+      {
+         for (cBuck3=-1; cBuck3<=1; cBuck3++)
+         {
+            bucNeigh[idxd++] = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         }
+      }
+   }
+   double wsuml, weight;
+   double hiLTr = 80.0/sigmaR;
+   // done indexing/hashing
+	
+	// proceed ...
+#ifdef PROMPT
+	msSys.Prompt("done.\nApplying mean shift (Using Lattice)... ");
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\n 0%%");
+#endif
+#endif
+
+	for(i = 0; i < L; i++)
+	{
+
+		// Assign window center (window centers are
+		// initialized by createLattice to be the point
+		// data[i])
+      idxs = i*lN;
+      for (j=0; j<lN; j++)
+         yk[j] = sdata[idxs+j];
+		
+		// Calculate the mean shift vector using the lattice
+		// LatticeMSVector(Mh, yk);
+      /*****************************************************/
+   	// Initialize mean shift vector
+	   for(j = 0; j < lN; j++)
+   		Mh[j] = 0;
+   	wsuml = 0;
+      // uniformLSearch(Mh, yk_ptr); // modify to new
+      // find bucket of yk
+      cBuck1 = (int) yk[0] + 1;
+      cBuck2 = (int) yk[1] + 1;
+      cBuck3 = (int) (yk[2] - sMins) + 1;
+      cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+      for (j=0; j<27; j++)
+      {
+         idxd = buckets[cBuck+bucNeigh[j]];
+         // list parse, crt point is cHeadList
+         while (idxd>=0)
+         {
+            idxs = lN*idxd;
+            // determine if inside search window
+            el = sdata[idxs+0]-yk[0];
+            diff = el*el;
+            el = sdata[idxs+1]-yk[1];
+            diff += el*el;
+
+            if (diff < 1.0)
+            {
+               el = sdata[idxs+2]-yk[2];
+               if (yk[2] > hiLTr)
+                  diff = 4*el*el;
+               else
+                  diff = el*el;
+
+               if (N>1)
+               {
+                  el = sdata[idxs+3]-yk[3];
+                  diff += el*el;
+                  el = sdata[idxs+4]-yk[4];
+                  diff += el*el;
+               }
+
+               if (diff < 1.0)
+               {
+                  weight = 1-weightMap[idxd];
+                  for (k=0; k<lN; k++)
+                     Mh[k] += weight*sdata[idxs+k];
+                  wsuml += weight;
+               }
+            }
+            idxd = slist[idxd];
+         }
+      }
+   	if (wsuml > 0)
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = Mh[j]/wsuml - yk[j];
+   	}
+   	else
+   	{
+		   for(j = 0; j < lN; j++)
+   			Mh[j] = 0;
+   	}
+      /*****************************************************/
+		
+		// Calculate its magnitude squared
+		mvAbs = 0;
+		for(j = 0; j < lN; j++)
+			mvAbs += Mh[j]*Mh[j];
+		
+		// Keep shifting window center until the magnitude squared of the
+		// mean shift vector calculated at the window center location is
+		// under a specified threshold (Epsilon)
+		
+		// NOTE: iteration count is for speed up purposes only - it
+		//       does not have any theoretical importance
+		iterationCount = 1;
+		while((mvAbs >= EPSILON)&&(iterationCount < LIMIT))
+		{
+			
+			// Shift window location
+			for(j = 0; j < lN; j++)
+				yk[j] += Mh[j];
+			
+			// Calculate the mean shift vector at the new
+			// window location using lattice
+			// LatticeMSVector(Mh, yk);
+         /*****************************************************/
+         // Initialize mean shift vector
+         for(j = 0; j < lN; j++)
+            Mh[j] = 0;
+         wsuml = 0;
+         // uniformLSearch(Mh, yk_ptr); // modify to new
+         // find bucket of yk
+         cBuck1 = (int) yk[0] + 1;
+         cBuck2 = (int) yk[1] + 1;
+         cBuck3 = (int) (yk[2] - sMins) + 1;
+         cBuck = cBuck1 + nBuck1*(cBuck2 + nBuck2*cBuck3);
+         for (j=0; j<27; j++)
+         {
+            idxd = buckets[cBuck+bucNeigh[j]];
+            // list parse, crt point is cHeadList
+            while (idxd>=0)
+            {
+               idxs = lN*idxd;
+               // determine if inside search window
+               el = sdata[idxs+0]-yk[0];
+               diff = el*el;
+               el = sdata[idxs+1]-yk[1];
+               diff += el*el;
+               
+               if (diff < 1.0)
+               {
+                  el = sdata[idxs+2]-yk[2];
+                  if (yk[2] > hiLTr)
+                     diff = 4*el*el;
+                  else
+                     diff = el*el;
+                  
+                  if (N>1)
+                  {
+                     el = sdata[idxs+3]-yk[3];
+                     diff += el*el;
+                     el = sdata[idxs+4]-yk[4];
+                     diff += el*el;
+                  }
+                  
+                  if (diff < 1.0)
+                  {
+                     weight = 1-weightMap[idxd];
+                     for (k=0; k<lN; k++)
+                        Mh[k] += weight*sdata[idxs+k];
+                     wsuml += weight;
+                  }
+               }
+               idxd = slist[idxd];
+            }
+         }
+         if (wsuml > 0)
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = Mh[j]/wsuml - yk[j];
+         }
+         else
+         {
+            for(j = 0; j < lN; j++)
+               Mh[j] = 0;
+         }
+         /*****************************************************/
+			
+			// Calculate its magnitude squared
+			//mvAbs = 0;
+			//for(j = 0; j < lN; j++)
+			//	mvAbs += Mh[j]*Mh[j];
+         mvAbs = (Mh[0]*Mh[0]+Mh[1]*Mh[1])*sigmaS*sigmaS;
+         if (N==3)
+            mvAbs += (Mh[2]*Mh[2]+Mh[3]*Mh[3]+Mh[4]*Mh[4])*sigmaR*sigmaR;
+         else
+            mvAbs += Mh[2]*Mh[2]*sigmaR*sigmaR;
+
+			// Increment interation count
+			iterationCount++;
+		}
+
+		// Shift window location
+		for(j = 0; j < lN; j++)
+			yk[j] += Mh[j];
+		
+		//store result into msRawData...
+		for(j = 0; j < N; j++)
+			msRawData[N*i+j] = (float)(yk[j+2]*sigmaR);
+
+		// Prompt user on progress
+#ifdef SHOW_PROGRESS
+		percent_complete = (float)(i/(float)(L))*100;
+		msSys.Prompt("\r%2d%%", (int)(percent_complete + 0.5));
+#endif
+	
+		// Check to see if the algorithm has been halted
+		if((i%PROGRESS_RATE == 0)&&((ErrorStatus = msSys.Progress((float)(i/(float)(L))*(float)(0.8)))) == EL_HALT)
+			break;
+	}
+	
+	// Prompt user that filtering is completed
+#ifdef PROMPT
+#ifdef SHOW_PROGRESS
+	msSys.Prompt("\r");
+#endif
+	msSys.Prompt("done.");
+#endif
+	
+	// de-allocate memory
+   delete [] buckets;
+   delete [] slist;
+   delete [] sdata;
+
+	delete [] yk;
+	delete [] Mh;
+
+	// done.
+	return;
+
+}
+
+void msImageProcessor::SetSpeedThreshold(float speedUpThreshold)
+{
+   speedThreshold = speedUpThreshold;
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
diff --git a/Utilities/otbedison/segm/msImageProcessor.h b/Utilities/otbedison/segm/msImageProcessor.h
old mode 100755
new mode 100644
index fe4ae4f91c0aa287bc6e48127d99a766ee061d7d..62095c90fb10059cee35235faddfcf5e255e0e29
--- a/Utilities/otbedison/segm/msImageProcessor.h
+++ b/Utilities/otbedison/segm/msImageProcessor.h
@@ -1,798 +1,798 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Mean Shift Image Processor Class:
-  ================================
-
-	The following class inherits from the mean shift library
-	in order to perform the specialized tasks of image
-	segmentation and filtering.
-	
-	The prototype of the Mean Shift	Image Processor Class
-	is provided below. Its definition is provided in
-	'msImageProcessor.cc'.
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-#ifndef msImageProcessor_H
-#define msImageProcessor_H
-
-//include mean shift library
-#include	"ms.h"
-
-//include prototypes of additional strucuters
-//used for image segmentation...
-
-//include region list used to store boundary pixel
-//indeces for each region
-#include	"rlist.h"
-
-//include region adjacency list class used for
-//region pruning and transitive closure
-#include	"RAList.h"
-
-//define constants
-
-	//image pruning
-#define	TOTAL_ITERATIONS	14
-#define BIG_NUM				0xffffffff	//BIG_NUM = 2^32-1
-#define NODE_MULTIPLE		10
-
-	//data space conversion...
-const double Xn			= 0.95050;
-const double Yn			= 1.00000;
-const double Zn			= 1.08870;
-//const double Un_prime	= 0.19780;
-//const double Vn_prime	= 0.46830;
-const double Un_prime	= 0.19784977571475;
-const double Vn_prime	= 0.46834507665248;
-const double Lt			= 0.008856;
-
-	//RGB to LUV conversion
-const double XYZ[3][3] = {	{  0.4125,  0.3576,  0.1804 },
-							{  0.2125,  0.7154,  0.0721 },
-							{  0.0193,  0.1192,  0.9502 }	};
-
-	//LUV to RGB conversion
-const double RGB[3][3] = {	{  3.2405, -1.5371, -0.4985 },
-							{ -0.9693,  1.8760,  0.0416 },
-							{  0.0556, -0.2040,  1.0573 }	};
-
-//define data types
-typedef unsigned char byte;
-
-//define enumerations
-enum imageType {GRAYSCALE, COLOR};
-
-//define prototype
-class msImageProcessor: public MeanShift {
-
-public:
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /* Class Constructor and Destructor */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  msImageProcessor( void );        //Default Constructor
- ~msImageProcessor( void );        //Class Destructor
-
- /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/
- /* Input Image Declaration  */
- /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				  * Define Image *                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Uploads an image to be segmented by the image    |//
-  //|   segmenter class.                                 |//
-  //|                                                    |//
-  //|   An image is defined by specifying the folloing:  |//
-  //|                                                    |//
-  //|   <* data *>                                       |//
-  //|   A one dimensional unsigned char array of RGB     |//
-  //|   vectors.                                         |//
-  //|                                                    |//
-  //|   <* type *>                                       |//
-  //|   Specifies the image type: COLOR or GREYSCALE.    |//
-  //|                                                    |//
-  //|   <* height *>                                     |//
-  //|   The image height.                                |//
-  //|                                                    |//
-  //|   <* width *>                                      |//
-  //|   The image width.                                 |//
-  //|                                                    |//
-  //|   This method uploads the image and converts its   |//
-  //|   data into the LUV space. If another conversion   |//
-  //|   is desired data may be uploaded into this class  |//
-  //|   via the procedure MeanShift::UploadInput().      |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		DefineImage(data, type, height, width)       |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void DefineImage(byte*,imageType, int, int);
-  void DefineBgImage(byte*, imageType , int , int );
-
-
- /*/\/\/\/\/\/\*/
- /* Weight Map */
- /*\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|			     * Set Weight Map *                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Uploads weight map specifying for each pixel     |//
-  //|   in the image a value between 0 and 1 - 1 indica- |//
-  //|   ting the presence of an edge and 0 the absense   |//
-  //|   of an edge.                                      |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* weightMap *>                                  |//
-  //|   A floating point array of size (height x width)  |//
-  //|   specifying at location (i,j) the edge strength   |//
-  //|   of pixel (i,j). (e.g. pixel (i,j) has an edge    |//
-  //|   strength of weightMap[j*width+i]).               |//
-  //|                                                    |//
-  //|   <* epsilon *>                                    |//
-  //|   A floating point number specifying the threshold |//
-  //|   used to fuse regions during transitive closure.  |//
-  //|                                                    |//
-  //|   Note: DefineImage must be called prior to call-  |//
-  //|         ing this method. DefineImage is used to    |//
-  //|         define the dimensions of the image.        |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		SetWeightMap(weightMap, epsilon)             |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void SetWeightMap(float*, float);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|			   * Remove Weight Map *                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Removes weight map. An error is NOT flagged      |//
-  //|   if a weight map was not defined prior to calling |//
-  //|   this method.                                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		RemoveWeightMap(void)                        |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void RemoveWeightMap(void);
-
- /*/\/\/\/\/\/\/\/\/\*/
- /* Image Filtering  */
- /*\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|                   *  Filter  *                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Apply mean shift filter to the defined image,    |//
-  //|   defined either via MeanShift::DefineLInput or    |//
-  //|   msImageProcessor::DefineImage. The resulting     |//
-  //|   segmented image is stored in the private data    |//
-  //|   members of the image segmenter class which can   |//
-  //|   be obtained by calling image msImageProcessor::  |//
-  //|   GetResults().                                    |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* sigmaS *>                                     |//
-  //|   The spatial radius of the mean shift window.     |//
-  //|                                                    |//
-  //|   <* sigmaR *>                                     |//
-  //|   The range radius of the mean shift window.       |//
-  //|                                                    |//
-  //|   <* speedUpLevel *>                               |//
-  //|   Determines if a speed up optimization should be  |//
-  //|   used to perform image filtering. A value of      |//
-  //|   NO_SPEEDUP turns this optimization off and a     |//
-  //|   value of SPEEDUP turns this optimization on.     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		Filter(sigmaS, sigmaR, speedUpLevel)         |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void Filter(int, float, SpeedUpLevel);
-
- /*/\/\/\/\/\/\/\/\/\/\/\*/
- /* Image Region Fusing  */
- /*\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				  *  Fuse Regions  *                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Fuses the regions of a filtered image,           |//
-  //|   defined either via MeanShift::DefineLInput or    |//
-  //|   msImageProcessor::DefineImage. The resulting     |//
-  //|   segmented image is stored in the private data    |//
-  //|   members of the image segmenter class which can   |//
-  //|   be obtained by calling image msImageProcessor::  |//
-  //|   GetResults().                                    |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* sigmaR *>                                     |//
-  //|   The range radius that defines similar color      |//
-  //|   amongst image regions.                           |//
-  //|                                                    |//
-  //|   <* minRegion *>                                  |//
-  //|   The minimum density a region may have in the     |//
-  //|   resulting segmented image. All regions have      |//
-  //|   point density < minRegion are pruned from the    |//
-  //|   image.                                           |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		FuseRegions(sigmaR, minRegion)               |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void FuseRegions(float, int);
-
- /*/\/\/\/\/\/\/\/\/\/\*/
- /* Image Segmentation */
- /*\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				     *  Segment  *                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Segments the defined image, defined either via   |//
-  //|   MeanShift::DefineLInput or msImageProcessor::De- |//
-  //|   fineImage. The resulting segmented image is      |//
-  //|   stored in the private data members of the image  |//
-  //|   processor class which can be obtained by calling |//
-  //|   ImageSegmenter::GetResults().                    |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* sigmaS *>                                     |//
-  //|   The spatial radius of the mean shift window.     |//
-  //|                                                    |//
-  //|   <* sigmaR *>                                     |//
-  //|   The range radius of the mean shift window.       |//
-  //|                                                    |//
-  //|   <* minRegion *>                                  |//
-  //|   The minimum density a region may have in the     |//
-  //|   resulting segmented image. All regions have      |//
-  //|   point density < minRegion are pruned from the    |//
-  //|   image.                                           |//
-  //|                                                    |//
-  //|   <* speedUpLevel *>                               |//
-  //|   Determines if a speed up optimization should be  |//
-  //|   used to perform image filtering. A value of      |//
-  //|   NO_SPEEDUP turns this optimization off and a     |//
-  //|   value of SPEEDUP turns this optimization on.     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		Segment(sigmaS, sigmaR, minRegion,           |//
-  //|                       speedUpLevel)                |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
- 
-  void Segment(int, float, int, SpeedUpLevel);
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /* Data Space Conversion  */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				 *  RGB To LUV  *                    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Converts an RGB vector to LUV.                   |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* rgbVal *>                                     |//
-  //|   An unsigned char array containing the RGB        |//
-  //|   vector.                                          |//
-  //|                                                    |//
-  //|   <* luvVal *>                                     |//
-  //|   A floating point array containing the LUV        |//
-  //|   vector.                                          |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		RGBtoLUV(rgbVal, luvVal)                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void RGBtoLUV(byte*, float*);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				 *  LUV To RGB  *                    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Converts an LUV vector to RGB.                   |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* luvVal *>                                     |//
-  //|   A floating point array containing the LUV        |//
-  //|   vector.                                          |//
-  //|                                                    |//
-  //|   <* rgbVal *>                                     |//
-  //|   An unsigned char array containing the RGB        |//
-  //|   vector.                                          |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		LUVtoRGB(luvVal, rgbVal)                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void LUVtoRGB(float*, byte*);
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Filtered and Segmented Image Output */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|			      *  Get Raw Data  *                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the resulting filtered or segmented im-  |//
-  //|   age data after calling Filter() or Segment().    |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* outputImageData *>                            |//
-  //|   A floating point array containing the vector     |//
-  //|   data of the filtered or segmented image.         |//
-  //|                                                    |//
-  //|   NOTE: If DefineImage was used to specify the     |//
-  //|         the input to this class, outputImageData   |//
-  //|         is in the LUV data space.                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		GetResults(outputImageData)                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void GetRawData(float*);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				 *  Get Results  *                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the resulting filtered or segmented im-  |//
-  //|   age after calling Filter() or Segment().         |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* outputImage *>                                |//
-  //|   An unsigned char array containing the RGB        |//
-  //|   vector data of the output image.                 |//
-  //|                                                    |//
-  //|   To obtain the un-converted (LUV) data space      |//
-  //|   output one may use                               |//
-  //|   msImageProcessor::GetRawData().                  |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		GetResults(outputImage)                      |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  void GetResults(byte*);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				 *  Get Boundaries  *                |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the boundaries of each region of the     |//
-  //|   segmented image using a region list object,      |//
-  //|   available after filtering or segmenting the      |//
-  //|   defined image.                                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		regionList = GetBoundaries()                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  RegionList *GetBoundaries( void );
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|			        * Get Regions *                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the regions of the processed image.      |//
-  //|   Each region in the image is uniquely character-  |//
-  //|   ized by its location and color (e.g. RGB).       |//
-  //|   GetRegions() therefore returns the following     |//
-  //|   information about the regions of the processed   |//
-  //|   image:                                           |//
-  //|                                                    |//
-  //|   <* regionCount *>                                |//
-  //|   An integer that specifies the number of regions  |//
-  //|   contained in the processed image.                |//
-  //|                                                    |//
-  //|   <* modes *>                                      |//
-  //|   A floating point array of length regionCount*N   |//
-  //|   containing the feature space component of each   |//
-  //|   region (e.g. LUV), and indexed by region label.  |//
-  //|                                                    |//
-  //|   <* labels *>                                     |//
-  //|   An integer array of length (height*width) which  |//
-  //|   contains at every pixel location (x,y) a label   |//
-  //|   relating that pixel to a region whose mode is    |//
-  //|   specified by modes and whose area is specified   |//
-  //|   by modePointCounts.                              |//
-  //|                                                    |//
-  //|   <* modePointCounts *>                            |//
-  //|   An integer array of length regionCount and ind-  |//
-  //|   exed by region label, that specifies the region  |//
-  //|   area (in pixels) for each segmented image reg-   |//
-  //|   ion. (e.g. Area of region having label specif-   |//
-  //|   ified by l, has area modePointCounts[l] (pix-    |//
-  //|   els).)                                           |//
-  //|                                                    |//
-  //|   NOTE: Memory for the above integer and floating  |//
-  //|         point arrays is allocated inside this      |//
-  //|         method.                                    |//
-  //|                                                    |//
-  //|         Also modes stored by the modes array are   |//
-  //|         not in the RGB space. Instead if the       |//
-  //|         method DefineImage was used, these data    |//
-  //|         points are in the LUV space, and if the    |//
-  //|         method DefineLInput was used these data    |//
-  //|         points are in whatever space you specified |//
-  //|         them to be in when calling DefineLInput.   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		regionCount = GetRegions(labels, modes       |//
-  //|                                modePointCounts)    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-  int GetRegions(int**, float**, int**);
-
-
-  void SetSpeedThreshold(float);
-private:
-
-  //========================
-  // *** Private Methods ***
-  //========================
-
-	/*/\/\/\/\/\/\/\/\/\*/
-	/*  Image Filtering */
-	/*\/\/\/\/\/\/\/\/\/*/
-
-	void NonOptimizedFilter(float, float);	// filters the image applying mean shift to each point
-											// Advantage	: most accurate
-											// Disadvantage	: time expensive
-   void NewNonOptimizedFilter(float, float);
-
-	void OptimizedFilter1(float, float);	// filters the image using previous mode information
-											// to avoid re-applying mean shift to some data points
-											// Advantage	: maintains high level of accuracy,
-											//				  large speed up compared to non-optimized
-											//				  version
-											// Disadvantage	: POSSIBLY not as accurate as non-optimized
-											//				  version
-   void NewOptimizedFilter1(float, float);
-
-
-	void OptimizedFilter2(float, float);	//filter the image using previous mode information
-											//and window traversals to avoid re-applying mean shift to
-											//some data points
-											// Advantage	: huge speed up - maintains accuracy good enough
-											//				  for segmentation
-											// Disadvantage	: not as accurate as previous filters
-   void NewOptimizedFilter2(float, float);
-
-	
-	/*/\/\/\/\/\/\/\/\/\/\/\*/
-	/* Image Classification */
-	/*\/\/\/\/\/\/\/\/\/\/\/*/
-
-	void Connect( void );					// classifies mean shift filtered image regions using
-											// private classification structure of this class
-
-	void Fill(int, int);					// used by Connect to perform label each region in the
-											// mean shift filtered image using an eight-connected
-											// fill
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/* Transitive Closure and Image Pruning */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-	void BuildRAM( void );					// build a region adjacency matrix using the region list
-											// object
-
-	void DestroyRAM( void );				// destroy the region adjacency matrix: de-allocate its memory
-											// initialize it for re-use
-
-	void TransitiveClosure( void );			// use the RAM to apply transitive closure to the image modes
-
-	void ComputeEdgeStrengths( void );		// computes the weights of the weighted graph using the weight
-											// map
-
-	//Usage: Prune(minRegion)
-	void Prune(int);						// use the RAM to prune the image of spurious regions (regions
-											// whose area is less than minRegion pixels, where minRegion is
-											// an argument of this method)
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/*  Region Boundary Detection */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-	void DefineBoundaries( void );			// defines the boundaries of each region using the classified segmented
-											// image storing the resulting boundary locations for each region using
-											// a region list object
-
-	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-	/*  Image Data Searching/Distance Calculation */
-	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-	//Usage: InWindow(modeIndex1, modeIndex2)
-	bool InWindow(int, int);				//returns true if the range data of the specified data points
-											//are within the defined search window (defined by kernel
-											//bandwidth h[1])
-
-	float SqDistance(int, int);				// computes the normalized square distance between two modes 
-
-	/*/\/\/\/\/\/\/\/\/\/\*/
-	/* Memory Management  */
-	/*\/\/\/\/\/\/\/\/\/\/*/
-
-	void InitializeOutput( void );			//Allocates memory needed by this class to perform image
-											//filtering and segmentation
-
-	void DestroyOutput( void );				//De-allocates memory needed by this class to perform image
-											//filtering and segmentation
-
-  //=============================
-  // *** Private Data Members ***
-  //=============================
-
-   //##########################################
-   //#######    IMAGE CLASSIFICATION   ########
-   //##########################################
-
-	/////////Image Boundaries/////////
-	RegionList		*regionList;			// stores the boundary locations for each region
-
-	/////////Image Regions////////
-	int				regionCount;			// stores the number of connected regions contained by the
-											// image
-
-	/////////8 Connected Neighbors/////////
-	int				neigh[8];
-
-	/////////Index Table/////////////////
-	int				*indexTable;			//used during fill algorithm
-
-	/////////LUV_data/////////////////
-   //int            *LUV_data;           //stores modes in integer format on lattice
-	float				*LUV_data;				//stores modes in float format on lattice
-   float          LUV_treshold;        //in float mode this determines what "close" means between modes
-
-
-   //##########################################
-   //#######   OUTPUT DATA STORAGE     ########
-   //##########################################
-
-	////////Raw Data (1 to 1 correlation with input)////////
-	float			*msRawData;				// Raw data output of mean shift algorithm
-											// to the location of the data point on the lattice
-
-	////////Data Modes////////
-	int				*labels;				// assigns a label to each data point associating it to
-											// a mode in modes (e.g. a data point having label l has
-											// mode modes[l])
-
-	float			*modes;					// stores the mode data of the input data set, indexed by labels
-
-	int				*modePointCounts;		// stores for each mode the number of point mapped to that mode,
-											// indexed by labels
-
-   //##########################################
-   //#######  REGION ADJACENCY MATRIX  ########
-   //##########################################
-
-	//////////Region Adjacency List/////////
-	RAList			*raList;				// an array of RAList objects containing an entry for each
-											// region of the image
-
-	//////////RAMatrix Free List///////////
-	RAList			*freeRAList;			// a pointer to the head of a region adjacency list object
-											// free list
-
-	RAList			*raPool;				// a pool of RAList objects used in the construction of the
-											// RAM
-
-   //##############################################
-   //#######  COMPUTATION OF EDGE STRENGTHS #######
-   //##############################################
-
-	//////////Epsilon///////////
-	float			epsilon;				//Epsilon used for transitive closure
-
-	//////Visit Table//////
-	unsigned char	*visitTable;			//Table used to keep track of which pixels have been
-											//already visited upon computing the boundary edge strengths
-
-   //##########################################
-   //#######       IMAGE PRUNING       ########
-   //##########################################
-
-	////////Transitive Closure/////////
-	float			rR2;					//defines square range radius used when clustering pixels
-											//together, thus defining image regions
-
-   float speedThreshold; // the % of window radius used in new optimized filter 2.
-};
-
-#endif
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Mean Shift Image Processor Class:
+  ================================
+
+	The following class inherits from the mean shift library
+	in order to perform the specialized tasks of image
+	segmentation and filtering.
+	
+	The prototype of the Mean Shift	Image Processor Class
+	is provided below. Its definition is provided in
+	'msImageProcessor.cc'.
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+#ifndef msImageProcessor_H
+#define msImageProcessor_H
+
+//include mean shift library
+#include	"ms.h"
+
+//include prototypes of additional strucuters
+//used for image segmentation...
+
+//include region list used to store boundary pixel
+//indeces for each region
+#include	"rlist.h"
+
+//include region adjacency list class used for
+//region pruning and transitive closure
+#include	"RAList.h"
+
+//define constants
+
+	//image pruning
+#define	TOTAL_ITERATIONS	14
+#define BIG_NUM				0xffffffff	//BIG_NUM = 2^32-1
+#define NODE_MULTIPLE		10
+
+	//data space conversion...
+const double Xn			= 0.95050;
+const double Yn			= 1.00000;
+const double Zn			= 1.08870;
+//const double Un_prime	= 0.19780;
+//const double Vn_prime	= 0.46830;
+const double Un_prime	= 0.19784977571475;
+const double Vn_prime	= 0.46834507665248;
+const double Lt			= 0.008856;
+
+	//RGB to LUV conversion
+const double XYZ[3][3] = {	{  0.4125,  0.3576,  0.1804 },
+							{  0.2125,  0.7154,  0.0721 },
+							{  0.0193,  0.1192,  0.9502 }	};
+
+	//LUV to RGB conversion
+const double RGB[3][3] = {	{  3.2405, -1.5371, -0.4985 },
+							{ -0.9693,  1.8760,  0.0416 },
+							{  0.0556, -0.2040,  1.0573 }	};
+
+//define data types
+typedef unsigned char byte;
+
+//define enumerations
+enum imageType {GRAYSCALE, COLOR};
+
+//define prototype
+class msImageProcessor: public MeanShift {
+
+public:
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /* Class Constructor and Destructor */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  msImageProcessor( void );        //Default Constructor
+ ~msImageProcessor( void );        //Class Destructor
+
+ /*/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+ /* Input Image Declaration  */
+ /*\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				  * Define Image *                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Uploads an image to be segmented by the image    |//
+  //|   segmenter class.                                 |//
+  //|                                                    |//
+  //|   An image is defined by specifying the folloing:  |//
+  //|                                                    |//
+  //|   <* data *>                                       |//
+  //|   A one dimensional unsigned char array of RGB     |//
+  //|   vectors.                                         |//
+  //|                                                    |//
+  //|   <* type *>                                       |//
+  //|   Specifies the image type: COLOR or GREYSCALE.    |//
+  //|                                                    |//
+  //|   <* height *>                                     |//
+  //|   The image height.                                |//
+  //|                                                    |//
+  //|   <* width *>                                      |//
+  //|   The image width.                                 |//
+  //|                                                    |//
+  //|   This method uploads the image and converts its   |//
+  //|   data into the LUV space. If another conversion   |//
+  //|   is desired data may be uploaded into this class  |//
+  //|   via the procedure MeanShift::UploadInput().      |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		DefineImage(data, type, height, width)       |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void DefineImage(byte*,imageType, int, int);
+  void DefineBgImage(byte*, imageType , int , int );
+
+
+ /*/\/\/\/\/\/\*/
+ /* Weight Map */
+ /*\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|			     * Set Weight Map *                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Uploads weight map specifying for each pixel     |//
+  //|   in the image a value between 0 and 1 - 1 indica- |//
+  //|   ting the presence of an edge and 0 the absense   |//
+  //|   of an edge.                                      |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* weightMap *>                                  |//
+  //|   A floating point array of size (height x width)  |//
+  //|   specifying at location (i,j) the edge strength   |//
+  //|   of pixel (i,j). (e.g. pixel (i,j) has an edge    |//
+  //|   strength of weightMap[j*width+i]).               |//
+  //|                                                    |//
+  //|   <* epsilon *>                                    |//
+  //|   A floating point number specifying the threshold |//
+  //|   used to fuse regions during transitive closure.  |//
+  //|                                                    |//
+  //|   Note: DefineImage must be called prior to call-  |//
+  //|         ing this method. DefineImage is used to    |//
+  //|         define the dimensions of the image.        |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		SetWeightMap(weightMap, epsilon)             |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void SetWeightMap(float*, float);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|			   * Remove Weight Map *                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Removes weight map. An error is NOT flagged      |//
+  //|   if a weight map was not defined prior to calling |//
+  //|   this method.                                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		RemoveWeightMap(void)                        |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void RemoveWeightMap(void);
+
+ /*/\/\/\/\/\/\/\/\/\*/
+ /* Image Filtering  */
+ /*\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|                   *  Filter  *                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Apply mean shift filter to the defined image,    |//
+  //|   defined either via MeanShift::DefineLInput or    |//
+  //|   msImageProcessor::DefineImage. The resulting     |//
+  //|   segmented image is stored in the private data    |//
+  //|   members of the image segmenter class which can   |//
+  //|   be obtained by calling image msImageProcessor::  |//
+  //|   GetResults().                                    |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* sigmaS *>                                     |//
+  //|   The spatial radius of the mean shift window.     |//
+  //|                                                    |//
+  //|   <* sigmaR *>                                     |//
+  //|   The range radius of the mean shift window.       |//
+  //|                                                    |//
+  //|   <* speedUpLevel *>                               |//
+  //|   Determines if a speed up optimization should be  |//
+  //|   used to perform image filtering. A value of      |//
+  //|   NO_SPEEDUP turns this optimization off and a     |//
+  //|   value of SPEEDUP turns this optimization on.     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		Filter(sigmaS, sigmaR, speedUpLevel)         |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void Filter(int, float, SpeedUpLevel);
+
+ /*/\/\/\/\/\/\/\/\/\/\/\*/
+ /* Image Region Fusing  */
+ /*\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				  *  Fuse Regions  *                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Fuses the regions of a filtered image,           |//
+  //|   defined either via MeanShift::DefineLInput or    |//
+  //|   msImageProcessor::DefineImage. The resulting     |//
+  //|   segmented image is stored in the private data    |//
+  //|   members of the image segmenter class which can   |//
+  //|   be obtained by calling image msImageProcessor::  |//
+  //|   GetResults().                                    |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* sigmaR *>                                     |//
+  //|   The range radius that defines similar color      |//
+  //|   amongst image regions.                           |//
+  //|                                                    |//
+  //|   <* minRegion *>                                  |//
+  //|   The minimum density a region may have in the     |//
+  //|   resulting segmented image. All regions have      |//
+  //|   point density < minRegion are pruned from the    |//
+  //|   image.                                           |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		FuseRegions(sigmaR, minRegion)               |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void FuseRegions(float, int);
+
+ /*/\/\/\/\/\/\/\/\/\/\*/
+ /* Image Segmentation */
+ /*\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				     *  Segment  *                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Segments the defined image, defined either via   |//
+  //|   MeanShift::DefineLInput or msImageProcessor::De- |//
+  //|   fineImage. The resulting segmented image is      |//
+  //|   stored in the private data members of the image  |//
+  //|   processor class which can be obtained by calling |//
+  //|   ImageSegmenter::GetResults().                    |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* sigmaS *>                                     |//
+  //|   The spatial radius of the mean shift window.     |//
+  //|                                                    |//
+  //|   <* sigmaR *>                                     |//
+  //|   The range radius of the mean shift window.       |//
+  //|                                                    |//
+  //|   <* minRegion *>                                  |//
+  //|   The minimum density a region may have in the     |//
+  //|   resulting segmented image. All regions have      |//
+  //|   point density < minRegion are pruned from the    |//
+  //|   image.                                           |//
+  //|                                                    |//
+  //|   <* speedUpLevel *>                               |//
+  //|   Determines if a speed up optimization should be  |//
+  //|   used to perform image filtering. A value of      |//
+  //|   NO_SPEEDUP turns this optimization off and a     |//
+  //|   value of SPEEDUP turns this optimization on.     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		Segment(sigmaS, sigmaR, minRegion,           |//
+  //|                       speedUpLevel)                |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+ 
+  void Segment(int, float, int, SpeedUpLevel);
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /* Data Space Conversion  */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				 *  RGB To LUV  *                    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Converts an RGB vector to LUV.                   |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* rgbVal *>                                     |//
+  //|   An unsigned char array containing the RGB        |//
+  //|   vector.                                          |//
+  //|                                                    |//
+  //|   <* luvVal *>                                     |//
+  //|   A floating point array containing the LUV        |//
+  //|   vector.                                          |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		RGBtoLUV(rgbVal, luvVal)                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void RGBtoLUV(byte*, float*);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				 *  LUV To RGB  *                    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Converts an LUV vector to RGB.                   |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* luvVal *>                                     |//
+  //|   A floating point array containing the LUV        |//
+  //|   vector.                                          |//
+  //|                                                    |//
+  //|   <* rgbVal *>                                     |//
+  //|   An unsigned char array containing the RGB        |//
+  //|   vector.                                          |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		LUVtoRGB(luvVal, rgbVal)                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void LUVtoRGB(float*, byte*);
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Filtered and Segmented Image Output */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|			      *  Get Raw Data  *                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the resulting filtered or segmented im-  |//
+  //|   age data after calling Filter() or Segment().    |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* outputImageData *>                            |//
+  //|   A floating point array containing the vector     |//
+  //|   data of the filtered or segmented image.         |//
+  //|                                                    |//
+  //|   NOTE: If DefineImage was used to specify the     |//
+  //|         the input to this class, outputImageData   |//
+  //|         is in the LUV data space.                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		GetResults(outputImageData)                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void GetRawData(float*);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				 *  Get Results  *                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the resulting filtered or segmented im-  |//
+  //|   age after calling Filter() or Segment().         |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* outputImage *>                                |//
+  //|   An unsigned char array containing the RGB        |//
+  //|   vector data of the output image.                 |//
+  //|                                                    |//
+  //|   To obtain the un-converted (LUV) data space      |//
+  //|   output one may use                               |//
+  //|   msImageProcessor::GetRawData().                  |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		GetResults(outputImage)                      |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  void GetResults(byte*);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				 *  Get Boundaries  *                |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the boundaries of each region of the     |//
+  //|   segmented image using a region list object,      |//
+  //|   available after filtering or segmenting the      |//
+  //|   defined image.                                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		regionList = GetBoundaries()                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  RegionList *GetBoundaries( void );
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|			        * Get Regions *                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the regions of the processed image.      |//
+  //|   Each region in the image is uniquely character-  |//
+  //|   ized by its location and color (e.g. RGB).       |//
+  //|   GetRegions() therefore returns the following     |//
+  //|   information about the regions of the processed   |//
+  //|   image:                                           |//
+  //|                                                    |//
+  //|   <* regionCount *>                                |//
+  //|   An integer that specifies the number of regions  |//
+  //|   contained in the processed image.                |//
+  //|                                                    |//
+  //|   <* modes *>                                      |//
+  //|   A floating point array of length regionCount*N   |//
+  //|   containing the feature space component of each   |//
+  //|   region (e.g. LUV), and indexed by region label.  |//
+  //|                                                    |//
+  //|   <* labels *>                                     |//
+  //|   An integer array of length (height*width) which  |//
+  //|   contains at every pixel location (x,y) a label   |//
+  //|   relating that pixel to a region whose mode is    |//
+  //|   specified by modes and whose area is specified   |//
+  //|   by modePointCounts.                              |//
+  //|                                                    |//
+  //|   <* modePointCounts *>                            |//
+  //|   An integer array of length regionCount and ind-  |//
+  //|   exed by region label, that specifies the region  |//
+  //|   area (in pixels) for each segmented image reg-   |//
+  //|   ion. (e.g. Area of region having label specif-   |//
+  //|   ified by l, has area modePointCounts[l] (pix-    |//
+  //|   els).)                                           |//
+  //|                                                    |//
+  //|   NOTE: Memory for the above integer and floating  |//
+  //|         point arrays is allocated inside this      |//
+  //|         method.                                    |//
+  //|                                                    |//
+  //|         Also modes stored by the modes array are   |//
+  //|         not in the RGB space. Instead if the       |//
+  //|         method DefineImage was used, these data    |//
+  //|         points are in the LUV space, and if the    |//
+  //|         method DefineLInput was used these data    |//
+  //|         points are in whatever space you specified |//
+  //|         them to be in when calling DefineLInput.   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		regionCount = GetRegions(labels, modes       |//
+  //|                                modePointCounts)    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+  int GetRegions(int**, float**, int**);
+
+
+  void SetSpeedThreshold(float);
+private:
+
+  //========================
+  // *** Private Methods ***
+  //========================
+
+	/*/\/\/\/\/\/\/\/\/\*/
+	/*  Image Filtering */
+	/*\/\/\/\/\/\/\/\/\/*/
+
+	void NonOptimizedFilter(float, float);	// filters the image applying mean shift to each point
+											// Advantage	: most accurate
+											// Disadvantage	: time expensive
+   void NewNonOptimizedFilter(float, float);
+
+	void OptimizedFilter1(float, float);	// filters the image using previous mode information
+											// to avoid re-applying mean shift to some data points
+											// Advantage	: maintains high level of accuracy,
+											//				  large speed up compared to non-optimized
+											//				  version
+											// Disadvantage	: POSSIBLY not as accurate as non-optimized
+											//				  version
+   void NewOptimizedFilter1(float, float);
+
+
+	void OptimizedFilter2(float, float);	//filter the image using previous mode information
+											//and window traversals to avoid re-applying mean shift to
+											//some data points
+											// Advantage	: huge speed up - maintains accuracy good enough
+											//				  for segmentation
+											// Disadvantage	: not as accurate as previous filters
+   void NewOptimizedFilter2(float, float);
+
+	
+	/*/\/\/\/\/\/\/\/\/\/\/\*/
+	/* Image Classification */
+	/*\/\/\/\/\/\/\/\/\/\/\/*/
+
+	void Connect( void );					// classifies mean shift filtered image regions using
+											// private classification structure of this class
+
+	void Fill(int, int);					// used by Connect to perform label each region in the
+											// mean shift filtered image using an eight-connected
+											// fill
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/* Transitive Closure and Image Pruning */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+	void BuildRAM( void );					// build a region adjacency matrix using the region list
+											// object
+
+	void DestroyRAM( void );				// destroy the region adjacency matrix: de-allocate its memory
+											// initialize it for re-use
+
+	void TransitiveClosure( void );			// use the RAM to apply transitive closure to the image modes
+
+	void ComputeEdgeStrengths( void );		// computes the weights of the weighted graph using the weight
+											// map
+
+	//Usage: Prune(minRegion)
+	void Prune(int);						// use the RAM to prune the image of spurious regions (regions
+											// whose area is less than minRegion pixels, where minRegion is
+											// an argument of this method)
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/*  Region Boundary Detection */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+	void DefineBoundaries( void );			// defines the boundaries of each region using the classified segmented
+											// image storing the resulting boundary locations for each region using
+											// a region list object
+
+	/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+	/*  Image Data Searching/Distance Calculation */
+	/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+	//Usage: InWindow(modeIndex1, modeIndex2)
+	bool InWindow(int, int);				//returns true if the range data of the specified data points
+											//are within the defined search window (defined by kernel
+											//bandwidth h[1])
+
+	float SqDistance(int, int);				// computes the normalized square distance between two modes 
+
+	/*/\/\/\/\/\/\/\/\/\/\*/
+	/* Memory Management  */
+	/*\/\/\/\/\/\/\/\/\/\/*/
+
+	void InitializeOutput( void );			//Allocates memory needed by this class to perform image
+											//filtering and segmentation
+
+	void DestroyOutput( void );				//De-allocates memory needed by this class to perform image
+											//filtering and segmentation
+
+  //=============================
+  // *** Private Data Members ***
+  //=============================
+
+   //##########################################
+   //#######    IMAGE CLASSIFICATION   ########
+   //##########################################
+
+	/////////Image Boundaries/////////
+	RegionList		*regionList;			// stores the boundary locations for each region
+
+	/////////Image Regions////////
+	int				regionCount;			// stores the number of connected regions contained by the
+											// image
+
+	/////////8 Connected Neighbors/////////
+	int				neigh[8];
+
+	/////////Index Table/////////////////
+	int				*indexTable;			//used during fill algorithm
+
+	/////////LUV_data/////////////////
+   //int            *LUV_data;           //stores modes in integer format on lattice
+	float				*LUV_data;				//stores modes in float format on lattice
+   float          LUV_treshold;        //in float mode this determines what "close" means between modes
+
+
+   //##########################################
+   //#######   OUTPUT DATA STORAGE     ########
+   //##########################################
+
+	////////Raw Data (1 to 1 correlation with input)////////
+	float			*msRawData;				// Raw data output of mean shift algorithm
+											// to the location of the data point on the lattice
+
+	////////Data Modes////////
+	int				*labels;				// assigns a label to each data point associating it to
+											// a mode in modes (e.g. a data point having label l has
+											// mode modes[l])
+
+	float			*modes;					// stores the mode data of the input data set, indexed by labels
+
+	int				*modePointCounts;		// stores for each mode the number of point mapped to that mode,
+											// indexed by labels
+
+   //##########################################
+   //#######  REGION ADJACENCY MATRIX  ########
+   //##########################################
+
+	//////////Region Adjacency List/////////
+	RAList			*raList;				// an array of RAList objects containing an entry for each
+											// region of the image
+
+	//////////RAMatrix Free List///////////
+	RAList			*freeRAList;			// a pointer to the head of a region adjacency list object
+											// free list
+
+	RAList			*raPool;				// a pool of RAList objects used in the construction of the
+											// RAM
+
+   //##############################################
+   //#######  COMPUTATION OF EDGE STRENGTHS #######
+   //##############################################
+
+	//////////Epsilon///////////
+	float			epsilon;				//Epsilon used for transitive closure
+
+	//////Visit Table//////
+	unsigned char	*visitTable;			//Table used to keep track of which pixels have been
+											//already visited upon computing the boundary edge strengths
+
+   //##########################################
+   //#######       IMAGE PRUNING       ########
+   //##########################################
+
+	////////Transitive Closure/////////
+	float			rR2;					//defines square range radius used when clustering pixels
+											//together, thus defining image regions
+
+   float speedThreshold; // the % of window radius used in new optimized filter 2.
+};
+
+#endif
diff --git a/Utilities/otbedison/segm/msSys.cpp b/Utilities/otbedison/segm/msSys.cpp
old mode 100755
new mode 100644
index ea2b3fc5afa267f390a0d35dddb75a30a42a6799..4523170e75fb38b8fa21470e3c2ce8d3e0823403
--- a/Utilities/otbedison/segm/msSys.cpp
+++ b/Utilities/otbedison/segm/msSys.cpp
@@ -1,234 +1,234 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Mean Shift System:
-  ==================
-
-	The Mean Shift System class provides a mechanism for the
-	mean shift library classes to prompt progress and to
-	time its computations. When porting the mean shift library
-	to an application the methods of this class may be changed
-	such that the output of the mean shift class prompts
-	will be given to whatever hardware or software device that
-	is desired.
-
-	The definition for the mean shift system class is provided
-	below. Its prototype is provided in "msSys.cc".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-//include the msSystem class prototype
-#include	"msSys.h"
-
-//include needed system libraries
-#include	<time.h>
-#include	<stdio.h>
-#include	<stdarg.h>
-#include	<stdlib.h>
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*** Class Constructor and Destructor ***/
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Class Constructor                                    */
-/*******************************************************/
-/*Constructs a mean shift system object.               */
-/*******************************************************/
-/*Post:                                                */
-/*      - an msSystem object has been properly init-   */
-/*        ialized.                                     */
-/*******************************************************/
-
-msSystem::msSystem( void )
-{
-
-	//initialize currentTime
-	currentTime = clock();
-
-	//done.
-
-}
-
-/*******************************************************/
-/*Class Destructor                                     */
-/*******************************************************/
-/*Destroys a mean shift system object.                 */
-/*******************************************************/
-/*Post:                                                */
-/*      - an msSystem object has been properly dest-   */
-/*        royed.                                       */
-/*******************************************************/
-
-msSystem::~msSystem( void )
-{
-	/* do nothing */
-}
-
- /*/\/\/\/\/\/\/\/\/\*/
- /*** System Timer ***/
- /*\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Start Timer                                          */
-/*******************************************************/
-/*Sets the mean shift system time to the current       */
-/*system time.                                         */
-/*******************************************************/
-/*Post:                                                */
-/*      - the mean shift system time has been set to   */
-/*        the current system time.                     */
-/*******************************************************/
-
-void msSystem::StartTimer( void )
-{
-
-	//set msSystem time to system time
-	currentTime = clock();
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Elapsed Time                                         */
-/*******************************************************/
-/*Returns the amount of time in seconds since the      */
-/*mean shift system time was last set.                 */
-/*******************************************************/
-/*Post:                                                */
-/*      - the amount of time in seconds since the mean */
-/*        shift system time was last set is returned.  */
-/*******************************************************/
-
-double msSystem::ElapsedTime( void )
-{
-
-	//return the amount of time elapsed in seconds
-	//since the msSystem time was last set...
-	return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC);
-
-}
-
- /*/\/\/\/\/\/\/\/\/\/\*/
- /***  System Output ***/
- /*\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Prompt                                               */
-/*******************************************************/
-/*Output a text message to the user.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - PromptStr is a string containing delimeters  */
-/*        that is to be output to the user.            */
-/*      - a variable set of arguments is also passed   */
-/*        to this method that are used to replace      */
-/*        the delimeters contained by PromptStr        */
-/*Post:                                                */
-/*      - the delimeters of PromptStr have been        */
-/*        replaced accordingly using the variable      */
-/*        set of arguments and the resulting string    */
-/*        has been output to the user.                 */
-/*******************************************************/
-
-extern void bgLogVar(const char *, va_list);
-
-void msSystem::Prompt(const char *PromptStr, ...)
-{
-
-	//obtain argument list using ANSI standard...
-	va_list	argList;
-	va_start(argList, PromptStr);
-
-	//print the output string to stderr using
-	//vfprintf
-	bgLogVar(PromptStr, argList);
-	va_end(argList);
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Progress                                             */
-/*******************************************************/
-/*The progress of a specific algorithm of the mean     */
-/*shift library is output to the user.                 */
-/*******************************************************/
-/*Pre:                                                 */
-/*		- percentComplete indicates the percentage     */
-/*		  of the algorithm that has executed and is    */
-/*		  a floating point number from zero to one     */
-/*Post:                                                */
-/*      - the percentComplete has been noted by the    */
-/*        interface (possibly to update a progress     */
-/*        bar).                                        */
-/*      - if the thread executing the mean shift code  */
-/*        must halt execution msSYS_HALT is returned,  */
-/*        msSYS_OK is returned otherwise               */
-/*******************************************************/
-
-///////////////////////////////////////////////////////////////////
-//NOTE: This implementation is specific to EDISON. In order
-//      for one to port the mean shift class to another project
-//      or program one must re-implement this method.
-///////////////////////////////////////////////////////////////////
-
-//is set by the GUI when the user presses the Cancel button
-//on the wxWindows progress modal window; this flag indicates
-//to the mean shift library that it is to halt execution.
-//This parameter is used and checked in the method
-//BgMdiSegmentChild::OnSegment.
-extern bool stop_flag;
-
-//is updated in the msSystem::Progress method and indicates to
-//the wxWindows progress modal window the percent complete, such
-//that it may update its progress bar accordingly; This parameter
-//is used and checked in the method BgMdiSegmentChild::OnSegment.
-extern int	percentDone;
-
-ErrorLevel msSystem::Progress(float percentComplete)
-{
-	percentDone	= (int)(percentComplete*100);
-
-	//check stop flag and return appropriate system state
-	ErrorLevel		myState = EL_OKAY;
-	if(stop_flag)	myState	= EL_HALT;
-
-	//done.
-	return myState;
-
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Mean Shift System:
+  ==================
+
+	The Mean Shift System class provides a mechanism for the
+	mean shift library classes to prompt progress and to
+	time its computations. When porting the mean shift library
+	to an application the methods of this class may be changed
+	such that the output of the mean shift class prompts
+	will be given to whatever hardware or software device that
+	is desired.
+
+	The definition for the mean shift system class is provided
+	below. Its prototype is provided in "msSys.cc".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+//include the msSystem class prototype
+#include	"msSys.h"
+
+//include needed system libraries
+#include	<time.h>
+#include	<stdio.h>
+#include	<stdarg.h>
+#include	<stdlib.h>
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*** Class Constructor and Destructor ***/
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Class Constructor                                    */
+/*******************************************************/
+/*Constructs a mean shift system object.               */
+/*******************************************************/
+/*Post:                                                */
+/*      - an msSystem object has been properly init-   */
+/*        ialized.                                     */
+/*******************************************************/
+
+msSystem::msSystem( void )
+{
+
+	//initialize currentTime
+	currentTime = clock();
+
+	//done.
+
+}
+
+/*******************************************************/
+/*Class Destructor                                     */
+/*******************************************************/
+/*Destroys a mean shift system object.                 */
+/*******************************************************/
+/*Post:                                                */
+/*      - an msSystem object has been properly dest-   */
+/*        royed.                                       */
+/*******************************************************/
+
+msSystem::~msSystem( void )
+{
+	/* do nothing */
+}
+
+ /*/\/\/\/\/\/\/\/\/\*/
+ /*** System Timer ***/
+ /*\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Start Timer                                          */
+/*******************************************************/
+/*Sets the mean shift system time to the current       */
+/*system time.                                         */
+/*******************************************************/
+/*Post:                                                */
+/*      - the mean shift system time has been set to   */
+/*        the current system time.                     */
+/*******************************************************/
+
+void msSystem::StartTimer( void )
+{
+
+	//set msSystem time to system time
+	currentTime = clock();
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Elapsed Time                                         */
+/*******************************************************/
+/*Returns the amount of time in seconds since the      */
+/*mean shift system time was last set.                 */
+/*******************************************************/
+/*Post:                                                */
+/*      - the amount of time in seconds since the mean */
+/*        shift system time was last set is returned.  */
+/*******************************************************/
+
+double msSystem::ElapsedTime( void )
+{
+
+	//return the amount of time elapsed in seconds
+	//since the msSystem time was last set...
+	return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC);
+
+}
+
+ /*/\/\/\/\/\/\/\/\/\/\*/
+ /***  System Output ***/
+ /*\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Prompt                                               */
+/*******************************************************/
+/*Output a text message to the user.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - PromptStr is a string containing delimeters  */
+/*        that is to be output to the user.            */
+/*      - a variable set of arguments is also passed   */
+/*        to this method that are used to replace      */
+/*        the delimeters contained by PromptStr        */
+/*Post:                                                */
+/*      - the delimeters of PromptStr have been        */
+/*        replaced accordingly using the variable      */
+/*        set of arguments and the resulting string    */
+/*        has been output to the user.                 */
+/*******************************************************/
+
+extern void bgLogVar(const char *, va_list);
+
+void msSystem::Prompt(const char *PromptStr, ...)
+{
+
+	//obtain argument list using ANSI standard...
+	va_list	argList;
+	va_start(argList, PromptStr);
+
+	//print the output string to stderr using
+	//vfprintf
+	bgLogVar(PromptStr, argList);
+	va_end(argList);
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Progress                                             */
+/*******************************************************/
+/*The progress of a specific algorithm of the mean     */
+/*shift library is output to the user.                 */
+/*******************************************************/
+/*Pre:                                                 */
+/*		- percentComplete indicates the percentage     */
+/*		  of the algorithm that has executed and is    */
+/*		  a floating point number from zero to one     */
+/*Post:                                                */
+/*      - the percentComplete has been noted by the    */
+/*        interface (possibly to update a progress     */
+/*        bar).                                        */
+/*      - if the thread executing the mean shift code  */
+/*        must halt execution msSYS_HALT is returned,  */
+/*        msSYS_OK is returned otherwise               */
+/*******************************************************/
+
+///////////////////////////////////////////////////////////////////
+//NOTE: This implementation is specific to EDISON. In order
+//      for one to port the mean shift class to another project
+//      or program one must re-implement this method.
+///////////////////////////////////////////////////////////////////
+
+//is set by the GUI when the user presses the Cancel button
+//on the wxWindows progress modal window; this flag indicates
+//to the mean shift library that it is to halt execution.
+//This parameter is used and checked in the method
+//BgMdiSegmentChild::OnSegment.
+extern bool stop_flag;
+
+//is updated in the msSystem::Progress method and indicates to
+//the wxWindows progress modal window the percent complete, such
+//that it may update its progress bar accordingly; This parameter
+//is used and checked in the method BgMdiSegmentChild::OnSegment.
+extern int	percentDone;
+
+ErrorLevel msSystem::Progress(float percentComplete)
+{
+	percentDone	= (int)(percentComplete*100);
+
+	//check stop flag and return appropriate system state
+	ErrorLevel		myState = EL_OKAY;
+	if(stop_flag)	myState	= EL_HALT;
+
+	//done.
+	return myState;
+
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
diff --git a/Utilities/otbedison/segm/msSys.h b/Utilities/otbedison/segm/msSys.h
old mode 100755
new mode 100644
index 9bd968d6c16229f3d5942860f69ed3d400c11b31..d7411b0941661bcc318a9bc5516facf7483e5a0b
--- a/Utilities/otbedison/segm/msSys.h
+++ b/Utilities/otbedison/segm/msSys.h
@@ -1,229 +1,229 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Mean Shift System:
-  ==================
-
-	The Mean Shift System class provides a mechanism for the
-	mean shift library classes to prompt progress and to
-	time its computations. When porting the mean shift library
-	to an application the methods of this class may be changed
-	such that the output of the mean shift class prompts
-	will be given to whatever hardware or software device that
-	is desired.
-
-	The prototype for the mean shift system class is provided
-	below. Its defition is provided in "msSys.cc".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-
-#ifndef MSSYS_H
-#define MSSYS_H
-
-//Include standard mean shift library type definitions
-#include	"tdef.h"
-
-//Include standard libraries needed for msSystem prototype
-#include	<time.h>
-
-extern void bgLogFile(const char*, ...);
-
-//Mean Shify System class prototype
-class msSystem {
-
- public:
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /* Class Constructor and Destructor */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  msSystem( void ); //Default Constructor
- ~msSystem( void ); //Class Destructor
-
- /*/\/\/\/\/\/\/\*/
- /* System Timer */
- /*\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				  *  Start Timer  *                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Initializes the system timer. The timer object   |//
-  //|   synthesized by this class is initialized during  |//
-  //|   construction of the msSystem class to be the     |//
-  //|   current time during construction.                |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
- void StartTimer( void );
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				 *  Elapsed Time  *                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the amount of time elapsed in seconds    |//
-  //|   from when StartTimer() was called. If            |//
-  //|   StartTimer() was not called, the time returned   |//
-  //|   is the time elapsed from the construction of the |//
-  //|   msSystem object.                                 |//
-  //|                                                    |//
-  //|   In order to create a valid kernel the following  |//
-  //|   argumens must be provided this method:           |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		TimeInSeconds = ElapsedTime()                |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
- double	ElapsedTime( void );
-
- /*/\/\/\/\/\/\/\/\*/
- /*  System Output */
- /*\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				     *  Prompt  *                    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Outputs to a device a character message contain- |//
-  //|   ing delimeters. These delimeters are replaced by |//
-  //|   the variable input parameters passed to prompt.  |//
-  //|   (Like printf.)                                   |//
-  //|                                                    |//
-  //|   This method should be altered if a special       |//
-  //|   device either than stderr is desired to be used  |//
-  //|   as an output prompt.                             |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* PromptStr *>                                  |//
-  //|   A string possibly containing delimeters that     |//
-  //|   is to be output to the user.                     |//
-  //|                                                    |//
-  //|   <* varArgs *>                                    |//
-  //|   A variable set of arguments to be placed into    |//
-  //|   the prompt string.                               |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|		Prompt(PromptStr, varArgs)                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
- void	Prompt(const char*, ...);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|				   *  Progress  *                    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   This method is called by the mean shift library  |//
-  //|   methods during the application of a specific     |//
-  //|   algorithm in which the progress of the algorithm |//
-  //|   is indicated. Its main use is for a multi-thre-  |//
-  //|   aded programming envioronment. Namely, it is     |//
-  //|   called fairly frequently by the mean shift       |//
-  //|   library methods. It then can be used to grace-   |//
-  //|   fully halt the algorithm, or to simply update    |//
-  //|   a progress bar.                                  |//
-  //|                                                    |//
-  //|   This method depends strongly on the interface    |//
-  //|   and therefore must be re-implemented to accom-   |//
-  //|   odate ones needs.                                |//
-  //|                                                    |//
-  //|   To facilitate a multi-threaded enviornment       |//
-  //|   the prompt function returns a value that         |//
-  //|   indicates to the mean shift method whether       |//
-  //|   to continue execution. EL_HALT is returned       |//
-  //|   when the mean shift procedure is to stop         |//
-  //|   execution and EL_OKAY is returned otherwise.     |//
-  //|                                                    |//
-  //|   The arguments to this method are:                |//
-  //|                                                    |//
-  //|   <* PercentComplete *>                            |//
-  //|   A floating point number that indicates the perc- |//
-  //|   ent complete of the algorithm. PercentComplete   |//
-  //|   takes a value between zero and one.              |//
-  //|                                                    |//
-  //|   <* SystemState *>                                |//
-  //|   Indicates the system state. It is EL_HALT        |//
-  //|   when the mean shift method is to halt execution  |//
-  //|   and it is EL_OKAY otherwise.                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|	 SystemState = Progress(PercentComplete)         |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
- ErrorLevel Progress(float);
-
- private:
-
-	 //Timer object...
-	 time_t currentTime;
-
-};
-
-#endif
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Mean Shift System:
+  ==================
+
+	The Mean Shift System class provides a mechanism for the
+	mean shift library classes to prompt progress and to
+	time its computations. When porting the mean shift library
+	to an application the methods of this class may be changed
+	such that the output of the mean shift class prompts
+	will be given to whatever hardware or software device that
+	is desired.
+
+	The prototype for the mean shift system class is provided
+	below. Its defition is provided in "msSys.cc".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+
+#ifndef MSSYS_H
+#define MSSYS_H
+
+//Include standard mean shift library type definitions
+#include	"tdef.h"
+
+//Include standard libraries needed for msSystem prototype
+#include	<time.h>
+
+extern void bgLogFile(const char*, ...);
+
+//Mean Shify System class prototype
+class msSystem {
+
+ public:
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /* Class Constructor and Destructor */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  msSystem( void ); //Default Constructor
+ ~msSystem( void ); //Class Destructor
+
+ /*/\/\/\/\/\/\/\*/
+ /* System Timer */
+ /*\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				  *  Start Timer  *                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Initializes the system timer. The timer object   |//
+  //|   synthesized by this class is initialized during  |//
+  //|   construction of the msSystem class to be the     |//
+  //|   current time during construction.                |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+ void StartTimer( void );
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				 *  Elapsed Time  *                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the amount of time elapsed in seconds    |//
+  //|   from when StartTimer() was called. If            |//
+  //|   StartTimer() was not called, the time returned   |//
+  //|   is the time elapsed from the construction of the |//
+  //|   msSystem object.                                 |//
+  //|                                                    |//
+  //|   In order to create a valid kernel the following  |//
+  //|   argumens must be provided this method:           |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		TimeInSeconds = ElapsedTime()                |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+ double	ElapsedTime( void );
+
+ /*/\/\/\/\/\/\/\/\*/
+ /*  System Output */
+ /*\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				     *  Prompt  *                    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Outputs to a device a character message contain- |//
+  //|   ing delimeters. These delimeters are replaced by |//
+  //|   the variable input parameters passed to prompt.  |//
+  //|   (Like printf.)                                   |//
+  //|                                                    |//
+  //|   This method should be altered if a special       |//
+  //|   device either than stderr is desired to be used  |//
+  //|   as an output prompt.                             |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* PromptStr *>                                  |//
+  //|   A string possibly containing delimeters that     |//
+  //|   is to be output to the user.                     |//
+  //|                                                    |//
+  //|   <* varArgs *>                                    |//
+  //|   A variable set of arguments to be placed into    |//
+  //|   the prompt string.                               |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|		Prompt(PromptStr, varArgs)                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+ void	Prompt(const char*, ...);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|				   *  Progress  *                    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   This method is called by the mean shift library  |//
+  //|   methods during the application of a specific     |//
+  //|   algorithm in which the progress of the algorithm |//
+  //|   is indicated. Its main use is for a multi-thre-  |//
+  //|   aded programming envioronment. Namely, it is     |//
+  //|   called fairly frequently by the mean shift       |//
+  //|   library methods. It then can be used to grace-   |//
+  //|   fully halt the algorithm, or to simply update    |//
+  //|   a progress bar.                                  |//
+  //|                                                    |//
+  //|   This method depends strongly on the interface    |//
+  //|   and therefore must be re-implemented to accom-   |//
+  //|   odate ones needs.                                |//
+  //|                                                    |//
+  //|   To facilitate a multi-threaded enviornment       |//
+  //|   the prompt function returns a value that         |//
+  //|   indicates to the mean shift method whether       |//
+  //|   to continue execution. EL_HALT is returned       |//
+  //|   when the mean shift procedure is to stop         |//
+  //|   execution and EL_OKAY is returned otherwise.     |//
+  //|                                                    |//
+  //|   The arguments to this method are:                |//
+  //|                                                    |//
+  //|   <* PercentComplete *>                            |//
+  //|   A floating point number that indicates the perc- |//
+  //|   ent complete of the algorithm. PercentComplete   |//
+  //|   takes a value between zero and one.              |//
+  //|                                                    |//
+  //|   <* SystemState *>                                |//
+  //|   Indicates the system state. It is EL_HALT        |//
+  //|   when the mean shift method is to halt execution  |//
+  //|   and it is EL_OKAY otherwise.                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|	 SystemState = Progress(PercentComplete)         |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+ ErrorLevel Progress(float);
+
+ private:
+
+	 //Timer object...
+	 time_t currentTime;
+
+};
+
+#endif
diff --git a/Utilities/otbedison/segm/msSysPrompt.cpp b/Utilities/otbedison/segm/msSysPrompt.cpp
old mode 100755
new mode 100644
index 8ca2f4b9f8b937a3d37083ec0fc3e281c63ec9fe..a4f2f43e980e867a729f31844303c31d864f123b
--- a/Utilities/otbedison/segm/msSysPrompt.cpp
+++ b/Utilities/otbedison/segm/msSysPrompt.cpp
@@ -1,232 +1,232 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Mean Shift System:
-  ==================
-
-	The Mean Shift System class provides a mechanism for the
-	mean shift library classes to prompt progress and to
-	time its computations. When porting the mean shift library
-	to an application the methods of this class may be changed
-	such that the output of the mean shift class prompts
-	will be given to whatever hardware or software device that
-	is desired.
-
-	The definition for the mean shift system class is provided
-	below. Its prototype is provided in "msSys.cc".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-////////////////////////////////////////////////////////////////////////
-// Command Line Version:
-//   This version of mean shift system is written for the command
-//   line version of EDISON.
-////////////////////////////////////////////////////////////////////////
-
-//include the msSystem class prototype
-#include	"msSys.h"
-
-//include needed system libraries
-#include	<time.h>
-#include	<stdio.h>
-#include	<stdarg.h>
-#include	<stdlib.h>
-
-//define bgLog
-extern bool CmCDisplayProgress;
-void bgLog(const char *PromptStr, ...)
-{
-	//obtain argument list using ANSI standard...
-	va_list	argList;
-	va_start(argList, PromptStr);
-
-	//print the output string to stderr using
-	if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList);
-	va_end(argList);
-
-	//done.
-	return;
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*** Class Constructor and Destructor ***/
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Class Constructor                                    */
-/*******************************************************/
-/*Constructs a mean shift system object.               */
-/*******************************************************/
-/*Post:                                                */
-/*      - an msSystem object has been properly init-   */
-/*        ialized.                                     */
-/*******************************************************/
-
-msSystem::msSystem( void )
-{
-
-	//initialize currentTime
-	currentTime = clock();
-
-	//done.
-
-}
-
-/*******************************************************/
-/*Class Destructor                                     */
-/*******************************************************/
-/*Destroys a mean shift system object.                 */
-/*******************************************************/
-/*Post:                                                */
-/*      - an msSystem object has been properly dest-   */
-/*        royed.                                       */
-/*******************************************************/
-
-msSystem::~msSystem( void )
-{
-	/* do nothing */
-}
-
- /*/\/\/\/\/\/\/\/\/\*/
- /*** System Timer ***/
- /*\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Start Timer                                          */
-/*******************************************************/
-/*Sets the mean shift system time to the current       */
-/*system time.                                         */
-/*******************************************************/
-/*Post:                                                */
-/*      - the mean shift system time has been set to   */
-/*        the current system time.                     */
-/*******************************************************/
-
-void msSystem::StartTimer( void )
-{
-
-	//set msSystem time to system time
-	currentTime = clock();
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Elapsed Time                                         */
-/*******************************************************/
-/*Returns the amount of time in seconds since the      */
-/*mean shift system time was last set.                 */
-/*******************************************************/
-/*Post:                                                */
-/*      - the amount of time in seconds since the mean */
-/*        shift system time was last set is returned.  */
-/*******************************************************/
-
-double msSystem::ElapsedTime( void )
-{
-
-	//return the amount of time elapsed in seconds
-	//since the msSystem time was last set...
-	return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC);
-
-}
-
- /*/\/\/\/\/\/\/\/\/\/\*/
- /***  System Output ***/
- /*\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Prompt                                               */
-/*******************************************************/
-/*Output a text message to the user.                   */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - PromptStr is a string containing delimeters  */
-/*        that is to be output to the user.            */
-/*      - a variable set of arguments is also passed   */
-/*        to this method that are used to replace      */
-/*        the delimeters contained by PromptStr        */
-/*Post:                                                */
-/*      - the delimeters of PromptStr have been        */
-/*        replaced accordingly using the variable      */
-/*        set of arguments and the resulting string    */
-/*        has been output to the user.                 */
-/*******************************************************/
-
-void msSystem::Prompt(const char *PromptStr, ...)
-{
-
-	//obtain argument list using ANSI standard...
-	va_list	argList;
-	va_start(argList, PromptStr);
-
-	//print the output string to stderr using
-	if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList);
-	va_end(argList);
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Progress                                             */
-/*******************************************************/
-/*The progress of a specific algorithm of the mean     */
-/*shift library is output to the user.                 */
-/*******************************************************/
-/*Pre:                                                 */
-/*		- percentComplete indicates the percentage     */
-/*		  of the algorithm that has executed and is    */
-/*		  a floating point number from zero to one     */
-/*Post:                                                */
-/*      - the percentComplete has been noted by the    */
-/*        interface (possibly to update a progress     */
-/*        bar).                                        */
-/*      - if the thread executing the mean shift code  */
-/*        must halt execution msSYS_HALT is returned,  */
-/*        msSYS_OK is returned otherwise               */
-/*******************************************************/
-
-///////////////////////////////////////////////////////////////////
-//NOTE: This implementation is specific to EDISON. In order
-//      for one to port the mean shift class to another project
-//      or program one must re-implement this method.
-///////////////////////////////////////////////////////////////////
-
-ErrorLevel msSystem::Progress(float percentComplete)
-{
-	return EL_OKAY;
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Mean Shift System:
+  ==================
+
+	The Mean Shift System class provides a mechanism for the
+	mean shift library classes to prompt progress and to
+	time its computations. When porting the mean shift library
+	to an application the methods of this class may be changed
+	such that the output of the mean shift class prompts
+	will be given to whatever hardware or software device that
+	is desired.
+
+	The definition for the mean shift system class is provided
+	below. Its prototype is provided in "msSys.cc".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+////////////////////////////////////////////////////////////////////////
+// Command Line Version:
+//   This version of mean shift system is written for the command
+//   line version of EDISON.
+////////////////////////////////////////////////////////////////////////
+
+//include the msSystem class prototype
+#include	"msSys.h"
+
+//include needed system libraries
+#include	<time.h>
+#include	<stdio.h>
+#include	<stdarg.h>
+#include	<stdlib.h>
+
+//define bgLog
+extern bool CmCDisplayProgress;
+void bgLog(const char *PromptStr, ...)
+{
+	//obtain argument list using ANSI standard...
+	va_list	argList;
+	va_start(argList, PromptStr);
+
+	//print the output string to stderr using
+	if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList);
+	va_end(argList);
+
+	//done.
+	return;
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*** Class Constructor and Destructor ***/
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Class Constructor                                    */
+/*******************************************************/
+/*Constructs a mean shift system object.               */
+/*******************************************************/
+/*Post:                                                */
+/*      - an msSystem object has been properly init-   */
+/*        ialized.                                     */
+/*******************************************************/
+
+msSystem::msSystem( void )
+{
+
+	//initialize currentTime
+	currentTime = clock();
+
+	//done.
+
+}
+
+/*******************************************************/
+/*Class Destructor                                     */
+/*******************************************************/
+/*Destroys a mean shift system object.                 */
+/*******************************************************/
+/*Post:                                                */
+/*      - an msSystem object has been properly dest-   */
+/*        royed.                                       */
+/*******************************************************/
+
+msSystem::~msSystem( void )
+{
+	/* do nothing */
+}
+
+ /*/\/\/\/\/\/\/\/\/\*/
+ /*** System Timer ***/
+ /*\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Start Timer                                          */
+/*******************************************************/
+/*Sets the mean shift system time to the current       */
+/*system time.                                         */
+/*******************************************************/
+/*Post:                                                */
+/*      - the mean shift system time has been set to   */
+/*        the current system time.                     */
+/*******************************************************/
+
+void msSystem::StartTimer( void )
+{
+
+	//set msSystem time to system time
+	currentTime = clock();
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Elapsed Time                                         */
+/*******************************************************/
+/*Returns the amount of time in seconds since the      */
+/*mean shift system time was last set.                 */
+/*******************************************************/
+/*Post:                                                */
+/*      - the amount of time in seconds since the mean */
+/*        shift system time was last set is returned.  */
+/*******************************************************/
+
+double msSystem::ElapsedTime( void )
+{
+
+	//return the amount of time elapsed in seconds
+	//since the msSystem time was last set...
+	return ((double) (clock() - currentTime))/(CLOCKS_PER_SEC);
+
+}
+
+ /*/\/\/\/\/\/\/\/\/\/\*/
+ /***  System Output ***/
+ /*\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Prompt                                               */
+/*******************************************************/
+/*Output a text message to the user.                   */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - PromptStr is a string containing delimeters  */
+/*        that is to be output to the user.            */
+/*      - a variable set of arguments is also passed   */
+/*        to this method that are used to replace      */
+/*        the delimeters contained by PromptStr        */
+/*Post:                                                */
+/*      - the delimeters of PromptStr have been        */
+/*        replaced accordingly using the variable      */
+/*        set of arguments and the resulting string    */
+/*        has been output to the user.                 */
+/*******************************************************/
+
+void msSystem::Prompt(const char *PromptStr, ...)
+{
+
+	//obtain argument list using ANSI standard...
+	va_list	argList;
+	va_start(argList, PromptStr);
+
+	//print the output string to stderr using
+	if(CmCDisplayProgress) vfprintf(stdout, PromptStr, argList);
+	va_end(argList);
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Progress                                             */
+/*******************************************************/
+/*The progress of a specific algorithm of the mean     */
+/*shift library is output to the user.                 */
+/*******************************************************/
+/*Pre:                                                 */
+/*		- percentComplete indicates the percentage     */
+/*		  of the algorithm that has executed and is    */
+/*		  a floating point number from zero to one     */
+/*Post:                                                */
+/*      - the percentComplete has been noted by the    */
+/*        interface (possibly to update a progress     */
+/*        bar).                                        */
+/*      - if the thread executing the mean shift code  */
+/*        must halt execution msSYS_HALT is returned,  */
+/*        msSYS_OK is returned otherwise               */
+/*******************************************************/
+
+///////////////////////////////////////////////////////////////////
+//NOTE: This implementation is specific to EDISON. In order
+//      for one to port the mean shift class to another project
+//      or program one must re-implement this method.
+///////////////////////////////////////////////////////////////////
+
+ErrorLevel msSystem::Progress(float percentComplete)
+{
+	return EL_OKAY;
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
diff --git a/Utilities/otbedison/segm/rlist.cpp b/Utilities/otbedison/segm/rlist.cpp
old mode 100755
new mode 100644
index d613c9cfb5f9725726de0f16ef85cebe832fd90a..3b0da9dae1d8781efd757c37e0764198717a9276
--- a/Utilities/otbedison/segm/rlist.cpp
+++ b/Utilities/otbedison/segm/rlist.cpp
@@ -1,339 +1,339 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Region List Class:
-  =================
-
-	During segmentation, data regions are defined. The 
-	RegionList class provides a mechanism for doing so, as
-	well as defines some basic operations, such as region
-	growing or small region pruning, on the defined regions.
-	It is defined below. Its prototype is given in "region.h".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-
-#include	"rlist.h"
-#include	<stdio.h>
-#include	<stdlib.h>
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*** Class Constructor and Destructor ***/
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Constructor                                          */
-/*******************************************************/
-/*Constructor                                          */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - modesPtr is a pointer to an array of modes   */
-/*      - maxRegions_ is the maximum number of regions */
-/*        that can be defined                          */
-/*      - L_ is the number of data points being class- */
-/*        ified by the region list class               */
-/*      - N is the dimension of the data set being cl- */
-/*        assified by the region list class            */
-/*Post:                                                */
-/*      - a region list object has been properly init- */
-/*        ialized.                                     */
-/*******************************************************/
-
-RegionList::RegionList(int maxRegions_, int L_, int N_)
-{
-
-	//Obtain maximum number of regions that can be
-	//defined by user
-	if((maxRegions = maxRegions_) <= 0)
-		ErrorHandler("RegionList", "Maximum number of regions is zero or negative.", FATAL);
-
-	//Obtain dimension of data set being classified by
-	//region list class
-	if((N = N_) <= 0)
-		ErrorHandler("RegionList", "Dimension is zero or negative.", FATAL);
-
-	//Obtain length of input data set...
-	if((L = L_) <= 0)
-		ErrorHandler("RegionList", "Length of data set is zero or negative.", FATAL);
-
-	//Allocate memory for index table
-	if(!(indexTable = new int [L]))
-		ErrorHandler("RegionList", "Not enough memory.", FATAL);
-
-	//Allocate memory for region list array
-	if(!(regionList = new REGION [maxRegions]))
-		ErrorHandler("RegionList", "Not enough memory.", FATAL);
-
-	//Initialize region list...
-	numRegions		= freeRegion = 0;
-
-	//Initialize indexTable
-	freeBlockLoc	= 0;
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Destructor                                           */
-/*******************************************************/
-/*Destroys region list object.                         */
-/*******************************************************/
-/*Post:                                                */
-/*      - region list object has been properly dest-   */
-/*        oyed.                                        */
-/*******************************************************/
-
-RegionList::~RegionList( void )
-{
-	//de-allocate memory...
-	delete [] regionList;
-	delete [] indexTable;
-
-	//done.
-	return;
-}
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /***  Region List Manipulation  ***/
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Add Region                                           */
-/*******************************************************/
-/*Adds a region to the region list.                    */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - label is a positive integer used to uniquely */
-/*        identify a region                            */
-/*      - pointCount is the number of N-dimensional    */
-/*        data points that exist in the region being   */
-/*        classified.                                  */
-/*      - indeces is a set of indeces specifying the   */
-/*        data points contained within this region     */
-/*      - pointCount must be > 0                       */
-/*Post:                                                */
-/*      - a new region labeled using label and contai- */
-/*        ning pointCount number of points has been    */
-/*        added to the region list.                    */
-/*******************************************************/
-
-void RegionList::AddRegion(int label, int pointCount, int *indeces)
-{
-
-	//make sure that there is enough room for this new region 
-	//in the region list array...
-	if(numRegions >= maxRegions)
-		ErrorHandler("AddRegion", "Not enough memory allocated.", FATAL);
-
-	//make sure that label is positive and point Count > 0...
-	if((label < 0)||(pointCount <= 0))
-		ErrorHandler("AddRegion", "Label is negative or number of points in region is invalid.", FATAL);
-
-	//make sure that there is enough memory in the indexTable
-	//for this region...
-	if((freeBlockLoc + pointCount) > L)
-		ErrorHandler("AddRegion", "Adding more points than what is contained in data set.", FATAL);
-
-	//place new region into region list array using
-	//freeRegion index
-	regionList[freeRegion].label		= label;
-	regionList[freeRegion].pointCount	= pointCount;
-	regionList[freeRegion].region		= freeBlockLoc;
-
-	//copy indeces into indexTable using freeBlock...
-	int i;
-	for(i = 0; i < pointCount; i++)
-		indexTable[freeBlockLoc+i] = indeces[i];
-
-	//increment freeBlock to point to the next free
-	//block
-	freeBlockLoc	+= pointCount;
-
-	//increment freeRegion to point to the next free region
-	//also, increment numRegions to indicate that another
-	//region has been added to the region list
-	freeRegion++;
-	numRegions++;
-
-	//done.
-	return;
-
-}
-
-/*******************************************************/
-/*Reset                                                */
-/*******************************************************/
-/*Resets the region list.                              */
-/*******************************************************/
-/*Post:                                                */
-/*      - the region list has been reset.              */
-/*******************************************************/
-
-void RegionList::Reset( void )
-{
-
-	//reset region list
-	freeRegion = numRegions = freeBlockLoc = 0;
-
-	//done.
-	return;
-
-}
-
-  /*/\/\/\/\/\/\/\/\/\/\*/
-  /*  Query Region List */
-  /*\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Get Number Regions                                   */
-/*******************************************************/
-/*Returns the number of regions stored by region list. */
-/*******************************************************/
-/*Post:                                                */
-/*      - the number of regions stored by the region   */
-/*        list is returned.                            */
-/*******************************************************/
-
-int	RegionList::GetNumRegions( void )
-{
-	// return region count
-	return numRegions;
-}
-
-/*******************************************************/
-/*Get Label                                            */
-/*******************************************************/
-/*Returns the label of a specified region.             */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - regionNum is an index into the region list   */
-/*        array.                                       */
-/*Post:                                                */
-/*      - the label of the region having region index  */
-/*        specified by regionNum has been returned.    */
-/*******************************************************/
-
-int	RegionList::GetLabel(int regionNum)
-{
-	//return the label of a specified region
-	return regionList[regionNum].label;
-}
-
-/*******************************************************/
-/*Get Region Count                                     */
-/*******************************************************/
-/*Returns the point count of a specified region.       */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - regionNum is an index into the region list   */
-/*        array.                                       */
-/*Post:                                                */
-/*      - the number of points that classify the       */
-/*        region whose index is specified by regionNum */
-/*        is returned.                                 */
-/*******************************************************/
-
-int RegionList::GetRegionCount(int regionNum)
-{
-	//return the region count of a specified region
-	return regionList[regionNum].pointCount;
-}
-
-/*******************************************************/
-/*Get Region Indeces                                   */
-/*******************************************************/
-/*Returns the point indeces specifying a region.       */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - regionNum is an index into the region list   */
-/*        array.                                       */
-/*Post:                                                */
-/*      - the region indeces specifying the points     */
-/*        contained by the region specified by region- */
-/*        Num are returned.                            */
-/*******************************************************/
-
-int *RegionList::GetRegionIndeces(int regionNum)
-{
-	//return point indeces using regionNum
-	return &indexTable[regionList[regionNum].region];
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     PRIVATE METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-
-  /*/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Class Error Handler */
-  /*\/\/\/\/\/\/\/\/\/\/\/*/
-
-/*******************************************************/
-/*Error Handler                                        */
-/*******************************************************/
-/*Class error handler.                                 */
-/*******************************************************/
-/*Pre:                                                 */
-/*      - functName is the name of the function that   */
-/*        caused an error                              */
-/*      - errmsg is the error message given by the     */
-/*        calling function                             */
-/*      - status is the error status: FATAL or NON-    */
-/*        FATAL                                        */
-/*Post:                                                */
-/*      - the error message errmsg is flagged on beh-  */
-/*        ave of function functName.                   */
-/*      - if the error status is FATAL then the program*/
-/*        is halted, otherwise execution is continued, */
-/*        error recovery is assumed to be handled by   */
-/*        the calling function.                        */
-/*******************************************************/
-
-void RegionList::ErrorHandler(char *functName, char* errmsg, ErrorType status)
-{
-
-	//flag error message on behalf of calling function, error format
-	//specified by the error status...
-	if(status == NONFATAL)
-		fprintf(stderr, "\n%s Error: %s\n", functName, errmsg);
-	else
-	{
-		fprintf(stderr, "\n%s Fatal Error: %s\n\nAborting Program.\n\n", functName, errmsg);
-		exit(1);
-	}
-
-}
-
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
-/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Region List Class:
+  =================
+
+	During segmentation, data regions are defined. The 
+	RegionList class provides a mechanism for doing so, as
+	well as defines some basic operations, such as region
+	growing or small region pruning, on the defined regions.
+	It is defined below. Its prototype is given in "region.h".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+
+#include	"rlist.h"
+#include	<stdio.h>
+#include	<stdlib.h>
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      PUBLIC METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*** Class Constructor and Destructor ***/
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Constructor                                          */
+/*******************************************************/
+/*Constructor                                          */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - modesPtr is a pointer to an array of modes   */
+/*      - maxRegions_ is the maximum number of regions */
+/*        that can be defined                          */
+/*      - L_ is the number of data points being class- */
+/*        ified by the region list class               */
+/*      - N is the dimension of the data set being cl- */
+/*        assified by the region list class            */
+/*Post:                                                */
+/*      - a region list object has been properly init- */
+/*        ialized.                                     */
+/*******************************************************/
+
+RegionList::RegionList(int maxRegions_, int L_, int N_)
+{
+
+	//Obtain maximum number of regions that can be
+	//defined by user
+	if((maxRegions = maxRegions_) <= 0)
+		ErrorHandler("RegionList", "Maximum number of regions is zero or negative.", FATAL);
+
+	//Obtain dimension of data set being classified by
+	//region list class
+	if((N = N_) <= 0)
+		ErrorHandler("RegionList", "Dimension is zero or negative.", FATAL);
+
+	//Obtain length of input data set...
+	if((L = L_) <= 0)
+		ErrorHandler("RegionList", "Length of data set is zero or negative.", FATAL);
+
+	//Allocate memory for index table
+	if(!(indexTable = new int [L]))
+		ErrorHandler("RegionList", "Not enough memory.", FATAL);
+
+	//Allocate memory for region list array
+	if(!(regionList = new REGION [maxRegions]))
+		ErrorHandler("RegionList", "Not enough memory.", FATAL);
+
+	//Initialize region list...
+	numRegions		= freeRegion = 0;
+
+	//Initialize indexTable
+	freeBlockLoc	= 0;
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Destructor                                           */
+/*******************************************************/
+/*Destroys region list object.                         */
+/*******************************************************/
+/*Post:                                                */
+/*      - region list object has been properly dest-   */
+/*        oyed.                                        */
+/*******************************************************/
+
+RegionList::~RegionList( void )
+{
+	//de-allocate memory...
+	delete [] regionList;
+	delete [] indexTable;
+
+	//done.
+	return;
+}
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /***  Region List Manipulation  ***/
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Add Region                                           */
+/*******************************************************/
+/*Adds a region to the region list.                    */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - label is a positive integer used to uniquely */
+/*        identify a region                            */
+/*      - pointCount is the number of N-dimensional    */
+/*        data points that exist in the region being   */
+/*        classified.                                  */
+/*      - indeces is a set of indeces specifying the   */
+/*        data points contained within this region     */
+/*      - pointCount must be > 0                       */
+/*Post:                                                */
+/*      - a new region labeled using label and contai- */
+/*        ning pointCount number of points has been    */
+/*        added to the region list.                    */
+/*******************************************************/
+
+void RegionList::AddRegion(int label, int pointCount, int *indeces)
+{
+
+	//make sure that there is enough room for this new region 
+	//in the region list array...
+	if(numRegions >= maxRegions)
+		ErrorHandler("AddRegion", "Not enough memory allocated.", FATAL);
+
+	//make sure that label is positive and point Count > 0...
+	if((label < 0)||(pointCount <= 0))
+		ErrorHandler("AddRegion", "Label is negative or number of points in region is invalid.", FATAL);
+
+	//make sure that there is enough memory in the indexTable
+	//for this region...
+	if((freeBlockLoc + pointCount) > L)
+		ErrorHandler("AddRegion", "Adding more points than what is contained in data set.", FATAL);
+
+	//place new region into region list array using
+	//freeRegion index
+	regionList[freeRegion].label		= label;
+	regionList[freeRegion].pointCount	= pointCount;
+	regionList[freeRegion].region		= freeBlockLoc;
+
+	//copy indeces into indexTable using freeBlock...
+	int i;
+	for(i = 0; i < pointCount; i++)
+		indexTable[freeBlockLoc+i] = indeces[i];
+
+	//increment freeBlock to point to the next free
+	//block
+	freeBlockLoc	+= pointCount;
+
+	//increment freeRegion to point to the next free region
+	//also, increment numRegions to indicate that another
+	//region has been added to the region list
+	freeRegion++;
+	numRegions++;
+
+	//done.
+	return;
+
+}
+
+/*******************************************************/
+/*Reset                                                */
+/*******************************************************/
+/*Resets the region list.                              */
+/*******************************************************/
+/*Post:                                                */
+/*      - the region list has been reset.              */
+/*******************************************************/
+
+void RegionList::Reset( void )
+{
+
+	//reset region list
+	freeRegion = numRegions = freeBlockLoc = 0;
+
+	//done.
+	return;
+
+}
+
+  /*/\/\/\/\/\/\/\/\/\/\*/
+  /*  Query Region List */
+  /*\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Get Number Regions                                   */
+/*******************************************************/
+/*Returns the number of regions stored by region list. */
+/*******************************************************/
+/*Post:                                                */
+/*      - the number of regions stored by the region   */
+/*        list is returned.                            */
+/*******************************************************/
+
+int	RegionList::GetNumRegions( void )
+{
+	// return region count
+	return numRegions;
+}
+
+/*******************************************************/
+/*Get Label                                            */
+/*******************************************************/
+/*Returns the label of a specified region.             */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - regionNum is an index into the region list   */
+/*        array.                                       */
+/*Post:                                                */
+/*      - the label of the region having region index  */
+/*        specified by regionNum has been returned.    */
+/*******************************************************/
+
+int	RegionList::GetLabel(int regionNum)
+{
+	//return the label of a specified region
+	return regionList[regionNum].label;
+}
+
+/*******************************************************/
+/*Get Region Count                                     */
+/*******************************************************/
+/*Returns the point count of a specified region.       */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - regionNum is an index into the region list   */
+/*        array.                                       */
+/*Post:                                                */
+/*      - the number of points that classify the       */
+/*        region whose index is specified by regionNum */
+/*        is returned.                                 */
+/*******************************************************/
+
+int RegionList::GetRegionCount(int regionNum)
+{
+	//return the region count of a specified region
+	return regionList[regionNum].pointCount;
+}
+
+/*******************************************************/
+/*Get Region Indeces                                   */
+/*******************************************************/
+/*Returns the point indeces specifying a region.       */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - regionNum is an index into the region list   */
+/*        array.                                       */
+/*Post:                                                */
+/*      - the region indeces specifying the points     */
+/*        contained by the region specified by region- */
+/*        Num are returned.                            */
+/*******************************************************/
+
+int *RegionList::GetRegionIndeces(int regionNum)
+{
+	//return point indeces using regionNum
+	return &indexTable[regionList[regionNum].region];
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     PRIVATE METHODS     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+  /*/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Class Error Handler */
+  /*\/\/\/\/\/\/\/\/\/\/\/*/
+
+/*******************************************************/
+/*Error Handler                                        */
+/*******************************************************/
+/*Class error handler.                                 */
+/*******************************************************/
+/*Pre:                                                 */
+/*      - functName is the name of the function that   */
+/*        caused an error                              */
+/*      - errmsg is the error message given by the     */
+/*        calling function                             */
+/*      - status is the error status: FATAL or NON-    */
+/*        FATAL                                        */
+/*Post:                                                */
+/*      - the error message errmsg is flagged on beh-  */
+/*        ave of function functName.                   */
+/*      - if the error status is FATAL then the program*/
+/*        is halted, otherwise execution is continued, */
+/*        error recovery is assumed to be handled by   */
+/*        the calling function.                        */
+/*******************************************************/
+
+void RegionList::ErrorHandler(char *functName, char* errmsg, ErrorType status)
+{
+
+	//flag error message on behalf of calling function, error format
+	//specified by the error status...
+	if(status == NONFATAL)
+		fprintf(stderr, "\n%s Error: %s\n", functName, errmsg);
+	else
+	{
+		fprintf(stderr, "\n%s Fatal Error: %s\n\nAborting Program.\n\n", functName, errmsg);
+		exit(1);
+	}
+
+}
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ END OF CLASS DEFINITION @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
diff --git a/Utilities/otbedison/segm/rlist.h b/Utilities/otbedison/segm/rlist.h
old mode 100755
new mode 100644
index 453fdc74c1760c069c43d69dc83b823e5541b0ee..55bb67ce2353b9f42fc29656491ccea18b6fc7ff
--- a/Utilities/otbedison/segm/rlist.h
+++ b/Utilities/otbedison/segm/rlist.h
@@ -1,337 +1,337 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Region List Class:
-  =================
-
-	During segmentation, data regions are defined. The 
-	RegionList class provides a mechanism for doing so, as
-	well as defines some basic operations, such as region
-	growing or small region pruning, on the defined regions.
-	The prototype for the RegionList class is provided below. It
-	is defined in "region.cc".
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-#ifndef RLIST_H
-#define RLIST_H
-
-//include global type definitions
-#include	"tdef.h"
-
-//define region structure
-struct REGION {
-	int			label;
-	int			pointCount;
-	int			region;
-
-};
-
-//region class prototype...
-class RegionList {
-
-public:
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /* Class Constructor and Destructor */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|               *  Class Constructor  *              |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Constructs a region list object.                 |//
-  //|                                                    |//
-  //|   Its arguments are:                               |//
-  //|                                                    |//
-  //|   <* maxRegions *>                                 |//
-  //|   The maximum amount of regions that can be class- |//
-  //|   ified by the region list.                        |//
-  //|                                                    |//
-  //|   <* L *>                                          |//
-  //|   The length of the input data set being class-    |//
-  //|   ified by the region list object.                 |//
-  //|                                                    |//
-  //|   <* N *>                                          |//
-  //|   The dimension of the input data set being class- |//
-  //|   ified by the region list object.                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|     RegionList(maxRegions, L, N)                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	RegionList(int, int, int);
-
-	// Class Destructor
-	~RegionList( void );
-
-  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Region List Manipulation  */
-  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|                *  Add Region  *                    |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Adds a region to the region list.                |//
-  //|                                                    |//
-  //|   Its arguments are:                               |//
-  //|                                                    |//
-  //|   <* label *>                                      |//
-  //|                                                    |//
-  //|   A positive integer used to uniquely identify     |//
-  //|   a region.                                        |//
-  //|                                                    |//
-  //|   <* pointCount *>                                 |//
-  //|   A positive integer that specifies the number of  |//
-  //|   N-dimensional data points that exist in the re-  |//
-  //|   gion being classified.                           |//
-  //|                                                    |//
-  //|   <* indeces *>                                    |//
-  //|   An integer array that specifies the set of ind-  |//
-  //|   eces of the data points that are contianed with- |//
-  //|   in this region.                                  |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|     AddRegion(label, pointCount, indeces)          |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	void AddRegion(int, int, int*);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|                    *  Reset  *                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Resets the region list for re-use (for new       |//
-  //|   classification).                                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	void Reset( void );	
-
-  /*/\/\/\/\/\/\/\/\/\/\*/
-  /*  Query Region List */
-  /*\/\/\/\/\/\/\/\/\/\/*/
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|          *  Get Number of Regions  *               |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the number of regions stored by the      |//
-  //|   region list.                                     |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	int	GetNumRegions ( void );
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|                  *  Get Label  *                   |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns the label of a specified region.         |//
-  //|                                                    |//
-  //|   Its arguments are:                               |//
-  //|                                                    |//
-  //|   <* regionNumber *>                               |//
-  //|   The index of the region in the region list       |//
-  //|   array.                                           |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|     label = GetLabel(regionNumber)                 |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	int	GetLabel(int);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|                *  Get Region Count  *              |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns number of data points contained by a sp- |//
-  //|   ecified region.                                  |//
-  //|                                                    |//
-  //|   Its arguments are:                               |//
-  //|                                                    |//
-  //|   <* regionNumber *>                               |//
-  //|   The index of the region in the region list       |//
-  //|   array.                                           |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|     pointCount = GetRegionCount(regionNumber)      |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	int GetRegionCount(int);
-
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Method Name:								     |//
-  //|   ============								     |//
-  //|               *  Get Region Indeces  *             |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Description:								     |//
-  //|	============								     |//
-  //|                                                    |//
-  //|   Returns a pointer to a set of grid location ind- |//
-  //|   eces specifying the data points belonging to a   |//
-  //|   specified region.                                |//
-  //|                                                    |//
-  //|   Its arguments are:                               |//
-  //|                                                    |//
-  //|   <* regionNumber *>                               |//
-  //|   The index of the region in the region list       |//
-  //|   array.                                           |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //|                                                    |//
-  //|	Usage:      								     |//
-  //|   ======      								     |//
-  //|     indeces = GetRegionIndeces(regionNumber)       |//
-  //|                                                    |//
-  //<--------------------------------------------------->|//
-  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
-
-	int*GetRegionIndeces(int);
-
-private:
-
-  /*/\/\/\/\/\/\/\/\/\/\/\*/
-  /*  Class Error Handler */
-  /*\/\/\/\/\/\/\/\/\/\/\/*/
-
-	void ErrorHandler(char*, char*, ErrorType);
-
-  //=============================
-  // *** Private Data Members ***
-  //=============================
-
-	//#####################################
-	//### REGION LIST PARTITIONED ARRAY ###
-	//#####################################
-
-	REGION		*regionList;			//array of maxRegions regions
-	int			minRegion;
-
-	int			maxRegions;				//defines the number maximum number of regions
-										//allowed (determined by user during class construction)
-	int			numRegions;				//the number of regions currently stored by the
-										//region list
-	int			freeRegion;				//an index into the regionList pointing to the next
-										//available region in the regionList
-
-	//#####################################
-	//###         INDEX TABLE           ###
-	//#####################################
-
-	int			*indexTable;			//an array of indexes that point into an external structure
-										//specifying which points belong to a region
-	int			freeBlockLoc;			//points to the next free block of memory in the indexTable
-
-	//#####################################
-	//###     INPUT DATA PARAMETERS     ###
-	//#####################################
-
-	//Dimension of data set
-	int			N;						//dimension of data set being classified by region list
-										//class
-
-	//Length of the data set
-	int			L;						//number of points contained by the data set being classified by
-										//region list class
-
-};
-
-#endif
-
-
-
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Region List Class:
+  =================
+
+	During segmentation, data regions are defined. The 
+	RegionList class provides a mechanism for doing so, as
+	well as defines some basic operations, such as region
+	growing or small region pruning, on the defined regions.
+	The prototype for the RegionList class is provided below. It
+	is defined in "region.cc".
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+#ifndef RLIST_H
+#define RLIST_H
+
+//include global type definitions
+#include	"tdef.h"
+
+//define region structure
+struct REGION {
+	int			label;
+	int			pointCount;
+	int			region;
+
+};
+
+//region class prototype...
+class RegionList {
+
+public:
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /* Class Constructor and Destructor */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|               *  Class Constructor  *              |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Constructs a region list object.                 |//
+  //|                                                    |//
+  //|   Its arguments are:                               |//
+  //|                                                    |//
+  //|   <* maxRegions *>                                 |//
+  //|   The maximum amount of regions that can be class- |//
+  //|   ified by the region list.                        |//
+  //|                                                    |//
+  //|   <* L *>                                          |//
+  //|   The length of the input data set being class-    |//
+  //|   ified by the region list object.                 |//
+  //|                                                    |//
+  //|   <* N *>                                          |//
+  //|   The dimension of the input data set being class- |//
+  //|   ified by the region list object.                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|     RegionList(maxRegions, L, N)                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	RegionList(int, int, int);
+
+	// Class Destructor
+	~RegionList( void );
+
+  /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Region List Manipulation  */
+  /*\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|                *  Add Region  *                    |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Adds a region to the region list.                |//
+  //|                                                    |//
+  //|   Its arguments are:                               |//
+  //|                                                    |//
+  //|   <* label *>                                      |//
+  //|                                                    |//
+  //|   A positive integer used to uniquely identify     |//
+  //|   a region.                                        |//
+  //|                                                    |//
+  //|   <* pointCount *>                                 |//
+  //|   A positive integer that specifies the number of  |//
+  //|   N-dimensional data points that exist in the re-  |//
+  //|   gion being classified.                           |//
+  //|                                                    |//
+  //|   <* indeces *>                                    |//
+  //|   An integer array that specifies the set of ind-  |//
+  //|   eces of the data points that are contianed with- |//
+  //|   in this region.                                  |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|     AddRegion(label, pointCount, indeces)          |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	void AddRegion(int, int, int*);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|                    *  Reset  *                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Resets the region list for re-use (for new       |//
+  //|   classification).                                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	void Reset( void );	
+
+  /*/\/\/\/\/\/\/\/\/\/\*/
+  /*  Query Region List */
+  /*\/\/\/\/\/\/\/\/\/\/*/
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|          *  Get Number of Regions  *               |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the number of regions stored by the      |//
+  //|   region list.                                     |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	int	GetNumRegions ( void );
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|                  *  Get Label  *                   |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns the label of a specified region.         |//
+  //|                                                    |//
+  //|   Its arguments are:                               |//
+  //|                                                    |//
+  //|   <* regionNumber *>                               |//
+  //|   The index of the region in the region list       |//
+  //|   array.                                           |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|     label = GetLabel(regionNumber)                 |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	int	GetLabel(int);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|                *  Get Region Count  *              |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns number of data points contained by a sp- |//
+  //|   ecified region.                                  |//
+  //|                                                    |//
+  //|   Its arguments are:                               |//
+  //|                                                    |//
+  //|   <* regionNumber *>                               |//
+  //|   The index of the region in the region list       |//
+  //|   array.                                           |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|     pointCount = GetRegionCount(regionNumber)      |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	int GetRegionCount(int);
+
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Method Name:								     |//
+  //|   ============								     |//
+  //|               *  Get Region Indeces  *             |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Description:								     |//
+  //|	============								     |//
+  //|                                                    |//
+  //|   Returns a pointer to a set of grid location ind- |//
+  //|   eces specifying the data points belonging to a   |//
+  //|   specified region.                                |//
+  //|                                                    |//
+  //|   Its arguments are:                               |//
+  //|                                                    |//
+  //|   <* regionNumber *>                               |//
+  //|   The index of the region in the region list       |//
+  //|   array.                                           |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //|                                                    |//
+  //|	Usage:      								     |//
+  //|   ======      								     |//
+  //|     indeces = GetRegionIndeces(regionNumber)       |//
+  //|                                                    |//
+  //<--------------------------------------------------->|//
+  //--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//--\\||//
+
+	int*GetRegionIndeces(int);
+
+private:
+
+  /*/\/\/\/\/\/\/\/\/\/\/\*/
+  /*  Class Error Handler */
+  /*\/\/\/\/\/\/\/\/\/\/\/*/
+
+	void ErrorHandler(char*, char*, ErrorType);
+
+  //=============================
+  // *** Private Data Members ***
+  //=============================
+
+	//#####################################
+	//### REGION LIST PARTITIONED ARRAY ###
+	//#####################################
+
+	REGION		*regionList;			//array of maxRegions regions
+	int			minRegion;
+
+	int			maxRegions;				//defines the number maximum number of regions
+										//allowed (determined by user during class construction)
+	int			numRegions;				//the number of regions currently stored by the
+										//region list
+	int			freeRegion;				//an index into the regionList pointing to the next
+										//available region in the regionList
+
+	//#####################################
+	//###         INDEX TABLE           ###
+	//#####################################
+
+	int			*indexTable;			//an array of indexes that point into an external structure
+										//specifying which points belong to a region
+	int			freeBlockLoc;			//points to the next free block of memory in the indexTable
+
+	//#####################################
+	//###     INPUT DATA PARAMETERS     ###
+	//#####################################
+
+	//Dimension of data set
+	int			N;						//dimension of data set being classified by region list
+										//class
+
+	//Length of the data set
+	int			L;						//number of points contained by the data set being classified by
+										//region list class
+
+};
+
+#endif
+
+
+
diff --git a/Utilities/otbedison/segm/tdef.h b/Utilities/otbedison/segm/tdef.h
old mode 100755
new mode 100644
index 3eae02c28b90ed82e2e064f2c3679fe8f2b09172..9b225b3b84a5fae9504701c5a77e5cf9069d3c91
--- a/Utilities/otbedison/segm/tdef.h
+++ b/Utilities/otbedison/segm/tdef.h
@@ -1,51 +1,51 @@
-/*******************************************************
-
-                 Mean Shift Analysis Library
-	=============================================
-
-	The mean shift library is a collection of routines
-	that use the mean shift algorithm. Using this algorithm,
-	the necessary output will be generated needed
-	to analyze a given input set of data.
-
-  Type Defintions:
-  ===============
-
-	This header file contains the type defintions and
-	enumerations shared among the various classes of the mean
-	shift library.
-
-The theory is described in the papers:
-
-  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
-									 space analysis.
-
-  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
-
-and they are is available at:
-  http://www.caip.rutgers.edu/riul/research/papers/
-
-Implemented by Chris M. Christoudias, Bogdan Georgescu
-********************************************************/
-
-#ifndef TDEF_H
-#define TDEF_H
-
-/*/\/\/\/\/\/\/\/\/\/\/\*/
-/* Define Enumerations  */
-/*\/\/\/\/\/\/\/\/\/\/\/*/
-
-//Kernel
-enum kernelType		{Uniform, Gaussian, UserDefined};
-
-// kd-Tree
-enum childType		{LEFT, RIGHT};
-
-// Speed Up Level
-enum SpeedUpLevel	{NO_SPEEDUP, MED_SPEEDUP, HIGH_SPEEDUP};
-
-// Error Handler
-enum ErrorLevel		{EL_OKAY, EL_ERROR, EL_HALT};
-enum ErrorType		{NONFATAL, FATAL};
-
-#endif
+/*******************************************************
+
+                 Mean Shift Analysis Library
+	=============================================
+
+	The mean shift library is a collection of routines
+	that use the mean shift algorithm. Using this algorithm,
+	the necessary output will be generated needed
+	to analyze a given input set of data.
+
+  Type Defintions:
+  ===============
+
+	This header file contains the type defintions and
+	enumerations shared among the various classes of the mean
+	shift library.
+
+The theory is described in the papers:
+
+  D. Comaniciu, P. Meer: Mean Shift: A robust approach toward feature
+									 space analysis.
+
+  C. Christoudias, B. Georgescu, P. Meer: Synergism in low level vision.
+
+and they are is available at:
+  http://www.caip.rutgers.edu/riul/research/papers/
+
+Implemented by Chris M. Christoudias, Bogdan Georgescu
+********************************************************/
+
+#ifndef TDEF_H
+#define TDEF_H
+
+/*/\/\/\/\/\/\/\/\/\/\/\*/
+/* Define Enumerations  */
+/*\/\/\/\/\/\/\/\/\/\/\/*/
+
+//Kernel
+enum kernelType		{Uniform, Gaussian, UserDefined};
+
+// kd-Tree
+enum childType		{LEFT, RIGHT};
+
+// Speed Up Level
+enum SpeedUpLevel	{NO_SPEEDUP, MED_SPEEDUP, HIGH_SPEEDUP};
+
+// Error Handler
+enum ErrorLevel		{EL_OKAY, EL_ERROR, EL_HALT};
+enum ErrorType		{NONFATAL, FATAL};
+
+#endif