Isis 3 Programmer Reference
ProcessByBrick.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include <functional>
8 
9 #include "ProcessByBrick.h"
10 #include "Brick.h"
11 #include "Cube.h"
12 
13 using namespace std;
14 
15 namespace Isis {
16  ProcessByBrick::ProcessByBrick() {
17  p_inputBrickSamples.clear();
18  p_inputBrickLines.clear();
19  p_inputBrickBands.clear();
20 
21  p_outputBrickSamples.clear();
22  p_outputBrickLines.clear();
23  p_outputBrickBands.clear();
24 
25  p_outputRequirements = 0;
26  p_inputBrickSizeSet = false;
27  p_outputBrickSizeSet = false;
28  p_wrapOption = false;
29  p_reverse = false;
30  }
31 
32 
33 
34 
35  ProcessByBrick::~ProcessByBrick() {
36  }
37 
38 
58  Cube *ProcessByBrick::SetInputCube(const QString &parameter,
59  int requirements) {
60  int allRequirements = AllMatchOrOne;
61  allRequirements |= requirements;
62  return Process::SetInputCube(parameter, allRequirements);
63  }
64 
86  Cube *ProcessByBrick::SetInputCube(const QString &file,
87  const CubeAttributeInput &att,
88  int requirements) {
89  int allRequirements = AllMatchOrOne;
90  allRequirements |= requirements;
91  return Process::SetInputCube(file, att, allRequirements);
92  }
93 
94 
95 void ProcessByBrick::SetOutputRequirements(int outputRequirements) {
96 
97  p_outputRequirements = outputRequirements;
98 
99 
100 }
101 
102  void ProcessByBrick::SetBricks(IOCubes cn){
103 
104  ;
105 
106  }
107 
120  void ProcessByBrick::VerifyCubes(IOCubes cn){
121 
122  switch(cn){
123 
124  //Error check
125  case InPlace:
126 
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_);
130  }
131  else if ( (InputCubes.size() + OutputCubes.size() == 0) ){
132 
133  string m = "You haven't specified an input or output cube";
134  throw IException(IException::Programmer, m, _FILEINFO_);
135  }
136 
137  break;
138 
139  case InputOutput:
140 
141  //Error checks ... there must be one input and output
142  if(InputCubes.size() != 1) {
143  string m = "You must specify exactly one input cube";
144  throw IException(IException::Programmer, m, _FILEINFO_);
145  }
146  else if(OutputCubes.size() != 1) {
147  string m = "You must specify exactly one output cube";
148  throw IException(IException::Programmer, m, _FILEINFO_);
149  }
150 
151  // The lines in the input and output must match
152  if(InputCubes[0]->lineCount() != OutputCubes[0]->lineCount()) {
153  string m = "The number of lines in the input and output cubes ";
154  m += "must match";
155  throw IException(IException::Programmer, m, _FILEINFO_);
156  }
157 
158  if(InputCubes[0]->sampleCount() != OutputCubes[0]->sampleCount()) {
159  string m = "The number of samples in the input and output cubes ";
160  m += "must match";
161  throw IException(IException::Programmer, m, _FILEINFO_);
162  }
163 
164 
165  // The bands in the input and output must match
166 
167  //If we are only looking for a spatial match (just match lines/samples)
168  //but not bands, then we skip over this check.
169 
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 ";
173  m += "must match";
174  throw IException(IException::Programmer, m, _FILEINFO_);
175  }
176 
177  }
178 
179  break;
180 
181  case InputOutputList:
182 
183  // Make sure we had an image
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_);
187  }
188 
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_);
194  }
195  //If we are only looking for a spatial match (just match lines/samples)
196  //but not bands, then we skip over this check.
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_);
202  }
203  }
204  }
205 
206  break;
207 
208 
209  }//end switch
210 
211  }
212 
213 
214 
225  void ProcessByBrick::SetBrickSize(int ns, int nl, int nb) {
226  SetInputBrickSize(ns, nl, nb);
227  SetOutputBrickSize(ns, nl, nb);
228  return;
229  }
230 
231 
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);
248 
249  p_inputBrickSizeSet = true;
250  }
251 
252 
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_);
268  }
269 
270  // If a default size has already been set, use it to fill in
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]);
275  }
276  // otherwise, make this the default size
277  else {
278  p_inputBrickSamples.resize(InputCubes.size() + 1, ns);
279  p_inputBrickLines.resize(InputCubes.size() + 1, nl);
280  p_inputBrickBands.resize(InputCubes.size() + 1, nb);
281  }
282 
283  p_inputBrickSamples[cube] = ns;
284  p_inputBrickLines[cube] = nl;
285  p_inputBrickBands[cube] = nb;
286 
287  p_inputBrickSizeSet = true;
288  }
289 
290 
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);
307 
308  p_outputBrickSizeSet = true;
309  }
310 
311 
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_);
327  }
328 
329  // If a default size has already been set, use it to fill in
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]);
335  }
336  // otherwise, make this the default size
337  else {
338  p_outputBrickSamples.resize(OutputCubes.size() + 1, ns);
339  p_outputBrickLines.resize(OutputCubes.size() + 1, nl);
340  p_outputBrickBands.resize(OutputCubes.size() + 1, nb);
341  }
342 
343  p_outputBrickSamples[cube] = ns;
344  p_outputBrickLines[cube] = nl;
345  p_outputBrickBands[cube] = nb;
346 
347  p_outputBrickSizeSet = true;
348  }
349 
364  Isis::Cube *ProcessByBrick::SetOutputCube(const QString &fname,
365  const Isis::CubeAttributeOutput &att) {
366  int nl = InputCubes[0]->lineCount();
367  int ns = InputCubes[0]->sampleCount();
368  int nb = InputCubes[0]->bandCount();
369  return Process::SetOutputCube(fname, att, ns, nl, nb);
370  }
371 
380  void ProcessByBrick::SetProcessingDirection(ProcessingDirection direction) {
381  p_reverse = direction == BandsFirst ? true : false;
382  }
383 
384 
393  ProcessByBrick::ProcessingDirection ProcessByBrick::GetProcessingDirection() {
394  return p_reverse ? BandsFirst : LinesFirst;
395  }
396 
397 
409  void ProcessByBrick::SetWrap(bool wrap) {
410  p_wrapOption = wrap;
411  }
412 
413 
419  bool ProcessByBrick::Wraps() {
420  return p_wrapOption;
421  }
422 
423 
437  void ProcessByBrick::StartProcess(void funct(Buffer &in)) {
438  Cube *cube = NULL;
439  Brick *brick = NULL;
440 
441  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
442 
443  // Loop and let the app programmer work with the bricks
444  p_progress->SetMaximumSteps(brick->Bricks());
445  p_progress->CheckStatus();
446 
447  for (brick->begin(); !brick->end(); (*brick)++) {
448  if (haveInput)
449  cube->read(*brick); // input only
450 
451  funct(*brick);
452 
453  // output only or input/output
454  if ((!haveInput) || (cube->isReadWrite())) {
455  cube->write(*brick);
456  }
457 
458  p_progress->CheckStatus();
459  }
460 
461  delete brick;
462  }
463 
464 
478  void ProcessByBrick::StartProcess(std::function<void(Buffer &in)> funct ) {
479  Cube *cube = NULL;
480  Brick *brick = NULL;
481 
482  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
483 
484  // Loop and let the app programmer work with the bricks
485  p_progress->SetMaximumSteps(brick->Bricks());
486  p_progress->CheckStatus();
487 
488  for (brick->begin(); !brick->end(); (*brick)++) {
489  if (haveInput)
490  cube->read(*brick); // input only
491 
492  funct(*brick);
493 
494  // output only or input/output
495  if ((!haveInput) || (cube->isReadWrite())) {
496  cube->write(*brick);
497  }
498 
499  p_progress->CheckStatus();
500  }
501 
502  delete brick;
503  }
504 
505 
520  void ProcessByBrick::StartProcess(void funct(Buffer &in, Buffer &out)) {
521  Brick *ibrick = NULL;
522  Brick *obrick = NULL;
523 
524  int numBricks = PrepProcessCube(&ibrick, &obrick);
525 
526  // Loop and let the app programmer work with the bricks
527  p_progress->SetMaximumSteps(numBricks);
528  p_progress->CheckStatus();
529 
530  ibrick->begin();
531  obrick->begin();
532 
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();
538  (*ibrick)++;
539  (*obrick)++;
540  }
541 
542  delete ibrick;
543  delete obrick;
544  }
545 
546 
561  void ProcessByBrick::StartProcess(std::function<void(Buffer &in, Buffer &out)> funct ) {
562  Brick *ibrick = NULL;
563  Brick *obrick = NULL;
564 
565  int numBricks = PrepProcessCube(&ibrick, &obrick);
566 
567  // Loop and let the app programmer work with the bricks
568  p_progress->SetMaximumSteps(numBricks);
569  p_progress->CheckStatus();
570 
571  ibrick->begin();
572  obrick->begin();
573 
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();
579  (*ibrick)++;
580  (*obrick)++;
581  }
582 
583  delete ibrick;
584  delete obrick;
585  }
586 
587 
601  void ProcessByBrick::StartProcess(void funct(std::vector<Buffer *> &in,
602  std::vector<Buffer *> &out)) {
603  // Construct two vectors of brick buffer managers
604  // The input buffer managers
605  vector<Brick *> imgrs;
606  vector<Buffer *> ibufs;
607 
608  // And the output buffer managers
609  vector<Brick *> omgrs;
610  vector<Buffer *> obufs;
611 
612  int numBricks = PrepProcessCubes(ibufs, obufs, imgrs, omgrs);
613 
614  // Loop and let the app programmer process the bricks
615  p_progress->SetMaximumSteps(numBricks);
616  p_progress->CheckStatus();
617 
618  for(int t = 0; t < numBricks; t++) {
619  // Read the input buffers
620  for(unsigned int i = 0; i < InputCubes.size(); i++) {
621  InputCubes[i]->read(*ibufs[i]);
622  }
623 
624  // Pass them to the application function
625  funct(ibufs, obufs);
626 
627  // And copy them into the output cubes
628  for(unsigned int i = 0; i < OutputCubes.size(); i++) {
629  OutputCubes[i]->write(*obufs[i]);
630  omgrs[i]->next();
631  }
632 
633  for(unsigned int i = 0; i < InputCubes.size(); i++) {
634  imgrs[i]->next();
635 
636  // if the manager has reached the end and the
637  // wrap option is on, wrap around to the beginning
638  if(Wraps() && imgrs[i]->end())
639  imgrs[i]->begin();
640 
641  // Enforce same band
642  if(imgrs[i]->Band() != imgrs[0]->Band() &&
643  InputCubes[i]->bandCount() != 1) {
644  imgrs[i]->SetBaseBand(imgrs[0]->Band());
645  }
646  }
647  p_progress->CheckStatus();
648  }
649 
650  for(unsigned int i = 0; i < ibufs.size(); i++) {
651  delete ibufs[i];
652  }
653  ibufs.clear();
654  imgrs.clear();
655 
656  for(unsigned int i = 0; i < obufs.size(); i++) {
657  delete obufs[i];
658  }
659  obufs.clear();
660  omgrs.clear();
661  }
662 
669  void ProcessByBrick::EndProcess() {
670  p_inputBrickSizeSet = false;
671  p_outputBrickSizeSet = false;
672  Process::EndProcess();
673  }
674 
675 
679  void ProcessByBrick::Finalize() {
680  EndProcess();
681  }
682 
683 
691  void ProcessByBrick::BlockingReportProgress(QFuture<void> &future) {
692  int isisReportedProgress = 0;
693  int lastProgressValue = future.progressValue();
694  // Using a mutex with a timeout isn't as bad of a hack as inheriting QThread
695  // but there ought to be a better way.
696  // Does having a local mutex make sense?
697  QMutex sleeper;
698  sleeper.lock();
699  while (!future.isFinished()) {
700  sleeper.tryLock(100);
701 
702  if (future.progressValue() != lastProgressValue) {
703  lastProgressValue = future.progressValue();
704  // Progress min/max are reporting as 0's currently, so we're
705  // assuming the progress value is an Isis progress value.
706  int isisProgressValue = lastProgressValue;
707  while (isisReportedProgress < isisProgressValue) {
708  p_progress->CheckStatus();
709  isisReportedProgress++;
710  }
711  }
712  }
713 
714  while (isisReportedProgress < future.progressValue()) {
715  p_progress->CheckStatus();
716  isisReportedProgress++;
717  }
718 
719  // Need to unlock the mutex before it goes out of scope, otherwise Qt5 issues a warning
720  sleeper.unlock();
721  }
722 
723 
737  vector<int> ProcessByBrick::CalculateMaxDimensions(
738  vector<Cube *> cubes) const {
739  int maxSamples = 0;
740  int maxLines = 0;
741  int maxBands = 0;
742 
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();
747 
748  if (sampleCount > maxSamples)
749  maxSamples = sampleCount;
750  if (lineCount > maxLines)
751  maxLines = lineCount;
752  if (bandCount > maxBands)
753  maxBands = bandCount;
754  }
755 
756  vector<int> maxDimensions;
757  maxDimensions.push_back(maxSamples);
758  maxDimensions.push_back(maxLines);
759  maxDimensions.push_back(maxBands);
760  return maxDimensions;
761  }
762 
763 
779  bool ProcessByBrick::PrepProcessCubeInPlace(Cube **cube, Brick **bricks) {
780  // Error checks
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_);
784  }
785 
786  bool haveInput;
787  if (InputCubes.size() == 1) {
788 
789  SetBricks(InPlace);
790  // Make sure the brick size has been set
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_);
795  }
796  // And the size is stored
797  else if (p_inputBrickSamples.size() == 1) {
798  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
799  p_inputBrickBands[0], 1);
800  }
801 
802  haveInput = true;
803  *cube = InputCubes[0];
804  *bricks = new Brick(**cube, p_inputBrickSamples[1],
805  p_inputBrickLines[1], p_inputBrickBands[1], p_reverse);
806  }
807  else {
808  SetBricks(InPlace);
809  // Make sure the brick size has been set
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_);
814  }
815  // And the size is stored
816  else if (p_outputBrickSamples.size() == 1) {
817  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
818  p_outputBrickBands[0], 1);
819  }
820 
821  haveInput = false;
822  *cube = OutputCubes[0];
823  *bricks = new Brick(**cube, p_outputBrickSamples[1],
824  p_outputBrickLines[1], p_outputBrickBands[1], p_reverse);
825  }
826 
827  return haveInput;
828  }
829 
830 
846  int ProcessByBrick::PrepProcessCube(Brick **ibrick, Brick **obrick) {
847  // Error checks ... there must be one input and output
848  if (InputCubes.size() != 1) {
849  string m = "You must specify exactly one input cube";
850  throw IException(IException::Programmer, m, _FILEINFO_);
851  }
852  else if (OutputCubes.size() != 1) {
853  string m = "You must specify exactly one output cube";
854  throw IException(IException::Programmer, m, _FILEINFO_);
855  }
856  SetBricks(InputOutput);
857  // Make sure the brick size has been set
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_);
862  }
863 
864  // Make all input and/or output cubes have the same size
865  if (p_outputBrickSamples.size() == 1) {
866  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
867  p_outputBrickBands[0], 1);
868  }
869  if (p_inputBrickSamples.size() == 1) {
870  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
871  p_inputBrickBands[0], 1);
872  }
873 
874  // Construct brick buffers
875  if (Wraps()) {
876  // Use the size of each cube as the area for the bricks to traverse since
877  // we will be wrapping if we hit the end of one, but not the other.
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);
882  }
883  else {
884  // Since we are not wrapping, we need to find the maximum size of the
885  // input cube and the output cube. We will use this size when
886  // constructing each of the bricks' area to traverse so that we don't
887  // read into nonexistent bands of the smaller of the two cubes.
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];
895 
896  *ibrick = new Brick(maxSamples, maxLines, maxBands,
897  p_inputBrickSamples[1],
898  p_inputBrickLines[1],
899  p_inputBrickBands[1],
900  InputCubes[0]->pixelType(),
901  p_reverse);
902  *obrick = new Brick(maxSamples, maxLines, maxBands,
903  p_outputBrickSamples[1],
904  p_outputBrickLines[1],
905  p_outputBrickBands[1],
906  OutputCubes[0]->pixelType(),
907  p_reverse);
908  }
909 
910  int numBricks;
911  if((*ibrick)->Bricks() > (*obrick)->Bricks()) {
912  numBricks = (*ibrick)->Bricks();
913  }
914  else {
915  numBricks = (*obrick)->Bricks();
916  }
917 
918  return numBricks;
919  }
920 
921 
938  int ProcessByBrick::PrepProcessCubes(vector<Buffer *> & ibufs,
939  vector<Buffer *> & obufs,
940  vector<Brick *> & imgrs,
941  vector<Brick *> & omgrs) {
942  // Make sure we had an image
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_);
946  }
947 
948  SetBricks(InputOutputList);
949 
950  // Make sure the brick size has been set
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_);
955  }
956  else if(p_inputBrickSizeSet && p_inputBrickSamples.size() == 1) {
957  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
958  p_inputBrickBands[0], InputCubes.size());
959  }
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_);
964  }
965  else if(p_outputBrickSizeSet && p_outputBrickSamples.size() == 1) {
966  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
967  p_outputBrickBands[0], OutputCubes.size());
968  }
969 
970  // this parameter holds the number of bricks to be used in processing
971  // which is the maximum number of bricks of all the cubes.
972  int numBricks = 0;
973 
974  // If we are not wrapping, we need to find the maximum size of the input and
975  // output cubes. We will use this size when constructing each of the bricks'
976  // area to traverse so that we don't read into nonexistent bands of the
977  // smaller cubes.
978  int maxSamples = 0;
979  int maxLines = 0;
980  int maxBands = 0;
981  if (!Wraps()) {
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];
989  }
990 
991  for (unsigned int i = 1; i <= InputCubes.size(); i++) {
992  Brick *ibrick = NULL;
993  if (Wraps()) {
994  // Use the size of each cube as the area for the bricks to traverse
995  // since we will be wrapping if we hit the end of a cube before we are
996  // done processing.
997  ibrick = new Brick(*InputCubes[i-1],
998  p_inputBrickSamples[i],
999  p_inputBrickLines[i],
1000  p_inputBrickBands[i],
1001  p_reverse);
1002  }
1003  else {
1004  ibrick = new Brick(maxSamples, maxLines, maxBands,
1005  p_inputBrickSamples[i],
1006  p_inputBrickLines[i],
1007  p_inputBrickBands[i],
1008  InputCubes[i - 1]->pixelType(),
1009  p_reverse);
1010  }
1011  ibrick->begin();
1012  ibufs.push_back(ibrick);
1013  imgrs.push_back(ibrick);
1014  if(numBricks < ibrick->Bricks()) {
1015  numBricks = ibrick->Bricks();
1016  }
1017  }
1018 
1019  for (unsigned int i = 1; i <= OutputCubes.size(); i++) {
1020  Brick *obrick = NULL;
1021  if (Wraps()) {
1022  obrick = new Brick(*OutputCubes[i-1],
1023  p_outputBrickSamples[i],
1024  p_outputBrickLines[i],
1025  p_outputBrickBands[i],
1026  p_reverse);
1027  }
1028  else {
1029  obrick = new Brick(maxSamples, maxLines, maxBands,
1030  p_outputBrickSamples[i],
1031  p_outputBrickLines[i],
1032  p_outputBrickBands[i],
1033  OutputCubes[i - 1]->pixelType(),
1034  p_reverse);
1035  }
1036  obrick->begin();
1037  obufs.push_back(obrick);
1038  omgrs.push_back(obrick);
1039  if(numBricks < obrick->Bricks()) {
1040  numBricks = obrick->Bricks();
1041  }
1042  }
1043 
1044  return numBricks;
1045  }
1046 
1047 
1053  ProcessByBrick::ProcessIterator::ProcessIterator(int position) :
1054  m_currentPosition(position) {
1055  }
1056 
1057 
1064  const ProcessIterator &other) :
1065  m_currentPosition(other.m_currentPosition) {
1066  }
1067 
1068 
1073  m_currentPosition = -1;
1074  }
1075 
1076 
1083  m_currentPosition++;
1084  return *this;
1085  }
1086 } // end namespace isis
Isis::Cube::read
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:807
Isis::CubeAttributeOutput
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
Isis::Brick
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:45
Isis::ProcessByBrick::ProcessIterator::operator++
ProcessIterator & operator++()
Increment the process iterator to the next position.
Definition: ProcessByBrick.cpp:1082
Isis::BufferManager::begin
bool begin()
Moves the shape buffer to the first position.
Definition: BufferManager.h:96
Isis::Brick::Bricks
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:168
Isis::Buffer
Buffer for reading and writing cube data.
Definition: Buffer.h:53
Isis::BufferManager::end
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
Definition: BufferManager.h:115
Isis::Cube::lineCount
int lineCount() const
Definition: Cube.cpp:1734
Isis::Cube::isReadWrite
bool isReadWrite() const
Test if the opened cube is read-write, that is read and write operations should succeed if this is tr...
Definition: Cube.cpp:235
Isis::ProcessByBrick::ProcessIterator::ProcessIterator
ProcessIterator(int position)
Initialize a process iterator given a position.
Definition: ProcessByBrick.cpp:1053
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::ProcessByBrick::ProcessIterator::~ProcessIterator
virtual ~ProcessIterator()
Destructor.
Definition: ProcessByBrick.cpp:1072
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::ProcessByBrick::ProcessIterator
This class is designed to iterate over all brick positions in a cube.
Definition: ProcessByBrick.h:748
std
Namespace for the standard library.
Isis::Cube::write
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition: Cube.cpp:971
Isis::CubeAttributeInput
Manipulate and parse attributes of input cube filenames.
Definition: CubeAttribute.h:381
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16