50 ProcessRubberSheet::ProcessRubberSheet(
int startSize,
int endSize) {
52 p_bandChangeFunct = NULL;
57 p_startQuadSize = startSize;
58 p_endQuadSize = endSize;
61 m_patchStartSample = 1;
65 m_patchSampleIncrement = 4;
66 m_patchLineIncrement = 4;
117 void ProcessRubberSheet::setPatchParameters(
int startSample,
int startLine,
118 int samples,
int lines,
119 int sampleIncrement,
int lineIncrement) {
121 m_patchStartSample = startSample;
122 m_patchStartLine = startLine;
123 m_patchSamples = samples;
124 m_patchLines = lines;
125 m_patchSampleIncrement = sampleIncrement;
126 m_patchLineIncrement = lineIncrement;
151 if (InputCubes.size() != 1) {
152 string m =
"You must specify exactly one input cube";
155 else if (OutputCubes.size() != 1) {
156 string m =
"You must specify exactly one output cube";
161 p_lineMap.resize(p_startQuadSize);
162 p_sampMap.resize(p_startQuadSize);
164 for (
unsigned int pos = 0; pos < p_lineMap.size(); pos++) {
165 p_lineMap[pos].resize(p_startQuadSize);
166 p_sampMap[pos].resize(p_startQuadSize);
170 TileManager otile(*OutputCubes[0], p_startQuadSize, p_startQuadSize);
174 InputCubes[0]->pixelType() ,
178 p_progress->SetMaximumSteps(otile.
Tiles());
179 p_progress->CheckStatus();
181 if (p_bandChangeFunct == NULL) {
187 long long int tilesPerBand = otile.
Tiles() / OutputCubes[0]->bandCount();
189 for (
long long int tile = 1; tile <= tilesPerBand; tile++) {
190 bool useLastTileMap =
false;
191 for (
int band = 1; band <= OutputCubes[0]->bandCount(); band++) {
194 if (p_startQuadSize <= 2) {
195 SlowGeom(otile, iportal, trans, interp);
198 QuadTree(otile, iportal, trans, interp, useLastTileMap);
201 useLastTileMap =
true;
203 OutputCubes[0]->write(otile);
204 p_progress->CheckStatus();
209 int lastOutputBand = -1;
211 for (otile.
begin(); !otile.
end(); otile++) {
213 if (lastOutputBand != otile.
Band()) {
214 lastOutputBand = otile.
Band();
216 p_bandChangeFunct(lastOutputBand);
219 if (p_startQuadSize <= 2) {
220 SlowGeom(otile, iportal, trans, interp);
223 QuadTree(otile, iportal, trans, interp,
false);
226 OutputCubes[0]->write(otile);
227 p_progress->CheckStatus();
246 void ProcessRubberSheet::BandChange(
void (*funct)(
const int band)) {
248 p_bandChangeFunct = funct;
255 double outputSamp, outputLine;
256 double inputSamp, inputLine;
257 int outputBand = otile.
Band();
259 for (
int i = 0; i < otile.
size(); i++) {
260 outputSamp = otile.
Sample(i);
261 outputLine = otile.
Line(i);
264 if (trans.
Xform(inputSamp, inputLine, outputSamp, outputLine)) {
265 if ((inputSamp < 0.5) || (inputLine < 0.5) ||
266 (inputLine > InputCubes[0]->lineCount() + 0.5) ||
267 (inputSamp > InputCubes[0]->sampleCount() + 0.5)) {
272 iportal.
SetPosition(inputSamp, inputLine, outputBand);
273 InputCubes[0]->read(iportal);
274 otile[i] = interp.
Interpolate(inputSamp, inputLine,
285 void ProcessRubberSheet::QuadTree(TileManager &otile, Portal &iportal,
286 Transform &trans, Interpolator &interp,
287 bool useLastTileMap) {
290 vector<Quad *> quadTree;
292 if (!useLastTileMap) {
294 Quad *quad =
new Quad;
295 quad->sline = otile.Line();
296 quad->ssamp = otile.Sample();
298 quad->eline = otile.Line(otile.size() - 1);
299 quad->esamp = otile.Sample(otile.size() - 1);
300 quad->slineTile = otile.Line();
301 quad->ssampTile = otile.Sample();
303 quadTree.push_back(quad);
307 while (quadTree.size() > 0) {
308 ProcessQuad(quadTree, trans, p_lineMap, p_sampMap);
313 int outputBand = otile.Band();
314 for (
int i = 0, line = 0; line < p_startQuadSize; line++) {
315 for (
int samp = 0; samp < p_startQuadSize; samp++, i++) {
316 double inputLine = p_lineMap[line][samp];
317 double inputSamp = p_sampMap[line][samp];
318 if (inputLine != NULL8) {
319 iportal.SetPosition(inputSamp, inputLine, outputBand);
320 InputCubes[0]->read(iportal);
321 otile[i] = interp.Interpolate(inputSamp, inputLine,
322 iportal.DoubleBuffer());
344 bool ProcessRubberSheet::TestLine(
Transform &trans,
int ssamp,
int esamp,
345 int sline,
int eline,
int increment) {
347 for (
int line = sline; line <= eline; line += increment) {
348 for (
int sample = ssamp; sample <= esamp; sample += increment) {
352 if (trans.
Xform(sjunk, ljunk, sample, line)) {
363 void ProcessRubberSheet::ProcessQuad(std::vector<Quad *> &quadTree,
365 std::vector< std::vector<double> > &lineMap,
366 std::vector< std::vector<double> > &sampMap) {
368 Quad *quad = quadTree[0];
369 double oline[4], osamp[4];
370 double iline[4], isamp[4];
374 oline[0] = quad->sline;
375 osamp[0] = quad->ssamp;
376 if (!trans.
Xform(isamp[0], iline[0], osamp[0], oline[0])) {
381 oline[1] = quad->sline;
382 osamp[1] = quad->esamp;
383 if (!trans.
Xform(isamp[1], iline[1], osamp[1], oline[1])) {
388 oline[2] = quad->eline;
389 osamp[2] = quad->ssamp;
390 if (!trans.
Xform(isamp[2], iline[2], osamp[2], oline[2])) {
395 oline[3] = quad->eline;
396 osamp[3] = quad->esamp;
397 if (!trans.
Xform(isamp[3], iline[3], osamp[3], oline[3])) {
404 if (badCorner == 4) {
405 if ((quad->eline - quad->sline) < p_endQuadSize) {
406 SlowQuad(quadTree, trans, lineMap, sampMap);
409 if (p_forceSamp !=
Null && p_forceLine !=
Null) {
410 if (p_forceSamp >= quad->ssamp && p_forceSamp <= quad->esamp &&
411 p_forceLine >= quad->sline && p_forceLine <= quad->eline) {
417 int centerSample = (quad->ssamp + quad->esamp) / 2;
418 int centerLine = (quad->sline + quad->eline) / 2;
435 if (TestLine(trans, quad->ssamp + 1, quad->esamp - 1,
436 quad->sline, quad->sline, 4) ||
438 TestLine(trans, quad->ssamp + 1, quad->esamp - 1,
439 quad->eline, quad->eline, 4) ||
441 TestLine(trans, quad->ssamp, quad->ssamp,
442 quad->sline + 1, quad->eline - 1, 4) ||
444 TestLine(trans, quad->esamp, quad->esamp,
445 quad->sline + 1, quad->eline - 1, 4) ||
447 TestLine(trans, centerSample, centerSample,
448 quad->sline + 1, quad->eline - 1, 4) ||
450 TestLine(trans, quad->ssamp + 1, quad->esamp - 1,
451 centerLine, centerLine, 4)) {
459 for (
int i = quad->sline; i <= quad->eline; i++) {
460 for (
int j = quad->ssamp; j <= quad->esamp; j++) {
461 lineMap[i-quad->slineTile][j-quad->ssampTile] = NULL8;
465 quadTree.erase(quadTree.begin());
489 if ((quad->eline - quad->sline) < p_endQuadSize) {
490 SlowQuad(quadTree, trans, lineMap, sampMap);
503 for (
int i = 0; i < 4; i++) {
506 A[i][2] = oline[i] * osamp[i];
514 if ((detA = Det4x4(A)) == 0.0) {
515 if ((quad->eline - quad->sline) < p_endQuadSize) {
516 SlowQuad(quadTree, trans, lineMap, sampMap);
528 for (
int j = 0; j < 4; j++) {
529 memmove(B, A, 16 *
sizeof(
double));
531 for (
int i = 0; i < 4; i++) {
535 lineCoef[j] = Det4x4(B) / detA;
540 for (
int j = 0; j < 4; j++) {
541 memmove(B, A, 16 *
sizeof(
double));
543 for (
int i = 0; i < 4; i++) {
547 sampCoef[j] = Det4x4(B) / detA;
551 double quadMidLine = (quad->sline + quad->eline) / 2.0;
552 double quadMidSamp = (quad->ssamp + quad->esamp) / 2.0;
553 double midLine, midSamp;
555 if (!trans.
Xform(midSamp, midLine, quadMidSamp, quadMidLine)) {
556 if ((quad->eline - quad->sline) < p_endQuadSize) {
557 SlowQuad(quadTree, trans, lineMap, sampMap);
565 double cmidLine = lineCoef[0] * quadMidLine +
566 lineCoef[1] * quadMidSamp +
567 lineCoef[2] * quadMidLine * quadMidSamp +
570 double cmidSamp = sampCoef[0] * quadMidLine +
571 sampCoef[1] * quadMidSamp +
572 sampCoef[2] * quadMidLine * quadMidSamp +
575 if ((abs(cmidSamp - midSamp) > 0.5) || (abs(cmidLine - midLine) > 0.5)) {
576 if ((quad->eline - quad->sline) < p_endQuadSize) {
577 SlowQuad(quadTree, trans, lineMap, sampMap);
587 double ulLine = lineCoef[0] * (double) quad->sline +
588 lineCoef[1] * (
double) quad->ssamp +
589 lineCoef[2] * (double) quad->sline * (
double) quad->ssamp +
592 double ulSamp = sampCoef[0] * (double) quad->sline +
593 sampCoef[1] * (
double) quad->ssamp +
594 sampCoef[2] * (double) quad->sline * (
double) quad->ssamp +
599 double lineChangeWrLine = lineCoef[0] + lineCoef[2] * (double) quad->ssamp;
600 double sampChangeWrLine = sampCoef[0] + sampCoef[2] * (
double) quad->ssamp;
602 for (
int ol = quad->sline; ol <= quad->eline; ol++) {
605 double lineChangeWrSamp = lineCoef[1] + lineCoef[2] * (double) ol;
606 double sampChangeWrSamp = sampCoef[1] + sampCoef[2] * (double) ol;
609 double cline = ulLine;
610 double csamp = ulSamp;
613 int startSamp = quad->ssamp - quad->ssampTile;
614 std::vector<double> &lineVect = lineMap[ol-quad->slineTile];
615 std::vector<double> &sampleVect = sampMap[ol-quad->slineTile];
618 for (
int os = quad->ssamp; os <= quad->esamp; os++) {
619 lineVect[startSamp] = cline;
620 sampleVect[startSamp] = csamp;
624 cline += lineChangeWrSamp;
625 csamp += sampChangeWrSamp;
629 ulLine += lineChangeWrLine;
630 ulSamp += sampChangeWrLine;
635 quadTree.erase(quadTree.begin());
640 void ProcessRubberSheet::SplitQuad(std::vector<Quad *> &quadTree) {
643 Quad *quad = quadTree[0];
644 int n = (quad->eline - quad->sline + 1) / 2;
649 q1->eline = quad->sline + n - 1;
650 q1->esamp = quad->ssamp + n - 1;
651 quadTree.push_back(q1);
656 q2->eline = quad->sline + n - 1;
657 q2->ssamp = quad->ssamp + n;
658 quadTree.push_back(q2);
663 q3->sline = quad->sline + n;
664 q3->esamp = quad->ssamp + n - 1;
665 quadTree.push_back(q3);
670 q4->sline = quad->sline + n;
671 q4->ssamp = quad->ssamp + n;
672 quadTree.push_back(q4);
676 quadTree.erase(quadTree.begin());
681 void ProcessRubberSheet::SlowQuad(std::vector<Quad *> &quadTree,
683 std::vector< std::vector<double> > &lineMap,
684 std::vector< std::vector<double> > &sampMap) {
687 Quad *quad = quadTree[0];
691 for (
int oline = quad->sline; oline <= quad->eline; oline++) {
692 int lineIndex = oline - quad->slineTile;
693 for (
int osamp = quad->ssamp; osamp <= quad->esamp; osamp++) {
694 int sampIndex = osamp - quad->ssampTile;
695 lineMap[lineIndex][sampIndex] = NULL8;
696 if (trans.Xform(isamp, iline, (
double) osamp, (
double) oline)) {
697 if ((isamp >= 0.5) ||
699 (iline <= InputCubes[0]->lineCount() + 0.5) ||
700 (isamp <= InputCubes[0]->sampleCount() + 0.5)) {
701 lineMap[lineIndex][sampIndex] = iline;
702 sampMap[lineIndex][sampIndex] = isamp;
710 quadTree.erase(quadTree.begin());
715 double ProcessRubberSheet::Det4x4(
double m[4][4]) {
719 cofact [0][0] = m[1][1];
720 cofact [0][1] = m[1][2];
721 cofact [0][2] = m[1][3];
722 cofact [1][0] = m[2][1];
723 cofact [1][1] = m[2][2];
724 cofact [1][2] = m[2][3];
725 cofact [2][0] = m[3][1];
726 cofact [2][1] = m[3][2];
727 cofact [2][2] = m[3][3];
728 double det = m[0][0] * Det3x3(cofact);
730 cofact [0][0] = m[1][0];
731 cofact [0][1] = m[1][2];
732 cofact [0][2] = m[1][3];
733 cofact [1][0] = m[2][0];
734 cofact [1][1] = m[2][2];
735 cofact [1][2] = m[2][3];
736 cofact [2][0] = m[3][0];
737 cofact [2][1] = m[3][2];
738 cofact [2][2] = m[3][3];
739 det -= m[0][1] * Det3x3(cofact);
741 cofact [0][0] = m[1][0];
742 cofact [0][1] = m[1][1];
743 cofact [0][2] = m[1][3];
744 cofact [1][0] = m[2][0];
745 cofact [1][1] = m[2][1];
746 cofact [1][2] = m[2][3];
747 cofact [2][0] = m[3][0];
748 cofact [2][1] = m[3][1];
749 cofact [2][2] = m[3][3];
750 det += m[0][2] * Det3x3(cofact);
752 cofact [0][0] = m[1][0];
753 cofact [0][1] = m[1][1];
754 cofact [0][2] = m[1][2];
755 cofact [1][0] = m[2][0];
756 cofact [1][1] = m[2][1];
757 cofact [1][2] = m[2][2];
758 cofact [2][0] = m[3][0];
759 cofact [2][1] = m[3][1];
760 cofact [2][2] = m[3][2];
761 det -= m[0][3] * Det3x3(cofact);
768 double ProcessRubberSheet::Det3x3(
double m[3][3]) {
770 return m[0][0] * m[1][1] * m[2][2] -
771 m[0][0] * m[1][2] * m[2][1] -
772 m[0][1] * m[1][0] * m[2][2] +
773 m[0][1] * m[1][2] * m[2][0] +
774 m[0][2] * m[1][0] * m[2][1] -
775 m[0][2] * m[1][1] * m[2][0];
801 void ProcessRubberSheet::processPatchTransform(
Transform &trans,
805 if (InputCubes.size() != 1) {
806 string m =
"You must specify exactly one input cube";
809 else if (OutputCubes.size() != 1) {
810 string m =
"You must specify exactly one output cube";
816 InputCubes[0]->pixelType() ,
820 int patchesPerBand = 0;
821 for (
int line = m_patchStartLine; line <= InputCubes[0]->lineCount();
822 line += m_patchLineIncrement) {
823 for (
int samp = m_patchStartSample;
824 samp <= InputCubes[0]->sampleCount();
825 samp += m_patchSampleIncrement) {
830 int patchCount = InputCubes[0]->bandCount() * patchesPerBand;
831 p_progress->SetMaximumSteps(patchCount);
832 p_progress->CheckStatus();
854 for (
int band=1; band <= InputCubes[0]->bandCount(); band++) {
855 if (p_bandChangeFunct != NULL) p_bandChangeFunct(band);
856 iportal.SetPosition(1,1,band);
858 for (
int line = m_patchStartLine; line <= InputCubes[0]->lineCount();
859 line += m_patchLineIncrement) {
860 for (
int samp = m_patchStartSample;
861 samp <= InputCubes[0]->sampleCount();
862 samp += m_patchSampleIncrement, p_progress->CheckStatus()) {
863 transformPatch((
double)samp, (
double)(samp + m_patchSamples - 1),
864 (
double)line, (
double)(line + m_patchLines - 1),
865 iportal, trans, interp);
873 void ProcessRubberSheet::transformPatch(
double ssamp,
double esamp,
874 double sline,
double eline,
880 if (esamp > InputCubes[0]->sampleCount()) {
881 esamp = InputCubes[0]->sampleCount();
882 if (ssamp == esamp) ssamp = esamp - 1;
884 if (eline > InputCubes[0]->lineCount()) {
885 eline = InputCubes[0]->lineCount();
886 if (sline == eline) sline = eline - 1;
898 if (trans.
Xform(tsamp,tline,ssamp,sline)) {
899 isamps.push_back(ssamp);
900 ilines.push_back(sline);
901 osamps.push_back(tsamp);
902 olines.push_back(tline);
905 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
910 if (trans.
Xform(tsamp,tline,esamp,sline)) {
911 isamps.push_back(esamp);
912 ilines.push_back(sline);
913 osamps.push_back(tsamp);
914 olines.push_back(tline);
917 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
922 if (trans.
Xform(tsamp,tline,ssamp,eline)) {
923 isamps.push_back(ssamp);
924 ilines.push_back(eline);
925 osamps.push_back(tsamp);
926 olines.push_back(tline);
929 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
934 if (trans.
Xform(tsamp,tline,esamp,eline)) {
935 isamps.push_back(esamp);
936 ilines.push_back(eline);
937 osamps.push_back(tsamp);
938 olines.push_back(tline);
941 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
946 int osampMin = (int) osamps[0];
947 int osampMax = (int) (osamps[0] + 0.5);
948 int olineMin = (int) olines[0];
949 int olineMax = (int) (olines[0] + 0.5);
950 for (
int i = 1; i < osamps.size(); i++) {
951 if (osamps[i] < osampMin) osampMin = (int) osamps[i];
952 if (osamps[i] > osampMax) osampMax = (int) (osamps[i] + 0.5);
953 if (olines[i] < olineMin) olineMin = (int) olines[i];
954 if (olines[i] > olineMax) olineMax = (int) (olines[i] + 0.5);
959 if (osampMax < 1)
return;
960 if (olineMax < 1)
return;
961 if (osampMin > OutputCubes[0]->sampleCount())
return;
962 if (olineMin > OutputCubes[0]->lineCount())
return;
965 if (osampMin < 1) osampMin = 1;
966 if (olineMin < 1) olineMin = 1;
967 if (osampMax > OutputCubes[0]->sampleCount()) {
968 osampMax = OutputCubes[0]->sampleCount();
970 if (olineMax > OutputCubes[0]->lineCount()) {
971 olineMax = OutputCubes[0]->lineCount();
983 if (osampMax - osampMin + 1.0 > OutputCubes[0]->sampleCount() * 0.50) {
984 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
987 if (olineMax - olineMin + 1.0 > OutputCubes[0]->lineCount() * 0.50) {
988 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
993 BasisFunction isampFunc(
"Ax+By+C",3,3);
994 LeastSquares isampLSQ(isampFunc);
996 BasisFunction ilineFunc(
"Dx+Ey+F",3,3);
997 LeastSquares ilineLSQ(ilineFunc);
1000 for (
int i=0; i < isamps.size(); i++) {
1001 std::vector<double> vars;
1002 vars.push_back(osamps[i]);
1003 vars.push_back(olines[i]);
1004 vars.push_back(1.0);
1006 isampLSQ.AddKnown(vars,isamps[i]);
1007 ilineLSQ.AddKnown(vars,ilines[i]);
1010 isampLSQ.Solve(LeastSquares::QRD);
1011 ilineLSQ.Solve(LeastSquares::QRD);
1013 catch (IException &e) {
1014 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
1019 for (
int i=0; i<isamps.size(); i++) {
1020 if (fabs(isampLSQ.Residual(i)) > 0.5) {
1021 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
1024 if (fabs(ilineLSQ.Residual(i)) > 0.5) {
1025 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
1034 double csamp = (ssamp + esamp) / 2.0;
1035 double cline = (sline + eline) / 2.0;
1036 if (trans.
Xform(tsamp,tline,csamp,cline)) {
1037 std::vector<double> vars;
1038 vars.push_back(tsamp);
1039 vars.push_back(tline);
1040 vars.push_back(1.0);
1042 double isamp = isampFunc.Evaluate(vars);
1043 double iline = ilineFunc.Evaluate(vars);
1045 double err = (csamp - isamp) * (csamp - isamp) +
1046 (cline - iline) * (cline - iline);
1048 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
1053 splitPatch(ssamp, esamp, sline, eline, iportal, trans, interp);
1058 double A = isampFunc.Coefficient(0);
1059 double B = isampFunc.Coefficient(1);
1060 double C = isampFunc.Coefficient(2);
1062 double D = ilineFunc.Coefficient(0);
1063 double E = ilineFunc.Coefficient(1);
1064 double F = ilineFunc.Coefficient(2);
1069 Brick oBrick(*OutputCubes[0], osampMax-osampMin+1, olineMax-olineMin+1, 1);
1070 oBrick.SetBasePosition(osampMin, olineMin, iportal.
Band());
1073 bool foundNull =
false;
1074 for (
int oline = olineMin; oline <= olineMax; oline++) {
1075 double isamp = A * osampMin + B * oline + C;
1076 double iline = D * osampMin +
E * oline + F;
1077 double isampChangeWRTosamp = A;
1078 double ilineChangeWRTosamp = D;
1079 for (
int osamp = osampMin; osamp <= osampMax;
1080 osamp++, isamp += isampChangeWRTosamp, iline += ilineChangeWRTosamp) {
1083 InputCubes[0]->read(iportal);
1085 oBrick[brickIndex] = dn;
1086 if (dn ==
Null) foundNull =
true;
1103 Brick readBrick(*OutputCubes[0], osampMax-osampMin+1, olineMax-olineMin+1, 1);
1104 readBrick.SetBasePosition(osampMin, olineMin, iportal.
Band());
1105 OutputCubes[0]->read(readBrick);
1106 for (brickIndex = 0; brickIndex<(osampMax-osampMin+1)*(olineMax-olineMin+1); brickIndex++) {
1107 if (readBrick[brickIndex] !=
Null) {
1108 oBrick[brickIndex] = readBrick[brickIndex];
1114 OutputCubes[0]->write(oBrick);
1120 void ProcessRubberSheet::splitPatch(
double ssamp,
double esamp,
1121 double sline,
double eline, Portal &iportal,
1122 Transform &trans, Interpolator &interp) {
1125 if ((esamp - ssamp < 0.1) && (eline - sline < 0.1))
return;
1128 double midSamp = (esamp + ssamp) / 2.0;
1129 double midLine = (eline + sline) / 2.0;
1131 transformPatch(ssamp, midSamp,
1133 iportal, trans, interp);
1134 transformPatch(midSamp, esamp,
1136 iportal, trans, interp);
1137 transformPatch(ssamp, midSamp,
1139 iportal, trans, interp);
1140 transformPatch(midSamp, esamp,
1142 iportal, trans, interp);
double HotSample()
Returns the sample coordinate of the center pixel in the buffer for the interpolator.
double * DoubleBuffer() const
Returns the value of the shape buffer.
const double Null
Value for an Isis Null pixel.
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
double Interpolate(const double isamp, const double iline, const double buf[])
Performs an interpolation on the data according to the parameters set in the constructor.
Buffer for containing a two dimensional section of an image.
Namespace for the standard library.
This algorithm is designed for applications that jump around between a couple of spots in the cube wi...
int size() const
Returns the total number of pixels in the shape buffer.
bool begin()
Moves the shape buffer to the first position.
This algorithm is designed for applications that jump around between a couple of spots in the cube wi...
int Tiles()
Returns the number of Tiles in the cube.
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
double HotLine()
Returns the line coordinate of the center pixel in the buffer for the interpolator.
int Samples()
Returns the number of samples needed by the interpolator.
bool SetTile(const int Tile, const int band=1)
Sets the current tile as requested.
#define _FILEINFO_
Macro for the filename and line number.
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
const double E
Sets some basic constants for use in ISIS programming.
void SetPosition(const double sample, const double line, const int band)
Sets the line and sample position of the buffer.
int Lines()
Returns the number of lines needed by the interpolator.
Namespace for ISIS/Bullet specific routines.
Buffer manager, for moving through a cube in tiles.