Skip to content
Snippets Groups Projects
Commit 571d610f authored by Sacha Percot-Tétu's avatar Sacha Percot-Tétu
Browse files

Improved the point op to handle double image

parent 44350450
No related branches found
No related tags found
No related merge requests found
...@@ -32,11 +32,14 @@ ...@@ -32,11 +32,14 @@
#include "PointOp.h" #include "PointOp.h"
#include "ImgWidget.h" #include "ImgWidget.h"
#include "ImageListBox.h" #include "ImageListBox.h"
#include "Widgets/ImageWidgets/StandardImageWindow.h"
#include "Widgets/ImageWidgets/DoubleImageWindow.h"
#include "../Tools.h" #include "../Tools.h"
using namespace std; using namespace std;
using namespace imagein; using namespace imagein;
using namespace genericinterface;
PointOp::PointOp() : Operation("Pixel operations") { PointOp::PointOp() : Operation("Pixel operations") {
...@@ -56,6 +59,15 @@ PointOp::PixelOp* PointOp::PixelOp::fromString(QString op, QString expr) { ...@@ -56,6 +59,15 @@ PointOp::PixelOp* PointOp::PixelOp::fromString(QString op, QString expr) {
std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
return new PixIdent(); return new PixIdent();
} }
PointOp::DoublePixelOp* PointOp::DoublePixelOp::fromString(QString op, QString expr) {
if(op=="+") return new DoublePixAdd(expr.toDouble());
if(op=="-") return new DoublePixAdd(-expr.toDouble());
if(op=="*") return new DoublePixMul(expr.toDouble());
if(op=="/") return new DoublePixMul(1/expr.toDouble());
if(op=="") return new DoublePixIdent();
std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
return new DoublePixIdent();
}
PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) { PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) {
if(op=="+") return new ImgAdd(); if(op=="+") return new ImgAdd();
...@@ -67,13 +79,36 @@ PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) { ...@@ -67,13 +79,36 @@ PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) {
std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
return new ImgIdent(); return new ImgIdent();
} }
PointOp::DoubleImageOp* PointOp::DoubleImageOp::fromString(QString op) {
if(op=="+") return new DoubleImgAdd();
if(op=="-") return new DoubleImgSub();
if(op=="*") return new DoubleImgMul();
if(op=="/") return new DoubleImgDiv();
if(op=="") return new DoubleImgIdent();
std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
return new DoubleImgIdent();
}
void PointOp::operator()(const imagein::Image* image, const std::map<const imagein::Image*, std::string>& imgList) { void PointOp::operator()(const ImageWindow* currentWnd, vector<ImageWindow*>& wndList) {
QStringList pixOperators, imgOperators; QStringList pixOperators, imgOperators;
pixOperators << "" << "+" << "-" << "*" << "/" << "&" << "|" << "^" << "<<" << ">>"; pixOperators << "" << "+" << "-" << "*" << "/" << "&" << "|" << "^" << "<<" << ">>";
imgOperators << "" << "+" << "-" << "&" << "|" << "^"; imgOperators << "" << "+" << "-" << "*" << "/" << "&" << "|" << "^";
QString currentImgName = QString(imgList.find(image)->second.c_str()); QString currentImgName = currentWnd->windowTitle();
map<const Image*,string> stdImgList;
map<const Image_t<double>*,string> dblImgList;
for(vector<ImageWindow*>::iterator it = wndList.begin(); it != wndList.end(); ++it) {
if((*it)->isStandard()) {
const StandardImageWindow* stdImgWnd = dynamic_cast<const StandardImageWindow*>(*it);
stdImgList.insert(pair<const Image*, string>(stdImgWnd->getImage(), stdImgWnd->windowTitle().toStdString()));
}
else if((*it)->isDouble()) {
const DoubleImageWindow* dblImgWnd = dynamic_cast<const DoubleImageWindow*>(*it);
dblImgList.insert(pair<const Image_t<double>*, string>(dblImgWnd->getImage(), dblImgWnd->windowTitle().toStdString()));
}
}
QDialog* dialog = new QDialog(); QDialog* dialog = new QDialog();
dialog->setWindowTitle(dialog->tr("Parameter")); dialog->setWindowTitle(dialog->tr("Parameter"));
...@@ -93,22 +128,23 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image ...@@ -93,22 +128,23 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image
QCheckBox* colorBox = new QCheckBox("Explode colors", dialog); QCheckBox* colorBox = new QCheckBox("Explode colors", dialog);
layout->addWidget(colorBox); layout->addWidget(colorBox);
int nChannel = image->getNbChannels(); int nChannel = currentWnd->getDisplayImage()->getNbChannels();
QHBoxLayout** valueLayouts = new QHBoxLayout*[nChannel+1]; QHBoxLayout** valueLayouts = new QHBoxLayout*[nChannel+1];
QComboBox** pixOperatorBoxes = new QComboBox*[nChannel+1]; QComboBox** pixOperatorBoxes = new QComboBox*[nChannel+1];
QComboBox** imgOperatorBoxes = new QComboBox*[nChannel+1]; QComboBox** imgOperatorBoxes = new QComboBox*[nChannel+1];
QLineEdit** exprEdits = new QLineEdit*[nChannel+1]; QLineEdit** exprEdits = new QLineEdit*[nChannel+1];
ImageListBox** imageBoxes = new ImageListBox*[nChannel+1]; MixImageListBox** imageBoxes = new MixImageListBox*[nChannel+1];
QWidget* pixelWidget = new QWidget(dialog); QWidget* pixelWidget = new QWidget(dialog);
valueLayouts[0] = new QHBoxLayout(); valueLayouts[0] = new QHBoxLayout();
pixOperatorBoxes[0] = new QComboBox(pixelWidget); pixOperatorBoxes[0] = new QComboBox(pixelWidget);
imgOperatorBoxes[0] = new QComboBox(pixelWidget); imgOperatorBoxes[0] = new QComboBox(pixelWidget);
pixOperatorBoxes[0]->addItems(pixOperators); pixOperatorBoxes[0]->addItems(pixOperators);
imgOperatorBoxes[0]->addItems(imgOperators); imgOperatorBoxes[0]->addItems(imgOperators);
exprEdits[0] = new QLineEdit(pixelWidget); exprEdits[0] = new QLineEdit(pixelWidget);
exprEdits[0]->setFixedWidth(64); exprEdits[0]->setFixedWidth(64);
imageBoxes[0] = new ImageListBox(pixelWidget, image, imgList); imageBoxes[0] = new MixImageListBox(pixelWidget, currentImgName.toStdString(), stdImgList, dblImgList);
valueLayouts[0]->addWidget(new QLabel(currentImgName, pixelWidget)); valueLayouts[0]->addWidget(new QLabel(currentImgName, pixelWidget));
valueLayouts[0]->addWidget(pixOperatorBoxes[0]); valueLayouts[0]->addWidget(pixOperatorBoxes[0]);
valueLayouts[0]->addWidget(imgOperatorBoxes[0]); valueLayouts[0]->addWidget(imgOperatorBoxes[0]);
...@@ -125,11 +161,11 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image ...@@ -125,11 +161,11 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image
valueLayouts[i] = new QHBoxLayout(); valueLayouts[i] = new QHBoxLayout();
pixOperatorBoxes[i] = new QComboBox(colorWidget); pixOperatorBoxes[i] = new QComboBox(colorWidget);
imgOperatorBoxes[i] = new QComboBox(colorWidget); imgOperatorBoxes[i] = new QComboBox(colorWidget);
pixOperatorBoxes[i]->addItems(pixOperators); pixOperatorBoxes[i]->addItems(pixOperators);
imgOperatorBoxes[i]->addItems(imgOperators); imgOperatorBoxes[i]->addItems(imgOperators);
exprEdits[i] = new QLineEdit(colorWidget); exprEdits[i] = new QLineEdit(colorWidget);
exprEdits[i]->setFixedWidth(64); exprEdits[i]->setFixedWidth(64);
imageBoxes[i] = new ImageListBox(colorWidget, image, imgList); imageBoxes[i] = new MixImageListBox(colorWidget, currentImgName.toStdString(), stdImgList, dblImgList);
valueLayouts[i]->addWidget(new QLabel(currentImgName+"::"+Tools::colorName(i-1, nChannel), colorWidget)); valueLayouts[i]->addWidget(new QLabel(currentImgName+"::"+Tools::colorName(i-1, nChannel), colorWidget));
valueLayouts[i]->addWidget(pixOperatorBoxes[i]); valueLayouts[i]->addWidget(pixOperatorBoxes[i]);
valueLayouts[i]->addWidget(imgOperatorBoxes[i]); valueLayouts[i]->addWidget(imgOperatorBoxes[i]);
...@@ -164,69 +200,202 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image ...@@ -164,69 +200,202 @@ void PointOp::operator()(const imagein::Image* image, const std::map<const image
return; return;
} }
PixelOp** pixelOps = new PixelOp*[nChannel]; bool dblResult = currentWnd->isDouble();
ImageOp** imageOps = new ImageOp*[nChannel]; if(!valueButton->isChecked()) {
const Image** imageImgs = new const Image*[nChannel]; if(!colorBox->isChecked()) {
unsigned int maxWidth = image->getWidth(); dblResult = dblResult || (imageBoxes[0]->currentType() == MixImageListBox::DBLIMG);
unsigned int maxHeight = image->getHeight();
if(!colorBox->isChecked()) {
QString expr = exprEdits[0]->text();
PixelOp* pixelOp = PixelOp::fromString(pixOperatorBoxes[0]->currentText(), expr);
ImageOp* imageOp = ImageOp::fromString(imgOperatorBoxes[0]->currentText());
const Image* imageImg = imageBoxes[0]->currentImage();
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
for(int i=0; i<nChannel; ++i) {
pixelOps[i] = pixelOp;
imageOps[i] = imageOp;
imageImgs[i] = imageImg;
} }
} else {
else { for(int i=0; i<nChannel; ++i) {
for(int i=0; i<nChannel; ++i) { dblResult = dblResult || (imageBoxes[i+1]->currentType() == MixImageListBox::DBLIMG);
QString expr = exprEdits[i+1]->text(); }
pixelOps[i] = PixelOp::fromString(pixOperatorBoxes[i+1]->currentText(), expr);
imageOps[i] = ImageOp::fromString(imgOperatorBoxes[i+1]->currentText());
imageImgs[i] = imageBoxes[i+1]->currentImage();
maxWidth = min(maxWidth, imageImgs[i]->getWidth());
maxHeight = min(maxHeight, imageImgs[i]->getHeight());
} }
} }
Image* resImg; if(dblResult) {
const DoubleImageWindow* currentDblWnd = dynamic_cast<const DoubleImageWindow*>(currentWnd);
if(valueButton->isChecked()) { const Image_t<double>* image = currentDblWnd ? currentDblWnd->getImage() : NULL;
resImg = new Image(image->getWidth(), image->getHeight(), nChannel); unsigned int maxWidth = image->getWidth();
for(int c = 0; c < nChannel; ++c) { unsigned int maxHeight = image->getHeight();
for(unsigned int j = 0; j < image->getHeight(); ++j) {
for(unsigned int i = 0; i < image->getWidth(); ++i) {
Image::depth_t value = image->getPixel(i, j, c); Image_t<double>* resImg;
value = pixelOps[c]->operator()(value);
resImg->setPixel(i, j, c, value); if(valueButton->isChecked()) {
DoublePixelOp** pixelOps = new DoublePixelOp*[nChannel];
if(!colorBox->isChecked()) {
QString expr = exprEdits[0]->text();
DoublePixelOp* pixelOp = DoublePixelOp::fromString(pixOperatorBoxes[0]->currentText(), expr);
for(int i=0; i<nChannel; ++i) pixelOps[i] = pixelOp;
}
else {
for(int i=0; i<nChannel; ++i) {
QString expr = exprEdits[i+1]->text();
pixelOps[i] = DoublePixelOp::fromString(pixOperatorBoxes[i+1]->currentText(), expr);
}
}
resImg = new Image_t<double>(image->getWidth(), image->getHeight(), nChannel);
for(int c = 0; c < nChannel; ++c) {
for(unsigned int j = 0; j < image->getHeight(); ++j) {
for(unsigned int i = 0; i < image->getWidth(); ++i) {
double value = image->getPixel(i, j, c);
value = pixelOps[c]->operator()(value);
resImg->setPixel(i, j, c, value);
}
} }
} }
} }
else {
DoubleImageOp** imageOps = new DoubleImageOp*[nChannel];
bool isDblImg[nChannel];
const Image_t<double>* dblImageImgs[nChannel];
const Image* stdImageImgs[nChannel];
if(!colorBox->isChecked()) {
DoubleImageOp* imageOp = DoubleImageOp::fromString(imgOperatorBoxes[0]->currentText());
for(int i=0; i<nChannel; ++i) imageOps[i] = imageOp;
if(imageBoxes[0]->currentType() == MixImageListBox::DBLIMG) {
const Image_t<double>* imageImg = imageBoxes[0]->getDblImage(imageBoxes[0]->currentText().toStdString());
for(int i=0; i<nChannel; ++i) {
dblImageImgs[i] = imageImg;
isDblImg[i] = true;
}
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
}
else {
const Image* imageImg = imageBoxes[0]->getStdImage(imageBoxes[0]->currentText().toStdString());
for(int i=0; i<nChannel; ++i) {
stdImageImgs[i] = imageImg;
isDblImg[i] = false;
}
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
}
}
else {
for(int i=0; i<nChannel; ++i) {
imageOps[i] = DoubleImageOp::fromString(imgOperatorBoxes[i+1]->currentText());
if(imageBoxes[i+1]->currentType() == MixImageListBox::DBLIMG) {
const Image_t<double>* imageImg = imageBoxes[i+1]->getDblImage(imageBoxes[i+1]->currentText().toStdString());
for(int i=0; i<nChannel; ++i) {
dblImageImgs[i] = imageImg;
isDblImg[i] = true;
}
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
}
else {
const Image* imageImg = imageBoxes[i+1]->getStdImage(imageBoxes[i+1]->currentText().toStdString());
for(int i=0; i<nChannel; ++i) {
stdImageImgs[i] = imageImg;
isDblImg[i] = false;
}
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
}
}
}
resImg = new Image_t<double>(maxWidth, maxHeight, nChannel);
for(int c = 0; c < resImg->getNbChannels(); ++c) {
for(unsigned int j = 0; j < resImg->getHeight(); ++j) {
for(unsigned int i = 0; i < resImg->getWidth(); ++i) {
double value1 = image->getPixel(i, j, c);
double value2;
if(isDblImg[c]) {
const unsigned int channel = (c < dblImageImgs[c]->getNbChannels() ? c : 0);
value2 = dblImageImgs[c]->getPixel(i, j, channel);
}
else {
const unsigned int channel = (c < stdImageImgs[c]->getNbChannels() ? c : 0);
value2 = stdImageImgs[c]->getPixel(i, j, channel);
}
value1 = imageOps[c]->operator()(value1, value2);
resImg->setPixel(i, j, c, value1);
}
}
}
}
this->outDoubleImage(resImg, "", currentDblWnd->isNormalized(), currentDblWnd->isLogScaled());
} }
else { else {
resImg = new Image(maxWidth, maxHeight, nChannel); const Image* image = dynamic_cast<const StandardImageWindow*>(currentWnd)->getImage();
for(int c = 0; c < resImg->getNbChannels(); ++c) { unsigned int maxWidth = image->getWidth();
for(unsigned int j = 0; j < resImg->getHeight(); ++j) { unsigned int maxHeight = image->getHeight();
for(unsigned int i = 0; i < resImg->getWidth(); ++i) {
Image::depth_t value1 = image->getPixel(i, j, c);
const unsigned int channel = (c < imageImgs[c]->getNbChannels() ? c : 0); Image* resImg;
Image::depth_t value2 = imageImgs[c]->getPixel(i, j, channel);
value1 = imageOps[c]->operator()(value1, value2); if(valueButton->isChecked()) {
resImg->setPixel(i, j, c, value1); PixelOp** pixelOps = new PixelOp*[nChannel];
if(!colorBox->isChecked()) {
QString expr = exprEdits[0]->text();
PixelOp* pixelOp = PixelOp::fromString(pixOperatorBoxes[0]->currentText(), expr);
for(int i=0; i<nChannel; ++i) pixelOps[i] = pixelOp;
}
else {
for(int i=0; i<nChannel; ++i) {
QString expr = exprEdits[i+1]->text();
pixelOps[i] = PixelOp::fromString(pixOperatorBoxes[i+1]->currentText(), expr);
}
}
resImg = new Image(image->getWidth(), image->getHeight(), nChannel);
for(int c = 0; c < nChannel; ++c) {
for(unsigned int j = 0; j < image->getHeight(); ++j) {
for(unsigned int i = 0; i < image->getWidth(); ++i) {
Image::depth_t value = image->getPixel(i, j, c);
value = pixelOps[c]->operator()(value);
resImg->setPixel(i, j, c, value);
}
}
}
}
else {
ImageOp** imageOps = new ImageOp*[nChannel];
const Image** imageImgs = new const Image*[nChannel];
if(!colorBox->isChecked()) {
ImageOp* imageOp = ImageOp::fromString(imgOperatorBoxes[0]->currentText());
const Image* imageImg = imageBoxes[0]->getStdImage(imageBoxes[0]->currentText().toStdString());
maxWidth = min(maxWidth, imageImg->getWidth());
maxHeight = min(maxHeight, imageImg->getHeight());
for(int i=0; i<nChannel; ++i) {
imageOps[i] = imageOp;
imageImgs[i] = imageImg;
}
}
else {
for(int i=0; i<nChannel; ++i) {
imageOps[i] = ImageOp::fromString(imgOperatorBoxes[i+1]->currentText());
imageImgs[i] = imageBoxes[i+1]->getStdImage(imageBoxes[i+1]->currentText().toStdString());
maxWidth = min(maxWidth, imageImgs[i]->getWidth());
maxHeight = min(maxHeight, imageImgs[i]->getHeight());
}
}
resImg = new Image(maxWidth, maxHeight, nChannel);
for(int c = 0; c < resImg->getNbChannels(); ++c) {
for(unsigned int j = 0; j < resImg->getHeight(); ++j) {
for(unsigned int i = 0; i < resImg->getWidth(); ++i) {
Image::depth_t value1 = image->getPixel(i, j, c);
const unsigned int channel = (c < imageImgs[c]->getNbChannels() ? c : 0);
Image::depth_t value2 = imageImgs[c]->getPixel(i, j, channel);
value1 = imageOps[c]->operator()(value1, value2);
resImg->setPixel(i, j, c, value1);
}
} }
} }
} }
}
this->outImage(resImg); this->outImage(resImg);
}
} }
bool PointOp::needCurrentImg() const { bool PointOp::needCurrentImg() const {
return true; return true;
} }
bool PointOp::isValidImgWnd(const genericinterface::ImageWindow*) const {
return true;
}
...@@ -30,15 +30,16 @@ ...@@ -30,15 +30,16 @@
class QWidget; class QWidget;
class PointOp : public Operation { class PointOp : public GenericOperation {
public: public:
PointOp(); PointOp();
void operator()(const imagein::Image*, const std::map<const imagein::Image*, std::string>&); virtual void operator()(const genericinterface::ImageWindow* currentWnd, std::vector<genericinterface::ImageWindow*>&);
bool needCurrentImg() const; bool needCurrentImg() const;
virtual bool isValidImgWnd(const genericinterface::ImageWindow* imgWnd) const;
private: private:
typedef imagein::Image::depth_t depth_t; typedef imagein::Image::depth_t depth_t;
...@@ -58,11 +59,24 @@ class PointOp : public Operation { ...@@ -58,11 +59,24 @@ class PointOp : public Operation {
virtual intmax_t op(depth_t pixel) = 0; virtual intmax_t op(depth_t pixel) = 0;
static PixelOp* fromString(QString op, QString expr); static PixelOp* fromString(QString op, QString expr);
}; };
struct DoublePixelOp {
DoublePixelOp(double value_ = 0) : value(value_) {}
virtual double operator()(double pixel) {
return this->op(pixel);
}
virtual double op(double pixel) = 0;
static DoublePixelOp* fromString(QString op, QString expr);
double value;
};
struct PixIdent : PixelOp { struct PixIdent : PixelOp {
intmax_t op(depth_t pixel) { return pixel; } intmax_t op(depth_t pixel) { return pixel; }
}; };
struct DoublePixIdent : DoublePixelOp {
double op(double pixel) { return pixel; }
};
template<typename T> template<typename T>
struct PixOp_t : public PixelOp { struct PixOp_t : public PixelOp {
PixOp_t(T value_) : value(value_) {} PixOp_t(T value_) : value(value_) {}
...@@ -73,10 +87,18 @@ class PointOp : public Operation { ...@@ -73,10 +87,18 @@ class PointOp : public Operation {
PixAdd(int value_) : PixOp_t(value_) {} PixAdd(int value_) : PixOp_t(value_) {}
intmax_t op(depth_t pixel) { return pixel + value; } intmax_t op(depth_t pixel) { return pixel + value; }
}; };
struct DoublePixAdd : DoublePixelOp {
DoublePixAdd(double value_) : DoublePixelOp(value_) {}
double op(double pixel) { return pixel + value; }
};
struct PixMul : PixOp_t<double> { struct PixMul : PixOp_t<double> {
PixMul(double value_) : PixOp_t(value_) {} PixMul(double value_) : PixOp_t(value_) {}
intmax_t op(depth_t pixel) { return pixel * value; } intmax_t op(depth_t pixel) { return pixel * value + 0.5; }
};
struct DoublePixMul : DoublePixelOp {
DoublePixMul(double value_) : DoublePixelOp(value_) {}
double op(double pixel) { return pixel * value; }
}; };
struct PixAnd : PixOp_t<depth_t> { struct PixAnd : PixOp_t<depth_t> {
...@@ -111,19 +133,42 @@ class PointOp : public Operation { ...@@ -111,19 +133,42 @@ class PointOp : public Operation {
virtual intmax_t op(depth_t pixel1, depth_t pixel2) = 0; virtual intmax_t op(depth_t pixel1, depth_t pixel2) = 0;
static ImageOp* fromString(QString op); static ImageOp* fromString(QString op);
}; };
struct DoubleImageOp {
virtual double operator()(double pixel1, double pixel2) {
return this->op(pixel1, pixel2);
}
virtual double op(double pixel1, double pixel2) = 0;
static DoubleImageOp* fromString(QString op);
};
struct ImgIdent : ImageOp { struct ImgIdent : ImageOp {
intmax_t op(depth_t pix1, depth_t pix2) { return pix1; } intmax_t op(depth_t pix1, depth_t pix2) { return pix1; }
}; };
struct DoubleImgIdent : DoubleImageOp {
double op(double pix1, double pix2) { return pix1; }
};
struct ImgAdd : ImageOp { struct ImgAdd : ImageOp {
intmax_t op(depth_t pix1, depth_t pix2) { return pix1 + pix2; } intmax_t op(depth_t pix1, depth_t pix2) { return pix1 + pix2; }
}; };
struct DoubleImgAdd : DoubleImageOp {
double op(double pix1, double pix2) { return pix1 + pix2; }
};
struct ImgSub : ImageOp { struct ImgSub : ImageOp {
intmax_t op(depth_t pix1, depth_t pix2) { return pix1 - pix2; } intmax_t op(depth_t pix1, depth_t pix2) { return pix1 - pix2; }
}; };
struct DoubleImgSub : DoubleImageOp {
double op(double pix1, double pix2) { return pix1 - pix2; }
};
struct DoubleImgMul : DoubleImageOp {
double op(double pix1, double pix2) { return pix1 * pix2; }
};
struct DoubleImgDiv : DoubleImageOp {
double op(double pix1, double pix2) { return pix1 / pix2; }
};
struct ImgAnd : ImageOp { struct ImgAnd : ImageOp {
intmax_t op(depth_t pix1, depth_t pix2) { return pix1 & pix2; } intmax_t op(depth_t pix1, depth_t pix2) { return pix1 & pix2; }
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment