| 1 |
|
/*========================================================================= |
| 2 |
|
|
| 3 |
|
Program: Insight Segmentation & Registration Toolkit |
| 4 |
|
Module: $RCSfile: itkSize.h.html,v $ |
| 5 |
|
Language: C++ |
| 6 |
|
Date: $Date: 2006/01/17 19:15:48 $ |
| 7 |
|
Version: $Revision: 1.4 $ |
| 8 |
|
|
| 9 |
|
Copyright (c) Insight Software Consortium. All rights reserved. |
| 10 |
|
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. |
| 11 |
|
|
| 12 |
|
This software is distributed WITHOUT ANY WARRANTY; without even |
| 13 |
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 |
|
PURPOSE. See the above copyright notices for more information. |
| 15 |
|
|
| 16 |
|
=========================================================================*/ |
| 17 |
|
#ifndef __itkSize_h |
| 18 |
|
#define __itkSize_h |
| 19 |
|
|
| 20 |
|
#include "itkMacro.h" |
| 21 |
|
|
| 22 |
|
namespace itk |
| 23 |
|
{ |
| 24 |
|
|
| 25 |
|
/** \class Size |
| 26 |
|
* \brief Represent the size (bounds) of a n-dimensional image. |
| 27 |
|
* |
| 28 |
|
* Size is a class to represent multi-dimensional array bounds, |
| 29 |
|
* templated over the dimension. Insight assumes that the first |
| 30 |
|
* element of Size is the fastest moving index. |
| 31 |
|
* |
| 32 |
|
* For the sake of efficiency, Size does not define a default constructor, a |
| 33 |
|
* copy constructor, or an operator=. We rely on the compiler to provide |
| 34 |
|
* efficient bitwise copies. |
| 35 |
|
* |
| 36 |
|
* Size is an "aggregate" class. Its data is public (m_Size) |
| 37 |
|
* allowing for fast and convienent instantiations/assignments. |
| 38 |
|
* |
| 39 |
|
* The following syntax for assigning a size is allowed/suggested: |
| 40 |
|
* Size<3> size = {256, 256, 20}; |
| 41 |
|
* |
| 42 |
|
* \sa Index |
| 43 |
|
* \ingroup ImageObjects |
| 44 |
|
*/ |
| 45 |
|
template<unsigned int VDimension=2> |
| 46 |
|
class Size { |
| 47 |
|
public: |
| 48 |
|
/** Standard class typedefs. */ |
| 49 |
|
typedef Size Self; |
| 50 |
|
|
| 51 |
|
/** Compatible Size and value typedef */ |
| 52 |
|
typedef Size<VDimension> SizeType; |
| 53 |
TDA |
typedef unsigned long SizeValueType; |
| 54 |
|
|
| 55 |
|
/** Get the dimension of the size object. */ |
| 56 |
|
static unsigned int GetSizeDimension(void) { return VDimension; } |
| 57 |
|
|
| 58 |
|
/** Add two sizes. */ |
| 59 |
|
const Self |
| 60 |
|
operator+(const Self &vec) |
| 61 |
|
{ |
| 62 |
|
Self result; |
| 63 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 64 |
|
{ result[i] = m_Size[i] + vec.m_Size[i]; } |
| 65 |
|
return result; |
| 66 |
|
} |
| 67 |
|
|
| 68 |
|
/** Increment size by a size. */ |
| 69 |
|
const Self & |
| 70 |
|
operator+=(const Self &vec) |
| 71 |
|
{ |
| 72 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 73 |
|
{ m_Size[i] += vec.m_Size[i]; } |
| 74 |
|
return *this; |
| 75 |
|
} |
| 76 |
|
|
| 77 |
|
/** Subtract two sizes. */ |
| 78 |
|
const Self |
| 79 |
|
operator-(const Self &vec) |
| 80 |
|
{ |
| 81 |
|
Self result; |
| 82 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 83 |
|
{ result[i] = m_Size[i] - vec.m_Size[i]; } |
| 84 |
|
return result; |
| 85 |
|
} |
| 86 |
|
|
| 87 |
|
/** Decrement size by a size. */ |
| 88 |
|
const Self & |
| 89 |
|
operator-=(const Self &vec) |
| 90 |
|
{ |
| 91 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 92 |
|
{ m_Size[i] -= vec.m_Size[i]; } |
| 93 |
|
return *this; |
| 94 |
|
} |
| 95 |
|
|
| 96 |
|
/** Multiply two sizes (elementwise product). */ |
| 97 |
|
const Self |
| 98 |
|
operator*(const Self &vec) |
| 99 |
|
{ |
| 100 |
|
Self result; |
| 101 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 102 |
|
{ result[i] = m_Size[i] * vec.m_Size[i]; } |
| 103 |
|
return result; |
| 104 |
|
} |
| 105 |
|
|
| 106 |
|
/** Multiply two sizes (elementwise product). */ |
| 107 |
|
const Self & |
| 108 |
|
operator*=(const Self &vec) |
| 109 |
|
{ |
| 110 |
|
for (unsigned int i=0; i < VDimension; i++) |
| 111 |
|
{ m_Size[i] *= vec.m_Size[i]; } |
| 112 |
|
return *this; |
| 113 |
|
} |
| 114 |
|
|
| 115 |
|
/** Compare two sizes. */ |
| 116 |
|
bool |
| 117 |
|
operator==(const Self &vec) const |
| 118 |
|
{ |
| 119 |
|
bool same=1; |
| 120 |
|
for (unsigned int i=0; i < VDimension && same; i++) |
| 121 |
|
{ same = (m_Size[i] == vec.m_Size[i]); } |
| 122 |
|
return same; |
| 123 |
|
} |
| 124 |
|
|
| 125 |
|
/** Compare two sizes. */ |
| 126 |
|
bool |
| 127 |
|
operator!=(const Self &vec) const |
| 128 |
|
{ |
| 129 |
|
bool same=1; |
| 130 |
|
for (unsigned int i=0; i < VDimension && same; i++) |
| 131 |
|
{ same = (m_Size[i] == vec.m_Size[i]); } |
| 132 |
|
return !same; |
| 133 |
|
} |
| 134 |
|
|
| 135 |
|
/** Access an element of the size. Elements are numbered |
| 136 |
|
* 0, ..., VDimension-1. No bounds checking is performed. */ |
| 137 |
|
SizeValueType & operator[](unsigned int dim) |
| 138 |
|
{ return m_Size[dim]; } |
| 139 |
|
|
| 140 |
|
/** Access an element of the size. Elements are numbered |
| 141 |
|
* 0, ..., VDimension-1. This version can only be an rvalue. |
| 142 |
|
* No bounds checking is performed. */ |
| 143 |
|
SizeValueType operator[](unsigned int dim) const |
| 144 |
|
{ return m_Size[dim]; } |
| 145 |
|
|
| 146 |
|
/** Get the size. This provides a read only reference to the size. |
| 147 |
|
* \sa SetSize */ |
| 148 |
|
const SizeValueType *GetSize() const { return m_Size; }; |
| 149 |
|
|
| 150 |
|
/** Set the size. |
| 151 |
|
* Try to prototype this function so that val has to point to a block of |
| 152 |
|
* memory that is the appropriate size. \sa GetSize */ |
| 153 |
|
void SetSize(const SizeValueType val[VDimension]) |
| 154 |
|
{ memcpy(m_Size, val, sizeof(SizeValueType)*VDimension); } |
| 155 |
|
|
| 156 |
|
/** Set an element of the Size. |
| 157 |
|
* sets the value of one of the elements in the Size |
| 158 |
|
* This method is mainly intended to facilitate the access to elements |
| 159 |
|
* from Tcl and Python where C++ notation is not very convenient. |
| 160 |
|
* \warning No bound checking is performed. |
| 161 |
|
* \sa SetSize() \sa GetElement() */ |
| 162 |
|
void SetElement(unsigned long element, SizeValueType val ) |
| 163 |
|
{ m_Size[ element ] = val; } |
| 164 |
|
|
| 165 |
|
/** Get an element of the Size. |
| 166 |
|
* gets the value of one of the elements in the size |
| 167 |
|
* This method is mainly intended to facilitate the access to elements |
| 168 |
|
* from Tcl and Python where C++ notation is not very convenient. |
| 169 |
|
* \warning No bound checking is performed |
| 170 |
|
* \sa GetSize() \sa SetElement() */ |
| 171 |
|
SizeValueType GetElement( unsigned long element ) const |
| 172 |
|
{ return m_Size[ element ]; } |
| 173 |
|
|
| 174 |
|
/** Set one value for the index in all dimensions. Useful for initializing |
| 175 |
|
* an offset to zero. */ |
| 176 |
|
void Fill(SizeValueType value) |
| 177 |
|
{ for(unsigned int i=0;i < VDimension; ++i) m_Size[i] = value; } |
| 178 |
|
|
| 179 |
|
/** Size is an "aggregate" class. Its data is public (m_Size) |
| 180 |
|
* allowing for fast and convenient instantiations/assignments. |
| 181 |
|
* |
| 182 |
|
* The following syntax for assigning a size is allowed/suggested: |
| 183 |
|
* |
| 184 |
|
* Size<3> size = {{256, 256, 20}}; |
| 185 |
|
* |
| 186 |
|
* The doubled braces {{ and }} are required to prevent `gcc -Wall' |
| 187 |
|
* (and perhaps other compilers) from complaining about a partly |
| 188 |
|
* bracketed initializer. */ |
| 189 |
|
SizeValueType m_Size[VDimension]; |
| 190 |
|
|
| 191 |
|
}; |
| 192 |
|
|
| 193 |
|
|
| 194 |
|
template<unsigned int VDimension> |
| 195 |
|
std::ostream & operator<<(std::ostream &os, const Size<VDimension> &size) |
| 196 |
|
{ |
| 197 |
|
os << "["; |
| 198 |
|
for (unsigned int i=0; i+1 < VDimension; ++i) |
| 199 |
|
{ |
| 200 |
|
os << size[i] << ", "; |
| 201 |
|
} |
| 202 |
|
if (VDimension >= 1) |
| 203 |
|
{ |
| 204 |
|
os << size[VDimension-1]; |
| 205 |
|
} |
| 206 |
|
os << "]"; |
| 207 |
|
return os; |
| 208 |
|
} |
| 209 |
|
#ifdef ITK_EXPLICIT_INSTANTIATION |
| 210 |
|
extern template class Size<1>; |
| 211 |
IND |
***extern template class Size<2>; |
| 212 |
IND |
***extern template class Size<3>; |
| 213 |
IND |
***extern template class Size<4>; |
| 214 |
IND |
***extern template class Size<5>; |
| 215 |
LEN,IND |
***extern template std::ostream & operator<<(std::ostream &os, const Size<1> &size); |
| 216 |
LEN,IND |
***extern template std::ostream & operator<<(std::ostream &os, const Size<2> &size); |
| 217 |
LEN,IND |
***extern template std::ostream & operator<<(std::ostream &os, const Size<3> &size); |
| 218 |
LEN,IND |
***extern template std::ostream & operator<<(std::ostream &os, const Size<4> &size); |
| 219 |
LEN,IND |
***extern template std::ostream & operator<<(std::ostream &os, const Size<5> &size); |
| 220 |
|
#endif |
| 221 |
|
|
| 222 |
|
} // end namespace itk |
| 223 |
|
|
| 224 |
|
#endif |
| 225 |
|
|