1 // This is brl/bbas/bgui/bgui_image_tableau.cxx
2 #include <iostream>
3 #include <cmath>
4 #include <cstdio>
5 #include "bgui_image_tableau.h"
6 //:
7 // \file
8 // \author J.L. Mundy
9 // \brief  See bgui_image_tableau.h for a description of this file.
10 
11 #ifdef _MSC_VER
12 #  include "vcl_msvc_warnings.h"
13 #endif
14 #include "vgui/vgui_event.h"
15 #include "vgui/vgui.h"
16 #include "vgui/vgui_adaptor.h"
17 #include "vgui/vgui_utils.h"
18 #include "vgui/vgui_projection_inspector.h"
19 #include "vil1/vil1_image.h"
20 #include "vil1/vil1_rgba.h"
21 #include "vil/vil_image_view.h"
22 #include "vgui/vgui_range_map_params.h"
23 
24 
25 //-----------------------------------------------------------------------------
26 //: The constructor takes a snapshot of the current viewport and scissor areas.
27 //  The destructor restores that state.
28 //--------------------------------------------------------------------------------
29 
bgui_image_tableau()30 bgui_image_tableau::bgui_image_tableau()
31 {
32   handle_motion_ = true; locked_ = false; show_path_=false;
33   mouse_message_ = false;
34   tt_ = new vgui_text_tableau();
35 }
36 
bgui_image_tableau(vil_image_resource_sptr const & img,vgui_range_map_params_sptr const & rmp)37 bgui_image_tableau::bgui_image_tableau(vil_image_resource_sptr const & img,
38                                        vgui_range_map_params_sptr const& rmp)
39  : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
40   mouse_message_ = false;
41   capture_mouse_ = false;
42   tt_ = new vgui_text_tableau();}
43 
bgui_image_tableau(vil_image_view_base const & img,vgui_range_map_params_sptr const & rmp)44 bgui_image_tableau::bgui_image_tableau(vil_image_view_base const & img,
45                                        vgui_range_map_params_sptr const& rmp)
46  : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
47   mouse_message_ = false;
48   capture_mouse_ = false;
49  tt_ = new vgui_text_tableau();}
50 
bgui_image_tableau(vil1_image const & img,vgui_range_map_params_sptr const & rmp)51 bgui_image_tableau::bgui_image_tableau(vil1_image const & img,
52                                        vgui_range_map_params_sptr const& rmp)
53  : base(img, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
54   mouse_message_ = false;
55   capture_mouse_ = false;
56  tt_ = new vgui_text_tableau();}
57 
bgui_image_tableau(char const * f,vgui_range_map_params_sptr const & rmp)58 bgui_image_tableau::bgui_image_tableau(char const *f,
59                                        vgui_range_map_params_sptr const& rmp)
60  : base(f, rmp) { handle_motion_ = true; locked_ = false; show_path_=false;
61   mouse_message_ = false;
62   capture_mouse_ = false;
63  tt_ = new vgui_text_tableau();}
64 
65 //--------------------------------------------------------------------------------
66 
get_image() const67 vil1_image bgui_image_tableau::get_image() const
68 {
69   return base::get_image();
70 }
71 
get_image_resource() const72 vil_image_resource_sptr bgui_image_tableau::get_image_resource() const
73 {
74   return base::get_image_resource();
75 }
76 
get_pixel_info_from_frame_buffer(const int x,const int y,vgui_event const & e,char * msg)77 void bgui_image_tableau::get_pixel_info_from_frame_buffer(const int x, const int y, vgui_event const &e, char* msg)
78 {
79   // It's easier to get the buffer in vil1_rgba format and then convert to
80   // RGB, because that avoids alignment problems with glReadPixels.
81   vgui_utils::set_glPixelZoom(1,1);
82   glPixelTransferi(GL_MAP_COLOR,0);
83   glPixelTransferi(GL_RED_SCALE,1);   glPixelTransferi(GL_RED_BIAS,0);
84   glPixelTransferi(GL_GREEN_SCALE,1); glPixelTransferi(GL_GREEN_BIAS,0);
85   glPixelTransferi(GL_BLUE_SCALE,1);  glPixelTransferi(GL_BLUE_BIAS,0);
86 
87   glPixelStorei(GL_PACK_ALIGNMENT,1);   // byte alignment.
88   glPixelStorei(GL_PACK_ROW_LENGTH,0);  // use default value (the arg to pixel routine).
89   glPixelStorei(GL_PACK_SKIP_PIXELS,0); //
90   glPixelStorei(GL_PACK_SKIP_ROWS,0);   //
91   double scale = vgui_adaptor::current->get_scale_factor();
92   vil1_rgba<GLubyte> pixel;
93   glReadPixels(e.wx*scale, e.wy*scale, // Physical pixel location
94                1, 1,             // height and width (only one pixel)
95                GL_RGBA,          // format
96                GL_UNSIGNED_BYTE, // type
97                &pixel);
98   std::sprintf(msg, "(%d, %d)   (ubyte)[ R=%d,G=%d,B=%d]", x, y,
99               pixel.r, pixel.g, pixel.b);
100 }
101 
102 void bgui_image_tableau::
get_pixel_info_from_image(const int x,const int y,vgui_event const & e,char * msg)103 get_pixel_info_from_image(const int x, const int y,
104                           vgui_event const &e, char* msg)
105 {
106   //only implemented for vil image resource and common vil types
107   //(I don't like macros)
108   vil_image_resource_sptr r = this->get_image_resource();
109   if (!r) {
110     if (!this->get_image())
111     {
112       std::sprintf(msg, "(%d, %d)   ?", x, y);
113       return;
114     }
115     else
116     {
117       this->get_pixel_info_from_frame_buffer(x, y, e, msg);
118       return;
119     }
120   }
121   //At this point, we have a vil_image and can proceed with the cases.
122   unsigned w = r->ni(), h = r->nj(), n_p = r->nplanes();
123   if (x<0||x>=int(w)||y<0||y>=int(h))
124   {
125     std::sprintf(msg, "(%d, %d)   ?", 0, 0);
126     return;
127   }
128   //note: will treat RGBA as a four plane type
129   vil_pixel_format type = vil_pixel_format_component_format(r->pixel_format());
130 
131   switch (type )
132   {
133    case VIL_PIXEL_FORMAT_BOOL:
134    {
135     vil_image_view<bool> v = r->get_view();
136     if (!v)
137       std::sprintf(msg, "Pixel Not Available");
138     else
139       std::sprintf(msg, "(%d, %d)   (bool) %d", x, y, v(x,y));
140     return;
141    }
142    case  VIL_PIXEL_FORMAT_BYTE:
143    {
144     if (n_p==1)
145     {
146       vil_image_view<vxl_byte> v = r->get_view(x,1,y,1);
147       if (!v)
148         std::sprintf(msg, "Pixel Not Available");
149       else
150         std::sprintf(msg, "(%d, %d)   (ubyte) %d", x, y, v(0,0));
151       return;
152     }
153     else if (n_p==3)
154     {
155       vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
156       if (!v)
157         std::sprintf(msg, "Pixel Not Available");
158       else
159         std::sprintf(msg, "(%d, %d)   (ubyte)[ R=%d,G=%d,B=%d]", x, y,
160                     v(0,0,0), v(0,0,1), v(0,0,2) );
161       return;
162     }
163     else if (n_p==4) {
164       vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
165       if (!v)
166         std::sprintf(msg, "Pixel Not Available");
167       else//as a default, just display first three bands as RGB
168         std::sprintf(msg, "(%d, %d) (ubyte)[ R=%d,G=%d,B=%d, X=%d]", x, y,
169                     v(0,0,0), v(0,0,1), v(0,0,2), v(0,0,3));
170       return;
171     }
172     return;
173    }
174    case  VIL_PIXEL_FORMAT_SBYTE:
175    {
176     if (n_p==1)
177     {
178       vil_image_view<vxl_sbyte> v = r->get_view(x,1,y,1);
179       if (!v)
180         std::sprintf(msg, "Pixel Not Available");
181       else
182         std::sprintf(msg, "(%d, %d)   (sbyte) %d", x, y, v(0,0));
183       return;
184     }
185     else if (n_p==3)
186     {
187       vil_image_view<vil_rgb<vxl_sbyte> > v = r->get_view(x,1,y,1);
188       if (!v)
189         std::sprintf(msg, "Pixel Not Available");
190       else
191         std::sprintf(msg, "(%d, %d)   (sbyte)[ R=%d,G=%d,B=%d]", x, y,
192                     v(0,0).R(), v(0,0).G(),v(0,0).B() );
193       return;
194     }
195     else if (n_p==4) {
196       vil_image_view<vxl_byte > v = r->get_view(x,1,y,1);
197       if (!v)
198         std::sprintf(msg, "Pixel Not Available");
199       else//as a default, just display first three bands as RGB
200         std::sprintf(msg, "(%d, %d) (sbyte)[ R=%d,G=%d,B=%d,X=%d]", x, y,
201                     v(0,0,0), v(0,0,1), v(0,0,2), v(0,0,3));
202       return;
203     }
204     return;
205    }
206    case  VIL_PIXEL_FORMAT_UINT_16:
207    {
208     if (n_p==1)
209     {
210       vil_image_view<vxl_uint_16> v = r->get_view(x,1,y,1);
211       if (!v)
212         std::sprintf(msg, "Pixel Not Available");
213       else
214         std::sprintf(msg, "(%d, %d)   (uint16) %d", x, y, v(0,0));
215       return;
216     }
217     else if (n_p==3)
218     {
219       vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
220       if (!v)
221         std::sprintf(msg, "Pixel Not Available");
222       else
223         std::sprintf(msg, "(%d, %d)   (uint16)[ R=%d,G=%d,B=%d]", x, y,
224                     v(0,0).R(), v(0,0).G(),v(0,0).B() );
225     }
226     else if (n_p==4)
227     {
228       vil_image_view<vil_rgba<vxl_uint_16> > v = r->get_view(x,1,y,1);
229       if (!v) {
230         std::sprintf(msg, "Pixel Not Available");
231         return;
232       }
233       else
234       {
235         int band_map = 0;
236         if (rmp_)
237           band_map = rmp_->band_map_;
238         switch (band_map)
239         {
240          case vgui_range_map_params::RGB_m :
241           std::sprintf(msg, "(%d, %d)   (RGB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
242                       x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
243           break;
244          case vgui_range_map_params::XRG_m :
245           std::sprintf(msg, "(%d, %d)   (IRG:uint16)[ R=%d,G=%d,B=%d,I=%d]",
246                       x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
247           break;
248          case vgui_range_map_params::RXB_m :
249           std::sprintf(msg, "(%d, %d)   (RIB:uint16)[ R=%d,G=%d,B=%d,I=%d]",
250                       x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
251           break;
252          case vgui_range_map_params::RGX_m :
253           std::sprintf(msg, "(%d, %d)   (RGI:uint16)[ R=%d,G=%d,B=%d,I=%d]",
254                       x, y, v(0,0).R(), v(0,0).G(),v(0,0).B(),v(0,0).A() );
255           break;
256          default:
257           std::sprintf(msg, "Pixel Not Available");
258           return;
259         }
260       }
261     }
262    }
263    case  VIL_PIXEL_FORMAT_INT_16: {
264     if (n_p==1)
265     {
266       vil_image_view<vxl_int_16> v = r->get_view(x,1,y,1);
267       if (!v)
268         std::sprintf(msg, "Pixel Not Available");
269       else
270         std::sprintf(msg, "(%d, %d)   (int16) %d", x, y, v(0,0));
271       return;
272     }
273     else if (n_p==3)
274     {
275       vil_image_view<vil_rgb<vxl_int_16> > v = r->get_view(x,1,y,1);
276       if (!v)
277         std::sprintf(msg, "Pixel Not Available");
278       else
279         std::sprintf(msg, "(%d, %d)   (int16)[ R=%d,G=%d,B=%d]", x, y,
280                     v(0,0).R(), v(0,0).G(),v(0,0).B() );
281       return;
282     }
283     return;
284    }
285    case  VIL_PIXEL_FORMAT_UINT_32: {
286     if (n_p==1)
287     {
288       vil_image_view<vxl_uint_32> v = r->get_view(x,1,y,1);
289       if (!v)
290         std::sprintf(msg, "Pixel Not Available");
291       else
292         std::sprintf(msg, "(%d, %d)   (uint32) %d", x, y, v(0,0));
293       return;
294     }
295     else if (n_p==3)
296     {
297       vil_image_view<vil_rgb<vxl_uint_32> > v = r->get_view(x,1,y,1);
298       if (!v)
299         std::sprintf(msg, "Pixel Not Available");
300       else
301         std::sprintf(msg, "(%d, %d)   (uint32)[ R=%d,G=%d,B=%d]", x, y,
302                     v(0,0).R(), v(0,0).G(),v(0,0).B() );
303       return;
304     }
305     return;
306    }
307    case  VIL_PIXEL_FORMAT_FLOAT: {
308     vil_image_view<float> v = r->get_view(x,1,y,1);
309     if (!v)
310       std::sprintf(msg, "Pixel Not Available");
311     else if (n_p == 1)
312       std::sprintf(msg, "(%d, %d)   (float) %f", x, y, v(0,0));
313     else if (n_p ==3)
314       std::sprintf(msg, "(%d, %d)   (float)[ R=%6.3f,G=%6.3f,B=%6.3f]", x, y,
315                   v(0,0,0), v(0,0,1), v(0,0,2) );
316     return;
317    }
318    case  VIL_PIXEL_FORMAT_DOUBLE: {
319     vil_image_view<double> v = r->get_view(x,1,y,1);
320     if (!v)
321       std::sprintf(msg, "Pixel Not Available");
322     else
323       std::sprintf(msg, "(%d, %d)   (double) %g", x, y, v(0,0));
324     return;
325    }
326    case VIL_PIXEL_FORMAT_RGB_BYTE: {
327     vil_image_view<vil_rgb<vxl_byte> > v = r->get_view(x,1,y,1);
328     if (!v)
329       std::sprintf(msg, "Pixel Not Available");
330     else
331       std::sprintf(msg, "(%d, %d)   (ubyte)[ R=%d,G=%d,B=%d]", x, y,
332                   v(0,0).R(), v(0,0).G(),v(0,0).B() );
333       return;
334    }
335    case VIL_PIXEL_FORMAT_RGB_UINT_16: {
336     vil_image_view<vil_rgb<vxl_uint_16> > v = r->get_view(x,1,y,1);
337     if (!v)
338       std::sprintf(msg, "Pixel Not Available");
339     else
340       std::sprintf(msg, "(%d, %d)   (uint16)[ R=%d,G=%d,B=%d]", x, y,
341                   v(0,0).R(), v(0,0).G(),v(0,0).B() );
342     return;
343    }
344 #if 0
345    case VIL_PIXEL_FORMAT_UINT_32:
346    case VIL_PIXEL_FORMAT_INT_32:
347    case VIL_PIXEL_FORMAT_RGB_SBYTE:
348    case VIL_PIXEL_FORMAT_RGB_INT_16:
349    case VIL_PIXEL_FORMAT_RGB_UINT_32:
350    case VIL_PIXEL_FORMAT_RGB_INT_32:
351    case VIL_PIXEL_FORMAT_RGB_FLOAT:
352    case VIL_PIXEL_FORMAT_RGB_DOUBLE:
353    case VIL_PIXEL_FORMAT_RGBA_UINT_32:
354    case VIL_PIXEL_FORMAT_RGBA_INT_32:
355    case VIL_PIXEL_FORMAT_RGBA_UINT_16:
356    case VIL_PIXEL_FORMAT_RGBA_INT_16:
357    case VIL_PIXEL_FORMAT_RGBA_BYTE:
358    case VIL_PIXEL_FORMAT_RGBA_SBYTE:
359    case VIL_PIXEL_FORMAT_RGBA_FLOAT:
360    case VIL_PIXEL_FORMAT_RGBA_DOUBLE:
361    case VIL_PIXEL_FORMAT_COMPLEX_FLOAT:
362    case VIL_PIXEL_FORMAT_COMPLEX_DOUBLE:
363 #endif
364    default:
365     std::sprintf(msg, "Pixel Not Available");
366   }
367 }
368 
369 double bgui_image_tableau::
get_pixel_value(const unsigned c,const unsigned r)370 get_pixel_value(const unsigned c, const unsigned r)
371 {
372   vil_image_resource_sptr rs = this->get_image_resource();
373   if (!rs)
374     return 0;
375   if (c>=rs->ni()||r>=rs->nj())
376     return 0;
377   unsigned n_p = rs->nplanes();
378   vil_pixel_format type = rs->pixel_format();
379   switch (type )
380   {
381     case VIL_PIXEL_FORMAT_BOOL: {
382       vil_image_view<bool> v = rs->get_view();
383       if (!v)
384         return 0;
385       else
386         return static_cast<double>(v(0,0));
387     }
388     case  VIL_PIXEL_FORMAT_BYTE: {
389       vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
390       if (!v)
391         return 0;
392       if (n_p==1)
393         return static_cast<double>(v(0,0));
394       else if (n_p==3)
395         return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
396     }
397     case  VIL_PIXEL_FORMAT_SBYTE: {
398       vil_image_view<vxl_sbyte> v = rs->get_view(c,1,r,1);
399       if (!v)
400         return 0;
401       else
402         if (n_p==1)
403           return static_cast<double>(v(0,0));
404         else if (n_p==3)
405           return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
406     }
407     case  VIL_PIXEL_FORMAT_UINT_16: {
408       vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
409       if (!v)
410         return 0;
411       else
412         if (n_p==1)
413           return static_cast<double>(v(0,0));
414         else if (n_p==3)
415           return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
416         else if (n_p==4)
417           return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2)+v(0,0,3))/4;
418     }
419     case  VIL_PIXEL_FORMAT_INT_16: {
420       vil_image_view<vxl_int_16> v = rs->get_view(c,1,r,1);
421       if (!v)
422         return 0;
423       else
424         if (n_p==1)
425           return static_cast<double>(v(0,0));
426         else if (n_p==3)
427           return static_cast<double>(v(0,0,0)+v(0,0,1)+v(0,0,2))/3;
428     }
429     case  VIL_PIXEL_FORMAT_FLOAT: {
430       vil_image_view<float> v = rs->get_view(c,1,r,1);
431       if (!v)
432         return 0;
433       else
434         return static_cast<double>(v(0,0));
435     }
436     case  VIL_PIXEL_FORMAT_DOUBLE: {
437       vil_image_view<double> v = rs->get_view(c,1,r,1);
438       if (!v)
439         return 0;
440       else
441         return v(0,0);
442     }
443     case VIL_PIXEL_FORMAT_RGB_BYTE: {
444       vil_image_view<vil_rgb<vxl_byte> > v = rs->get_view(c,1,r,1);
445       if (!v)
446         return 0;
447       else
448         return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
449     }
450     case VIL_PIXEL_FORMAT_RGB_UINT_16: {
451       vil_image_view<vil_rgb<vxl_uint_16> > v = rs->get_view(c,1,r,1);
452       if (!v)
453         return 0;
454       else
455         return static_cast<double>(v(0,0).R()+v(0,0).G()+v(0,0).B())/3;
456     }
457     default:
458       return 0;
459    }
460 }
461 
462 //: get the pixel value as color
get_color_pixel_value(const unsigned c,const unsigned r)463 std::vector<double> bgui_image_tableau::get_color_pixel_value(const unsigned c, const unsigned r)
464 {
465   vil_image_resource_sptr rs = this->get_image_resource();
466   if (!rs)
467     return std::vector<double>(0);
468   if (c>=rs->ni()||r>=rs->nj())
469     return std::vector<double>(0);
470   unsigned n_p = rs->nplanes();
471   std::vector<double> val(n_p, 0.0);
472   if (n_p==1)
473   {
474     val[0]=this->get_pixel_value(c, r);
475     return val;
476   }
477   //note: will treat RGBA as a four plane type
478   vil_pixel_format type = vil_pixel_format_component_format(rs->pixel_format());
479 
480   switch (type )
481   {
482     case  VIL_PIXEL_FORMAT_BYTE: {
483       vil_image_view<vxl_byte> v = rs->get_view(c,1,r,1);
484       if (!v)
485         return val;
486       for (unsigned p = 0; p<n_p; ++p)
487         val[p]=static_cast<double>(v(0,0,p));
488       return val;
489     }
490     case  VIL_PIXEL_FORMAT_UINT_16: {
491       vil_image_view<vxl_uint_16> v = rs->get_view(c,1,r,1);
492       if (!v)
493         return val;
494       for (unsigned p = 0; p<n_p; ++p)
495             val[p]=static_cast<double>(v(0,0,p));
496       return val;
497     }
498     default:
499       return val;
500   }
501 }
502 
image_line(const float col_start,const float row_start,const float col_end,const float row_end,std::vector<double> & line_pos,std::vector<double> & vals)503 void bgui_image_tableau::image_line(const float col_start,
504                                     const float row_start,
505                                     const float col_end,
506                                     const float row_end,
507                                     std::vector<double>& line_pos,
508                                     std::vector<double>& vals)
509 {
510   line_pos.clear();vals.clear();
511   vil_image_resource_sptr resc = this->get_image_resource();
512   if(!resc){
513     std::cerr <<  "null image resoure in image_line" << std::endl;
514     return;
515   }
516   size_t ni = resc->ni(), nj = resc->nj();
517   float nif = static_cast<float>(ni)-1.0f, njf = static_cast<float>(nj)-1.0f;
518   float cs = col_start, ce = col_end;
519   float rs = row_start, re = row_end;
520   // clamp line extremes to valid image range
521   if (cs < 0.0f && ce < 0.0f) {
522       std::cerr << " image line outside of image - abandon plot" << std::endl;
523       return;
524   }
525   if(cs < 0.0f) cs = 0.0f;
526   if(ce < 0.0f) ce = 0.0f;
527 
528   if(rs < 0.0f) rs = 0.0f;
529   if(re < 0.0f) re = 0.0f;
530   if (rs < 0.0f && re < 0.0f) {
531       std::cerr << " image line outside of image - abandon plot" << std::endl;
532       return;
533   }
534   if (cs > nif && ce > nif) {
535       std::cerr << " image line outside of image - abandon plot" << std::endl;
536       return;
537   }
538   if(cs > nif) cs = nif;
539   if(ce > nif) ce = nif;
540   if (rs > njf && re > njf) {
541       std::cerr << " image line outside of image - abandon plot" << std::endl;
542       return;
543   }
544   if(rs > njf) rs = njf;
545   if(re > njf) re = njf;
546 
547 
548 
549   //Get the image data
550   // the line length in pixels
551   float length = std::sqrt((ce-cs)*(ce-cs) +
552                           (re-rs)*(re-rs));
553   if (length == 0)
554     return;
555   //initialize the line scan parameters
556   float xstep = (ce-cs)/length;
557   float ystep = (re-rs)/length;
558   float sinc = std::sqrt(xstep*xstep + ystep*ystep);
559   float spos = 0;
560   line_pos.push_back(spos);
561   unsigned c = static_cast<unsigned>(cs),
562    r = static_cast<unsigned>(rs);
563   vals.push_back(get_pixel_value(c, r));
564 
565   //extract the pixel values along the line
566   float xpos = cs, ypos = rs;
567   unsigned nsteps = static_cast<unsigned>(length);
568   for (unsigned i = 0; i<nsteps; ++i)
569   {
570     xpos += xstep;
571     ypos += ystep;
572     spos += sinc;
573     c = static_cast<unsigned>(xpos);
574     r = static_cast<unsigned>(ypos);
575     line_pos.push_back(spos);
576     vals.push_back(get_pixel_value(c, r));
577   }
578 }
579 
580 //: Extract a line of pixel values return color if available
image_line(const float col_start,const float row_start,const float col_end,const float row_end,std::vector<double> & line_pos,std::vector<std::vector<double>> & vals)581 void bgui_image_tableau::image_line(const float col_start,
582                                     const float row_start,
583                                     const float col_end,
584                                     const float row_end,
585                                     std::vector<double>& line_pos,
586                                     std::vector<std::vector<double> >& vals)
587 {
588   line_pos.clear();vals.clear();
589   vil_image_resource_sptr resc = this->get_image_resource();
590   if(!resc){
591     std::cerr <<  "null image resoure in image_line" << std::endl;
592     return;
593   }
594   size_t ni = resc->ni(), nj = resc->nj();
595   float nif = static_cast<float>(ni)-1.0f, njf = static_cast<float>(nj)-1.0f;
596   float cs = col_start, ce = col_end;
597   float rs = row_start, re = row_end;
598   // clamp line extremes to valid image range
599   if (cs < 0.0f && ce < 0.0f) {
600       std::cerr << " image line outside of image - abandon plot" << std::endl;
601       return;
602   }
603   if (cs < 0.0f) cs = 0.0f;
604   if (ce < 0.0f) ce = 0.0f;
605 
606   if (rs < 0.0f) rs = 0.0f;
607   if (re < 0.0f) re = 0.0f;
608   if (rs < 0.0f && re < 0.0f) {
609       std::cerr << " image line outside of image - abandon plot" << std::endl;
610       return;
611   }
612   if (cs > nif && ce > nif) {
613       std::cerr << " image line outside of image - abandon plot" << std::endl;
614       return;
615   }
616   if (cs > nif) cs = nif;
617   if (ce > nif) ce = nif;
618   if (rs > njf && re > njf) {
619       std::cerr << " image line outside of image - abandon plot" << std::endl;
620       return;
621   }
622   if (rs > njf) rs = njf;
623   if (re > njf) re = njf;
624 
625 
626   //Get the image data
627   // the line length in pixels
628   float length = std::sqrt((ce-cs)*(ce-cs) +
629                           (re-rs)*(re-rs));
630   if (length == 0)
631     return;
632   //initialize the line scan parameters
633   float xstep = (ce-cs)/length;
634   float ystep = (re-rs)/length;
635   float sinc = std::sqrt(xstep*xstep + ystep*ystep);
636   float spos = 0;
637   line_pos.push_back(spos);
638   unsigned c = static_cast<unsigned>(cs),
639    r = static_cast<unsigned>(rs);
640   std::vector<double> cv = get_color_pixel_value(c, r);
641   unsigned n_bands = cv.size();
642   vals.resize(n_bands);
643   for (unsigned i = 0; i<n_bands; ++i)
644     vals[i].push_back(cv[i]);
645 
646   //extract the pixel values along the line
647   float xpos = cs, ypos = rs;
648   unsigned nsteps = static_cast<unsigned>(length);
649   for (unsigned i = 0; i<nsteps; ++i)
650   {
651     xpos += xstep;
652     ypos += ystep;
653     spos += sinc;
654     c = static_cast<unsigned>(xpos);
655     r = static_cast<unsigned>(ypos);
656     line_pos.push_back(spos);
657     cv = get_color_pixel_value(c, r);
658     for (unsigned i = 0; i<n_bands; ++i)
659       vals[i].push_back(cv[i]);
660   }
661 }
unset_mouse_message()662 void bgui_image_tableau::unset_mouse_message(){
663   mouse_message_ = false;
664   capture_mouse_ = false;
665   tt_->clear();
666   post_redraw();
667 }
668 
669 //--------------------------------------------------------------------------------
670 //:
671 // Handle all events for this tableau.
handle(vgui_event const & e)672 bool bgui_image_tableau::handle(vgui_event const &e)
673 {
674 #if 0
675   if(e.type != vgui_MOTION)
676     std::cout << "bgui_image " << e << '\n' << std::flush;
677 #endif
678   static bool button_down = false;
679   if (e.type == vgui_DRAW)
680   {
681     bool handled = base::handle(e);
682 
683     if(tt_) tt_->handle(e);
684 
685     return handled;
686   }
687 
688   if (e.type == vgui_BUTTON_DOWN)
689   {
690     button_down = true;
691     if (handle_motion_)
692       vgui::out << ' ' << std::endl;
693     // if the mouse message is active
694     // then store the pixel location of the mouse
695     if(e.button == vgui_LEFT && capture_mouse_){
696       vgui_projection_inspector p_insp;
697       p_insp.window_to_image_coordinates(e.wx, e.wy, mouse_pos_[0],
698                                          mouse_pos_[1]);
699     }
700   }
701   else if (e.type == vgui_BUTTON_UP)
702   {
703     button_down = false;
704     // if the mouse message is active
705     // display a single line of text (mouse_message_text_)
706     if(e.button == vgui_LEFT && mouse_message_){
707       tt_->clear();
708       tt_->set_colour(0.0f, 0.0f, 0.0f);
709       tt_->set_size(12);
710       //                                                        display banner
711       //                                                            |
712       //                                                            V
713       tt_->add(mouse_pos_[0], mouse_pos_[1], mouse_message_text_);//need to modify text-tableau
714       post_redraw();
715     }
716   }
717   else if (e.type == vgui_MOTION && handle_motion_ && !button_down)
718   {
719     // Get X,Y position to display on status bar:
720     float pointx, pointy;
721     vgui_projection_inspector p_insp;
722     p_insp.window_to_image_coordinates(e.wx, e.wy, pointx, pointy);
723     int intx = (int)std::floor(pointx), inty = (int)std::floor(pointy);
724     char msg[100];
725 
726     this->get_pixel_info_from_image(intx, inty,e, msg);
727 
728     // gets a snapshot of the viewport so that it restores it back after vgui::out
729     // this is needed, because vgui::out changes viewport, and image tableau
730     // gets confused
731     bgui_image_tableau_vp_sc_snapshot snap;
732 
733     // Display on status bar:
734     if (!locked_) {
735       if (show_path_)
736         vgui::out << msg << "  " << this->file_name() << std::endl;
737       else
738         vgui::out << msg << std::endl;
739     }
740   }
741   return base::handle(e);
742 }
743 
744 //--------------------------------------------------------------------------------
745