1 /** @file displaywindow.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 "displaywindow.hpp"
17 #include "line_real_t.hpp"
19 #include "displaylines.hpp"
26 #include <qfiledialog.h>
30 #include <qlineedit.h>
31 #include <qmessagebox.h>
37 #include <qpushbutton.h>
41 #include <qwhatsthis.h>
44 #include <qscrollview.h>
46 #define EPSILON 0.00000001
49 #define MIN(a, b) (((a < b) ? (a) : (b)))
52 // extern displaywindow **displaywindowset;
53 // QImage rec; // this needs to be an INSTANCE VARIABLE
54 // bool converted; // wouldn't hurt to make this an INSTANCE VARIABLE either (but it's unused??)
57 * Constructs a displaywindow 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 displaywindow::displaywindow( QWidget* parent, const char* name, bool modal, WFlags fl , DIGDataFormat dataformat, int imagenumber, int x, int y )
64 // : QDialog( parent, name, modal, fl )
65 : QWidget(parent, name, fl)
67 // -Qt::WStyle_Customize | Qt::WStyle_NoBorder
68 // std::cerr << "++displaywindow constructor for imagenumber " << imagenumber << std::endl;
71 recp = 0; // initialize
72 // double **phantomimage;
73 double **phantomimage;
76 // displaywindowset[id]=this; // don't need this.
77 setName(imagetitles[id]);
78 imagename=QString(imagetitles[id]);
79 setCaption(imagetitles[id]);
80 // displaywindowactive[id]=true;
85 imageset[imagenumber]->readImage(imagenumber,dataformat);
86 //printf("max=%f min=%f \n",imageset[imagenumber]->getMax(),imageset[imagenumber]->getMin());
87 if(imageset[imagenumber]->getMax() > globalmax) {
88 globalmax=imageset[imagenumber]->getMax();
90 if(imageset[imagenumber]->getMin() < globalmin) {
91 globalmin=imageset[imagenumber]->getMin();
93 maxzoom = 2 * maxSizex / Sizex;
94 if(maxzoom<=1) maxzoom = 2;
95 image = imageset[imagenumber]->getImage();
96 lowthreshold=minval=imageset[imagenumber]->getMin();
97 highthreshold=maxval=imageset[imagenumber]->getMax();
98 range=highthreshold-lowthreshold;
99 Range=highthreshold-lowthreshold;
100 if(phantomexists && id) { // (id) means "image number is not 0" (phantom must be 0)
101 diffimage=(double **)malloc(Sizey*sizeof(double *));
103 std::cerr << "Failed to allocate space for diffimage" << std::endl;
105 for(j=0;j<Sizey;j++) {
106 diffimage[j]=(double *)malloc(Sizex*sizeof(double));
108 std::cerr << "Failed to allocate space for diffimage" << std::endl;
111 if(!imageset[0]->isLoaded()) {
112 imageset[0]->readImage(0,dataformat);
113 if(imageset[0]->getMax()>globalmax)
114 globalmax=imageset[0]->getMax();
115 if(imageset[0]->getMin()<globalmin)
116 globalmin=imageset[0]->getMin();
118 phantomimage=imageset[0]->getImage();
121 for(i=0;i<Sizey;i++) {
122 for(j=0;j<Sizex;j++) {
123 diffimage[i][j]=image[i][j]-phantomimage[i][j];
124 if(diffimage[i][j]>diffmaxval)
125 diffmaxval=diffimage[i][j];
126 if(diffimage[i][j]<diffminval)
127 diffminval=diffimage[i][j];
130 if(diffmaxval > globaldiffmax) globaldiffmax = diffmaxval;
131 if(diffminval < globaldiffmin) globaldiffmin = diffminval;
134 int fudge = 105; // "dynamic" replacement of stuff
136 setMinimumSize(200, 500); // good enough
137 // setMinimumSize( QSize( 190 + MIN(Sizex, maxSizex) +10,
138 // 20 + MIN(Sizey,maxSizey) ) );
139 // resize( QSize( 190+MIN(Sizex, maxSizex),
140 // 20 + MIN(Sizey,maxSizey) ) ); // no point in this
143 std::cerr << "Error: recp already assigned!" << std::endl;
145 recp = new QImage(Sizex,Sizey,8,256);
146 // rec = QImage(Sizex,Sizey,8,256);
147 QImage& rec = (*recp);
149 rec.setColor(i,qRgb(i,i,i));
152 *(rec.scanLine(i)+j)=(unsigned char)(((image[i][j]-lowthreshold)/range)*255);
154 disp = QPixmap(Sizex,Sizey);
155 converted=disp.convertFromImage(rec,QPixmap::Auto);
157 // displaywidget->setGeometry( QRect( 190, 10, Sizex, Sizey ) );
158 displaywidget = new displayWidget( this, "displaywidget" );
159 displaywidget->setBackgroundPixmap( disp );
160 //displaywidget->setScaledContents( TRUE );
161 QObject::connect(displaywidget,SIGNAL(clicked(int,int)),this,SLOT(updateClickedPixel(int,int)));
162 zoomlabel = new QLabel( this, "zoomlabel" );
163 zoomlabel->setGeometry( QRect( 65, 5, 45, 20 ) );
164 zoomlabel->setText( tr( "Zoom" ) );
166 zoomslider = new QSlider( this, "zoomslider" );
167 zoomslider->setGeometry( QRect( 5, 30, 175, 20 ) );
168 zoomslider->setOrientation( QSlider::Horizontal );
169 zoomslider->setRange(1,maxzoom);
170 zoomslider->setValue(1);
171 zoomslider->setLineStep(1);
172 zoomslider->setPageStep(2);
173 QObject::connect(zoomslider,SIGNAL(valueChanged(int)),this,SLOT(updateZoom()));
176 zoom = new QLineEdit( this, "zoom" );
177 zoom->setGeometry( QRect( 5, 55, 90, 30 ) );
180 setzoombutton = new QPushButton( this, "setzoombutton" );
181 setzoombutton->setGeometry( QRect( 95, 50, 90, 40 ) );
182 setzoombutton->setText( "Set Value" );
183 QObject::connect(setzoombutton,SIGNAL(clicked()),this,SLOT(updateZoomslider()));
185 lowthreshlabel = new QLabel( this, "lowthreshlabel" );
186 // lowthreshlabel->setGeometry( QRect( 35, 205, 110, 20 ) );
187 lowthreshlabel->setGeometry( QRect( 35, 205 - fudge, 110, 20 ) );
188 lowthreshlabel->setText( tr( "Low Threshold" ) );
190 lowthreshslider = new QSlider( this, "Slider4_2" );
191 lowthreshslider->setGeometry( QRect( 5, 230 - fudge, 175, 20 ) );
192 lowthreshslider->setOrientation( QSlider::Horizontal );
193 lowthreshslider->setRange(0,1000000000);
194 lowthreshslider->setValue(0);
195 QObject::connect(lowthreshslider,SIGNAL(valueChanged(int)),this,SLOT(updateLowthresh()));
197 lowthresh = new QLineEdit( this, "lowthresh" );
198 lowthresh->setGeometry( QRect( 5, 260 - fudge, 90, 30 ) );
200 sprintf(s,"%10.7f",minval);
201 lowthresh->setText(s);
203 setlowthreshbutton = new QPushButton( this, "setlowthreshbutton" );
204 setlowthreshbutton->setGeometry( QRect( 95, 255 - fudge, 90, 40 ) );
205 setlowthreshbutton->setText( tr( "Set Value" ) );
206 QObject::connect(setlowthreshbutton,SIGNAL(clicked()),this,SLOT(updateLowthreshslider()));
208 highthreshlabel = new QLabel( this, "highthreshlabel" );
209 highthreshlabel->setGeometry( QRect( 35, 300 - fudge, 115, 20 ) );
210 highthreshlabel->setText( tr( "High Threshold" ) );
212 highthreshslider = new QSlider( this, "Slider4_3" );
213 highthreshslider->setGeometry( QRect( 5, 325 -fudge, 175, 20 ) );
214 highthreshslider->setOrientation( QSlider::Horizontal );
215 highthreshslider->setRange(0,1000000000);
216 highthreshslider->setValue(1000000000);
217 QObject::connect(highthreshslider,SIGNAL(valueChanged(int)),this,SLOT(updateHighthresh()));
219 highthresh = new QLineEdit( this, "highthresh" );
220 highthresh->setGeometry( QRect( 5, 355 - fudge, 90, 30 ) );
221 sprintf(s,"%10.7f",maxval);
222 highthresh->setText(s);
224 sethighthreshbutton = new QPushButton( this, "sethighthreshbutton" );
225 sethighthreshbutton->setGeometry( QRect( 95, 350 - fudge , 90, 40 ) );
226 sethighthreshbutton->setText( tr( "Set Value" ) );
227 QObject::connect(sethighthreshbutton,SIGNAL(clicked()),this,SLOT(updateHighthreshslider()));
229 pixelposlabel = new QLabel( this, "pixelposlabel" );
230 pixelposlabel->setGeometry( QRect( 30, 395 - fudge, 45, 20 ) );
231 pixelposlabel->setText( tr( "Pixel" ) );
233 pixelpos = new QLineEdit( this, "pixelpos" );
234 pixelpos->setGeometry( QRect( 5, 420 - fudge, 80, 30 ) );
236 pixelvaluelabel = new QLabel( this, "pixelvaluelabel" );
237 pixelvaluelabel->setGeometry( QRect( 110, 395 - fudge, 45, 20 ) );
238 pixelvaluelabel->setText( tr( "Value" ) );
240 pixelvalue = new QLineEdit( this, "pixelvalue" );
241 pixelvalue->setGeometry( QRect( 90, 420 - fudge, 90, 30 ) );
243 savebutton = new QPushButton( this, "savebutton" );
244 savebutton->setGeometry( QRect( 15, 460 - fudge, 150, 40 ) );
245 savebutton->setText( tr( "Save Image" ) );
246 QObject::connect(savebutton,SIGNAL(clicked()),this,SLOT(saveImage()));
248 linesbutton = new QPushButton( this, "linesbutton" );
249 linesbutton->setGeometry( QRect( 15, 505 - fudge, 150, 40 ) );
250 linesbutton->setText( tr( "Display Lines" ) );
251 QObject::connect(linesbutton,SIGNAL(clicked()),this,SLOT(callLines()));
253 closebutton = new QPushButton( this, "closebutton" );
254 closebutton->setGeometry( QRect( 15, 550 - fudge, 150, 40 ) );
255 closebutton->setText( tr( "Close Window" ) );
256 QObject::connect(closebutton,SIGNAL(clicked()),this,SLOT(closeWindow()));
258 scrollv = new QScrollView(this, "qscrollview", Qt::WStyle_Customize | Qt::WStyle_NoBorder );
259 scrollv->viewport()->setBackgroundColor(colorGroup().background());
260 scrollv->setFrameShape(QFrame::NoFrame);
261 scrollv->setGeometry( 190, 10, maxSizex - 200, maxSizey - 100 );
262 scrollv->addChild(displaywidget);
263 useglobal = usedifference = useintensity = false;
265 // hide(); // don't need, not shown unless show() called
266 } // --displaywindow ctor
271 * Destroys the object and frees any allocated resources
273 displaywindow::~displaywindow()
275 // no need to delete child widgets, Qt does it all for us
276 displaywindowactive[id]=false;
277 // delete displaywindowset[id]; // see if this will work?
278 // displaywindowset[id]= 0; // NULL
279 } // --displaywindow::~displaywindow()
283 /** non-destructive! only hide the window, don't lose any information. */
284 void displaywindow::closeWindow()
286 displaywindowactive[id]=false;
288 } // --displaywindow::closeWindow()
292 /** do the same thing as closing the window, don't self-destruct! */
293 void displaywindow::closeEvent(QCloseEvent * e)
296 } // --displaywindow::closeEvent()
299 void displaywindow::updateClickedPixel(int cx,int cy)
301 if(usedifference && !id) return;
307 //printf("pixel(%d,%d) image[%d][%d]=%f\n",cx,cy,iy,ix,image[iy][ix]);
308 sprintf(s,"(%d,%d)",ix,iy);
309 pixelpos->setText(s);
311 sprintf(s,"%10.7f",diffimage[iy][ix]);
313 sprintf(s,"%10.7f",image[iy][ix]);
314 pixelvalue->setText(s);
315 } // --displaywindow::updateClickedPixel()
319 void displaywindow::updateZoom()
322 int v=zoomslider->value();
327 if(id) resetDiffImage();
329 resize(MIN(maxSizex, 200+(Sizex*zoomval)),
330 MIN(maxSizey, 20+(Sizey*zoomval)));
331 scrollv->resizeContents ( Sizex*zoomval + 10, Sizey*zoomval + 10 );
336 } // --displaywindow::updateZoom()
340 void displaywindow::updateZoomslider()
344 v=zoom->text().toInt(&ok,10);
345 if(ok && v>0 && v<=maxzoom)
346 zoomslider->setValue(v);
348 QMessageBox::information(this,"SnarkDisplay","Error!\n"
349 "Zoom value invalid or out of range.");
351 } // --displaywindow::updateZoomslider()
354 void displaywindow::setGlobal(bool on) {
356 // globalthresholdbutton->setChecked( on );
357 lowthreshlabel->setEnabled(!on);
358 lowthreshslider->setEnabled(!on);
359 lowthresh->setEnabled(!on);
360 setlowthreshbutton->setEnabled(!on);
361 highthreshlabel->setEnabled(!on);
362 highthreshslider->setEnabled(!on);
363 highthresh->setEnabled(!on);
364 sethighthreshbutton->setEnabled(!on);
365 setDifference(usedifference); // hack!!! // we no like mutual recursion without base case
366 } // --displaywindow::setGlobal()
370 void displaywindow::setDifference(bool on) {
372 // differencebutton->setChecked( on );
373 if(usedifference && !id) return;
376 l=imagename.length();
378 imagename.replace(l-3,1,"d");
379 setCaption(imagename);
381 // lowthreshslider->setMinValue((int)(diffminval*1000000000));
382 // lowthreshslider->setValue((int)(diffminval*1000000000));
383 lowthreshslider->setValue(0);
384 highthreshslider->setValue(1000000000);
385 lowthreshold=diffminval;
386 sprintf(s,"%10.7f",lowthreshold);
387 lowthresh->setText(s);
388 // highthreshslider->setMaxValue((int)(diffmaxval*1000000000));
389 // highthreshslider->setValue((int)(diffmaxval*1000000000));
390 highthreshold=diffmaxval;
391 sprintf(s,"%10.7f",highthreshold);
392 highthresh->setText(s);
393 range=diffmaxval-diffminval;
394 Range=diffmaxval-diffminval;
399 imagename.replace(l-3,1,"r");
400 setCaption(imagename);
402 // lowthreshslider->setMinValue((int)(minval*1000000000));
403 // lowthreshslider->setValue((int)(minval*1000000000));
404 lowthreshslider->setValue(0);
405 highthreshslider->setValue(1000000000);
407 sprintf(s,"%10.7f",lowthreshold);
408 lowthresh->setText(s);
409 // highthreshslider->setMaxValue((int)(maxval*1000000000));
410 // highthreshslider->setValue((int)(maxval*1000000000));
411 highthreshold=maxval;
412 sprintf(s,"%10.7f",highthreshold);
413 highthresh->setText(s);
419 } // --displaywindow::setDifference()
423 void displaywindow::setIntensity(bool on) {
425 // intensitybutton->setChecked(on);
427 l=imagename.length();
430 imagename.replace(l-1,1,"i");
432 imagename.append("i");
433 setCaption(imagename);
437 imagename.replace(l-1,1,"a");
439 imagename.remove(l-1,1);
440 setCaption(imagename);
443 if(id) resetDiffImage();
447 } // --displaywindows::setIntensity()
451 bool displaywindow::isGlobalthreshs()
454 } // --displaywindow::isGlobalthreshs()
458 void displaywindow::updateGlobalthreshs()
469 } // --displaywindow::updateGlobalthreshs()
473 void displaywindow::setGlobalthreshs()
475 if(usedifference && !id) return;
480 } // --displaywindow::setGlobalthreshs()
483 /** update lowthreshold (number) and lowthresh (text) based on lowthreshslider */
484 void displaywindow::updateLowthresh()
486 if(id || !usedifference) {
488 int v = lowthreshslider->value();
489 if(v > highthreshslider->value()) { // cap it
490 lowthreshslider->setValue(highthreshslider->value());
491 lowthreshold = highthreshold;
492 lowthresh->setText(highthresh->text());
494 lowthreshold = (((double)v) / 1000000000) * Range + (usedifference ? diffminval : minval);
495 sprintf(s,"%10.7f",lowthreshold);
496 lowthresh->setText(s);
504 } // --displaywindow::updateLowthresh()
508 double displaywindow::getLowthresh()
511 } // --displaywindow::getLowthresh()
514 /** update lowthreshold and low threshold slider pos based on entered lowthresh */
515 void displaywindow::updateLowthreshslider()
517 if(id || !usedifference) {
521 fv=lowthresh->text().toDouble(&ok);
523 if(fv > highthreshold) {
524 QMessageBox::information(this,"SnarkDisplay","Error!\n"
525 "Cannot set low threshold higher than high threshold!");
527 if(fv < (usedifference ? diffminval : minval)) {
528 QMessageBox::information(this,"SnarkDisplay","Error!\n"
529 "Cannot set low threshold that low!");
532 v= (int)(((fv - (usedifference ? diffminval : minval)) / Range) * 1000000000 + 0.5);
534 v= (int)(((fv - (usedifference ? diffminval : minval)) / Range) * 1000000000 - 0.5);
536 lowthreshslider->setValue(v);
547 QMessageBox::information(this,"SnarkDisplay","Error!\n"
548 "Low Threshold value invalid.");
550 char s[12]; // if got here, no good one way or another.
551 sprintf(s,"%10.7f",lowthreshold);
552 lowthresh->setText(s); // old val
553 lowthresh->setFocus();
555 } // --displaywindow::updateLowthreshslider()
558 /** update highthreshold (number) and highthresh (text) based on highthreshslider */
559 void displaywindow::updateHighthresh()
561 if(id || !usedifference) {
563 int v = highthreshslider->value();
564 if(v < lowthreshslider->value()) {
565 highthreshslider->setValue(lowthreshslider->value());
566 highthreshold = lowthreshold;
567 highthresh->setText(lowthresh->text());
569 highthreshold = (((double)v) / 1000000000) * Range + (usedifference ? diffminval : minval);
570 sprintf(s,"%10.7f",highthreshold);
571 highthresh->setText(s);
579 } // --displaywindow::updateHighthresh()
583 double displaywindow::getHighthresh()
585 return highthreshold;
590 void displaywindow::updateHighthreshslider()
592 if(id || !usedifference) {
596 fv=highthresh->text().toDouble(&ok);
598 if(fv < lowthreshold) {
599 QMessageBox::information(this,"SnarkDisplay","Error!\n"
600 "Cannot set high threshold lower than low threshold!");
602 if(fv > (usedifference ? diffmaxval : maxval)) {
603 QMessageBox::information(this,"SnarkDisplay","Error!\n"
604 "Cannot set high threshold that high!");
607 v=(int)(((fv-(usedifference ? diffminval : minval))/Range)*1000000000+0.5);
609 v=(int)(((fv-(usedifference ? diffminval : minval))/Range)*1000000000+0.5);
611 highthreshslider->setValue(v);
622 QMessageBox::information(this,"SnarkDisplay","Error!\n"
623 "High Threshold value invalid.");
625 char s[12]; // if got here, no good one way or another.
626 sprintf(s,"%10.7f",highthreshold);
627 highthresh->setText(s); // old val
628 highthresh->setFocus();
630 } // --displaywindow::updateHighthreshslider()
634 void displaywindow::resetImage()
636 if(id && usedifference) return;
637 double old_lowthreshold = lowthreshold; // hack
638 double old_highthreshold = highthreshold;
639 if(useglobal) { // see if we can get away so easily
640 lowthreshold = lowglobalthresh;
641 highthreshold = highglobalthresh;
643 /* adjust image to current thresholds and zoom */
644 int i,j,m,n,base,point;
648 QImage& rec = (*recp);
649 rec = rec.smoothScale(Sizex*zoomval,Sizey*zoomval);
650 rec.setNumColors(256);
652 rec.setColor(i,qRgb(i,i,i));
653 range=highthreshold-lowthreshold;
654 /* printf("low=%f high=%f range=%f \n",lowthreshold,highthreshold,range); */
656 for(i=0;i<Sizey;i++) {
658 for(j=0;j<Sizex;j++) {
660 t=((image[i][j]-lowthreshold)/range);
661 //printf("t=%f\n",t);
662 if(t==0.0 || t<0.0) {
663 //printf("t=%f\n",t);
664 for(m=0;m<zoomval;m++)
665 for(n=0;n<zoomval;n++)
666 *(rec.scanLine(base+m)+point+n)=0;
669 //printf("t=%f\n",t);
670 if(t>1.0 || t==1.0) {
671 for(m=0;m<zoomval;m++)
672 for(n=0;n<zoomval;n++)
673 *(rec.scanLine(base+m)+point+n)=255;
674 //printf("%d\n",rec.pixelIndex(i,j));
677 //printf("t=%f\n",t);
679 tuc=(unsigned char)(sqrt(t)*255);
680 for(m=0;m<zoomval;m++)
681 for(n=0;n<zoomval;n++) {
682 //printf("tuc=%d\n",tuc);
683 *(rec.scanLine(base+m)+point+n)=tuc;
684 //printf("%d\n",*(rec.scanLine(i)+j));
688 tuc=(unsigned char)(t*255);
689 for(m=0;m<zoomval;m++)
690 for(n=0;n<zoomval;n++) {
691 //printf("tuc=%d\n",tuc);
692 *(rec.scanLine(base+m)+point+n)=tuc;
693 //printf("%d\n",*(rec.scanLine(i)+j));
700 converted=disp.convertFromImage(rec,QPixmap::Auto);
701 displaywidget->resize(Sizex*zoomval,Sizey*zoomval);
702 displaywidget->setBackgroundPixmap( disp );
704 lowthreshold = old_lowthreshold;
705 highthreshold = old_highthreshold;
707 resize(MIN(maxSizex, 200+(Sizex*zoomval)),
708 MIN(maxSizey, 20+(Sizey*zoomval)));
709 scrollv->resizeContents ( Sizex*zoomval + 10, Sizey*zoomval + 10 );
710 } // --displaywindow::resetImage()
714 void displaywindow::resetDiffImage()
716 double old_lowthreshold = lowthreshold; // hack
717 double old_highthreshold = highthreshold;
718 if(useglobal) { // see if we can get away so easily
719 lowthreshold = lowglobalthresh;
720 highthreshold = highglobalthresh;
722 /* adjust image to current thresholds and zoom */
723 int i,j,m,n,base,point;
727 QImage& rec = (*recp);
728 rec = rec.smoothScale(Sizex*zoomval,Sizey*zoomval);
729 rec.setNumColors(256);
731 rec.setColor(i,qRgb(i,i,i));
732 range=highthreshold-lowthreshold;
733 /* printf("low=%f high=%f range=%f \n",lowthreshold,highthreshold,range); */
735 for(i=0;i<Sizey;i++) {
737 for(j=0;j<Sizex;j++) {
739 t=((diffimage[i][j]-lowthreshold)/range);
740 //printf("t=%f\n",t);
741 if(t==0.0 || t<0.0) {
742 //printf("t=%f\n",t);
743 for(m=0;m<zoomval;m++)
744 for(n=0;n<zoomval;n++)
745 *(rec.scanLine(base+m)+point+n)=0;
748 //printf("t=%f\n",t);
749 if(t>1.0 || t==1.0) {
750 for(m=0;m<zoomval;m++)
751 for(n=0;n<zoomval;n++)
752 *(rec.scanLine(base+m)+point+n)=255;
753 //printf("%d\n",rec.pixelIndex(i,j));
756 //printf("t=%f\n",t);
758 tuc=(unsigned char)(sqrt(t)*255);
759 for(m=0;m<zoomval;m++)
760 for(n=0;n<zoomval;n++) {
761 //printf("tuc=%d\n",tuc);
762 *(rec.scanLine(base+m)+point+n)=tuc;
763 //printf("%d\n",*(rec.scanLine(i)+j));
767 tuc=(unsigned char)(t*255);
768 for(m=0;m<zoomval;m++)
769 for(n=0;n<zoomval;n++) {
770 //printf("tuc=%d\n",tuc);
771 *(rec.scanLine(base+m)+point+n)=tuc;
772 //printf("%d\n",*(rec.scanLine(i)+j));
779 converted=disp.convertFromImage(rec,QPixmap::Auto);
780 displaywidget->resize(Sizex*zoomval,Sizey*zoomval);
781 displaywidget->setBackgroundPixmap( disp );
783 lowthreshold = old_lowthreshold;
784 highthreshold = old_highthreshold;
786 resize(MIN(maxSizex, 200+(Sizex*zoomval)),
787 MIN(maxSizey, 20+(Sizey*zoomval)));
788 scrollv->resizeContents ( Sizex*zoomval + 10, Sizey*zoomval + 10 );
789 } // --displaywindow::resetDiffImage()
793 void displaywindow::resetImageRange()
795 /* adjust image to current thresholds */
799 QImage& rec = (*recp);
800 range=highthreshold-lowthreshold;
801 /* printf("low=%f high=%f range=%f \n",lowthreshold,highthreshold,range); */
804 for(j=0;j<Sizex;j++) {
805 t=((image[i][j]-lowthreshold)/range);
807 *(rec.scanLine(i)+j)=0;
810 *(rec.scanLine(i)+j)=255;
812 *(rec.scanLine(i)+j)=(unsigned char)(t*255);
814 converted=disp.convertFromImage(rec,QPixmap::Auto);
815 displaywidget->setBackgroundPixmap( disp );
817 } // --displaywindow::resetImageRange()
821 /** Starts a lines window
823 @author Bruno M. Carvalho for version 1.0, Deniz
825 @description a lot like SnarkDisplay::callLines() defined in SnarkDisplay.cpp
827 void displaywindow::callLines()
830 int linetype,c,i,j,minx,maxx, topleftx,toplefty;
833 QString title,xaxis,yaxis,temp;
835 imagename = imagename.simplifyWhiteSpace();
836 lineswindow* nw = new lineswindow(this,imagename,lowthreshold,highthreshold,true,1);
838 if(c==QDialog::Accepted) {
839 linetype=nw->getLinetype(); // default == 0 == row; 1 == column
840 // '0' means 'show for suchandsuch rows all columns within x-selection' etc
845 title=nw->getTitle(); // bug 227, wei, 6/13/2007
846 xaxis=nw->getXAxis();
847 yaxis=nw->getYAxis();
853 topleftx=topleft.x();
854 toplefty=topleft.y();
855 QString rowOrColumn = ( (linetype) ? ("Column ") : ("Row ") );
856 QString vs = ( (linetype) ? ("Rows") : ("Columns"));
857 // loop through selection
859 if(l[j]>=0 && l[j]<Sizex) {
860 // spawn different plot for each valid j!
861 line_real_set_t myLRS(minx,maxx,miny,maxy); // create a brand new LRS for brand new plot
862 myLRS.clear(); // and be sure of it!
865 QPixmap* pixmap = new QPixmap(sd_line_t::WIDTH, sd_line_t::HEIGHT);
866 pixmap->fill(Qt::white);
868 picasso.begin(pixmap);
869 picasso.setBackgroundColor(Qt::white);
870 QString whichRowOrCol;
871 whichRowOrCol.setNum(l[j]);
872 QString plotSuffix = (rowOrColumn + whichRowOrCol);
873 //QString plotName = imagename.simplifyWhiteSpace();
874 QString plotName = title.simplifyWhiteSpace(); // bug 227, wei, 6/13/2007
875 plotName += (" :: " + plotSuffix);
876 line_real_t ourImageLine(imagename);
877 // references for unification -- have to be initialized right here
878 int&row = ( (linetype) ? (i) : (l[j]) );
879 int&col = ( (linetype) ? (l[j]) : (i) );
881 // now do the stuff for phantom
882 if((nw->isPhantomChecked()) && id) {
883 if(!imageset[0]->isLoaded())
884 imageset[0]->readImage(0,DIGDataFormat_ASCII);
885 img=imageset[0]->getImage();
886 QString phantomName = imagetitles[0];
887 phantomName = phantomName.simplifyWhiteSpace();
888 line_real_t phantomLine(phantomName);
889 for(i=0;i<Sizey;i++) {
890 phantomLine.add(i, img[row][col]);
892 myLRS.add(phantomLine);
896 double **&ourim = ( (usedifference) ? (diffimage) : (image) );
897 for(i=0;i<Sizey;i++) {
898 ourImageLine.add(i,ourim[row][col]);
900 myLRS.add(ourImageLine);
902 plot_t myPlot(myLRS);
903 myPlot.setName(plotName); // actual param has to be be a legitimate QString object
904 myPlot.setXAxisName(xaxis); // for all three of these names
905 myPlot.setYAxisName(yaxis);
906 // jk 1/13/2009 adding grayScale option for graphs
907 if (nw->isGrayScaleChecked()) {
908 myPlot.plotGray(picasso);
911 myPlot.plot(picasso);
913 /* Call display lines with pixmap as one of the arguments */
914 displaylineswindow* dw=new displaylineswindow(this,plotName,pixmap,false,0,topleftx,toplefty);
919 } // --displaywindow::callLines()
923 /** Saves the current image
925 @author Bruno M. Carvalho
927 void displaywindow::saveImage()
930 QString prefixForSaving = imagename;
931 prefixForSaving = prefixForSaving.simplifyWhiteSpace();
932 prefixForSaving.replace( QRegExp("\\="), "_EQ_");
933 prefixForSaving.replace( QRegExp("\\+"), "_PLUS_");
934 prefixForSaving.replace( QRegExp("\\@"), "_AT_");
935 // prefixForSaving.replace( QRegExp("-"), "_MINUS_"); // maybe
936 // convert everything non-alphanumeric to underscore
937 prefixForSaving.replace( QRegExp("[^a-zA-Z0-9]"), "_");
938 // allow maximum of 2 consecutive underscores
939 prefixForSaving.replace( QRegExp("__+") , "__");
940 // chuck underscore from beginning and end
941 prefixForSaving.replace( QRegExp("^_+"), "");
942 prefixForSaving.replace( QRegExp("_+$"), "");
944 QString myExtensionFilter =
947 "flt (ASCII float file);;"
954 QString mySaveAs = "Save Image as";
955 QString startInDir = "./";
956 QFileDialog fd(startInDir, myExtensionFilter, this, mySaveAs, true);
957 fd.setMode(QFileDialog::AnyFile);
958 fd.setSelection(prefixForSaving);
959 if (QDialog::Accepted != fd.exec()) {
960 if(std::verbose >=2) std::cout << "--displaywindow::saveImage() in a hurry" << std::endl;
961 return; // happens, say, when cancel is pressed. just leave, no harm.
963 QString userFileSavePrefix = fd.selectedFile();
964 QString userFileSaveExtension = fd.selectedFilter();
965 if (userFileSavePrefix.isEmpty()) { // double-check for absurdity
966 if(std::verbose >=2) std::cout << "--displaywindow::saveImage() in a hurry" << std::endl;
967 return; // happens, say, when cancel is pressed. just leave, no harm.
969 if(std::verbose >=2) std::cout << "Got file name as: \"" << userFileSavePrefix << "\"" << std::endl;
970 if(std::verbose >=2) std::cout << "Got selected ext: \"" << userFileSaveExtension << "\"" << std::endl;
971 /* NB: userFileSavePrefix now contains directory info as well.
972 * if user entered additional forward-slashes without
973 * knowing that it signified directory, that's NOT our problem.
974 * (the user MAY legitimately enter "a/myImage" as file name if there is a directory "a"
975 * within the currently open directory in the save dialog window)
976 * do part only after last forward-slash (i.e., what user entered)...
977 * don't want to burn ourselves if path in fact had legit non-alphanumericounderscore chars
979 QString justFilePrefix, justPath;
980 // funnylooking because written to work with Qt BOTH 2.3 and 3.3
981 int posLastSlash = userFileSavePrefix.findRev('/'); // returns pos if found, -1 if not.
982 if (-1 != posLastSlash) {
983 justPath = userFileSavePrefix.left(posLastSlash+1); // +1 to include last '/'
984 justFilePrefix = userFileSavePrefix;
985 QRegExp fakeRegex("^" + justPath); // it just *looks* fake...
986 justFilePrefix.replace( fakeRegex, "" ); // chuck away including last '/' for justFilePrefix
987 if(std::verbose >=2) std::cout << "just after regex replace, justFilePrefix: \"" << justFilePrefix << "\"" << std::endl;
988 } else { // if for some reason no forwardslash, handle that gracefully too.
989 justFilePrefix = userFileSavePrefix;
992 if(std::verbose >=2) std::cout << "justPath is: \"" << justPath << "\"" << std::endl;
993 if(std::verbose >=2) std::cout << "justFilePrefix is first: \"" << justFilePrefix << "\"" << std::endl;
994 // remove justFilePrefix from ONLY the end of 'userFileSavePrefix'.
995 justFilePrefix.replace( QRegExp("="), "_EQ_");
996 justFilePrefix.replace( QRegExp("+"), "_PLUS_");
997 justFilePrefix.replace( QRegExp("[^a-zA-Z0-9]"), "_"); // no forward slash in regex
998 // allow maximum of 2 consecutive underscores
999 justFilePrefix.replace( QRegExp("__+") , "__");
1000 // chuck underscore from beginning and end
1001 justFilePrefix.replace( QRegExp("^_+"), "");
1002 justFilePrefix.replace( QRegExp("_+$"), "");
1003 if(std::verbose >=2) std::cout << "justFilePrefix is later: \"" << justFilePrefix << "\"" << std::endl;
1004 // reset userFileSavePrefix by putting back together justPath and the refined justFilePrefix
1005 userFileSavePrefix = justPath + justFilePrefix;
1006 userFileSaveExtension.truncate(3);
1007 if(std::verbose >=2) std::cout << "My userFileSavePrefix is \"" << userFileSavePrefix << "\"" << std::endl;
1008 if(std::verbose >=2) std::cout << "My userFileSaveExtension is \"" << userFileSaveExtension << "\"" << std::endl;
1009 QString extensionUpper = userFileSaveExtension.upper();
1010 QString saveFullNameWithPath = userFileSavePrefix + "." + extensionUpper;
1011 if(std::verbose >=2) std::cout << "extensionUpper is now \"" << extensionUpper << "\"" << std::endl;
1012 if(std::verbose >=2) std::cout << "saveFullNameWithPath is now \"" << saveFullNameWithPath << "\"" << std::endl;
1013 if(extensionUpper.compare(QString("FLT"))) { // if NOT "FLT" extension ("FLT" is Bruno's / Linkoping's bunchafloats format)
1015 QImage& rec = (*recp);
1016 recio.setImage(rec);
1017 recio.setFormat(extensionUpper);
1018 recio.setFileName(saveFullNameWithPath);
1019 if ( recio.write() ) {
1020 if(std::verbose >= 1) {
1021 std::cout << "displaywindow::saveImage() successfully saved: \"" << saveFullNameWithPath << "\"" << std::endl;
1025 std::cerr << "Error opening " << saveFullNameWithPath << std::endl;
1030 if((fp = fopen(saveFullNameWithPath.latin1(),"w"))==NULL) {
1031 std::cerr << "UNsuccessfully tried to save as: \"" << saveFullNameWithPath << "\"" << std::endl;
1034 for(i=0;i<Sizey;i++) {
1035 for(j=0;j<Sizex;j++) {
1036 fprintf(fp,"%f ",image[i][j]);
1043 if(std::verbose>=1) {
1044 std::cout << "(we think) successfully saved: \"" << saveFullNameWithPath << "\"" << std::endl;
1048 } // --displaywindow::saveImage()