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

KDE's Doxygen guidelines are available online.