00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <klocale.h>
00022 #include <kmessagebox.h>
00023 #include <kfiledialog.h>
00024 #include <kaction.h>
00025 #include <kaccel.h>
00026 #include <kdebug.h>
00027 #include <ktoolbar.h>
00028 #include <kapplication.h>
00029 #include <kpixmap.h>
00030 #include <ktempfile.h>
00031 #include <kimageeffect.h>
00032 #include <kmenubar.h>
00033 #include <kprogress.h>
00034 #include <kstatusbar.h>
00035
00036 #include <qfile.h>
00037 #include <qvbox.h>
00038 #include <qcursor.h>
00039 #include <qpixmap.h>
00040 #include <qframe.h>
00041
00042 #include <math.h>
00043 #include <unistd.h>
00044 #include <stdlib.h>
00045 #include <netinet/in.h>
00046
00047 #include "fitsimage.h"
00048 #include "fitsviewer.h"
00049
00050 #include "ksutils.h"
00051
00052
00053 typedef struct
00054 {
00055 uint replace;
00056 uint use_datamin;
00057 uint compose;
00058 } FITSLoadVals;
00059
00060 static FITSLoadVals plvals =
00061 {
00062 0,
00063 0,
00064 0
00065 };
00066
00067 FITSImage::FITSImage(QWidget * parent, const char * name) : QScrollView(parent, name), zoomFactor(1.2)
00068 {
00069 viewer = (FITSViewer *) parent;
00070 reducedImgBuffer = NULL;
00071 displayImage = NULL;
00072
00073 imgFrame = new FITSFrame(this, viewport());
00074 addChild(imgFrame);
00075
00076 currentZoom = 0.0;
00077 grayTable=new QRgb[256];
00078 for (int i=0;i<256;i++)
00079 grayTable[i]=qRgb(i,i,i);
00080
00081 viewport()->setMouseTracking(true);
00082 imgFrame->setMouseTracking(true);
00083
00084 }
00085
00086 FITSImage::~FITSImage()
00087 {
00088 free(reducedImgBuffer);
00089 delete(displayImage);
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00100
00101
00102
00103
00104
00105
00106
00107 void FITSImage::resizeEvent (QResizeEvent *)
00108 {
00109 updateScrollBars();
00110 }
00111
00112 void FITSImage::contentsMouseMoveEvent ( QMouseEvent * e )
00113 {
00114
00115 double x,y;
00116 bool validPoint = true;
00117 if (!displayImage) return;
00118
00119
00120 x = e->x();
00121 y = e->y();
00122
00123 if (imgFrame->x() > 0)
00124 x -= imgFrame->x();
00125
00126 if (imgFrame->y() > 0)
00127 y -= imgFrame->y();
00128
00129 y -= 20;
00130 x -= 20;
00131
00132
00133 if (currentZoom > 0)
00134 {
00135 x /= pow(zoomFactor, currentZoom);
00136 y /= pow(zoomFactor, currentZoom);
00137 }
00138 else if (currentZoom < 0)
00139 {
00140 x *= pow(zoomFactor, abs((int) currentZoom));
00141
00142 y *= pow(zoomFactor, abs((int) currentZoom));
00143 }
00144
00145 if (x < 0 || x > width)
00146 validPoint = false;
00147
00148
00149
00150
00151 if (y < 0 || y > height)
00152 validPoint = false;
00153 else
00154
00155 y = height - y;
00156
00157
00158
00159 if (viewer->imgBuffer == NULL)
00160 kdDebug() << "viewer buffer is NULL " << endl;
00161
00162 if (validPoint)
00163 {
00164 viewer->statusBar()->changeItem(QString("%1 , %2").arg( (int) x).arg( (int) y), 0);
00165 viewer->statusBar()->changeItem( KGlobal::locale()->formatNumber( viewer->imgBuffer[(int) (y * width + x)], 3 ), 1 );
00166 setCursor(Qt::CrossCursor);
00167 }
00168 else
00169 {
00170
00171 setCursor(Qt::ArrowCursor);
00172 }
00173 }
00174
00175 void FITSImage::viewportResizeEvent ( QResizeEvent * )
00176 {
00177 int w, h, conW, conH, x, y;
00178 if (!displayImage) return;
00179
00180 w = viewport()->width();
00181 h = viewport()->height();
00182
00183 conW = (int) (currentWidth + 40);
00184 conH = (int) (currentHeight + 40);
00185
00186 if ( w > conW )
00187 x = (int) ( (w - conW) / 2.);
00188 else
00189 x = 0;
00190 if ( h > conH )
00191 y = (int) ( (h - conH) / 2.);
00192 else
00193 y = 0;
00194
00195
00196 moveChild( imgFrame, x, y );
00197
00198 }
00199
00200 void FITSImage::reLoadTemplateImage()
00201 {
00202 *displayImage = templateImage->copy();
00203 }
00204
00205 void FITSImage::saveTemplateImage()
00206 {
00207 templateImage = new QImage(displayImage->copy());
00208 }
00209
00210 void FITSImage::destroyTemplateImage()
00211 {
00212 delete (templateImage);
00213 }
00214
00215 void FITSImage::clearMem()
00216 {
00217
00218 free(reducedImgBuffer);
00219 delete (displayImage);
00220 reducedImgBuffer = NULL;
00221 displayImage = NULL;
00222
00223 }
00224
00225
00226 int FITSImage::loadFits (const char *filename)
00227 {
00228 FILE *fp;
00229 FITS_FILE *ifp;
00230 FITS_HDU_LIST *hdl;
00231
00232 FITS_PIX_TRANSFORM trans;
00233 register unsigned char *dest;
00234
00235 unsigned char *data;
00236 int i, j;
00237 double a, b;
00238 int err = 0;
00239
00240 fp = fopen (filename, "rb");
00241 if (!fp)
00242 {
00243 KMessageBox::error(0, i18n("Cannot open file for reading"));
00244 return (-1);
00245 }
00246 fclose (fp);
00247
00248 ifp = fits_open (filename, "r");
00249 if (ifp == NULL)
00250 {
00251 KMessageBox::error(0, i18n("Error during open of FITS file"));
00252 return (-1);
00253 }
00254 if (ifp->n_pic <= 0)
00255 {
00256 KMessageBox::error(0, i18n("FITS file keeps no displayable images"));
00257 fits_close (ifp);
00258 return (-1);
00259 }
00260
00261
00262 KProgressDialog fitsProgress(this, 0, i18n("FITS Viewer"), i18n("Loading FITS..."));
00263
00264 hdl = fits_seek_image (ifp, 1);
00265 if (hdl == NULL) return (-1);
00266
00267 width = hdl->naxisn[0];
00268 height = hdl->naxisn[1];
00269 currentWidth = hdl->naxisn[0];
00270 currentHeight = hdl->naxisn[1];
00271 bitpix = hdl->bitpix;
00272 bpp = hdl->bpp;
00273
00274 imgFrame->setGeometry(0, 0, width, height);
00275
00276 data = (unsigned char *) malloc (height * width * sizeof(unsigned char));
00277
00278 if (data == NULL)
00279 {
00280 KMessageBox::error(0, i18n("Not enough memory to load FITS."));
00281 return (-1);
00282 }
00283
00284
00285
00286 if ( plvals.use_datamin
00287 && hdl->used.datamin && hdl->used.datamax
00288 && hdl->used.bzero && hdl->used.bscale)
00289 {
00290 a = (hdl->datamin - hdl->bzero) / hdl->bscale;
00291 b = (hdl->datamax - hdl->bzero) / hdl->bscale;
00292 if (a < b) trans.pixmin = a, trans.pixmax = b;
00293 else trans.pixmin = b, trans.pixmax = a;
00294 }
00295 else
00296 {
00297 trans.pixmin = hdl->pixmin;
00298 trans.pixmax = hdl->pixmax;
00299 }
00300 trans.datamin = 0.0;
00301 trans.datamax = 255.0;
00302 trans.replacement = plvals.replace;
00303 trans.dsttyp = 'c';
00304
00305
00306 currentRect.setX(0);
00307 currentRect.setY(0);
00308 currentRect.setWidth(width);
00309 currentRect.setHeight(height);
00310
00311 fitsProgress.progressBar()->setTotalSteps(height);
00312 fitsProgress.setMinimumWidth(300);
00313 fitsProgress.show();
00314
00315 delete (displayImage);
00316
00317 displayImage = new QImage(width, height, 8, 256, QImage::IgnoreEndian);
00318 for (int i=0; i < 256; i++)
00319 displayImage->setColor(i, grayTable[i]);
00320
00321
00322
00323
00324
00325
00326 dest = data + height * width;
00327
00328 for (i = height - 1; i >= 0 ; i--)
00329 {
00330
00331 dest -= width;
00332 if (fits_read_pixel (ifp, hdl, width, &trans, dest) != width)
00333 {
00334 err = 1;
00335 break;
00336 }
00337
00338
00339
00340
00341
00342
00343 for (j = 0 ; j < width; j++)
00344 displayImage->setPixel(j, i, dest[j]);
00345
00346 fitsProgress.progressBar()->setProgress(height - i);
00347 }
00348
00349 reducedImgBuffer = data;
00350 convertImageToPixmap();
00351 viewportResizeEvent(NULL);
00352
00353 if (err)
00354 KMessageBox::error(0, i18n("EOF encountered on reading."));
00355
00356 fits_record_list * FRList = hdl->header_record_list;
00357 while (FRList != NULL)
00358 {
00359 viewer->record << QString((char *) FRList->data);
00360 FRList = FRList->next_record;
00361 }
00362
00363
00364 fits_close(ifp);
00365 return (err ? -1 : 0);
00366 }
00367
00368 void FITSImage::convertImageToPixmap()
00369 {
00370 qpix = kpix.convertToPixmap ( *(displayImage) );
00371 }
00372
00373 void FITSImage::zoomToCurrent()
00374 {
00375
00376 double cwidth, cheight;
00377
00378 if (currentZoom >= 0)
00379 {
00380 cwidth = ((double) displayImage->width()) * pow(zoomFactor, currentZoom) ;
00381 cheight = ((double) displayImage->height()) * pow(zoomFactor, currentZoom);
00382 }
00383 else
00384 {
00385 cwidth = ((double) displayImage->width()) / pow(zoomFactor, abs((int) currentZoom)) ;
00386 cheight = ((double) displayImage->height()) / pow(zoomFactor, abs((int) currentZoom));
00387 }
00388
00389 if (cwidth != displayImage->width() || cheight != displayImage->height())
00390 {
00391 qpix = kpix.convertToPixmap (displayImage->smoothScale( (int) cwidth, (int) cheight));
00392
00393 viewportResizeEvent (NULL);
00394 imgFrame->update();
00395 }
00396 else
00397 {
00398 qpix = kpix.convertToPixmap ( *displayImage );
00399 imgFrame->update();
00400 }
00401
00402 }
00403
00404
00405 void FITSImage::fitsZoomIn()
00406 {
00407 currentZoom++;
00408 viewer->actionCollection()->action("view_zoom_out")->setEnabled (true);
00409 if (currentZoom > 5)
00410 viewer->actionCollection()->action("view_zoom_in")->setEnabled (false);
00411
00412 currentWidth *= zoomFactor;
00413 currentHeight *= zoomFactor;
00414
00415
00416
00417 qpix = kpix.convertToPixmap (displayImage->smoothScale( (int) currentWidth, (int) currentHeight));
00418 imgFrame->resize( (int) currentWidth, (int) currentHeight);
00419
00420 update();
00421 viewportResizeEvent (NULL);
00422
00423 }
00424
00425 void FITSImage::fitsZoomOut()
00426 {
00427 currentZoom--;
00428 if (currentZoom < -5)
00429 viewer->actionCollection()->action("view_zoom_out")->setEnabled (false);
00430 viewer->actionCollection()->action("view_zoom_in")->setEnabled (true);
00431
00432 currentWidth /= zoomFactor;
00433 currentHeight /= zoomFactor;
00434
00435 qpix = kpix.convertToPixmap (displayImage->smoothScale( (int) currentWidth, (int) currentHeight));
00436 imgFrame->resize( (int) currentWidth, (int) currentHeight);
00437
00438 update();
00439 viewportResizeEvent (NULL);
00440
00441 }
00442
00443 void FITSImage::fitsZoomDefault()
00444 {
00445
00446 viewer->actionCollection()->action("view_zoom_out")->setEnabled (true);
00447 viewer->actionCollection()->action("view_zoom_in")->setEnabled (true);
00448
00449 currentZoom = 0;
00450 currentWidth = width;
00451 currentHeight = height;
00452
00453 qpix = kpix.convertToPixmap (*displayImage);
00454 imgFrame->resize( (int) currentWidth, (int) currentHeight);
00455
00456 update();
00457 viewportResizeEvent (NULL);
00458
00459
00460 }
00461
00462 FITSFrame::FITSFrame(FITSImage * img, QWidget * parent, const char * name) : QFrame(parent, name, Qt::WNoAutoErase)
00463 {
00464 image = img;
00465 setPaletteBackgroundColor(image->viewport()->paletteBackgroundColor());
00466 }
00467
00468 FITSFrame::~FITSFrame() {}
00469
00470 void FITSFrame::paintEvent(QPaintEvent * )
00471 {
00472
00473 bitBlt(this, 20, 20, &(image->qpix));
00474 resize( (int) (image->currentWidth + 40), (int) (image->currentHeight + 40));
00475
00476 }
00477
00478
00479
00480 #include "fitsimage.moc"