Orfeo Toolbox  3.16
otbImageWidgetBase.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbImageWidgetBase_txx
19 #define __otbImageWidgetBase_txx
20 
21 #include "otbConfigure.h"
23 
24 #include "otbMacro.h"
25 
26 namespace otb
27 {
31 template <class TPixel>
34  : Fl_Gl_Window(0, 0, 0, 0, 0)
35 {
36  m_Image = NULL;
37  m_OpenGlIsotropicZoom = 1.0;
38  SizeType size;
39  size.Fill(0);
40  IndexType index;
41  index.Fill(0);
42  RegionType region;
43  region.SetSize(size);
44  region.SetIndex(index);
45  m_BufferedRegion = region;
46  m_ViewedRegion = region;
47  m_ViewModel = RGB;
48  m_RedChannelIndex = 0;
49  m_GreenChannelIndex = 1;
50  m_BlueChannelIndex = 2;
51  m_OpenGlBuffer = NULL;
52  m_FormOverlayVisible = false;
53  m_ImageOverlayVisible = false;
54  m_BlackTransparency = false;
55  m_FormList = FormListType::New();
56  m_ImageOverlay = NULL;
57  m_OpenGlImageOverlayBuffer = NULL;
58  m_ImageOverlayOpacity = 128;
59  m_TransferFunctionList = TransferFunctionListType::New();
60  m_TransferFunctionList->PushBack(AffineTransferFunctionType::New());
61  m_SubSamplingRate = 1;
62 }
66 template <class TPixel>
69 {
70  if (m_OpenGlBuffer != NULL)
71  {
72  delete[] m_OpenGlBuffer;
73  }
74  if (m_OpenGlImageOverlayBuffer != NULL)
75  {
76  delete[] m_OpenGlImageOverlayBuffer;
77  }
78 }
82 template <class TPixel>
83 void
85 ::Reset(void)
86 {
87  int x = this->x();
88  int y = this->y();
89  int w = this->w();
90  int h = this->h();
91  const char * label = this->label();
92  ClearBufferedRegion();
93  Init(x, y, w, h, label);
94 }
95 
96 template <class TPixel>
97 void
100 {
101  SizeType size;
102  size.Fill(0);
103  m_BufferedRegion.SetSize(size);
104 }
105 
106 template <class TPixel>
107 void
109 ::Init(int /*x*/, int /*y*/, int /*w*/, int /*h*/, const char * /*l*/)
110 {
111  for (unsigned int i = 0; i < m_Image->GetNumberOfComponentsPerPixel(); ++i)
112  {
113  if (i >= m_TransferFunctionList->Size())
114  {
115  m_TransferFunctionList->PushBack(AffineTransferFunctionType::New());
116  }
117  }
118 
119 }
120 
126 template <class TPixel>
128 ::IndexType
131 {
132  double x, y;
133  IndexType resp;
134  IndexType origin = this->GetViewedRegion().GetIndex();
135  x = static_cast<double>(index[0]) / m_OpenGlIsotropicZoom
136  + static_cast<double>(origin[0]);
137  y = static_cast<double>(origin[1])
138  + static_cast<double>(index[1]) / m_OpenGlIsotropicZoom;
139 
140  SizeType maxSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
141  IndexType maxIndex = this->GetInput()->GetLargestPossibleRegion().GetIndex();
142 
143  if (x < maxIndex[0])
144  {
145  resp[0] = maxIndex[0];
146  }
147  else if (x > maxIndex[0] + maxSize[0])
148  {
149  resp[0] = maxIndex[0] + maxSize[0];
150  }
151  else
152  {
153  resp[0] = static_cast<int>(x);
154  }
155 
156  if (y < maxIndex[1])
157  {
158  resp[1] = maxIndex[1];
159 
160  }
161  else if (y > maxIndex[1] + maxSize[1])
162  {
163  resp[1] = maxIndex[1] + maxSize[1];
164  }
165  else
166  {
167  resp[1] = static_cast<int>(y);
168  }
169  return resp;
170 }
171 
175 template <class TPixel>
176 void
179 {
180  m_Image = image;
181  m_Image->UpdateOutputInformation();
182  SizeType size;
183  size.Fill(0);
184  m_BufferedRegion.SetSize(size);
185  SizeType displaySize;
186  displaySize[0] = this->w();
187  displaySize[1] = this->h();
188  m_ViewedRegion.SetSize(displaySize);
189  m_ViewedRegion.Crop(m_Image->GetLargestPossibleRegion());
190 }
194 template <class TPixel>
196 ::ImageType *
199 {
200  return m_Image;
201 }
202 
206 template <class TPixel>
207 void
210 {
211  m_ImageOverlay = image;
212 }
213 
217 template <class TPixel>
218 void
221 {
222  m_FormList = formList;
223 }
224 
228 template <class TPixel>
229 void
232 {
233  m_TransferFunctionList = list;
234 }
235 
239 template <class TPixel>
241 ::OverlayImageType *
244 {
245  return m_ImageOverlay;
246 }
247 
251 template <class TPixel>
252 void
254 ::Show(void)
255 {
256  if (!m_Image)
257  {
258  itkExceptionMacro(<< "No input image !");
259  }
260  else
261  {
262  //otbMsgDebugMacro(<<"Zoomable widget Show");
263  this->show();
264  //otbMsgDebugMacro(<<"Before redraw.");
265  this->redraw();
266  //otbMsgDebugMacro(<<"After redraw.");
267  }
268 }
269 
270 template <class TPixel>
271 unsigned char
273 ::Normalize(PixelType value, unsigned int channelIndex)
274 {
275  return m_TransferFunctionList->GetNthElement(channelIndex)->Map(value);
276 }
277 
281 template <class TPixel>
282 void
284 ::draw(void)
285 {
286 
287  // otbMsgDebugMacro(<<"Draw");
288 
289  if (this->UpdateOpenGlBufferedRegionRequested())
290  {
291  UpdateOpenGlBufferedRegion();
292  m_Image->SetRequestedRegion(m_BufferedRegion);
293  m_Image->PropagateRequestedRegion();
294  m_Image->UpdateOutputData();
295  RebuildOpenGlBuffer();
296  if (m_ImageOverlayVisible)
297  {
298  m_ImageOverlay->SetRequestedRegion(m_BufferedRegion);
299  m_ImageOverlay->PropagateRequestedRegion();
300  m_ImageOverlay->UpdateOutputData();
301  }
302  }
303 
304  if (m_ImageOverlayVisible)
305  {
306  RebuildOpenGlImageOverlayBuffer();
307  }
308 
309  if (!this->valid())
310  {
311  valid(1);
312  glLoadIdentity();
313  glViewport(0, 0, w(), h());
314  glClearColor((float) 0.0, (float) 0.0, (float) 0.0, (float) 0.0);
315  glShadeModel(GL_FLAT);
316  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
317  }
318 
319  glClear(GL_COLOR_BUFFER_BIT); //this clears and paints to black
320  glMatrixMode(GL_MODELVIEW); //clear previous 3D draw params
321  glLoadIdentity();
322  glMatrixMode(GL_PROJECTION);
323  this->ortho();
324  glDisable(GL_BLEND);
325 
326  // To be consistent with old method
327  int displayHeight = static_cast<int>(vcl_ceil(m_BufferedRegion.GetSize()[1] * m_OpenGlIsotropicZoom));
328  int viewPortOffset = 0;
329  viewPortOffset = h() - displayHeight;
330  glRasterPos2i(0, viewPortOffset);
331 
332  glPixelZoom(m_OpenGlIsotropicZoom, m_OpenGlIsotropicZoom);
333 
334  // display the image
335  glDrawPixels(m_BufferedRegion.GetSize()[0],
336  m_BufferedRegion.GetSize()[1],
337  GL_RGBA,
338  GL_UNSIGNED_BYTE,
339  m_OpenGlBuffer);
340 
341 
342 #if 0
343 /* This code use Texture to draw raster (OTB_GL_USE_ACCEL) */
344 
345  glEnable(GL_TEXTURE_2D);
346  glColor4f(1.0, 1.0, 1.0, 0.0);
347  GLuint texture;
348  glGenTextures(1, &texture);
349  glBindTexture(GL_TEXTURE_2D, texture);
350  glTexImage2D(GL_TEXTURE_2D, 0, 3, m_BufferedRegion.GetSize()[0],
351  m_BufferedRegion.GetSize()[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, m_OpenGlBuffer);
352  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
353  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
354  // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
355  // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
356 
357  glBindTexture (GL_TEXTURE_2D, texture);
358  glBegin (GL_QUADS);
359  int hOffset = this->h() - this->hDisplayed();
360  glTexCoord2f (0.0, 1.0);
361  glVertex3f (0.0, 0.0 + hOffset, 0.0);
362  glTexCoord2f (1.0, 1.0);
363  glVertex3f (this->wDisplayed(), 0.0 + hOffset, 0.0);
364  glTexCoord2f (1.0, 0.0);
365  glVertex3f (this->wDisplayed(), this->hDisplayed() + hOffset, 0.0);
366  glTexCoord2f (0.0, 0.0);
367  glVertex3f (0.0, this->hDisplayed() + hOffset, 0.0);
368  glEnd ();
369 
370  glDisable(GL_TEXTURE_2D);
371 #endif
372 
373  // if image overlay is activated, display image overlay
374  if (m_ImageOverlayVisible)
375  {
376  glEnable(GL_BLEND);
377  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
378  glDrawPixels(m_BufferedRegion.GetSize()[0],
379  m_BufferedRegion.GetSize()[1],
380  GL_RGBA,
381  GL_UNSIGNED_BYTE,
382  m_OpenGlImageOverlayBuffer);
383 
384  glDisable(GL_BLEND);
385  glEnd();
386 
387 #if 0
388  /* This code use Texture to draw raster (OTB_GL_USE_ACCEL) */
389  glEnable(GL_BLEND);
390  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
391  glEnable(GL_TEXTURE_2D);
392  glColor4f(1.0, 1.0, 1.0, 1.0);
393  GLuint textureOverlay;
394  glGenTextures(1, &textureOverlay);
395  glBindTexture(GL_TEXTURE_2D, textureOverlay);
396  glTexImage2D(GL_TEXTURE_2D, 0, 4, m_BufferedRegion.GetSize()[0],
397  m_BufferedRegion.GetSize()[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, m_OpenGlImageOverlayBuffer);
398  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Nearest Filtering
399  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Nearest Filtering
400 
401  glBindTexture (GL_TEXTURE_2D, textureOverlay);
402  glBegin (GL_QUADS);
403  int hOffset = this->h() - this->hDisplayed();
404  glTexCoord2f (0.0, 1.0);
405  glVertex3f (0.0, 0.0 + hOffset, 1.0);
406  glTexCoord2f (1.0, 1.0);
407  glVertex3f (this->wDisplayed(), 0.0 + hOffset, 1.0);
408  glTexCoord2f (1.0, 0.0);
409  glVertex3f (this->wDisplayed(), this->hDisplayed() + hOffset, 1.0);
410  glTexCoord2f (0.0, 0.0);
411  glVertex3f (0.0, this->hDisplayed() + hOffset, 1.0);
412  glEnd ();
413  glDisable(GL_TEXTURE_2D);
414  glDisable(GL_BLEND);
415 #endif
416 
417  }
418 
419  if (m_FormOverlayVisible)
420  {
421  ReverseIteratorType it = m_FormList->ReverseBegin();
422  //otbMsgDebugMacro(<<"Formlist size: "<<m_FormList->Size());
423  for (; it != m_FormList->ReverseEnd(); ++it)
424  {
425  it.Get()->Draw(m_OpenGlIsotropicZoom,
426  m_ViewedRegion.GetIndex()[0],
427  m_ViewedRegion.GetIndex()[1],
428  this->h(), m_SubSamplingRate);
429  }
430  }
431 
432 }
433 
437 template <class TPixel>
438 void
441 {
442  // Channel indices outofbound check
443  if (m_RedChannelIndex >= m_Image->GetNumberOfComponentsPerPixel())
444  {
445  itkExceptionMacro(<< "Red channel index out of bound.");
446  }
447  if (m_ViewModel != GRAYSCALE && m_GreenChannelIndex >= m_Image->GetNumberOfComponentsPerPixel())
448  {
449  itkExceptionMacro(<< "Green channel index out of bound.");
450  }
451  if (m_ViewModel == RGB && m_BlueChannelIndex >= m_Image->GetNumberOfComponentsPerPixel())
452  {
453  itkExceptionMacro(<< "Blue channel index out of bound.");
454  }
455 
456  //otbMsgDebugMacro(<<"RebuildOpenGlBuffer");
457  if (m_OpenGlBuffer != NULL)
458  {
459  //otbMsgDebugMacro(<<"Deleting previous buffer ...");
460  delete[] m_OpenGlBuffer;
461  }
462  //otbMsgDebugMacro(<<"Buffered region: "<<m_BufferedRegion);
463  unsigned int bufferLength = 4 * m_BufferedRegion.GetNumberOfPixels();
464  //otbMsgDebugMacro(<<"New buffer length: "<<bufferLength);
465  m_OpenGlBuffer = new unsigned char[bufferLength];
466 
468  IteratorType it(m_Image, m_BufferedRegion);
469  unsigned int index = 0;
470  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
471  {
472  index = GetRevertedBufferIndex(it.GetIndex());
473 #if 0
474  /* OTB_GL_USE_ACCEL */
475  index = GetBufferIndex(it.GetIndex());
476 #endif
477 
478  switch (m_ViewModel)
479  {
480  case RGB:
481  {
482  m_OpenGlBuffer[index] = Normalize(it.Get()[m_RedChannelIndex], m_RedChannelIndex);
483  m_OpenGlBuffer[index + 1] = Normalize(it.Get()[m_GreenChannelIndex], m_GreenChannelIndex);
484  m_OpenGlBuffer[index + 2] = Normalize(it.Get()[m_BlueChannelIndex], m_BlueChannelIndex);
485  m_OpenGlBuffer[index + 3] = 255;
486  break;
487  }
488  case GRAYSCALE:
489  {
490  unsigned char gray = Normalize(it.Get()[m_RedChannelIndex], m_RedChannelIndex);
491  m_OpenGlBuffer[index] = gray;
492  m_OpenGlBuffer[index + 1] = gray;
493  m_OpenGlBuffer[index + 2] = gray;
494  m_OpenGlBuffer[index + 3] = 255;
495  break;
496  }
497  case COMPLEX_MODULUS:
498  {
499  double re = static_cast<double>(it.Get()[m_RedChannelIndex]);
500  double im = static_cast<double>(it.Get()[m_GreenChannelIndex]);
501  // std::cout << " *** " << m_RedChannelIndex << " " << m_GreenChannelIndex << std::endl;
502  unsigned char modulus = Normalize(static_cast<PixelType>(vcl_sqrt(static_cast<double>(im * im + re * re))), 0);
503  // std::cout << " ** " << im << " " << re << " -> " << static_cast<int>(modulus) << std::endl;
504  m_OpenGlBuffer[index] = modulus;
505  m_OpenGlBuffer[index + 1] = modulus;
506  m_OpenGlBuffer[index + 2] = modulus;
507  m_OpenGlBuffer[index + 3] = 255;
508  break;
509  }
510  case COMPLEX_PHASE:
511  {
512  unsigned char phase =
513  Normalize(static_cast<PixelType>(vcl_atan2(static_cast<double>(it.Get()[m_GreenChannelIndex]),
514  static_cast<double>(it.Get()[m_RedChannelIndex]))), 0);
515  m_OpenGlBuffer[index] = phase;
516  m_OpenGlBuffer[index + 1] = phase;
517  m_OpenGlBuffer[index + 2] = phase;
518  m_OpenGlBuffer[index + 3] = 255;
519  break;
520  }
521  }
522  }
523 }
527 template <class TPixel>
528 void
531 {
532  if (m_ImageOverlay->GetNumberOfComponentsPerPixel() < 3)
533  {
534  itkExceptionMacro(<< "Image overlay should have at least 3 channels.");
535  }
536 
537  //otbMsgDebugMacro(<<"RebuildOpenGlImageOverlayBuffer");
538  if (m_OpenGlImageOverlayBuffer != NULL)
539  {
540  //otbMsgDebugMacro(<<"Deleting previous buffer ...");
541  delete[] m_OpenGlImageOverlayBuffer;
542  }
543  //otbMsgDebugMacro(<<"Buffered region: "<<m_BufferedRegion);
544  unsigned int bufferLength = 4 * m_BufferedRegion.GetNumberOfPixels();
545  //otbMsgDebugMacro(<<"New buffer length: "<<bufferLength);
546  m_OpenGlImageOverlayBuffer = new unsigned char[bufferLength];
547 
549  IteratorType it(m_ImageOverlay, m_BufferedRegion);
550  unsigned int index = 0;
551  if (m_BlackTransparency)
552  {
553  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
554  {
555  index = GetRevertedBufferIndex(it.GetIndex());
556 #if 0
557  /* OTB_GL_USE_ACCEL */
558  index = GetBufferIndex(it.GetIndex());
559 #endif
560  if ((it.Get()[0] == 0) && (it.Get()[1] == 0) && (it.Get()[2] == 0))
561  {
562  m_OpenGlImageOverlayBuffer[index] = 0;
563  m_OpenGlImageOverlayBuffer[index + 1] = 0;
564  m_OpenGlImageOverlayBuffer[index + 2] = 0;
565  m_OpenGlImageOverlayBuffer[index + 3] = 0;
566  }
567  else
568  {
569  m_OpenGlImageOverlayBuffer[index] = static_cast<unsigned char>(it.Get()[0]);
570  m_OpenGlImageOverlayBuffer[index + 1] = static_cast<unsigned char>(it.Get()[1]);
571  m_OpenGlImageOverlayBuffer[index + 2] = static_cast<unsigned char>(it.Get()[2]);
572  m_OpenGlImageOverlayBuffer[index + 3] = m_ImageOverlayOpacity;
573  }
574  }
575  }
576  else
577  {
578  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
579  {
580  index = GetRevertedBufferIndex(it.GetIndex());
581 #if 0
582  /* OTB_GL_USE_ACCEL */
583  index = GetBufferIndex(it.GetIndex());
584 #endif
585  m_OpenGlImageOverlayBuffer[index] = static_cast<unsigned char>(it.Get()[0]);
586  m_OpenGlImageOverlayBuffer[index + 1] = static_cast<unsigned char>(it.Get()[1]);
587  m_OpenGlImageOverlayBuffer[index + 2] = static_cast<unsigned char>(it.Get()[2]);
588  m_OpenGlImageOverlayBuffer[index + 3] = m_ImageOverlayOpacity;
589  }
590  }
591 }
592 } // end namespace otb
593 #endif

Generated at Sun Feb 3 2013 00:31:22 for Orfeo Toolbox with doxygen 1.8.1.1