summaryrefslogtreecommitdiffstats
path: root/raslib/miterf.icc
diff options
context:
space:
mode:
Diffstat (limited to 'raslib/miterf.icc')
-rw-r--r--raslib/miterf.icc222
1 files changed, 222 insertions, 0 deletions
diff --git a/raslib/miterf.icc b/raslib/miterf.icc
new file mode 100644
index 0000000..dad1b2e
--- /dev/null
+++ b/raslib/miterf.icc
@@ -0,0 +1,222 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * SOURCE: miterf.icc
+ *
+ * MODULE: raslib
+ * CLASS: r_MiterFloat
+ *
+*/
+
+#include "raslib/miterf.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rmdebug.hh"
+
+#include <math.h>
+
+
+const int r_FixedPointNumber::FIXPREC = 30;
+const r_Range r_FixedPointNumber::carryPos = 1<<FIXPREC;
+const r_Range r_FixedPointNumber::fracMask = carryPos-1;
+const double r_FixedPointNumber::fixOne = pow(2,(double)FIXPREC);
+
+inline
+r_FixedPointNumber::r_FixedPointNumber()
+ {
+ intPart=0; fracPart=0;
+ }
+
+inline
+r_FixedPointNumber::r_FixedPointNumber(const double &d)
+ { init(d);
+ }
+
+inline
+r_FixedPointNumber& r_FixedPointNumber::operator=(const r_FixedPointNumber &f)
+ {
+ intPart = f.intPart;
+ fracPart = f.fracPart;
+ return *this;
+ }
+
+inline
+r_FixedPointNumber& r_FixedPointNumber::operator=(const double &d)
+ {
+ init(d);
+ return *this;
+ }
+
+inline
+void r_FixedPointNumber::init(const double &d)
+ {
+ intPart = (r_Range)d;
+
+ fracPart= (r_Range)fmod(fixOne*d,fixOne);
+
+ }
+
+inline
+r_Range r_FixedPointNumber::stepForward(const r_FixedPointNumber &f)
+ {
+ r_Range oldIntPart = intPart;
+
+ intPart+=f.intPart; fracPart+=f.fracPart;
+
+ if(fracPart & carryPos)
+ {
+ intPart++;
+ fracPart &= fracMask;
+
+ }
+ return intPart-oldIntPart;
+ }
+
+inline
+bool r_FixedPointNumber::stepForwardFlag(const r_FixedPointNumber &f)
+ {
+ intPart+=f.intPart; fracPart+=f.fracPart;
+
+ if(fracPart & carryPos)
+ {
+ intPart++;
+ fracPart &= fracMask;
+ return true;
+ }
+ return false;
+ }
+
+inline
+r_Range r_FixedPointNumber::getIntPart()
+ {
+ return intPart;
+ }
+
+inline
+std::ostream& operator<<(std::ostream &os,r_FixedPointNumber &f)
+ { os<<'('<<f.intPart<<':'<<f.fracPart<<')';
+ return os;
+ }
+
+//######################################
+
+inline
+r_MiterFloat::r_MiterFloat(Tile *sourceTile, r_Minterval& sourceDomain, r_Minterval& destDomain)
+ {
+ dim = sourceDomain.dimension();
+ iterDesc = new iter_desc[dim];
+
+ r_Bytes cellSize = sourceTile->getType()->getSize();
+ firstCell = sourceTile->getContents();
+
+ iter_desc *id = 0;
+ const r_Minterval& tileDomain = sourceTile->getDomain();
+
+ int i = 0;
+ r_Bytes step = cellSize;
+
+ id = iterDesc + dim-1;
+
+ for(i=dim-1; i>=0; i--, id-- )
+ {
+ id->min = (double)sourceDomain[i].low();
+ id->step = (double)(sourceDomain[i].high()-sourceDomain[i].low() +1) / ( destDomain[i].high() - destDomain[i].low()+1);
+ id->maxSteps = destDomain[i].high() - destDomain[i].low()+1;
+ id->dimStep = step;
+ id->scaleStep = step * id->step.getIntPart();
+ firstCell += step* (sourceDomain[i].low() - tileDomain[i].low());
+ step *= (tileDomain[i].high() - tileDomain[i].low() + 1);
+ }
+ reset();
+ }
+
+inline
+r_MiterFloat::~r_MiterFloat()
+ {
+ if(iterDesc) delete[] iterDesc;
+ }
+
+inline
+void r_MiterFloat::reset()
+ {
+ for(r_Dimension i=0;i<dim;i++)
+ {
+ iterDesc[i].pos = iterDesc[i].min;
+ iterDesc[i].cell = (char*)firstCell;
+ iterDesc[i].countSteps = iterDesc[i].maxSteps;
+ }
+
+ done=false;
+ }
+
+inline
+char* r_MiterFloat::nextCell()
+ {
+ if(done) return currentCell;
+
+ r_Dimension i = dim;
+ iter_desc *id = iterDesc + dim -1;
+ currentCell = iterDesc[dim-1].cell;
+
+ while( i>0 )
+ {
+ id->countSteps--;
+
+ if(id->countSteps)
+ {// one more step in this dimension
+ if(id->pos.stepForwardFlag(id->step))
+ id->cell += id->dimStep;
+
+ id->cell += id->scaleStep;
+ break;
+ }
+ else
+ { // we are finished with this dimension
+ id->pos = id->min;
+ id->countSteps = id-> maxSteps;
+ id--;
+ i--;
+ }
+ }
+
+ if(i<dim)
+ {
+ if(i == 0)
+ done = true;
+ else
+ {
+ r_Dimension j;
+ for( j=i; j<dim; j++)
+ iterDesc[j].cell = iterDesc[i-1].cell;
+ }
+ }
+ return currentCell;
+ }
+
+inline
+bool r_MiterFloat::isDone()
+ {
+ return done;
+ }
+
+
+