1#include "StretchTool.h"
14#include <QStackedWidget>
18#include <QInputDialog>
20#include "AdvancedStretchDialog.h"
23#include "CubeViewport.h"
25#include "IException.h"
27#include "MainWindow.h"
28#include "MdiCubeViewport.h"
29#include "RubberBandTool.h"
30#include "Statistics.h"
33#include "ViewportBuffer.h"
34#include "ViewportMainWindow.h"
37#include "CubeStretch.h"
67 QPushButton *hiddenButton =
new QPushButton();
68 hiddenButton->setVisible(
false);
69 hiddenButton->setDefault(
true);
84 if (parentMainWindow) {
85 connect(
this, SIGNAL(
warningSignal(std::string &,
const std::string)),
86 parentMainWindow, SLOT(displayWarning(std::string &,
const std::string &)));
113 action->setIcon(QPixmap(
toolIconDir() +
"/stretch_global.png"));
114 action->setToolTip(
"Stretch (S)");
115 action->setShortcut(Qt::Key_S);
117 "<b>Function:</b> Change the stretch range of the cube.\
118 <p><b>Shortcut:</b> S</p> ";
119 action->setWhatsThis(text);
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");
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);
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.";
190 "<b>Function:</b> Select the minimum & maximum value types to \
191 set the stretch to. The four options are: \
192 <p>- Default: Min and max values are set to the \
193 0.5 and 99.5 percentiles, respectively. \
194 <p>- Best: The better of the absolute min/max or the \
195 Chebyshev min/max. The better value is considered the value \
196 closest to the mean. \
197 <p>- Absolute: The absolute min/max value of all valid pixels. \
198 <p>- Chebyshev: The min/max value such that a certain percentage \
199 of data will fall within K standard deviations of the average \
200 (Chebyshev's Theorem). It can be used to obtain a value that \
201 does not include statistical outliers.";
210 QDoubleValidator *dval =
new QDoubleValidator(hbox);
215 "<b>Function:</b> Shows the current minimum pixel value. Pixel values \
216 below minimum are shown as black. Pixel values above the maximum \
217 are shown as white or the highest intensity of red/green/blue \
218 if in color. Pixel values between the minimum and maximum are stretched \
219 linearly between black and white (or color component). \
220 <p><b>Hint:</b> You can manually edit the minimum but it must be \
221 less than the maximum.";
231 "<b>Function:</b> Shows the current maximum pixel value. Pixel values \
232 below minimum are shown as black. Pixel values above the maximum \
233 are shown as white or the highest intensity of red/green/blue \
234 if in color. Pixel values between the minimum and maximum are stretched \
235 linearly between black and white (or color component). \
236 <p><b>Hint:</b> You can manually edit the maximum but it must be \
237 greater than the minimum";
251 copyAll->setIcon(QPixmap(
toolIconDir() +
"/copy_stretch.png"));
252 copyAll->setText(
"to All Viewports");
255 copyMenu->addAction(copyAll);
262 m_copyButton->setPopupMode(QToolButton::MenuButtonPopup);
267 "<b>Function:</b> Copy the current stretch to all the \
268 active viewports. Or use the drop down menu to copy the current stretch \
269 to all the bands in the active viewport. \
270 <p><b>Hint:</b> Can reset the stretch to an automaticaly computed \
271 stretch by using the 'Reset' stretch button option. </p>";
275 currentView->setText(
"Active Viewport");
276 currentView->setIcon(QPixmap(
toolIconDir() +
"/global_stretch.png"));
277 globalMenu->addAction(currentView);
278 connect(currentView, SIGNAL(triggered(
bool)),
this, SLOT(
stretchGlobal()));
281 globalAll->setText(
"All Viewports");
282 globalMenu->addAction(globalAll);
286 globalBands->setText(
"All Bands");
287 globalMenu->addAction(globalBands);
298 "<b>Function:</b> Reset the stretch to be automatically computed "
299 "using the statisics from the entire image. Use the drop down menu "
300 "to reset the stretch for all the bands in the active viewport or "
301 "to reset the stretch for all the viewports.";
304 QPushButton *advancedButton =
new QPushButton(
"Advanced");
309 "<b>Function:</b> While this button is pressed down, the visible stretch "
310 "will be the automatically computed stretch using the statisics from the "
311 "entire image. The original stretch is restored once you let up on this "
318 QPushButton *saveToCubeButton =
new QPushButton(
"Save");
319 connect(saveToCubeButton, SIGNAL(clicked(
bool)),
this, SLOT(
saveStretchToCube()));
321 QPushButton *deleteFromCubeButton =
new QPushButton(
"Delete");
322 connect(deleteFromCubeButton, SIGNAL(clicked(
bool)),
this, SLOT(
deleteFromCube()));
324 QPushButton *loadStretchButton =
new QPushButton(
"Restore");
327 QHBoxLayout *layout =
new QHBoxLayout(hbox);
328 layout->setMargin(0);
336 layout->addWidget(advancedButton);
341 layout->addWidget(saveToCubeButton);
342 layout->addWidget(deleteFromCubeButton);
343 layout->addWidget(loadStretchButton);
345 layout->addStretch();
346 hbox->setLayout(layout);
362 if(cvp->isGray() && !cvp->grayBuffer()->working()) {
369 if(hist.ValidPixels() > 0) {
375 else if(!cvp->isGray() &&
376 !cvp->redBuffer()->working() &&
377 !cvp->greenBuffer()->working() &&
378 !cvp->blueBuffer()->working()) {
387 if(redHist.ValidPixels() > 0 &&
388 grnHist.ValidPixels() > 0 &&
389 bluHist.ValidPixels() > 0) {
410 !cvp->redBuffer()->working() &&
411 !cvp->greenBuffer()->working() &&
412 !cvp->blueBuffer()->working()) {
417 Stretch redStretch(cvp->redStretch());
418 Stretch grnStretch(cvp->greenStretch());
419 Stretch bluStretch(cvp->blueStretch());
423 bluStretch, bluHist);
434 Cube* icube = cvp->cube();
435 Pvl* lab = icube->label();
442 for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
443 if (objIter->name() ==
"Stretch") {
444 PvlKeyword tempKeyword = objIter->findKeyword(
"Name");
445 int bandNumber = int(objIter->findKeyword(
"BandNumber"));
446 if (cvp->grayBand() == bandNumber) {
447 QString tempName = tempKeyword[0];
448 namelist.append(tempName);
454 int redBandNumber = cvp->redBand();
455 int greenBandNumber = cvp->greenBand();
456 int blueBandNumber = cvp->blueBand();
458 QMap<QString, QList<int>> tempNameMap;
460 for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
461 if (objIter->name() ==
"Stretch") {
462 PvlKeyword tempKeyword = objIter->findKeyword(
"Name");
463 int bandNumber = int(objIter->findKeyword(
"BandNumber"));
464 if (bandNumber == redBandNumber || bandNumber == greenBandNumber
465 || bandNumber == blueBandNumber) {
466 QString tempName = tempKeyword[0];
467 if (tempNameMap.contains(tempName)) {
468 tempNameMap[tempName].append(bandNumber);
472 tempNameMap[tempName] = {bandNumber};
477 QMap<QString, QList<int>>::const_iterator i = tempNameMap.constBegin();
478 while (i != tempNameMap.constEnd()) {
479 if (i.value().contains(redBandNumber) && i.value().contains(greenBandNumber) &&
480 i.value().contains(blueBandNumber) ){
481 namelist.append(i.key());
490 if (namelist.size() >=1) {
491 stretchName = QInputDialog::getItem((
QWidget *)parent(), tr(
"Load Stretch"),
492 tr(
"Name of Stretch to Load:"), namelist, 0,
496 QMessageBox::information((
QWidget *)parent(),
"Information",
497 "There are no saved stretches to restore.");
502 CubeStretch cubeStretch = icube->readCubeStretch(stretchName);
510 cvp->stretchGray(grayOriginal);
513 std::vector<PvlKeyword> keywordValueRed;
514 keywordValueRed.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->redBand())));
516 std::vector<PvlKeyword> keywordValueGreen;
517 keywordValueGreen.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->greenBand())));
519 std::vector<PvlKeyword> keywordValueBlue;
520 keywordValueBlue.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->blueBand())));
522 CubeStretch redStretch = icube->readCubeStretch(stretchName, keywordValueRed);
523 CubeStretch greenStretch = icube->readCubeStretch(stretchName, keywordValueGreen);
524 CubeStretch blueStretch = icube->readCubeStretch(stretchName, keywordValueBlue);
537 greenOriginal.CopyPairs(greenStretch);
538 blueOriginal.CopyPairs(blueStretch);
540 cvp->stretchRed(redOriginal);
541 cvp->stretchGreen(greenOriginal);
542 cvp->stretchBlue(blueOriginal);
554 Cube* icube = cvp->cube();
555 Pvl* lab = icube->label();
560 for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
561 if (objIter->name() ==
"Stretch") {
562 PvlKeyword tempKeyword = objIter->findKeyword(
"Name");
563 int bandNumber = int(objIter->findKeyword(
"BandNumber"));
564 if (cvp->grayBand() == bandNumber) {
565 QString tempName = tempKeyword[0];
566 namelist.append(tempName);
574 if (namelist.size() >= 1) {
575 toDelete = QInputDialog::getItem((
QWidget *)parent(), tr(
"Delete Stretch"),
576 tr(
"Name of Stretch to Delete:"), namelist, 0,
580 QMessageBox::information((
QWidget *)parent(),
"Information",
581 "There are no saved stretches to delete.");
585 if (icube->isReadOnly()) {
587 cvp->cube()->reopen(
"rw");
590 cvp->cube()->reopen(
"r");
591 QMessageBox::information((
QWidget *)parent(),
"Error",
592 "Cannot open cube read/write to delete stretch");
597 bool cubeDeleted = icube->deleteBlob(toDelete,
"Stretch");
601 msgBox.setText(
"Stretch Could Not Be Deleted!");
602 msgBox.setInformativeText(
"A stretch with name: \"" + toDelete +
603 "\" Could not be found, so there was nothing to delete from the Cube.");
604 msgBox.setStandardButtons(QMessageBox::Ok);
605 msgBox.setIcon(QMessageBox::Critical);
610 cvp->cube()->reopen(
"r");
620 Cube* icube = cvp->cube();
621 Pvl* lab = icube->label();
626 for (objIter=lab->beginObject(); objIter<lab->endObject(); objIter++) {
627 if (objIter->name() ==
"Stretch") {
628 PvlKeyword tempKeyword = objIter->findKeyword(
"Name");
629 QString tempName = tempKeyword[0];
630 namelist.append(tempName);
647 if (!cvp->isGray()) {
655 redStretch = cvp->redStretch();
656 greenStretch = cvp->greenStretch();
657 blueStretch = cvp->blueStretch();
660 int redBand = cvp->redBand();
661 int greenBand = cvp->greenBand();
662 int blueBand = cvp->blueBand();
664 if (((redBand == greenBand) && !(redStretch == greenStretch)) ||
665 ((redBand == blueBand) && !(redBand == blueBand)) ||
666 ((greenBand == blueBand) && !(greenBand == blueBand))) {
667 QMessageBox::information((
QWidget *)parent(),
"Error",
"Sorry, cannot save RGB stretches which include the same band multiple times, but have different stretches for each");
674 tr(
"Enter a name to save the stretch as:"), QLineEdit::Normal,
679 if (namelist.contains(text)) {
681 msgBox.setText(tr(
"Stretch Name Already Exists!"));
682 msgBox.setInformativeText(
"A stretch pair with name: \"" + text +
"\" already exists and "
683 "the existing saved data will be overwritten. Are you sure you "
685 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
686 msgBox.setIcon(QMessageBox::Warning);
687 msgBox.setDefaultButton(QMessageBox::Cancel);
688 int ret = msgBox.exec();
691 case QMessageBox::Save:
693 case QMessageBox::Cancel:
704 if (icube->isReadOnly()) {
711 QMessageBox::information((
QWidget *)parent(),
"Error",
"Cannot open cube read/write to save stretch");
723 stretch = cvp->grayStretch();
732 icube->write(stretch);
742 redStretch = cvp->redStretch();
743 greenStretch = cvp->greenStretch();
744 blueStretch = cvp->blueStretch();
750 icube->write(stretchBlob,
false);
754 stretchBlob = greenStretch.
toBlob();
755 icube->write(stretchBlob,
false);
759 stretchBlob = blueStretch.
toBlob();
760 icube->write(stretchBlob,
false);
764 cvp->cube()->reopen(
"r");
786 if(cvp->isGray() && !cvp->grayBuffer()->working()) {
788 Stretch stretch(cvp->grayStretch());
792 else if(!cvp->isGray() &&
793 !cvp->redBuffer()->working() &&
794 !cvp->greenBuffer()->working() &&
795 !cvp->blueBuffer()->working()) {
799 Stretch redStretch(cvp->redStretch());
800 Stretch grnStretch(cvp->greenStretch());
801 Stretch bluStretch(cvp->blueStretch());
804 bluStretch, bluHist);
836 if(cvp && cvp->isGray()) {
877 QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
879 if(bandId == (
int)
Gray) {
880 if(cvp->grayBuffer() && cvp->grayBuffer()->hasEntireCube()) {
881 Stretch newStretch = cvp->grayStretch();
883 cvp->stretchGray(newStretch);
887 cvp->stretchGray(newStretch);
892 if(bandId == (
int)
Red || bandId == (
int)
All) {
893 if(cvp->redBuffer() && cvp->redBuffer()->hasEntireCube()) {
894 Stretch newStretch = cvp->redStretch();
896 cvp->stretchRed(newStretch);
900 cvp->stretchRed(newStretch);
903 if(bandId == (
int)
Green || bandId == (
int)
All) {
904 if(cvp->greenBuffer() && cvp->greenBuffer()->hasEntireCube()) {
905 Stretch newStretch = cvp->greenStretch();
907 cvp->stretchGreen(newStretch);
911 cvp->stretchGreen(newStretch);
914 if(bandId == (
int)
Blue || bandId == (
int)
All) {
915 if(cvp->blueBuffer() && cvp->blueBuffer()->hasEntireCube()) {
916 Stretch newStretch = cvp->blueStretch();
918 cvp->stretchBlue(newStretch);
922 cvp->stretchBlue(newStretch);
937 if(cvp == NULL)
return;
948 cvp->stretchKnownGlobal();
965 double min = 0, max = 0;
969 Stretch stretch = cvp->grayStretch();
970 min = stretch.
Input(0);
976 Stretch rstretch = cvp->redStretch();
977 Stretch gstretch = cvp->greenStretch();
978 Stretch bstretch = cvp->blueStretch();
982 min = rstretch.
Input(0);
983 max = rstretch.Input(rstretch.Pairs() - 1);
986 min = gstretch.Input(0);
987 max = gstretch.Input(gstretch.Pairs() - 1);
990 min = bstretch.Input(0);
991 max = bstretch.Input(bstretch.Pairs() - 1);
1021 if(cvp == NULL)
return;
1024 Stretch grayStretch = cvp->grayStretch();
1027 cvp->stretchGray(grayStretch);
1034 Stretch redStretch = cvp->redStretch();
1037 cvp->stretchRed(redStretch);
1039 Stretch grnStretch = cvp->greenStretch();
1042 cvp->stretchGreen(grnStretch);
1044 Stretch bluStretch = cvp->blueStretch();
1047 cvp->stretchBlue(bluStretch);
1061 if(cvp == NULL)
return;
1078 Stretch stretch = cvp->grayStretch();
1087 cvp->stretchGray(stretch);
1091 Stretch redStretch = cvp->redStretch();
1092 Stretch greenStretch = cvp->greenStretch();
1093 Stretch blueStretch = cvp->blueStretch();
1098 redStretch.
AddPair(max, 255.0);
1102 greenStretch.
AddPair(min, 0.0);
1103 greenStretch.
AddPair(max, 255.0);
1107 blueStretch.
AddPair(min, 0.0);
1108 blueStretch.
AddPair(max, 255.0);
1111 cvp->stretchRed(redStretch);
1112 cvp->stretchGreen(greenStretch);
1113 cvp->stretchBlue(blueStretch);
1126 int bandNum = cvp->grayBand();
1127 if(bandId == (
int)
Red) {
1128 bandNum = cvp->redBand();
1130 else if(bandId == (
int)
Green) {
1131 bandNum = cvp->greenBand();
1133 else if(bandId == (
int)
Blue) {
1134 bandNum = cvp->blueBand();
1143 double selectedMin = 0;
1144 double selectedMax = 0;
1146 if (minMaxIndex == 0) {
1147 selectedMin = hist.Percent(0.5);
1148 selectedMax = hist.Percent(99.5);
1149 }
else if (minMaxIndex == 1) {
1151 selectedMin = stats.BestMinimum();
1152 selectedMax = stats.BestMaximum();
1153 }
else if (minMaxIndex == 2) {
1155 selectedMin = stats.Minimum();
1156 selectedMax = stats.Maximum();
1157 }
else if (minMaxIndex == 3) {
1159 selectedMin = stats.ChebyshevMinimum();
1160 selectedMax = stats.ChebyshevMaximum();
1163 QString qMin = QString::number(selectedMin);
1164 QString qMax = QString::number(selectedMax);
1193 if(cvp == NULL)
return;
1204 if(cvp == NULL)
return;
1206 cvp->forgetStretches();
1216 cvp->stretchKnownGlobal();
1240 if(cvp == NULL)
return;
1251 QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
1256 QString message =
"Cannot stretch while the cube is still loading";
1257 QMessageBox::warning((
QWidget *)parent(),
"Warning", message);
1271 if(cvp == NULL)
return;
1272 if(!rubberBandTool()->isValid())
return;
1274 QRect rubberBandRect = rubberBandTool()->
rectangle();
1276 if(rubberBandRect.width() == 0 || rubberBandRect.height() == 0)
return;
1291 newStretch = cvp->grayStretch();
1293 newStretch.CopyPairs(
stretchBuffer(cvp->grayBuffer(), rect));
1294 cvp->stretchGray(newStretch);
1302 newStretch = cvp->redStretch();
1303 newStretch.ClearPairs();
1304 newStretch.CopyPairs(
stretchBuffer(cvp->redBuffer(), rect));
1305 cvp->stretchRed(newStretch);
1308 newStretch = cvp->greenStretch();
1309 newStretch.ClearPairs();
1310 newStretch.CopyPairs(
stretchBuffer(cvp->greenBuffer(), rect));
1311 cvp->stretchGreen(newStretch);
1314 newStretch = cvp->blueStretch();
1315 newStretch.ClearPairs();
1316 newStretch.CopyPairs(
stretchBuffer(cvp->blueBuffer(), rect));
1317 cvp->stretchBlue(newStretch);
1322 "Unknown stretch band",
1340 if(cvp == NULL)
return;
1346 if(s == Qt::RightButton) {
1363 rubberBandTool()->
enable(RubberBandTool::RectangleMode);
1375 if(cvp == NULL)
return;
1382 stretch = cvp->grayStretch();
1388 stretch = cvp->redStretch();
1392 cvp->stretchGreen(stretch);
1393 cvp->stretchBlue(stretch);
1396 stretch = cvp->greenStretch();
1400 cvp->stretchRed(stretch);
1401 cvp->stretchBlue(stretch);
1404 stretch = cvp->blueStretch();
1408 cvp->stretchRed(stretch);
1409 cvp->stretchGreen(stretch);
1415 cvp->setAllBandStretches(stretch);
1427 if(thisViewport == NULL)
return;
1432 if(thisViewport->isGray() && cvp->isGray()) {
1433 Stretch newStretch(cvp->grayStretch());
1434 newStretch.CopyPairs(thisViewport->grayStretch());
1435 cvp->stretchGray(newStretch);
1437 else if(!thisViewport->isGray() && !cvp->isGray()) {
1438 Stretch newStretchRed(cvp->redStretch());
1439 newStretchRed.CopyPairs(thisViewport->redStretch());
1440 cvp->stretchRed(newStretchRed);
1442 Stretch newStretchGreen(cvp->greenStretch());
1443 newStretchGreen.CopyPairs(thisViewport->greenStretch());
1444 cvp->stretchGreen(newStretchGreen);
1446 Stretch newStretchBlue(cvp->blueStretch());
1447 newStretchBlue.CopyPairs(thisViewport->blueStretch());
1448 cvp->stretchBlue(newStretchBlue);
1450 else if(!thisViewport->isGray() && cvp->isGray()) {
1453 else if(thisViewport->isGray() && !cvp->isGray()) {
1472 if(stats.ValidPixels() > 1 &&
1473 fabs(stats.Minimum() - stats.Maximum()) > DBL_EPSILON) {
1475 stats.BestMinimum(), stats.BestMaximum());
1477 if(fabs(hist.Percent(0.5) - hist.Percent(99.5)) > DBL_EPSILON) {
1478 stretch.
AddPair(hist.Percent(0.5), 0.0);
1479 stretch.
AddPair(hist.Percent(99.5), 255.0);
1483 if(stretch.
Pairs() == 0) {
1484 stretch.
AddPair(-DBL_MAX, 0.0);
1485 stretch.
AddPair(DBL_MAX, 255.0);
1500 int bandNum = cvp->grayBand();
1501 Stretch stretch = cvp->grayStretch();
1503 bandNum = cvp->redBand();
1504 stretch = cvp->redStretch();
1506 else if(band ==
Green) {
1507 bandNum = cvp->greenBand();
1508 stretch = cvp->greenStretch();
1510 else if(band ==
Blue) {
1511 bandNum = cvp->blueBand();
1512 stretch = cvp->blueStretch();
1517 stats.BestMinimum(), stats.BestMaximum());
1520 if(fabs(hist.Percent(0.5) - hist.Percent(99.5)) > DBL_EPSILON) {
1521 stretch.
AddPair(hist.Percent(0.5), 0.0);
1522 stretch.
AddPair(hist.Percent(99.5), 255.0);
1525 stretch.
AddPair(-DBL_MAX, 0.0);
1526 stretch.
AddPair(DBL_MAX, 255.0);
1545 for(
int line = 0; line < cube->
lineCount(); line++) {
1546 brick.SetBasePosition(0, line, band);
1548 stats.AddData(brick.DoubleBuffer(), cube->
sampleCount());
1568 "Cannot stretch while the cube is still loading",
1572 QRect dataArea = QRect(buffer->
bufferXYRect().intersected(rect));
1575 for(
int y = dataArea.top();
1576 !dataArea.isNull() && y <= dataArea.bottom();
1580 for(
int x = dataArea.left(); x < dataArea.right(); x++) {
1581 stats.AddData(line[x - buffer->
bufferXYRect().left()]);
1600 double min,
double max) {
1604 for(
int line = 0; line < cube->
lineCount(); line++) {
1605 brick.SetBasePosition(0, line, band);
1607 hist.AddData(brick.DoubleBuffer(), cube->
sampleCount());
1624 stats.BestMinimum(), stats.BestMaximum());
1641 QRect rect,
double min,
double max) {
1642 QRect dataArea = QRect(buffer->
bufferXYRect().intersected(rect));
1647 for(
int y = dataArea.top(); !dataArea.isNull() && y <= dataArea.bottom(); y++) {
1649 hist.AddData(&line.front() + (dataArea.left() - buffer->
bufferXYRect().left()), dataArea.width());
1658 std::string msg =
"Insufficient data Min [" + sMin +
"], Max [" + sMax +
"]";
1659 msg +=
" in the stretch area.";
CubeStretch getBluStretch()
This returns the advanced stretch's stretch for blue.
void updateHistograms(const Histogram &redHist, const Histogram &grnHist, const Histogram &bluHist)
This calls setHistogram on all of the advanced stretches.
void enable(bool enable)
Sets the enabled state to enable.
void restoreGrayStretch(CubeStretch stretch)
Restores a saved grayscale stretch from the cube.
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.
void updateHistogram(const Histogram &grayHist)
This calls setHistogram on the gray advanced stretches.
void enableRgbMode(Stretch &redStretch, Histogram &redHist, Stretch &grnStretch, Histogram &grnHist, Stretch &bluStretch, Histogram &bluHist)
This displays RGB advanced stretches.
CubeStretch getGrnStretch()
This returns the advanced stretch's stretch for green.
CubeStretch getGrayStretch()
This returns the advanced stretch's stretch for gray.
CubeStretch getRedStretch()
This returns the advanced stretch's stretch for red.
bool isRgbMode() const
Returns true if the dialog is displaying the RGB advanced stretches.
bool enabled()
Returns true if the advanced stretch is enabled.
void restoreRgbStretch(CubeStretch red, CubeStretch green, CubeStretch blue)
Restores a saved RGB stretch from the cube.
void updateStretch(CubeViewport *)
This calls setStretch on all applicable advanced stretches.
void enableGrayMode(Stretch &grayStretch, Histogram &grayHist)
This displays a gray advanced stretch.
Buffer for containing a three dimensional section of an image.
IO Handler for Isis Cubes.
PixelType pixelType() const
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Stores stretch information for a cube.
void setBandNumber(int bandNumber)
Set the band number for the stretch.
void setName(QString name)
Set the Stretch name.
Isis::Blob toBlob() const
Serialize the CubeStretch to a Blob.
Widget to display Isis cubes for qt apps.
Container of a cube histogram.
@ Unknown
A type of error that cannot be classified as any of the other error types.
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
@ Programmer
This error is for when a programmer made an API call that was illegal.
Adds specific functionality to C++ strings.
Cube display widget for certain Isis MDI applications.
Container for cube-like labels.
A single keyword-value pair.
QList< PvlObject >::iterator PvlObjectIterator
The counter for objects.
This class is used to accumulate statistics on double arrays.
void CopyPairs(const Stretch &other)
Copies the stretch pairs from another Stretch object, but maintains special pixel values.
void AddPair(const double input, const double output)
Adds a stretch pair to the list of pairs.
double Input(const int index) const
Returns the value of the input side of the stretch pair at the specified index.
void ClearPairs()
Clears the stretch pairs.
int Pairs() const
Returns the number of stretch pairs.
Reads and stores visible DN values.
const std::vector< double > & getLine(int line)
Retrieves a line from the buffer.
QRect bufferXYRect()
Returns a rect, in screen pixels, of the area this buffer covers.
bool working()
This tests if queued actions exist in the viewport buffer.
This was called the Qisis MainWindow.
This is free and unencumbered software released into the public domain.
int toInt(const QString &string)
Global function to convert from a string to an integer.
Namespace for the standard library.