summaryrefslogtreecommitdiffstats
path: root/raslib/miter.icc
diff options
context:
space:
mode:
Diffstat (limited to 'raslib/miter.icc')
-rw-r--r--raslib/miter.icc144
1 files changed, 144 insertions, 0 deletions
diff --git a/raslib/miter.icc b/raslib/miter.icc
new file mode 100644
index 0000000..f4578d2
--- /dev/null
+++ b/raslib/miter.icc
@@ -0,0 +1,144 @@
+/*
+* 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: miter.cc
+ *
+ * MODULE: raslib
+ * CLASS: r_Miter
+ *
+*/
+
+#include "raslib/miter.hh"
+#include "raslib/minterval.hh"
+#include "raslib/rmdebug.hh"
+
+inline
+r_Miter::r_Miter( const r_Minterval* newAreaIter,
+ const r_Minterval* newAreaTile,
+ r_Bytes newCellSize, const char* newFirstCell )
+ : areaIter(newAreaIter), areaTile(newAreaTile), cellSize(newCellSize),
+ firstCell(newFirstCell), done(false)
+{
+ RMDBGENTER(1, RMDebug::module_raslib, "r_Miter", "r_Miter()");
+ // the following initializes incArrIter and calculates the first offset
+ int tIncIter = 1; // total increment for current dimension
+ int prevTIncIter = 1; // total increment for previous dimension
+ r_Bytes incIter = cellSize; // current increment
+ r_Dimension i;
+ int firstOff = 0;
+
+ RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "area for iteration: " << *newAreaIter);
+ RMDBGMIDDLE(2, RMDebug::module_raslib, "r_Miter", "whole area: " << *newAreaTile);
+
+ // dimensionality of both areaIter and areaTile
+ r_Dimension dim = areaIter->dimension();
+ // stores the increments
+ incArrIter = new incArrElem[dim];
+
+ for( i=0; i<dim; i++ ) {
+ // in RasDaMan the order of dimensions is the other way round!
+ int r = dim - i - 1;
+ // used for counting in iteration, initialize with 0
+ incArrIter[i].curr = 0;
+ // how often is the increment added?
+ incArrIter[i].repeat = (*areaIter)[r].high() - (*areaIter)[r].low() + 1;
+ RMDBGMIDDLE(4, RMDebug::module_raslib, "r_Miter", "repeat dim " << i << ": " << incArrIter[i].repeat );
+ // the increment for the result tile (higher dimensions calculated
+ // further down)
+ incArrIter[i].inc = incIter;
+ RMDBGMIDDLE(4, RMDebug::module_raslib, "r_Miter", "incIter dim " << i << ": " << incIter );
+
+ // calculate starting offset and increments for higher dimensions
+ // firstOff is the offset in chars of the first cell
+ firstOff += ((*areaIter)[r].low()-(*areaTile)[r].low()) * prevTIncIter * cellSize;
+ // tInc is the increment if the dimension would be skipped
+ tIncIter = ((*areaTile)[r].high()-(*areaTile)[r].low()+1) * prevTIncIter;
+ // inc is the real increment, after some cells in the dimensions
+ // have been iterated through.
+ incIter = (tIncIter - incArrIter[i].repeat*prevTIncIter) * cellSize;
+ // remember total increment of last dimension
+ prevTIncIter = tIncIter;
+ }
+ firstCell += firstOff;
+ reset();
+ RMDBGEXIT(1, RMDebug::module_raslib, "r_Miter", "r_Miter()");
+}
+
+inline
+r_Miter::~r_Miter()
+{
+ delete [] incArrIter;
+}
+
+inline void
+r_Miter::reset()
+{
+ currCell = (char*)firstCell;
+ done = false;
+ lowCount = 0;
+ for( r_Dimension i=0; i<areaIter->dimension(); i++ ) {
+ incArrIter[i].curr = 0;
+ }
+}
+
+inline char*
+r_Miter::nextCell()
+{
+ // return the current cell
+ char* retVal = currCell;
+ r_Dimension i = 0;
+
+ if(done)
+ return retVal;
+
+ // increment adresses
+ currCell += incArrIter[0].inc;
+ lowCount++;
+ if(lowCount == incArrIter[0].repeat) {
+ lowCount = 0;
+ // increment other dimensions
+ for(i=1; i < areaIter->dimension(); i++) {
+ incArrIter[i].curr++;
+ currCell += incArrIter[i].inc;
+ if(incArrIter[i].curr < incArrIter[i].repeat) {
+ // no overflow in this dimension
+ break;
+ } else {
+ // overflow in this dimension
+ incArrIter[i].curr = 0;
+ }
+ }
+ if( i == areaIter->dimension() ) {
+ // overflow in last dimension
+ done = true;
+ currCell = retVal;
+ }
+ }
+ return retVal;
+}
+
+bool
+r_Miter::isDone()
+{
+ return done;
+}