From b6d2a0f68f004089418cc2a1ec09a75d9bff2c45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sacha=20Percot-T=C3=A9tu?= <zakinster@zakinster.com>
Date: Wed, 19 Sep 2012 18:08:18 +0200
Subject: [PATCH] Added the MICD operation

---
 app/Operations/MICD.cpp           | 262 ++++++++++++++++++++++++++++++
 app/Operations/MICD.h             |  45 +++++
 app/Operations/MICDDialog.cpp     |  71 ++++++++
 app/Operations/MICDDialog.h       |  51 ++++++
 app/Operations/MICDDialog.ui      | 259 +++++++++++++++++++++++++++++
 app/Operations/MICDDialog_.ui     | 248 ++++++++++++++++++++++++++++
 app/Operations/MICDEncodingOp.cpp |  63 +++++++
 app/Operations/MICDEncodingOp.h   |  35 ++++
 8 files changed, 1034 insertions(+)
 create mode 100644 app/Operations/MICD.cpp
 create mode 100644 app/Operations/MICD.h
 create mode 100644 app/Operations/MICDDialog.cpp
 create mode 100644 app/Operations/MICDDialog.h
 create mode 100644 app/Operations/MICDDialog.ui
 create mode 100644 app/Operations/MICDDialog_.ui
 create mode 100644 app/Operations/MICDEncodingOp.cpp
 create mode 100644 app/Operations/MICDEncodingOp.h

diff --git a/app/Operations/MICD.cpp b/app/Operations/MICD.cpp
new file mode 100644
index 0000000..03232e8
--- /dev/null
+++ b/app/Operations/MICD.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MICD.h"
+#include <cstring>
+#include <cstdio>
+
+using namespace std;
+using namespace imagein;
+
+MICD::MICD()
+{
+    long counter;
+    for( counter=0; counter< 128; counter++ ) {
+      iloiqu[counter] = 0;
+    }
+    for( counter=0; counter< 2048*20; counter++ ) {
+      ((int*)itcod)[counter] = 0;
+        ((int*)itrco)[counter] = 0;
+    }
+    for( counter=0; counter< 40; counter++ ) {
+      ((int*)ktab)[counter] = 0;
+    }
+    quantdef = NULL;
+}
+
+MICD::~MICD()
+{
+
+}
+
+string MICD::execute( const GrayscaleImage *im, Prediction prediction_alg, Image **err_image, Image **recons_image, double Q ) {
+    char buffer[255];
+    if( quantdef == NULL ) {
+        throw "Error in MICD::execute:\nquantdef = NULL";
+    }
+    string returnval;
+    int nbl,nbc,size,rep,i,j,pred,ier,ireco,icode;
+    float pi[512],nbpt = 0;
+    double h = 0.;
+    rep = prediction_alg;
+
+    nbl = im->getHeight();
+    nbc = im->getWidth();
+    size = nbc * nbl;
+
+    int po;
+    int temp_p;
+    /* initialisation de la loi de quantification */
+    set_levels();
+    codlq(0);
+    /* allocation mmoire pour l'image d'erreur de prdiction */
+    GrayscaleImage *error_prediction_image = new GrayscaleImage(nbc, nbl);
+    Image *reconstructed_image = new GrayscaleImage(*im);
+    // File these images with all values of zero
+    long wcounter, hcounter;
+    for( hcounter=0; hcounter< nbl; hcounter++ ) {
+        for( wcounter=0; wcounter< nbc; wcounter++ ) {
+            error_prediction_image->setPixelAt(wcounter, hcounter, 0);
+        }
+    }
+
+    /* mise  0 du tableau des probas servant pour le calcul de
+    l'entropie de l'erreur de prdiction */
+    for(i=0 ; i<512 ; i++) pi[i]= 0.;
+
+    /* codage de l'image */
+    for(i=1; i<nbl ; i++)
+    {
+         for(j=1; j<nbc ; j++)
+         {
+             if(rep == PX_EQ_A) {
+                 temp_p = reconstructed_image->getPixelAt( j - 1, i );
+                 pred = temp_p;
+             }
+             else if(rep == PX_EQ_B) {
+                 temp_p = reconstructed_image->getPixelAt( j, i - 1);
+                 pred = temp_p;
+             }
+             else if(rep == PX_EQ_APC) {
+                 temp_p = reconstructed_image->getPixelAt( j - 1, i );
+                 pred = (int)temp_p;
+                 temp_p = reconstructed_image->getPixelAt( j, i - 1 );
+                 pred = ( pred + (int)temp_p ) / 2;
+         }
+         else if(rep == PX_EQ_Q) {
+                /*
+             Modified Graham's Algorithm:
+             if |B-C| - Q <= |B-A| <= |B-C| + Q
+                        P(X) = (A+C)/2
+             else
+                    if |B-A| > |B-C|
+                            P(X) = A
+                    else
+                            P(X) = C
+             */
+             float A = im->getPixelAt( j - 1, i );
+             float B = im->getPixelAt( j - 1, i - 1 );
+             float C = im->getPixelAt( j, i - 1 );
+             if( ((fabs(B-C) - Q) <= fabs(B-A)) &&
+                 (fabs(B-A) <= (fabs(B-C) + Q)) ) {
+                 pred = (uint8_t)((A + C) / 2);
+             }
+             else {
+                 if( fabs(B-A) > fabs(B-C) ) {
+                   pred = (uint8_t)A;
+                 }
+                 else {
+                   pred = (uint8_t)C;
+                 }
+             }
+         }
+
+         temp_p = reconstructed_image->getPixelAt( j, i );
+         ier = (int)temp_p - pred;
+         codec(0,ier,&icode,&ireco);
+         pi[ier+255]++;      /* proba associe  l'erreur de prdiction */
+         nbpt++;
+
+         int tempvalue;
+         tempvalue = ier + 128;
+         if( tempvalue > 255 ) tempvalue = 255;
+         if( tempvalue < 0 ) tempvalue = 0;
+         po = tempvalue;
+         error_prediction_image->setPixelAt( j, i, po );
+         tempvalue = pred + ireco;
+         if( tempvalue > 255 ) tempvalue = 255;
+         if( tempvalue < 0 ) tempvalue = 0;
+         po = tempvalue;
+         reconstructed_image->setPixelAt( j, i, po );
+     }
+  }
+
+    /* calcul de l'entropie de l'image d'erreur de prdiction */
+    for(i=0 ; i<512 ; i++)
+    {
+        if(pi[i] != 0) {
+            pi[i] /= nbpt;
+            h -= (double)pi[i] * log((double)pi[i])/log((double)2.0);
+        }
+    }
+
+
+    /* affichage des rsultats */
+    sprintf(buffer, "\nL'entropie de l'image d'erreur de prediction vaut : %lf\n",h);
+    returnval = returnval + buffer;
+    returnval = returnval + "\n";
+    returnval = returnval + print_iloiqu();
+
+
+    /* libration de la mmoire alloue */
+    *err_image = error_prediction_image;
+    *recons_image = reconstructed_image;
+    return returnval;
+}
+
+void MICD::codlq(int m) {
+   int n,nar,nk,i,j;
+
+    n=iloiqu[0];
+    ktab[0][m]=iloiqu[1];
+    nar=ktab[0][m] - 1;
+    j= -1;
+    for(i=0;i < n-1 ; i++)
+    {
+      nk=1+nar-iloiqu[2*i+1];
+      do{j++;itcod[j][m]=i;nk++;} while(nk <= 0);
+      nar=iloiqu[2*i+1];
+      itrco[i][m]=iloiqu[2*i+2];
+    }
+    itcod[j+1][m]=i;
+    itrco[i][m]=iloiqu[2*i+2];
+    ktab[1][m]=iloiqu[2*i+1];
+}
+
+void MICD::codec(int nlq,int ier,int *icode,int *ireco) {
+   int m,ip,iep,ierp,n,l;
+    m=nlq;
+    ip=ktab[0][m];
+    ierp=ier-ip;
+    if(ierp > 0)
+    {
+      ip=ktab[1][m];
+      iep=ier-ip;
+      if(iep < 0)
+        n=ier - ktab[0][m];
+      else
+        n=ktab[1][m] - ktab[0][m];
+      *icode=itcod[n][m];
+      l= *icode;
+      *ireco=itrco[l][m];
+    }
+    else
+    {
+      *icode=itcod[0][m];
+      *ireco=itrco[0][m];
+    }
+}
+
+void MICD::set_levels() {
+  // Fills in iloiqu with the specified values
+    if( quantdef->size - 1 > 32 || quantdef->size - 1 < 1 ) {
+        char buffer[255];
+        sprintf( buffer, "Error in MICD::set_levels:\nquantdef->GetNumThresholds() = %d", quantdef->size - 1 );
+        throw buffer;
+    }
+    int counter;
+    iloiqu[0] = quantdef->size;
+    for( counter=0; counter< quantdef->size - 1; counter++ ) {
+        iloiqu[ counter * 2 + 1 ] = quantdef->threshold[ counter ];
+        iloiqu[ counter * 2 + 2 ] = quantdef->values[ counter ];
+    }
+    iloiqu[ (quantdef->size - 1) * 2 + 1 ] = iloiqu[ (quantdef->size - 1) * 2 - 1 ] + 1;
+    iloiqu[ (quantdef->size - 1) * 2 + 2 ] = quantdef->values[ quantdef->size - 1 ];
+}
+
+string MICD::print_iloiqu() {
+  string returnval;
+    returnval = "seuils de dcision --------------- niveaux de reconstruction\n";
+  int counter;
+    char buffer[100];
+    for( counter=1; counter<= iloiqu[0]*2-1; counter++ ) {
+        if( !(counter & 1 == 1) ) {
+          sprintf( buffer, "                                                 %3d     \n", iloiqu[counter] );
+            returnval = returnval + buffer;
+            sprintf( buffer, "      %3d ---------------------------------------------\n", iloiqu[counter-1] );
+            returnval = returnval + buffer;
+        }
+    }
+    sprintf( buffer, "                                                 %3d     \n", iloiqu[counter] );
+    returnval = returnval + buffer;
+
+    return returnval;
+}
+
+void MICD::setQuantification( Quantification *tquantdef ) {
+    if( tquantdef == NULL ) {
+        throw "Error in MICD::setQuantDef:\ntquantdef = NULL";
+    }
+    if( tquantdef->size - 1 > 32 || tquantdef->size - 1 < 1 ) {
+        char buffer[255];
+        sprintf( buffer, "Error in MICD::setQuantDef:\ntquantdef->GetNumThresholds() = %d", tquantdef->size - 1 );
+        throw buffer;
+    }
+    quantdef = tquantdef;
+}
diff --git a/app/Operations/MICD.h b/app/Operations/MICD.h
new file mode 100644
index 0000000..c54b9fa
--- /dev/null
+++ b/app/Operations/MICD.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MICD_H
+#define MICD_H
+
+#include <string>
+#include <GrayscaleImage.h>
+#include "Quantification.h"
+
+class MICD
+{
+public:
+    MICD();
+    enum Prediction {PX_EQ_A, PX_EQ_B, PX_EQ_APC, PX_EQ_Q};
+    virtual ~MICD();
+    std::string execute( const imagein::GrayscaleImage *im, Prediction prediction_alg, imagein::Image **err_image, imagein::Image **recons_image, double Q = 0 );
+    void setQuantification( Quantification* tquantdef );
+private:
+    std::string print_iloiqu();
+    Quantification* quantdef;
+    void codlq(int m);
+    void codec(int nlq,int ier,int *icode,int *ireco);
+    void set_levels();
+    int iloiqu[128];
+    int itcod[2048][20],itrco[2048][20],ktab[2][20];
+};
+
+#endif // MICD_H
diff --git a/app/Operations/MICDDialog.cpp b/app/Operations/MICDDialog.cpp
new file mode 100644
index 0000000..ca87540
--- /dev/null
+++ b/app/Operations/MICDDialog.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MICDDialog.h"
+#include "ui_MICDDialog.h"
+#include <QFileDialog>
+#include "QuantificationDialog.h"
+
+MICDDialog::MICDDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::MICDDialog)
+{
+    ui->setupUi(this);
+}
+
+MICDDialog::~MICDDialog()
+{
+    delete ui;
+}
+
+void MICDDialog::on_quantBrowseButton_clicked()
+{
+    QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), "", tr("Loi de quantification (*.loi)"));
+    ui->quantFileEdit->setText(filename);
+}
+
+void MICDDialog::on_quantEditorButton_clicked()
+{
+
+    QuantificationDialog* dialog = new QuantificationDialog(QApplication::activeWindow());
+    dialog->exec();
+}
+
+Quantification* MICDDialog::getQuantification() const {
+    try {
+        Quantification* quantif = new Quantification(ui->quantFileEdit->text().toStdString());
+        return quantif;
+    }
+    catch(std::exception&) {
+        return NULL;
+    }
+
+}
+
+MICD::Prediction MICDDialog::getPrediction() const {
+    if(ui->predictRadioA->isChecked()) return MICD::PX_EQ_A;
+    else if(ui->predictRadioAC->isChecked()) return MICD::PX_EQ_B;
+    else if(ui->predictRadioC->isChecked()) return MICD::PX_EQ_APC;
+    else if(ui->predictRadioGraham->isChecked()) return MICD::PX_EQ_Q;
+    else return MICD::PX_EQ_A;
+}
+
+double MICDDialog::getQ() const {
+    return ui->qSpinBox->value();
+}
diff --git a/app/Operations/MICDDialog.h b/app/Operations/MICDDialog.h
new file mode 100644
index 0000000..c4d15ea
--- /dev/null
+++ b/app/Operations/MICDDialog.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MICDDIALOG_H
+#define MICDDIALOG_H
+
+#include <QDialog>
+#include "Quantification.h"
+#include "MICD.h"
+
+namespace Ui {
+class MICDDialog;
+}
+
+class MICDDialog : public QDialog
+{
+    Q_OBJECT
+    
+public:
+    explicit MICDDialog(QWidget *parent = 0);
+    ~MICDDialog();
+    Quantification* getQuantification() const;
+    MICD::Prediction getPrediction() const;
+    double getQ() const;
+    
+private slots:
+    void on_quantBrowseButton_clicked();
+
+    void on_quantEditorButton_clicked();
+
+private:
+    Ui::MICDDialog *ui;
+};
+
+#endif // MICDDIALOG_H
diff --git a/app/Operations/MICDDialog.ui b/app/Operations/MICDDialog.ui
new file mode 100644
index 0000000..06732e3
--- /dev/null
+++ b/app/Operations/MICDDialog.ui
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MICDDialog</class>
+ <widget class="QDialog" name="MICDDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>545</width>
+    <height>340</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item alignment="Qt::AlignHCenter">
+    <widget class="QLabel" name="micdImage">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="pixmap">
+      <pixmap resource="../eiimage_app_res.qrc">:/img/micd.png</pixmap>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QWidget" name="widget" native="true">
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="QGroupBox" name="predictorBox">
+          <property name="title">
+           <string>Predictor P(X)</string>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_4">
+           <item>
+            <widget class="QRadioButton" name="predictRadioA">
+             <property name="text">
+              <string>A</string>
+             </property>
+             <property name="checked">
+              <bool>true</bool>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="predictRadioC">
+             <property name="text">
+              <string>C</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="predictRadioAC">
+             <property name="text">
+              <string>( A + C ) / 2</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="predictRadioGraham">
+             <property name="text">
+              <string>Modified Graham's</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_2">
+             <item alignment="Qt::AlignRight">
+              <widget class="QLabel" name="qLabel">
+               <property name="text">
+                <string>Q = </string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QSpinBox" name="qSpinBox">
+               <property name="enabled">
+                <bool>false</bool>
+               </property>
+               <property name="maximum">
+                <number>255</number>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QWidget" name="widget_2" native="true">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
+        <item>
+         <widget class="QGroupBox" name="quantifierBox">
+          <property name="title">
+           <string>Quantifier</string>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_5">
+           <item>
+            <widget class="QLabel" name="quantFileLabel">
+             <property name="text">
+              <string>Quantification file :</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_3">
+             <item>
+              <widget class="QLineEdit" name="quantFileEdit"/>
+             </item>
+             <item>
+              <widget class="QPushButton" name="quantBrowseButton">
+               <property name="font">
+                <font>
+                 <pointsize>10</pointsize>
+                 <weight>75</weight>
+                 <italic>true</italic>
+                 <bold>true</bold>
+                </font>
+               </property>
+               <property name="text">
+                <string>Browse</string>
+               </property>
+               <property name="iconSize">
+                <size>
+                 <width>8</width>
+                 <height>8</height>
+                </size>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>22</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item>
+            <widget class="QPushButton" name="quantEditorButton">
+             <property name="text">
+              <string>Open quantification editor</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_3">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>22</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../eiimage_app_res.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MICDDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MICDDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>predictRadioGraham</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>qSpinBox</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>113</x>
+     <y>224</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>153</x>
+     <y>256</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/app/Operations/MICDDialog_.ui b/app/Operations/MICDDialog_.ui
new file mode 100644
index 0000000..9e70d16
--- /dev/null
+++ b/app/Operations/MICDDialog_.ui
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+  <property name="windowModality">
+   <enum>Qt::WindowModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>678</width>
+    <height>528</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MICD Encoding</string>
+  </property>
+  <property name="modal">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item alignment="Qt::AlignHCenter|Qt::AlignVCenter">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string/>
+     </property>
+     <property name="pixmap">
+      <pixmap resource="../eiimage_app_res.qrc">:/img/micd.png</pixmap>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QWidget" name="widget_2" native="true">
+       <layout class="QVBoxLayout" name="verticalLayout_4">
+        <item>
+         <widget class="QGroupBox" name="groupBox_2">
+          <property name="title">
+           <string>Predictor P(X)</string>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_3">
+           <item>
+            <widget class="QRadioButton" name="radioButton_3">
+             <property name="text">
+              <string>A</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="radioButton_4">
+             <property name="text">
+              <string>C</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="radioButton_5">
+             <property name="text">
+              <string>(A + C) / 2</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QRadioButton" name="radioButton_6">
+             <property name="text">
+              <string>Modified Graham's</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_2">
+             <item alignment="Qt::AlignRight">
+              <widget class="QLabel" name="label_2">
+               <property name="text">
+                <string>Q = </string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QSpinBox" name="spinBox">
+               <property name="maximum">
+                <number>255</number>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_4">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+          <zorder>radioButton_3</zorder>
+          <zorder>radioButton_4</zorder>
+          <zorder>radioButton_5</zorder>
+          <zorder>radioButton_6</zorder>
+          <zorder>verticalSpacer_4</zorder>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <widget class="QWidget" name="widget" native="true">
+       <layout class="QVBoxLayout" name="verticalLayout_2">
+        <item>
+         <widget class="QGroupBox" name="groupBox">
+          <property name="title">
+           <string>Quantifier</string>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_5">
+           <item>
+            <widget class="QLabel" name="label_3">
+             <property name="text">
+              <string>Quantification file :</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <layout class="QHBoxLayout" name="horizontalLayout_3">
+             <item>
+              <widget class="QLineEdit" name="lineEdit"/>
+             </item>
+             <item>
+              <widget class="QPushButton" name="pushButton">
+               <property name="font">
+                <font>
+                 <pointsize>10</pointsize>
+                 <weight>75</weight>
+                 <italic>true</italic>
+                 <bold>true</bold>
+                </font>
+               </property>
+               <property name="text">
+                <string>Browse</string>
+               </property>
+               <property name="iconSize">
+                <size>
+                 <width>8</width>
+                 <height>8</height>
+                </size>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+           <item>
+            <widget class="QPushButton" name="pushButton_2">
+             <property name="text">
+              <string>Open quantification editor</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_3">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../eiimage_app_res.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>Dialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>Dialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/app/Operations/MICDEncodingOp.cpp b/app/Operations/MICDEncodingOp.cpp
new file mode 100644
index 0000000..19e5e2f
--- /dev/null
+++ b/app/Operations/MICDEncodingOp.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MICDEncodingOp.h"
+#include "../Tools.h"
+#include <QApplication>
+#include "MICDDialog.h"
+#include "MICD.h"
+#include <QMessageBox>
+#include <GrayscaleImage.h>
+#include <Converter.h>
+
+using namespace std;
+using namespace imagein;
+
+MICDEncodingOp::MICDEncodingOp() : Operation(qApp->translate("Operations", "MICD Encoding").toStdString())
+{
+}
+
+bool MICDEncodingOp::needCurrentImg() const {
+    return true;
+}
+
+void MICDEncodingOp::operator()(const imagein::Image* img, const std::map<const imagein::Image*, std::string>&) {
+
+    MICDDialog* dialog = new MICDDialog(QApplication::activeWindow());
+    QDialog::DialogCode code = static_cast<QDialog::DialogCode>(dialog->exec());
+
+
+    if(code!=QDialog::Accepted) return;
+
+    MICD micd;
+    try {
+        micd.setQuantification(dialog->getQuantification());
+    }
+    catch(const char* str) {
+        QMessageBox::critical(NULL, qApp->translate("MICD", "Error while loading quantification file"), qApp->translate("MICD", "The specified quantification file could not be opened !"));
+        return;
+    }
+    GrayscaleImage* image = Converter<GrayscaleImage>::convert(*img);
+    Image *errorImage, *reconstructedImage;
+    string s = micd.execute(image, dialog->getPrediction(), &errorImage, &reconstructedImage, dialog->getQ());
+    outText(s);
+    outImage(errorImage, qApp->translate("MICD", "Error image").toStdString());
+    outImage(reconstructedImage, qApp->translate("MICD", "Reconstructed image").toStdString());
+}
+
diff --git a/app/Operations/MICDEncodingOp.h b/app/Operations/MICDEncodingOp.h
new file mode 100644
index 0000000..cb0522a
--- /dev/null
+++ b/app/Operations/MICDEncodingOp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MICDENCODINGOP_H
+#define MICDENCODINGOP_H
+
+#include <Operation.h>
+
+class MICDEncodingOp : public Operation
+{
+public:
+    MICDEncodingOp();
+
+    void operator()(const imagein::Image*, const std::map<const imagein::Image*, std::string>&);
+
+    bool needCurrentImg() const;
+};
+
+#endif // MICDENCODINGOP_H
-- 
GitLab