-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds the ability to save and restore a greyscale stretch to/from a Cube #3717
Changes from 18 commits
6dafcfa
5ea5b89
4dd4d55
03fdf3e
ce7cf0a
66deadf
fc80fdd
298596b
0d284c8
d7a14f5
b09c930
91314eb
143dc95
b739397
ad7dc7b
e5c8a7d
1f00cfa
1a92f55
58ab204
1cfcf38
8c3e931
199753c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,7 @@ namespace Isis { | |
* Constructs a Stretch object with default mapping of special pixel values to | ||
* themselves. | ||
*/ | ||
Stretch::Stretch() { | ||
Stretch::Stretch() : Blob("NAME", "Stretch") { | ||
p_null = Isis::NULL8; | ||
p_lis = Isis::LOW_INSTR_SAT8; | ||
p_lrs = Isis::LOW_REPR_SAT8; | ||
|
@@ -47,8 +47,29 @@ namespace Isis { | |
p_minimum = p_lrs; | ||
p_maximum = p_hrs; | ||
p_pairs = 0; | ||
p_type = "None"; | ||
} | ||
|
||
|
||
/** | ||
* Constructs a Stretch object with default mapping of special pixel values to | ||
* themselves and a provided name. | ||
* | ||
* @param name Name to use for Stretch | ||
*/ | ||
Stretch::Stretch(QString name) : Blob(name, "Stretch") { | ||
p_null = Isis::NULL8; | ||
p_lis = Isis::LOW_INSTR_SAT8; | ||
p_lrs = Isis::LOW_REPR_SAT8; | ||
p_his = Isis::HIGH_INSTR_SAT8; | ||
p_hrs = Isis::HIGH_REPR_SAT8; | ||
p_minimum = p_lrs; | ||
p_maximum = p_hrs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why these aren't VALID_MIN8 and VALID_MAX8? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a copy of the default constructor so this is just more of a curious question for me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure, @scsides do you know? |
||
p_pairs = 0; | ||
p_type = "None"; | ||
} | ||
|
||
|
||
/** | ||
* Adds a stretch pair to the list of pairs. Note that all input pairs must be | ||
* in ascending order. | ||
|
@@ -410,6 +431,89 @@ namespace Isis { | |
this->p_output = other.p_output; | ||
} | ||
|
||
|
||
/** | ||
* Read saved Stretch data from a Cube into this object. | ||
* | ||
* This is called by Blob::Read() and is the actual data reading function | ||
* ultimately called when running something like cube->read(stretch); | ||
* | ||
* @param is input stream containing the saved Stretch information | ||
*/ | ||
void Stretch::ReadData(std::istream &is) { | ||
// Set the Stretch Type | ||
p_type = p_blobPvl["StretchType"][0]; | ||
|
||
// Read in the Stretch Pairs | ||
streampos sbyte = p_startByte - 1; | ||
is.seekg(sbyte, std::ios::beg); | ||
if (!is.good()) { | ||
QString msg = "Error preparing to read data from " + p_type + | ||
" [" + p_blobName + "]"; | ||
throw IException(IException::Io, msg, _FILEINFO_); | ||
} | ||
|
||
char *buf = new char[p_nbytes+1]; | ||
memset(buf, 0, p_nbytes + 1); | ||
|
||
is.read(buf, p_nbytes); | ||
|
||
// Read buffer data into a QString so we can call Parse() | ||
std::string stringFromBuffer(buf); | ||
QString qStringFromBuffer = QString::fromStdString(stringFromBuffer); | ||
Parse(qStringFromBuffer); | ||
|
||
delete [] buf; | ||
|
||
if (!is.good()) { | ||
QString msg = "Error reading data from " + p_type + " [" + | ||
p_blobName + "]"; | ||
throw IException(IException::Io, msg, _FILEINFO_); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Get the Type of Stretch. This is only used by the AdvancedStretchTool. | ||
* | ||
* @return QString Type of Stretch. | ||
*/ | ||
QString Stretch::getType(){ | ||
return p_type; | ||
} | ||
|
||
|
||
/** | ||
* Set the Type of Stretch. This is only used by the AdvancedStretchTool. | ||
* | ||
* @param stretchType The type of stretch. | ||
*/ | ||
void Stretch::setType(QString stretchType){ | ||
// check to see if valid input | ||
p_type = stretchType; | ||
} | ||
|
||
|
||
/** | ||
* Initializes for writing stretch to cube blob | ||
*/ | ||
void Stretch::WriteInit() { | ||
p_nbytes = Text().toStdString().size(); | ||
} | ||
|
||
|
||
/** | ||
* Writes the stretch information to a cube. | ||
* | ||
* This is called by Blob::write() and is ultimately the function | ||
* called when running something like cube->write(stretch); | ||
* | ||
* @param os output stream to write the stretch data to. | ||
*/ | ||
void Stretch::WriteData(std::fstream &os) { | ||
os.write(Text().toStdString().c_str(), p_nbytes); | ||
} | ||
|
||
} // end namespace isis | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ | |
#include <string> | ||
#include "Pvl.h" | ||
#include "Histogram.h" | ||
#include "Blob.h" | ||
|
||
namespace Isis { | ||
/** | ||
|
@@ -67,9 +68,10 @@ namespace Isis { | |
* Created second Parse method for handling pairs where the | ||
* input side is a perentage. Fixed Input and Output getters | ||
* to check both sides of boundry condition for valid data | ||
* | ||
* @history 2020-02-27 Kristin Berry - Updated to inherit from Blob so Stretches can be | ||
* saved and restored from cubes. | ||
*/ | ||
class Stretch { | ||
class Stretch : public Isis::Blob { | ||
private: | ||
std::vector<double> p_input; //!< Array for input side of stretch pairs | ||
std::vector<double> p_output; //!< Array for output side of stretch pairs | ||
|
@@ -88,10 +90,13 @@ namespace Isis { | |
double p_minimum; //!<By default this value is set to p_lrs | ||
double p_maximum; //!<By default this value is set to p_hrs | ||
|
||
QString p_type; //! Type of stretch. This is only currently used in the AdvancedStretchTool. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be passed in on as a signal slot variable? |
||
|
||
std::pair<double, double> NextPair(QString &pairs); | ||
|
||
public: | ||
Stretch(); | ||
Stretch(QString name); | ||
|
||
//! Destroys the Stretch object | ||
~Stretch() {}; | ||
|
@@ -177,6 +182,9 @@ namespace Isis { | |
return p_pairs; | ||
}; | ||
|
||
QString getType(); | ||
void setType(QString type); | ||
|
||
double Input(const int index) const; | ||
double Output(const int index) const; | ||
|
||
|
@@ -188,6 +196,11 @@ namespace Isis { | |
}; | ||
|
||
void CopyPairs(const Stretch &other); | ||
|
||
protected: | ||
void WriteInit(); | ||
void ReadData(std::istream &is); | ||
void WriteData(std::fstream &os); | ||
}; | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
#include <QHBoxLayout> | ||
#include <QLabel> | ||
#include <QComboBox> | ||
#include <QMessageBox> | ||
|
||
#include "Stretch.h" | ||
#include "IString.h" | ||
|
@@ -35,40 +36,52 @@ namespace Isis { | |
typeSelectionArea->setLayout(new QHBoxLayout()); | ||
typeSelectionArea->layout()->addWidget(new QLabel("Stretch Type")); | ||
|
||
QComboBox *stretchTypeSelection = new QComboBox(); | ||
stretchTypeSelection->addItem("Linear", 0); | ||
stretchTypeSelection->addItem("Sawtooth", 1); | ||
stretchTypeSelection->addItem("Binary", 2); | ||
stretchTypeSelection->addItem("Manual", 3); | ||
p_stretchTypeSelection = new QComboBox(); | ||
p_stretchTypeSelection->addItem("Linear", 0); | ||
p_stretchTypeSelection->addItem("Sawtooth", 1); | ||
p_stretchTypeSelection->addItem("Binary", 2); | ||
p_stretchTypeSelection->addItem("Manual", 3); | ||
|
||
typeSelectionArea->layout()->addWidget(stretchTypeSelection); | ||
typeSelectionArea->layout()->addWidget(p_stretchTypeSelection); | ||
layout()->addWidget(typeSelectionArea); | ||
|
||
p_stretchTypeStack = new QStackedWidget(); | ||
LinearStretchType *linear = new LinearStretchType(hist, curStretch, | ||
name, color); | ||
connect(linear, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); | ||
connect(linear, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); | ||
connect(linear, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); | ||
connect(linear, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); | ||
p_stretchTypeStack->addWidget(linear); | ||
|
||
SawtoothStretchType *sawtooth = new SawtoothStretchType(hist, curStretch, | ||
name, color); | ||
connect(sawtooth, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); | ||
connect(sawtooth, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); | ||
connect(sawtooth, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); | ||
connect(sawtooth, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); | ||
p_stretchTypeStack->addWidget(sawtooth); | ||
|
||
BinaryStretchType *binary = new BinaryStretchType(hist, curStretch, | ||
name, color); | ||
connect(binary, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); | ||
connect(binary, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); | ||
connect(binary, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); | ||
connect(binary, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); | ||
p_stretchTypeStack->addWidget(binary); | ||
|
||
ManualStretchType *manual = new ManualStretchType(hist, curStretch, | ||
name, color); | ||
connect(manual, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); | ||
connect(manual, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); | ||
connect(manual, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); | ||
connect(manual, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); | ||
p_stretchTypeStack->addWidget(manual); | ||
|
||
layout()->addWidget(p_stretchTypeStack); | ||
connect(stretchTypeSelection, SIGNAL(currentIndexChanged(int)), | ||
connect(p_stretchTypeSelection, SIGNAL(currentIndexChanged(int)), | ||
p_stretchTypeStack, SLOT(setCurrentIndex(int))); | ||
connect(stretchTypeSelection, SIGNAL(currentIndexChanged(int)), | ||
connect(p_stretchTypeSelection, SIGNAL(currentIndexChanged(int)), | ||
this, SIGNAL(stretchChanged())); | ||
} | ||
|
||
|
@@ -105,6 +118,41 @@ namespace Isis { | |
} | ||
|
||
|
||
/** | ||
* Used to restore a saved Stretch from a cube. This function is | ||
* distinct from setStretch in that setStretch delibrately _does not_ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delibrately -> deliberately |
||
* change the stretch type, and this function does change the stretch type. | ||
* | ||
* @param newStretch saved stretch to restore | ||
*/ | ||
void AdvancedStretch::setStretchFromCube(Stretch newStretch) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is confusing that setStretchFromCube doesn't do anything with a cube. |
||
QString stretchTypeName = newStretch.getType(); | ||
|
||
int index = 0; | ||
if (stretchTypeName.compare("LinearStretch") == 0 ) { | ||
index = 0; | ||
} | ||
else if (stretchTypeName.compare("SawtoothStretch") == 0 ) { | ||
index = 1; | ||
} | ||
else if (stretchTypeName.compare("BinaryStretch") == 0) { | ||
index = 2; | ||
} | ||
else if (stretchTypeName.compare("ManualStretch") == 0) { | ||
index = 3; | ||
} | ||
// Fail by defaulting to Linear | ||
|
||
|
||
// p_stretchTypeStack->setCurrentIndex(index); <- does not work. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this comment here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was originally so that I would remember that it didn't work, but the codebase doesn't need my personal reminders. |
||
|
||
p_stretchTypeSelection->setCurrentIndex(index); | ||
StretchType *stretchType = (StretchType *) | ||
p_stretchTypeStack->currentWidget(); | ||
stretchType->setStretch(newStretch); | ||
} | ||
|
||
|
||
/** | ||
* This is called when the visible area changes, so that the | ||
* histogram can be updated. It is essential that the stretch | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,10 @@ namespace Isis { | |
p_bluStretch = NULL; | ||
p_enabled = false; | ||
|
||
setWindowTitle("Advanced Stretch Tool"); | ||
|
||
QHBoxLayout *layout = new QHBoxLayout(); | ||
|
||
setLayout(layout); | ||
} | ||
|
||
|
@@ -69,6 +72,7 @@ namespace Isis { | |
this, SIGNAL(stretchChanged())); | ||
connect(p_bluStretch, SIGNAL(stretchChanged()), | ||
this, SIGNAL(stretchChanged())); | ||
// add signal for RGB | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a TODO? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but beyond this scope of this week. I'll make a ticket. |
||
} | ||
|
||
/** | ||
|
@@ -124,6 +128,22 @@ namespace Isis { | |
|
||
connect(p_grayStretch, SIGNAL(stretchChanged()), | ||
this, SIGNAL(stretchChanged())); | ||
connect(p_grayStretch, SIGNAL(saveToCube()), | ||
this, SIGNAL(saveToCube())); | ||
connect(p_grayStretch, SIGNAL(deleteFromCube()), | ||
this, SIGNAL(deleteFromCube())); | ||
connect(p_grayStretch, SIGNAL(loadStretch()), | ||
this, SIGNAL(loadStretch())); | ||
} | ||
|
||
|
||
/** | ||
* Restores a saved stretch from the cube | ||
* | ||
* @param stretch | ||
*/ | ||
void AdvancedStretchDialog::setStretchFromCube(Stretch stretch){ | ||
p_grayStretch->setStretchFromCube(stretch); | ||
} | ||
|
||
|
||
|
@@ -213,7 +233,7 @@ namespace Isis { | |
|
||
|
||
/** | ||
* This calls setHistogram on the gray advanced stretche. This | ||
* This calls setHistogram on the gray advanced stretches. This | ||
* should be called every time the visible area changes. | ||
* | ||
* @param grayHist Histogram of visible area on gray band | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other BLOB subclasses they still have a descriptive name in the default constructor. I would call this ImageStretch or something more descriptive.