Isis 3 Programmer Reference
ProcessByBrick.cpp
Go to the documentation of this file.
1 
23 #include <functional>
24 
25 #include "ProcessByBrick.h"
26 #include "Brick.h"
27 #include "Cube.h"
28 
29 using namespace std;
30 
31 namespace Isis {
32  ProcessByBrick::ProcessByBrick() {
33  p_inputBrickSamples.clear();
34  p_inputBrickLines.clear();
35  p_inputBrickBands.clear();
36 
37  p_outputBrickSamples.clear();
38  p_outputBrickLines.clear();
39  p_outputBrickBands.clear();
40 
41  p_outputRequirements = 0;
42  p_inputBrickSizeSet = false;
43  p_outputBrickSizeSet = false;
44  p_wrapOption = false;
45  p_reverse = false;
46  }
47 
48 
49 
50 
51  ProcessByBrick::~ProcessByBrick() {
52  }
53 
54 
74  Cube *ProcessByBrick::SetInputCube(const QString &parameter,
75  int requirements) {
76  int allRequirements = AllMatchOrOne;
77  allRequirements |= requirements;
78  return Process::SetInputCube(parameter, allRequirements);
79  }
80 
102  Cube *ProcessByBrick::SetInputCube(const QString &file,
103  const CubeAttributeInput &att,
104  int requirements) {
105  int allRequirements = AllMatchOrOne;
106  allRequirements |= requirements;
107  return Process::SetInputCube(file, att, allRequirements);
108  }
109 
110 
111 void ProcessByBrick::SetOutputRequirements(int outputRequirements) {
112 
113  p_outputRequirements = outputRequirements;
114 
115 
116 }
117 
118  void ProcessByBrick::SetBricks(IOCubes cn){
119 
120  ;
121 
122  }
123 
136  void ProcessByBrick::VerifyCubes(IOCubes cn){
137 
138  switch(cn){
139 
140  //Error check
141  case InPlace:
142 
143  if (InputCubes.size() +OutputCubes.size() > 1) {
144  string m = "You can only specify exactly one input or output cube";
145  throw IException(IException::Programmer,m,_FILEINFO_);
146  }
147  else if ( (InputCubes.size() + OutputCubes.size() == 0) ){
148 
149  string m = "You haven't specified an input or output cube";
150  throw IException(IException::Programmer, m, _FILEINFO_);
151  }
152 
153  break;
154 
155  case InputOutput:
156 
157  //Error checks ... there must be one input and output
158  if(InputCubes.size() != 1) {
159  string m = "You must specify exactly one input cube";
160  throw IException(IException::Programmer, m, _FILEINFO_);
161  }
162  else if(OutputCubes.size() != 1) {
163  string m = "You must specify exactly one output cube";
164  throw IException(IException::Programmer, m, _FILEINFO_);
165  }
166 
167  // The lines in the input and output must match
168  if(InputCubes[0]->lineCount() != OutputCubes[0]->lineCount()) {
169  string m = "The number of lines in the input and output cubes ";
170  m += "must match";
171  throw IException(IException::Programmer, m, _FILEINFO_);
172  }
173 
174  if(InputCubes[0]->sampleCount() != OutputCubes[0]->sampleCount()) {
175  string m = "The number of samples in the input and output cubes ";
176  m += "must match";
177  throw IException(IException::Programmer, m, _FILEINFO_);
178  }
179 
180 
181  // The bands in the input and output must match
182 
183  //If we are only looking for a spatial match (just match lines/samples)
184  //but not bands, then we skip over this check.
185 
186  if ( !(p_outputRequirements & Isis::SpatialMatch ) ) {
187  if(InputCubes[0]->bandCount() != OutputCubes[0]->bandCount()) {
188  string m = "The number of bands in the input and output cubes ";
189  m += "must match";
190  throw IException(IException::Programmer, m, _FILEINFO_);
191  }
192 
193  }
194 
195  break;
196 
197  case InputOutputList:
198 
199  // Make sure we had an image
200  if (InputCubes.size() + OutputCubes.size() < 1) {
201  string m = "You have not specified any input or output cubes";
202  throw IException(IException::Programmer, m, _FILEINFO_);
203  }
204 
205  for (unsigned int i = 0; i < OutputCubes.size(); i++) {
206  if (OutputCubes[i]->lineCount() != OutputCubes[0]->lineCount() ) {
207  string m = "All output cubes must have the same number of lines ";
208  m += "as the first input cube or output cube";
209  throw IException(IException::Programmer, m, _FILEINFO_);
210  }
211  //If we are only looking for a spatial match (just match lines/samples)
212  //but not bands, then we skip over this check.
213  if ( !(p_outputRequirements & Isis::SpatialMatch ) ) {
214  if (OutputCubes[i]->bandCount() != OutputCubes[0]->bandCount() ) {
215  string m = "All output cubes must have the same number of bands ";
216  m += "as the first input cube or output cube";
217  throw IException(IException::Programmer, m, _FILEINFO_);
218  }
219  }
220  }
221 
222  break;
223 
224 
225  }//end switch
226 
227  }
228 
229 
230 
241  void ProcessByBrick::SetBrickSize(int ns, int nl, int nb) {
242  SetInputBrickSize(ns, nl, nb);
243  SetOutputBrickSize(ns, nl, nb);
244  return;
245  }
246 
247 
257  void ProcessByBrick::SetInputBrickSize(int ns, int nl, int nb) {
258  p_inputBrickSamples.clear();
259  p_inputBrickSamples.resize(InputCubes.size() + 1, ns);
260  p_inputBrickLines.clear();
261  p_inputBrickLines.resize(InputCubes.size() + 1, nl);
262  p_inputBrickBands.clear();
263  p_inputBrickBands.resize(InputCubes.size() + 1, nb);
264 
265  p_inputBrickSizeSet = true;
266  }
267 
268 
280  void ProcessByBrick::SetInputBrickSize(int ns, int nl, int nb, int cube) {
281  if (cube > (int)InputCubes.size()) {
282  string m = "The specified cube is out of range";
283  throw IException(IException::Programmer, m, _FILEINFO_);
284  }
285 
286  // If a default size has already been set, use it to fill in
287  if (p_inputBrickSamples.size() > 0) {
288  p_inputBrickSamples.resize(InputCubes.size() + 1, p_inputBrickSamples[0]);
289  p_inputBrickLines.resize(InputCubes.size() + 1, p_inputBrickLines[0]);
290  p_inputBrickBands.resize(InputCubes.size() + 1, p_inputBrickBands[0]);
291  }
292  // otherwise, make this the default size
293  else {
294  p_inputBrickSamples.resize(InputCubes.size() + 1, ns);
295  p_inputBrickLines.resize(InputCubes.size() + 1, nl);
296  p_inputBrickBands.resize(InputCubes.size() + 1, nb);
297  }
298 
299  p_inputBrickSamples[cube] = ns;
300  p_inputBrickLines[cube] = nl;
301  p_inputBrickBands[cube] = nb;
302 
303  p_inputBrickSizeSet = true;
304  }
305 
306 
316  void ProcessByBrick::SetOutputBrickSize(int ns, int nl, int nb) {
317  p_outputBrickSamples.clear();
318  p_outputBrickSamples.resize(OutputCubes.size() + 1, ns);
319  p_outputBrickLines.clear();
320  p_outputBrickLines.resize(OutputCubes.size() + 1, nl);
321  p_outputBrickBands.clear();
322  p_outputBrickBands.resize(OutputCubes.size() + 1, nb);
323 
324  p_outputBrickSizeSet = true;
325  }
326 
327 
339  void ProcessByBrick::SetOutputBrickSize(int ns, int nl, int nb, int cube) {
340  if(cube > (int)OutputCubes.size()) {
341  string m = "The specified cube is out of range";
342  throw IException(IException::Programmer, m, _FILEINFO_);
343  }
344 
345  // If a default size has already been set, use it to fill in
346  if(p_outputBrickSamples.size() > 0) {
347  p_outputBrickSamples.resize(OutputCubes.size() + 1,
348  p_outputBrickSamples[0]);
349  p_outputBrickLines.resize(OutputCubes.size() + 1, p_outputBrickLines[0]);
350  p_outputBrickBands.resize(OutputCubes.size() + 1, p_outputBrickBands[0]);
351  }
352  // otherwise, make this the default size
353  else {
354  p_outputBrickSamples.resize(OutputCubes.size() + 1, ns);
355  p_outputBrickLines.resize(OutputCubes.size() + 1, nl);
356  p_outputBrickBands.resize(OutputCubes.size() + 1, nb);
357  }
358 
359  p_outputBrickSamples[cube] = ns;
360  p_outputBrickLines[cube] = nl;
361  p_outputBrickBands[cube] = nb;
362 
363  p_outputBrickSizeSet = true;
364  }
365 
380  Isis::Cube *ProcessByBrick::SetOutputCube(const QString &fname,
381  const Isis::CubeAttributeOutput &att) {
382  int nl = InputCubes[0]->lineCount();
383  int ns = InputCubes[0]->sampleCount();
384  int nb = InputCubes[0]->bandCount();
385  return Process::SetOutputCube(fname, att, ns, nl, nb);
386  }
387 
396  void ProcessByBrick::SetProcessingDirection(ProcessingDirection direction) {
397  p_reverse = direction == BandsFirst ? true : false;
398  }
399 
400 
409  ProcessByBrick::ProcessingDirection ProcessByBrick::GetProcessingDirection() {
410  return p_reverse ? BandsFirst : LinesFirst;
411  }
412 
413 
425  void ProcessByBrick::SetWrap(bool wrap) {
426  p_wrapOption = wrap;
427  }
428 
429 
435  bool ProcessByBrick::Wraps() {
436  return p_wrapOption;
437  }
438 
439 
453  void ProcessByBrick::StartProcess(void funct(Buffer &in)) {
454  Cube *cube = NULL;
455  Brick *brick = NULL;
456 
457  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
458 
459  // Loop and let the app programmer work with the bricks
460  p_progress->SetMaximumSteps(brick->Bricks());
461  p_progress->CheckStatus();
462 
463  for (brick->begin(); !brick->end(); (*brick)++) {
464  if (haveInput)
465  cube->read(*brick); // input only
466 
467  funct(*brick);
468 
469  // output only or input/output
470  if ((!haveInput) || (cube->isReadWrite())) {
471  cube->write(*brick);
472  }
473 
474  p_progress->CheckStatus();
475  }
476 
477  delete brick;
478  }
479 
480 
494  void ProcessByBrick::StartProcess(std::function<void(Buffer &in)> funct ) {
495  Cube *cube = NULL;
496  Brick *brick = NULL;
497 
498  bool haveInput = PrepProcessCubeInPlace(&cube, &brick);
499 
500  // Loop and let the app programmer work with the bricks
501  p_progress->SetMaximumSteps(brick->Bricks());
502  p_progress->CheckStatus();
503 
504  for (brick->begin(); !brick->end(); (*brick)++) {
505  if (haveInput)
506  cube->read(*brick); // input only
507 
508  funct(*brick);
509 
510  // output only or input/output
511  if ((!haveInput) || (cube->isReadWrite())) {
512  cube->write(*brick);
513  }
514 
515  p_progress->CheckStatus();
516  }
517 
518  delete brick;
519  }
520 
521 
536  void ProcessByBrick::StartProcess(void funct(Buffer &in, Buffer &out)) {
537  Brick *ibrick = NULL;
538  Brick *obrick = NULL;
539 
540  int numBricks = PrepProcessCube(&ibrick, &obrick);
541 
542  // Loop and let the app programmer work with the bricks
543  p_progress->SetMaximumSteps(numBricks);
544  p_progress->CheckStatus();
545 
546  ibrick->begin();
547  obrick->begin();
548 
549  for (int i = 0; i < numBricks; i++) {
550  InputCubes[0]->read(*ibrick);
551  funct(*ibrick, *obrick);
552  OutputCubes[0]->write(*obrick);
553  p_progress->CheckStatus();
554  (*ibrick)++;
555  (*obrick)++;
556  }
557 
558  delete ibrick;
559  delete obrick;
560  }
561 
562 
577  void ProcessByBrick::StartProcess(std::function<void(Buffer &in, Buffer &out)> funct ) {
578  Brick *ibrick = NULL;
579  Brick *obrick = NULL;
580 
581  int numBricks = PrepProcessCube(&ibrick, &obrick);
582 
583  // Loop and let the app programmer work with the bricks
584  p_progress->SetMaximumSteps(numBricks);
585  p_progress->CheckStatus();
586 
587  ibrick->begin();
588  obrick->begin();
589 
590  for (int i = 0; i < numBricks; i++) {
591  InputCubes[0]->read(*ibrick);
592  funct(*ibrick, *obrick);
593  OutputCubes[0]->write(*obrick);
594  p_progress->CheckStatus();
595  (*ibrick)++;
596  (*obrick)++;
597  }
598 
599  delete ibrick;
600  delete obrick;
601  }
602 
603 
617  void ProcessByBrick::StartProcess(void funct(std::vector<Buffer *> &in,
618  std::vector<Buffer *> &out)) {
619  // Construct two vectors of brick buffer managers
620  // The input buffer managers
621  vector<Brick *> imgrs;
622  vector<Buffer *> ibufs;
623 
624  // And the output buffer managers
625  vector<Brick *> omgrs;
626  vector<Buffer *> obufs;
627 
628  int numBricks = PrepProcessCubes(ibufs, obufs, imgrs, omgrs);
629 
630  // Loop and let the app programmer process the bricks
631  p_progress->SetMaximumSteps(numBricks);
632  p_progress->CheckStatus();
633 
634  for(int t = 0; t < numBricks; t++) {
635  // Read the input buffers
636  for(unsigned int i = 0; i < InputCubes.size(); i++) {
637  InputCubes[i]->read(*ibufs[i]);
638  }
639 
640  // Pass them to the application function
641  funct(ibufs, obufs);
642 
643  // And copy them into the output cubes
644  for(unsigned int i = 0; i < OutputCubes.size(); i++) {
645  OutputCubes[i]->write(*obufs[i]);
646  omgrs[i]->next();
647  }
648 
649  for(unsigned int i = 0; i < InputCubes.size(); i++) {
650  imgrs[i]->next();
651 
652  // if the manager has reached the end and the
653  // wrap option is on, wrap around to the beginning
654  if(Wraps() && imgrs[i]->end())
655  imgrs[i]->begin();
656 
657  // Enforce same band
658  if(imgrs[i]->Band() != imgrs[0]->Band() &&
659  InputCubes[i]->bandCount() != 1) {
660  imgrs[i]->SetBaseBand(imgrs[0]->Band());
661  }
662  }
663  p_progress->CheckStatus();
664  }
665 
666  for(unsigned int i = 0; i < ibufs.size(); i++) {
667  delete ibufs[i];
668  }
669  ibufs.clear();
670  imgrs.clear();
671 
672  for(unsigned int i = 0; i < obufs.size(); i++) {
673  delete obufs[i];
674  }
675  obufs.clear();
676  omgrs.clear();
677  }
678 
685  void ProcessByBrick::EndProcess() {
686  p_inputBrickSizeSet = false;
687  p_outputBrickSizeSet = false;
688  Process::EndProcess();
689  }
690 
691 
695  void ProcessByBrick::Finalize() {
696  EndProcess();
697  }
698 
699 
707  void ProcessByBrick::BlockingReportProgress(QFuture<void> &future) {
708  int isisReportedProgress = 0;
709  int lastProgressValue = future.progressValue();
710  // Using a mutex with a timeout isn't as bad of a hack as inheriting QThread
711  // but there ought to be a better way.
712  // Does having a local mutex make sense?
713  QMutex sleeper;
714  sleeper.lock();
715  while (!future.isFinished()) {
716  sleeper.tryLock(100);
717 
718  if (future.progressValue() != lastProgressValue) {
719  lastProgressValue = future.progressValue();
720  // Progress min/max are reporting as 0's currently, so we're
721  // assuming the progress value is an Isis progress value.
722  int isisProgressValue = lastProgressValue;
723  while (isisReportedProgress < isisProgressValue) {
724  p_progress->CheckStatus();
725  isisReportedProgress++;
726  }
727  }
728  }
729 
730  while (isisReportedProgress < future.progressValue()) {
731  p_progress->CheckStatus();
732  isisReportedProgress++;
733  }
734 
735  // Need to unlock the mutex before it goes out of scope, otherwise Qt5 issues a warning
736  sleeper.unlock();
737  }
738 
739 
753  vector<int> ProcessByBrick::CalculateMaxDimensions(
754  vector<Cube *> cubes) const {
755  int maxSamples = 0;
756  int maxLines = 0;
757  int maxBands = 0;
758 
759  for (unsigned int i = 0; i < cubes.size(); i++) {
760  int sampleCount = cubes[i]->sampleCount();
761  int lineCount = cubes[i]->lineCount();
762  int bandCount = cubes[i]->bandCount();
763 
764  if (sampleCount > maxSamples)
765  maxSamples = sampleCount;
766  if (lineCount > maxLines)
767  maxLines = lineCount;
768  if (bandCount > maxBands)
769  maxBands = bandCount;
770  }
771 
772  vector<int> maxDimensions;
773  maxDimensions.push_back(maxSamples);
774  maxDimensions.push_back(maxLines);
775  maxDimensions.push_back(maxBands);
776  return maxDimensions;
777  }
778 
779 
795  bool ProcessByBrick::PrepProcessCubeInPlace(Cube **cube, Brick **bricks) {
796  // Error checks
797  if ((InputCubes.size() + OutputCubes.size()) != 1) {
798  string m = "You can only specify exactly one input or output cube";
799  throw IException(IException::Programmer, m, _FILEINFO_);
800  }
801 
802  bool haveInput;
803  if (InputCubes.size() == 1) {
804 
805  SetBricks(InPlace);
806  // Make sure the brick size has been set
807  if (!p_inputBrickSizeSet) {
808  string m = "Use the SetBrickSize() or SetInputBrickSize() method to set"
809  " the input brick size";
810  throw IException(IException::Programmer, m, _FILEINFO_);
811  }
812  // And the size is stored
813  else if (p_inputBrickSamples.size() == 1) {
814  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
815  p_inputBrickBands[0], 1);
816  }
817 
818  haveInput = true;
819  *cube = InputCubes[0];
820  *bricks = new Brick(**cube, p_inputBrickSamples[1],
821  p_inputBrickLines[1], p_inputBrickBands[1], p_reverse);
822  }
823  else {
824  SetBricks(InPlace);
825  // Make sure the brick size has been set
826  if (!p_outputBrickSizeSet) {
827  string m = "Use the SetBrickSize() or SetOutputBrickSize() method to "
828  "set the output brick size";
829  throw IException(IException::Programmer, m, _FILEINFO_);
830  }
831  // And the size is stored
832  else if (p_outputBrickSamples.size() == 1) {
833  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
834  p_outputBrickBands[0], 1);
835  }
836 
837  haveInput = false;
838  *cube = OutputCubes[0];
839  *bricks = new Brick(**cube, p_outputBrickSamples[1],
840  p_outputBrickLines[1], p_outputBrickBands[1], p_reverse);
841  }
842 
843  return haveInput;
844  }
845 
846 
862  int ProcessByBrick::PrepProcessCube(Brick **ibrick, Brick **obrick) {
863  // Error checks ... there must be one input and output
864  if (InputCubes.size() != 1) {
865  string m = "You must specify exactly one input cube";
866  throw IException(IException::Programmer, m, _FILEINFO_);
867  }
868  else if (OutputCubes.size() != 1) {
869  string m = "You must specify exactly one output cube";
870  throw IException(IException::Programmer, m, _FILEINFO_);
871  }
872  SetBricks(InputOutput);
873  // Make sure the brick size has been set
874  if (!p_inputBrickSizeSet || !p_outputBrickSizeSet) {
875  string m = "Use the SetBrickSize(), SetInputBrickSize(), or "
876  "SetOutputBrickSize() method to set the brick sizes";
877  throw IException(IException::Programmer, m, _FILEINFO_);
878  }
879 
880  // Make all input and/or output cubes have the same size
881  if (p_outputBrickSamples.size() == 1) {
882  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
883  p_outputBrickBands[0], 1);
884  }
885  if (p_inputBrickSamples.size() == 1) {
886  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
887  p_inputBrickBands[0], 1);
888  }
889 
890  // Construct brick buffers
891  if (Wraps()) {
892  // Use the size of each cube as the area for the bricks to traverse since
893  // we will be wrapping if we hit the end of one, but not the other.
894  *ibrick = new Brick(*InputCubes[0], p_inputBrickSamples[1],
895  p_inputBrickLines[1], p_inputBrickBands[1], p_reverse);
896  *obrick = new Brick(*OutputCubes[0], p_outputBrickSamples[1],
897  p_outputBrickLines[1], p_outputBrickBands[1], p_reverse);
898  }
899  else {
900  // Since we are not wrapping, we need to find the maximum size of the
901  // input cube and the output cube. We will use this size when
902  // constructing each of the bricks' area to traverse so that we don't
903  // read into nonexistent bands of the smaller of the two cubes.
904  vector<Cube *> allCubes;
905  allCubes.push_back(InputCubes[0]);
906  allCubes.push_back(OutputCubes[0]);
907  vector<int> maxDimensions = CalculateMaxDimensions(allCubes);
908  int maxSamples = maxDimensions[0];
909  int maxLines = maxDimensions[1];
910  int maxBands = maxDimensions[2];
911 
912  *ibrick = new Brick(maxSamples, maxLines, maxBands,
913  p_inputBrickSamples[1],
914  p_inputBrickLines[1],
915  p_inputBrickBands[1],
916  InputCubes[0]->pixelType(),
917  p_reverse);
918  *obrick = new Brick(maxSamples, maxLines, maxBands,
919  p_outputBrickSamples[1],
920  p_outputBrickLines[1],
921  p_outputBrickBands[1],
922  OutputCubes[0]->pixelType(),
923  p_reverse);
924  }
925 
926  int numBricks;
927  if((*ibrick)->Bricks() > (*obrick)->Bricks()) {
928  numBricks = (*ibrick)->Bricks();
929  }
930  else {
931  numBricks = (*obrick)->Bricks();
932  }
933 
934  return numBricks;
935  }
936 
937 
954  int ProcessByBrick::PrepProcessCubes(vector<Buffer *> & ibufs,
955  vector<Buffer *> & obufs,
956  vector<Brick *> & imgrs,
957  vector<Brick *> & omgrs) {
958  // Make sure we had an image
959  if(InputCubes.size() == 0 && OutputCubes.size() == 0) {
960  string m = "You have not specified any input or output cubes";
961  throw IException(IException::Programmer, m, _FILEINFO_);
962  }
963 
964  SetBricks(InputOutputList);
965 
966  // Make sure the brick size has been set
967  if(!p_inputBrickSizeSet && InputCubes.size() > 0) {
968  string m = "Use the SetBrickSize() or SetInputBrick() method to set the "
969  "input brick size(s)";
970  throw IException(IException::Programmer, m, _FILEINFO_);
971  }
972  else if(p_inputBrickSizeSet && p_inputBrickSamples.size() == 1) {
973  SetInputBrickSize(p_inputBrickSamples[0], p_inputBrickLines[0],
974  p_inputBrickBands[0], InputCubes.size());
975  }
976  if(!p_outputBrickSizeSet && OutputCubes.size() > 0) {
977  string m = "Use the SetBrickSize() or SetOutputBrick() method to set the "
978  "output brick size(s)";
979  throw IException(IException::Programmer, m, _FILEINFO_);
980  }
981  else if(p_outputBrickSizeSet && p_outputBrickSamples.size() == 1) {
982  SetOutputBrickSize(p_outputBrickSamples[0], p_outputBrickLines[0],
983  p_outputBrickBands[0], OutputCubes.size());
984  }
985 
986  // this parameter holds the number of bricks to be used in processing
987  // which is the maximum number of bricks of all the cubes.
988  int numBricks = 0;
989 
990  // If we are not wrapping, we need to find the maximum size of the input and
991  // output cubes. We will use this size when constructing each of the bricks'
992  // area to traverse so that we don't read into nonexistent bands of the
993  // smaller cubes.
994  int maxSamples = 0;
995  int maxLines = 0;
996  int maxBands = 0;
997  if (!Wraps()) {
998  vector<Cube *> allCubes(InputCubes);
999  for (unsigned int i = 0; i < OutputCubes.size(); i++)
1000  allCubes.push_back(OutputCubes[i]);
1001  vector<int> maxDimensions = CalculateMaxDimensions(allCubes);
1002  maxSamples = maxDimensions[0];
1003  maxLines = maxDimensions[1];
1004  maxBands = maxDimensions[2];
1005  }
1006 
1007  for (unsigned int i = 1; i <= InputCubes.size(); i++) {
1008  Brick *ibrick = NULL;
1009  if (Wraps()) {
1010  // Use the size of each cube as the area for the bricks to traverse
1011  // since we will be wrapping if we hit the end of a cube before we are
1012  // done processing.
1013  ibrick = new Brick(*InputCubes[i-1],
1014  p_inputBrickSamples[i],
1015  p_inputBrickLines[i],
1016  p_inputBrickBands[i],
1017  p_reverse);
1018  }
1019  else {
1020  ibrick = new Brick(maxSamples, maxLines, maxBands,
1021  p_inputBrickSamples[i],
1022  p_inputBrickLines[i],
1023  p_inputBrickBands[i],
1024  InputCubes[i - 1]->pixelType(),
1025  p_reverse);
1026  }
1027  ibrick->begin();
1028  ibufs.push_back(ibrick);
1029  imgrs.push_back(ibrick);
1030  if(numBricks < ibrick->Bricks()) {
1031  numBricks = ibrick->Bricks();
1032  }
1033  }
1034 
1035  for (unsigned int i = 1; i <= OutputCubes.size(); i++) {
1036  Brick *obrick = NULL;
1037  if (Wraps()) {
1038  obrick = new Brick(*OutputCubes[i-1],
1039  p_outputBrickSamples[i],
1040  p_outputBrickLines[i],
1041  p_outputBrickBands[i],
1042  p_reverse);
1043  }
1044  else {
1045  obrick = new Brick(maxSamples, maxLines, maxBands,
1046  p_outputBrickSamples[i],
1047  p_outputBrickLines[i],
1048  p_outputBrickBands[i],
1049  OutputCubes[i - 1]->pixelType(),
1050  p_reverse);
1051  }
1052  obrick->begin();
1053  obufs.push_back(obrick);
1054  omgrs.push_back(obrick);
1055  if(numBricks < obrick->Bricks()) {
1056  numBricks = obrick->Bricks();
1057  }
1058  }
1059 
1060  return numBricks;
1061  }
1062 
1063 
1069  ProcessByBrick::ProcessIterator::ProcessIterator(int position) :
1070  m_currentPosition(position) {
1071  }
1072 
1073 
1080  const ProcessIterator &other) :
1081  m_currentPosition(other.m_currentPosition) {
1082  }
1083 
1084 
1089  m_currentPosition = -1;
1090  }
1091 
1092 
1099  m_currentPosition++;
1100  return *this;
1101  }
1102 } // end namespace isis
Buffer for reading and writing cube data.
Definition: Buffer.h:69
Manipulate and parse attributes of input cube filenames.
This class is designed to iterate over all brick positions in a cube.
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:61
Namespace for the standard library.
ProcessIterator & operator++()
Increment the process iterator to the next position.
bool begin()
Moves the shape buffer to the first position.
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:152
int Bricks()
Returns the number of Bricks in the cube.
Definition: Brick.h:184
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
Manipulate and parse attributes of output cube filenames.
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:724
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
int lineCount() const
Definition: Cube.cpp:1379
void write(Blob &blob)
This method will write a blob of data (e.g.
Definition: Cube.cpp:763
ProcessIterator(int position)
Initialize a process iterator given a position.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
IO Handler for Isis Cubes.
Definition: Cube.h:170