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.";
186 QDoubleValidator *dval =
new QDoubleValidator(hbox);
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.";
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";
227 copyAll->setIcon(QPixmap(
toolIconDir() +
"/copy_stretch.png"));
228 copyAll->setText(
"to All Viewports");
231 copyMenu->addAction(copyAll);
238 m_copyButton->setPopupMode(QToolButton::MenuButtonPopup);
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>";
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()));
257 globalAll->setText(
"All Viewports");
258 globalMenu->addAction(globalAll);
262 globalBands->setText(
"All Bands");
263 globalMenu->addAction(globalBands);
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.";
280 QPushButton *advancedButton =
new QPushButton(
"Advanced");
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 "
294 QPushButton *saveToCubeButton =
new QPushButton(
"Save");
295 connect(saveToCubeButton, SIGNAL(clicked(
bool)),
this, SLOT(
saveStretchToCube()));
297 QPushButton *deleteFromCubeButton =
new QPushButton(
"Delete");
298 connect(deleteFromCubeButton, SIGNAL(clicked(
bool)),
this, SLOT(
deleteFromCube()));
300 QPushButton *loadStretchButton =
new QPushButton(
"Restore");
303 QHBoxLayout *layout =
new QHBoxLayout(hbox);
304 layout->setMargin(0);
311 layout->addWidget(advancedButton);
316 layout->addWidget(saveToCubeButton);
317 layout->addWidget(deleteFromCubeButton);
318 layout->addWidget(loadStretchButton);
320 layout->addStretch();
321 hbox->setLayout(layout);
337 if(cvp->isGray() && !cvp->grayBuffer()->working()) {
344 if(hist.ValidPixels() > 0) {
350 else if(!cvp->isGray() &&
351 !cvp->redBuffer()->working() &&
352 !cvp->greenBuffer()->working() &&
353 !cvp->blueBuffer()->working()) {
362 if(redHist.ValidPixels() > 0 &&
363 grnHist.ValidPixels() > 0 &&
364 bluHist.ValidPixels() > 0) {
385 !cvp->redBuffer()->working() &&
386 !cvp->greenBuffer()->working() &&
387 !cvp->blueBuffer()->working()) {
392 Stretch redStretch(cvp->redStretch());
393 Stretch grnStretch(cvp->greenStretch());
394 Stretch bluStretch(cvp->blueStretch());
398 bluStretch, bluHist);
409 Cube* icube = cvp->cube();
410 Pvl* lab = icube->label();
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);
429 int redBandNumber = cvp->redBand();
430 int greenBandNumber = cvp->greenBand();
431 int blueBandNumber = cvp->blueBand();
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);
447 tempNameMap[tempName] = {bandNumber};
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());
465 if (namelist.size() >=1) {
466 stretchName = QInputDialog::getItem((
QWidget *)parent(), tr(
"Load Stretch"),
467 tr(
"Name of Stretch to Load:"), namelist, 0,
471 QMessageBox::information((
QWidget *)parent(),
"Information",
472 "There are no saved stretches to restore.");
477 CubeStretch cubeStretch = icube->readCubeStretch(stretchName);
485 cvp->stretchGray(grayOriginal);
488 std::vector<PvlKeyword> keywordValueRed;
489 keywordValueRed.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->redBand())));
491 std::vector<PvlKeyword> keywordValueGreen;
492 keywordValueGreen.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->greenBand())));
494 std::vector<PvlKeyword> keywordValueBlue;
495 keywordValueBlue.push_back(
PvlKeyword(
"BandNumber", QString::number(cvp->blueBand())));
497 CubeStretch redStretch = icube->readCubeStretch(stretchName, keywordValueRed);
498 CubeStretch greenStretch = icube->readCubeStretch(stretchName, keywordValueGreen);
499 CubeStretch blueStretch = icube->readCubeStretch(stretchName, keywordValueBlue);
512 greenOriginal.CopyPairs(greenStretch);
513 blueOriginal.CopyPairs(blueStretch);
515 cvp->stretchRed(redOriginal);
516 cvp->stretchGreen(greenOriginal);
517 cvp->stretchBlue(blueOriginal);
529 Cube* icube = cvp->cube();
530 Pvl* lab = icube->label();
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);
549 if (namelist.size() >= 1) {
550 toDelete = QInputDialog::getItem((
QWidget *)parent(), tr(
"Delete Stretch"),
551 tr(
"Name of Stretch to Delete:"), namelist, 0,
555 QMessageBox::information((
QWidget *)parent(),
"Information",
556 "There are no saved stretches to delete.");
560 if (icube->isReadOnly()) {
562 cvp->cube()->reopen(
"rw");
565 cvp->cube()->reopen(
"r");
566 QMessageBox::information((
QWidget *)parent(),
"Error",
567 "Cannot open cube read/write to delete stretch");
572 bool cubeDeleted = icube->deleteBlob(toDelete,
"Stretch");
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);
585 cvp->cube()->reopen(
"r");
595 Cube* icube = cvp->cube();
596 Pvl* lab = icube->label();
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);
622 if (!cvp->isGray()) {
630 redStretch = cvp->redStretch();
631 greenStretch = cvp->greenStretch();
632 blueStretch = cvp->blueStretch();
635 int redBand = cvp->redBand();
636 int greenBand = cvp->greenBand();
637 int blueBand = cvp->blueBand();
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");
649 tr(
"Enter a name to save the stretch as:"), QLineEdit::Normal,
654 if (namelist.contains(text)) {
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 "
660 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
661 msgBox.setIcon(QMessageBox::Warning);
662 msgBox.setDefaultButton(QMessageBox::Cancel);
663 int ret = msgBox.exec();
666 case QMessageBox::Save:
668 case QMessageBox::Cancel:
679 if (icube->isReadOnly()) {
686 QMessageBox::information((
QWidget *)parent(),
"Error",
"Cannot open cube read/write to save stretch");
698 stretch = cvp->grayStretch();
707 icube->write(stretch);
717 redStretch = cvp->redStretch();
718 greenStretch = cvp->greenStretch();
719 blueStretch = cvp->blueStretch();
725 icube->write(stretchBlob,
false);
729 stretchBlob = greenStretch.
toBlob();
730 icube->write(stretchBlob,
false);
734 stretchBlob = blueStretch.
toBlob();
735 icube->write(stretchBlob,
false);
739 cvp->cube()->reopen(
"r");
761 if(cvp->isGray() && !cvp->grayBuffer()->working()) {
763 Stretch stretch(cvp->grayStretch());
767 else if(!cvp->isGray() &&
768 !cvp->redBuffer()->working() &&
769 !cvp->greenBuffer()->working() &&
770 !cvp->blueBuffer()->working()) {
774 Stretch redStretch(cvp->redStretch());
775 Stretch grnStretch(cvp->greenStretch());
776 Stretch bluStretch(cvp->blueStretch());
779 bluStretch, bluHist);
811 if(cvp && cvp->isGray()) {
852 QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
854 if(bandId == (
int)
Gray) {
855 if(cvp->grayBuffer() && cvp->grayBuffer()->hasEntireCube()) {
856 Stretch newStretch = cvp->grayStretch();
858 cvp->stretchGray(newStretch);
862 cvp->stretchGray(newStretch);
867 if(bandId == (
int)
Red || bandId == (
int)
All) {
868 if(cvp->redBuffer() && cvp->redBuffer()->hasEntireCube()) {
869 Stretch newStretch = cvp->redStretch();
871 cvp->stretchRed(newStretch);
875 cvp->stretchRed(newStretch);
878 if(bandId == (
int)
Green || bandId == (
int)
All) {
879 if(cvp->greenBuffer() && cvp->greenBuffer()->hasEntireCube()) {
880 Stretch newStretch = cvp->greenStretch();
882 cvp->stretchGreen(newStretch);
886 cvp->stretchGreen(newStretch);
889 if(bandId == (
int)
Blue || bandId == (
int)
All) {
890 if(cvp->blueBuffer() && cvp->blueBuffer()->hasEntireCube()) {
891 Stretch newStretch = cvp->blueStretch();
893 cvp->stretchBlue(newStretch);
897 cvp->stretchBlue(newStretch);
912 if(cvp == NULL)
return;
923 cvp->stretchKnownGlobal();
940 double min = 0, max = 0;
944 Stretch stretch = cvp->grayStretch();
945 min = stretch.
Input(0);
951 Stretch rstretch = cvp->redStretch();
952 Stretch gstretch = cvp->greenStretch();
953 Stretch bstretch = cvp->blueStretch();
957 min = rstretch.
Input(0);
958 max = rstretch.Input(rstretch.Pairs() - 1);
961 min = gstretch.Input(0);
962 max = gstretch.Input(gstretch.Pairs() - 1);
965 min = bstretch.Input(0);
966 max = bstretch.Input(bstretch.Pairs() - 1);
996 if(cvp == NULL)
return;
999 Stretch grayStretch = cvp->grayStretch();
1002 cvp->stretchGray(grayStretch);
1009 Stretch redStretch = cvp->redStretch();
1012 cvp->stretchRed(redStretch);
1014 Stretch grnStretch = cvp->greenStretch();
1017 cvp->stretchGreen(grnStretch);
1019 Stretch bluStretch = cvp->blueStretch();
1022 cvp->stretchBlue(bluStretch);
1036 if(cvp == NULL)
return;
1050 Stretch stretch = cvp->grayStretch();
1059 cvp->stretchGray(stretch);
1063 Stretch redStretch = cvp->redStretch();
1064 Stretch greenStretch = cvp->greenStretch();
1065 Stretch blueStretch = cvp->blueStretch();
1070 redStretch.
AddPair(max, 255.0);
1074 greenStretch.
AddPair(min, 0.0);
1075 greenStretch.
AddPair(max, 255.0);
1079 blueStretch.
AddPair(min, 0.0);
1080 blueStretch.
AddPair(max, 255.0);
1083 cvp->stretchRed(redStretch);
1084 cvp->stretchGreen(greenStretch);
1085 cvp->stretchBlue(blueStretch);
1113 if(cvp == NULL)
return;
1124 if(cvp == NULL)
return;
1126 cvp->forgetStretches();
1136 cvp->stretchKnownGlobal();
1160 if(cvp == NULL)
return;
1171 QRect rect(0, 0, cvp->viewport()->width(), cvp->viewport()->height());
1176 QString message =
"Cannot stretch while the cube is still loading";
1177 QMessageBox::warning((
QWidget *)parent(),
"Warning", message);
1191 if(cvp == NULL)
return;
1192 if(!rubberBandTool()->isValid())
return;
1194 QRect rubberBandRect = rubberBandTool()->
rectangle();
1196 if(rubberBandRect.width() == 0 || rubberBandRect.height() == 0)
return;
1211 newStretch = cvp->grayStretch();
1213 newStretch.CopyPairs(
stretchBuffer(cvp->grayBuffer(), rect));
1214 cvp->stretchGray(newStretch);
1222 newStretch = cvp->redStretch();
1223 newStretch.ClearPairs();
1224 newStretch.CopyPairs(
stretchBuffer(cvp->redBuffer(), rect));
1225 cvp->stretchRed(newStretch);
1228 newStretch = cvp->greenStretch();
1229 newStretch.ClearPairs();
1230 newStretch.CopyPairs(
stretchBuffer(cvp->greenBuffer(), rect));
1231 cvp->stretchGreen(newStretch);
1234 newStretch = cvp->blueStretch();
1235 newStretch.ClearPairs();
1236 newStretch.CopyPairs(
stretchBuffer(cvp->blueBuffer(), rect));
1237 cvp->stretchBlue(newStretch);
1242 "Unknown stretch band",
1260 if(cvp == NULL)
return;
1266 if(s == Qt::RightButton) {
1283 rubberBandTool()->
enable(RubberBandTool::RectangleMode);
1295 if(cvp == NULL)
return;
1302 stretch = cvp->grayStretch();
1308 stretch = cvp->redStretch();
1312 cvp->stretchGreen(stretch);
1313 cvp->stretchBlue(stretch);
1316 stretch = cvp->greenStretch();
1320 cvp->stretchRed(stretch);
1321 cvp->stretchBlue(stretch);
1324 stretch = cvp->blueStretch();
1328 cvp->stretchRed(stretch);
1329 cvp->stretchGreen(stretch);
1335 cvp->setAllBandStretches(stretch);
1347 if(thisViewport == NULL)
return;
1352 if(thisViewport->isGray() && cvp->isGray()) {
1353 Stretch newStretch(cvp->grayStretch());
1354 newStretch.CopyPairs(thisViewport->grayStretch());
1355 cvp->stretchGray(newStretch);
1357 else if(!thisViewport->isGray() && !cvp->isGray()) {
1358 Stretch newStretchRed(cvp->redStretch());
1359 newStretchRed.CopyPairs(thisViewport->redStretch());
1360 cvp->stretchRed(newStretchRed);
1362 Stretch newStretchGreen(cvp->greenStretch());
1363 newStretchGreen.CopyPairs(thisViewport->greenStretch());
1364 cvp->stretchGreen(newStretchGreen);
1366 Stretch newStretchBlue(cvp->blueStretch());
1367 newStretchBlue.CopyPairs(thisViewport->blueStretch());
1368 cvp->stretchBlue(newStretchBlue);
1370 else if(!thisViewport->isGray() && cvp->isGray()) {
1373 else if(thisViewport->isGray() && !cvp->isGray()) {
1392 if(stats.ValidPixels() > 1 &&
1393 fabs(stats.Minimum() - stats.Maximum()) > DBL_EPSILON) {
1395 stats.BestMinimum(), stats.BestMaximum());
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);
1403 if(stretch.
Pairs() == 0) {
1404 stretch.
AddPair(-DBL_MAX, 0.0);
1405 stretch.
AddPair(DBL_MAX, 255.0);
1420 int bandNum = cvp->grayBand();
1421 Stretch stretch = cvp->grayStretch();
1423 bandNum = cvp->redBand();
1424 stretch = cvp->redStretch();
1426 else if(band ==
Green) {
1427 bandNum = cvp->greenBand();
1428 stretch = cvp->greenStretch();
1430 else if(band ==
Blue) {
1431 bandNum = cvp->blueBand();
1432 stretch = cvp->blueStretch();
1437 stats.BestMinimum(), stats.BestMaximum());
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);
1445 stretch.
AddPair(-DBL_MAX, 0.0);
1446 stretch.
AddPair(DBL_MAX, 255.0);
1465 for(
int line = 0; line < cube->
lineCount(); line++) {
1466 brick.SetBasePosition(0, line, band);
1468 stats.AddData(brick.DoubleBuffer(), cube->
sampleCount());
1488 "Cannot stretch while the cube is still loading",
1492 QRect dataArea = QRect(buffer->
bufferXYRect().intersected(rect));
1495 for(
int y = dataArea.top();
1496 !dataArea.isNull() && y <= dataArea.bottom();
1500 for(
int x = dataArea.left(); x < dataArea.right(); x++) {
1501 stats.AddData(line[x - buffer->
bufferXYRect().left()]);
1520 double min,
double max) {
1524 for(
int line = 0; line < cube->
lineCount(); line++) {
1525 brick.SetBasePosition(0, line, band);
1527 hist.AddData(brick.DoubleBuffer(), cube->
sampleCount());
1544 stats.BestMinimum(), stats.BestMaximum());
1561 QRect rect,
double min,
double max) {
1562 QRect dataArea = QRect(buffer->
bufferXYRect().intersected(rect));
1567 for(
int y = dataArea.top(); !dataArea.isNull() && y <= dataArea.bottom(); y++) {
1569 hist.AddData(&line.front() + (dataArea.left() - buffer->
bufferXYRect().left()), dataArea.width());
1578 std::string msg =
"Insufficient data Min [" + sMin +
"], Max [" + sMax +
"]";
1579 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.