[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libcvd-members] libcvd/cvd image.h
From: |
Edward Rosten |
Subject: |
[libcvd-members] libcvd/cvd image.h |
Date: |
Thu, 02 Jul 2009 10:56:59 +0000 |
CVSROOT: /cvsroot/libcvd
Module name: libcvd
Changes by: Edward Rosten <edrosten> 09/07/02 10:56:59
Modified files:
cvd : image.h
Log message:
Rewrote SubImageIterator to hold a runtime bool to determine if it
corresponds to .end(). This allows the compiler to eliminate a test,
and the
resulting iterator is much faster.
For the following 4 functions (summing up an image):
int sum1(const SubImage<byte>& i)
{
int s=0;
ImageRef p(0,0);
do
s+=i[p];
while(p.next(i.size()));
return s;
}
int sum2(const SubImage<byte>& i)
{
int s=0;
for(int r=0; r < i.size().y; r++)
for(int c=0; c < i.size().x; c++)
s+=i[r][c];
return s;
}
int sum3(const SubImage<byte>& i)
{
int s=0;
for(SubImage<byte>::const_iterator j=i.begin(); j != i.end();
j++)
s+=*j;
return s;
}
int sum4(const Image<byte>& i)
{
int s=0;
for(Image<byte>::const_iterator j=i.begin(); j != i.end(); j++)
s+=*j;
return s;
}
The relative timings are (on 100,000 128x128 images):
Old New
sum1 (ImageRef) 1.76961 1.78257
sum2 (double loop) 1.05468 1.04649
sum3 (SubImageIterator) 1.65211 1.06172
sum4 (byte*) 1 1
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/image.h?cvsroot=libcvd&r1=1.45&r2=1.46
Patches:
Index: image.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/image.h,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- image.h 15 Apr 2009 09:53:54 -0000 1.45
+++ image.h 2 Jul 2009 10:56:58 -0000 1.46
@@ -125,10 +125,7 @@
}
}
-template<class T> class SubImageIteratorEnd;
template<class T> class SubImage;
-template<class T> class ConstSubImageIteratorEnd;
-template<class T> class ConstSubImage;
template<class T> class ConstSubImageIterator
@@ -156,16 +153,36 @@
const T* operator->() const { return ptr; }
const T& operator*() const { return *ptr;}
- bool operator<(const ConstSubImageIterator& s) const { return
ptr < s.ptr; }
- bool operator==(const ConstSubImageIterator& s) const { return
ptr == s.ptr; }
- bool operator!=(const ConstSubImageIterator& s) const { return
ptr != s.ptr; }
+ bool operator<(const ConstSubImageIterator& s) const
+ {
+ //It's illegal to iterate _past_ end(), so < is
equivalent to !=
+ //for end iterators.
+ if(is_end && s.is_end)
+ return 0;
+ else if(is_end)
+ return s.end != NULL;
+ else if(s.is_end)
+ return end != NULL;
+ else
+ return ptr < s.ptr;
+ }
+ bool operator==(const ConstSubImageIterator& s) const
+ {
+ return !((*this)!=s);
+ }
- bool operator!=(const ConstSubImageIteratorEnd<T>&) const {
return end != NULL; }
- bool operator!=(const SubImageIteratorEnd<T>&) const { return
end != NULL; }
- //It's illegal to iterate _past_ end(), so < is equivalent to !=
- bool operator<(const ConstSubImageIteratorEnd<T>&) const {
return end != NULL; }
- bool operator<(const SubImageIteratorEnd<T>&) const { return
end != NULL; }
+ bool operator!=(const ConstSubImageIterator& s) const
+ {
+ if(is_end && s.is_end)
+ return 0;
+ else if(is_end)
+ return s.end != NULL;
+ else if(s.is_end)
+ return end != NULL;
+ else
+ return ptr != s.ptr;
+ }
//Make it look like a standard iterator
@@ -184,18 +201,21 @@
:ptr(const_cast<T*>(start)),
row_end(start + image_width),
end(off_end),
+ is_end(0),
row_increment(row_stride-image_width),
total_width(row_stride)
{ }
- ConstSubImageIterator(const T* end)
- :ptr(const_cast<T*>(end))
+ //Prevent automatic conversion from a pointer (ie
Image::iterator)
+ explicit ConstSubImageIterator(const T* end)
+
:ptr(const_cast<T*>(end)),is_end(1),row_increment(0),total_width(0)
{ }
protected:
T* ptr;
const T *row_end, *end;
- int row_increment, total_width;
+ const bool is_end;
+ const int row_increment, total_width;
};
template<class T> class SubImageIterator: public ConstSubImageIterator<T>
@@ -205,7 +225,7 @@
:ConstSubImageIterator<T>(start, image_width, row_stride,
off_end)
{}
- SubImageIterator(T* end)
+ explicit SubImageIterator(T* end)
:ConstSubImageIterator<T>(end)
{ }
@@ -219,38 +239,6 @@
T& operator*() { return *ConstSubImageIterator<T>::ptr;}
};
-template<class T> class SubImageIteratorEnd
-{
- public:
- SubImageIteratorEnd(SubImage<T>* p)
- :i(p){}
-
- operator SubImageIterator<T>()
- {
- return i->end();
- }
-
- private:
- SubImage<T>* i;
-};
-
-
-template<class T> class ConstSubImageIteratorEnd
-{
- public:
- ConstSubImageIteratorEnd(const SubImage<T>* p)
- :i(p){}
-
- operator ConstSubImageIterator<T>()
- {
- return i->end();
- }
-
- private:
- const SubImage<T>* i;
-};
-
-
/// A generic image class to manage a block of arbitrarily padded data as an
image. Provides
/// basic image access such as accessing a particular pixel co-ordinate.
/// @param T The pixel type for this image. Typically either
@@ -377,17 +365,6 @@
return ConstSubImageIterator<T>(end_ptr());
}
- /// Returns an object corresponding to end(), which should
eliminate a test.
- inline SubImageIteratorEnd<T> fastend()
- {
- return SubImageIteratorEnd<T>(this);
- }
- /// Returns an object corresponding to end() const, which
should eliminate a test.
- inline ConstSubImageIteratorEnd<T> fastend() const
- {
- return ConstSubImageIteratorEnd<T>(this);
- }
-
inline void copy_from( const SubImage<T> & other ){
CVD_IMAGE_ASSERT(other.size() == this->size(),
Exceptions::Image::IncompatibleImageSizes);
std::copy(other.begin(), other.end(), this->begin());
@@ -698,7 +675,6 @@
Image<T> tmp(copy.size());
*this = tmp;
- // FIXME: this is currently slow. Use fastend().
std::copy(copy.begin(), copy.end(), this->begin());
}
- [libcvd-members] libcvd/cvd image.h,
Edward Rosten <=