00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #ifndef QVIMAGE_H
00026 #define QVIMAGE_H
00027
00028 #include <QMetaType>
00029 #include <qvcore/qvimagebuffer.h>
00030
00038 #define QVIMAGE_INIT_READ(TYPE, IMAGE) \
00039 const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData(); \
00040 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00041 const uChar __qv_planes_##IMAGE##__ = IMAGE.getChannels();
00042
00050 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE) \
00051 TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData(); \
00052 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00053 const uChar __qv_planes_##IMAGE##__ = IMAGE.getChannels();
00054
00062 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE) \
00063 const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData(); \
00064 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00065 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels();
00066
00074 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE) \
00075 TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData(); \
00076 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00077 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels();
00078
00087 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00088 (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00089
00121 class QVGenericImage
00122 {
00123 public:
00127 QVGenericImage (): roi(0,0,0,0), anchor(QPoint(0,0)) { }
00128
00132 QVGenericImage(QVGenericImage const &img): roi(img.getROI()), anchor(img.getAnchor()) { }
00133
00135 virtual ~QVGenericImage () { };
00136
00140 virtual uInt getCols() const = 0;
00141
00145 virtual uInt getRows() const = 0;
00146
00155 virtual uInt getStep() const = 0;
00156
00163 virtual uInt getChannels() const = 0;
00164
00171 virtual uInt getTypeSize() const = 0;
00172
00179 virtual uInt getDataSize() const = 0;
00180
00187 const QRect & getROI() const { return roi; }
00188
00195 const QPoint & getAnchor() const { return anchor; }
00196
00197
00206 void resetROI() { setROI(0,0,getCols(), getRows()); }
00207
00217 void erodeROI(uInt cols, uInt rows)
00218 { setROI(getROI().x()+cols, getROI().y()+rows, getROI().width()-2*cols, getROI().height()-2*rows); }
00219
00229 void dilateROI(uInt cols, uInt rows)
00230 { setROI(getROI().x()-cols, getROI().y()-rows, getROI().width()+2*cols, getROI().height()+2*rows); }
00231
00244 void setROI(int x, int y, uInt w, uInt h) { setROI(QRect(x,y,w,h)); }
00245
00249 void setMarginROI(int margin)
00250 { setROI(margin, margin, getCols() - 2*margin, getRows() -2*margin); }
00251
00255 void setROI(const QRect &rect)
00256 {
00257 Q_ASSERT_X(rect.x() >= 0,"QVGenericImage::setROI()","QRect.x() is less than zero");
00258 Q_ASSERT_X(rect.y() >= 0,"QVGenericImage::setROI()","QRect.y() is less than zero");
00259 Q_ASSERT_X(rect.width() > 0,"QVGenericImage::setROI()","QRect.width() is less or equal to zero");
00260 Q_ASSERT_X(rect.height() > 0,"QVGenericImage::setROI()","QRect.height() is less or equal to zero");
00261 Q_ASSERT_X(rect.x()+rect.width() <= (int) getCols(),"QVGenericImage::setROI()","x + width > columns");
00262 Q_ASSERT_X(rect.x()+rect.height() <= (int) getRows(),"QVGenericImage::setROI()","y + height > rows");
00263 roi = rect;
00264 }
00265
00266
00269 void resetAnchor() { setAnchor(0,0); }
00270
00275 void setAnchor(int col, int row) { setAnchor(QPoint(col,row)); }
00276
00280 void setAnchor(const QPoint &point)
00281 {
00282 Q_ASSERT_X(point.x()>=0,"QVGenericImage::setAnchor()","horizontal value for anchor is less than zero");
00283 Q_ASSERT_X(point.y()>=0,"QVGenericImage::setAnchor()","vertical value for anchor is less than zero");
00284 Q_ASSERT_X(point.x() < (int) getCols(),"QVGenericImage::setAnchor()","horizontal value exceeds cols");
00285 Q_ASSERT_X(point.y() < (int) getRows(),"QVGenericImage::setAnchor()","vertical value exceeds rows");
00286 anchor = point;
00287 }
00288
00293 virtual const char * getTypeQString() const = 0;
00294
00323 bool isCompatibleWith(const char *qvImageClassName) const
00324 {
00325 Q_ASSERT_X(qvImageClassName!= NULL,"QVGenericImage::isCompatibleWith()","class name string is NULL");
00326 return (0 == strcmp(this->getTypeQString(),qvImageClassName));
00327 }
00328
00339 bool isCompatibleWith(const QVGenericImage *image) const
00340 {
00341 Q_ASSERT_X(image!= NULL,"QVGenericImage::isCompatibleWith()","NULL pointer");
00342 return this->isCompatibleWith(image->getTypeQString());
00343 }
00344
00345 protected:
00346 QRect roi;
00347 QPoint anchor;
00348 };
00349
00614 template <typename Type, int Channels = 1> class QVImage: public QVGenericImage
00615 {
00616 public:
00622 QVImage():QVGenericImage()
00623 {
00624 this->imageBuffer = new QVImageBuffer<Type, Channels>(1, 1);
00625 setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00626 setAnchor(0,0);
00627 }
00628
00665 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00666 {
00667 this->imageBuffer = new QVImageBuffer<Type, Channels>(cols, rows, step, buffer);
00668 setROI(0,0, cols, rows);
00669 setAnchor(0,0);
00670 }
00671
00688 QVImage(QVImage<uChar,1> const &img);
00689
00691 QVImage(QVImage<uChar,3> const &img);
00692
00694 QVImage(QVImage<sShort,1> const &img);
00695
00697 QVImage(QVImage<sShort,3> const &img);
00698
00700 QVImage(QVImage<sFloat,1> const &img);
00701
00703 QVImage(QVImage<sFloat,3> const &img);
00704
00706 const char * getTypeQString() const;
00707
00709 uInt getRows() const { return imageBuffer->getRows(); }
00710
00712 uInt getCols() const { return imageBuffer->getCols(); }
00713
00715 inline uInt getStep() const { return imageBuffer->getStep(); }
00716
00718 inline uInt getChannels() const { return imageBuffer->getChannels(); }
00719
00721 uInt getDataSize() const { return imageBuffer->getDataSize(); }
00722
00724 uInt getTypeSize() const { return imageBuffer->getTypeSize(); }
00725
00736 const Type * getReadData() const { return imageBuffer->getReadData(); }
00737
00748 Type * getWriteData() { return imageBuffer->getWriteData(); }
00749
00764 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00765
00774 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00775 {
00776 Type * data = imageBuffer->getWriteData();
00777 uInt step = getStep();
00778
00779 Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00780 Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00781 int idx = row*step/sizeof(Type) + Channels*col+channel;
00782 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00783 Q_ASSERT_X(idx < imageBuffer->getDataSize(),"QVImage::operator()","accessing above data");
00784 return data[idx];
00785 }
00786
00787 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00788 {
00789 Type const * data = imageBuffer->getReadData();
00790 uInt cols = getCols(), rows = getRows();
00791 uInt step = getStep();
00792 int dataSize = getDataSize();
00793
00794 Q_ASSERT_X(col < cols,"QVImage::operator()","row out of upper bound");
00795 Q_ASSERT_X(row < rows,"QVImage::operator()","row out of upper bound");
00796 int idx = row*step/sizeof(Type) + Channels*col+channel;
00797 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00798 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00799 return data[idx];
00800 }
00801
00808 inline Type &operator()(const QPoint point, const uInt channel = 0)
00809 {
00810 Type * data = imageBuffer->getWriteData();
00811 uInt cols = getCols(), rows = getRows(), step = getStep();
00812 int dataSize = getDataSize();
00813
00814 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","col further upper bound");
00815 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row further upper bound");
00816 int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00817 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00818 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00819 return data[idx];
00820 }
00821
00822 inline Type operator()(const QPoint point, const uInt channel = 0) const
00823 {
00824 Type const * data = imageBuffer->getReadData();
00825 uInt cols = getCols(), rows = getRows(), step = getStep();
00826 int dataSize = getDataSize();
00827
00828 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","row out of upper bound");
00829 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row out of upper bound");
00830 int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00831 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00832 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00833 return data[idx];
00834 }
00835
00852 QVImage<Type, Channels> & operator=(const QVImage<uChar, 1> &sourceImage);
00853
00855 QVImage<Type, Channels> & operator=(const QVImage<uChar, 3> &sourceImage);
00856
00858 QVImage<Type, Channels> & operator=(const QVImage<sShort, 1> &sourceImage);
00859
00861 QVImage<Type, Channels> & operator=(const QVImage<sShort, 3> &sourceImage);
00862
00864 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 1> &sourceImage);
00865
00867 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 3> &sourceImage);
00868
00879 bool operator==(const QVImage<Type, Channels> &img) const;
00880
00894 bool operator!=(const QVImage<Type, Channels> &img) const { return !(*this == img); }
00895
00901 QVImage<uChar> operator<(const QVImage<Type, Channels> &img) const;
00902
00908 QVImage<uChar> operator>(const QVImage<Type, Channels> &img) const;
00909
00915 QVImage<uChar> operator<=(const QVImage<Type, Channels> &img) const;
00916
00922 QVImage<uChar> operator>=(const QVImage<Type, Channels> &img) const;
00923
00933 QVImage<Type, Channels> operator+(const Type constant) const;
00934
00944 QVImage<Type, Channels> operator*(const Type constant) const;
00945
00955 QVImage<Type, Channels> operator-(const Type constant) const;
00956
00966 QVImage<Type, Channels> operator/(const Type constant) const;
00967
00977 QVImage<Type, Channels> operator<<(const Type constant) const;
00978
00988 QVImage<Type, Channels> operator>>(const Type constant) const;
00989
00995 QVImage<Type, Channels> operator!() const;
00996
01003 QVImage<Type, Channels> operator&(const Type constant) const;
01004
01011 QVImage<Type, Channels> operator|(const Type constant) const;
01012
01019 QVImage<Type, Channels> operator^(const Type constant) const;
01020
01028 QVImage<Type, Channels> operator+(const QVImage<Type, Channels> &img) const;
01029
01037 QVImage<Type, Channels> operator*(const QVImage<Type, Channels> &img) const;
01038
01046 QVImage<Type, Channels> operator-(const QVImage<Type, Channels> &img) const;
01047
01055 QVImage<Type, Channels> operator/(const QVImage<Type, Channels> &img) const;
01056
01057 protected:
01058 QSharedDataPointer< QVImageBuffer<Type,Channels> > imageBuffer;
01059 };
01060
01061 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
01062 {
01063 Q_ASSERT_X(img.getChannels() == this->getChannels(), "QVImage::operator==", "different number of planes");
01064 if (this->getCols() != img.getCols()) return false;
01065 if (this->getRows() != img.getRows()) return false;
01066 if (this->getChannels() != img.getChannels()) return false;
01067 if (this->getROI() != img.getROI()) return false;
01068 QVIMAGE_INIT_READ(Type,img);
01069 QVIMAGE_PTR_INIT_READ(Type,this);
01070
01071 uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y();
01072 uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height();
01073
01074 uInt lineSize = x1 * img.getChannels();
01075 for(uInt row = y0; row < y1; row++)
01076 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
01077 return false;
01078 return true;
01079 };
01080
01081
01082 typedef QVImage<uChar,1> QVImageUCharC1;
01083 typedef QVImage<uChar,3> QVImageUCharC3;
01084 typedef QVImage<sFloat,1> QVImageSFloatC1;
01085 typedef QVImage<sFloat,3> QVImageSFloatC3;
01086 typedef QVImage<sShort,1> QVImageSShortC1;
01087 typedef QVImage<sShort,3> QVImageSShortC3;
01088
01089
01090 Q_DECLARE_METATYPE(QVImageUCharC1);
01091 Q_DECLARE_METATYPE(QVImageUCharC3);
01092 Q_DECLARE_METATYPE(QVImageSFloatC1);
01093 Q_DECLARE_METATYPE(QVImageSFloatC3);
01094 Q_DECLARE_METATYPE(QVImageSShortC1);
01095 Q_DECLARE_METATYPE(QVImageSShortC3);
01096
01097 #endif // QVIMAGE_H