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

KDE's Doxygen guidelines are available online.