36 #ifndef VIGRA_MULTI_BLOCKING_HXX 
   37 #define VIGRA_MULTI_BLOCKING_HXX 
   39 #include "vigra/tinyvector.hxx" 
   40 #include "vigra/box.hxx" 
   41 #include "vigra/multi_iterator.hxx" 
   42 #include "vigra/multi_convolution.hxx" 
   43 #include "vigra/transform_iterator.hxx" 
   48     template<
unsigned int DIM, 
class C>
 
   52     namespace detail_multi_blocking{
 
   54         template<
unsigned int DIM, 
class C>
 
   55         class BlockWithBorder{
 
   69             const Block & core()
const{
 
   73             Block  localCore()
const{
 
   74                 return core_-border_.begin();
 
   78             const Block & border()
const{
 
   82             bool operator == (
const BlockWithBorder & rhs)
 const{
 
   83                 return core_ == rhs.core_ && border_ == rhs.border_;
 
   85             bool operator != (
const BlockWithBorder & rhs)
 const{
 
   86                 return core_ != rhs.core_ || border_ != rhs.border_;
 
   94         template<
class VALUETYPE, 
unsigned int DIMENSION>
 
   95         std::ostream& operator<< (std::ostream& stream, const BlockWithBorder<DIMENSION,VALUETYPE> & bwb) {
 
   96             stream<<
"["<<bwb.core()<<
", "<<bwb.border()<<
" ]";
 
  102         class MultiCoordToBlockWithBoarder{
 
  104             typedef typename MB::Shape Shape;
 
  105             typedef typename MB::BlockDesc BlockDesc;
 
  106             typedef typename MB::BlockWithBorder result_type;
 
  107             MultiCoordToBlockWithBoarder()
 
  111             MultiCoordToBlockWithBoarder(
const MB & mb, 
const Shape & width)
 
  116             result_type operator()(
const BlockDesc & blockDesc)
const{
 
  117                 return mb_->getBlockWithBorder(blockDesc, width_);
 
  125         class MultiCoordToBlock{
 
  127             typedef typename MB::Shape Shape;
 
  128             typedef typename MB::BlockDesc BlockDesc;
 
  129             typedef typename MB::Block result_type;
 
  133             MultiCoordToBlock(
const MB & mb)
 
  137             result_type operator()(
const BlockDesc & blockDesc)
const{
 
  138                 return mb_->getBlock(blockDesc);
 
  156     template<
unsigned int DIM, 
class C = MultiArrayIndex>
 
  159         typedef MultiBlocking<DIM, C> SelfType;
 
  160         friend class detail_multi_blocking::MultiCoordToBlock<SelfType>;
 
  161         friend class detail_multi_blocking::MultiCoordToBlockWithBoarder<SelfType>;
 
  162         typedef C  PointValue;
 
  163         typedef TinyVector<PointValue, DIM> Point;
 
  165         typedef Point BlockDesc;
 
  166         typedef Box<PointValue, DIM> Block;
 
  167         typedef MultiCoordinateIterator< DIM> MultiCoordIter;
 
  168         typedef detail_multi_blocking::BlockWithBorder<DIM, PointValue> BlockWithBorder;
 
  172         typedef detail_multi_blocking::MultiCoordToBlockWithBoarder<SelfType> CoordToBwb;
 
  173         typedef detail_multi_blocking::MultiCoordToBlock<SelfType> CoordToB;
 
  174         typedef EndAwareTransformIterator<CoordToBwb, MultiCoordIter> BlockWithBorderIter;
 
  175         typedef EndAwareTransformIterator<CoordToB,   MultiCoordIter> BlockIter;
 
  178         MultiBlocking(
const Shape & shape,
 
  179                       const Shape & blockShape,
 
  180                       const Shape & roiBegin = Shape(0),
 
  181                       const Shape & roiEnd = Shape(0)
 
  184             roiBlock_(roiBegin,roiEnd == Shape(0) ? shape : roiEnd),
 
  185             blockShape_(blockShape),
 
  186             blocksPerAxis_(vigra::SkipInitialization),
 
  189             const Shape roiShape = roiBlock_.
size();
 
  190             blocksPerAxis_ = roiShape / blockShape_;
 
  194             for(
size_t d=0; d<DIM; ++d){
 
  195                 if(blocksPerAxis_[d]*blockShape_[d] < roiShape[d] ){
 
  198                 numBlocks_ *= blocksPerAxis_[d];
 
  202             Shape beginCA(0),endCB(shape);
 
  203             for(
size_t d=0; d<DIM; ++d){
 
  208                     volumeBorderBlocks_.push_back(Block(beginCA,endCA));
 
  212                     Shape beginCB(shape);
 
  214                     volumeBorderBlocks_.push_back(Block(beginCB,endCB));
 
  219             Shape insideVolBlockShapeEnd(shape);
 
  220             insideVolBlockShapeEnd -= Shape(1);
 
  221             insideVolBlock_.
setEnd(insideVolBlockShapeEnd);
 
  229         BlockWithBorderIter blockWithBorderBegin(
const Shape & width)
const{
 
  230             return BlockWithBorderIter(MultiCoordIter(blocksPerAxis_),
 
  231                                        CoordToBwb(*
this, width));
 
  234         BlockWithBorderIter blockWithBorderEnd(
const Shape & width)
const{
 
  235             const MultiCoordIter beginIter(blocksPerAxis_);
 
  236             return BlockWithBorderIter(beginIter.getEndIterator(),
 
  237                                        CoordToBwb(*
this, width));
 
  240         Block blockDescToBlock(
const BlockDesc & desc){
 
  241             MultiCoordIter beginIter(blocksPerAxis_);
 
  243             return *BlockIter(beginIter,CoordToB(*
this));
 
  245         BlockIter blockBegin()
const{
 
  246             return BlockIter(MultiCoordIter(blocksPerAxis_),CoordToB(*
this));
 
  250         BlockIter blockEnd()
const{
 
  251             const MultiCoordIter beginIter(blocksPerAxis_);
 
  252             return BlockIter(beginIter.getEndIterator(),CoordToB(*
this));
 
  256         Block blockDescToBlock(
const BlockDesc & blockDesc)
const{
 
  257             MultiCoordIter iter(blocksPerAxis_);
 
  259             return *BlockIter(iter,CoordToB(*
this));
 
  265             return !insideVolBlock_.
contains(block);
 
  269         const Shape & roiBegin()
const{
 
  270             return roiBlock_.
begin();
 
  273         const Shape & roiEnd()
const{
 
  274             return roiBlock_.
end();
 
  277         const Shape & shape()
const{
 
  281         const Shape & blockShape()
const{
 
  285         const Shape & blocksPerAxis()
const{
 
  286             return blocksPerAxis_;
 
  289         const std::vector<Block> & volumeBorderBlocks()
const{
 
  290             return volumeBorderBlocks_;
 
  294         std::vector<UInt32> intersectingBlocks(
 
  295             const Shape roiBegin,
 
  299             std::vector<UInt32> iBlocks;
 
  300             const Block testBlock(roiBegin, roiEnd);
 
  301             for(BlockIter iter=blockBegin(); iter!=blockEnd(); ++iter){
 
  302                 if(testBlock.intersects(*iter)){
 
  303                     iBlocks.push_back(i);
 
  315         BlockWithBorder getBlockWithBorder(
const BlockDesc & blockDesc, 
const Shape & width )
const{
 
  316             const Point blockStart(blockDesc * blockShape_ + roiBlock_.
begin());
 
  317             const Point blockEnd(blockStart + blockShape_);
 
  318             const Block core = Block(blockStart, blockEnd) & roiBlock_ ;
 
  321             border &= Block(shape_);
 
  322             return BlockWithBorder( core, border );
 
  326         Block getBlock(
const BlockDesc & blockDesc)
const{
 
  327             const Point blockStart(blockDesc * blockShape_ + roiBlock_.
begin());
 
  328             const Point blockEnd(blockStart + blockShape_);
 
  329             return Block(blockStart, blockEnd) & roiBlock_;
 
  335         Shape blocksPerAxis_;   
 
  339         std::vector<Block> volumeBorderBlocks_;
 
  340         Block insideVolBlock_;
 
  345 #endif // VIGRA_MULTI_BLOCKING_HXX 
Vector size() const 
Definition: box.hxx:232
bool contains(Vector const &p) const 
Definition: box.hxx:314
size_t numBlocks() const 
total number of blocks 
Definition: multi_blocking.hxx:225
Vector const & end() const 
Definition: box.hxx:163
Definition: multi_blocking.hxx:49
Vector const & begin() const 
Definition: box.hxx:143
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal 
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal 
Definition: fftw3.hxx:825
void setEnd(Vector const &end)
Definition: box.hxx:190
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
bool containsVolumeBorder(const Block &block) const 
does this block intersect with the volume border 
Definition: multi_blocking.hxx:264
void setBegin(Vector const &begin)
Definition: box.hxx:182
void addBorder(VALUETYPE borderWidth)
Definition: box.hxx:260
Iterate over a virtual array where each element contains its coordinate. 
Definition: multi_fwd.hxx:157