From 97ec669558b7a45e1dfcd1b2b72ff6906a1c5427 Mon Sep 17 00:00:00 2001
From: yliu2 <liuyu2209@gmail.com>
Date: Thu, 13 Aug 2020 06:28:49 +0200
Subject: [PATCH] Pixel operations upgraded

---
 app/Operations/PointOp.cpp | 29 ++++++++++++++++++++++++-----
 app/Operations/PointOp.h   | 30 +++++++++++++++++++++++++++++-
 lib/detiq-t                |  2 +-
 3 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/app/Operations/PointOp.cpp b/app/Operations/PointOp.cpp
index 7316f71..75a3f25 100644
--- a/app/Operations/PointOp.cpp
+++ b/app/Operations/PointOp.cpp
@@ -64,6 +64,9 @@ PointOp::DoublePixelOp* PointOp::DoublePixelOp::fromString(QString op, QString e
     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 DoublePixAnd(expr.toDouble());
+    if(op=="|") return new DoublePixOr(expr.toDouble());
+    if(op=="^") return new DoublePixXor(expr.toDouble());
     if(op=="") return new DoublePixIdent();
     std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
     return new DoublePixIdent();
@@ -81,11 +84,15 @@ PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) {
     std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
     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 DoubleImgAnd();
+    if(op=="|") return new DoubleImgOr();
+    if(op=="^") return new DoubleImgXor();
     if(op=="") return new DoubleImgIdent();
     std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl;
     return new DoubleImgIdent();
@@ -118,14 +125,18 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image
     QVBoxLayout* layout = new QVBoxLayout();
     dialog->setLayout(layout);
 
+    /*The generation order of the widgets does not match the layout, exchange their positions*/
     QGroupBox* radioGroup = new QGroupBox(qApp->translate("PointOp", "Second operand"), dialog);
-    QRadioButton* uCharButton = new QRadioButton(qApp->translate("PointOp", "UChar"));
-    QRadioButton* doubleButton = new QRadioButton(qApp->translate("PointOp", "Double"));
-
-    QGroupBox* radioGroup2 = new QGroupBox(qApp->translate("PointOp", "Output image"), dialog);
+//    QRadioButton* uCharButton = new QRadioButton(qApp->translate("PointOp", "UChar"));
+//    QRadioButton* doubleButton = new QRadioButton(qApp->translate("PointOp", "Double"));
     QRadioButton* valueButton = new QRadioButton(qApp->translate("PointOp", "Value"));
     QRadioButton* imageButton = new QRadioButton(qApp->translate("PointOp", "Image"));
 
+    QGroupBox* radioGroup2 = new QGroupBox(qApp->translate("PointOp", "Output image"), dialog);
+//    QRadioButton* valueButton = new QRadioButton(qApp->translate("PointOp", "Value"));
+//    QRadioButton* imageButton = new QRadioButton(qApp->translate("PointOp", "Image"));
+    QRadioButton* uCharButton = new QRadioButton(qApp->translate("PointOp", "UChar"));
+    QRadioButton* doubleButton = new QRadioButton(qApp->translate("PointOp", "Double"));
 
 
     QHBoxLayout* radioLayout = new QHBoxLayout(radioGroup);
@@ -294,6 +305,8 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image
     }
     else {
         DoubleImageOp** imageOps = new DoubleImageOp*[nChannel];
+        /*The double image process exist already, but cases of standard images is ignored*/
+        ImageOp** imageOpsStd = new ImageOp*[nChannel];
         bool isDblImg[nChannel];
         const Image_t<double>* dblImageImgs[nChannel];
         const Image* stdImageImgs[nChannel];
@@ -311,7 +324,9 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image
             }
             else {
                 const Image* imageImg = imageBoxes[0]->getStdImage(imageBoxes[0]->currentText().toStdString());
+                ImageOp* imageOpStd = ImageOp::fromString(imgOperatorBoxes[0]->currentText());
                 for(int i=0; i<nChannel; ++i) {
+                    imageOpsStd[i] = imageOpStd;
                     stdImageImgs[i] = imageImg;
                     isDblImg[i] = false;
                 }
@@ -357,7 +372,11 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image
                         const unsigned int channel = (c < stdImageImgs[c]->getNbChannels() ? c : 0);
                         value2 = stdImageImgs[c]->getPixel(i, j, channel);
                     }
-                    value1 = imageOps[c]->operator()(value1, value2);
+                    if(isDblImg[c]){
+                        value1 = imageOps[c]->operator()(value1, value2);
+                    }else{
+                        value1 = imageOpsStd[c]->operator()(value1, value2);
+                    }
                     resImg->setPixel(i, j, c, value1);
                 }
             }
diff --git a/app/Operations/PointOp.h b/app/Operations/PointOp.h
index 7c58dad..e78e5ff 100644
--- a/app/Operations/PointOp.h
+++ b/app/Operations/PointOp.h
@@ -106,16 +106,34 @@ class PointOp : public GenericOperation {
         intmax_t op(depth_t pixel) { return pixel & value; }
     };
 
+    /*Return zero if the operands have zero*/
+    struct DoublePixAnd : DoublePixelOp {
+        DoublePixAnd(double value_) : DoublePixelOp(value_) {}
+        double op(double pixel) { return (pixel==0 or value==0) ? 0 : pixel; }
+    };
+
     struct PixOr : PixOp_t<depth_t> {
         PixOr(depth_t value_) : PixOp_t<depth_t>(value_) {}
         intmax_t op(depth_t pixel) { return pixel | value; }
     };
 
+    /*Return zero only if the operands are both zero*/
+    struct DoublePixOr : DoublePixelOp {
+        DoublePixOr(double value_) : DoublePixelOp(value_) {}
+        double op(double pixel) { return (pixel==0 and value==0) ? 0 : pixel; }
+    };
+
     struct PixXor : PixOp_t<depth_t> {
         PixXor(depth_t value_) : PixOp_t<depth_t>(value_) {}
         intmax_t op(depth_t pixel) { return pixel ^ value; }
     };
 
+    /*Return zero only if the operands have the same value*/
+    struct DoublePixXor : DoublePixelOp {
+        DoublePixXor(double value_) : DoublePixelOp(value_) {}
+        double op(double pixel) { return (pixel==value) ? 0 : pixel; }
+    };
+
     struct PixLshift : PixOp_t<unsigned int> {
         PixLshift(unsigned int value_) : PixOp_t<unsigned int>(value_) {}
         intmax_t op(depth_t pixel) { return pixel << value; }
@@ -181,16 +199,26 @@ class PointOp : public GenericOperation {
     struct ImgAnd : ImageOp {
         intmax_t op(depth_t pix1, depth_t pix2) { return pix1 & pix2; } 
     };
+
+    struct DoubleImgAnd : DoubleImageOp {
+        double op(double pix1, double pix2) { return (pix1==0 or pix2==0) ? 0 : pix1;}
+    };
     
     struct ImgOr : ImageOp {
         intmax_t op(depth_t pix1, depth_t pix2) { return pix1 | pix2; } 
     };
     
+    struct DoubleImgOr : DoubleImageOp {
+        double op(double pix1, double pix2) { return (pix1==0 and pix2==0) ? 0 : pix1;}
+    };
+
     struct ImgXor : ImageOp {
         intmax_t op(depth_t pix1, depth_t pix2) { return pix1 ^ pix2; } 
     };
 
-
+    struct DoubleImgXor : DoubleImageOp {
+        double op(double pix1, double pix2) { return (pix1 == pix2) ? 0 : pix1; }
+    };
 
 };
 
diff --git a/lib/detiq-t b/lib/detiq-t
index 3f970a0..3a99904 160000
--- a/lib/detiq-t
+++ b/lib/detiq-t
@@ -1 +1 @@
-Subproject commit 3f970a071b367a8ea462f4fa2db7f96fd5148119
+Subproject commit 3a99904c0770a286941c6158e2a44cf1e1ceceb6
-- 
GitLab