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++;