9 #include "ProcessByBrick.h"
16 ProcessByBrick::ProcessByBrick() {
17 p_inputBrickSamples.clear();
18 p_inputBrickLines.clear();
19 p_inputBrickBands.clear();
21 p_outputBrickSamples.clear();
22 p_outputBrickLines.clear();
23 p_outputBrickBands.clear();
25 p_outputRequirements = 0;
26 p_inputBrickSizeSet =
false;
27 p_outputBrickSizeSet =
false;
35 ProcessByBrick::~ProcessByBrick() {
58 Cube *ProcessByBrick::SetInputCube(
const QString ¶meter,
60 int allRequirements = AllMatchOrOne;
61 allRequirements |= requirements;
62 return Process::SetInputCube(parameter, allRequirements);
86 Cube *ProcessByBrick::SetInputCube(
const QString &file,
89 int allRequirements = AllMatchOrOne;
90 allRequirements |= requirements;
91 return Process::SetInputCube(file, att, allRequirements);
95 void ProcessByBrick::SetOutputRequirements(
int outputRequirements) {
97 p_outputRequirements = outputRequirements;
102 void ProcessByBrick::SetBricks(IOCubes cn){
120 void ProcessByBrick::VerifyCubes(IOCubes cn){
127 if (InputCubes.size() +OutputCubes.size() > 1) {
128 string m =
"You can only specify exactly one input or output cube";
129 throw IException(IException::Programmer,m,_FILEINFO_);
131 else if ( (InputCubes.size() + OutputCubes.size() == 0) ){
133 string m =
"You haven't specified an input or output cube";
134 throw IException(IException::Programmer, m, _FILEINFO_);
142 if(InputCubes.size() != 1) {
143 string m =
"You must specify exactly one input cube";
144 throw IException(IException::Programmer, m, _FILEINFO_);
146 else if(OutputCubes.size() != 1) {
147 string m =
"You must specify exactly one output cube";
148 throw IException(IException::Programmer, m, _FILEINFO_);
152 if(InputCubes[0]->lineCount() != OutputCubes[0]->lineCount()) {
153 string m =
"The number of lines in the input and output cubes ";
155 throw IException(IException::Programmer, m, _FILEINFO_);
158 if(InputCubes[0]->sampleCount() != OutputCubes[0]->sampleCount()) {
159 string m =
"The number of samples in the input and output cubes ";
161 throw IException(IException::Programmer, m, _FILEINFO_);
170 if ( !(p_outputRequirements & Isis::SpatialMatch ) ) {
171 if(InputCubes[0]->bandCount() != OutputCubes[0]->bandCount()) {
172 string m =
"The number of bands in the input and output cubes ";
174 throw IException(IException::Programmer, m, _FILEINFO_);
181 case InputOutputList:
184 if (InputCubes.size() + OutputCubes.size() < 1) {
185 string m =
"You have not specified any input or output cubes";
186 throw IException(IException::Programmer, m, _FILEINFO_);
189 for (
unsigned int i = 0; i < OutputCubes.size(); i++) {
190 if (OutputCubes[i]->lineCount() != OutputCubes[0]->lineCount() ) {
191 string m =
"All output cubes must have the same number of lines ";
192 m +=
"as the first input cube or output cube";
193 throw IException(IException::Programmer, m, _FILEINFO_);
197 if ( !(p_outputRequirements & Isis::SpatialMatch ) ) {
198 if (OutputCubes[i]->bandCount() != OutputCubes[0]->bandCount() ) {
199 string m =
"All output cubes must have the same number of bands ";
200 m +=
"as the first input cube or output cube";
201 throw IException(IException::Programmer, m, _FILEINFO_);
225 void ProcessByBrick::SetBrickSize(
int ns,
int nl,
int nb) {
226 SetInputBrickSize(ns, nl, nb);
227 SetOutputBrickSize(ns, nl, nb);
241 void ProcessByBrick::SetInputBrickSize(
int ns,
int nl,
int nb) {
242 p_inputBrickSamples.clear();
243 p_inputBrickSamples.resize(InputCubes.size() + 1, ns);
244 p_inputBrickLines.clear();
245 p_inputBrickLines.resize(InputCubes.size() + 1, nl);
246 p_inputBrickBands.clear();
247 p_inputBrickBands.resize(InputCubes.size() + 1, nb);
249 p_inputBrickSizeSet =
true;
264 void ProcessByBrick::SetInputBrickSize(
int ns,
int nl,
int nb,
int cube) {
265 if (cube > (
int)InputCubes.size()) {
266 string m =
"The specified cube is out of range";
267 throw IException(IException::Programmer, m, _FILEINFO_);
271 if (p_inputBrickSamples.size() > 0) {
272 p_inputBrickSamples.resize(InputCubes.size() + 1, p_inputBrickSamples[0]);
273 p_inputBrickLines.resize(InputCubes.size() + 1, p_inputBrickLines[0]);
274 p_inputBrickBands.resize(InputCubes.size() + 1, p_inputBrickBands[0]);
278 p_inputBrickSamples.resize(InputCubes.size() + 1, ns);
279 p_inputBrickLines.resize(InputCubes.size() + 1, nl);
280 p_inputBrickBands.resize(InputCubes.size() + 1, nb);
283 p_inputBrickSamples[cube] = ns;
284 p_inputBrickLines[cube] = nl;
285 p_inputBrickBands[cube] = nb;
287 p_inputBrickSizeSet =
true;
300 void ProcessByBrick::SetOutputBrickSize(
int ns,
int nl,
int nb) {
301 p_outputBrickSamples.clear();
302 p_outputBrickSamples.resize(OutputCubes.size() + 1, ns);
303 p_outputBrickLines.clear();
304 p_outputBrickLines.resize(OutputCubes.size() + 1, nl);
305 p_outputBrickBands.clear();
306 p_outputBrickBands.resize(OutputCubes.size() + 1, nb);
308 p_outputBrickSizeSet =
true;
323 void ProcessByBrick::SetOutputBrickSize(
int ns,
int nl,
int nb,
int cube) {
324 if(cube > (
int)OutputCubes.size()) {
325 string m =
"The specified cube is out of range";
326 throw IException(IException::Programmer, m, _FILEINFO_);
330 if(p_outputBrickSamples.size() > 0) {
331 p_outputBrickSamples.resize(OutputCubes.size() + 1,
332 p_outputBrickSamples[0]);
333 p_outputBrickLines.resize(OutputCubes.size() + 1, p_outputBrickLines[0]);
334 p_outputBrickBands.resize(OutputCubes.size() + 1, p_outputBrickBands[0]);
338 p_outputBrickSamples.resize(OutputCubes.size() + 1, ns);
339 p_outputBrickLines.resize(OutputCubes.size() + 1, nl);
340 p_outputBrickBands.resize(OutputCubes.size() + 1, nb);
343 p_outputBrickSamples[cube] = ns;
344 p_outputBrickLines[cube] = nl;
345 p_outputBrickBands[cube] = nb;
347 p_outputBrickSizeSet =
true;
364 Isis::Cube *ProcessByBrick::SetOutputCube(
const QString &fname,
367 int ns = InputCubes[0]->sampleCount();
368 int nb = InputCubes[0]->bandCount();
369 return Process::SetOutputCube(fname, att, ns, nl, nb);
380 void ProcessByBrick::SetProcessingDirection(ProcessingDirection direction) {
381 p_reverse = direction == BandsFirst ? true :
false;
393 ProcessByBrick::ProcessingDirection ProcessByBrick::GetProcessingDirection() {
394 return p_reverse ? BandsFirst : LinesFirst;
409 void ProcessByBrick::SetWrap(
bool wrap) {
419 bool ProcessByBrick::Wraps() {
437 void ProcessByBrick::StartProcess(
void funct(
Buffer &in)) {
441 bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
444 p_progress->SetMaximumSteps(brick->
Bricks());
445 p_progress->CheckStatus();
447 for (brick->
begin(); !brick->
end(); (*brick)++) {
458 p_progress->CheckStatus();
478 void ProcessByBrick::StartProcess(std::function<
void(
Buffer &in)> funct ) {
482 bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
485 p_progress->SetMaximumSteps(brick->
Bricks());
486 p_progress->CheckStatus();
488 for (brick->
begin(); !brick->
end(); (*brick)++) {
499 p_progress->CheckStatus();
520 void ProcessByBrick::StartProcess(
void funct(
Buffer &in,
Buffer &out)) {
521 Brick *ibrick = NULL;
522 Brick *obrick = NULL;
524 int numBricks = PrepProcessCube(&ibrick, &obrick);
527 p_progress->SetMaximumSteps(numBricks);
528 p_progress->CheckStatus();
533 for (
int i = 0; i < numBricks; i++) {
534 InputCubes[0]->read(*ibrick);
535 funct(*ibrick, *obrick);
536 OutputCubes[0]->write(*obrick);
537 p_progress->CheckStatus();
561 void ProcessByBrick::StartProcess(std::function<
void(
Buffer &in,
Buffer &out)> funct ) {
562 Brick *ibrick = NULL;
563 Brick *obrick = NULL;
565 int numBricks = PrepProcessCube(&ibrick, &obrick);
568 p_progress->SetMaximumSteps(numBricks);
569 p_progress->CheckStatus();
574 for (
int i = 0; i < numBricks; i++) {
575 InputCubes[0]->read(*ibrick);
576 funct(*ibrick, *obrick);
577 OutputCubes[0]->write(*obrick);
578 p_progress->CheckStatus();
601 void ProcessByBrick::StartProcess(
void funct(std::vector<Buffer *> &in,
602 std::vector<Buffer *> &out)) {
605 vector<Brick *> imgrs;
606 vector<Buffer *> ibufs;
609 vector<Brick *> omgrs;
610 vector<Buffer *> obufs;
612 int numBricks = PrepProcessCubes(ibufs, obufs, imgrs, omgrs);
615 p_progress->SetMaximumSteps(numBricks);
616 p_progress->CheckStatus();
618 for(
int t = 0; t < numBricks; t++) {
620 for(
unsigned int i = 0; i < InputCubes.size(); i++) {
621 InputCubes[i]->read(*ibufs[i]);
628 for(
unsigned int i = 0; i < OutputCubes.size(); i++) {
629 OutputCubes[i]->write(*obufs[i]);
633 for(
unsigned int i = 0; i < InputCubes.size(); i++) {
638 if(Wraps() && imgrs[i]->end())
642 if(imgrs[i]->Band() != imgrs[0]->Band() &&
643 InputCubes[i]->bandCount() != 1) {
644 imgrs[i]->SetBaseBand(imgrs[0]->Band());
647 p_progress->CheckStatus();
650 for(
unsigned int i = 0; i < ibufs.size(); i++) {
656 for(
unsigned int i = 0; i < obufs.size(); i++) {
669 void ProcessByBrick::EndProcess() {
670 p_inputBrickSizeSet =
false;
671 p_outputBrickSizeSet =
false;
672 Process::EndProcess();
679 void ProcessByBrick::Finalize() {
691 void ProcessByBrick::BlockingReportProgress(QFuture<void> &future) {
692 int isisReportedProgress = 0;
693 int lastProgressValue = future.progressValue();
699 while (!future.isFinished()) {
700 sleeper.tryLock(100);
702 if (future.progressValue() != lastProgressValue) {
703 lastProgressValue = future.progressValue();
706 int isisProgressValue = lastProgressValue;
707 while (isisReportedProgress < isisProgressValue) {
708 p_progress->CheckStatus();
709 isisReportedProgress++;
714 while (isisReportedProgress < future.progressValue()) {
715 p_progress->CheckStatus();
716 isisReportedProgress++;
737 vector<int> ProcessByBrick::CalculateMaxDimensions(
738 vector<Cube *> cubes)
const {
743 for (
unsigned int i = 0; i < cubes.size(); i++) {
744 int sampleCount = cubes[i]->sampleCount();
745 int lineCount = cubes[i]->lineCount();
746 int bandCount = cubes[i]->bandCount();
748 if (sampleCount > maxSamples)
749 maxSamples = sampleCount;
750 if (lineCount > maxLines)
751 maxLines = lineCount;
752 if (bandCount > maxBands)
753 maxBands = bandCount;
756 vector<int> maxDimensions;
757 maxDimensions.push_back(maxSamples);
758 maxDimensions.push_back(maxLines);
759 maxDimensions.push_back(maxBands);
760 return maxDimensions;
779 bool ProcessByBrick::PrepProcessCubeInPlace(
Cube **cube,
Brick **bricks) {
781 if ((InputCubes.size() + OutputCubes.size()) != 1) {
782 string m =
"You can only specify exactly one input or output cube";
783 throw IException(IException::Programmer, m, _FILEINFO_);
787 if (InputCubes.size() == 1) {
791 if (!p_inputBrickSizeSet) {
792 string m =
"Use the SetBrickSize() or SetInputBrickSize() method to set"
793 " the input brick size";
794 throw IException(IException::Programmer, m, _FILEINFO_);
797 else if (p_inputBrickSamples.size() == 1) {
798 SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
799 p_inputBrickBands[0], 1);
803 *cube = InputCubes[0];
804 *bricks =
new Brick(**cube, p_inputBrickSamples[1],
805 p_inputBrickLines[1], p_inputBrickBands[1], p_reverse);
810 if (!p_outputBrickSizeSet) {
811 string m =
"Use the SetBrickSize() or SetOutputBrickSize() method to "
812 "set the output brick size";
813 throw IException(IException::Programmer, m, _FILEINFO_);
816 else if (p_outputBrickSamples.size() == 1) {
817 SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
818 p_outputBrickBands[0], 1);
822 *cube = OutputCubes[0];
823 *bricks =
new Brick(**cube, p_outputBrickSamples[1],
824 p_outputBrickLines[1], p_outputBrickBands[1], p_reverse);
846 int ProcessByBrick::PrepProcessCube(
Brick **ibrick,
Brick **obrick) {
848 if (InputCubes.size() != 1) {
849 string m =
"You must specify exactly one input cube";
850 throw IException(IException::Programmer, m, _FILEINFO_);
852 else if (OutputCubes.size() != 1) {
853 string m =
"You must specify exactly one output cube";
854 throw IException(IException::Programmer, m, _FILEINFO_);
856 SetBricks(InputOutput);
858 if (!p_inputBrickSizeSet || !p_outputBrickSizeSet) {
859 string m =
"Use the SetBrickSize(), SetInputBrickSize(), or "
860 "SetOutputBrickSize() method to set the brick sizes";
861 throw IException(IException::Programmer, m, _FILEINFO_);
865 if (p_outputBrickSamples.size() == 1) {
866 SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
867 p_outputBrickBands[0], 1);
869 if (p_inputBrickSamples.size() == 1) {
870 SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
871 p_inputBrickBands[0], 1);
878 *ibrick =
new Brick(*InputCubes[0], p_inputBrickSamples[1],
879 p_inputBrickLines[1], p_inputBrickBands[1], p_reverse);
880 *obrick =
new Brick(*OutputCubes[0], p_outputBrickSamples[1],
881 p_outputBrickLines[1], p_outputBrickBands[1], p_reverse);
888 vector<Cube *> allCubes;
889 allCubes.push_back(InputCubes[0]);
890 allCubes.push_back(OutputCubes[0]);
891 vector<int> maxDimensions = CalculateMaxDimensions(allCubes);
892 int maxSamples = maxDimensions[0];
893 int maxLines = maxDimensions[1];
894 int maxBands = maxDimensions[2];
896 *ibrick =
new Brick(maxSamples, maxLines, maxBands,
897 p_inputBrickSamples[1],
898 p_inputBrickLines[1],
899 p_inputBrickBands[1],
900 InputCubes[0]->pixelType(),
902 *obrick =
new Brick(maxSamples, maxLines, maxBands,
903 p_outputBrickSamples[1],
904 p_outputBrickLines[1],
905 p_outputBrickBands[1],
906 OutputCubes[0]->pixelType(),
911 if((*ibrick)->Bricks() > (*obrick)->Bricks()) {
912 numBricks = (*ibrick)->Bricks();
915 numBricks = (*obrick)->Bricks();
938 int ProcessByBrick::PrepProcessCubes(vector<Buffer *> & ibufs,
939 vector<Buffer *> & obufs,
940 vector<Brick *> & imgrs,
941 vector<Brick *> & omgrs) {
943 if(InputCubes.size() == 0 && OutputCubes.size() == 0) {
944 string m =
"You have not specified any input or output cubes";
945 throw IException(IException::Programmer, m, _FILEINFO_);
948 SetBricks(InputOutputList);
951 if(!p_inputBrickSizeSet && InputCubes.size() > 0) {
952 string m =
"Use the SetBrickSize() or SetInputBrick() method to set the "
953 "input brick size(s)";
954 throw IException(IException::Programmer, m, _FILEINFO_);
956 else if(p_inputBrickSizeSet && p_inputBrickSamples.size() == 1) {
957 SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
958 p_inputBrickBands[0], InputCubes.size());
960 if(!p_outputBrickSizeSet && OutputCubes.size() > 0) {
961 string m =
"Use the SetBrickSize() or SetOutputBrick() method to set the "
962 "output brick size(s)";
963 throw IException(IException::Programmer, m, _FILEINFO_);
965 else if(p_outputBrickSizeSet && p_outputBrickSamples.size() == 1) {
966 SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
967 p_outputBrickBands[0], OutputCubes.size());
982 vector<Cube *> allCubes(InputCubes);
983 for (
unsigned int i = 0; i < OutputCubes.size(); i++)
984 allCubes.push_back(OutputCubes[i]);
985 vector<int> maxDimensions = CalculateMaxDimensions(allCubes);
986 maxSamples = maxDimensions[0];
987 maxLines = maxDimensions[1];
988 maxBands = maxDimensions[2];
991 for (
unsigned int i = 1; i <= InputCubes.size(); i++) {
992 Brick *ibrick = NULL;
997 ibrick =
new Brick(*InputCubes[i-1],
998 p_inputBrickSamples[i],
999 p_inputBrickLines[i],
1000 p_inputBrickBands[i],
1004 ibrick =
new Brick(maxSamples, maxLines, maxBands,
1005 p_inputBrickSamples[i],
1006 p_inputBrickLines[i],
1007 p_inputBrickBands[i],
1008 InputCubes[i - 1]->pixelType(),
1012 ibufs.push_back(ibrick);
1013 imgrs.push_back(ibrick);
1014 if(numBricks < ibrick->Bricks()) {
1015 numBricks = ibrick->
Bricks();
1019 for (
unsigned int i = 1; i <= OutputCubes.size(); i++) {
1020 Brick *obrick = NULL;
1022 obrick =
new Brick(*OutputCubes[i-1],
1023 p_outputBrickSamples[i],
1024 p_outputBrickLines[i],
1025 p_outputBrickBands[i],
1029 obrick =
new Brick(maxSamples, maxLines, maxBands,
1030 p_outputBrickSamples[i],
1031 p_outputBrickLines[i],
1032 p_outputBrickBands[i],
1033 OutputCubes[i - 1]->pixelType(),
1037 obufs.push_back(obrick);
1038 omgrs.push_back(obrick);
1039 if(numBricks < obrick->Bricks()) {
1040 numBricks = obrick->
Bricks();
1053 ProcessByBrick::ProcessIterator::ProcessIterator(
int position) :
1054 m_currentPosition(position) {
1065 m_currentPosition(other.m_currentPosition) {
1073 m_currentPosition = -1;
1083 m_currentPosition++;