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
00040 #define QVIMAGE_INIT_READ(TYPE, IMAGE) \
00041 const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData(); \
00042 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00043 const uChar __qv_planes_##IMAGE##__ = IMAGE.getChannels(); \
00044 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols();
00045
00055 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE) \
00056 TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData(); \
00057 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep()/sizeof(TYPE); \
00058 const uChar __qv_planes_##IMAGE##__ = IMAGE.getChannels(); \
00059 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE.getCols();
00060
00070 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE) \
00071 const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData(); \
00072 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE); \
00073 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels(); \
00074 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE->getCols();
00075
00085 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE) \
00086 TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData(); \
00087 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep()/sizeof(TYPE); \
00088 const uChar __qv_planes_##IMAGE##__ = IMAGE->getChannels(); \
00089 const uInt __qv_next_line_inc_##IMAGE##__ = __qv_step_##IMAGE##__ - IMAGE->getCols();
00090
00100 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00101 (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00102
00112 #define QVIMAGE_PIXEL_PTR(IMAGE, Col, Row, Channel) \
00113 (& (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)]))
00114
00121 #define QVIMAGE_ROW_INCREMENT_PTR(IMAGE) ( __qv_step_##IMAGE##__ )
00122
00129 #define QVIMAGE_COL_INCREMENT_PTR(IMAGE) ( __qv_planes_##IMAGE##__ )
00130
00137 #define QVIMAGE_NEXT_LINE_INCREMENT_PTR(IMAGE) ( __qv_next_line_inc_##IMAGE##__ )
00138
00171 class QVGenericImage
00172 {
00173 public:
00177 QVGenericImage (): roi(0,0,0,0), anchor(QPoint(0,0)) { }
00178
00182 QVGenericImage(QVGenericImage const &img): roi(img.getROI()), anchor(img.getAnchor()) { }
00183
00185 virtual ~QVGenericImage () { };
00186
00190 virtual uInt getCols() const = 0;
00191
00195 virtual uInt getRows() const = 0;
00196
00205 virtual uInt getStep() const = 0;
00206
00213 virtual uInt getChannels() const = 0;
00214
00221 virtual uInt getTypeSize() const = 0;
00222
00229 virtual uInt getDataSize() const = 0;
00230
00237 const QRect & getROI() const { return roi; }
00238
00245 const QPoint & getAnchor() const { return anchor; }
00246
00247
00256 void resetROI() { setROI(0,0,getCols(), getRows()); }
00257
00267 void erodeROI(uInt cols, uInt rows)
00268 { setROI(getROI().x()+cols, getROI().y()+rows, getROI().width()-2*cols, getROI().height()-2*rows); }
00269
00279 void dilateROI(uInt cols, uInt rows)
00280 { setROI(getROI().x()-cols, getROI().y()-rows, getROI().width()+2*cols, getROI().height()+2*rows); }
00281
00294 void setROI(int x, int y, uInt w, uInt h) { setROI(QRect(x,y,w,h)); }
00295
00299 void setMarginROI(int margin)
00300 { setROI(margin, margin, getCols() - 2*margin, getRows() -2*margin); }
00301
00305 void setROI(const QRect &rect)
00306 {
00307 Q_ASSERT_X(rect.x() >= 0,"QVGenericImage::setROI()","QRect.x() is less than zero");
00308 Q_ASSERT_X(rect.y() >= 0,"QVGenericImage::setROI()","QRect.y() is less than zero");
00309 Q_ASSERT_X(rect.width() > 0,"QVGenericImage::setROI()","QRect.width() is less or equal to zero");
00310 Q_ASSERT_X(rect.height() > 0,"QVGenericImage::setROI()","QRect.height() is less or equal to zero");
00311 Q_ASSERT_X(rect.x()+rect.width() <= (int) getCols(),"QVGenericImage::setROI()","x + width > columns");
00312 Q_ASSERT_X(rect.y()+rect.height() <= (int) getRows(),"QVGenericImage::setROI()","y + height > rows");
00313 roi = rect;
00314 }
00315
00316
00319 void resetAnchor() { setAnchor(0,0); }
00320
00325 void setAnchor(int col, int row) { setAnchor(QPoint(col,row)); }
00326
00330 void setAnchor(const QPoint &point)
00331 {
00332 Q_ASSERT_X(point.x()>=0,"QVGenericImage::setAnchor()","horizontal value for anchor is less than zero");
00333 Q_ASSERT_X(point.y()>=0,"QVGenericImage::setAnchor()","vertical value for anchor is less than zero");
00334 Q_ASSERT_X(point.x() < (int) getCols(),"QVGenericImage::setAnchor()","horizontal value exceeds cols");
00335 Q_ASSERT_X(point.y() < (int) getRows(),"QVGenericImage::setAnchor()","vertical value exceeds rows");
00336 anchor = point;
00337 }
00338
00343 virtual const char * getTypeQString() const = 0;
00344
00373 bool isCompatibleWith(const char *qvImageClassName) const
00374 {
00375 Q_ASSERT_X(qvImageClassName!= NULL,"QVGenericImage::isCompatibleWith()","class name string is NULL");
00376 return (0 == strcmp(this->getTypeQString(),qvImageClassName));
00377 }
00378
00389 bool isCompatibleWith(const QVGenericImage *image) const
00390 {
00391 Q_ASSERT_X(image!= NULL,"QVGenericImage::isCompatibleWith()","NULL pointer");
00392 return this->isCompatibleWith(image->getTypeQString());
00393 }
00394
00395 protected:
00396 QRect roi;
00397 QPoint anchor;
00398 };
00399
00604 template <typename Type, int Channels = 1> class QVImage: public QVGenericImage
00605 {
00606 public:
00612 QVImage():QVGenericImage()
00613 {
00614 this->imageBuffer = new QVImageBuffer<Type, Channels>(1, 1);
00615 setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00616 setAnchor(0,0);
00617 }
00618
00655 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00656 {
00657 this->imageBuffer = new QVImageBuffer<Type, Channels>(cols, rows, step, buffer);
00658 setROI(0,0, cols, rows);
00659 setAnchor(0,0);
00660 }
00661
00678 QVImage(QVImage<uChar,1> const &img);
00679
00681 QVImage(QVImage<uChar,3> const &img);
00682
00684 QVImage(QVImage<uShort,1> const &img);
00685
00687 QVImage(QVImage<uShort,3> const &img);
00688
00690 QVImage(QVImage<sShort,1> const &img);
00691
00693 QVImage(QVImage<sShort,3> const &img);
00694
00696 QVImage(QVImage<sInt,1> const &img);
00697
00699 QVImage(QVImage<sInt,3> const &img);
00700
00702 QVImage(QVImage<sFloat,1> const &img);
00703
00705 QVImage(QVImage<sFloat,3> const &img);
00706
00716 QVImage(QVImage<uChar,1> const &red, QVImage<uChar,1> const &green, QVImage<uChar,1> const &blue);
00717
00719 QVImage(QVImage<uShort,1> const &red, QVImage<uShort,1> const &green, QVImage<uShort,1> const &blue);
00720
00722 QVImage(QVImage<sShort,1> const &red, QVImage<sShort,1> const &green, QVImage<sShort,1> const &blue);
00723
00725 QVImage(QVImage<sInt,1> const &red, QVImage<sInt,1> const &green, QVImage<sInt,1> const &blue);
00726
00728 QVImage(QVImage<sFloat,1> const &red, QVImage<sFloat,1> const &green, QVImage<sFloat,1> const &blue);
00729
00730
00732 const char * getTypeQString() const;
00733
00735 uInt getRows() const { return imageBuffer->getRows(); }
00736
00738 uInt getCols() const { return imageBuffer->getCols(); }
00739
00741 inline uInt getStep() const { return imageBuffer->getStep(); }
00742
00744 inline uInt getChannels() const { return imageBuffer->getChannels(); }
00745
00747 uInt getDataSize() const { return imageBuffer->getDataSize(); }
00748
00750 uInt getTypeSize() const { return imageBuffer->getTypeSize(); }
00751
00762 const Type * getReadData() const { return imageBuffer->getReadData(); }
00763
00774 Type * getWriteData() { return imageBuffer->getWriteData(); }
00775
00790 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00791
00800 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00801 {
00802 Type * data = imageBuffer->getWriteData();
00803 uInt step = getStep();
00804
00805 Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00806 Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00807 int idx = row*step/sizeof(Type) + Channels*col+channel;
00808 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00809 Q_ASSERT_X(idx < imageBuffer->getDataSize(),"QVImage::operator()","accessing above data");
00810 return data[idx];
00811 }
00812
00813 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00814 {
00815 Type const * data = imageBuffer->getReadData();
00816 uInt cols = getCols(), rows = getRows();
00817 uInt step = getStep();
00818 int dataSize = getDataSize();
00819
00820 Q_ASSERT_X(col < cols,"QVImage::operator()","row out of upper bound");
00821 Q_ASSERT_X(row < rows,"QVImage::operator()","row out of upper bound");
00822 int idx = row*step/sizeof(Type) + Channels*col+channel;
00823 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00824 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00825 return data[idx];
00826 }
00827
00834 inline Type &operator()(const QPoint point, const uInt channel = 0)
00835 {
00836 Type * data = imageBuffer->getWriteData();
00837 uInt cols = getCols(), rows = getRows(), step = getStep();
00838 int dataSize = getDataSize();
00839
00840 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","col further upper bound");
00841 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row further upper bound");
00842 int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00843 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00844 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00845 return data[idx];
00846 }
00847
00848 inline Type operator()(const QPoint point, const uInt channel = 0) const
00849 {
00850 Type const * data = imageBuffer->getReadData();
00851 uInt cols = getCols(), rows = getRows(), step = getStep();
00852 int dataSize = getDataSize();
00853
00854 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","row out of upper bound");
00855 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row out of upper bound");
00856 int idx = point.y()*step/sizeof(Type) + Channels*point.x()+channel;
00857 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00858 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00859 return data[idx];
00860 }
00861
00870 QVImage<Type, 1> operator()(const uInt channel = 0) const;
00871
00888 QVImage<Type, Channels> & operator=(const QVImage<uChar, 1> &sourceImage);
00889
00891 QVImage<Type, Channels> & operator=(const QVImage<uChar, 3> &sourceImage);
00892
00894 QVImage<Type, Channels> & operator=(const QVImage<uShort, 1> &sourceImage);
00895
00897 QVImage<Type, Channels> & operator=(const QVImage<uShort, 3> &sourceImage);
00898
00900 QVImage<Type, Channels> & operator=(const QVImage<sShort, 1> &sourceImage);
00901
00903 QVImage<Type, Channels> & operator=(const QVImage<sShort, 3> &sourceImage);
00904
00906 QVImage<Type, Channels> & operator=(const QVImage<sInt, 1> &sourceImage);
00907
00909 QVImage<Type, Channels> & operator=(const QVImage<sInt, 3> &sourceImage);
00910
00912 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 1> &sourceImage);
00913
00915 QVImage<Type, Channels> & operator=(const QVImage<sFloat, 3> &sourceImage);
00916
00927 bool operator==(const QVImage<Type, Channels> &img) const;
00928
00942 bool operator!=(const QVImage<Type, Channels> &img) const { return !(*this == img); }
00943
00949 QVImage<uChar, 1> operator<(const QVImage<uChar, Channels> &img) const;
00950
00956 QVImage<uChar, 1> operator<(const QVImage<uShort, Channels> &img) const;
00957
00963 QVImage<uChar, 1> operator<(const QVImage<sShort, Channels> &img) const;
00964
00970 QVImage<uChar, 1> operator<(const QVImage<sInt, Channels> &img) const;
00971
00977 QVImage<uChar, 1> operator<(const QVImage<sFloat, Channels> &img) const;
00978
00984 QVImage<uChar, 1> operator>(const QVImage<uChar, Channels> &img) const;
00985
00991 QVImage<uChar, 1> operator>(const QVImage<uShort, Channels> &img) const;
00992
00998 QVImage<uChar, 1> operator>(const QVImage<sShort, Channels> &img) const;
00999
01005 QVImage<uChar, 1> operator>(const QVImage<sInt, Channels> &img) const;
01006
01012 QVImage<uChar, 1> operator>(const QVImage<sFloat, Channels> &img) const;
01013
01019 QVImage<uChar, 1> operator<=(const QVImage<uChar, Channels> &img) const;
01020
01026 QVImage<uChar, 1> operator<=(const QVImage<uShort, Channels> &img) const;
01027
01033 QVImage<uChar, 1> operator<=(const QVImage<sShort, Channels> &img) const;
01034
01040 QVImage<uChar, 1> operator<=(const QVImage<sInt, Channels> &img) const;
01041
01047 QVImage<uChar, 1> operator<=(const QVImage<sFloat, Channels> &img) const;
01048
01054 QVImage<uChar, 1> operator>=(const QVImage<uChar, Channels> &img) const;
01055
01061 QVImage<uChar, 1> operator>=(const QVImage<uShort, Channels> &img) const;
01062
01068 QVImage<uChar, 1> operator>=(const QVImage<sShort, Channels> &img) const;
01069
01075 QVImage<uChar, 1> operator>=(const QVImage<sInt, Channels> &img) const;
01076
01082 QVImage<uChar, 1> operator>=(const QVImage<sFloat, Channels> &img) const;
01083
01093 QVImage<Type, Channels> operator+(const Type constant) const;
01094
01104 QVImage<Type, Channels> operator*(const Type constant) const;
01105
01115 QVImage<Type, Channels> operator-(const Type constant) const;
01116
01126 QVImage<Type, Channels> operator/(const Type constant) const;
01127
01137 QVImage<Type, Channels> operator<<(const Type constant) const;
01138
01148 QVImage<Type, Channels> operator>>(const Type constant) const;
01149
01155 QVImage<Type, Channels> operator!() const;
01156
01163 QVImage<Type, Channels> operator&(const Type constant) const;
01164
01171 QVImage<Type, Channels> operator|(const Type constant) const;
01172
01179 QVImage<Type, Channels> operator^(const Type constant) const;
01180
01188 QVImage<Type, Channels> operator+(const QVImage<Type, Channels> &img) const;
01189
01197 QVImage<Type, Channels> operator*(const QVImage<Type, Channels> &img) const;
01198
01206 QVImage<Type, Channels> operator-(const QVImage<Type, Channels> &img) const;
01207
01215 QVImage<Type, Channels> operator/(const QVImage<Type, Channels> &img) const;
01216
01217 protected:
01218 QSharedDataPointer< QVImageBuffer<Type,Channels> > imageBuffer;
01219 };
01220
01221 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
01222 {
01223 Q_ASSERT_X(img.getChannels() == this->getChannels(), "QVImage::operator==", "different number of planes");
01224 if (this->getCols() != img.getCols()) return false;
01225 if (this->getRows() != img.getRows()) return false;
01226 if (this->getChannels() != img.getChannels()) return false;
01227 if (this->getROI() != img.getROI()) return false;
01228 QVIMAGE_INIT_READ(Type,img);
01229 QVIMAGE_PTR_INIT_READ(Type,this);
01230
01231 uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y();
01232 uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height();
01233
01234 uInt lineSize = x1 * img.getChannels();
01235 for(uInt row = y0; row < y1; row++)
01236 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
01237 return false;
01238 return true;
01239 };
01240
01241
01242 typedef QVImage<uChar,1> QVImageUCharC1;
01243 typedef QVImage<uChar,3> QVImageUCharC3;
01244 typedef QVImage<uShort,1> QVImageUShortC1;
01245 typedef QVImage<uShort,3> QVImageUShortC3;
01246 typedef QVImage<sShort,1> QVImageSShortC1;
01247 typedef QVImage<sShort,3> QVImageSShortC3;
01248 typedef QVImage<sInt,1> QVImageSIntC1;
01249 typedef QVImage<sInt,3> QVImageSIntC3;
01250 typedef QVImage<sFloat,1> QVImageSFloatC1;
01251 typedef QVImage<sFloat,3> QVImageSFloatC3;
01252
01253 Q_DECLARE_METATYPE(QVImageUCharC1);
01254 Q_DECLARE_METATYPE(QVImageUCharC3);
01255 Q_DECLARE_METATYPE(QVImageUShortC1);
01256 Q_DECLARE_METATYPE(QVImageUShortC3);
01257 Q_DECLARE_METATYPE(QVImageSShortC1);
01258 Q_DECLARE_METATYPE(QVImageSShortC3);
01259 Q_DECLARE_METATYPE(QVImageSIntC1);
01260 Q_DECLARE_METATYPE(QVImageSIntC3);
01261 Q_DECLARE_METATYPE(QVImageSFloatC1);
01262 Q_DECLARE_METATYPE(QVImageSFloatC3);
01263
01264 #endif // QVIMAGE_H