Isis 3 Programmer Reference
CubeAttribute.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "CubeAttribute.h"
8
9#include <iostream>
10
11#include <QDebug>
12
13#include "FileName.h"
14#include "IException.h"
15#include "Preference.h"
16#include "SpecialPixel.h"
17
18
19using namespace std;
20
21namespace Isis {
22 //---------------------------------------------------------------------------
23 // CubeAttributeInput Implementation
24 //---------------------------------------------------------------------------
27
28
30 CubeAttribute<CubeAttributeInput>(testers(), fileName) {
31 }
32
33
36
37
47// void CubeAttributeInput::Set(const FileName &fileName) {
48// Reset();
49//
50// QString str(fileName.attributes());
51//
52// // Get rid of any white space
53// str.ConvertWhiteSpace();
54// str.Compress();
55// str.Remove(" ");
56// str.UpCase();
57//
58// // Look at each comma delimited token
59// QString commaTok;
60// while((commaTok = str.Token(",")).length() > 0) {
61// // Is this token a range of bands
62// if (commaTok.find('-') != string::npos) {
63// QString dashTok;
64// int start = commaTok.Token("-").ToInteger();
65// int end = commaTok.Token("-").ToInteger();
66// int direction;
67// direction = (start <= end) ? 1 : -1;
68// // Save the entire range of bands
69// for (int band = start; band != end; band += direction) {
70// m_bands.push_back(Isis::QString(band));
71// }
72// m_bands.push_back(Isis::QString(end));
73// }
74// // This token is a single band specification
75// else {
76// m_bands.push_back(commaTok);
77// }
78// }
79// }
80
81
82 vector<QString> CubeAttributeInput::bands() const {
83 vector<QString> result;
84
85 QString str = toString().remove(QRegExp("^\\+"));
86
87 QStringList strSplit = str.split(",", QString::SkipEmptyParts);
88 foreach (QString commaTok, strSplit) {
89 // Is this token a range of bands
90 if (commaTok.contains('-')) {
91 QString dashTok;
92 int start = toInt(commaTok.mid(0, commaTok.indexOf("-")));
93 int end = toInt(commaTok.mid(commaTok.indexOf("-") + 1));
94 int direction;
95 direction = (start <= end) ? 1 : -1;
96 // Save the entire range of bands
97 for (int band = start; band != end; band += direction) {
98 result.push_back(Isis::toString(band));
99 }
100 result.push_back(Isis::toString(end));
101 }
102 // This token is a single band specification
103 else {
104 result.push_back(commaTok);
105 }
106 }
107
108 return result;
109 }
110
111
113 return toString(bands());
114 }
115
116
117 void CubeAttributeInput::setBands(const vector<QString> &bands) {
119 }
120
121
122 bool CubeAttributeInput::isBandRange(QString attribute) const {
123 return QRegExp("[0-9,\\-]+").exactMatch(attribute);
124 }
125
126
127 QString CubeAttributeInput::toString(const vector<QString> &bands) {
128 QString result;
129 for (unsigned int i = 0; i < bands.size(); i++) {
130 if (i > 0)
131 result += ",";
132
133 result += bands[i];
134 }
135
136 return result;
137 }
138
139
140 QList<bool (CubeAttributeInput::*)(QString) const> CubeAttributeInput::testers() {
141 QList<bool (CubeAttributeInput::*)(QString) const> result;
142
143 result.append(&CubeAttributeInput::isBandRange);
144
145 return result;
146 }
147
148
149 //---------------------------------------------------------------------------
150 // CubeAttributeOutput Implementation
151 //---------------------------------------------------------------------------
154
155
157 : CubeAttribute<CubeAttributeOutput>(testers(), fileName) {
158 }
159
160
163
164
166 bool result = false;
167
168 QStringList pixelTypeAtts = attributeList(&CubeAttributeOutput::isPixelType);
169
170 if (pixelTypeAtts.isEmpty() || pixelTypeAtts.last() == "PROPAGATE")
171 result = true;
172
173 return result;
174 }
175
176
178 return attributeList(&CubeAttributeOutput::isRange).isEmpty();
179 }
180
181
182// void CubeAttributeOutput::Set(const FileName &fileName) {
183// Reset();
184//
185// Isis::QString str(fileName.attributes());
186//
187// // Remove any white space
188// str.ConvertWhiteSpace();
189// str.Compress();
190// str.Remove(" ");
191// str.UpCase();
192// str.TrimHead("+");
193//
194// // Look at each "+" separate attribute
195// Isis::QString tok;
196// while((tok = str.Token("+")).length() > 0) {
197//
198// // If there is a ":" in this token then it is assumed to be a min:max
199// if (tok.find(":") != string::npos) {
200//
201// // Pull out the minimum
202// Isis::QString colonTok = tok;
203// Isis::QString min = colonTok.Token(":");
204// if (min.length() > 0) {
205// m_minimum = min.ToDouble();
206// }
207// else {
208// m_minimum = 0.0;
209// }
210//
211// // Pull out the maximum
212// Isis::QString max = colonTok.Token(":");
213// if (max.length() > 0) {
214// m_maximum = max.ToDouble();
215// }
216// else {
217// m_maximum = 0.0;
218// }
219// m_rangeType = RangeSet;
220// }
221//
222// // Parse any pixel type attributes
223// else if (tok == "8BIT" || tok == "8-BIT" || tok == "UNSIGNEDBYTE") {
224// m_pixelType = Isis::UnsignedByte;
225// m_pixelTypeDef = "SET";
226// }
227// else if (tok == "16BIT" || tok == "16-BIT" || tok == "SIGNEDWORD") {
228// m_pixelType = Isis::SignedWord;
229// m_pixelTypeDef = "SET";
230// }
231// else if (tok == "32BIT" || tok == "32-BIT" || tok == "REAL") {
232// m_pixelType = Isis::Real;
233// m_pixelTypeDef = "SET";
234// }
235// else if (tok == "PROPAGATE") {
236// m_pixelType = Isis::None;
237// m_pixelTypeDef = "PROPAGATE";
238// }
239//
240// // Parse any file formats
241// else if (tok == "TILE") {
242// m_format = Cube::Tile;
243// }
244// else if (tok == "BSQ" || tok == "BANDSEQUENTIAL") {
245// m_format = Cube::Bsq;
246// }
247//
248// // Parse any byte order
249// else if (tok == "LSB") {
250// m_order = Isis::Lsb;
251// }
252// else if (tok == "MSB") {
253// m_order = Isis::Msb;
254// }
255//
256// // Parse any label type
257// else if (tok == "ATTACHED") {
258// m_labelAttachment = Isis::AttachedLabel;
259// }
260// else if (tok == "DETACHED") {
261// m_labelAttachment = Isis::DetachedLabel;
262// }
263// }
264// }
265
266
268 Cube::Format result = Cube::Tile;
269
270 QStringList formatList = attributeList(&CubeAttributeOutput::isFileFormat);
271
272 if (!formatList.isEmpty()) {
273 QString formatString = formatList.last();
274
275 if (formatString == "BSQ" || formatString == "BANDSEQUENTIAL")
276 result = Cube::Bsq;
277 }
278
279 return result;
280 }
281
282
284 return toString(fileFormat());
285 }
286
287
289 setAttribute((fmt == Cube::Tile)? "Tile" : "BandSequential",
290 &CubeAttributeOutput::isFileFormat);
291 }
292
293
295 double result = Null;
296
298 QString range = attributeList(&CubeAttributeOutput::isRange).last();
299
300 QStringList rangeList = range.split(":");
301 if (rangeList.count() == 2 && rangeList.first() != "")
302 result = toDouble(rangeList.first());
303 }
304
305 return result;
306 }
307
308
310 double result = Null;
311
313 QString range = attributeList(&CubeAttributeOutput::isRange).last();
314
315 QStringList rangeList = range.split(":");
316 if (rangeList.count() == 2 && rangeList.last() != "")
317 result = toDouble(rangeList.last());
318 }
319
320 return result;
321 }
322
323
325 if (!IsSpecial(min)) {
326 QString newRange = Isis::toString(min) + ":";
327
328 if (!IsSpecial(maximum()))
329 newRange += Isis::toString(maximum());
330
331 setAttribute(newRange, &CubeAttributeOutput::isRange);
332 }
333 else if (!IsSpecial(maximum())) {
334 setAttribute(":" + Isis::toString(maximum()), &CubeAttributeOutput::isRange);
335 }
336 else {
337 setAttribute("", &CubeAttributeOutput::isRange);
338 }
339 }
340
341
343 if (!IsSpecial(max)) {
344 QString newRange = ":" + Isis::toString(max);
345
346 if (!IsSpecial(minimum()))
347 newRange = Isis::toString(minimum()) + newRange;
348
349 setAttribute(newRange, &CubeAttributeOutput::isRange);
350 }
351 else if (!IsSpecial(minimum())) {
352 setAttribute(Isis::toString(minimum()) + ":", &CubeAttributeOutput::isRange);
353 }
354 else {
355 setAttribute("", &CubeAttributeOutput::isRange);
356 }
357 }
358
359
361 PixelType result = None;
362
363 if (!propagatePixelType()) {
364 QString pixelTypeAtt = attributeList(&CubeAttributeOutput::isPixelType).last();
365
366 if (pixelTypeAtt == "8BIT" || pixelTypeAtt == "8-BIT" || pixelTypeAtt == "UNSIGNEDBYTE") {
367 result = UnsignedByte;
368 }
369 else if (pixelTypeAtt == "16BIT" || pixelTypeAtt == "16-BIT" || pixelTypeAtt == "SIGNEDWORD") {
370 result = SignedWord;
371 }
372 else if (pixelTypeAtt == "16UBIT" || pixelTypeAtt == "16-UBIT" || pixelTypeAtt == "UNSIGNEDWORD") {
373 result = UnsignedWord;
374 }
375 else if (pixelTypeAtt == "32BIT" || pixelTypeAtt == "32-BIT" || pixelTypeAtt == "REAL") {
376 result = Real;
377 }
378 else if (pixelTypeAtt == "32UINT" || pixelTypeAtt == "32-UINT" || pixelTypeAtt == "UNSIGNEDINTEGER") {
379 result = UnsignedInteger;
380 }
381 else if (pixelTypeAtt == "32INT" || pixelTypeAtt == "32-INT" || pixelTypeAtt == "SIGNEDINTEGER") {
382 result = SignedInteger;
383 }
384 }
385
386 return result;
387 }
388
389
391 setAttribute(PixelTypeName(type), &CubeAttributeOutput::isPixelType);
392 }
393
394
396 setAttribute(LabelAttachmentName(attachment), &CubeAttributeOutput::isLabelAttachment);
397 }
398
399
400 LabelAttachment CubeAttributeOutput::labelAttachment() const {
402
403 QStringList labelAttachmentAtts = attributeList(&CubeAttributeOutput::isLabelAttachment);
404 if (!labelAttachmentAtts.isEmpty()) {
405 QString labelAttachmentAtt = labelAttachmentAtts.last();
406
407 if (labelAttachmentAtt == "DETACHED")
408 result = DetachedLabel;
409 else if (labelAttachmentAtt == "EXTERNAL")
410 result = ExternalLabel;
411 }
412
413 return result;
414 }
415
416
417 bool CubeAttributeOutput::isByteOrder(QString attribute) const {
418 return QRegExp("(M|L)SB").exactMatch(attribute);
419 }
420
421
422 bool CubeAttributeOutput::isFileFormat(QString attribute) const {
423 return QRegExp("(BANDSEQUENTIAL|BSQ|TILE)").exactMatch(attribute);
424 }
425
426
427 bool CubeAttributeOutput::isLabelAttachment(QString attribute) const {
428 return QRegExp("(ATTACHED|DETACHED|EXTERNAL)").exactMatch(attribute);
429 }
430
431
432 bool CubeAttributeOutput::isPixelType(QString attribute) const {
433 QString expressions = "(8-?BIT|16-?BIT|32-?BIT|UNSIGNEDBYTE|SIGNEDWORD|UNSIGNEDWORD|REAL";
434 expressions += "|32-?UINT|32-?INT|UNSIGNEDINTEGER|SIGNEDINTEGER)";
435 return QRegExp(expressions).exactMatch(attribute);
436
437 }
438
439
440 bool CubeAttributeOutput::isRange(QString attribute) const {
441 return QRegExp("[\\-+E0-9.]*:[\\-+E0-9.]*").exactMatch(attribute);
442 }
443
444
446 QString result = "Tile";
447
448 if (format == Cube::Bsq)
449 result = "BandSequential";
450
451 return result;
452 }
453
454
456 ByteOrder result = IsLsb()? Lsb : Msb;
457
458 QStringList byteOrderAtts = attributeList(&CubeAttributeOutput::isByteOrder);
459
460 if (!byteOrderAtts.isEmpty()) {
461 QString byteOrderAtt = byteOrderAtts.last();
462 result = (byteOrderAtt == "LSB")? Lsb : Msb;
463 }
464
465 return result;
466 }
467
468
470 return ByteOrderName(byteOrder());
471 }
472
473
475 setAttribute((order == Msb)? "MSB" : "LSB",
476 &CubeAttributeOutput::isByteOrder);
477 }
478
479
480 QList<bool (CubeAttributeOutput::*)(QString) const> CubeAttributeOutput::testers() {
481 QList<bool (CubeAttributeOutput::*)(QString) const> result;
482
483 result.append(&CubeAttributeOutput::isByteOrder);
484 result.append(&CubeAttributeOutput::isFileFormat);
485 result.append(&CubeAttributeOutput::isLabelAttachment);
486 result.append(&CubeAttributeOutput::isPixelType);
487 result.append(&CubeAttributeOutput::isRange);
488
489 return result;
490 }
491}
Parent class for CubeAttributeInput and CubeAttributeOutput.
QString toString() const
Return a string-representation of this cube attributes.
QStringList attributeList(bool(ChildClass::*tester)(QString) const) const
Get a list of attributes that the tester returns true on.
void setAttributes(const FileName &fileName)
Replaces the current attributes with the attributes in the given file name.
void setAttribute(QString newValue, bool(ChildClass::*tester)(QString) const)
Set the attribute(s) for which tester returns true to newValue.
Manipulate and parse attributes of input cube filenames.
void setBands(const std::vector< QString > &bands)
Set the band attribute according to the list of bands.
QString bandsString() const
Return a string representation of all the bands.
CubeAttributeInput()
Constructs an empty CubeAttributeInput.
~CubeAttributeInput()
Destroys the object.
std::vector< QString > bands() const
Return a vector of the input bands specified.
Manipulate and parse attributes of output cube filenames.
double minimum() const
Return the output cube attribute minimum.
void setLabelAttachment(LabelAttachment attachment)
Set the label attachment type to the parameter value.
ByteOrder byteOrder() const
Return the byte order as an Isis::ByteOrder.
double maximum() const
Return the output cube attribute maximum.
void setByteOrder(ByteOrder order)
Set the order according to the parameter order.
bool propagateMinimumMaximum() const
Return true if the min/max are to be propagated from an input cube.
bool propagatePixelType() const
Return true if the pixel type is to be propagated from an input cube.
Cube::Format fileFormat() const
Return the file format an Cube::Format.
QString fileFormatString() const
Return the file format as a string.
QString byteOrderString() const
Return the byte order as a string.
CubeAttributeOutput()
Constructs an empty CubeAttributeOutput.
PixelType pixelType() const
Return the pixel type as an Isis::PixelType.
void setMinimum(double min)
Set the output cube attribute minimum.
void setMaximum(double max)
Set the output cube attribute maximum.
~CubeAttributeOutput()
Destroys the object.
void setPixelType(PixelType type)
Set the pixel type to that given by the parameter.
void setFileFormat(Cube::Format fmt)
Set the format to the fmt parameter.
Format
These are the possible storage formats of ISIS cubes.
Definition Cube.h:179
@ Tile
Cubes are stored in tile format, that is the order of the pixels in the file (on disk) is BSQ within ...
Definition Cube.h:233
@ Bsq
Cubes are stored in band-sequential format, that is the order of the pixels in the file (on disk) is:
Definition Cube.h:200
File name manipulation and expansion.
Definition FileName.h:100
This is free and unencumbered software released into the public domain.
ByteOrder
Tests the current architecture for byte order.
Definition Endian.h:42
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
bool IsLsb()
Return true if this host is an LSB first machine and false if it is not.
Definition Endian.h:67
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
LabelAttachment
Input cube label type tracker.
@ ExternalLabel
The label is pointing to an external DN file - the label is also external to the data.
@ AttachedLabel
The input label is embedded in the image file.
@ DetachedLabel
The input label is in a separate data file from the image.
const double Null
Value for an Isis Null pixel.
bool IsSpecial(const double d)
Returns if the input pixel is special.
QString PixelTypeName(Isis::PixelType pixelType)
Returns string name of PixelType enumeration entered as input parameter.
Definition PixelType.h:66
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149
QString LabelAttachmentName(LabelAttachment labelType)
Return the string representation of the contents of a variable of type LabelAttachment.
PixelType
Enumerations for Isis Pixel Types.
Definition PixelType.h:27
Namespace for the standard library.