void MainWindow::save(QUrl url) {
    //if saving process was aborted
    if(!url.isValid())
        return;

    QString path = url.toLocalFile();

    //if no file suffix was chosen, automatically use the PNG format
    QFileInfo file(path);
    if(!file.baseName().isEmpty() && file.suffix().isEmpty())
        path += ".png";

    QString suffix = file.suffix();
    //Qt can only read tga, saving is not supported
    if(suffix.toLower() == "tga")
        suffix = "png";

    //append a suffix to the map names (result: path/original_normal.png)
    QString name_normal = file.absolutePath() + "/" + file.baseName() + "_normal." + suffix;
    QString name_specular = file.absolutePath() + "/" + file.baseName() + "_spec." + suffix;
    QString name_displace = file.absolutePath() + "/" + file.baseName() + "_displace." + suffix;

    bool successfullySaved = true;
    
    if(ui->checkBox_queue_generateNormal->isChecked()) {
        if(normalmap.isNull())
            ui->statusBar->showMessage("calculating normalmap...");
            calcNormal();
        
        successfullySaved &= normalmap.save(name_normal);
    }    
    
    if(ui->checkBox_queue_generateSpec->isChecked()) {
        if(specmap.isNull())
            ui->statusBar->showMessage("calculating specularmap...");
            calcSpec();
        
        successfullySaved &= specmap.save(name_specular);
    }

    if(ui->checkBox_queue_generateDisplace->isChecked()) {
        if(displacementmap.isNull())
            ui->statusBar->showMessage("calculating displacementmap...");
            calcDisplace();
        
        successfullySaved &= displacementmap.save(name_displace);
    }
    
    if(successfullySaved)
        ui->statusBar->showMessage("Maps successfully saved", 4000);
    else
        QMessageBox::information(this, "Maps not saved", "One or more of the maps was NOT saved!");
    
    //store export path
    setExportPath(url.adjusted(QUrl::RemoveFilename));
    //enable "Open Export Folder" gui button
    ui->pushButton_openExportFolder->setEnabled(true);
}
void MainWindow::calcSpecAndPreview() {
    ui->statusBar->showMessage("calculating specularmap...");

    //timer for measuring calculation time
    QElapsedTimer timer;
    timer.start();

    //calculate map
    calcSpec();

    //display time it took to calculate the map
    this->lastCalctime_specular = timer.elapsed();
    displayCalcTime(lastCalctime_specular, "specularmap", 5000);

    //preview in specular map tab
    preview(2);
    
    //activate corresponding save checkbox
    ui->checkBox_queue_generateSpec->setChecked(true);
}
TEST_F(TestOptiCluster, calcSpec) {
    long long tp,tn,fp,fn; tp=5000; tn=10000; fp=10; fn=200;
    
    ASSERT_DOUBLE_EQ(0.9990, calcSpec(tp,tn,fp,fn)); //metric value
}