File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
StretchTool.cpp
1 #include "StretchTool.h"
2 
3 #include <sstream>
4 
5 #include <QAction>
6 #include <QComboBox>
7 #include <QHBoxLayout>
8 #include <QLineEdit>
9 #include <QMenuBar>
10 #include <QMessageBox>
11 #include <QPixmap>
12 #include <QPushButton>
13 #include <QSizePolicy>
14 #include <QStackedWidget>
15 #include <QToolBar>
16 #include <QToolButton>
17 #include <QValidator>
18 #include <QInputDialog>
19 
20 #include "AdvancedStretchDialog.h"
21 #include "Brick.h"
22 #include "Blob.h"
23 #include "CubeViewport.h"
24 #include "Histogram.h"
25 #include "IException.h"
26 #include "IString.h"
27 #include "MainWindow.h"
28 #include "MdiCubeViewport.h"
29 #include "RubberBandTool.h"
30 #include "Statistics.h"
31 #include "Stretch.h"
32 #include "ToolPad.h"
33 #include "ViewportBuffer.h"
34 #include "ViewportMainWindow.h"
35 #include "Workspace.h"
36 
37 #include "CubeStretch.h"
38 
39 using namespace std;
40 
41 namespace Isis {
48  StretchTool::StretchTool(QWidget *parent) : Tool::Tool(parent) {
49  m_chipViewportStretch = NULL;
50  m_preGlobalStretches = NULL;
51  m_advancedStretch = NULL;
52 
54 
56  connect(m_advancedStretch, SIGNAL(stretchChanged()),
57  this, SLOT(advancedStretchChanged()));
58  connect(m_advancedStretch, SIGNAL(visibilityChanged()),
59  this, SLOT(updateTool()));
60  connect(m_advancedStretch, SIGNAL(saveToCube()),
61  this, SLOT(saveStretchToCube()));
62  connect(m_advancedStretch, SIGNAL(deleteFromCube()),
63  this, SLOT(deleteFromCube()));
64  connect(m_advancedStretch, SIGNAL(loadStretch()),
65  this, SLOT(loadStretchFromCube()));
66 
67  QPushButton *hiddenButton = new QPushButton();
68  hiddenButton->setVisible(false);
69  hiddenButton->setDefault(true);
70 
71  m_stretchGlobal = new QAction(parent);
72  m_stretchGlobal->setShortcut(Qt::CTRL + Qt::Key_G);
73  m_stretchGlobal->setText("Global Stretch");
74  connect(m_stretchGlobal, SIGNAL(triggered()), this, SLOT(stretchGlobal()));
75 
76  m_stretchRegional = new QAction(parent);
77  m_stretchRegional->setShortcut(Qt::CTRL + Qt::Key_R);
78  m_stretchRegional->setText("Regional Stretch");
79  connect(m_stretchRegional, SIGNAL(triggered()), this, SLOT(stretchRegional()));
80 
81  // Emit a signal when an exception occurs and connect to the Warning object
82  // to display Warning icon and the message
83  ViewportMainWindow *parentMainWindow = qobject_cast<ViewportMainWindow *>(parent);
84  if (parentMainWindow) {
85  connect(this, SIGNAL(warningSignal(std::string &, const std::string)),
86  parentMainWindow, SLOT(displayWarning(std::string &, const std::string &)));
87  }
88  }
89 
90 
95  delete [] m_preGlobalStretches;
96  m_preGlobalStretches = NULL;
97 
98  delete m_chipViewportStretch;
99  m_chipViewportStretch = NULL;
100  }
101 
102 
112  QAction *action = new QAction(pad);
113  action->setIcon(QPixmap(toolIconDir() + "/stretch_global.png"));
114  action->setToolTip("Stretch (S)");
115  action->setShortcut(Qt::Key_S);
116  QString text =
117  "<b>Function:</b> Change the stretch range of the cube.\
118  <p><b>Shortcut:</b> S</p> ";
119  action->setWhatsThis(text);
120 
121  return action;
122  }
123 
124 
131  void StretchTool::addTo(QMenu *menu) {
132  menu->addAction(m_stretchGlobal);
133  menu->addAction(m_stretchRegional);
134  }
135 
136 
145  QWidget *StretchTool::createToolBarWidget(QStackedWidget *parent) {
146  QWidget *hbox = new QWidget(parent);
147 
148  QToolButton *butt = new QToolButton(hbox);
149  butt->setAutoRaise(true);
150  butt->setIconSize(QSize(22, 22));
151  butt->setIcon(QPixmap(toolIconDir() + "/regional_stretch-2.png"));
152  butt->setToolTip("Stretch");
153  QString text =
154  "<b>Function:</b> Automatically compute min/max stretch using viewed \
155  pixels in the band(s) of the active viewport. That is, only pixels \
156  that are visible in the viewport are used. \
157  If the viewport is in RGB color all three bands will be stretched. \
158  <p><b>Shortcut:</b> Ctrl+R</p> \
159  <p><b>Mouse:</b> Left click \
160  <p><b>Hint:</b> Left click and drag for a local stretch. Uses only \
161  pixels in the red marquee</p>";
162  butt->setWhatsThis(text);
163  connect(butt, SIGNAL(clicked()), this, SLOT(stretchRegional()));
165 
166  m_stretchBandComboBox = new QComboBox(hbox);
167  m_stretchBandComboBox->setEditable(false);
168  m_stretchBandComboBox->addItem("Red Band", Red);
169  m_stretchBandComboBox->addItem("Green Band", Green);
170  m_stretchBandComboBox->addItem("Blue Band", Blue);
171  m_stretchBandComboBox->addItem("All Bands", All);
172  m_stretchBandComboBox->setToolTip("Select Color");
173  text =
174  "<b>Function:</b> Selecting the color will allow the appropriate \
175  min/max to be seen and/or edited in text fields to the right.";
176 
177 // The All option implies the same min/max will be applied
178 // to all three colors (RGB) if either text field is edited";
179  m_stretchBandComboBox->setWhatsThis(text);
180  m_stretchBand = All;
181  m_stretchBandComboBox->setCurrentIndex(
183  connect(m_stretchBandComboBox, SIGNAL(currentIndexChanged(int)),
184  this, SLOT(stretchBandChanged(int)));
185 
186  QDoubleValidator *dval = new QDoubleValidator(hbox);
187  m_stretchMinEdit = new QLineEdit(hbox);
188  m_stretchMinEdit->setValidator(dval);
189  m_stretchMinEdit->setToolTip("Minimum");
190  text =
191  "<b>Function:</b> Shows the current minimum pixel value. Pixel values \
192  below minimum are shown as black. Pixel values above the maximum \
193  are shown as white or the highest intensity of red/green/blue \
194  if in color. Pixel values between the minimum and maximum are stretched \
195  linearly between black and white (or color component). \
196  <p><b>Hint:</b> You can manually edit the minimum but it must be \
197  less than the maximum.";
198  m_stretchMinEdit->setWhatsThis(text);
199  m_stretchMinEdit->setMaximumWidth(100);
200  connect(m_stretchMinEdit, SIGNAL(returnPressed()),
201  this, SLOT(changeStretch()));
202 
203  m_stretchMaxEdit = new QLineEdit(hbox);
204  m_stretchMaxEdit->setValidator(dval);
205  m_stretchMaxEdit->setToolTip("Maximum");
206  text =
207  "<b>Function:</b> Shows the current maximum pixel value. Pixel values \
208  below minimum are shown as black. Pixel values above the maximum \
209  are shown as white or the highest intensity of red/green/blue \
210  if in color. Pixel values between the minimum and maximum are stretched \
211  linearly between black and white (or color component). \
212  <p><b>Hint:</b> You can manually edit the maximum but it must be \
213  greater than the minimum";
214  m_stretchMaxEdit->setWhatsThis(text);
215  m_stretchMaxEdit->setMaximumWidth(100);
216  connect(m_stretchMaxEdit, SIGNAL(returnPressed()), this, SLOT(changeStretch()));
217 
218  // Create the two menus that drop down from the buttons
219  QMenu *copyMenu = new QMenu();
220  QMenu *globalMenu = new QMenu();
221 
222  m_copyBands = new QAction(parent);
223  m_copyBands->setText("to All Bands");
224  connect(m_copyBands, SIGNAL(triggered(bool)), this, SLOT(setStretchAcrossBands()));
225 
226  QAction *copyAll = new QAction(parent);
227  copyAll->setIcon(QPixmap(toolIconDir() + "/copy_stretch.png"));
228  copyAll->setText("to All Viewports");
229  connect(copyAll, SIGNAL(triggered(bool)), this, SLOT(setStretchAllViewports()));
230 
231  copyMenu->addAction(copyAll);
232  copyMenu->addAction(m_copyBands);
233 
234  m_copyButton = new QToolButton();
235  m_copyButton->setAutoRaise(true);
236  m_copyButton->setIconSize(QSize(22, 22));
237  m_copyButton->setIcon(QPixmap(toolIconDir() + "/copy_stretch.png"));
238  m_copyButton->setPopupMode(QToolButton::MenuButtonPopup);
239  m_copyButton->setMenu(copyMenu);
240  m_copyButton->setDefaultAction(copyAll);
241  m_copyButton->setToolTip("Copy");
242  text =
243  "<b>Function:</b> Copy the current stretch to all the \
244  active viewports. Or use the drop down menu to copy the current stretch \
245  to all the bands in the active viewport. \
246  <p><b>Hint:</b> Can reset the stretch to an automaticaly computed \
247  stretch by using the 'Reset' stretch button option. </p>";
248  m_copyButton->setWhatsThis(text);
249 
250  QAction *currentView = new QAction(parent);
251  currentView->setText("Active Viewport");
252  currentView->setIcon(QPixmap(toolIconDir() + "/global_stretch.png"));
253  globalMenu->addAction(currentView);
254  connect(currentView, SIGNAL(triggered(bool)), this, SLOT(stretchGlobal()));
255 
256  QAction *globalAll = new QAction(parent);
257  globalAll->setText("All Viewports");
258  globalMenu->addAction(globalAll);
259  connect(globalAll, SIGNAL(triggered(bool)), this, SLOT(stretchGlobalAllViewports()));
260 
261  QAction *globalBands = new QAction(parent);
262  globalBands->setText("All Bands");
263  globalMenu->addAction(globalBands);
264  connect(globalBands, SIGNAL(triggered(bool)), this, SLOT(stretchGlobalAllBands()));
265 
266  m_globalButton = new QToolButton(); //basically acts as a 'reset'
267  m_globalButton->setAutoRaise(true);
268  m_globalButton->setIconSize(QSize(22, 22));
269  m_globalButton->setPopupMode(QToolButton::MenuButtonPopup);
270  m_globalButton->setMenu(globalMenu);
271  m_globalButton->setDefaultAction(currentView);
272  m_globalButton->setToolTip("Reset");
273  text =
274  "<b>Function:</b> Reset the stretch to be automatically computed "
275  "using the statisics from the entire image. Use the drop down menu "
276  "to reset the stretch for all the bands in the active viewport or "
277  "to reset the stretch for all the viewports.";
278  m_globalButton->setWhatsThis(text);
279 
280  QPushButton *advancedButton = new QPushButton("Advanced");
281  connect(advancedButton, SIGNAL(clicked()), this, SLOT(showAdvancedDialog()));
282 
283  m_flashButton = new QPushButton("Show Global");
284  text =
285  "<b>Function:</b> While this button is pressed down, the visible stretch "
286  "will be the automatically computed stretch using the statisics from the "
287  "entire image. The original stretch is restored once you let up on this "
288  "button.";
289  m_flashButton->setWhatsThis(text);
290  connect(m_flashButton, SIGNAL(pressed()), this, SLOT(stretchChanged()));
291  connect(m_flashButton, SIGNAL(released()), this, SLOT(stretchChanged()));
292 
293  // Buttons migrated out of Advanced Stretch Tool
294  QPushButton *saveToCubeButton = new QPushButton("Save");
295  connect(saveToCubeButton, SIGNAL(clicked(bool)), this, SLOT(saveStretchToCube()));
296 
297  QPushButton *deleteFromCubeButton = new QPushButton("Delete");
298  connect(deleteFromCubeButton, SIGNAL(clicked(bool)), this, SLOT(deleteFromCube()));
299 
300  QPushButton *loadStretchButton = new QPushButton("Restore");
301  connect(loadStretchButton, SIGNAL(clicked(bool)), this, SLOT(loadStretchFromCube()));
302 
303  QHBoxLayout *layout = new QHBoxLayout(hbox);
304  layout->setMargin(0);
305  layout->addWidget(m_copyButton);
306  layout->addWidget(m_globalButton);
307  layout->addWidget(m_stretchRegionalButton);
308  layout->addWidget(m_stretchBandComboBox);
309  layout->addWidget(m_stretchMinEdit);
310  layout->addWidget(m_stretchMaxEdit);
311  layout->addWidget(advancedButton);
312  layout->addWidget(m_flashButton);
313 
314  // should only display if gray stretch
315  // Save/Restore strech only supported for Grayscale images. Hide buttons if in RGB.
316  layout->addWidget(saveToCubeButton);
317  layout->addWidget(deleteFromCubeButton);
318  layout->addWidget(loadStretchButton);
319 
320  layout->addStretch(); // Pushes everything else left in the menu bar
321  hbox->setLayout(layout);
322 
323  return hbox;
324  }
325 
326 
332  if(m_advancedStretch->isVisible()) {
333  MdiCubeViewport *cvp = cubeViewport();
334 
335  if(!cvp) return;
336 
337  if(cvp->isGray() && !cvp->grayBuffer()->working()) {
339  updateTool();
340  }
341  else {
342  Histogram hist(histFromBuffer(cvp->grayBuffer()));
343 
344  if(hist.ValidPixels() > 0) {
346  }
347  }
348  }
349  // Otherwise it is in color mode
350  else if(!cvp->isGray() &&
351  !cvp->redBuffer()->working() &&
352  !cvp->greenBuffer()->working() &&
353  !cvp->blueBuffer()->working()) {
354  if(!m_advancedStretch->isRgbMode()) {
355  updateTool();
356  }
357  else {
358  Histogram redHist(histFromBuffer(cvp->redBuffer()));
359  Histogram grnHist(histFromBuffer(cvp->greenBuffer()));
360  Histogram bluHist(histFromBuffer(cvp->blueBuffer()));
361 
362  if(redHist.ValidPixels() > 0 &&
363  grnHist.ValidPixels() > 0 &&
364  bluHist.ValidPixels() > 0) {
365  m_advancedStretch->updateHistograms(redHist, grnHist, bluHist);
366  }
367  }
368  }
369  }
370  }
371 
372 
380  {
381  if(m_advancedStretch->isVisible()) {
382  MdiCubeViewport *cvp = cubeViewport();
383 
384  if(!cvp->isGray() &&
385  !cvp->redBuffer()->working() &&
386  !cvp->greenBuffer()->working() &&
387  !cvp->blueBuffer()->working()) {
388 
389  Histogram redHist(histFromBuffer(cvp->redBuffer()));
390  Histogram grnHist(histFromBuffer(cvp->greenBuffer()));
391  Histogram bluHist(histFromBuffer(cvp->blueBuffer()));
392  Stretch redStretch(cvp->redStretch());
393  Stretch grnStretch(cvp->greenStretch());
394  Stretch bluStretch(cvp->blueStretch());
395 
396  m_advancedStretch->updateForRGBMode(redStretch, redHist,
397  grnStretch, grnHist,
398  bluStretch, bluHist);
399  }
400  }
401  }
402 
403 
408  MdiCubeViewport *cvp = cubeViewport();
409  Cube* icube = cvp->cube();
410  Pvl* lab = icube->label();
411 
412  QStringList namelist;
413 
414  // Create a list of existing Stretch names
415  if (cvp->isGray()) {
417  for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
418  if (objIter->name() == "Stretch") {
419  PvlKeyword tempKeyword = objIter->findKeyword("Name");
420  int bandNumber = int(objIter->findKeyword("BandNumber"));
421  if (cvp->grayBand() == bandNumber) {
422  QString tempName = tempKeyword[0];
423  namelist.append(tempName);
424  }
425  }
426  }
427  }
428  else {
429  int redBandNumber = cvp->redBand();
430  int greenBandNumber = cvp->greenBand();
431  int blueBandNumber = cvp->blueBand();
432 
433  QMap<QString, QList<int>> tempNameMap;
435  for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
436  if (objIter->name() == "Stretch") {
437  PvlKeyword tempKeyword = objIter->findKeyword("Name");
438  int bandNumber = int(objIter->findKeyword("BandNumber"));
439  if (bandNumber == redBandNumber || bandNumber == greenBandNumber
440  || bandNumber == blueBandNumber) {
441  QString tempName = tempKeyword[0];
442  if (tempNameMap.contains(tempName)) {
443  tempNameMap[tempName].append(bandNumber);
444  }
445  else
446  {
447  tempNameMap[tempName] = {bandNumber};
448  }
449  }
450  }
451  }
452  QMap<QString, QList<int>>::const_iterator i = tempNameMap.constBegin();
453  while (i != tempNameMap.constEnd()) {
454  if (i.value().contains(redBandNumber) && i.value().contains(greenBandNumber) &&
455  i.value().contains(blueBandNumber) ){
456  namelist.append(i.key());
457  }
458  ++i;
459  }
460  }
461 
462  bool ok = false;
463  QString stretchName;
464  // Only display load stretch dialog if there are stretches saved to the cube
465  if (namelist.size() >=1) {
466  stretchName = QInputDialog::getItem((QWidget *)parent(), tr("Load Stretch"),
467  tr("Name of Stretch to Load:"), namelist, 0,
468  false, &ok);
469  }
470  else {
471  QMessageBox::information((QWidget *)parent(), "Information",
472  "There are no saved stretches to restore.");
473  }
474 
475  if (ok) {
476  if (cvp->isGray()) {
477  CubeStretch cubeStretch = icube->readCubeStretch(stretchName);
478  if (m_advancedStretch->isVisible()) {
480  }
481  // Get the current cube stretche and copy the new stretch pairs over so that the
482  // special pixel values set in the viewport are maintained.
483  CubeStretch grayOriginal = cvp->grayStretch();
484  grayOriginal.CopyPairs(cubeStretch);
485  cvp->stretchGray(grayOriginal);
486  }
487  else {
488  std::vector<PvlKeyword> keywordValueRed;
489  keywordValueRed.push_back(PvlKeyword("BandNumber", QString::number(cvp->redBand())));
490 
491  std::vector<PvlKeyword> keywordValueGreen;
492  keywordValueGreen.push_back(PvlKeyword("BandNumber", QString::number(cvp->greenBand())));
493 
494  std::vector<PvlKeyword> keywordValueBlue;
495  keywordValueBlue.push_back(PvlKeyword("BandNumber", QString::number(cvp->blueBand())));
496 
497  CubeStretch redStretch = icube->readCubeStretch(stretchName, keywordValueRed);
498  CubeStretch greenStretch = icube->readCubeStretch(stretchName, keywordValueGreen);
499  CubeStretch blueStretch = icube->readCubeStretch(stretchName, keywordValueBlue);
500 
501  if (m_advancedStretch->isVisible()) {
502  m_advancedStretch->restoreRgbStretch(redStretch, greenStretch, blueStretch);
503  }
504 
505  // Get the current cube stretches and copy the new stretch pairs over so that the
506  // special pixel values set in the viewport are maintained.
507  CubeStretch redOriginal = cvp->redStretch();
508  CubeStretch greenOriginal = cvp->greenStretch();
509  CubeStretch blueOriginal = cvp->blueStretch();
510 
511  redOriginal.CopyPairs(redStretch);
512  greenOriginal.CopyPairs(greenStretch);
513  blueOriginal.CopyPairs(blueStretch);
514 
515  cvp->stretchRed(redOriginal);
516  cvp->stretchGreen(greenOriginal);
517  cvp->stretchBlue(blueOriginal);
518  }
519  emit stretchChanged();
520  }
521  }
522 
523 
528  MdiCubeViewport *cvp = cubeViewport();
529  Cube* icube = cvp->cube();
530  Pvl* lab = icube->label();
531 
532  // Create a list of existing Stretch names
533  QStringList namelist;
535  for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
536  if (objIter->name() == "Stretch") {
537  PvlKeyword tempKeyword = objIter->findKeyword("Name");
538  int bandNumber = int(objIter->findKeyword("BandNumber"));
539  if (cvp->grayBand() == bandNumber) {
540  QString tempName = tempKeyword[0];
541  namelist.append(tempName);
542  }
543  }
544  }
545 
546  bool ok = false;
547  QString toDelete;
548  // Only display list of stretches to delete if there are stretches saved to the cube
549  if (namelist.size() >= 1) {
550  toDelete = QInputDialog::getItem((QWidget *)parent(), tr("Delete Stretch"),
551  tr("Name of Stretch to Delete:"), namelist, 0,
552  false, &ok);
553  }
554  else {
555  QMessageBox::information((QWidget *)parent(), "Information",
556  "There are no saved stretches to delete.");
557  }
558 
559  if (ok) {
560  if (icube->isReadOnly()) {
561  try {
562  cvp->cube()->reopen("rw");
563  }
564  catch(IException &) {
565  cvp->cube()->reopen("r");
566  QMessageBox::information((QWidget *)parent(), "Error",
567  "Cannot open cube read/write to delete stretch");
568  return;
569  }
570  }
571 
572  bool cubeDeleted = icube->deleteBlob(toDelete, "Stretch");
573 
574  if (!cubeDeleted) {
575  QMessageBox msgBox;
576  msgBox.setText("Stretch Could Not Be Deleted!");
577  msgBox.setInformativeText("A stretch with name: \"" + toDelete +
578  "\" Could not be found, so there was nothing to delete from the Cube.");
579  msgBox.setStandardButtons(QMessageBox::Ok);
580  msgBox.setIcon(QMessageBox::Critical);
581  msgBox.exec();
582  }
583 
584  // Don't leave open rw -- not optimal.
585  cvp->cube()->reopen("r");
586  }
587  }
588 
589 
594  MdiCubeViewport *cvp = cubeViewport();
595  Cube* icube = cvp->cube();
596  Pvl* lab = icube->label();
597 
598  // Create a list of existing Stretch names
599  QStringList namelist;
601  for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
602  if (objIter->name() == "Stretch") {
603  PvlKeyword tempKeyword = objIter->findKeyword("Name");
604  QString tempName = tempKeyword[0];
605  namelist.append(tempName);
606  }
607  }
608 
609  bool ok;
610  QString name;
611 
612  //
613  // At this time, it is NOT possible to save an RGB stretch with the same band number
614  // multiple times, if the saved stretch for each is different. If the saved stretch is the same
615  // this is okay.
616  //
617  // For example, r=1, g=1, b=1, with the same stretch for each is okay
618  // r=1, g=1, b=2, where the stretches for band 1 are the same, is okay
619  // r=1, g=1, b=1, where the the stretches for band 1 are different (red stretch !=
620  // green stretch)
621  //
622  if (!cvp->isGray()) {
623  CubeStretch redStretch, greenStretch, blueStretch;
624  if (m_advancedStretch->isVisible()) {
625  redStretch = m_advancedStretch->getRedStretch();
626  greenStretch = m_advancedStretch->getGrnStretch();
627  blueStretch = m_advancedStretch->getBluStretch();
628  }
629  else {
630  redStretch = cvp->redStretch();
631  greenStretch = cvp->greenStretch();
632  blueStretch = cvp->blueStretch();
633  }
634 
635  int redBand = cvp->redBand();
636  int greenBand = cvp->greenBand();
637  int blueBand = cvp->blueBand();
638 
639  if (((redBand == greenBand) && !(redStretch == greenStretch)) ||
640  ((redBand == blueBand) && !(redBand == blueBand)) ||
641  ((greenBand == blueBand) && !(greenBand == blueBand))) {
642  QMessageBox::information((QWidget *)parent(), "Error", "Sorry, cannot save RGB stretches which include the same band multiple times, but have different stretches for each");
643  return;
644  }
645  }
646 
647  // "Get the name for the stretch" dialog
648  QString text = QInputDialog::getText(m_advancedStretch, tr("Save Stretch"),
649  tr("Enter a name to save the stretch as:"), QLineEdit::Normal,
650  "stretch", &ok);
651 
652  if (ok) {
653  // Stretch Name Already Exists Dialog!
654  if (namelist.contains(text)) {
655  QMessageBox msgBox;
656  msgBox.setText(tr("Stretch Name Already Exists!"));
657  msgBox.setInformativeText("A stretch pair with name: \"" + text + "\" already exists and "
658  "the existing saved data will be overwritten. Are you sure you "
659  "wish to proceed?");
660  msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
661  msgBox.setIcon(QMessageBox::Warning);
662  msgBox.setDefaultButton(QMessageBox::Cancel);
663  int ret = msgBox.exec();
664 
665  switch (ret) {
666  case QMessageBox::Save:
667  break;
668  case QMessageBox::Cancel:
669  // Cancel was clicked, exit this function
670  return;
671  break;
672  default:
673  // should never be reached
674  return;
675  break;
676  }
677  }
678 
679  if (icube->isReadOnly()) {
680  // reOpen cube as read/write
681  try {
682  icube->reopen("rw");
683  }
684  catch(IException &) {
685  icube->reopen("r");
686  QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write to save stretch");
687  return;
688  }
689  }
690 
691  // If gray, only one stretch to save
692  if (cvp->isGray()) {
693  CubeStretch stretch;
694  if (m_advancedStretch->isVisible()) {
695  stretch = m_advancedStretch->getGrayStretch();
696  }
697  else {
698  stretch = cvp->grayStretch();
699  }
700 
701  // Write single stretch to cube
702  stretch.setName(text);
703  stretch.setBandNumber(cvp->grayBand());
704 
705  // Overwrite an existing stretch with the same name if it exists. The user was warned
706  // and decided to overwrite.
707  icube->write(stretch);
708  }
709  else {
710  CubeStretch redStretch, greenStretch, blueStretch;
711  if (m_advancedStretch->isVisible()) {
712  redStretch = m_advancedStretch->getRedStretch();
713  greenStretch = m_advancedStretch->getGrnStretch();
714  blueStretch = m_advancedStretch->getBluStretch();
715  }
716  else {
717  redStretch = cvp->redStretch();
718  greenStretch = cvp->greenStretch();
719  blueStretch = cvp->blueStretch();
720  }
721 
722  redStretch.setName(text);
723  redStretch.setBandNumber(cvp->redBand());
724  Blob stretchBlob = redStretch.toBlob();
725  icube->write(stretchBlob, false);
726 
727  greenStretch.setName(text);
728  greenStretch.setBandNumber(cvp->greenBand());
729  stretchBlob = greenStretch.toBlob();
730  icube->write(stretchBlob, false);
731 
732  blueStretch.setName(text);
733  blueStretch.setBandNumber(cvp->blueBand());
734  stretchBlob = blueStretch.toBlob();
735  icube->write(stretchBlob, false);
736  }
737 
738  // Don't leave open rw -- not optimal.
739  cvp->cube()->reopen("r");
740  }
741  }
742 
743 
749  }
750 
751 
758  if(m_advancedStretch->isVisible()) {
759  m_advancedStretch->enable(true);
760  //If the viewport is in gray mode
761  if(cvp->isGray() && !cvp->grayBuffer()->working()) {
762  Histogram hist(histFromBuffer(cvp->grayBuffer()));
763  Stretch stretch(cvp->grayStretch());
764  m_advancedStretch->enableGrayMode(stretch, hist);
765  }
766  //Otherwise it is in color mode
767  else if(!cvp->isGray() &&
768  !cvp->redBuffer()->working() &&
769  !cvp->greenBuffer()->working() &&
770  !cvp->blueBuffer()->working()) {
771  Histogram redHist(histFromBuffer(cvp->redBuffer()));
772  Histogram grnHist(histFromBuffer(cvp->greenBuffer()));
773  Histogram bluHist(histFromBuffer(cvp->blueBuffer()));
774  Stretch redStretch(cvp->redStretch());
775  Stretch grnStretch(cvp->greenStretch());
776  Stretch bluStretch(cvp->blueStretch());
777  m_advancedStretch->enableRgbMode(redStretch, redHist,
778  grnStretch, grnHist,
779  bluStretch, bluHist);
780  }
781  else {
782  m_advancedStretch->enable(false);
783  }
784  }
785  else {
786  m_advancedStretch->enable(false);
787  }
788  }
789 
790 
796  CubeViewport *cvp = cubeViewport();
797 
798  if(cvp == NULL) {
799  //If the current viewport is NULL and the advanced dialog is visible, hide it
800  if(m_advancedStretch->isVisible()) {
801  m_advancedStretch->hide();
802  }
803  }
804  else {
805  if(!m_advancedStretch->enabled() ||
806  m_advancedStretch->isRgbMode() != !cvp->isGray()) {
807  setCubeViewport(cvp);
808  }
809  }
810 
811  if(cvp && cvp->isGray()) {
812  m_copyBands->setEnabled(true);
813  m_stretchBandComboBox->setVisible(false);
814  m_stretchMinEdit->show();
815  m_stretchMaxEdit->show();
816  }
817  else if(cvp) {
818  m_copyBands->setEnabled(true);
819  m_stretchBandComboBox->setVisible(true);
821  }
822  else {
823  m_copyBands->setEnabled(false);
824  m_stretchBandComboBox->setVisible(false);
825  }
826 
827  if(m_advancedStretch->isVisible()) {
828  m_stretchMinEdit->setEnabled(false);
829  m_stretchMaxEdit->setEnabled(false);
830  }
831  else {
832  m_stretchMinEdit->setEnabled(true);
833  m_stretchMaxEdit->setEnabled(true);
834  }
835 
836  stretchChanged();
838  }
839 
840 
849  // Yeah this is a hack... but it's necessary to make this tool
850  // do anything while its not the active tool.
851  connect(cvp, SIGNAL(screenPixelsChanged()), this, SLOT(updateHistograms()));
852  QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
853 
854  if(bandId == (int)Gray) {
855  if(cvp->grayBuffer() && cvp->grayBuffer()->hasEntireCube()) {
856  Stretch newStretch = cvp->grayStretch();
857  newStretch.CopyPairs(stretchBuffer(cvp->grayBuffer(), rect));
858  cvp->stretchGray(newStretch);
859  }
860  else {
861  Stretch newStretch = stretchBand(cvp, (StretchBand)bandId);
862  cvp->stretchGray(newStretch);
863  }
864  }
865  else
866  {
867  if(bandId == (int)Red || bandId == (int)All) {
868  if(cvp->redBuffer() && cvp->redBuffer()->hasEntireCube()) {
869  Stretch newStretch = cvp->redStretch();
870  newStretch.CopyPairs(stretchBuffer(cvp->redBuffer(), rect));
871  cvp->stretchRed(newStretch);
872  }
873  else {
874  Stretch newStretch = stretchBand(cvp, Red);
875  cvp->stretchRed(newStretch);
876  }
877  }
878  if(bandId == (int)Green || bandId == (int)All) {
879  if(cvp->greenBuffer() && cvp->greenBuffer()->hasEntireCube()) {
880  Stretch newStretch = cvp->greenStretch();
881  newStretch.CopyPairs(stretchBuffer(cvp->greenBuffer(), rect));
882  cvp->stretchGreen(newStretch);
883  }
884  else {
885  Stretch newStretch = stretchBand(cvp, Green);
886  cvp->stretchGreen(newStretch);
887  }
888  }
889  if(bandId == (int)Blue || bandId == (int)All) {
890  if(cvp->blueBuffer() && cvp->blueBuffer()->hasEntireCube()) {
891  Stretch newStretch = cvp->blueStretch();
892  newStretch.CopyPairs(stretchBuffer(cvp->blueBuffer(), rect));
893  cvp->stretchBlue(newStretch);
894  }
895  else {
896  Stretch newStretch = stretchBand(cvp, Blue);
897  cvp->stretchBlue(newStretch);
898  }
899  }
900  }
901  stretchChanged();
902  }
903 
904 
911  MdiCubeViewport *cvp = cubeViewport();
912  if(cvp == NULL) return;
913 
914  if(m_flashButton->isDown()) {
915  if(!m_preGlobalStretches) {
916  m_preGlobalStretches = new Stretch[4];
917  m_preGlobalStretches[0] = cvp->grayStretch();
918  m_preGlobalStretches[1] = cvp->redStretch();
920  m_preGlobalStretches[3] = cvp->blueStretch();
921  }
922 
923  cvp->stretchKnownGlobal();
924  return;
925  }
926  else if(m_preGlobalStretches) {
927  if(cvp->isGray()) {
929  }
930  else {
934  }
935 
936  delete [] m_preGlobalStretches;
937  m_preGlobalStretches = NULL;
938  }
939 
940  double min = 0, max = 0;
941  //If the viewport is in gray mode
942  if(cvp->isGray()) {
943  //Get the min/max from the current stretch
944  Stretch stretch = cvp->grayStretch();
945  min = stretch.Input(0);
946  max = stretch.Input(stretch.Pairs() - 1);
947  }
948 
949  //Otherwise it is in color mode
950  else {
951  Stretch rstretch = cvp->redStretch();
952  Stretch gstretch = cvp->greenStretch();
953  Stretch bstretch = cvp->blueStretch();
954 
955  //Get the min/max from the current stretch
956  if(m_stretchBand == Red) {
957  min = rstretch.Input(0);
958  max = rstretch.Input(rstretch.Pairs() - 1);
959  }
960  else if(m_stretchBand == Green) {
961  min = gstretch.Input(0);
962  max = gstretch.Input(gstretch.Pairs() - 1);
963  }
964  else if(m_stretchBand == Blue) {
965  min = bstretch.Input(0);
966  max = bstretch.Input(bstretch.Pairs() - 1);
967  }
968  }
969 
970  //Set the min/max text fields
971  if(m_stretchBand != All || cvp->isGray()) {
972  QString strMin;
973  strMin.setNum(min);
974  m_stretchMinEdit->setText(strMin);
975 
976  QString strMax;
977  strMax.setNum(max);
978  m_stretchMaxEdit->setText(strMax);
979  }
980 
981  if(m_advancedStretch->isVisible()) {
982  if(m_stretchBand == All){
984  }
986  }
987  }
988 
989 
995  CubeViewport *cvp = cubeViewport();
996  if(cvp == NULL) return;
997 
998  if(!m_advancedStretch->isRgbMode()) {
999  Stretch grayStretch = cvp->grayStretch();
1000  grayStretch.ClearPairs();
1001  grayStretch.CopyPairs(m_advancedStretch->getGrayStretch());
1002  cvp->stretchGray(grayStretch);
1003 
1004  // send the stretch to any ChipViewports that want to listen
1005  *m_chipViewportStretch = grayStretch;
1007  }
1008  else {
1009  Stretch redStretch = cvp->redStretch();
1010  redStretch.ClearPairs();
1011  redStretch.CopyPairs(m_advancedStretch->getRedStretch());
1012  cvp->stretchRed(redStretch);
1013 
1014  Stretch grnStretch = cvp->greenStretch();
1015  grnStretch.ClearPairs();
1016  grnStretch.CopyPairs(m_advancedStretch->getGrnStretch());
1017  cvp->stretchGreen(grnStretch);
1018 
1019  Stretch bluStretch = cvp->blueStretch();
1020  bluStretch.ClearPairs();
1021  bluStretch.CopyPairs(m_advancedStretch->getBluStretch());
1022  cvp->stretchBlue(bluStretch);
1023  }
1024  stretchChanged();
1025  }
1026 
1027 
1035  MdiCubeViewport *cvp = cubeViewport();
1036  if(cvp == NULL) return;
1037 
1038  // Make sure the user didn't enter bad min/max and if so fix it
1039  double min = m_stretchMinEdit->text().toDouble();
1040  double max = m_stretchMaxEdit->text().toDouble();
1041 
1042  if(min >= max || m_stretchMinEdit->text() == "" ||
1043  m_stretchMaxEdit->text() == "") {
1044  updateTool();
1045  return;
1046  }
1047 
1048  //The viewport is in gray mode
1049  if(cvp->isGray()) {
1050  Stretch stretch = cvp->grayStretch();
1051  stretch.ClearPairs();
1052  stretch.AddPair(min, 0.0);
1053  stretch.AddPair(max, 255.0);
1054 
1055  // send the stretch to any ChipViewports that want to listen
1056  *m_chipViewportStretch = stretch;
1058 
1059  cvp->stretchGray(stretch);
1060  }
1061  //Otherwise the viewport is in color mode
1062  else {
1063  Stretch redStretch = cvp->redStretch();
1064  Stretch greenStretch = cvp->greenStretch();
1065  Stretch blueStretch = cvp->blueStretch();
1066 
1067  if(m_stretchBand == Red) {
1068  redStretch.ClearPairs();
1069  redStretch.AddPair(min, 0.0);
1070  redStretch.AddPair(max, 255.0);
1071  }
1072  if(m_stretchBand == Green) {
1073  greenStretch.ClearPairs();
1074  greenStretch.AddPair(min, 0.0);
1075  greenStretch.AddPair(max, 255.0);
1076  }
1077  if(m_stretchBand == Blue) {
1078  blueStretch.ClearPairs();
1079  blueStretch.AddPair(min, 0.0);
1080  blueStretch.AddPair(max, 255.0);
1081  }
1082 
1083  cvp->stretchRed(redStretch);
1084  cvp->stretchGreen(greenStretch);
1085  cvp->stretchBlue(blueStretch);
1086  }
1087 
1088  stretchChanged();
1089  }
1090 
1091 
1097  if(m_advancedStretch->isVisible()) return;
1098 
1099  if(cubeViewport()) {
1101  m_advancedStretch->show();
1102  }
1103  updateTool();
1104  }
1105 
1106 
1112  CubeViewport *cvp = cubeViewport();
1113  if(cvp == NULL) return;
1114 
1115  stretchGlobal(cvp);
1116  }
1117 
1118 
1123  CubeViewport *cvp = cubeViewport();
1124  if(cvp == NULL) return;
1125 
1126  cvp->forgetStretches();
1127  stretchGlobal(cvp);
1128  }
1129 
1130 
1136  cvp->stretchKnownGlobal();
1137  stretchChanged();
1138  }
1139 
1140 
1146  for(int i = 0; i < (int)cubeViewportList()->size(); i++) {
1147  CubeViewport *cvp = cubeViewportList()->at(i);
1148 
1149  stretchGlobal(cvp);
1150  }
1151  }
1152 
1153 
1159  CubeViewport *cvp = cubeViewport();
1160  if(cvp == NULL) return;
1161 
1162  stretchRegional(cvp);
1163  }
1164 
1170  try {
1171  QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
1172 
1173  stretchRect(cvp, rect);
1174  }
1175  catch (IException &e) {
1176  QString message = "Cannot stretch while the cube is still loading";
1177  QMessageBox::warning((QWidget *)parent(), "Warning", message);
1178  return;
1179  }
1180  }
1181 
1182 
1190  CubeViewport *cvp = cubeViewport();
1191  if(cvp == NULL) return;
1192  if(!rubberBandTool()->isValid()) return;
1193 
1194  QRect rubberBandRect = rubberBandTool()->rectangle();
1195  //Return if the width or height is zero
1196  if(rubberBandRect.width() == 0 || rubberBandRect.height() == 0) return;
1197 
1198  stretchRect(cvp, rubberBandRect);
1199  }
1200 
1201 
1208  void StretchTool::stretchRect(CubeViewport *cvp, QRect rect) {
1209  Stretch newStretch;
1210  if(cvp->isGray()) {
1211  newStretch = cvp->grayStretch();
1212  newStretch.ClearPairs();
1213  newStretch.CopyPairs(stretchBuffer(cvp->grayBuffer(), rect));
1214  cvp->stretchGray(newStretch);
1215 
1216  // send the stretch to any ChipViewports that want to listen
1217  *m_chipViewportStretch = newStretch;
1219  }
1220  else {
1221  if (m_stretchBand==Red || m_stretchBand==All) {
1222  newStretch = cvp->redStretch();
1223  newStretch.ClearPairs();
1224  newStretch.CopyPairs(stretchBuffer(cvp->redBuffer(), rect));
1225  cvp->stretchRed(newStretch);
1226  }
1228  newStretch = cvp->greenStretch();
1229  newStretch.ClearPairs();
1230  newStretch.CopyPairs(stretchBuffer(cvp->greenBuffer(), rect));
1231  cvp->stretchGreen(newStretch);
1232  }
1233  if (m_stretchBand==Blue || m_stretchBand==All){
1234  newStretch = cvp->blueStretch();
1235  newStretch.ClearPairs();
1236  newStretch.CopyPairs(stretchBuffer(cvp->blueBuffer(), rect));
1237  cvp->stretchBlue(newStretch);
1238  }
1239  if(m_stretchBand != Red && m_stretchBand != Blue &&
1240  m_stretchBand != Green && m_stretchBand != All) {
1242  "Unknown stretch band",
1243  _FILEINFO_);
1244  }
1245  }
1246 
1247  stretchChanged();
1248  }
1249 
1250 
1258  void StretchTool::mouseButtonRelease(QPoint start, Qt::MouseButton s) {
1259  CubeViewport *cvp = cubeViewport();
1260  if(cvp == NULL) return;
1261 
1262  // Call the parent Tool function to reset the Warning as different activity is
1263  // taking place
1264  Tool::mouseButtonRelease(start, s);
1265 
1266  if(s == Qt::RightButton) {
1267  stretchGlobal(cvp);
1268 
1269  // notify any ChipViewports listening that the CubeViewport was stretched
1270  // back to global
1271  emit stretchChipViewport(NULL, cvp);
1272 
1273  // Resets the RubberBandTool on screen.
1275  }
1276  }
1277 
1283  rubberBandTool()->enable(RubberBandTool::RectangleMode);
1284  rubberBandTool()->setDrawActiveViewportOnly(true);
1285  }
1286 
1287 
1294  CubeViewport *cvp = cubeViewport();
1295  if(cvp == NULL) return;
1296 
1297  double min = m_stretchMinEdit->text().toDouble();
1298  double max = m_stretchMaxEdit->text().toDouble();
1299 
1300  Stretch stretch;
1301  if(cvp->isGray()) {
1302  stretch = cvp->grayStretch();
1303  stretch.ClearPairs();
1304  stretch.AddPair(min, 0.0);
1305  stretch.AddPair(max, 255.0);
1306  }
1307  else if(m_stretchBand == Red) {
1308  stretch = cvp->redStretch();
1309  stretch.ClearPairs();
1310  stretch.AddPair(min, 0.0);
1311  stretch.AddPair(max, 255.0);
1312  cvp->stretchGreen(stretch);
1313  cvp->stretchBlue(stretch);
1314  }
1315  else if(m_stretchBand == Green) {
1316  stretch = cvp->greenStretch();
1317  stretch.ClearPairs();
1318  stretch.AddPair(min, 0.0);
1319  stretch.AddPair(max, 255.0);
1320  cvp->stretchRed(stretch);
1321  cvp->stretchBlue(stretch);
1322  }
1323  else if(m_stretchBand == Blue) {
1324  stretch = cvp->blueStretch();
1325  stretch.ClearPairs();
1326  stretch.AddPair(min, 0.0);
1327  stretch.AddPair(max, 255.0);
1328  cvp->stretchRed(stretch);
1329  cvp->stretchGreen(stretch);
1330  }
1331  else {
1332  return;
1333  }
1334 
1335  cvp->setAllBandStretches(stretch);
1336  }
1337 
1338 
1345  CubeViewport *thisViewport = cubeViewport();
1346 
1347  if(thisViewport == NULL) return;
1348 
1349  for(int i = 0; i < (int)cubeViewportList()->size(); i++) {
1350  CubeViewport *cvp = cubeViewportList()->at(i);
1351 
1352  if(thisViewport->isGray() && cvp->isGray()) {
1353  Stretch newStretch(cvp->grayStretch());
1354  newStretch.CopyPairs(thisViewport->grayStretch());
1355  cvp->stretchGray(newStretch);
1356  }
1357  else if(!thisViewport->isGray() && !cvp->isGray()) {
1358  Stretch newStretchRed(cvp->redStretch());
1359  newStretchRed.CopyPairs(thisViewport->redStretch());
1360  cvp->stretchRed(newStretchRed);
1361 
1362  Stretch newStretchGreen(cvp->greenStretch());
1363  newStretchGreen.CopyPairs(thisViewport->greenStretch());
1364  cvp->stretchGreen(newStretchGreen);
1365 
1366  Stretch newStretchBlue(cvp->blueStretch());
1367  newStretchBlue.CopyPairs(thisViewport->blueStretch());
1368  cvp->stretchBlue(newStretchBlue);
1369  }
1370  else if(!thisViewport->isGray() && cvp->isGray()) {
1371  // don't copy rgb to gray
1372  }
1373  else if(thisViewport->isGray() && !cvp->isGray()) {
1374  // don't copy gray stretches to rgb
1375  }
1376  }
1377 
1378  stretchChanged();
1379  }
1380 
1381 
1389  //Get the statistics and histogram from the region
1390  Statistics stats = statsFromBuffer(buffer, rect);
1391  Stretch stretch;
1392  if(stats.ValidPixels() > 1 &&
1393  fabs(stats.Minimum() - stats.Maximum()) > DBL_EPSILON) {
1394  Histogram hist = histFromBuffer(buffer, rect,
1395  stats.BestMinimum(), stats.BestMaximum());
1396 
1397  if(fabs(hist.Percent(0.5) - hist.Percent(99.5)) > DBL_EPSILON) {
1398  stretch.AddPair(hist.Percent(0.5), 0.0);
1399  stretch.AddPair(hist.Percent(99.5), 255.0);
1400  }
1401  }
1402 
1403  if(stretch.Pairs() == 0) {
1404  stretch.AddPair(-DBL_MAX, 0.0);
1405  stretch.AddPair(DBL_MAX, 255.0);
1406  }
1407 
1408  return stretch;
1409  }
1410 
1411 
1419 
1420  int bandNum = cvp->grayBand();
1421  Stretch stretch = cvp->grayStretch();
1422  if(band == Red) {
1423  bandNum = cvp->redBand();
1424  stretch = cvp->redStretch();
1425  }
1426  else if(band == Green) {
1427  bandNum = cvp->greenBand();
1428  stretch = cvp->greenStretch();
1429  }
1430  else if(band == Blue) {
1431  bandNum = cvp->blueBand();
1432  stretch = cvp->blueStretch();
1433  }
1434 
1435  Statistics stats = statsFromCube(cvp->cube(), bandNum);
1436  Histogram hist = histFromCube(cvp->cube(), bandNum,
1437  stats.BestMinimum(), stats.BestMaximum());
1438 
1439  stretch.ClearPairs();
1440  if(fabs(hist.Percent(0.5) - hist.Percent(99.5)) > DBL_EPSILON) {
1441  stretch.AddPair(hist.Percent(0.5), 0.0);
1442  stretch.AddPair(hist.Percent(99.5), 255.0);
1443  }
1444  else {
1445  stretch.AddPair(-DBL_MAX, 0.0);
1446  stretch.AddPair(DBL_MAX, 255.0);
1447  }
1448 
1449  return stretch;
1450  }
1451 
1462  Statistics stats;
1463  Brick brick(cube->sampleCount(), 1, 1, cube->pixelType());
1464 
1465  for(int line = 0; line < cube->lineCount(); line++) {
1466  brick.SetBasePosition(0, line, band);
1467  cube->read(brick);
1468  stats.AddData(brick.DoubleBuffer(), cube->sampleCount());
1469  }
1470 
1471  return stats;
1472  }
1473 
1474 
1485  QRect rect) {
1486  if(buffer->working()) {
1488  "Cannot stretch while the cube is still loading",
1489  _FILEINFO_);
1490  }
1491 
1492  QRect dataArea = QRect(buffer->bufferXYRect().intersected(rect));
1493  Statistics stats;
1494 
1495  for(int y = dataArea.top();
1496  !dataArea.isNull() && y <= dataArea.bottom();
1497  y++) {
1498  const std::vector<double> &line = buffer->getLine(y - buffer->bufferXYRect().top());
1499 
1500  for(int x = dataArea.left(); x < dataArea.right(); x++) {
1501  stats.AddData(line[x - buffer->bufferXYRect().left()]);
1502  }
1503  }
1504 
1505  return stats;
1506  }
1507 
1520  double min, double max) {
1521  Histogram hist(min, max);
1522  Brick brick(cube->sampleCount(), 1, 1, cube->pixelType());
1523 
1524  for(int line = 0; line < cube->lineCount(); line++) {
1525  brick.SetBasePosition(0, line, band);
1526  cube->read(brick);
1527  hist.AddData(brick.DoubleBuffer(), cube->sampleCount());
1528  }
1529 
1530  return hist;
1531  }
1532 
1533 
1542  Statistics stats = statsFromBuffer(buffer, buffer->bufferXYRect());
1543  return histFromBuffer(buffer, buffer->bufferXYRect(),
1544  stats.BestMinimum(), stats.BestMaximum());
1545 
1546  }
1547 
1548 
1561  QRect rect, double min, double max) {
1562  QRect dataArea = QRect(buffer->bufferXYRect().intersected(rect));
1563 
1564  try {
1565  Histogram hist(min, max);
1566 
1567  for(int y = dataArea.top(); !dataArea.isNull() && y <= dataArea.bottom(); y++) {
1568  const std::vector<double> &line = buffer->getLine(y - buffer->bufferXYRect().top());
1569  hist.AddData(&line.front() + (dataArea.left() - buffer->bufferXYRect().left()), dataArea.width());
1570  }
1571 
1572  return hist;
1573  }
1574  catch(IException &e) {
1575  // get the min and max DN values of the data area
1576  IString sMin(min);
1577  IString sMax(max);
1578  std::string msg = "Insufficient data Min [" + sMin + "], Max [" + sMax + "]";
1579  msg += " in the stretch area.";
1580 
1581  // Emit signal to the parent tool to display Warning object with the warning message
1582  //emit warningSignal(msg, e.Errors());
1583 
1584  throw IException(e, IException::Unknown, msg, _FILEINFO_);
1585  }
1586  }
1587 
1588 
1589 
1594 
1596  m_stretchBandComboBox->currentIndex()
1597  ).toInt();
1598 
1599  if(m_stretchBand == All) {
1600  m_stretchMinEdit->hide();
1601  m_stretchMaxEdit->hide();
1602  }
1603  else {
1604  m_stretchMinEdit->show();
1605  m_stretchMaxEdit->show();
1606  }
1607  stretchChanged();
1608  }
1609 
1610 
1725 }
Isis::Brick::SetBasePosition
void SetBasePosition(const int start_sample, const int start_line, const int start_band)
This method is used to set the base position of the shape buffer.
Definition: Brick.h:120
Isis::AdvancedStretchDialog::isRgbMode
bool isRgbMode() const
Returns true if the dialog is displaying the RGB advanced stretches.
Definition: AdvancedStretchDialog.cpp:340
Isis::ViewportBuffer
Reads and stores visible DN values.
Definition: ViewportBuffer.h:63
Isis::AdvancedStretchDialog::restoreRgbStretch
void restoreRgbStretch(CubeStretch red, CubeStretch green, CubeStretch blue)
Restores a saved RGB stretch from the cube.
Definition: AdvancedStretchDialog.cpp:194
Isis::MdiCubeViewport
Cube display widget for certain Isis MDI applications.
Definition: MdiCubeViewport.h:39
QWidget
Isis::CubeViewport::redBuffer
ViewportBuffer * redBuffer()
Returns the red viewport buffer (Will be NULL if in Gray mode.)
Definition: CubeViewport.h:421
Isis::CubeViewport::setAllBandStretches
void setAllBandStretches(Stretch stretch)
Sets a stretch for all bands.
Definition: CubeViewport.cpp:1983
Isis::StretchTool::m_stretchBandComboBox
QComboBox * m_stretchBandComboBox
Stretch combo box.
Definition: StretchTool.h:194
Isis::StretchTool::stretchChipViewport
void stretchChipViewport(Stretch *, CubeViewport *)
when a viewport is stretched, send the stretch and the viewport associated with it to any ChipViewpor...
Isis::Statistics
This class is used to accumulate statistics on double arrays.
Definition: Statistics.h:94
Isis::AdvancedStretchDialog::updateHistogram
void updateHistogram(const Histogram &grayHist)
This calls setHistogram on the gray advanced stretches.
Definition: AdvancedStretchDialog.cpp:306
Isis::Statistics::AddData
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Definition: Statistics.cpp:141
Isis::ViewportBuffer::getLine
const std::vector< double > & getLine(int line)
Retrieves a line from the buffer.
Definition: ViewportBuffer.cpp:342
Isis::Histogram::Percent
double Percent(const double percent) const
Computes and returns the value at X percent of the histogram.
Definition: Histogram.cpp:351
Isis::RubberBandTool::setDrawActiveViewportOnly
void setDrawActiveViewportOnly(bool activeOnly=false)
This called to set whether rubber band is drawn on active viewport only rather than all linked viewpo...
Definition: RubberBandTool.cpp:333
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::StretchTool::stretchBandChanged
void stretchBandChanged(int)
The selected band for stretching changed.
Definition: StretchTool.cpp:1593
Isis::Tool::cubeViewportList
CubeViewportList * cubeViewportList() const
Return the list of cubeviewports.
Definition: Tool.cpp:390
Isis::StretchTool::stretchBuffer
static Stretch stretchBuffer(ViewportBuffer *buffer, QRect rect)
This method computes the stretch over a region using the viewport buffer.
Definition: StretchTool.cpp:1388
Isis::StretchTool::m_copyBands
QAction * m_copyBands
Copy band stretch action.
Definition: StretchTool.h:192
Isis::PvlObject::beginObject
PvlObjectIterator beginObject()
Returns the index of the beginning object.
Definition: PvlObject.h:235
Isis::Cube::read
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:807
Isis::Tool
Base class for the Qisis tools.
Definition: Tool.h:67
Isis::StretchTool::All
@ All
All Bands.
Definition: StretchTool.h:101
Isis::CubeViewport::isGray
bool isGray() const
Definition: CubeViewport.h:189
Isis::AdvancedStretchDialog::getGrayStretch
CubeStretch getGrayStretch()
This returns the advanced stretch's stretch for gray.
Definition: AdvancedStretchDialog.cpp:350
Isis::StretchTool::setStretchAcrossBands
void setStretchAcrossBands()
Sets the stretch for all the bands in the active viewport to the current stretch.
Definition: StretchTool.cpp:1293
Isis::IException::Unknown
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:118
Isis::AdvancedStretchDialog::updateStretch
void updateStretch(CubeViewport *)
This calls setStretch on all applicable advanced stretches.
Definition: AdvancedStretchDialog.cpp:260
Isis::Buffer::DoubleBuffer
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition: Buffer.h:138
Isis::Stretch
Pixel value mapper.
Definition: Stretch.h:58
QMenu
Isis::Tool::toolIconDir
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:113
Isis::StretchTool::stretchGlobalAllBands
void stretchGlobalAllBands()
This resets the stretch across all bands.
Definition: StretchTool.cpp:1122
Isis::Statistics::Maximum
double Maximum() const
Returns the absolute maximum double found in all data passed through the AddData method.
Definition: Statistics.cpp:403
Isis::AdvancedStretchDialog
Advanced Stretch Dialog.
Definition: AdvancedStretchDialog.h:30
Isis::RubberBandTool::enable
void enable(RubberBandMode mode, bool showIndicatorColors=false)
This is called when changing modes or turning on.
Definition: RubberBandTool.cpp:302
Isis::StretchTool::m_stretchRegional
QAction * m_stretchRegional
Regional stretch action.
Definition: StretchTool.h:190
Isis::StretchTool::m_stretchGlobal
QAction * m_stretchGlobal
Global stretch action.
Definition: StretchTool.h:189
Isis::Tool::mouseButtonRelease
virtual void mouseButtonRelease(QPoint p, Qt::MouseButton s)
Resets the Warning to Nowarning when a different activity occurs on the application.
Definition: Tool.cpp:380
Isis::StretchTool::screenPixelsChanged
void screenPixelsChanged()
This is called when the visible area changes.
Definition: StretchTool.cpp:747
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::CubeViewport::forgetStretches
void forgetStretches()
Resets all remembered stretches.
Definition: CubeViewport.cpp:1973
Isis::StretchTool::createToolBarWidget
QWidget * createToolBarWidget(QStackedWidget *parent)
Creates the widget to add to the tool bar.
Definition: StretchTool.cpp:145
Isis::StretchTool::updateHistograms
void updateHistograms()
This updates the visible histograms in the advanced stretch, if present.
Definition: StretchTool.cpp:331
Isis::Stretch::Pairs
int Pairs() const
Returns the number of stretch pairs.
Definition: Stretch.h:162
Isis::StretchTool::m_stretchRegionalButton
QToolButton * m_stretchRegionalButton
Regional Stretch Button.
Definition: StretchTool.h:186
Isis::CubeStretch::setName
void setName(QString name)
Set the Stretch name.
Definition: CubeStretch.cpp:135
Isis::CubeStretch
Stores stretch information for a cube.
Definition: CubeStretch.h:27
Isis::StretchTool::~StretchTool
~StretchTool()
Destructor.
Definition: StretchTool.cpp:94
Isis::CubeViewport::greenStretch
CubeStretch greenStretch() const
Return the green band stretch.
Definition: CubeViewport.cpp:1674
Isis::Statistics::ValidPixels
BigInt ValidPixels() const
Returns the total number of valid pixels processed.
Definition: Statistics.cpp:433
Isis::StretchTool::stretchBand
static Stretch stretchBand(CubeViewport *cvp, StretchBand band)
This method computes the stretch over the entire cube.
Definition: StretchTool.cpp:1418
QStringList
Isis::Brick
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:45
Isis::StretchTool::Red
@ Red
Red Band.
Definition: StretchTool.h:98
QComboBox
Isis::CubeViewport::blueBand
int blueBand() const
Definition: CubeViewport.h:209
Isis::StretchTool::statsFromBuffer
static Statistics statsFromBuffer(ViewportBuffer *buffer, QRect rect)
This method will calculate and return the statistics for a given region and viewport buffer.
Definition: StretchTool.cpp:1484
Isis::CubeViewport::redStretch
CubeStretch redStretch() const
Return the red band stretch.
Definition: CubeViewport.cpp:1668
Isis::StretchTool::stretchRequested
void stretchRequested(MdiCubeViewport *cvp, int bandId)
The cube viewport requested a stretch at this time, give it to the viewport.
Definition: StretchTool.cpp:848
Isis::StretchTool::warningSignal
void warningSignal(std::string &pStr, const std::string pExStr)
Shows a warning.
Isis::AdvancedStretchDialog::getBluStretch
CubeStretch getBluStretch()
This returns the advanced stretch's stretch for blue.
Definition: AdvancedStretchDialog.cpp:398
Isis::CubeViewport::stretchKnownGlobal
void stretchKnownGlobal()
List<Tool *> p This stretches to the global stretch.
Definition: CubeViewport.cpp:2153
Isis::PvlObject::PvlObjectIterator
QList< PvlObject >::iterator PvlObjectIterator
The counter for objects.
Definition: PvlObject.h:227
Isis::AdvancedStretchDialog::restoreGrayStretch
void restoreGrayStretch(CubeStretch stretch)
Restores a saved grayscale stretch from the cube.
Definition: AdvancedStretchDialog.cpp:176
Isis::StretchTool::m_copyButton
QToolButton * m_copyButton
Copy Button.
Definition: StretchTool.h:184
Isis::StretchTool::stretchRect
void stretchRect(CubeViewport *cvp, QRect rect)
stretch the specified CubeViewport with the given rect
Definition: StretchTool.cpp:1208
Isis::CubeViewport::blueStretch
CubeStretch blueStretch() const
Return the blue band stretch.
Definition: CubeViewport.cpp:1680
Isis::StretchTool::m_flashButton
QPushButton * m_flashButton
Button to press for global stretch.
Definition: StretchTool.h:187
Isis::StretchTool::showAdvancedDialog
void showAdvancedDialog()
This methods shows and updates the advanced dialog.
Definition: StretchTool.cpp:1096
Isis::CubeViewport::grayBand
int grayBand() const
Definition: CubeViewport.h:194
Isis::AdvancedStretchDialog::updateHistograms
void updateHistograms(const Histogram &redHist, const Histogram &grnHist, const Histogram &bluHist)
This calls setHistogram on all of the advanced stretches.
Definition: AdvancedStretchDialog.cpp:284
Isis::StretchTool::rubberBandComplete
void rubberBandComplete()
This method is called when the RubberBandTool is complete.
Definition: StretchTool.cpp:1189
Isis::Cube::lineCount
int lineCount() const
Definition: Cube.cpp:1734
Isis::ViewportMainWindow
This was called the Qisis MainWindow.
Definition: ViewportMainWindow.h:43
Isis::StretchTool::m_chipViewportStretch
Stretch * m_chipViewportStretch
ChipViewport's stretch.
Definition: StretchTool.h:204
Isis::CubeViewport::grayStretch
CubeStretch grayStretch() const
Return the gray band stretch.
Definition: CubeViewport.cpp:1662
Isis::Stretch::CopyPairs
void CopyPairs(const Stretch &other)
Copies the stretch pairs from another Stretch object, but maintains special pixel values.
Definition: Stretch.cpp:392
Isis::toInt
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:93
Isis::Histogram::AddData
virtual void AddData(const double *data, const unsigned int count)
Add an array of doubles to the histogram counters.
Definition: Histogram.cpp:232
Isis::Statistics::Minimum
double Minimum() const
Returns the absolute minimum double found in all data passed through the AddData method.
Definition: Statistics.cpp:382
Isis::StretchTool::m_globalButton
QToolButton * m_globalButton
Global Button.
Definition: StretchTool.h:185
Isis::StretchTool::Blue
@ Blue
Blue Band.
Definition: StretchTool.h:100
Isis::StretchTool::histFromCube
static Histogram histFromCube(Cube *cube, int band, double min, double max)
This method will calculate and return the histogram for a given cube and band.
Definition: StretchTool.cpp:1519
Isis::StretchTool::histFromBuffer
static Histogram histFromBuffer(ViewportBuffer *buffer)
Given a viewport buffer, this calculates a histogram.
Definition: StretchTool.cpp:1541
Isis::StretchTool::Gray
@ Gray
Gray Band.
Definition: StretchTool.h:97
Isis::Stretch::AddPair
void AddPair(const double input, const double output)
Adds a stretch pair to the list of pairs.
Definition: Stretch.cpp:48
Isis::Stretch::ClearPairs
void ClearPairs()
Clears the stretch pairs.
Definition: Stretch.h:170
Isis::AdvancedStretchDialog::getRedStretch
CubeStretch getRedStretch()
This returns the advanced stretch's stretch for red.
Definition: AdvancedStretchDialog.cpp:366
Isis::Cube::sampleCount
int sampleCount() const
Definition: Cube.cpp:1807
Isis::Statistics::BestMaximum
double BestMaximum(const double percent=99.5) const
This method returns the better of the absolute maximum or the Chebyshev maximum.
Definition: Statistics.cpp:625
Isis::StretchTool::advancedStretchChanged
void advancedStretchChanged()
This is called when one of the advanced stretches changed.
Definition: StretchTool.cpp:994
Isis::StretchTool::m_stretchMaxEdit
QLineEdit * m_stretchMaxEdit
Max. line edit.
Definition: StretchTool.h:197
Isis::StretchTool::m_stretchBand
StretchBand m_stretchBand
Current stretch band.
Definition: StretchTool.h:199
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::StretchTool::m_advancedStretch
AdvancedStretchDialog * m_advancedStretch
The advanced dialog.
Definition: StretchTool.h:182
Isis::CubeViewport
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:122
Isis::StretchTool::enableRubberBandTool
void enableRubberBandTool()
This method enables the RubberBandTool.
Definition: StretchTool.cpp:1282
Isis::ViewportBuffer::bufferXYRect
QRect bufferXYRect()
Returns a rect, in screen pixels, of the area this buffer covers.
Definition: ViewportBuffer.cpp:1257
Isis::StretchTool::changeStretch
void changeStretch()
This method is called when the stretch has changed and sets the min/max text fields to the correct va...
Definition: StretchTool.cpp:1034
Isis::AdvancedStretchDialog::enable
void enable(bool enable)
Sets the enabled state to enable.
Definition: AdvancedStretchDialog.h:74
Isis::StretchTool::updateAdvStretchDialogforAll
void updateAdvStretchDialogforAll(void)
Update the streches and corresponding histograms for all the colors Red, Green and Blue for Stretch A...
Definition: StretchTool.cpp:379
Isis::StretchTool::stretchRegional
void stretchRegional()
Does a regional stretch for the active viewport.
Definition: StretchTool.cpp:1158
Isis::ToolPad
Definition: ToolPad.h:14
Isis::CubeStretch::toBlob
Isis::Blob toBlob() const
Serialize the CubeStretch to a Blob.
Definition: CubeStretch.cpp:84
Isis::Cube::deleteBlob
bool deleteBlob(QString BlobName, QString BlobType)
This method will delete a blob label object from the cube as specified by the Blob type and name.
Definition: Cube.cpp:1955
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
Isis::StretchTool::updateTool
void updateTool()
Updates the stretch tool.
Definition: StretchTool.cpp:795
std
Namespace for the standard library.
Isis::CubeViewport::stretchGreen
void stretchGreen(const QString &string)
Apply stretch pairs to green bands.
Definition: CubeViewport.cpp:2131
Isis::AdvancedStretchDialog::enableGrayMode
void enableGrayMode(Stretch &grayStretch, Histogram &grayHist)
This displays a gray advanced stretch.
Definition: AdvancedStretchDialog.cpp:151
Isis::AdvancedStretchDialog::updateForRGBMode
void updateForRGBMode(Stretch &redStretch, Histogram &redHist, Stretch &grnStretch, Histogram &grnHist, Stretch &bluStretch, Histogram &bluHist)
Update the stretch and histogram for all the bands for All BandId option.
Definition: AdvancedStretchDialog.cpp:122
Isis::CubeStretch::setBandNumber
void setBandNumber(int bandNumber)
Set the band number for the stretch.
Definition: CubeStretch.cpp:165
Isis::CubeViewport::blueBuffer
ViewportBuffer * blueBuffer()
Returns the blue viewport buffer (Will be NULL if in Gray mode.)
Definition: CubeViewport.h:441
Isis::StretchTool::loadStretchFromCube
void loadStretchFromCube()
Restores a saved stretch from the cube.
Definition: StretchTool.cpp:407
Isis::Cube::isReadOnly
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true.
Definition: Cube.cpp:213
Isis::Cube::pixelType
PixelType pixelType() const
Definition: Cube.cpp:1758
Isis::Histogram
Container of a cube histogram.
Definition: Histogram.h:74
Isis::Statistics::BestMinimum
double BestMinimum(const double percent=99.5) const
This method returns the better of the absolute minimum or the Chebyshev minimum.
Definition: Statistics.cpp:598
Isis::StretchTool::mouseButtonRelease
void mouseButtonRelease(QPoint p, Qt::MouseButton s)
This method will call a global stretch if the right mouse button is released.
Definition: StretchTool.cpp:1258
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::Cube::write
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition: Cube.cpp:971
QMap
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:22
Isis::StretchTool::setStretchAllViewports
void setStretchAllViewports()
Sets the stretch for all the viewports to the current stretch in the active viewport.
Definition: StretchTool.cpp:1344
Isis::StretchTool::statsFromCube
static Statistics statsFromCube(Cube *cube, int band)
This method will calculate and return the statistics for a given cube and band.
Definition: StretchTool.cpp:1461
Isis::ViewportBuffer::hasEntireCube
bool hasEntireCube()
Method to see if the entire cube is in the buffer.
Definition: ViewportBuffer.cpp:423
Isis::AdvancedStretchDialog::enabled
bool enabled()
Returns true if the advanced stretch is enabled.
Definition: AdvancedStretchDialog.h:65
Isis::StretchTool::m_stretchMinEdit
QLineEdit * m_stretchMinEdit
Min. line edit.
Definition: StretchTool.h:196
Isis::StretchTool::Green
@ Green
Green Band.
Definition: StretchTool.h:99
Isis::StretchTool::StretchBand
StretchBand
Enum to store the bands.
Definition: StretchTool.h:96
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::StretchTool::stretchChanged
void stretchChanged()
This method is called when the stretch has changed and sets the min/max text fields to the correct va...
Definition: StretchTool.cpp:910
Isis::StretchTool::setCubeViewport
void setCubeViewport(CubeViewport *)
This updates the advanced stretch to use the given viewport.
Definition: StretchTool.cpp:757
Isis::CubeViewport::grayBuffer
ViewportBuffer * grayBuffer()
Returns the gray viewport buffer (Will be NULL if in RGB mode.)
Definition: CubeViewport.h:411
Isis::Blob
Definition: Blob.h:51
Isis::StretchTool::stretchGlobal
void stretchGlobal()
Does a global stretch for the active viewport.
Definition: StretchTool.cpp:1111
QAction
Isis::StretchTool::deleteFromCube
void deleteFromCube()
Deletes a saved stretch from the cube.
Definition: StretchTool.cpp:527
Isis::CubeViewport::cube
Cube * cube() const
Definition: CubeViewport.h:338
Isis::StretchTool::addTo
void addTo(QMenu *menu)
Adds the stretch action to the given menu.
Definition: StretchTool.cpp:131
Isis::AdvancedStretchDialog::getGrnStretch
CubeStretch getGrnStretch()
This returns the advanced stretch's stretch for green.
Definition: AdvancedStretchDialog.cpp:382
Isis::CubeViewport::redBand
int redBand() const
Definition: CubeViewport.h:199
Isis::StretchTool::toolPadAction
QAction * toolPadAction(ToolPad *pad)
Adds the stretch action to the toolpad.
Definition: StretchTool.cpp:111
Isis::StretchTool::m_preGlobalStretches
Stretch * m_preGlobalStretches
Stretches before global button pressed.
Definition: StretchTool.h:202
Isis::RubberBandTool::rectangle
QRect rectangle()
This method returns a rectangle from the vertices set by the RubberBandTool.
Definition: RubberBandTool.cpp:966
Isis::Tool::cubeViewport
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:197
Isis::Cube::readCubeStretch
CubeStretch readCubeStretch(QString name="CubeStretch", const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
Read a Stretch from a cube.
Definition: Cube.cpp:912
Isis::CubeViewport::stretchGray
void stretchGray(const QString &string)
Apply stretch pairs to gray band.
Definition: CubeViewport.cpp:2107
Isis::CubeViewport::stretchBlue
void stretchBlue(const QString &string)
Apply stretch pairs to blue bands.
Definition: CubeViewport.cpp:2143
Isis::CubeViewport::greenBuffer
ViewportBuffer * greenBuffer()
Returns the green viewport buffer (Will be NULL if in Gray mode.)
Definition: CubeViewport.h:431
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::CubeViewport::greenBand
int greenBand() const
Definition: CubeViewport.h:204
Isis::Cube::reopen
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition: Cube.cpp:774
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126
Isis::StretchTool::saveStretchToCube
void saveStretchToCube()
Saves a strech to the cube.
Definition: StretchTool.cpp:593
Isis::Stretch::Input
double Input(const int index) const
Returns the value of the input side of the stretch pair at the specified index.
Definition: Stretch.cpp:287
Isis::StretchTool::stretchGlobalAllViewports
void stretchGlobalAllViewports()
Does a global stretch for all the viewports.
Definition: StretchTool.cpp:1145
Isis::ViewportBuffer::working
bool working()
This tests if queued actions exist in the viewport buffer.
Definition: ViewportBuffer.cpp:759
Isis::AdvancedStretchDialog::enableRgbMode
void enableRgbMode(Stretch &redStretch, Histogram &redHist, Stretch &grnStretch, Histogram &grnHist, Stretch &bluStretch, Histogram &bluHist)
This displays RGB advanced stretches.
Definition: AdvancedStretchDialog.cpp:52
Isis::CubeViewport::stretchRed
void stretchRed(const QString &string)
Apply stretch pairs to red bands.
Definition: CubeViewport.cpp:2119

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:17:20