Orfeo Toolbox  3.16
otbImageAlternateViewer.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 __otbImageAlternateViewer_txx
19 #define __otbImageAlternateViewer_txx
20 
22 #include <FL/fl_draw.H>
23 #include <FL/Fl.H>
24 #include "otbMath.h"
25 #include "itkTimeProbe.h"
26 #include "itkMacro.h"
27 
28 namespace otb
29 {
33 template <class TPixel>
36  : Fl_Gl_Window(0, 0, 0, 0, 0)
37 {
38  m_Image = NULL;
39  m_OpenGlIsotropicZoom = 1.0;
40  m_OpenGlBuffer = NULL;
41  m_ViewModelIsRGB = true;
42  m_InsightViewModelIsRGB = true;
43  m_RedChannelIndex = 0;
44  m_GreenChannelIndex = 1;
45  m_BlueChannelIndex = 2;
46 
47  m_MinComponentValues.SetSize(1);
48  m_MaxComponentValues.SetSize(1);
49  m_MinComponentValues.Fill(0);
50  m_MaxComponentValues.Fill(255);
51 
52  m_DecompositionFilter = VectorImageDecompositionFilterType::New();
53 
54  typename DefaultInterpolatorType::Pointer defaultInterpolator = DefaultInterpolatorType::New();
55  m_ZoomInInterpolator = defaultInterpolator;
56  m_ZoomOutInterpolator = defaultInterpolator;
57 
58  m_SpacingZoomFactor = 1;
59  m_Updating = false;
60  m_Drag = false;
61  m_DragEventCounter = 0;
62  m_OldMousePos.Fill(0);
63  m_ZoomState = 0;
64  m_SubWindowMode = false;
65 }
66 
70 template <class TPixel>
73 {
74  if (m_OpenGlBuffer != NULL)
75  {
76  delete[] m_OpenGlBuffer;
77  }
78 }
79 
80 template <class TPixel>
81 void
84 {
85  m_OldViewedRegionCenter = m_ViewedRegionCenter;
86  m_ViewedRegionCenter = index;
87 }
88 
92 template <class TPixel>
93 void
95 ::Reset(void)
96 {
97  const char * label = this->label();
98  Init(this->x(), this->y(), this->w(), this->h(), label);
99 }
100 
101 template <class TPixel>
102 void
104 ::Init(int x, int y, int w, int h, const char * l)
105 {
106  IndexType index;
107  SizeType size;
108 
109  index[0] = 0;
110  index[1] = 0;
111  size[0] = w;
112  size[1] = h;
113 
114  SizeType nullSize;
115  nullSize.Fill(0);
116 
117  m_RequestedRegion.SetSize(nullSize);
118  m_RequestedRegion.SetIndex(index);
119  m_BufferedRegion = m_RequestedRegion;
120  m_OldBufferedRegion = m_BufferedRegion;
121 
122  RegionType newRegion;
123  m_DisplayExtent.SetIndex(index);
124  m_DisplayExtent.SetSize(size);
125  m_OldDisplayExtent = m_DisplayExtent;
126 
127  m_OldSpacingZoomFactor = m_SpacingZoomFactor;
128 
129  m_Splitter = SplitterType::New();
130 
131  m_SubWindowRegion.SetIndex(index);
132  m_SubWindowRegion.SetSize(nullSize);
133 
134  m_Image->UpdateOutputInformation();
135  m_DecompositionFilter->SetInput(m_Image);
136  m_OldViewedRegionCenter = m_ViewedRegionCenter;
137 
138  typename ImageListType::Pointer bandList = m_DecompositionFilter->GetOutput();
139  bandList->UpdateOutputInformation();
140  bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion);
141 
142  if (m_ViewModelIsRGB)
143  {
144  bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion);
145  bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion);
146  }
147  bandList->PropagateRequestedRegion();
148 
149  if (!this->GetImage())
150  {
151  itkExceptionMacro("No input image!");
152  }
153  this->label(l);
154  this->resize(x,
155  y,
156  m_DisplayExtent.GetSize()[0],
157  m_DisplayExtent.GetSize()[1]);
158 }
159 template <class TPixel>
160 void
162 ::resize(int x, int y, int w, int h)
163 {
164  if (m_Updating) return;
165  // avoid odd sizes
166  if (w % 2 == 1) w += 1;
167  if (h % 2 == 1) h += 1;
168 
169  IndexType index;
170  SizeType size;
171  m_OldDisplayExtent = m_DisplayExtent;
172  index[0] = 0;
173  index[1] = 0;
174  size[0] = w;
175  size[1] = h;
176 
177  m_DisplayExtent.SetIndex(index);
178  m_DisplayExtent.SetSize(size);
179 
180  this->Fl_Gl_Window::resize(x, y, w, h);
181  this->redraw();
182 }
186 template <class TPixel>
187 void
190 {
191  m_ViewModelIsRGB = true;
192 }
196 template <class TPixel>
197 void
200 {
201  m_ViewModelIsRGB = false;
202 }
203 
207 template <class TPixel>
208 void
211 {
212  m_InsightViewModelIsRGB = true;
213 }
217 template <class TPixel>
218 void
221 {
222  m_InsightViewModelIsRGB = false;
223 }
224 
228 template <class TPixel>
229 void
231 ::Show(void)
232 {
233  if (!m_Image)
234  {
235  itkExceptionMacro(<< "No input image !");
236  }
237  else
238  {
239  this->show();
240  this->redraw();
241  }
242 }
243 
247 template <class TPixel>
248 void
250 ::draw(void)
251 {
252  if (!m_Updating)
253  {
254  m_Updating = true;
255  IncrementalOpenGlBufferUpdate();
256  ResetOpenGlContext();
257  this->Draw(m_OpenGlBuffer, m_BufferedRegion);
258 
259  if (!m_Drag)
260  {
261  AdditionalRedraw();
262  }
263  m_Updating = false;
264  }
265 }
266 
267 template <class TPixel>
268 void
271 {
272  std::vector<unsigned char *> bufferList;
273  std::vector<RegionType> bufferRegionList;
274 
275  if (m_BufferedRegion != m_DisplayExtent)
276  {
277  for (unsigned int i = 0; i < 8; ++i)
278  {
279  RegionType additionalBufferRegion = GetAdditionalBufferRegion(i);
280  unsigned char * additionalBuffer = CreateAdditionalBuffer(additionalBufferRegion, m_Image, m_ViewModelIsRGB);
281  this->Draw(additionalBuffer, additionalBufferRegion);
282  bufferList.push_back(additionalBuffer);
283  bufferRegionList.push_back(additionalBufferRegion);
284  }
285  DecorationRedraw();
286  MergeBuffersAndFreeMemory(bufferList, bufferRegionList);
287  }
288  if (m_SubWindowMode)
289  {
290  unsigned char * subWindowBuffer = CreateAdditionalBuffer(m_SubWindowRegion, m_SecondImage, m_InsightViewModelIsRGB);
291  this->Draw(subWindowBuffer, m_SubWindowRegion);
292  delete[] subWindowBuffer;
293  }
294  DecorationRedraw();
295 }
296 
297 template <class TPixel>
298 void
301 {
302  if (m_SubWindowMode)
303  {
304  this->DrawRegionBoundary(m_SubWindowRegion);
305  }
306  swap_buffers();
307  glFlush();
308 }
309 
310 template <class TPixel>
311 long
313 ::IndexInOldGrid(PointType point, PointType oldUpperLeft, SpacingType spacing, SizeType size)
314 {
315  long resp;
316  double x = (point[0] - oldUpperLeft[0]) / spacing[0];
317  double y = (point[1] - oldUpperLeft[1]) / spacing[1];
318 
319  if ((vcl_floor(x) != x) || (vcl_floor(y) != y))
320  {
321  resp = -1;
322  }
323  else if (x < 0 || x > size[0] || y<0 || y> size[1])
324  {
325  resp = -1;
326  }
327  else
328  {
329  resp = 3 * (static_cast<long>(y) * size[0] + static_cast<long>(x));
330  }
331 
332  return resp;
333 }
334 
335 template <class TPixel>
336 void
339 {
340  IndexType focusOffset;
341  focusOffset[0] = static_cast<long>(static_cast<double>(
342  m_ViewedRegionCenter[0] - m_OldViewedRegionCenter[0]) / m_SpacingZoomFactor);
343  focusOffset[1] = static_cast<long>(static_cast<double>(
344  m_ViewedRegionCenter[1] - m_OldViewedRegionCenter[1]) / m_SpacingZoomFactor);
345 
346  IndexType newBufferedRegionIndex;
347 
348  SizeType newBufferedRegionSize;
349 
350  newBufferedRegionSize[0] =
351  static_cast<unsigned long>(static_cast<double>((m_BufferedRegion.GetSize()[0]) * m_OldSpacingZoomFactor /
352  m_SpacingZoomFactor));
353  newBufferedRegionSize[1] =
354  static_cast<unsigned long>(static_cast<double>((m_BufferedRegion.GetSize()[1]) * m_OldSpacingZoomFactor /
355  m_SpacingZoomFactor));
356 
357  m_OldBufferedRegion = m_BufferedRegion;
358 
359  m_BufferedRegion.SetSize(newBufferedRegionSize);
360 
361  newBufferedRegionIndex[0] = (static_cast<long>(m_DisplayExtent.GetSize()[0])
362  - static_cast<long>(m_BufferedRegion.GetSize()[0])) / 2;
363  newBufferedRegionIndex[1] = (static_cast<long>(m_DisplayExtent.GetSize()[1])
364  - static_cast<long>(m_BufferedRegion.GetSize()[1])) / 2;
365  newBufferedRegionIndex[0] -= focusOffset[0];
366  newBufferedRegionIndex[1] -= focusOffset[1];
367  m_BufferedRegion.SetIndex(newBufferedRegionIndex);
368 
369  PointType center;
370  m_Image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter, center);
371 
372  if (m_SpacingZoomFactor != m_OldSpacingZoomFactor)
373  {
374  m_BufferedRegion.Crop(m_DisplayExtent);
375 
376  SpacingType spacing = m_Image->GetSpacing() * m_SpacingZoomFactor;
377  SpacingType oldSpacing = m_Image->GetSpacing() * m_OldSpacingZoomFactor;
378 
379  PointType origin;
380  origin[0] = center[0] - (static_cast<double>(this->m_DisplayExtent.GetSize()[0]) / 2 - 1) * spacing[0];
381  origin[1] = center[1] - (static_cast<double>(this->m_DisplayExtent.GetSize()[1]) / 2 - 1) * spacing[1];
382 
383  PointType oldOrigin;
384  oldOrigin[0] = center[0] - (static_cast<double>(this->m_DisplayExtent.GetSize()[0]) / 2 - 1) * oldSpacing[0];
385  oldOrigin[1] = center[1] - (static_cast<double>(this->m_DisplayExtent.GetSize()[1]) / 2 - 1) * oldSpacing[1];
386 
387  PointType oldBufferedUpperLeft;
388  oldBufferedUpperLeft[0] = oldOrigin[0] + static_cast<double>(m_OldBufferedRegion.GetIndex()[0]) * oldSpacing[0];
389  oldBufferedUpperLeft[1] = oldOrigin[1] + static_cast<double>(m_OldBufferedRegion.GetIndex()[1]) * oldSpacing[1];
390 
391  PointType bufferedUpperLeft;
392  bufferedUpperLeft[0] = origin[0] + static_cast<double>(m_BufferedRegion.GetIndex()[0]) * spacing[0];
393  bufferedUpperLeft[1] = origin[1] + static_cast<double>(m_BufferedRegion.GetIndex()[1]) * spacing[1];
394 
395  unsigned char * newBuffer = NULL;
396  unsigned int bufferLength = 3 * m_BufferedRegion.GetSize()[0] * m_BufferedRegion.GetSize()[1];
397 
398  newBuffer = new unsigned char[bufferLength];
399  typename ImageListType::Pointer bandList;
400  unsigned int index = 0;
401  PixelType interpolatedValue = 0;
402  PointType interpolatedPos;
403  interpolatedPos.Fill(0);
404  unsigned int numberOfSplits = 1;
405 
406  unsigned int optiCount = 0;
407  InterpolatorPointerType interpolator;
408  if (m_SpacingZoomFactor > 1)
409  {
410  numberOfSplits =
411  std::max((static_cast<unsigned int>(m_SpacingZoomFactor)) * (static_cast<unsigned int>(m_SpacingZoomFactor)), 1U);
412  interpolator = m_ZoomOutInterpolator;
413  }
414  else
415  {
416  interpolator = m_ZoomInInterpolator;
417  }
418 
419  unsigned int splitterNumberOfSplits = m_Splitter->GetNumberOfSplits(m_BufferedRegion, numberOfSplits);
420 
421  for (unsigned int splitIndex = 0; splitIndex < splitterNumberOfSplits; ++splitIndex)
422  {
423  RegionType splitRegion = m_Splitter->GetSplit(splitIndex, splitterNumberOfSplits, m_BufferedRegion);
424  m_RequestedRegion = ComputeRequestedRegion(splitRegion);
425  if (!m_RequestedRegion.Crop(m_Image->GetLargestPossibleRegion()))
426  {
427  SizeType nullSize;
428  nullSize.Fill(0);
429  IndexType nullIndex;
430  nullIndex.Fill(0);
431  m_RequestedRegion.SetSize(nullSize);
432  m_RequestedRegion.SetIndex(nullIndex);
433  }
434  m_DecompositionFilter = VectorImageDecompositionFilterType::New();
435  m_DecompositionFilter->SetInput(m_Image);
436  bandList = m_DecompositionFilter->GetOutput();
437  bandList->UpdateOutputInformation();
438  bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion);
439  if (m_ViewModelIsRGB)
440  {
441  bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion);
442  bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion);
443  }
444  bandList->PropagateRequestedRegion();
445  bandList->UpdateOutputData();
446 
447  PointType upperLeft;
448  upperLeft[0] = origin[0] + static_cast<double>(splitRegion.GetIndex()[0]) * spacing[0];
449  upperLeft[1] = origin[1] + static_cast<double>(splitRegion.GetIndex()[1]) * spacing[1];
450 
451  interpolatedPos[1] = upperLeft[1];
452  for (unsigned int j = 0; j < splitRegion.GetSize()[1]; ++j)
453  {
454  interpolatedPos[0] = upperLeft[0];
455  for (unsigned int i = 0; i < splitRegion.GetSize()[0]; ++i)
456  {
457 
458  long indexInOldBuffer = IndexInOldGrid(interpolatedPos,
459  oldBufferedUpperLeft,
460  oldSpacing,
461  m_OldBufferedRegion.GetSize());
462  if (indexInOldBuffer > 0)
463  {
464  newBuffer[index] = m_OpenGlBuffer[indexInOldBuffer];
465  newBuffer[index + 1] = m_OpenGlBuffer[indexInOldBuffer + 1];
466  newBuffer[index + 2] = m_OpenGlBuffer[indexInOldBuffer + 2];
467  index += 3;
468  optiCount++;
469  }
470  else
471  {
472  interpolator->SetInputImage(bandList->GetNthElement(m_RedChannelIndex));
473  if (interpolator->IsInsideBuffer(interpolatedPos))
474  {
475  interpolatedValue = static_cast<PixelType>(m_ZoomInInterpolator->Evaluate(interpolatedPos));
476  }
477  else
478  {
479  interpolatedValue = 0;
480  }
481  newBuffer[index] = Normalize(interpolatedValue, m_RedChannelIndex);
482  if (m_ViewModelIsRGB)
483  {
484  m_ZoomInInterpolator->SetInputImage(bandList->GetNthElement(m_GreenChannelIndex));
485  if (m_ZoomInInterpolator->IsInsideBuffer(interpolatedPos))
486  {
487  interpolatedValue = static_cast<PixelType>(interpolator->Evaluate(interpolatedPos));
488  }
489  else
490  {
491  interpolatedValue = 0;
492  }
493  newBuffer[index + 1] = Normalize(interpolatedValue, m_GreenChannelIndex);
494  interpolator->SetInputImage(bandList->GetNthElement(m_BlueChannelIndex));
495  if (interpolator->IsInsideBuffer(interpolatedPos))
496  {
497  interpolatedValue = static_cast<PixelType>(interpolator->Evaluate(interpolatedPos));
498  }
499  else
500  {
501  interpolatedValue = 0;
502  }
503  newBuffer[index + 2] = Normalize(interpolatedValue, m_BlueChannelIndex);
504  index += 3;
505  }
506  else
507  {
508  newBuffer[index + 1] = Normalize(interpolatedValue, m_RedChannelIndex);
509  newBuffer[index + 2] = Normalize(interpolatedValue, m_RedChannelIndex);
510  index += 3;
511  }
512  }
513  interpolatedPos[0] += spacing[0];
514  }
515  interpolatedPos[1] += spacing[1];
516  }
517  }
518  if (m_OpenGlBuffer != NULL)
519  {
520  delete[] m_OpenGlBuffer;
521  }
522  m_OpenGlBuffer = newBuffer;
523 
524  m_OldSpacingZoomFactor = m_SpacingZoomFactor;
525  }
526 }
527 
528 template <class TPixel>
530 ::RegionType
532 ::GetAdditionalBufferRegion(unsigned int part)
533 {
534  RegionType region;
535  SizeType size;
536  IndexType index;
537 
538  size.Fill(0);
539  index.Fill(0);
540 
541  SizeType deSize = m_DisplayExtent.GetSize();
542  IndexType deUL = m_DisplayExtent.GetIndex();
543  IndexType deLR;
544  deLR[0] = deSize[0] + deUL[0];
545  deLR[1] = deSize[1] + deUL[1];
546 
547  SizeType bufSize = m_BufferedRegion.GetSize();
548  IndexType bufUL = m_BufferedRegion.GetIndex();
549  IndexType bufLR;
550  bufLR[0] = bufUL[0] + bufSize[0];
551  bufLR[1] = bufUL[1] + bufSize[1];
552 
553  switch (part)
554  {
555  case 0:
556  index = deUL;
557  size[0] = std::max(bufUL[0] - deUL[0], 0L);
558  size[1] = std::max(bufUL[1] - deUL[1], 0L);
559  break;
560 
561  case 1:
562  index[0] = std::max(deUL[0], bufUL[0]);
563  index[1] = deUL[1];
564  size[0] = std::min(bufLR[0] - std::max(bufUL[0], 0L), deLR[0] - index[0]);
565  size[1] = std::max(bufUL[1] - deUL[1], 0L);
566  break;
567 
568  case 2:
569  index[0] = std::min(bufLR[0], deLR[0]);
570  index[1] = deUL[1];
571  size[0] = std::max(deLR[0] - bufLR[0], 0L);
572  size[1] = std::max(bufUL[1] - deUL[1], 0L);
573  break;
574 
575  case 3:
576  index[0] = deUL[0];
577  index[1] = std::max(bufUL[1], 0L);
578  size[0] = std::max(bufUL[0] - deUL[0], 0L);
579  size[1] = std::min(bufLR[1] - std::max(bufUL[1], 0L), deLR[1] - index[1]);
580  break;
581 
582  case 4:
583  index[0] = std::min(bufLR[0], deLR[0]);
584  index[1] = std::max(bufUL[1], deUL[0]);
585  size[0] = std::max(deLR[0] - bufLR[0], 0L);
586  size[1] = std::min(bufLR[1] - std::max(bufUL[1], 0L), deLR[1] - index[1]);
587  break;
588 
589  case 5:
590  index[0] = deUL[0];
591  index[1] = std::min(deLR[1], bufLR[1]);
592  size[0] = std::max(bufUL[0] - deUL[0], 0L);
593  size[1] = std::max(deLR[1] - bufLR[1], 0L);
594  break;
595 
596  case 6:
597  index[0] = std::max(deUL[0], bufUL[0]);
598  index[1] = std::min(deLR[1], bufLR[1]);
599  size[0] = std::min(bufLR[0] - std::max(bufUL[0], 0L), deLR[0] - index[0]);
600  size[1] = std::max(deLR[1] - bufLR[1], 0L);
601  break;
602 
603  case 7:
604  index[0] = std::min(bufLR[0], deLR[0]);
605  index[1] = std::min(deLR[1], bufLR[1]);
606  size[0] = std::max(deLR[0] - bufLR[0], 0L);
607  size[1] = std::max(deLR[1] - bufLR[1], 0L);
608  }
609  region.SetSize(size);
610  region.SetIndex(index);
611  return region;
612 }
613 
614 template <class TPixel>
616 ::RegionType
619 {
620  RegionType outputRegion;
621 
622  SpacingType spacing = m_Image->GetSpacing() * m_SpacingZoomFactor;
623 
624  PointType center;
625  m_Image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter, center);
626  PointType origin;
627  origin[0] = center[0] - (static_cast<double>(this->m_DisplayExtent.GetSize()[0]) / 2 - 1) * spacing[0];
628  origin[1] = center[1] - (static_cast<double>(this->m_DisplayExtent.GetSize()[1]) / 2 - 1) * spacing[1];
629 
630  PointType oldOrigin;
631  oldOrigin[0] = center[0] - (static_cast<double>(this->m_OldDisplayExtent.GetSize()[0]) / 2 - 1) * spacing[0];
632  oldOrigin[1] = center[1] - (static_cast<double>(this->m_OldDisplayExtent.GetSize()[1]) / 2 - 1) * spacing[1];
633 
634  PointType upperLeft;
635  upperLeft[0] = origin[0] + (static_cast<double>(region.GetIndex()[0])) * spacing[0];
636  upperLeft[1] = origin[1] + (static_cast<double>(region.GetIndex()[1])) * spacing[1];
637 
638  PointType lowerRight;
639  lowerRight[0] = upperLeft[0] + (static_cast<double>(region.GetSize()[0]) - 1) * spacing[0];
640  lowerRight[1] = upperLeft[1] + (static_cast<double>(region.GetSize()[1]) - 1) * spacing[1];
641 
642  PointType bufferedUpperLeft;
643  bufferedUpperLeft[0] = origin[0] + static_cast<double>(m_BufferedRegion.GetIndex()[0]) * spacing[0];
644  bufferedUpperLeft[1] = origin[1] + static_cast<double>(m_BufferedRegion.GetIndex()[1]) * spacing[1];
645 
646  PointType bufferedLowerRight;
647  bufferedLowerRight[0] = bufferedUpperLeft[0] + static_cast<double>(m_BufferedRegion.GetSize()[0] - 1) * spacing[0];
648  bufferedLowerRight[1] = bufferedUpperLeft[1] + static_cast<double>(m_BufferedRegion.GetSize()[1] - 1) * spacing[1];
649 
650  IndexType lowerRightIndex;
651  IndexType requestedIndex;
652  SizeType requestedSize;
653  m_Image->TransformPhysicalPointToIndex(upperLeft, requestedIndex);
654  m_Image->TransformPhysicalPointToIndex(lowerRight, lowerRightIndex);
655  requestedSize[0] = lowerRightIndex[0] - requestedIndex[0] + 1;
656  requestedSize[1] = lowerRightIndex[1] - requestedIndex[1] + 1;
657 
658  outputRegion.SetIndex(requestedIndex);
659  outputRegion.SetSize(requestedSize);
660  outputRegion.PadByRadius(2);
661 
662  return outputRegion;
663 
664 }
665 
666 template <class TPixel>
667 unsigned char *
670 {
671  itk::TimeProbe total, filter, interpolation;
672  total.Start();
673  unsigned char * result = NULL;
674 
675  unsigned int bufferLength = 3 * region.GetSize()[0] * region.GetSize()[1];
676 
677  if (bufferLength == 0)
678  {
679  return result;
680  }
681 
682  result = new unsigned char[bufferLength];
683 
684  filter.Start();
685  typename ImageListType::Pointer bandList = m_DecompositionFilter->GetOutput();
686  bandList->UpdateOutputInformation();
687 
688  unsigned int index = 0;
689  PixelType interpolatedValue = 0;
690  PointType interpolatedPos;
691  interpolatedPos.Fill(0);
692  unsigned int numberOfSplits = 1;
693 
694  InterpolatorPointerType interpolator;
695  if (m_SpacingZoomFactor > 1)
696  {
697  numberOfSplits =
698  std::max((static_cast<unsigned int>(m_SpacingZoomFactor)) * (static_cast<unsigned int>(m_SpacingZoomFactor)), 1U);
699  interpolator = m_ZoomOutInterpolator;
700  }
701  else
702  {
703  interpolator = m_ZoomInInterpolator;
704  }
705 
706  unsigned int splitterNumberOfSplits = m_Splitter->GetNumberOfSplits(region, numberOfSplits);
707 
708  SpacingType spacing = image->GetSpacing() * m_SpacingZoomFactor;
709 
710  PointType center;
711  image->TransformIndexToPhysicalPoint(m_ViewedRegionCenter, center);
712  PointType origin;
713  origin[0] = center[0] - (static_cast<double>(this->m_DisplayExtent.GetSize()[0]) / 2 - 1) * spacing[0];
714  origin[1] = center[1] - (static_cast<double>(this->m_DisplayExtent.GetSize()[1]) / 2 - 1) * spacing[1];
715 
716  for (unsigned int splitIndex = 0; splitIndex < splitterNumberOfSplits; ++splitIndex)
717  {
718  RegionType splitRegion = m_Splitter->GetSplit(splitIndex, splitterNumberOfSplits, region);
719 
720  PointType upperLeft;
721  upperLeft[0] = origin[0] + (static_cast<double>(splitRegion.GetIndex()[0])) * spacing[0];
722  upperLeft[1] = origin[1] + (static_cast<double>(splitRegion.GetIndex()[1])) * spacing[1];
723  m_RequestedRegion = ComputeRequestedRegion(splitRegion);
724  if (!m_RequestedRegion.Crop(image->GetLargestPossibleRegion()))
725  {
726  SizeType nullSize;
727  nullSize.Fill(0);
728  IndexType nullIndex;
729  nullIndex.Fill(0);
730  m_RequestedRegion.SetSize(nullSize);
731  m_RequestedRegion.SetIndex(nullIndex);
732  }
733  m_DecompositionFilter = VectorImageDecompositionFilterType::New();
734  m_DecompositionFilter->SetInput(image);
735  bandList = m_DecompositionFilter->GetOutput();
736 
737  bandList->UpdateOutputInformation();
738  bandList->GetNthElement(m_RedChannelIndex)->SetRequestedRegion(m_RequestedRegion);
739  if (rgb)
740  {
741  bandList->GetNthElement(m_GreenChannelIndex)->SetRequestedRegion(m_RequestedRegion);
742  bandList->GetNthElement(m_BlueChannelIndex)->SetRequestedRegion(m_RequestedRegion);
743  }
744  bandList->PropagateRequestedRegion();
745  bandList->UpdateOutputData();
746 
747  filter.Stop();
748 
749  interpolation.Start();
750  interpolatedPos[1] = upperLeft[1];
751  for (unsigned int j = 0; j < splitRegion.GetSize()[1]; ++j)
752  {
753  interpolatedPos[0] = upperLeft[0];
754  for (unsigned int i = 0; i < splitRegion.GetSize()[0]; ++i)
755  {
756  interpolator->SetInputImage(bandList->GetNthElement(m_RedChannelIndex));
757  if (interpolator->IsInsideBuffer(interpolatedPos))
758  {
759  interpolatedValue = static_cast<PixelType>(interpolator->Evaluate(interpolatedPos));
760  }
761  else
762  {
763  interpolatedValue = 0;
764  }
765  result[index] = Normalize(interpolatedValue, m_RedChannelIndex);
766  if (rgb)
767  {
768  interpolator->SetInputImage(bandList->GetNthElement(m_GreenChannelIndex));
769  if (interpolator->IsInsideBuffer(interpolatedPos))
770  {
771  interpolatedValue = static_cast<PixelType>(interpolator->Evaluate(interpolatedPos));
772  }
773  else
774  {
775  interpolatedValue = 0;
776  }
777  result[index + 1] = Normalize(interpolatedValue, m_GreenChannelIndex);
778  interpolator->SetInputImage(bandList->GetNthElement(m_BlueChannelIndex));
779  if (interpolator->IsInsideBuffer(interpolatedPos))
780  {
781  interpolatedValue = static_cast<PixelType>(interpolator->Evaluate(interpolatedPos));
782  }
783  else
784  {
785  interpolatedValue = 0;
786  }
787  result[index + 2] = Normalize(interpolatedValue, m_BlueChannelIndex);
788  index += 3;
789  }
790  else
791  {
792  result[index + 1] = Normalize(interpolatedValue, m_RedChannelIndex);
793  result[index + 2] = Normalize(interpolatedValue, m_RedChannelIndex);
794  index += 3;
795  }
796  interpolatedPos[0] += spacing[0];
797  }
798  interpolatedPos[1] += spacing[1];
799  }
800  }
801 
802  interpolation.Stop();
803  total.Stop();
804  return result;
805 }
806 
807 template <class TPixel>
808 int
810 ::handle(int event)
811 {
812  if (m_Updating) return 0;
813  switch (event)
814  {
815  case FL_PUSH:
816  {
817  if (!m_Drag)
818  {
819  m_OldMousePos[0] = static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[0] / 2)
820  + (static_cast<double>(Fl::event_x()) -
821  static_cast<double>(
822  m_DisplayExtent.GetSize()[0] / 2)) / m_OpenGlIsotropicZoom);
823  m_OldMousePos[1] = static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[1] / 2)
824  + (static_cast<double>(Fl::event_y()) -
825  static_cast<double>(
826  m_DisplayExtent.GetSize()[1] / 2)) / m_OpenGlIsotropicZoom);
827  m_Drag = true;
828  m_DragEventCounter = 0;
829 
830  if (m_SubWindowRegion.IsInside(m_OldMousePos))
831  {
832  m_SubWindowMove = true;
833  }
834  else
835  {
836  m_OldViewedRegionCenter = m_ViewedRegionCenter;
837  }
838  }
839  return 1;
840  }
841 
842  case FL_DRAG:
843  {
844  m_Drag = true;
845 
846  int x = static_cast<int>(static_cast<double>(m_DisplayExtent.GetSize()[0] / 2)
847  + (Fl::event_x() - static_cast<double>(
848  m_DisplayExtent.GetSize()[0] / 2)) / m_OpenGlIsotropicZoom);
849  int y = static_cast<long int>(static_cast<double>(m_DisplayExtent.GetSize()[1] / 2)
850  + (Fl::event_y() - static_cast<double>(
851  m_DisplayExtent.GetSize()[1] / 2)) / m_OpenGlIsotropicZoom);
852  if (Fl::event_button() == FL_MIDDLE_MOUSE)
853  {
854  if (!m_SubWindowMode) m_SubWindowMode = true;
855  IndexType newIndex;
856  SizeType newSize;
857 
858  newIndex[0] = (x > m_OldMousePos[0] ? m_OldMousePos[0] : x);
859  newIndex[1] = (y > m_OldMousePos[1] ? m_OldMousePos[1] : y);
860  newSize[0] = vcl_abs(x - m_OldMousePos[0]);
861  newSize[1] = vcl_abs(y - m_OldMousePos[1]);
862  m_SubWindowRegion.SetIndex(newIndex);
863  m_SubWindowRegion.SetSize(newSize);
864  this->redraw();
865  ++m_DragEventCounter;
866  }
867  else if (m_SubWindowMove)
868  {
869  IndexType index = m_SubWindowRegion.GetIndex();
870  index[0] += (x - m_OldMousePos[0]);
871  index[1] += (y - m_OldMousePos[1]);
872  m_SubWindowRegion.SetIndex(index);
873  m_OldMousePos[0] = x;
874  m_OldMousePos[1] = y;
875  this->redraw();
876  ++m_DragEventCounter;
877  }
878 
879  else
880  {
881  SpacingType spacing = m_Image->GetSpacing() * m_SpacingZoomFactor;
882  PointType origin;
883  origin[0] = static_cast<double>(m_OldViewedRegionCenter[0]) - static_cast<double>(
884  this->m_DisplayExtent.GetSize()[0] / 2) * spacing[0];
885  origin[1] = static_cast<double>(m_OldViewedRegionCenter[1]) - static_cast<double>(
886  this->m_DisplayExtent.GetSize()[1] / 2) * spacing[1];
887  PointType newCenter;
888  newCenter[0] = origin[0] +
889  static_cast<double>(m_OldMousePos[0] - x + static_cast<long>(
890  this->m_DisplayExtent.GetSize()[0]) /
891  2) * spacing[0];
892  newCenter[1] = origin[1] +
893  static_cast<double>(m_OldMousePos[1] - y + static_cast<long>(
894  this->m_DisplayExtent.GetSize()[1]) /
895  2) * spacing[1];
896  m_Image->TransformPhysicalPointToIndex(newCenter, m_ViewedRegionCenter);
897  this->redraw();
898  ++m_DragEventCounter;
899  }
900 
901  DecorationRedraw();
902  return 1;
903  }
904 
905  case FL_RELEASE:
906  {
907  m_OldViewedRegionCenter = m_ViewedRegionCenter;
908  m_Drag = false;
909  AdditionalRedraw();
910  m_SubWindowMove = false;
911  return 1;
912  }
913  case FL_FOCUS:
914  {
915  return 1;
916  }
917  case FL_UNFOCUS:
918  {
919  return 1;
920  }
921  case FL_KEYDOWN:
922  {
923  if (Fl::event_key() == 116) // T key
924  {
925  m_SubWindowMode = !m_SubWindowMode;
926  this->redraw();
927  }
928  return 1;
929  }
930  }
931  return 0;
932 }
933 
934 template <class TPixel>
935 void
937 ::MergeBuffersAndFreeMemory(std::vector<unsigned char *> bufferList, std::vector<RegionType> bufferRegionList)
938 {
939  if (bufferList.size() != 8 || bufferRegionList.size() != 8)
940  {
941  itkExceptionMacro("Invalid number of additionnal buffers");
942  }
943 
944  if (bufferRegionList[0].GetNumberOfPixels() == 0
945  && bufferRegionList[1].GetNumberOfPixels() == 0
946  && bufferRegionList[2].GetNumberOfPixels() == 0
947  && bufferRegionList[3].GetNumberOfPixels() == 0
948  && bufferRegionList[4].GetNumberOfPixels() == 0
949  && bufferRegionList[5].GetNumberOfPixels() == 0
950  && bufferRegionList[6].GetNumberOfPixels() == 0
951  && bufferRegionList[7].GetNumberOfPixels() == 0)
952  {
953  return;
954  }
955 
956  // malloc new buffer
957  unsigned char * newBuffer = new unsigned char[3 * m_DisplayExtent.GetNumberOfPixels()];
958 
959  // fill the new buffer
960  unsigned int indexInNewBuffer = 0;
961 
962  unsigned int indexInBuffer1 = 0;
963  unsigned int indexInBuffer2 = 0;
964  unsigned int indexInBuffer3 = 0;
965  unsigned int indexInBuffer4 = 0;
966  unsigned int indexInBuffer5 = 0;
967  unsigned int indexInBuffer6 = 0;
968  unsigned int indexInBuffer7 = 0;
969  unsigned int indexInBuffer8 = 0;
970  unsigned int indexInCentralBuffer = 0;
971 
972  if (bufferRegionList[0].GetSize()[1] != bufferRegionList[1].GetSize()[1]
973  || bufferRegionList[2].GetSize()[1] != bufferRegionList[1].GetSize()[1]
974  || bufferRegionList[2].GetSize()[1] != bufferRegionList[0].GetSize()[1]
975  || bufferRegionList[0].GetIndex()[1] != bufferRegionList[1].GetIndex()[1]
976  || bufferRegionList[2].GetIndex()[1] != bufferRegionList[1].GetIndex()[1]
977  || bufferRegionList[2].GetIndex()[1] != bufferRegionList[0].GetIndex()[1]
978  )
979  {
980  itkExceptionMacro("Additional buffers misaligned.");
981  }
982 
983  // Fill region 1
984 
985  for (unsigned int j = 0; j < bufferRegionList[0].GetSize()[1]; ++j)
986  {
987  if (bufferList[0] != NULL)
988  {
989  for (unsigned int i = 0; i < 3 * bufferRegionList[0].GetSize()[0]; ++i)
990  {
991  newBuffer[indexInNewBuffer] = bufferList[0][indexInBuffer1];
992  ++indexInNewBuffer;
993  ++indexInBuffer1;
994  }
995  }
996  // Fill region 2
997  if (bufferList[1] != NULL)
998  {
999  for (unsigned int i = 0; i < 3 * bufferRegionList[1].GetSize()[0]; ++i)
1000  {
1001  newBuffer[indexInNewBuffer] = bufferList[1][indexInBuffer2];
1002  ++indexInNewBuffer;
1003  ++indexInBuffer2;
1004  }
1005  }
1006  // Fill region 3
1007  if (bufferList[2] != NULL)
1008  {
1009  for (unsigned int i = 0; i < 3 * bufferRegionList[2].GetSize()[0]; ++i)
1010  {
1011  newBuffer[indexInNewBuffer] = bufferList[2][indexInBuffer3];
1012  ++indexInNewBuffer;
1013  ++indexInBuffer3;
1014  }
1015  }
1016  }
1017 
1018  unsigned int lineOffset = static_cast<unsigned int>(-std::min(0L, m_BufferedRegion.GetIndex()[0]));
1019  unsigned int lineOffsetEnd =
1020  static_cast<unsigned int>(-std::min(0L, static_cast<long>(m_DisplayExtent.GetSize()[0]) -
1021  m_BufferedRegion.GetIndex()[0] - static_cast<long>(m_BufferedRegion.GetSize()[0])));
1022  unsigned int columnOffset = static_cast<unsigned int>(-std::min(0L, m_BufferedRegion.GetIndex()[1]));
1023  unsigned int offsety = columnOffset * (static_cast<int>(m_BufferedRegion.GetSize()[0])) * 3;
1024  unsigned int offsetx = lineOffset * 3;
1025 
1026  indexInCentralBuffer += offsety;
1027 
1028  // For each line
1029  for (unsigned int j = 0; j < bufferRegionList[3].GetSize()[1]; ++j)
1030  {
1031  //Fill line from region 4
1032  if (bufferList[3] != NULL)
1033  {
1034  for (unsigned int i = 0; i < 3 * bufferRegionList[3].GetSize()[0]; ++i)
1035  {
1036  newBuffer[indexInNewBuffer] = bufferList[3][indexInBuffer4];
1037  ++indexInNewBuffer;
1038  ++indexInBuffer4;
1039  }
1040  }
1041  // Fill line from central region
1042  if (m_OpenGlBuffer != NULL)
1043  {
1044 
1045  indexInCentralBuffer += offsetx;
1046  for (unsigned int i = 0; i < 3 * bufferRegionList[1].GetSize()[0]; ++i)
1047  {
1048  newBuffer[indexInNewBuffer] = m_OpenGlBuffer[indexInCentralBuffer];
1049  ++indexInNewBuffer;
1050  ++indexInCentralBuffer;
1051  }
1052  indexInCentralBuffer += lineOffsetEnd * 3;
1053  }
1054  // Fill line from region 5
1055  if (bufferList[4] != NULL)
1056  {
1057  for (unsigned int i = 0; i < 3 * bufferRegionList[4].GetSize()[0]; ++i)
1058  {
1059  newBuffer[indexInNewBuffer] = bufferList[4][indexInBuffer5];
1060  ++indexInNewBuffer;
1061  ++indexInBuffer5;
1062  }
1063  }
1064  }
1065 
1066  if (bufferRegionList[5].GetSize()[1] != bufferRegionList[6].GetSize()[1]
1067  || bufferRegionList[6].GetSize()[1] != bufferRegionList[7].GetSize()[1]
1068  || bufferRegionList[7].GetSize()[1] != bufferRegionList[5].GetSize()[1]
1069  || bufferRegionList[5].GetIndex()[1] != bufferRegionList[6].GetIndex()[1]
1070  || bufferRegionList[6].GetIndex()[1] != bufferRegionList[7].GetIndex()[1]
1071  || bufferRegionList[7].GetIndex()[1] != bufferRegionList[5].GetIndex()[1]
1072  )
1073  {
1074  itkExceptionMacro("Additional buffers misaligned.");
1075  }
1076 
1077  // Fill region 6
1078 
1079  for (unsigned int j = 0; j < bufferRegionList[5].GetSize()[1]; ++j)
1080  {
1081  if (bufferList[5] != NULL)
1082  {
1083  for (unsigned int i = 0; i < 3 * bufferRegionList[5].GetSize()[0]; ++i)
1084  {
1085  newBuffer[indexInNewBuffer] = bufferList[5][indexInBuffer6];
1086  ++indexInNewBuffer;
1087  ++indexInBuffer6;
1088  }
1089  }
1090  // Fill region 2
1091  if (bufferList[6] != NULL)
1092  {
1093  for (unsigned int i = 0; i < 3 * bufferRegionList[6].GetSize()[0]; ++i)
1094  {
1095  newBuffer[indexInNewBuffer] = bufferList[6][indexInBuffer7];
1096  ++indexInNewBuffer;
1097  ++indexInBuffer7;
1098  }
1099  }
1100  // Fill region 3
1101  if (bufferList[7] != NULL)
1102  {
1103  for (unsigned int i = 0; i < 3 * bufferRegionList[7].GetSize()[0]; ++i)
1104  {
1105  newBuffer[indexInNewBuffer] = bufferList[7][indexInBuffer8];
1106  ++indexInNewBuffer;
1107  ++indexInBuffer8;
1108  }
1109  }
1110  }
1111 
1112  // Free all intermediate buffers
1113  typename std::vector<unsigned char *>::iterator it;
1114  for (it = bufferList.begin(); it != bufferList.end(); ++it)
1115  {
1116  if ((*it) != NULL)
1117  {
1118  delete[] (*it);
1119  }
1120  }
1121 
1122  // update buffered region
1123  m_OldBufferedRegion = m_BufferedRegion;
1124  m_BufferedRegion = m_DisplayExtent;
1125  // delete previous buffer
1126  if (m_OpenGlBuffer != NULL)
1127  {
1128  delete[] m_OpenGlBuffer;
1129  }
1130  // replace by current buffer
1131  m_OpenGlBuffer = newBuffer;
1132 
1133  //std::cout<<"Buffers merged and freed"<<std::endl;
1134 }
1135 
1136 template <class TPixel>
1137 void
1139 ::Draw(unsigned char * buffer, RegionType& region)
1140 {
1141  itk::TimeProbe total;
1142  total.Start();
1143  if (buffer != NULL)
1144  {
1145  // This enable negative raster pos
1146  glRasterPos3d(0, 0, 0);
1147 
1148  double zoomOffsetX = 0;
1149  double zoomOffsetY = 0;
1150 
1151  zoomOffsetX =
1152  (1 -
1153  m_OpenGlIsotropicZoom) *
1154  (static_cast<double>(m_DisplayExtent.GetSize()[0] / 2) - static_cast<double>(region.GetIndex()[0]));
1155  zoomOffsetY =
1156  (1 -
1157  m_OpenGlIsotropicZoom) *
1158  (static_cast<double>(m_DisplayExtent.GetSize()[1] / 2) - static_cast<double>(region.GetIndex()[1]));
1159 
1160  double movex = static_cast<double>(region.GetIndex()[0]) + zoomOffsetX;
1161  double movey = static_cast<double>(m_DisplayExtent.GetSize()[1]) - static_cast<double>(region.GetIndex()[1]) -
1162  zoomOffsetY;
1163  glBitmap(0, 0, 0, 0, movex, movey, NULL);
1164  glPixelZoom(m_OpenGlIsotropicZoom, -m_OpenGlIsotropicZoom);
1165 
1166  // display the image
1167  glDrawPixels(region.GetSize()[0],
1168  region.GetSize()[1],
1169  GL_RGB,
1170  GL_UNSIGNED_BYTE,
1171  buffer);
1172  glEnd();
1173  swap_buffers();
1174  glFlush();
1175  }
1176  total.Stop();
1177 }
1178 
1179 template <class TPixel>
1180 void
1183 {
1184  double zoomOffsetX = 0;
1185  double zoomOffsetY = 0;
1186 
1187  zoomOffsetX =
1188  (1 -
1189  m_OpenGlIsotropicZoom) *
1190  (static_cast<double>(m_DisplayExtent.GetSize()[0] / 2) - static_cast<double>(region.GetIndex()[0]));
1191  zoomOffsetY =
1192  (1 -
1193  m_OpenGlIsotropicZoom) *
1194  (static_cast<double>(m_DisplayExtent.GetSize()[1] / 2) - static_cast<double>(region.GetIndex()[1]));
1195  double minx, maxx, miny, maxy;
1196 
1197  minx = static_cast<double>(region.GetIndex()[0]) + zoomOffsetX;
1198  maxx = minx + static_cast<double>(region.GetSize()[0]) * m_OpenGlIsotropicZoom;
1199  miny = static_cast<double>(m_DisplayExtent.GetSize()[1]) -
1200  static_cast<double>(region.GetIndex()[1]) - zoomOffsetY;
1201  maxy = miny - static_cast<double>(region.GetSize()[1]) * m_OpenGlIsotropicZoom;
1202 
1203  glEnable(GL_BLEND);
1204  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1205  glColor3f(1, 0, 0);
1206  glBegin(GL_LINE_LOOP);
1207  glVertex2f(minx, miny);
1208  glVertex2f(minx, maxy);
1209  glVertex2f(maxx, maxy);
1210  glVertex2f(maxx, miny);
1211  glEnd();
1212  glDisable(GL_BLEND);
1213 
1214 }
1215 template <class TPixel>
1216 void
1219 {
1220  if (!this->valid())
1221  {
1222  valid(1);
1223  glLoadIdentity();
1224  glViewport(0, 0, m_DisplayExtent.GetSize()[0], m_DisplayExtent.GetSize()[1]);
1225  glClearColor((float) 0.0, (float) 0.0, (float) 0.0, (float) 0.0);
1226  glShadeModel(GL_SMOOTH);
1227  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1228  }
1229 
1230  glClear(GL_COLOR_BUFFER_BIT); //this clears and paints to black
1231  glMatrixMode(GL_PROJECTION);
1232  this->ortho();
1233  glMatrixMode(GL_MODELVIEW); //clear previous 3D draw params
1234  glLoadIdentity();
1235  glDisable(GL_BLEND);
1236 
1237  glShadeModel(GL_SMOOTH);
1238 }
1239 
1240 template <class TPixel>
1241 unsigned char
1243 ::Normalize(PixelType value, unsigned int channelIndex)
1244 {
1245  PixelType max = 255;
1246  PixelType min = 0;
1247  if (channelIndex < m_MaxComponentValues.GetSize())
1248  {
1249  max = m_MaxComponentValues[channelIndex];
1250  }
1251  if (channelIndex < m_MinComponentValues.GetSize())
1252  {
1253  min = m_MinComponentValues[channelIndex];
1254  }
1255  if (value >= max)
1256  {
1257  return 255;
1258  }
1259 
1260  else if (value <= min)
1261  {
1262  return 0;
1263  }
1264  else
1265  {
1266  return static_cast<unsigned char>(255. * static_cast<double>(value - min)
1267  / static_cast<double>(max - min));
1268  }
1269 }
1273 template <class TPixel>
1274 void
1276 ::PrintSelf(std::ostream& os, itk::Indent indent) const
1277 {
1278  Superclass::PrintSelf(os, indent);
1279 }
1280 } // End namespace otb
1281 #endif

Generated at Sun Feb 3 2013 00:26:05 for Orfeo Toolbox with doxygen 1.8.1.1