• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

fitsimage.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           FITSImage.cpp  -  FITS Image
00003                              -------------------
00004     begin                : Thu Jan 22 2004
00005     copyright            : (C) 2004 by Jasem Mutlaq
00006     email                : mutlaqja@ikarustech.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  *   Some code fragments were adapted from Peter Kirchgessner's FITS plugin*
00017  *   See http://members.aol.com/pkirchg for more details.                  *
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 //#include "focusdialog.h" 
00050 #include "ksutils.h"
00051 
00052 /* Load info */
00053 typedef struct
00054 {
00055   uint replace;    /* replacement for blank/NaN-values */
00056   uint use_datamin;/* Use DATAMIN/MAX-scaling if possible */
00057   uint compose;    /* compose images with naxis==3 */
00058 } FITSLoadVals;
00059 
00060 static FITSLoadVals plvals =
00061 {
00062   0,        /* Replace with black */
00063   0,        /* Do autoscale on pixel-values */
00064   0         /* Dont compose images */
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 /*void FITSImage::drawContents ( QPainter * p, int clipx, int clipy, int clipw, int cliph )
00093 {
00094   //kdDebug() << "in draw contents " << endl;
00095   //imgFrame->update();
00096   
00097 }*/
00098 
00100 /*void FITSImage::paintEvent (QPaintEvent *ev)
00101 {
00102  //kdDebug() << "in paint event " << endl;
00103  //bitBlt(imgFrame, 0, 0, &qpix);
00104 }*/
00105 
00106 /* Resize event */
00107 void FITSImage::resizeEvent (QResizeEvent */*ev*/)
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    //kdDebug() << "X= " << x << " -- Y= " << y << endl;      
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     //kdDebug() << "The X power is " << pow(zoomFactor, abs(currentZoom)) << " -- X final = " << x << endl;
00142     y *= pow(zoomFactor, abs((int) currentZoom));
00143   }
00144   
00145   if (x < 0 || x > width)
00146     validPoint = false;
00147   
00148   //kdDebug() << "regular x= " << e->x() << " -- X= " << x << " -- imgFrame->x()= " << imgFrame->x() << " - displayImageWidth= " << viewer->displayImage->width() << endl;
00149   
00150   
00151   if (y < 0 || y > height)
00152     validPoint = false;
00153   else    
00154   // invert the Y since we read FITS buttom up
00155   y = height - y;
00156   
00157   //kdDebug() << " -- X= " << x << " -- Y= " << y << endl;
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   //viewer->statusBar()->changeItem(QString("(X,Y)"), 0);
00171   setCursor(Qt::ArrowCursor);
00172   }
00173 }
00174 
00175 void FITSImage::viewportResizeEvent ( QResizeEvent * /*e*/)
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     // do new movement
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  // TODO add KStars options for transformation
00232  FITS_PIX_TRANSFORM trans;
00233  register unsigned char *dest; 
00234  //register unsigned char *tempBuffer;
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  //displayImage  = new QImage();
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  //tempBuffer = (unsigned char  *) malloc (height * width * sizeof(unsigned char));
00278  if (data == NULL)
00279  {
00280   KMessageBox::error(0, i18n("Not enough memory to load FITS."));
00281   return (-1);
00282  }
00283  
00284  /* If the transformation from pixel value to */
00285  /* data value has been specified, use it */
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  //displayImage->create(width, height, 32); 
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 //displayImage = new QImage();
00321 //displayImage->create(width, height, 32);
00322 
00323 
00324  /* FITS stores images with bottom row first. Therefore we have */
00325  /* to fill the image from bottom to top. */
00326    dest = data + height * width;
00327    
00328    for (i = height - 1; i >= 0 ; i--)
00329    {
00330      /* Read FITS line */
00331      dest -= width;
00332      if (fits_read_pixel (ifp, hdl, width, &trans, dest) != width)
00333      {
00334        err = 1;
00335        break;
00336      }
00337      
00338      //for (j=0; j < width; j++)
00339      //{
00340        //val = dest[j];
00341        //displayImage->setPixel(j, i, qRgb(val, val, val));
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  //memcpy(viewer->record, hdl->header_record_list->data , FITS_RECORD_SIZE);
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         //imgFrame->resize( (int) width, (int) height);
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; //pow(zoomFactor, abs(currentZoom)) ;
00413    currentHeight *= zoomFactor; //pow(zoomFactor, abs(currentZoom));
00414 
00415    //kdDebug() << "Current width= " << currentWidth << " -- Current height= " << currentHeight << endl;
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    //updateScrollBars();
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; //pow(zoomFactor, abs(currentZoom));
00433   currentHeight /= zoomFactor;//pow(zoomFactor, abs(currentZoom));
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   //updateScrollBars();
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   //updateScrollBars();
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 * /*e*/)
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"

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal