Kstars

fitsview.h
1/*
2 SPDX-FileCopyrightText: 2003-2017 Jasem Mutlaq <mutlaqja@ikarustech.com>
3 SPDX-FileCopyrightText: 2016-2017 Robert Lancaster <rlancaste@gmail.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#pragma once
9
10#include "fitscommon.h"
11#include "auxiliary/imagemask.h"
12
13#include <config-kstars.h>
14#include "stretch.h"
15
16#ifdef HAVE_DATAVISUALIZATION
17#include "starprofileviewer.h"
18#endif
19
20#include <QFutureWatcher>
21#include <QPixmap>
22#include <QScrollArea>
23#include <QStack>
24#include <QTimer>
25#include <QPointer>
26
27#ifdef WIN32
28// avoid compiler warning when windows.h is included after fitsio.h
29#include <windows.h>
30#endif
31
32#include <fitsio.h>
33
34#include <memory>
35
36class QAction;
37class QEvent;
38class QGestureEvent;
39class QImage;
40class QLabel;
41class QPinchGesture;
42class QResizeEvent;
43class QToolBar;
44
45class FITSData;
46class FITSLabel;
47
48class FITSView : public QScrollArea
49{
51 Q_PROPERTY(bool suspended MEMBER m_Suspended)
52
53 public:
54 explicit FITSView(QWidget *parent = nullptr, FITSMode fitsMode = FITS_NORMAL, FITSScale filterType = FITS_NONE);
55 virtual ~FITSView() override;
56
57 typedef enum {dragCursor, selectCursor, scopeCursor, crosshairCursor } CursorMode;
58
59 /**
60 * @brief loadFITS Loads FITS data and displays it in a FITSView frame
61 * @param inFilename FITS File name
62 * @note If image is successfully, loaded() signal is emitted, otherwise failed() signal is emitted.
63 * Obtain error by calling lastError()
64 */
65 void loadFile(const QString &inFilename);
66
67 /**
68 * @brief loadFITSFromData Takes ownership of the FITSData instance passed in and displays it in a FITSView frame
69 * @param data pointer to FITSData objects
70 */
71 bool loadData(const QSharedPointer<FITSData> &data);
72
73 /**
74 * @brief clearView Reset view to NO IMAGE
75 */
76 void clearData();
77
78 // Save FITS
79 bool saveImage(const QString &newFilename);
80 // Rescale image lineary from image_buffer, fit to window if desired
81 bool rescale(FITSZoom type);
82
83 const QSharedPointer<FITSData> &imageData() const
84 {
85 return m_ImageData;
86 }
87
88 double getCurrentZoom() const
89 {
90 return currentZoom;
91 }
92 const QImage &getDisplayImage() const
93 {
94 return rawImage;
95 }
96 const QPixmap &getDisplayPixmap() const
97 {
98 return displayPixmap;
99 }
100
101 // Tracking square
102 void setTrackingBoxEnabled(bool enable);
103 bool isTrackingBoxEnabled() const
104 {
105 return trackingBoxEnabled;
106 }
107 QPixmap &getTrackingBoxPixmap(uint8_t margin = 0);
108 void setTrackingBox(const QRect &rect);
109 const QRect &getTrackingBox() const
110 {
111 return trackingBox;
112 }
113
114 // last error
115 const QString &lastError() const
116 {
117 return m_LastError;
118 }
119
120 // Overlay
121 virtual void drawOverlay(QPainter *, double scale);
122
123 // Overlay objects
124 void drawStarRingFilter(QPainter *, double scale, ImageRingMask *ringMask);
125 void drawStarCentroid(QPainter *, double scale);
126 void drawClipping(QPainter *);
127 void drawTrackingBox(QPainter *, double scale);
128 void drawMarker(QPainter *, double scale);
129 void drawCrosshair(QPainter *, double scale);
130
131#if !defined(KSTARS_LITE) && defined(HAVE_WCSLIB)
132 void drawEQGrid(QPainter *, double scale);
133 void drawHiPSOverlay(QPainter *painter, double scale);
134#endif
135 void drawObjectNames(QPainter *painter, double scale);
136 void drawPixelGrid(QPainter *painter, double scale);
137 void drawMagnifyingGlass(QPainter *painter, double scale);
138
139 bool isImageStretched();
140 bool isCrosshairShown();
141 bool isClippingShown();
142 bool areObjectsShown();
143 bool isEQGridShown();
144 bool isSelectionRectShown();
145 bool isPixelGridShown();
146 bool isHiPSOverlayShown();
147 bool imageHasWCS();
148
149 // Setup the graphics.
150 void updateFrame(bool now = false);
151
152 // Telescope
153 bool isTelescopeActive();
154 void updateScopeButton();
155 void setScopeButton(QAction *action)
156 {
157 centerTelescopeAction = action;
158 }
159
160 // Events Management
161 void enterEvent(QEvent *event) override;
162 void leaveEvent(QEvent *event) override;
163 CursorMode getCursorMode();
164 void setCursorMode(CursorMode mode);
165 void updateMouseCursor();
166
167 // Zoom related
168 void cleanUpZoom(QPoint viewCenter = QPoint());
169 QPoint getImagePoint(QPoint viewPortPoint);
170 uint16_t zoomedWidth()
171 {
172 return currentWidth;
173 }
174 uint16_t zoomedHeight()
175 {
176 return currentHeight;
177 }
178 double ZoomFactor() const
179 {
180 return m_ZoomFactor;
181 }
182
183 // Star Detection
184 QFuture<bool> findStars(StarAlgorithm algorithm = ALGORITHM_CENTROID, const QRect &searchBox = QRect());
185 void toggleStars(bool enable);
186 void searchStars();
187 void setStarsEnabled(bool enable);
188 void setStarsHFREnabled(bool enable);
189 int filterStars();
190
191 // image masks
192 QSharedPointer<ImageMask> imageMask() { return m_ImageMask; }
193 void setImageMask(ImageMask *mask);
194
195 // FITS Mode
196 void updateMode(FITSMode fmode);
197 FITSMode getMode()
198 {
199 return mode;
200 }
201
202 void setFilter(FITSScale newFilter)
203 {
204 filter = newFilter;
205 }
206
207 void setFirstLoad(bool value);
208
209 void pushFilter(FITSScale value)
210 {
211 filterStack.push(value);
212 }
213 FITSScale popFilter()
214 {
215 return filterStack.pop();
216 }
217
218 CursorMode lastMouseMode { selectCursor };
219 bool isStarProfileShown()
220 {
221 return showStarProfile;
222 }
223 // Floating toolbar
224 void createFloatingToolBar();
225
226 //void setLoadWCSEnabled(bool value);
227
228 // Returns the params set to stretch the image.
229 StretchParams getStretchParams() const
230 {
231 return stretchParams;
232 }
233
234 // Returns true if we're automatically generating stretch parameters.
235 // Note: this is not whether we're stretching, that's controlled by stretchImage.
236 bool getAutoStretch() const
237 {
238 return autoStretch;
239 }
240
241 // Sets the params for stretching. Will also stretch and re-display the image.
242 // This only sets the first channel stretch params. For RGB images, the G&B channel
243 // stretch parameters are a function of the Red input param and the existing RGB params.
244 void setStretchParams(const StretchParams &params);
245
246 // Sets whether to stretch the image or not.
247 // Will also re-display the image if onOff != stretchImage.
248 void setStretch(bool onOff);
249
250 // Automatically generates stretch parameters and use them to re-display the image.
251 void setAutoStretchParams();
252
253 // When sampling is > 1, we will display the image at a lower resolution.
254 // When sampling = 0, reset to the adaptive sampling value
255 void setPreviewSampling(uint8_t value)
256 {
257 if (value == 0)
258 {
259 m_PreviewSampling = m_AdaptiveSampling;
260 m_StretchingInProgress = false;
261 }
262 else
263 {
264 m_PreviewSampling = value * m_AdaptiveSampling;
265 m_StretchingInProgress = true;
266 }
267 }
268
269 // Returns the number of clipped pixels, if that's being computed.
270 int getNumClipped()
271 {
272 return m_NumClipped;
273 }
274
275 QRect getSelectionRegion() const
276 {
277 return selectionRectangleRaw;
278 }
279
280 public slots:
281 void wheelEvent(QWheelEvent *event) override;
282 void resizeEvent(QResizeEvent *event) override;
283 void ZoomIn();
284 void ZoomOut();
285 void ZoomDefault();
286 void ZoomToFit();
287 void updateMagnifyingGlass(int x, int y);
288
289 // Grids
290 void toggleEQGrid();
291 void toggleObjects();
292 void togglePixelGrid();
293 void toggleCrosshair();
294
295 // HiPS
296 void toggleHiPSOverlay();
297
298 //Selection Rectngle
299 void toggleSelectionMode();
300
301 // Stars
302 void toggleStars();
303 void toggleStarProfile();
304 void viewStarProfile();
305
306 void centerTelescope();
307
308 void toggleStretch();
309 void toggleClipping();
310
311 virtual void processPointSelection(int x, int y);
312 virtual void processMarkerSelection(int x, int y);
313
314 void move3DTrackingBox(int x, int y);
315 void resizeTrackingBox(int newSize);
316 void processRectangle(QPoint p1, QPoint p2, bool refreshCenter = false);
317 void processRectangleFixed(int s);
318
319 protected slots:
320 /**
321 * @brief syncWCSState Update toolbar and actions depending on whether WCS is available or not
322 */
323 void syncWCSState();
324
325 bool event(QEvent *event) override;
326 bool gestureEvent(QGestureEvent *event);
327 void pinchTriggered(QPinchGesture *gesture);
328
329 protected:
330 double average();
331 double stddev();
332 void calculateMaxPixel(double min, double max);
333 void initDisplayImage();
334
335 QPointF getPointForGridLabel(QPainter *painter, const QString &str, double scale);
336 bool pointIsInImage(QPointF pt, double scale);
337
338 void loadInFrame();
339
340 double getScale();
341
342 /// selectionRectangleRaw is used to do the calculations, this rectangle remains the same when user changes the zoom
343 QRect selectionRectangleRaw;
344 /// Floating toolbar
345 QToolBar *floatingToolBar { nullptr };
346 /// WCS Future Watcher
347 QFutureWatcher<bool> wcsWatcher;
348 /// FITS Future Watcher
349 QFutureWatcher<bool> fitsWatcher;
350 /// Cross hair
351 QPointF markerCrosshair;
352 /// Pointer to FITSData object
353 QSharedPointer<FITSData> m_ImageData;
354 /// Current zoom level
355 double currentZoom { 0 };
356 // The maximum percent zoom. The value is recalculated in the constructor
357 // based on the amount of physical memory.
358 int zoomMax { 400 };
359 /// Image Buffer if Selection is to be done
360 uint8_t *m_ImageRoiBuffer { nullptr };
361 /// Above buffer size in bytes
362 uint32_t m_ImageRoiBufferSize { 0 };
363
364 private:
365 bool processData();
366 void doStretch(QImage *outputImage);
367 double scaleSize(double size);
368 bool isLargeImage();
369 bool initDisplayPixmap(QImage &image, float space);
370 void updateFrameLargeImage();
371 void updateFrameSmallImage();
372 bool drawHFR(QPainter * painter, const QString &hfr, int x, int y);
373
374 QPointer<QLabel> noImageLabel;
375 QPixmap noImage;
376 QPointer<FITSLabel> m_ImageFrame;
377 QVector<QPointF> eqGridPoints;
378
379 /// Current width due to zoom
380 uint16_t currentWidth { 0 };
381 /// Current height due to zoom
382 uint16_t currentHeight { 0 };
383 /// Image zoom factor
384 const double m_ZoomFactor;
385
386 // Original full-size image
387 QImage rawImage;
388 // Actual pixmap after all the overlays
389 QPixmap displayPixmap;
390
391 bool firstLoad { true };
392 bool markStars { false };
393 bool showStarProfile { false };
394 bool showCrosshair { false };
395 bool showObjects { false };
396 bool showEQGrid { false };
397 bool showPixelGrid { false };
398 bool showHiPSOverlay { false };
399 bool showStarsHFR { false };
400 bool showClipping { false };
401
402 int m_NumClipped { 0 };
403
404 bool showSelectionRect { false };
405
406 // Should the image be displayed in linear (false) or stretched (true).
407 // Initial value controlled by Options::autoStretch.
408 bool stretchImage { false };
409
410 // When stretching, should we automatically compute parameters.
411 // When first displaying, this should be true, but may be set to false
412 // if the user has overridden the automatically set parameters.
413 bool autoStretch { true };
414
415 // Params for stretching image.
416 StretchParams stretchParams;
417
418 // Resolution for display. Sampling=2 means display every other sample.
419 uint8_t m_PreviewSampling { 1 };
420 bool m_StretchingInProgress { false};
421 // Adaptive sampling is based on available RAM
422 uint8_t m_AdaptiveSampling {1};
423
424 // mask for star detection
425 QSharedPointer<ImageMask> m_ImageMask;
426
427 CursorMode cursorMode { selectCursor };
428 bool zooming { false };
429 int zoomTime { 0 };
430 QPoint zoomLocation;
431
432 QString filename;
433 FITSMode mode;
434 FITSScale filter;
435 QString m_LastError;
436 QTimer m_UpdateFrameTimer;
437
438 QStack<FITSScale> filterStack;
439
440 // Tracking box
441 bool trackingBoxEnabled { false };
442 QRect trackingBox;
443 QPixmap trackingBoxPixmap;
444 QPixmap m_HiPSOverlayPixmap;
445
446 // Scope pixmap
447 QPixmap redScopePixmap;
448 // Magenta Scope Pixmap
449 QPixmap magentaScopePixmap;
450
451 QAction *centerTelescopeAction { nullptr };
452 QAction *toggleEQGridAction { nullptr };
453 QAction *toggleObjectsAction { nullptr };
454 QAction *toggleStarsAction { nullptr };
455 QAction *toggleProfileAction { nullptr };
456 QAction *toggleStretchAction { nullptr };
457 QAction *toggleHiPSOverlayAction { nullptr };
458
459 // State for the magnifying glass overlay.
460 int magnifyingGlassX { -1 };
461 int magnifyingGlassY { -1 };
462 bool showMagnifyingGlass { false };
463 bool m_Suspended {false};
464 // Schedule updated when we have changes that adds
465 // information to the view (not just zoom)
466 bool m_QueueUpdate {false};
467
468 QMutex updateMutex;
469
470 //Star Profile Viewer
471#ifdef HAVE_DATAVISUALIZATION
473#endif
474
475 signals:
476 void newStatus(const QString &msg, FITSBar id);
477 void newStretch(const StretchParams &params);
478 void debayerToggled(bool);
479 void wcsToggled(bool);
480 void actionUpdated(const QString &name, bool enable);
481 void trackingStarSelected(int x, int y);
482 void loaded();
483 void updated();
484 void failed(const QString &error);
485 void starProfileWindowClosed();
486 void rectangleUpdated(QRect roi);
487 void setRubberBand(QRect rect);
488 void showRubberBand(bool on = false);
489 void zoomRubberBand(double scale);
490 void mouseOverPixel(int x, int y);
491
492 friend class FITSLabel;
493};
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
QObject * parent() const const
void push(const T &t)
QRegion mask() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.