Commit 362394db authored by Jasem Mutlaq's avatar Jasem Mutlaq
Browse files

Various fixes for KStars Lite

parent 7b5afc70
......@@ -32,7 +32,7 @@ set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH})
if(BUILD_KSTARS_LITE)
find_package(Qt5 5.7 REQUIRED COMPONENTS Gui Qml Quick QuickControls2 Xml Svg Sql Network Positioning)
find_package(Qt5 5.7 REQUIRED COMPONENTS Gui Qml Quick QuickControls2 Xml Svg Sql Network Positioning Concurrent)
else()
find_package(Qt5 5.4 REQUIRED COMPONENTS Gui Qml Quick Xml Sql Svg Network PrintSupport Concurrent)
endif()
......
......@@ -61,8 +61,7 @@ endif(NOT BUILD_KSTARS_LITE)
if (INDI_FOUND)
if(BUILD_KSTARS_LITE)
set (fits_SRCS
fitsviewer/fitsdatalite.cpp
fitsviewer/fitsviewlite.cpp
fitsviewer/fitsdata.cpp
fitsviewer/bayer.c
)
include_directories(${CFITSIO_INCLUDE_DIR})
......@@ -609,6 +608,7 @@ set(kstars_extra_SRCS
auxiliary/kspaths.cpp
auxiliary/QRoundProgressBar.cpp
auxiliary/skyobjectlistmodel.cpp
auxiliary/ksnotification.cpp
time/simclock.cpp
time/kstarsdatetime.cpp
time/timezonerule.cpp
......@@ -880,6 +880,7 @@ if(BUILD_KSTARS_LITE)
Qt5::Quick
Qt5::QuickControls2
Qt5::Positioning
Qt5::Concurrent
${ZLIB_LIBRARIES}
)
if(INDI_FOUND)
......
......@@ -16,7 +16,10 @@
#include <KLocalizedString>
#include "filedownloader.h"
#ifndef KSTARS_LITE
#include "kstars.h"
#endif
FileDownloader::FileDownloader(QObject *parent) : QObject(parent)
{
......@@ -129,6 +132,7 @@ bool FileDownloader::setDownloadedFileURL(const QUrl &DownloadedFile)
void FileDownloader::setDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
#ifndef KSTARS_LITE
if (m_ShowProgressDialog)
{
if (progressDialog == NULL)
......@@ -146,6 +150,7 @@ void FileDownloader::setDownloadProgress(qint64 bytesReceived, qint64 bytesTotal
progressDialog->setMaximum(bytesTotal);
progressDialog->setValue(bytesReceived);
}
#endif
}
QByteArray FileDownloader::downloadedData() const
......
......@@ -65,7 +65,10 @@ private:
// Optional Progress dialog
bool m_ShowProgressDialog = false;
#ifndef KSTARS_LITE
QProgressDialog* progressDialog = NULL;
#endif
bool isCancelled = false;
QString label, title;
};
......
This diff is collapsed.
/***************************************************************************
fitsdatalite.h - FITS Image
-------------------
begin : Fri Jul 22 2016
copyright : (C) 2016 by Jasem Mutlaq and Artem Fedoskin
email : mutlaqja@ikarustech.com, afedoskin3@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* Some code fragments were adapted from Peter Kirchgessner's FITS plugin*
* See http://members.aol.com/pkirchg for more details. *
***************************************************************************/
#ifndef FITSDATALITE_H_
#define FITSDATALITE_H_
#ifdef WIN32
// avoid compiler warning when windows.h is included after fitsio.h
#include <windows.h>
#endif
#include <fitsio.h>
#include "fitscommon.h"
#include <QRectF>
#include "skypoint.h"
#include "dms.h"
#include "bayer.h"
#define INITIAL_W 640
#define INITIAL_H 480
#define MINIMUM_PIXEL_RANGE 5
#define MINIMUM_STDVAR 5
typedef struct
{
double ra;
double dec;
} wcs_point;
class Edge
{
public:
float x;
float y;
int val;
int scanned;
float width;
float HFR;
float sum;
};
class FITSDataLite
{
public:
typedef enum { CHANNEL_ONE, CHANNEL_TWO, CHANNEL_THREE } ColorChannel;
FITSDataLite(FITSMode mode=FITS_NORMAL);
~FITSDataLite();
/* Loads FITS image, scales it, and displays it in the GUI */
bool loadFITS(const QString &filename, bool silent=true);
/* Save FITS */
int saveFITS(const QString &filename);
/* Rescale image lineary from image_buffer, fit to window if desired */
int rescale(FITSZoom type);
/* Calculate stats */
void calculateStats(bool refresh=false);
/* Calculate running average & standard deviation using Welford’s method for computing variance */
void runningAverageStdDev();
// Access functions
//double getValue(float *buffer, int i);
//void setValue(float *buffer, int i, double value);
//double getValue(int i);
//void setValue(int i, float value);
void clearImageBuffers();
void setImageBuffer(float *buffer);
float * getImageBuffer();
// Stats
int getDataType() { return data_type; }
unsigned int getSize() { return stats.samples_per_channel; }
void getDimensions(double *w, double *h) { *w = stats.width; *h = stats.height; }
void setWidth(long w) { stats.width = w;}
void setHeight(long h) { stats.height = h;}
long getWidth() { return stats.width; }
long getHeight() { return stats.height; }
// Statistics
int getNumOfChannels() { return channels;}
void setMinMax(double newMin, double newMax, uint8_t channel=0);
void getMinMax(double *min, double *max,uint8_t channel=0) { *min = stats.min[channel]; *max = stats.max[channel]; }
double getMin(uint8_t channel=0) { return stats.min[channel]; }
double getMax(uint8_t channel=0) { return stats.max[channel]; }
void setStdDev(double value, uint8_t channel=0) { stats.stddev[channel] = value;}
double getStdDev(uint8_t channel=0) { return stats.stddev[channel]; }
void setMean(double value, uint8_t channel=0) { stats.mean[channel] = value; }
double getMean(uint8_t channel=0) { return stats.mean[channel]; }
void setMedian(double val, uint8_t channel=0) { stats.median[channel] = val;}
double getMedian(uint8_t channel=0) { return stats.median[channel];}
void setSNR(double val) { stats.SNR = val;}
double getSNR() { return stats.SNR;}
void setBPP(int value) { stats.bitpix = value;}
int getBPP() { return stats.bitpix; }
double getADU();
// Star detection
int getDetectedStars() { return starCenters.count(); }
bool areStarsSearched() { return starsSearched; }
QList<Edge*> getStarCenters() { return starCenters;}
int findStars(const QRectF &boundary = QRectF(), bool force=false);
void getCenterSelection(int *x, int *y);
// Half Flux Radius
Edge * getMaxHFRStar() { return maxHFRStar;}
double getHFR(HFRType type=HFR_AVERAGE);
double getHFR(int x, int y);
// FITS Mode (Normal, Guide, Focus..etc).
FITSMode getMode() { return mode;}
// WCS
bool hasWCS() { return HasWCS; }
wcs_point *getWCSCoord() { return wcs_coord; }
// Debayer
bool hasDebayer() { return HasDebayer; }
bool debayer();
void getBayerParams(BayerParams *param);
void setBayerParams(BayerParams *param);
// FITS Record
int getFITSRecord(QString &recordList, int &nkeys);
// Histogram
//void setHistogram(FITSHistogram *inHistogram) { histogram = inHistogram; }
// Filter
void applyFilter(FITSScale type, float *image=NULL, float min=-1, float max=-1);
// Rotation counter. We keep count to rotate WCS keywords on save
int getRotCounter() const;
void setRotCounter(int value);
// Horizontal flip counter. We keep count to rotate WCS keywords on save
int getFlipHCounter() const;
void setFlipHCounter(int value);
// Horizontal flip counter. We keep count to rotate WCS keywords on save
int getFlipVCounter() const;
void setFlipVCounter(int value);
// Dark frame
float *getDarkFrame() const;
void setDarkFrame(float *value);
void subtract(float *darkFrame);
/* stats struct to hold statisical data about the FITS data */
struct
{
double min[3], max[3];
double mean[3];
double stddev[3];
double median[3];
double SNR;
int bitpix;
int ndim;
uint32_t samples_per_channel;
uint16_t width;
uint16_t height;
} stats;
private:
bool rotFITS (int rotate, int mirror);
void rotWCSFITS (int angle, int mirror);
bool checkCollision(Edge* s1, Edge*s2);
int calculateMinMax(bool refresh=false);
void checkWCS();
bool checkDebayer();
void readWCSKeys();
fitsfile* fptr; // Pointer to CFITSIO FITS file struct
int data_type; // FITS image data type
int channels; // Number of channels
float *image_buffer; // Current image buffer
float *darkFrame; // Optional dark frame pointer
bool tempFile; // Is this a tempoprary file or one loaded from disk?
bool starsSearched; // Did we search for stars yet?
bool HasWCS; // Do we have WCS keywords in this FITS data?
bool markStars; // Do we need to mark stars for the user?
bool HasDebayer; // Is the image debayarable?
QString filename; // Our very own file name
FITSMode mode; // FITS Mode (Normal, WCS, Guide, Focus..etc)
int rotCounter; // How many times the image was rotated? Useful for WCS keywords rotation on save.
int flipHCounter; // How many times the image was flipped horizontally?
int flipVCounter; // How many times the image was flipped vertically?
wcs_point *wcs_coord; // Pointer to WCS coordinate data, if any.
QList<Edge*> starCenters; // All the stars we detected, if any.
Edge* maxHFRStar; // The biggest fattest star in the image.
float *bayer_buffer; // Bayer buffer
BayerParams debayerParams; // Bayer parameters
};
#endif
/***************************************************************************
FITSViewLite.cpp - FITS Image
-------------------
begin : Fri Jul 22 2016
copyright : (C) 2016 by Jasem Mutlaq and Artem Fedoskin
email : mutlaqja@ikarustech.com, afedoskin3@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* Some code fragments were adapted from Peter Kirchgessner's FITS plugin*
* See http://members.aol.com/pkirchg for more details. *
***************************************************************************/
#include <config-kstars.h>
#include <cmath>
#include <cstdlib>
#include <KLocalizedString>
#include "fitsviewlite.h"
#include "kstarsdata.h"
#include "ksutils.h"
#include "Options.h"
#include <basedevice.h>
#include "indi/indilistener.h"
#include "indi/indistd.h"
#include "indi/driverinfo.h"
#include <QImage>
#define ZOOM_DEFAULT 100.0
#define ZOOM_MIN 10
#define ZOOM_MAX 400
#define ZOOM_LOW_INCR 10
#define ZOOM_HIGH_INCR 50
#define DECAY_CONSTANT -0.04
FITSViewLite::FITSViewLite(FITSMode fitsMode, FITSScale filterType) :zoomFactor(1.2)
{
image_data = NULL;
display_image = NULL;
firstLoad = true;
gammaValue=0;
filter = filterType;
mode = fitsMode;
markerCrosshair.setX(0);
markerCrosshair.setY(0);
currentZoom = 0.0;
markStars = false;
}
FITSViewLite::~FITSViewLite()
{
delete(image_data);
delete(display_image);
}
QImage *FITSViewLite::loadFITS (const QString &inFilename , bool silent)
{
bool setBayerParams=false;
BayerParams param;
if (image_data && image_data->hasDebayer())
{
setBayerParams=true;
image_data->getBayerParams(&param);
}
delete (image_data);
image_data = NULL;
image_data = new FITSDataLite(mode);
if (setBayerParams)
image_data->setBayerParams(&param);
if (mode == FITS_NORMAL)
{
/*fitsProg.setWindowModality(Qt::WindowModal);
fitsProg.setLabelText(i18n("Please hold while loading FITS file..."));
fitsProg.setWindowTitle(i18n("Loading FITS"));
fitsProg.setValue(10);
qApp->processEvents();*/
}
if (image_data->loadFITS(inFilename, silent) == false)
return false;
image_data->getDimensions(&currentWidth, &currentHeight);
image_width = currentWidth;
image_height = currentHeight;
hasWCS = image_data->hasWCS();
maxPixel = image_data->getMax();
minPixel = image_data->getMin();
if (gammaValue != 0 && (filter== FITS_NONE || filter >= FITS_FLIP_H))
{
double maxGammaPixel = maxPixel* (100 * exp(DECAY_CONSTANT * gammaValue))/100.0;
// If calculated maxPixel after gamma is different from image data max pixel, then we apply filter immediately.
image_data->applyFilter(FITS_LINEAR, NULL, minPixel, maxGammaPixel);
}
initDisplayImage();
if(rescale()) {
return display_image;
}
return NULL;
}
int FITSViewLite::saveFITS( const QString &newFilename )
{
return image_data->saveFITS(newFilename);
}
bool FITSViewLite::rescale()
{
double val=0;
double bscale, bzero;
double min, max;
unsigned int size = image_data->getSize();
image_data->getMinMax(&min, &max);
calculateMaxPixel(min, max);
min = minPixel;
max = maxGammaPixel;
if (min == max)
{
display_image->fill(Qt::white);
//emit newStatus(i18n("Image is saturated!"), FITS_MESSAGE);
}
else
{
bscale = 255. / (max - min);
bzero = (-min) * (255. / (max - min));
if (image_height != image_data->getHeight() || image_width != image_data->getWidth())
{
image_width = image_data->getWidth();
image_height = image_data->getHeight();
initDisplayImage();
//if (isVisible())
//emit newStatus(QString("%1x%2").arg(image_width).arg(image_height), FITS_RESOLUTION);
}
currentWidth = display_image->width();
currentHeight = display_image->height();
float *image_buffer = image_data->getImageBuffer();
if (image_data->getNumOfChannels() == 1)
{
/* Fill in pixel values using indexed map, linear scale */
for (int j = 0; j < image_height; j++)
{
unsigned char *scanLine = display_image->scanLine(j);
for (int i = 0; i < image_width; i++)
{
val = image_buffer[j * image_width + i];
if (gammaValue > 0)
val = qBound(minPixel, val, maxGammaPixel);
scanLine[i]= (val * bscale + bzero);
}
}
return true;
}
else
{
double rval=0,gval=0,bval=0;
QRgb value;
/* Fill in pixel values using indexed map, linear scale */
for (int j = 0; j < image_height; j++)
{
QRgb *scanLine = reinterpret_cast<QRgb*>((display_image->scanLine(j)));
for (int i = 0; i < image_width; i++)
{
rval = image_buffer[j * image_width + i];
gval = image_buffer[j * image_width + i + size];
bval = image_buffer[j * image_width + i + size * 2];
if (gammaValue > 0)
{
rval = qBound(minPixel, rval, maxGammaPixel);
gval = qBound(minPixel, gval, maxGammaPixel);
gval = qBound(minPixel, gval, maxGammaPixel);
}
value = qRgb(rval* bscale + bzero, gval* bscale + bzero, bval* bscale + bzero);
//display_image->setPixel(i, j, value);
scanLine[i] = value;
}
}
return true;
}
}
//if (type != ZOOM_KEEP_LEVEL)
//emit newStatus(QString("%1%").arg(currentZoom), FITS_ZOOM);
return false;
}
void FITSViewLite::calculateMaxPixel(double min, double max)
{
minPixel=min;
maxPixel=max;
if (gammaValue == 0)
maxGammaPixel = maxPixel;
else
maxGammaPixel = maxPixel* (100 * exp(DECAY_CONSTANT * gammaValue))/100.0;
}
void FITSViewLite::initDisplayImage()
{
delete (display_image);
display_image = NULL;
if (image_data->getNumOfChannels() == 1)
{
display_image = new QImage(image_width, image_height, QImage::Format_Indexed8);
display_image->setColorCount(256);
for (int i=0; i < 256; i++)
display_image->setColor(i, qRgb(i,i,i));
}
else
{
display_image = new QImage(image_width, image_height, QImage::Format_RGB32);
}
}
/***************************************************************************
fitsviewlite.h - FITS Image
-------------------
begin : Fri Jul 22 2016
copyright : (C) 2016 by Jasem Mutlaq and Artem Fedoskin
email : mutlaqja@ikarustech.com, afedoskin3@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* Some code fragments were adapted from Peter Kirchgessner's FITS plugin*
* See http://members.aol.com/pkirchg for more details. *
***************************************************************************/
#ifndef FITSView_H_
#define FITSView_H_
#ifdef WIN32
// avoid compiler warning when windows.h is included after fitsio.h
#include <windows.h>
#endif
#include "fitsio.h"
#include "fitscommon.h"
#include "dms.h"
#include "fitsdatalite.h"
#define INITIAL_W 640
#define INITIAL_H 480
#define MINIMUM_PIXEL_RANGE 5
#define MINIMUM_STDVAR 5
class FITSView;
class FITSViewLite : public QObject//: public QScrollArea
{
Q_OBJECT
public:
FITSViewLite(FITSMode mode=FITS_NORMAL, FITSScale filter=FITS_NONE);
~FITSViewLite();
/* Loads FITS image, scales it, and displays it in the GUI */
QImage *loadFITS(const QString &filename, bool silent=true);
/* Save FITS */
int saveFITS(const QString &filename);
/* Rescale image lineary from image_buffer, fit to window if desired */
bool rescale();
void setImageData(FITSDataLite *d) { image_data = d; }
// Access functions
FITSDataLite *getImageData() { return image_data; }
double getCurrentZoom() { return currentZoom; }
QImage * getDisplayImage() { return display_image; }
QImage * getImageFromFITS();
int getGammaValue() const;
void setGammaValue(int value);