1 /***************************************************************************
2 FITSImage.cpp - FITS Image
4 begin : Thu Jan 22 2004
5 copyright : (C) 2004 by Jasem Mutlaq
6 email : mutlaqja@ikarustech.com
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * Some code fragments were adapted from Peter Kirchgessner's FITS plugin*
17 * See http://members.aol.com/pkirchg for more details. *
18 ***************************************************************************/
22 #include <kmessagebox.h>
23 #include <kfiledialog.h>
28 #include <kapplication.h>
30 #include <ktempfile.h>
31 #include <kimageeffect.h>
33 #include <kprogress.h>
34 #include <kstatusbar.h>
45 #include <netinet/in.h>
47 #include "fitsimage.h"
48 #include "fitsviewer.h"
49 //#include "focusdialog.h"
55 uint replace
; /* replacement for blank/NaN-values */
56 uint use_datamin
;/* Use DATAMIN/MAX-scaling if possible */
57 uint compose
; /* compose images with naxis==3 */
60 static FITSLoadVals plvals
=
62 0, /* Replace with black */
63 0, /* Do autoscale on pixel-values */
64 0 /* Dont compose images */
67 FITSImage::FITSImage(QWidget
* parent
, const char * name
) : QScrollView(parent
, name
), zoomFactor(1.2)
69 viewer
= (FITSViewer
*) parent
;
70 reducedImgBuffer
= NULL
;
73 imgFrame
= new FITSFrame(this, viewport());
77 grayTable
=new QRgb
[256];
78 for (int i
=0;i
<256;i
++)
79 grayTable
[i
]=qRgb(i
,i
,i
);
81 viewport()->setMouseTracking(true);
82 imgFrame
->setMouseTracking(true);
86 FITSImage::~FITSImage()
88 free(reducedImgBuffer
);
92 /*void FITSImage::drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph )
94 //kdDebug() << "in draw contents " << endl;
99 /**Bitblt the image onto the viewer widget */
100 /*void FITSImage::paintEvent (QPaintEvent *ev)
102 //kdDebug() << "in paint event " << endl;
103 //bitBlt(imgFrame, 0, 0, &qpix);
107 void FITSImage::resizeEvent (QResizeEvent */
*ev*/
)
112 void FITSImage::contentsMouseMoveEvent ( QMouseEvent
* e
)
116 bool validPoint
= true;
117 if (!displayImage
) return;
123 if (imgFrame
->x() > 0)
126 if (imgFrame
->y() > 0)
131 //kdDebug() << "X= " << x << " -- Y= " << y << endl;
135 x
/= pow(zoomFactor
, currentZoom
);
136 y
/= pow(zoomFactor
, currentZoom
);
138 else if (currentZoom
< 0)
140 x
*= pow(zoomFactor
, abs((int) currentZoom
));
141 //kdDebug() << "The X power is " << pow(zoomFactor, abs(currentZoom)) << " -- X final = " << x << endl;
142 y
*= pow(zoomFactor
, abs((int) currentZoom
));
145 if (x
< 0 || x
> width
)
148 //kdDebug() << "regular x= " << e->x() << " -- X= " << x << " -- imgFrame->x()= " << imgFrame->x() << " - displayImageWidth= " << viewer->displayImage->width() << endl;
151 if (y
< 0 || y
> height
)
154 // invert the Y since we read FITS buttom up
157 //kdDebug() << " -- X= " << x << " -- Y= " << y << endl;
159 if (viewer
->imgBuffer
== NULL
)
160 kdDebug() << "viewer buffer is NULL " << endl
;
164 viewer
->statusBar()->changeItem(QString("%1 , %2").arg( (int) x
).arg( (int) y
), 0);
165 viewer
->statusBar()->changeItem( KGlobal::locale()->formatNumber( viewer
->imgBuffer
[(int) (y
* width
+ x
)], 3 ), 1 );
166 setCursor(Qt::CrossCursor
);
170 //viewer->statusBar()->changeItem(QString("(X,Y)"), 0);
171 setCursor(Qt::ArrowCursor
);
175 void FITSImage::viewportResizeEvent ( QResizeEvent
* /*e*/)
177 int w
, h
, conW
, conH
, x
, y
;
178 if (!displayImage
) return;
180 w
= viewport()->width();
181 h
= viewport()->height();
183 conW
= (int) (currentWidth
+ 40);
184 conH
= (int) (currentHeight
+ 40);
187 x
= (int) ( (w
- conW
) / 2.);
191 y
= (int) ( (h
- conH
) / 2.);
196 moveChild( imgFrame
, x
, y
);
200 void FITSImage::reLoadTemplateImage()
202 *displayImage
= templateImage
->copy();
205 void FITSImage::saveTemplateImage()
207 templateImage
= new QImage(displayImage
->copy());
210 void FITSImage::destroyTemplateImage()
212 delete (templateImage
);
215 void FITSImage::clearMem()
218 free(reducedImgBuffer
);
219 delete (displayImage
);
220 reducedImgBuffer
= NULL
;
226 int FITSImage::loadFits (const char *filename
)
231 // TODO add KStars options for transformation
232 FITS_PIX_TRANSFORM trans
;
233 register unsigned char *dest
;
234 //register unsigned char *tempBuffer;
240 fp
= fopen (filename
, "rb");
243 KMessageBox::error(0, i18n("Cannot open file for reading"));
248 ifp
= fits_open (filename
, "r");
251 KMessageBox::error(0, i18n("Error during open of FITS file"));
256 KMessageBox::error(0, i18n("FITS file keeps no displayable images"));
261 //displayImage = new QImage();
262 KProgressDialog
fitsProgress(this, 0, i18n("FITS Viewer"), i18n("Loading FITS..."));
264 hdl
= fits_seek_image (ifp
, 1);
265 if (hdl
== NULL
) return (-1);
267 width
= hdl
->naxisn
[0];
268 height
= hdl
->naxisn
[1];
269 currentWidth
= hdl
->naxisn
[0];
270 currentHeight
= hdl
->naxisn
[1];
271 bitpix
= hdl
->bitpix
;
274 imgFrame
->setGeometry(0, 0, width
, height
);
276 data
= (unsigned char *) malloc (height
* width
* sizeof(unsigned char));
277 //tempBuffer = (unsigned char *) malloc (height * width * sizeof(unsigned char));
280 KMessageBox::error(0, i18n("Not enough memory to load FITS."));
284 /* If the transformation from pixel value to */
285 /* data value has been specified, use it */
286 if ( plvals
.use_datamin
287 && hdl
->used
.datamin
&& hdl
->used
.datamax
288 && hdl
->used
.bzero
&& hdl
->used
.bscale
)
290 a
= (hdl
->datamin
- hdl
->bzero
) / hdl
->bscale
;
291 b
= (hdl
->datamax
- hdl
->bzero
) / hdl
->bscale
;
292 if (a
< b
) trans
.pixmin
= a
, trans
.pixmax
= b
;
293 else trans
.pixmin
= b
, trans
.pixmax
= a
;
297 trans
.pixmin
= hdl
->pixmin
;
298 trans
.pixmax
= hdl
->pixmax
;
301 trans
.datamax
= 255.0;
302 trans
.replacement
= plvals
.replace
;
305 //displayImage->create(width, height, 32);
308 currentRect
.setWidth(width
);
309 currentRect
.setHeight(height
);
311 fitsProgress
.progressBar()->setTotalSteps(height
);
312 fitsProgress
.setMinimumWidth(300);
315 delete (displayImage
);
317 displayImage
= new QImage(width
, height
, 8, 256, QImage::IgnoreEndian
);
318 for (int i
=0; i
< 256; i
++)
319 displayImage
->setColor(i
, grayTable
[i
]);
320 //displayImage = new QImage();
321 //displayImage->create(width, height, 32);
324 /* FITS stores images with bottom row first. Therefore we have */
325 /* to fill the image from bottom to top. */
326 dest
= data
+ height
* width
;
328 for (i
= height
- 1; i
>= 0 ; i
--)
332 if (fits_read_pixel (ifp
, hdl
, width
, &trans
, dest
) != width
)
338 //for (j=0; j < width; j++)
341 //displayImage->setPixel(j, i, qRgb(val, val, val));
343 for (j
= 0 ; j
< width
; j
++)
344 displayImage
->setPixel(j
, i
, dest
[j
]);
346 fitsProgress
.progressBar()->setProgress(height
- i
);
349 reducedImgBuffer
= data
;
350 convertImageToPixmap();
351 viewportResizeEvent(NULL
);
354 KMessageBox::error(0, i18n("EOF encountered on reading."));
356 fits_record_list
* FRList
= hdl
->header_record_list
;
357 while (FRList
!= NULL
)
359 viewer
->record
<< QString((char *) FRList
->data
);
360 FRList
= FRList
->next_record
;
362 //memcpy(viewer->record, hdl->header_record_list->data , FITS_RECORD_SIZE);
365 return (err
? -1 : 0);
368 void FITSImage::convertImageToPixmap()
370 qpix
= kpix
.convertToPixmap ( *(displayImage
) );
373 void FITSImage::zoomToCurrent()
376 double cwidth
, cheight
;
378 if (currentZoom
>= 0)
380 cwidth
= ((double) displayImage
->width()) * pow(zoomFactor
, currentZoom
) ;
381 cheight
= ((double) displayImage
->height()) * pow(zoomFactor
, currentZoom
);
385 cwidth
= ((double) displayImage
->width()) / pow(zoomFactor
, abs((int) currentZoom
)) ;
386 cheight
= ((double) displayImage
->height()) / pow(zoomFactor
, abs((int) currentZoom
));
389 if (cwidth
!= displayImage
->width() || cheight
!= displayImage
->height())
391 qpix
= kpix
.convertToPixmap (displayImage
->smoothScale( (int) cwidth
, (int) cheight
));
392 //imgFrame->resize( (int) width, (int) height);
393 viewportResizeEvent (NULL
);
398 qpix
= kpix
.convertToPixmap ( *displayImage
);
405 void FITSImage::fitsZoomIn()
408 viewer
->actionCollection()->action("view_zoom_out")->setEnabled (true);
410 viewer
->actionCollection()->action("view_zoom_in")->setEnabled (false);
412 currentWidth
*= zoomFactor
; //pow(zoomFactor, abs(currentZoom)) ;
413 currentHeight
*= zoomFactor
; //pow(zoomFactor, abs(currentZoom));
415 //kdDebug() << "Current width= " << currentWidth << " -- Current height= " << currentHeight << endl;
417 qpix
= kpix
.convertToPixmap (displayImage
->smoothScale( (int) currentWidth
, (int) currentHeight
));
418 imgFrame
->resize( (int) currentWidth
, (int) currentHeight
);
421 viewportResizeEvent (NULL
);
422 //updateScrollBars();
425 void FITSImage::fitsZoomOut()
428 if (currentZoom
< -5)
429 viewer
->actionCollection()->action("view_zoom_out")->setEnabled (false);
430 viewer
->actionCollection()->action("view_zoom_in")->setEnabled (true);
432 currentWidth
/= zoomFactor
; //pow(zoomFactor, abs(currentZoom));
433 currentHeight
/= zoomFactor
;//pow(zoomFactor, abs(currentZoom));
435 qpix
= kpix
.convertToPixmap (displayImage
->smoothScale( (int) currentWidth
, (int) currentHeight
));
436 imgFrame
->resize( (int) currentWidth
, (int) currentHeight
);
439 viewportResizeEvent (NULL
);
440 //updateScrollBars();
443 void FITSImage::fitsZoomDefault()
446 viewer
->actionCollection()->action("view_zoom_out")->setEnabled (true);
447 viewer
->actionCollection()->action("view_zoom_in")->setEnabled (true);
450 currentWidth
= width
;
451 currentHeight
= height
;
453 qpix
= kpix
.convertToPixmap (*displayImage
);
454 imgFrame
->resize( (int) currentWidth
, (int) currentHeight
);
457 viewportResizeEvent (NULL
);
458 //updateScrollBars();
462 FITSFrame::FITSFrame(FITSImage
* img
, QWidget
* parent
, const char * name
) : QFrame(parent
, name
, Qt::WNoAutoErase
)
465 setPaletteBackgroundColor(image
->viewport()->paletteBackgroundColor());
468 FITSFrame::~FITSFrame() {}
470 void FITSFrame::paintEvent(QPaintEvent
* /*e*/)
473 bitBlt(this, 20, 20, &(image
->qpix
));
474 resize( (int) (image
->currentWidth
+ 40), (int) (image
->currentHeight
+ 40));
480 #include "fitsimage.moc"