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
00031 #define QVIMAGE_INIT_READ(TYPE, IMAGE) \
00032 const TYPE * __qv_data_##IMAGE##__ = IMAGE.getReadData(); \
00033 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep(); \
00034 const uChar __qv_size_##IMAGE##__ = sizeof(TYPE), \
00035 __qv_planes_##IMAGE##__ = IMAGE.getPlanes();
00036
00037 #define QVIMAGE_INIT_WRITE(TYPE, IMAGE) \
00038 TYPE * __qv_data_##IMAGE##__ = IMAGE.getWriteData(); \
00039 const uInt __qv_step_##IMAGE##__ = IMAGE.getStep(); \
00040 const uChar __qv_size_##IMAGE##__ = sizeof(TYPE), \
00041 __qv_planes_##IMAGE##__ = IMAGE.getPlanes();
00042
00043 #define QVIMAGE_PTR_INIT_READ(TYPE, IMAGE) \
00044 const TYPE * __qv_data_##IMAGE##__ = IMAGE->getReadData(); \
00045 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep(); \
00046 const uChar __qv_size_##IMAGE##__ = sizeof(TYPE), \
00047 __qv_planes_##IMAGE##__ = IMAGE->getPlanes();
00048
00049 #define QVIMAGE_PTR_INIT_WRITE(TYPE, IMAGE) \
00050 TYPE * __qv_data_##IMAGE##__ = IMAGE->getWriteData(); \
00051 const uInt __qv_step_##IMAGE##__ = IMAGE->getStep(); \
00052 const uChar __qv_size_##IMAGE##__ = sizeof(TYPE), \
00053 __qv_planes_##IMAGE##__ = IMAGE->getPlanes();
00054
00055 #define QVIMAGE_PIXEL(IMAGE, Col, Row, Channel) \
00056 (__qv_data_##IMAGE##__ [(Row)* __qv_step_##IMAGE##__ /__qv_size_##IMAGE##__ + __qv_planes_##IMAGE##__ *(Col)+(Channel)])
00057
00067 class QVGenericImage
00068 {
00069 public:
00073 QVGenericImage (): roi(0,0,0,0), anchor(QPoint(0,0)) { }
00074
00078 QVGenericImage(QVGenericImage const &img): roi(img.getROI()), anchor(img.getAnchor()) { }
00079
00081 virtual ~QVGenericImage () { };
00082
00086 virtual uInt getCols() const = 0;
00087
00091 virtual uInt getRows() const = 0;
00092
00101 virtual uInt getStep() const = 0;
00102
00109 virtual uInt getPlanes() const = 0;
00110
00117 virtual uInt getTypeSize() const = 0;
00118
00125 virtual uInt getDataSize() const = 0;
00126
00133 const QRect & getROI() const { return roi; }
00134
00141 const QPoint & getAnchor() const { return anchor; }
00142
00143
00152 void resetROI() { setROI(0,0,getCols(), getRows()); }
00153
00163 void erodeROI(uInt cols, uInt rows)
00164 { setROI(getROI().x()+cols, getROI().y()+rows, getROI().width()-2*cols, getROI().height()-2*rows); }
00165
00175 void dilateROI(uInt cols, uInt rows)
00176 { setROI(getROI().x()-cols, getROI().y()-rows, getROI().width()+2*cols, getROI().height()+2*rows); }
00177
00190 void setROI(int x, int y, uInt w, uInt h) { setROI(QRect(x,y,w,h)); }
00191
00195 void setMarginROI(int margin)
00196 { setROI(margin, margin, getCols() - 2*margin, getRows() -2*margin); }
00197
00201 void setROI(const QRect &rect)
00202 {
00203 Q_ASSERT_X(rect.x() >= 0,"QVGenericImage::setROI()","QRect.x() is less than zero");
00204 Q_ASSERT_X(rect.y() >= 0,"QVGenericImage::setROI()","QRect.y() is less than zero");
00205 Q_ASSERT_X(rect.width() > 0,"QVGenericImage::setROI()","QRect.width() is less or equal to zero");
00206 Q_ASSERT_X(rect.height() > 0,"QVGenericImage::setROI()","QRect.height() is less or equal to zero");
00207 Q_ASSERT_X(rect.x()+rect.width() <= (int) getCols(),"QVGenericImage::setROI()","x + width > columns");
00208 Q_ASSERT_X(rect.x()+rect.height() <= (int) getRows(),"QVGenericImage::setROI()","y + height > rows");
00209 roi = rect;
00210 }
00211
00212
00215 void resetAnchor() { setAnchor(0,0); }
00216
00221 void setAnchor(int col, int row) { setAnchor(QPoint(col,row)); }
00222
00226 void setAnchor(const QPoint &point)
00227 {
00228 Q_ASSERT_X(point.x()>=0,"QVGenericImage::setAnchor()","horizontal value for anchor is less than zero");
00229 Q_ASSERT_X(point.y()>=0,"QVGenericImage::setAnchor()","vertical value for anchor is less than zero");
00230 Q_ASSERT_X(point.x() < (int) getCols(),"QVGenericImage::setAnchor()","horizontal value exceeds cols");
00231 Q_ASSERT_X(point.y() < (int) getRows(),"QVGenericImage::setAnchor()","vertical value exceeds rows");
00232 anchor = point;
00233 }
00234
00239 virtual const char * getTypeQString() const = 0;
00240
00269 bool isCompatibleWith(const char *qvImageClassName) const
00270 {
00271 Q_ASSERT_X(qvImageClassName!= NULL,"QVGenericImage::isCompatibleWith()","class name string is NULL");
00272 return (0 == strcmp(this->getTypeQString(),qvImageClassName));
00273 }
00274
00285 bool isCompatibleWith(const QVGenericImage *image) const
00286 {
00287 Q_ASSERT_X(image!= NULL,"QVGenericImage::isCompatibleWith()","NULL pointer");
00288 return this->isCompatibleWith(image->getTypeQString());
00289 }
00290
00291 protected:
00292 QRect roi;
00293 QPoint anchor;
00294 };
00295
00302 template <typename Type, int Planes = 1> class QVImage: public QVGenericImage
00303 {
00304 public:
00310 QVImage():QVGenericImage()
00311 {
00312 this->imageBuffer = new QVImageBuffer<Type, Planes>(1, 1);
00313 setROI(0,0, this->imageBuffer->getCols(), this->imageBuffer->getRows());
00314 setAnchor(0,0);
00315 }
00316
00330 QVImage(uInt cols, uInt rows, uInt step = 0, const Type * buffer = NULL):QVGenericImage()
00331 {
00332 this->imageBuffer = new QVImageBuffer<Type, Planes>(cols, rows, step, buffer);
00333 setROI(0,0, cols, rows);
00334 setAnchor(0,0);
00335 }
00336
00353 QVImage(QVImage<uChar,1> const &img);
00354
00356 QVImage(QVImage<uChar,3> const &img);
00357
00359 QVImage(QVImage<sShort,1> const &img);
00360
00362 QVImage(QVImage<sShort,3> const &img);
00363
00365 QVImage(QVImage<sFloat,1> const &img);
00366
00368 QVImage(QVImage<sFloat,3> const &img);
00369
00371 const char * getTypeQString() const;
00372
00374 uInt getRows() const { return imageBuffer->getRows(); }
00375
00377 uInt getCols() const { return imageBuffer->getCols(); }
00378
00380 inline uInt getStep() const { return imageBuffer->getStep(); }
00381
00383 inline uInt getPlanes() const { return imageBuffer->getPlanes(); }
00384
00386 uInt getDataSize() const { return imageBuffer->getDataSize(); }
00387
00389 uInt getTypeSize() const { return imageBuffer->getTypeSize(); }
00390
00401 const Type * getReadData() const { return imageBuffer->getReadData(); }
00402
00413 Type * getWriteData() { return imageBuffer->getWriteData(); }
00414
00429 void set(Type c1 = 0, Type c2 = 0, Type c3 = 0);
00430
00439 inline Type &operator()(const uInt col, const uInt row, const uInt channel = 0)
00440 {
00441 Type * data = imageBuffer->getWriteData();
00442 uInt step = getStep();
00443
00444
00445 Q_ASSERT_X(col < getCols(),"QVImage::operator()","col further upper bound");
00446 Q_ASSERT_X(row < getRows(),"QVImage::operator()","row further upper bound");
00447 int idx = row*step/sizeof(Type) + Planes*col+channel;
00448 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00449 Q_ASSERT_X(idx < imageBuffer->getDataSize(),"QVImage::operator()","accessing above data");
00450 return data[idx];
00451 }
00452
00453 inline Type operator()(const uInt col, const uInt row, const uInt channel = 0) const
00454 {
00455 Type const * data = imageBuffer->getReadData();
00456 uInt cols = getCols(), rows = getRows();
00457 uInt step = getStep();
00458 int dataSize = getDataSize();
00459
00460 Q_ASSERT_X(col < cols,"QVImage::operator()","row out of upper bound");
00461 Q_ASSERT_X(row < rows,"QVImage::operator()","row out of upper bound");
00462 int idx = row*step/sizeof(Type) + Planes*col+channel;
00463 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00464 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00465 return data[idx];
00466 }
00467
00474 inline Type &operator()(const QPoint point, const uInt channel = 0)
00475 {
00476 Type * data = imageBuffer->getWriteData();
00477 uInt cols = getCols(), rows = getRows(), step = getStep();
00478 int dataSize = getDataSize();
00479
00480 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","col further upper bound");
00481 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row further upper bound");
00482 int idx = point.y()*step/sizeof(Type) + Planes*point.x()+channel;
00483 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00484 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00485 return data[idx];
00486 }
00487
00488 inline Type operator()(const QPoint point, const uInt channel = 0) const
00489 {
00490 Type const * data = imageBuffer->getReadData();
00491 uInt cols = getCols(), rows = getRows(), step = getStep();
00492 int dataSize = getDataSize();
00493
00494 Q_ASSERT_X(point.x() < (int) cols,"QVImage::operator()","row out of upper bound");
00495 Q_ASSERT_X(point.y() < (int) rows,"QVImage::operator()","row out of upper bound");
00496 int idx = point.y()*step/sizeof(Type) + Planes*point.x()+channel;
00497 Q_ASSERT_X(idx >= 0,"QVImage::operator()","accessing below data");
00498 Q_ASSERT_X(idx < dataSize,"QVImage::operator()","accessing above data");
00499 return data[idx];
00500 }
00501
00518 QVImage<Type, Planes> & operator=(const QVImage<uChar, 1> &sourceImage);
00519
00521 QVImage<Type, Planes> & operator=(const QVImage<uChar, 3> &sourceImage);
00522
00524 QVImage<Type, Planes> & operator=(const QVImage<sShort, 1> &sourceImage);
00525
00527 QVImage<Type, Planes> & operator=(const QVImage<sShort, 3> &sourceImage);
00528
00530 QVImage<Type, Planes> & operator=(const QVImage<sFloat, 1> &sourceImage);
00531
00533 QVImage<Type, Planes> & operator=(const QVImage<sFloat, 3> &sourceImage);
00534
00545 bool operator==(const QVImage<Type, Planes> &img) const;
00546
00561 bool operator!=(const QVImage<Type, Planes> &img) const { return !(*this == img); }
00562
00568 QVImage<uChar> operator<(const QVImage<Type, Planes> &img) const;
00569
00575 QVImage<uChar> operator>(const QVImage<Type, Planes> &img) const;
00576
00582 QVImage<uChar> operator<=(const QVImage<Type, Planes> &img) const;
00583
00589 QVImage<uChar> operator>=(const QVImage<Type, Planes> &img) const;
00590
00600 QVImage<Type, Planes> operator+(const Type constant) const;
00601
00611 QVImage<Type, Planes> operator*(const Type constant) const;
00612
00622 QVImage<Type, Planes> operator-(const Type constant) const;
00623
00633 QVImage<Type, Planes> operator/(const Type constant) const;
00634
00644 QVImage<Type, Planes> operator<<(const Type constant) const;
00645
00655 QVImage<Type, Planes> operator>>(const Type constant) const;
00656
00662 QVImage<Type, Planes> operator!() const;
00663
00670 QVImage<Type, Planes> operator&(const Type constant) const;
00671
00678 QVImage<Type, Planes> operator|(const Type constant) const;
00679
00686 QVImage<Type, Planes> operator^(const Type constant) const;
00687
00695 QVImage<Type, Planes> operator+(const QVImage<Type, Planes> &img) const;
00696
00704 QVImage<Type, Planes> operator*(const QVImage<Type, Planes> &img) const;
00705
00713 QVImage<Type, Planes> operator-(const QVImage<Type, Planes> &img) const;
00714
00722 QVImage<Type, Planes> operator/(const QVImage<Type, Planes> &img) const;
00723
00724 protected:
00725 QSharedDataPointer< QVImageBuffer<Type,Planes> > imageBuffer;
00726 };
00727
00728 template <typename Type, int C> bool QVImage<Type, C>::operator==(const QVImage<Type, C> &img) const
00729 {
00730 Q_ASSERT_X(img.getPlanes() == this->getPlanes(), "QVImage::operator==", "different number of planes");
00731 if (this->getCols() != img.getCols()) return false;
00732 if (this->getRows() != img.getRows()) return false;
00733 if (this->getPlanes() != img.getPlanes()) return false;
00734 if (this->getROI() != img.getROI()) return false;
00735 QVIMAGE_INIT_READ(Type,img);
00736 QVIMAGE_PTR_INIT_READ(Type,this);
00737
00738 uInt x0 = (uInt) img.getROI().x(), y0 = (uInt) img.getROI().y();
00739 uInt x1 = (uInt) img.getROI().width(), y1 = (uInt) img.getROI().height();
00740
00741 uInt lineSize = x1 * img.getPlanes();
00742 for(uInt row = y0; row < y1; row++)
00743 if (memcmp(&QVIMAGE_PIXEL(img, x0, row, 0),&QVIMAGE_PIXEL(this, x0, row, 0), lineSize) != 0)
00744 return false;
00745 return true;
00746 };
00747
00748
00749 typedef QVImage<uChar,1> QVImageUCharC1;
00750 typedef QVImage<uChar,3> QVImageUCharC3;
00751 typedef QVImage<sFloat,1> QVImageSFloatC1;
00752 typedef QVImage<sFloat,3> QVImageSFloatC3;
00753 typedef QVImage<sShort,1> QVImageSShortC1;
00754 typedef QVImage<sShort,3> QVImageSShortC3;
00755
00756
00757 Q_DECLARE_METATYPE(QVImageUCharC1);
00758 Q_DECLARE_METATYPE(QVImageUCharC3);
00759 Q_DECLARE_METATYPE(QVImageSFloatC1);
00760 Q_DECLARE_METATYPE(QVImageSFloatC3);
00761 Q_DECLARE_METATYPE(QVImageSShortC1);
00762 Q_DECLARE_METATYPE(QVImageSShortC3);
00763
00764 #endif // QVIMAGE_H