1 /** @file displayprojection.cpp
2 @package snark14Display
3 @author Bruno M. Carvalho and Deniz Sarioz
4 licensed under (open-source) QPL v1.0
5 which accompanies this distribution in the file QPL
7 modification: Joanna Klukowska 1/13/2009
8 added choice of grayScale display for plot
9 in addition to color display
12 #include "variables.hpp"
13 #include "verbosity.hpp"
14 #include "displaywidget.hpp"
15 #include "displayprojection.hpp"
17 #include "SnarkDisplay.hpp"
18 #include "line_real_t.hpp"
20 #include "displaylines.hpp"
27 #include <qlineedit.h>
28 #include <qpushbutton.h>
29 #include <qradiobutton.h>
34 #include <qwhatsthis.h>
41 #include <qmessagebox.h>
42 #include <qfiledialog.h>
46 #include <qscrollview.h>
49 #define MIN(a, b) (((a < b) ? (a) : (b)))
52 extern Snarkimage **imageset;
57 * Constructs a displayprojection which is a child of 'parent', with the
58 * name 'name' and widget flags set to 'f'
60 * The dialog will by default be modeless, unless you set 'modal' to
61 * TRUE to construct a modal dialog.
63 displayprojection::displayprojection(QWidget* parent, const char* name, bool modal, WFlags fl, int x, int y)
64 : QDialog(parent, name, modal, fl) {
65 unsigned int i, j, minvalrange, maxvalrange;
69 windowname.sprintf("Sinogram: %s", name);
70 windowname = windowname.simplifyWhiteSpace();
71 imagename.sprintf("%s", name);
72 imagename = imagename.simplifyWhiteSpace();
74 setCaption(windowname);
79 // projfil->readProj(projformat);
81 maxzoom = 2 * maxSizex / prjnum;
82 if (maxzoom <= 1) maxzoom = 2;
83 proj = projfil->getProj();
84 lowthreshold = minval = projfil->getMin();
85 highthreshold = maxval = projfil->getMax();
86 range = highthreshold - lowthreshold;
88 setMinimumSize(QSize(190 + prjnum + 10, 600));
89 resize(190 + prjnum + 10, usrays + 20);
90 // if((10+(usrays*maxzoom)+10)>600)
91 // setMaximumSize( QSize( 190+(prjnum*maxzoom)+10, 10+(usrays*maxzoom)+10 ) );
93 // setMaximumSize( QSize( 190+(prjnum*maxzoom)+10, 600 ) );
95 projection = QImage(prjnum, usrays, 8, 256);
96 for (i = 0; i < 256; i++)
97 projection.setColor(i, qRgb(i, i, i));
98 for (i = 0; i < usrays; i++)
99 for (j = 0; j < prjnum; j++)
100 *(projection.scanLine(i) + j) = (unsigned char) (((proj[j][i] - lowthreshold) / range)*255);
102 disp = QPixmap(prjnum, usrays);
103 convproj = disp.convertFromImage(projection, QPixmap::Auto);
105 displaywidget = new displayWidget(this, "displaywidget");
106 displaywidget->setGeometry(QRect(190, 10, prjnum, usrays));
107 displaywidget->setBackgroundPixmap(disp);
108 //displaywidget->setScaledContents( TRUE );
109 QObject::connect(displaywidget, SIGNAL(clicked(int, int)), this, SLOT(updateClickedPixel(int, int)));
111 maxvalrange = (int) (maxval * 1000);
112 minvalrange = (int) (minval * 1000);
114 zoomlabel = new QLabel(this, "zoomlabel");
115 zoomlabel->setGeometry(QRect(60, 5, 45, 20));
116 zoomlabel->setText(tr("Zoom"));
118 zoomslider = new QSlider(this, "zoomslider");
119 zoomslider->setGeometry(QRect(5, 30, 170, 20));
120 zoomslider->setOrientation(QSlider::Horizontal);
121 zoomslider->setRange(1, maxzoom);
122 zoomslider->setValue(1);
123 zoomslider->setLineStep(1);
124 zoomslider->setPageStep(2);
125 QObject::connect(zoomslider, SIGNAL(valueChanged(int)), this, SLOT(updateZoom()));
128 zoom = new QLineEdit(this, "zoom");
129 zoom->setGeometry(QRect(5, 55, 80, 30));
132 setzoombutton = new QPushButton(this, "setzoombutton");
133 setzoombutton->setGeometry(QRect(90, 50, 90, 40));
134 setzoombutton->setText(tr("Set Value"));
135 QObject::connect(setzoombutton, SIGNAL(clicked()), this, SLOT(updateZoomslider()));
137 globalthresholdbutton = new QRadioButton(this, "globalthresholdbutton");
138 globalthresholdbutton->setGeometry(QRect(10, 100, 160, 25));
139 globalthresholdbutton->setText(tr("Global Thresholds"));
140 globalthresholdbutton->setEnabled(false);
142 differencebutton = new QRadioButton(this, "differencebutton");
143 differencebutton->setGeometry(QRect(10, 135, 160, 25));
144 differencebutton->setText(tr("Difference"));
145 differencebutton->setEnabled(false);
147 intensitybutton = new QRadioButton(this, "intensitybutton");
148 intensitybutton->setGeometry(QRect(10, 170, 160, 25));
149 intensitybutton->setText(tr("Intensity"));
150 QObject::connect(intensitybutton, SIGNAL(clicked()), this, SLOT(intensity()));
152 lowthreshlabel = new QLabel(this, "lowthreshlabel");
153 lowthreshlabel->setGeometry(QRect(30, 205, 110, 20));
154 lowthreshlabel->setText(tr("Low Threshold"));
156 lowthreshslider = new QSlider(this, "Slider4_2");
157 lowthreshslider->setGeometry(QRect(5, 230, 170, 20));
158 lowthreshslider->setOrientation(QSlider::Horizontal);
159 lowthreshslider->setRange(minvalrange, maxvalrange);
160 lowthreshslider->setValue(minvalrange);
161 QObject::connect(lowthreshslider, SIGNAL(valueChanged(int)), this, SLOT(updateLowthresh()));
163 lowthresh = new QLineEdit(this, "lowthresh");
164 lowthresh->setGeometry(QRect(5, 260, 80, 30));
166 sprintf(s, "%7.4f", minval);
167 lowthresh->setText(s);
169 setlowthreshbutton = new QPushButton(this, "setlowthreshbutton");
170 setlowthreshbutton->setGeometry(QRect(90, 255, 90, 40));
171 setlowthreshbutton->setText(tr("Set Value"));
172 QObject::connect(setlowthreshbutton, SIGNAL(clicked()), this, SLOT(updateLowthreshslider()));
174 highthreshlabel = new QLabel(this, "highthreshlabel");
175 highthreshlabel->setGeometry(QRect(30, 300, 115, 20));
176 highthreshlabel->setText(tr("High Threshold"));
178 highthreshslider = new QSlider(this, "Slider4_3");
179 highthreshslider->setGeometry(QRect(5, 325, 170, 20));
180 highthreshslider->setOrientation(QSlider::Horizontal);
181 highthreshslider->setRange(minvalrange, maxvalrange);
182 highthreshslider->setValue(maxvalrange);
183 QObject::connect(highthreshslider, SIGNAL(valueChanged(int)), this, SLOT(updateHighthresh()));
185 highthresh = new QLineEdit(this, "highthresh");
186 highthresh->setGeometry(QRect(5, 355, 80, 30));
187 sprintf(s, "%7.4f", maxval);
188 highthresh->setText(s);
190 sethighthreshbutton = new QPushButton(this, "sethighthreshbutton");
191 sethighthreshbutton->setGeometry(QRect(90, 350, 90, 40));
192 sethighthreshbutton->setText(tr("Set Value"));
193 QObject::connect(sethighthreshbutton, SIGNAL(clicked()), this, SLOT(updateHighthreshslider()));
195 pixelposlabel = new QLabel(this, "pixelposlabel");
196 pixelposlabel->setGeometry(QRect(30, 395, 45, 20));
197 pixelposlabel->setText(tr("Pixel"));
199 pixelpos = new QLineEdit(this, "pixelpos");
200 pixelpos->setGeometry(QRect(5, 420, 80, 30));
202 pixelvaluelabel = new QLabel(this, "pixelvaluelabel");
203 pixelvaluelabel->setGeometry(QRect(110, 395, 45, 20));
204 pixelvaluelabel->setText(tr("Value"));
206 pixelvalue = new QLineEdit(this, "pixelvalue");
207 pixelvalue->setGeometry(QRect(95, 420, 80, 30));
209 savebutton = new QPushButton(this, "savebutton");
210 savebutton->setGeometry(QRect(15, 460, 150, 40));
211 savebutton->setText(tr("Save Image"));
212 QObject::connect(savebutton, SIGNAL(clicked()), this, SLOT(saveImage()));
214 linesbutton = new QPushButton(this, "linesbutton");
215 linesbutton->setGeometry(QRect(15, 505, 150, 40));
216 linesbutton->setText(tr("Display Lines"));
217 // QObject::connect(linesbutton,SIGNAL(clicked()),this,SLOT(callLines_old()));
218 QObject::connect(linesbutton, SIGNAL(clicked()), this, SLOT(callLines()));
220 closebutton = new QPushButton(this, "closebutton");
221 closebutton->setGeometry(QRect(15, 550, 150, 40));
222 closebutton->setText(tr("Close Window"));
223 QObject::connect(closebutton, SIGNAL(clicked()), this, SLOT(accept()));
225 scrollv = new QScrollView(this, "qscrollview");
226 scrollv->viewport()->setBackgroundColor(colorGroup().background());
227 scrollv->setFrameShape(QFrame::NoFrame);
228 scrollv->setGeometry(190, 10, maxSizex - 210, maxSizey - 110);
229 scrollv->addChild(displaywidget);
232 void displayprojection::resetscroll() {
233 scrollv->resize(MIN(maxSizex - 210, 20 + (prjnum * zoomval)),
234 MIN(maxSizey - 110, 20 + (usrays * zoomval)));
235 scrollv->resizeContents(prjnum * zoomval + 10, usrays * zoomval + 10);
239 * Destroys the object and frees any allocated resources
241 displayprojection::~displayprojection() {
242 // no need to delete child widgets, Qt does it all for us
245 void displayprojection::updateClickedPixel(int cx, int cy) {
251 sprintf(s, "(%d,%d)", ix, iy);
252 pixelpos->setText(s);
253 sprintf(s, "%7.4f", proj[ix][iy]);
254 pixelvalue->setText(s);
257 void displayprojection::updateZoom() {
259 int v = zoomslider->value();
263 displaywidget->resize(prjnum*zoomval, usrays * zoomval);
264 resize(MIN(maxSizex, 210 + (prjnum * zoomval)),
265 MIN(maxSizey, 20 + (usrays * zoomval)));
270 void displayprojection::updateZoomslider() {
273 v = zoom->text().toInt(&ok, 10);
274 if (ok && v > 0 && v <= maxzoom)
275 zoomslider->setValue(v);
277 QMessageBox::information(this, "SnarkDisplay", "Error!\n"
278 "Zoom value invalid or out of range.");
281 void displayprojection::intensity() {
284 l = windowname.length();
285 if (intensitybutton->isChecked()) {
286 windowname.append("_i");
287 setCaption(windowname);
289 windowname.remove(l - 2, 2);
290 setCaption(windowname);
295 /** obtain threshold value from the low threshold slider position
296 update the text of the slider
297 pre: low threshold slider not greater than high threshold slider
300 void displayprojection::updateLowthresh() {
302 int v = lowthreshslider->value();
303 int hv = highthreshslider->value();
306 lowthreshslider->setValue(hv);
308 double fv = ((double) v) / 1000;
310 sprintf(s, "%7.4f", fv);
311 lowthresh->setText(s);
315 double displayprojection::getLowthresh() {
319 void displayprojection::updateLowthreshslider() {
323 fv = lowthresh->text().toDouble(&ok);
325 if (fv > highthreshold) {
326 QMessageBox::information(this, "SnarkDisplay", "Error!\n"
327 "Entered low threshold higher than high threshold.");
331 v = (int) (fv * 1000 + 0.5);
333 v = (int) (fv * 1000 - 0.5);
334 if (v < lowthreshslider->minValue())
335 lowthreshslider->setMinValue(v);
336 lowthreshslider->setValue(v);
341 /** have fixed this */
342 void displayprojection::updateHighthresh() {
344 int v = highthreshslider->value();
345 int Lv = lowthreshslider->value();
348 highthreshslider->setValue(Lv);
350 double fv = ((double) v) / 1000;
352 sprintf(s, "%7.4f", fv);
353 highthresh->setText(s);
357 double displayprojection::getHighthresh() {
358 return highthreshold;
361 void displayprojection::updateHighthreshslider() {
365 fv = highthresh->text().toDouble(&ok);
367 if (fv < lowthreshold) {
368 QMessageBox::information(this, "SnarkDisplay", "Error!\n"
369 "Entered high threshold lower than low threshold.");
373 v = (int) (fv * 1000 + 0.5);
375 v = (int) (fv * 1000 - 0.5);
376 if (v > highthreshslider->maxValue())
377 highthreshslider->setMaxValue(v);
378 highthreshslider->setValue(v);
381 } // --displayprojection::updateHighthreshslider()
383 void displayprojection::resetImage() {
384 /* adjust image to current thresholds and zoom */
386 int m, n, base, point;
391 // if((20+(usrays*zoomval)+1)>530)
392 // resize(190+(prjnum*zoomval)+10, 20+(usrays*zoomval)+10);
394 // resize(190+(prjnum*zoomval)+10, 530);
396 projection = projection.smoothScale(prjnum*zoomval, usrays * zoomval);
397 projection.setNumColors(256);
398 for (i = 0; i < 256; i++)
399 projection.setColor(i, qRgb(i, i, i));
400 range = highthreshold - lowthreshold;
402 for (i = 0; i < usrays; i++) {
404 for (j = 0; j < prjnum; j++) {
406 t = ((proj[j][i] - lowthreshold) / range);
407 if (t == 0.0 || t < 0.0) {
408 for (m = 0; m < zoomval; m++)
409 for (n = 0; n < zoomval; n++)
410 *(projection.scanLine(base + m) + point + n) = 0;
412 if (t > 1.0 || t == 1.0) {
413 for (m = 0; m < zoomval; m++)
414 for (n = 0; n < zoomval; n++)
415 *(projection.scanLine(base + m) + point + n) = 255;
417 if (intensitybutton->isChecked()) {
418 tuc = (unsigned char) (sqrt(t)*255);
419 for (m = 0; m < zoomval; m++)
420 for (n = 0; n < zoomval; n++) {
421 *(projection.scanLine(base + m) + point + n) = tuc;
424 tuc = (unsigned char) (t * 255);
425 for (m = 0; m < zoomval; m++)
426 for (n = 0; n < zoomval; n++) {
427 *(projection.scanLine(base + m) + point + n) = tuc;
434 convproj = disp.convertFromImage(projection, QPixmap::Auto);
435 // displaywidget->resize(prjnum*zoomval,usrays*zoomval);
436 displaywidget->setBackgroundPixmap(disp);
438 } // --displayprojection::resetImage()
440 void displayprojection::resetImageRange() {
441 /* adjust image to current thresholds */
446 range = highthreshold - lowthreshold;
448 for (i = 0; i < usrays; i++)
449 for (j = 0; j < prjnum; j++) {
450 t = ((proj[i][j] - lowthreshold) / range);
452 *(projection.scanLine(i) + j) = 0;
455 *(projection.scanLine(i) + j) = 255;
457 *(projection.scanLine(i) + j) = (unsigned char) (t * 255);
459 convproj = disp.convertFromImage(projection, QPixmap::Auto);
460 displaywidget->setBackgroundPixmap(disp);
461 } // --displayprojection::resetImageRange()
463 /** Starts a lines window
465 @author Bruno M. Carvalho
467 void displayprojection::callLines() {
469 // unsigned int l[4];
470 int l[4], linetype, c, x, y, sx = 400, sy = 300, xn, yn;
471 int a1, minx, maxx, xrange;
472 int topleftx, toplefty;
473 double miny, maxy, yrange, t1, t2, a2;
474 bool above = false, below = false;
476 QString title, xaxis, yaxis, temp, profilename;
478 QString projname_qstr(projname);
479 projname_qstr = projname_qstr.simplifyWhiteSpace();
480 lineswindow* nw = new lineswindow(this, projname_qstr, lowthreshold, highthreshold, true, 0);
482 if (c == QDialog::Accepted) {
483 linetype = nw->getLinetype();
484 QString rowOrColumn = ((linetype) ? ("Column ") : ("Row "));
485 QString vs = ((linetype) ? ("Rows") : ("Columns"));
486 // std::cerr << "Plotting " << rowOrColumn << "vs " << vs << std::endl;
487 // std::cerr << "There are " << prjnum << " columns and " << usrays << " rows" << std::endl;
488 int i_upperbnd = static_cast<int> ((linetype) ? (usrays) : (prjnum));
489 int elljay_upperbnd = static_cast<int> ((linetype) ? (prjnum) : (usrays));
490 // std::cerr << i_upperbnd << " is upperbound of independent" << std::endl;
491 l[0] = nw->getLine1();
492 l[1] = nw->getLine2();
493 l[2] = nw->getLine3();
494 l[3] = nw->getLine4();
495 title = nw->getTitle();
496 xaxis = nw->getXAxis();
497 yaxis = nw->getYAxis();
498 minx = nw->getMinX();
499 maxx = nw->getMaxX();
500 miny = nw->getMinY();
501 maxy = nw->getMaxY();
502 topleft = this->pos();
503 topleftx = topleft.x();
504 toplefty = topleft.y();
505 for (j = 0; j < 4; j++) { // loop through selection
506 int&row = ((linetype) ? (i) : (l[j]));
507 int&col = ((linetype) ? (l[j]) : (i));
508 if ((l[j] >= 0) && (l[j] < elljay_upperbnd)) { // different plot for each valid j
509 line_real_set_t myLRS(minx, maxx, miny, maxy); // create a brand new LRS for brand new plot
510 myLRS.clear(); // and be sure of it!
513 QPixmap* pixmap = new QPixmap(sd_line_t::WIDTH, sd_line_t::HEIGHT);
514 pixmap->fill(Qt::white);
516 picasso.begin(pixmap);
517 picasso.setBackgroundColor(Qt::white);
518 QString whichRowOrCol;
519 whichRowOrCol.setNum(l[j]);
520 QString plotSuffix = (rowOrColumn + whichRowOrCol);
521 //QString plotName = projname_qstr.simplifyWhiteSpace();
522 QString plotName = title.simplifyWhiteSpace(); // bug 227, wei, 6/13/2007
523 plotName += (" (sinogram):: " + plotSuffix);
524 // std::cerr << "plotName : " << plotName << std::endl;
525 line_real_t ourProjLine(projname_qstr);
526 for (i = 0; i < i_upperbnd; i++) {
527 ourProjLine.add(i, proj[col][row]);
529 myLRS.add(ourProjLine);
530 plot_t myPlot(myLRS);
531 myPlot.setName(plotName);
532 myPlot.setXAxisName(xaxis); // for all three of these names
533 myPlot.setYAxisName(yaxis);
534 // jk 1/13/2009 adding grayScale option for graphs
535 if (nw->isGrayScaleChecked()) { // picasso paints on QPixmap pointed to by pmp
536 myPlot.plotGray(picasso);
538 myPlot.plot(picasso);
540 displaylineswindow* dw = new displaylineswindow(this, plotName, pixmap, false, 0, topleftx, toplefty);
542 } // --if on l[j] being ok
543 } // --loop through the j's [0,4)
545 } // --displayprojection::callLines()
547 /** Saves the current image
549 @author Bruno M. Carvalho
551 void displayprojection::saveImage() {
554 QString prefixForSaving = projname;
555 prefixForSaving = prefixForSaving.simplifyWhiteSpace();
556 prefixForSaving.replace(QRegExp("\\="), "_EQ_");
557 prefixForSaving.replace(QRegExp("\\+"), "_PLUS_");
558 prefixForSaving.replace(QRegExp("\\@"), "_AT_");
559 // prefixForSaving.replace( QRegExp("-"), "_MINUS_"); // maybe
560 // convert everything non-alphanumeric to underscore
561 prefixForSaving.replace(QRegExp("[^a-zA-Z0-9]"), "_");
562 // allow maximum of 2 consecutive underscores
563 prefixForSaving.replace(QRegExp("__+"), "__");
564 // chuck underscore from beginning and end
565 prefixForSaving.replace(QRegExp("^_+"), "");
566 prefixForSaving.replace(QRegExp("_+$"), "");
568 QString myExtensionFilter =
571 "flt (ASCII float file);;"
578 QString mySaveAs = "Save Image as";
579 QString startInDir = "./";
580 QFileDialog fd(startInDir, myExtensionFilter, this, mySaveAs, true);
581 fd.setMode(QFileDialog::AnyFile);
582 fd.setSelection(prefixForSaving);
583 if (QDialog::Accepted != fd.exec()) {
584 if (std::verbose >= 2) std::cout << "--displaylineswindow::saveImage() in a hurry" << std::endl;
585 return; // happens, say, when cancel is pressed. just leave, no harm.
587 QString userFileSavePrefix = fd.selectedFile();
588 QString userFileSaveExtension = fd.selectedFilter();
589 if (userFileSavePrefix.isEmpty()) { // double-check for absurdity
590 if (std::verbose >= 2) std::cout << "--displaylineswindow::saveImage() in a hurry" << std::endl;
591 return; // happens, say, when cancel is pressed. just leave, no harm.
593 if (std::verbose >= 2) std::cout << "Got file name as: \"" << userFileSavePrefix << "\"" << std::endl;
594 if (std::verbose >= 2) std::cout << "Got selected ext: \"" << userFileSaveExtension << "\"" << std::endl;
595 /* NB: userFileSavePrefix now contains directory info as well.
596 * if user entered additional forward-slashes without
597 * knowing that it signified directory, that's NOT our problem.
598 * (the user MAY legitimately enter "a/myImage" as file name if there is a directory "a"
599 * within the currently open directory in the save dialog window)
600 * do part only after last forward-slash (i.e., what user entered)...
601 * don't want to burn ourselves if path in fact had legit non-alphanumericounderscore chars
603 QString justFilePrefix, justPath;
604 // funnylooking because written to work with Qt BOTH 2.3 and 3.3
605 int posLastSlash = userFileSavePrefix.findRev('/'); // returns pos if found, -1 if not.
606 if (-1 != posLastSlash) {
607 justPath = userFileSavePrefix.left(posLastSlash + 1); // +1 to include last '/'
608 justFilePrefix = userFileSavePrefix;
609 QRegExp fakeRegex("^" + justPath); // it just *looks* fake...
610 justFilePrefix.replace(fakeRegex, ""); // chuck away including last '/' for justFilePrefix
611 if (std::verbose >= 2) std::cout << "just after regex replace, justFilePrefix: \"" << justFilePrefix << "\"" << std::endl;
612 } else { // if for some reason no forwardslash, handle that gracefully too.
613 justFilePrefix = userFileSavePrefix;
616 if (std::verbose >= 2) std::cout << "justPath is: \"" << justPath << "\"" << std::endl;
617 if (std::verbose >= 2) std::cout << "justFilePrefix is first: \"" << justFilePrefix << "\"" << std::endl;
618 // remove justFilePrefix from ONLY the end of 'userFileSavePrefix'.
619 justFilePrefix.replace(QRegExp("="), "_EQ_");
620 justFilePrefix.replace(QRegExp("+"), "_PLUS_");
621 justFilePrefix.replace(QRegExp("[^a-zA-Z0-9]"), "_"); // no forward slash in regex
622 // allow maximum of 2 consecutive underscores
623 justFilePrefix.replace(QRegExp("__+"), "__");
624 // chuck underscore from beginning and end
625 justFilePrefix.replace(QRegExp("^_+"), "");
626 justFilePrefix.replace(QRegExp("_+$"), "");
627 if (std::verbose >= 2) std::cout << "justFilePrefix is later: \"" << justFilePrefix << "\"" << std::endl;
628 // reset userFileSavePrefix by putting back together justPath and the refined justFilePrefix
629 userFileSavePrefix = justPath + justFilePrefix;
630 userFileSaveExtension.truncate(3);
631 if (std::verbose >= 2) std::cout << "My userFileSavePrefix is \"" << userFileSavePrefix << "\"" << std::endl;
632 if (std::verbose >= 2) std::cout << "My userFileSaveExtension is \"" << userFileSaveExtension << "\"" << std::endl;
633 QString extensionUpper = userFileSaveExtension.upper();
634 QString saveFullNameWithPath = userFileSavePrefix + "." + extensionUpper;
635 if (std::verbose >= 2) std::cout << "extensionUpper is now \"" << extensionUpper << "\"" << std::endl;
636 if (std::verbose >= 2) std::cout << "saveFullNameWithPath is now \"" << saveFullNameWithPath << "\"" << std::endl;
637 if (extensionUpper.compare(QString("FLT"))) { // if NOT "FLT" extension ("FLT" is Bruno's / Linkoping's bunchafloats format)
639 recio.setImage(projection);
640 recio.setFormat(extensionUpper);
641 recio.setFileName(saveFullNameWithPath);
643 if (std::verbose >= 1) {
644 std::cout << "successfully saved: \"" << saveFullNameWithPath << "\"" << std::endl;
648 std::cerr << "Error opening " << saveFullNameWithPath << std::endl;
653 if ((fp = fopen(saveFullNameWithPath.latin1(), "w")) == NULL) {
654 std::cerr << "UNsuccessfully tried to save as: \"" << saveFullNameWithPath << "\"" << std::endl;
656 for (i = 0; i < (static_cast<int> (usrays)); i++) {
657 for (j = 0; j < (static_cast<int> (prjnum)); j++) {
658 fprintf(fp, "%f ", proj[i][j]);
665 if (std::verbose >= 1) {
666 std::cout << "(we think) successfully saved: \"" << saveFullNameWithPath << "\"" << std::endl;