From 38c8e12145038188dfcf1e0aee4e603ad74c0c98 Mon Sep 17 00:00:00 2001 From: Jared Males Date: Sat, 11 Nov 2023 12:46:47 -0700 Subject: [PATCH] debug statements --- src/images/fitsDirectory.cpp | 2 +- src/images/fitsDirectory.hpp | 6 +- src/images/fitsImage.cpp | 2 +- src/images/fitsImage.hpp | 6 +- src/images/mzmqImage.cpp | 54 +- src/images/mzmqImage.hpp | 6 +- src/images/shmimImage.cpp | 32 +- src/images/shmimImage.hpp | 6 +- src/rtimvBase.cpp | 661 +++++++++++++-------- src/rtimvBase.hpp | 348 ++++++----- src/rtimvControlPanel.cpp | 5 +- src/rtimvGraphicsView.cpp | 23 +- src/rtimvGraphicsView.hpp | 18 +- src/rtimvImage.hpp | 25 + src/rtimvInterfaces.hpp | 19 + src/rtimvMainWindow.cpp | 1084 ++++++++++++++++++++++------------ src/rtimvMainWindow.hpp | 38 +- src/rtimvStats.cpp | 9 +- 18 files changed, 1511 insertions(+), 833 deletions(-) diff --git a/src/images/fitsDirectory.cpp b/src/images/fitsDirectory.cpp index 707b63b..1ec6442 100644 --- a/src/images/fitsDirectory.cpp +++ b/src/images/fitsDirectory.cpp @@ -5,7 +5,7 @@ #include #include -fitsDirectory::fitsDirectory() +fitsDirectory::fitsDirectory(std::mutex * mut) : rtimvImage(mut) { connect(&m_timer, SIGNAL(timeout()), this, SLOT(imageTimerout())); diff --git a/src/images/fitsDirectory.hpp b/src/images/fitsDirectory.hpp index 907c03c..c774926 100644 --- a/src/images/fitsDirectory.hpp +++ b/src/images/fitsDirectory.hpp @@ -59,8 +59,10 @@ struct fitsDirectory : public rtimvImage public: - ///Default c'tor - fitsDirectory(); + fitsDirectory() = delete; + + ///Only c'tor + fitsDirectory(std::mutex * mut); /// Set the image key to the directory path /** diff --git a/src/images/fitsImage.cpp b/src/images/fitsImage.cpp index 7f4c79f..f6a78b8 100644 --- a/src/images/fitsImage.cpp +++ b/src/images/fitsImage.cpp @@ -5,7 +5,7 @@ #include #include -fitsImage::fitsImage() +fitsImage::fitsImage(std::mutex * mut) : rtimvImage(mut) { connect(&m_timer, SIGNAL(timeout()), this, SLOT(imageTimerout())); diff --git a/src/images/fitsImage.hpp b/src/images/fitsImage.hpp index 6a2c0b0..49c9a54 100644 --- a/src/images/fitsImage.hpp +++ b/src/images/fitsImage.hpp @@ -55,8 +55,10 @@ struct fitsImage : public rtimvImage public: - ///Default c'tor - fitsImage(); + fitsImage() = delete; + + ///Only c'tor + fitsImage(std::mutex * mut); /// Set the image key to a path to a fits file. /** diff --git a/src/images/mzmqImage.cpp b/src/images/mzmqImage.cpp index 56f2e18..7f192fa 100644 --- a/src/images/mzmqImage.cpp +++ b/src/images/mzmqImage.cpp @@ -31,7 +31,7 @@ constexpr size_t imageOffset = headerSize; static_assert(endOfHeader <= imageOffset, "Header fields sum to larger than reserved headerSize"); -mzmqImage::mzmqImage() +mzmqImage::mzmqImage(std::mutex * mut) : rtimvImage(mut) { m_ZMQ_context = new zmq::context_t(1); @@ -314,7 +314,12 @@ void mzmqImage::imageThreadExec() if( nx != new_nx || ny != new_ny || atype != new_atype || !m_imageAttached) { - if(m_data) + DEBUG_TRACE_CRUMB + std::lock_guard guard(*m_accessMutex); + + DEBUG_TRACE_CRUMB + + if(m_data) //This can't be a call to detach due to mutex { m_imageAttached = false; delete m_data; @@ -370,6 +375,8 @@ void mzmqImage::imageThreadExec() xe = xrif_allocate(xrif); m_imageAttached = true; + + DEBUG_TRACE_CRUMB } atype = new_atype; @@ -423,12 +430,7 @@ void mzmqImage::imageThreadExec() subscriber.close(); //close so that unsent messages are dropped. - m_imageAttached = false; - if(m_data) - { - delete m_data; - } - m_data = nullptr; + detach(); atype=0; nx =0; @@ -446,12 +448,7 @@ void mzmqImage::imageThreadExec() }// outer loop (checking stale connections) - m_imageAttached = false; - if(m_data) - { - delete m_data; - } - m_data = nullptr; + detach(); xrif_delete(xrif); @@ -514,19 +511,34 @@ int mzmqImage::update() void mzmqImage::detach() { - m_imageAttached = false; - if(m_data) delete m_data; - m_data = nullptr; + DEBUG_TRACE_ANCHOR(mzmqImage::detach begin) + + std::lock_guard guard(*m_accessMutex); + + DEBUG_TRACE_CRUMB + + m_imageAttached = false; + if(m_data) delete m_data; + m_data = nullptr; - m_lastCnt0 = -1; + m_lastCnt0 = -1; + DEBUG_TRACE_ANCHOR(mzmqImage::detach end) } bool mzmqImage::valid() { - if(m_data && m_imageAttached) return true; - - return false; + DEBUG_TRACE_ANCHOR(mzmqImage::valid begin) + + if(m_data && m_imageAttached) + { + DEBUG_TRACE_ANCHOR(mzmqImage::valid true) + return true; + } + + DEBUG_TRACE_ANCHOR(mzmqImage::valid false) + return false; + } float mzmqImage::pixel(size_t n) diff --git a/src/images/mzmqImage.hpp b/src/images/mzmqImage.hpp index a51501e..24559d5 100644 --- a/src/images/mzmqImage.hpp +++ b/src/images/mzmqImage.hpp @@ -65,8 +65,10 @@ struct mzmqImage : public rtimvImage public: - ///Default c'tor - mzmqImage(); + mzmqImage() = delete; + + ///Only c'tor + mzmqImage(std::mutex * mut); ///Destructor, cleans up the zmq context and allocate memory. ~mzmqImage(); diff --git a/src/images/shmimImage.cpp b/src/images/shmimImage.cpp index c685940..02b1fa2 100644 --- a/src/images/shmimImage.cpp +++ b/src/images/shmimImage.cpp @@ -6,12 +6,9 @@ #ifdef RTIMV_MILK -shmimImage::shmimImage() +shmimImage::shmimImage(std::mutex * mut) : rtimvImage(mut) { - //ImageStreamIO_set_printError(new_printError); - - connect(&m_timer, SIGNAL(timeout()), this, SLOT(shmimTimerout())); - + connect(&m_timer, SIGNAL(timeout()), this, SLOT(shmimTimerout())); } int shmimImage::imageKey( const std::string & sn ) @@ -95,6 +92,11 @@ void shmimImage::imConnect() m_notFoundLogged = false; close(SM_fd); + if(m_accessMutex) + { + std::lock_guard guard(*m_accessMutex); + } + if( ImageStreamIO_openIm(&m_image, m_shmimName.c_str()) != 0) { //This shouldn't really happen . . . @@ -199,6 +201,11 @@ int shmimImage::update() if(m_image.md->sem <= 0 || m_image.md == NULL) //Indicates that the server has cleaned up. { + if(m_accessMutex) + { + std::lock_guard guard(*m_accessMutex); + } + m_data = nullptr; ImageStreamIO_closeIm(&m_image); m_shmimAttached = 0; @@ -222,6 +229,11 @@ int shmimImage::update() if( snx != m_nx || sny != m_ny ) //Something else changed! { + if(m_accessMutex) + { + std::lock_guard guard(*m_accessMutex); + } + m_data = nullptr; ImageStreamIO_closeIm(&m_image); m_shmimAttached = 0; @@ -234,6 +246,11 @@ int shmimImage::update() if(cnt0 != m_lastCnt0) //Only redraw if it's actually a new image. { + if(m_accessMutex) + { + std::lock_guard guard(*m_accessMutex); + } + m_data = ((char *) (m_image.array.raw)) + curr_image*snx*sny*m_typeSize; m_imageTime = m_image.md->writetime.tv_sec + ((double) m_image.md->writetime.tv_nsec)/1e9; @@ -302,6 +319,11 @@ void shmimImage::detach() { if(m_shmimAttached == 0) return; + if(m_accessMutex) + { + std::lock_guard guard(*m_accessMutex); + } + m_data = nullptr; ImageStreamIO_closeIm(&m_image); m_shmimAttached = 0; diff --git a/src/images/shmimImage.hpp b/src/images/shmimImage.hpp index 628719e..314d9f8 100644 --- a/src/images/shmimImage.hpp +++ b/src/images/shmimImage.hpp @@ -55,8 +55,10 @@ struct shmimImage : public rtimvImage public: - ///Default c'tor - shmimImage(); + shmimImage() = delete; + + ///Only c'tor + shmimImage(std::mutex * mut); ///Set the image key to a shared memory image name /** If this contains the string ".fits" then it is treated as a FITS file and loaded as a static image. Otherwise diff --git a/src/rtimvBase.cpp b/src/rtimvBase.cpp index 1242d8e..8b85702 100644 --- a/src/rtimvBase.cpp +++ b/src/rtimvBase.cpp @@ -8,10 +8,14 @@ #include "images/fitsDirectory.hpp" #include "images/mzmqImage.hpp" +#if 0 rtimvBase *globalIMV; int rtimvBase::sigsegvFd[2]; +#endif + + rtimvBase::rtimvBase( QWidget *Parent, Qt::WindowFlags f) : QWidget(Parent, f) { @@ -30,65 +34,66 @@ void rtimvBase::startup(const std::vector &shkeys) for (size_t i = 0; i < m_images.size(); ++i) { - if (shkeys.size() > i) + if(shkeys.size() > i) { - if (shkeys[i] != "") + if(shkeys[i] != "") { // safely accept several different common fits extensions bool isFits = false; - if (shkeys[i].size() > 4) + if(shkeys[i].size() > 4) { - if (shkeys[i].rfind(".fit") == shkeys[i].size() - 4 || + if(shkeys[i].rfind(".fit") == shkeys[i].size() - 4 || shkeys[i].rfind(".FIT") == shkeys[i].size() - 4) isFits = true; } - if (shkeys[i].size() > 5 && !isFits) + if(shkeys[i].size() > 5 && !isFits) { - if (shkeys[i].rfind(".fits") == shkeys[i].size() - 5 || + if(shkeys[i].rfind(".fits") == shkeys[i].size() - 5 || shkeys[i].rfind(".FITS") == shkeys[i].size() - 5) isFits = true; } bool isDirectory = false; - if (!isFits) + if(!isFits) { - if (shkeys[i][shkeys[i].size() - 1] == '/') + if(shkeys[i][shkeys[i].size() - 1] == '/') { isDirectory = true; } } - if (isFits) + if(isFits) { - fitsImage *fi = new fitsImage; + fitsImage *fi = new fitsImage(&m_rawMutex); m_images[i] = (rtimvImage *)fi; } - else if (isDirectory) + else if(isDirectory) { - fitsDirectory *fd = new fitsDirectory; + fitsDirectory *fd = new fitsDirectory(&m_rawMutex); m_images[i] = (rtimvImage *)fd; } - else if (shkeys[i].find('@') != std::string::npos || shkeys[i].find(':') != std::string::npos || m_mzmqAlways == true) + else if(shkeys[i].find('@') != std::string::npos || shkeys[i].find(':') != std::string::npos || m_mzmqAlways == true) { - mzmqImage *mi = new mzmqImage; + mzmqImage *mi = new mzmqImage(&m_rawMutex); // change defaults std::cerr << m_mzmqServer << "\n"; - if (m_mzmqServer != "") + if(m_mzmqServer != "") mi->imageServer(m_mzmqServer); - if (m_mzmqPort != 0) + if(m_mzmqPort != 0) mi->imagePort(m_mzmqPort); m_images[i] = (rtimvImage *)mi; } else { -#ifdef RTIMV_MILK - shmimImage *si = new shmimImage; + #ifdef RTIMV_MILK + //If we get here we try to interpret as a ImageStreamIO image + shmimImage *si = new shmimImage(&m_rawMutex); m_images[i] = (rtimvImage *)si; -#else + #else qFatal("Unrecognized image key format"); -#endif + #endif } m_images[i]->imageKey(shkeys[i]); // Set the key @@ -97,86 +102,85 @@ void rtimvBase::startup(const std::vector &shkeys) } // Turn on features if images exist: - if (m_images[1] != nullptr) + if(m_images[1] != nullptr) { m_subtractDark = true; } - if (m_images[2] != nullptr) + if(m_images[2] != nullptr) { m_applyMask = true; } - if (m_images[3] != nullptr) + if(m_images[3] != nullptr) { m_applySatMask = true; } - connect(&m_timer, SIGNAL(timeout()), this, SLOT(timerout())); - - // Install signal handling - - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigsegvFd)) - qFatal("Couldn't create TERM socketpair"); - - snSegv = new QSocketNotifier(sigsegvFd[1], QSocketNotifier::Read, this); - connect(snSegv, SIGNAL(activated(int)), this, SLOT(handleSigSegv())); - - globalIMV = this; - - struct sigaction act; - sigset_t set; - - act.sa_sigaction = &rtimvBase::st_handleSigSegv; - act.sa_flags = SA_SIGINFO; - sigemptyset(&set); - act.sa_mask = set; - - errno = 0; - if (sigaction(SIGBUS, &act, 0) < 0) - { - perror("rtimv: error installing SIGBUS handler"); - } - - if (sigaction(SIGSEGV, &act, 0) < 0) - { - perror("rtimv: error installing SIGSEGV handler"); - } + connect(&m_imageTimer, SIGNAL(timeout()), this, SLOT(updateImages())); } bool rtimvBase::imageValid(size_t n) { - if (n >= m_images.size()) + if(n >= m_images.size()) return false; - if (m_images[n] == nullptr) + if(m_images[n] == nullptr) return false; return m_images[n]->valid(); } void rtimvBase::setImsize(uint32_t x, uint32_t y) { - int cb; + DEBUG_TRACE_ANCHOR(rtimvBase::setImsize start) - if (m_nx != x || m_ny != y || m_qim == 0) + //Always have at least one pixel + if(x == 0) x = 1; + if(y == 0) y = 1; + + if(m_nx != x || m_ny != y || m_calData == 0 || m_qim == 0) { - if (x != 0 && y != 0) - { - m_nx = x; - m_ny = y; + m_nx = x; + m_ny = y; - if (m_qim) - delete m_qim; + DEBUG_TRACE_VAL(m_nx) + DEBUG_TRACE_VAL(m_ny) - m_qim = new QImage(m_nx, m_ny, QImage::Format_Indexed8); + if(m_calData != nullptr) + { + DEBUG_TRACE_CRUMB - cb = current_colorbar; // force a reload. - current_colorbar = -1; + delete[] m_calData; + m_calData = nullptr; + } - load_colorbar(cb); + DEBUG_TRACE_CRUMB + + m_calData = new float[m_nx*m_ny]; + + if(m_qim != nullptr) + { + DEBUG_TRACE_CRUMB - postSetImsize(); + delete m_qim; + m_qim = nullptr; } + + DEBUG_TRACE_CRUMB + + m_qim = new QImage(m_nx, m_ny, QImage::Format_Indexed8); + + DEBUG_TRACE_CRUMB + + load_colorbar(current_colorbar, false); //have to load into newly create image + + DEBUG_TRACE_CRUMB + + postSetImsize(); + + DEBUG_TRACE_CRUMB } + + DEBUG_TRACE_ANCHOR(rtimvBase::setImsize end) } void rtimvBase::postSetImsize() @@ -194,129 +198,178 @@ uint32_t rtimvBase::ny() return m_ny; } -void rtimvBase::timerout() +void rtimvBase::updateImages() { + DEBUG_TRACE_ANCHOR(rtimvBase::updateImages begin) + static bool connected = false; int doupdate = RTIMVIMAGE_NOUPDATE; int supportUpdate = RTIMVIMAGE_NOUPDATE; - if (m_images[0] != nullptr) + if(m_images[0] != nullptr) + { + DEBUG_TRACE_CRUMB doupdate = m_images[0]->update(); + } + + DEBUG_TRACE_CRUMB for (size_t i = 1; i < m_images.size(); ++i) { - if (m_images[i] != nullptr) + if(m_images[i] != nullptr) { int sU = m_images[i]->update(); - if (sU > supportUpdate) - supportUpdate = sU; + if(sU > supportUpdate) //Do an update if any support image needs an update + { + supportUpdate = sU; + } } } - if (doupdate >= RTIMVIMAGE_IMUPDATE || supportUpdate >= RTIMVIMAGE_IMUPDATE) + DEBUG_TRACE_CRUMB + + if(doupdate >= RTIMVIMAGE_IMUPDATE || supportUpdate >= RTIMVIMAGE_IMUPDATE) { + DEBUG_TRACE_CRUMB + changeImdata(true); - if (!connected) + DEBUG_TRACE_CRUMB + + if(!connected) { + DEBUG_TRACE_CRUMB onConnect(); connected = true; + DEBUG_TRACE_CRUMB } } - if (!connected) + DEBUG_TRACE_CRUMB + if(!connected) { + DEBUG_TRACE_CRUMB updateNC(); + DEBUG_TRACE_ANCHOR(rtimvBase::updateImages early) return; } - if (doupdate == RTIMVIMAGE_FPSUPDATE) + if(doupdate == RTIMVIMAGE_FPSUPDATE) { + DEBUG_TRACE_CRUMB updateFPS(); } - if (doupdate == RTIMVIMAGE_AGEUPDATE) + DEBUG_TRACE_CRUMB + + if(doupdate == RTIMVIMAGE_AGEUPDATE) { updateAge(); } + + DEBUG_TRACE_ANCHOR(rtimvBase::updateImages end) } -void rtimvBase::timeout(int to) +void rtimvBase::imageTimeout(int to) { - m_timer.stop(); + if(to == m_imageTimeout) //Don't interrupt if not needed + { + return; + } + + m_imageTimer.stop(); for (size_t i = 0; i < m_images.size(); ++i) { - if (m_images[i] != nullptr) + if(m_images[i] != nullptr) + { m_images[i]->timeout(to); // just for fps calculations + } } - m_timer.start(to); + m_imageTimer.start(to); +} + +int rtimvBase::imageTimeout() +{ + return m_imageTimeout; } -rtimvBase::pixelF rtimvBase::pixel() +rtimvBase::pixelF rtimvBase::rawPixel() { pixelF _pixel = nullptr; - if (m_images[0] == nullptr) + if(m_images[0] == nullptr) + { return _pixel; // no valid base image + } - if (m_images[0]->valid()) + if(m_images[0]->valid()) + { _pixel = &pixel_noCal; // default if there is a valid base image. + } else + { return _pixel; // no valid base image + } - if (m_subtractDark == true) // && m_applyMask == false) + if(m_subtractDark == true && m_applyMask == false) { - if (m_images[1] == nullptr) + if(m_images[1] == nullptr) + { return _pixel; + } - if (m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) + if(m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) + { return _pixel; + } - if (m_images[0]->valid() && m_images[1]->valid()) + if(m_images[0]->valid() && m_images[1]->valid()) + { _pixel = &pixel_subDark; + } } - if (m_subtractDark == false && m_applyMask == true) + if(m_subtractDark == false && m_applyMask == true) { - if (m_images[2] == nullptr) + if(m_images[2] == nullptr) return _pixel; - if (m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) + if(m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) return _pixel; - if (m_images[0]->valid() && m_images[2]->valid()) + if(m_images[0]->valid() && m_images[2]->valid()) _pixel = &pixel_applyMask; } - if (m_subtractDark == true && m_applyMask == true) + if(m_subtractDark == true && m_applyMask == true) { - if (m_images[1] == nullptr && m_images[2] == nullptr) + if(m_images[1] == nullptr && m_images[2] == nullptr) return _pixel; - else if (m_images[2] == nullptr) + else if(m_images[2] == nullptr) { - if (m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) + if(m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) return _pixel; - if (m_images[1]->valid()) + if(m_images[1]->valid()) _pixel = &pixel_subDark; } - else if (m_images[1] == nullptr) + else if(m_images[1] == nullptr) { - if (m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) + if(m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) return _pixel; - if (m_images[2]->valid()) + if(m_images[2]->valid()) _pixel = &pixel_applyMask; } else { - if (m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) + if(m_images[1]->nx() != m_images[0]->nx() || m_images[1]->ny() != m_images[0]->ny()) return _pixel; - if (m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) + if(m_images[2]->nx() != m_images[0]->nx() || m_images[2]->ny() != m_images[0]->ny()) return _pixel; - if (m_images[1]->valid() && m_images[2]->valid()) + if(m_images[1]->valid() && m_images[2]->valid()) _pixel = &pixel_subDarkApplyMask; } } @@ -348,13 +401,20 @@ float rtimvBase::pixel_subDarkApplyMask(rtimvBase *imv, return (imv->m_images[0]->pixel(idx) - imv->m_images[1]->pixel(idx)) * imv->m_images[2]->pixel(idx); } +float rtimvBase::calPixel( uint32_t x, + uint32_t y + ) +{ + return m_calData[y * m_nx + x]; +} + // https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color/56678483#56678483 template realT sRGBtoLinRGB(int rgb) { realT V = ((realT)rgb) / 255.0; - if (V <= 0.0405) + if(V <= 0.0405) return V / 12.92; return pow((V + 0.055) / 1.055, 2.4); @@ -371,7 +431,7 @@ realT linRGBtoLuminance(realT linR, template realT pLightness(realT lum) { - if (lum <= static_cast(216) / static_cast(24389)) + if(lum <= static_cast(216) / static_cast(24389)) { return lum * static_cast(24389) / static_cast(27); } @@ -379,9 +439,18 @@ realT pLightness(realT lum) return pow(lum, static_cast(1) / static_cast(3)) * 116 - 16; } -void rtimvBase::load_colorbar(int cb) +void rtimvBase::load_colorbar( int cb, + bool update + ) { - if (current_colorbar != cb && m_qim) + DEBUG_TRACE_ANCHOR(rtimvBase::load_colorbar start) + + if(!m_qim) + { + DEBUG_TRACE_ANCHOR(rtimvBase::load_colorbar early-null) + } + + if(m_qim) { current_colorbar = cb; switch (cb) @@ -432,19 +501,21 @@ void rtimvBase::load_colorbar(int cb) for (int n = 0; n < 256; ++n) { - // QRgb rgb = m_qim->color(n); - - // m_lightness[n] = pLightness(linRGBtoLuminance( sRGBtoLinRGB(qRed(rgb)), sRGBtoLinRGB(qGreen(rgb)), sRGBtoLinRGB(qBlue(rgb)))); m_lightness[n] = QColor(m_qim->color(n)).lightness(); } - changeImdata(); + if(update) + { + changeImdata(); + } } + + DEBUG_TRACE_ANCHOR(rtimvBase::load_colorbar end) } void rtimvBase::set_cbStretch(int ct) { - if (ct < 0 || ct >= cbStretches_max) + if(ct < 0 || ct >= cbStretches_max) { ct = stretchLinear; } @@ -531,11 +602,11 @@ int calcPixIndex_linear(float pixval, float mindat, float maxdat, int mincol, in { // We first produce a value nominally between 0 and 1, though depending on the range it could be > 1. pixval = (pixval - mindat) / ((float)(maxdat - mindat)); - if (pixval < 0) + if(pixval < 0) return 0; // Clamp it to <= 1 - if (pixval > 1.) + if(pixval > 1.) pixval = 1.; // And finally put it in the color bar index range @@ -549,13 +620,13 @@ int calcPixIndex_log(float pixval, float mindat, float maxdat, int mincol, int m // We first produce a value nominally between 0 and 1, though depending on the range it could be > 1. pixval = (pixval - mindat) / ((float)(maxdat - mindat)); - if (pixval < 0) + if(pixval < 0) return 0; pixval = log10(pixval * a + 1) / log10_a; // Clamp it to <= 1 - if (pixval > 1.) + if(pixval > 1.) pixval = 1.; // And finally put it in the color bar index range @@ -568,13 +639,13 @@ int calcPixIndex_pow(float pixval, float mindat, float maxdat, int mincol, int m // We first produce a value nominally between 0 and 1, though depending on the range it could be > 1. pixval = (pixval - mindat) / ((float)(maxdat - mindat)); - if (pixval < 0) + if(pixval < 0) return 0; pixval = (pow(a, pixval)) / a; // Clamp it to <= 1 - if (pixval > 1.) + if(pixval > 1.) pixval = 1.; // And finally put it in the color bar index range @@ -585,13 +656,13 @@ int calcPixIndex_sqrt(float pixval, float mindat, float maxdat, int mincol, int { // We first produce a value nominally between 0 and 1, though depending on the range it could be > 1. pixval = (pixval - mindat) / ((float)(maxdat - mindat)); - if (pixval < 0) + if(pixval < 0) return 0; pixval = sqrt(pixval); // Clamp it to <= 1 - if (pixval > 1.) + if(pixval > 1.) pixval = 1.; // And finally put it in the color bar index range @@ -602,13 +673,13 @@ int calcPixIndex_square(float pixval, float mindat, float maxdat, int mincol, in { // We first produce a value nominally between 0 and 1, though depending on the range it could be > 1. pixval = (pixval - mindat) / ((float)(maxdat - mindat)); - if (pixval < 0) + if(pixval < 0) return 0; pixval = pixval * pixval; // Clamp it to <= 1 - if (pixval > 1.) + if(pixval > 1.) pixval = 1.; // And finally put it in the color bar index range @@ -617,62 +688,119 @@ int calcPixIndex_square(float pixval, float mindat, float maxdat, int mincol, in void rtimvBase::changeImdata(bool newdata) { + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata start) + float tmp_min; float tmp_max; int idx; float imval; - if (m_images[0] == nullptr) - return; - if (!m_images[0]->valid()) + if(m_images[0] == nullptr) + { + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata early-null) return; + } - // Get the pixel calculating function - float (*_pixel)(rtimvBase *, size_t) = pixel(); + DEBUG_TRACE_CRUMB - // Get the color index calculating function - int (*_index)(float, float, float, int, int); - switch (m_cbStretch) + if(!m_images[0]->valid()) { - case stretchLog: - _index = calcPixIndex_log; - break; - case stretchPow: - _index = calcPixIndex_pow; - break; - case stretchSqrt: - _index = calcPixIndex_sqrt; - break; - case stretchSquare: - _index = calcPixIndex_square; - break; - default: - _index = calcPixIndex_linear; + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata early-not-valid) + return; } - if (m_images[0]->nx() != m_nx || m_images[0]->ny() != m_ny || m_autoScale) + DEBUG_TRACE_CRUMB + + bool resized = false; + + //Here we realize we need to resize + if(m_images[0]->nx() != m_nx || m_images[0]->ny() != m_ny || !m_qim) { + amChangingimdata = true; + + DEBUG_TRACE_CRUMB + + //Need to lock a mutex here setImsize(m_images[0]->nx(), m_images[0]->ny()); + DEBUG_TRACE_CRUMB + + resized = true; + } + + DEBUG_TRACE_CRUMB + + if(resized || newdata) //need to copy new data to m_calData + { + std::unique_lock lock(m_rawMutex); //, std::try_to_lock); + if(!lock.owns_lock()) + { + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata early-no-lock) + return; + } + + DEBUG_TRACE_CRUMB + + // Get the pixel calculating function + float (*_pixel)(rtimvBase *, size_t) = rawPixel(); + + if(_pixel == nullptr) + { + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata early-null_pixel) + return; + } + + DEBUG_TRACE_CRUMB + + if(m_nx != m_images[0]->nx() || m_ny != m_images[0]->ny()) + { + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata early-size-mismatch) + return; + } + + DEBUG_TRACE_CRUMB + + for(uint64_t n=0; n < m_nx*m_ny; ++n) + { + m_calData[n] = _pixel(this, n); + } + } + + DEBUG_TRACE_CRUMB + + if(resized || newdata || m_autoScale) + { + DEBUG_TRACE_CRUMB + // Need to set these at the beginning imdat_min = std::numeric_limits::max(); imdat_max = -std::numeric_limits::max(); + for (uint32_t i = 0; i < m_ny; ++i) { for (uint32_t j = 0; j < m_nx; ++j) { - imval = _pixel(this, i * m_nx + j); - if (!std::isfinite(imval)) + imval = calPixel(j,i); + + if(!std::isfinite(imval)) + { continue; - if (imval > imdat_max) - imdat_max = _pixel(this, i * m_nx + j); - if (imval < imdat_min) - imdat_min = _pixel(this, i * m_nx + j); + } + + if(imval > imdat_max) + { + imdat_max = calPixel(j,i);//_pixel(this, i * m_nx + j); + } + + if(imval < imdat_min) + { + imdat_min = calPixel(j,i);//_pixel(this, i * m_nx + j); + } } } - if (!std::isfinite(imdat_max) || !std::isfinite(imdat_min)) + if(!std::isfinite(imdat_max) || !std::isfinite(imdat_min)) { // It should be impossible for them to be infinite by themselves unless it's all NaNs. imdat_max = 0; @@ -683,11 +811,48 @@ void rtimvBase::changeImdata(bool newdata) maxdat(imdat_max); } + DEBUG_TRACE_CRUMB + + if(!m_qim) + { + amChangingimdata = false; + return; + } + + DEBUG_TRACE_CRUMB + amChangingimdata = true; - if (!newdata) + /* Here is where we color the pixmap*/ + + DEBUG_TRACE_CRUMB + + // Get the color index calculating function + int (*_index)(float, float, float, int, int); + switch (m_cbStretch) + { + case stretchLog: + _index = calcPixIndex_log; + break; + case stretchPow: + _index = calcPixIndex_pow; + break; + case stretchSqrt: + _index = calcPixIndex_sqrt; + break; + case stretchSquare: + _index = calcPixIndex_square; + break; + default: + _index = calcPixIndex_linear; + } + + DEBUG_TRACE_CRUMB + + if(!newdata && !resized) //This is just a recolor { - if (m_mindat == m_maxdat) + DEBUG_TRACE_CRUMB + if(m_mindat == m_maxdat) //Constant { for (uint32_t i = 0; i < m_ny; ++i) { @@ -703,10 +868,10 @@ void rtimvBase::changeImdata(bool newdata) { for (uint32_t j = 0; j < m_nx; ++j) { - idx = i * m_nx + j; - imval = _pixel(this, idx); + //idx = i * m_nx + j; + imval = calPixel(j,i);// _pixel(this, idx); - if (!std::isfinite(imval)) + if(!std::isfinite(imval)) { m_qim->setPixel(j, m_ny - i - 1, m_nanColor); continue; @@ -718,47 +883,53 @@ void rtimvBase::changeImdata(bool newdata) } else { + DEBUG_TRACE_CRUMB + // Update statistics tmp_min = std::numeric_limits::max(); tmp_max = -std::numeric_limits::max(); saturated = 0; - if (colorBoxActive) + if(colorBoxActive) { colorBox_min = std::numeric_limits::max(); colorBox_max = -std::numeric_limits::max(); } - if (m_mindat == m_maxdat) + DEBUG_TRACE_CRUMB + + if(m_mindat == m_maxdat) { + DEBUG_TRACE_CRUMB + for (uint32_t i = 0; i < m_ny; ++i) { for (uint32_t j = 0; j < m_nx; ++j) { - idx = i * m_nx + j; - imval = _pixel(this, idx); // m_imData[idx]; + //idx = i * m_nx + j; + imval = calPixel(j,i); //_pixel(this, idx); // m_imData[idx]; - if (!std::isfinite(imval)) + if(!std::isfinite(imval)) { m_qim->setPixel(j, m_ny - i - 1, m_nanColor); continue; } - if (imval > tmp_max) + if(imval > tmp_max) tmp_max = imval; - if (imval < tmp_min) + if(imval < tmp_min) tmp_min = imval; - if (imval >= sat_level) + if(imval >= sat_level) saturated++; - if (colorBoxActive) + if(colorBoxActive) { - if (i >= colorBox_i0 && i < colorBox_i1 && j >= colorBox_j0 && j < colorBox_j1) + if(i >= colorBox_i0 && i < colorBox_i1 && j >= colorBox_j0 && j < colorBox_j1) { - if (imval < colorBox_min) + if(imval < colorBox_min) colorBox_min = imval; - if (imval > colorBox_max) + if(imval > colorBox_max) colorBox_max = imval; } } @@ -768,39 +939,41 @@ void rtimvBase::changeImdata(bool newdata) } else { + DEBUG_TRACE_CRUMB + for (uint32_t i = 0; i < m_ny; ++i) { for (uint32_t j = 0; j < m_nx; ++j) { - idx = i * m_nx + j; - imval = _pixel(this, idx); // m_imData[idx]; + imval = calPixel(j,i); - if (!std::isfinite(imval)) + if(!std::isfinite(imval)) { m_qim->setPixel(j, m_ny - i - 1, m_nanColor); continue; } - if (imval > tmp_max) + if(imval > tmp_max) tmp_max = imval; - if (imval < tmp_min) + if(imval < tmp_min) tmp_min = imval; - if (imval >= sat_level) + if(imval >= sat_level) saturated++; - if (colorBoxActive) + if(colorBoxActive) { - if (i >= colorBox_i0 && i < colorBox_i1 && j >= colorBox_j0 && j < colorBox_j1) + if(i >= colorBox_i0 && i < colorBox_i1 && j >= colorBox_j0 && j < colorBox_j1) { - if (imval < colorBox_min) + if(imval < colorBox_min) colorBox_min = imval; - if (imval > colorBox_max) + if(imval > colorBox_max) colorBox_max = imval; } } - m_qim->setPixel(j, m_ny - i - 1, _index(imval, m_mindat, m_maxdat, m_minColor, m_maxColor)); + int idxVal = _index(imval, m_mindat, m_maxdat, m_minColor, m_maxColor); + m_qim->setPixel(j, m_ny - i - 1, idxVal); } } } @@ -809,32 +982,32 @@ void rtimvBase::changeImdata(bool newdata) imdat_min = tmp_min; } - if (m_applyMask && m_images[2] != nullptr) + if(m_applyMask && m_images[2] != nullptr) { - if (m_images[2]->nx() == m_images[0]->nx() || m_images[2]->ny() == m_images[0]->ny()) + if(m_images[2]->nx() == m_images[0]->nx() || m_images[2]->ny() == m_images[0]->ny()) { for (uint32_t i = 0; i < m_ny; ++i) { for (uint32_t j = 0; j < m_nx; ++j) { idx = i * m_nx + j; - if (m_images[2]->pixel(idx) == 0) + if(m_images[2]->pixel(idx) == 0) m_qim->setPixel(j, m_ny - i - 1, m_maskColor); } } } } - if (m_applySatMask && m_images[3] != nullptr) + if(m_applySatMask && m_images[3] != nullptr) { - if (m_images[3]->nx() == m_images[0]->nx() || m_images[3]->ny() == m_images[0]->ny()) + if(m_images[3]->nx() == m_images[0]->nx() || m_images[3]->ny() == m_images[0]->ny()) { for (uint32_t i = 0; i < m_ny; ++i) { for (uint32_t j = 0; j < m_nx; ++j) { idx = i * m_nx + j; - if (m_images[3]->pixel(idx) == 1) + if(m_images[3]->pixel(idx) == 1) m_qim->setPixel(j, m_ny - i - 1, m_satColor); } } @@ -843,9 +1016,20 @@ void rtimvBase::changeImdata(bool newdata) m_qpm.convertFromImage(*m_qim, Qt::AutoColor | Qt::ThresholdDither); + if(resized) + { + //Always switch to zoom 1 after a resize occurs + zoomLevel(1); + } + postChangeImdata(); amChangingimdata = false; -} + + DEBUG_TRACE_ANCHOR(rtimvBase::changeImdata end) + + + +} //void rtimvBase::changeImdata(bool newdata) void rtimvBase::postChangeImdata() { @@ -854,14 +1038,27 @@ void rtimvBase::postChangeImdata() void rtimvBase::zoomLevel(float zl) { - if (zl < m_zoomLevelMin) + DEBUG_TRACE_ANCHOR(rtimvBase::zoomLevel begin) + + DEBUG_TRACE_VAL(zl) + + if(zl < m_zoomLevelMin) + { zl = m_zoomLevelMin; - if (zl > m_zoomLevelMax) + } + + if(zl > m_zoomLevelMax) + { zl = m_zoomLevelMax; + } m_zoomLevel = zl; + DEBUG_TRACE_VAL(m_zoomLevel) + post_zoomLevel(); + + DEBUG_TRACE_ANCHOR(rtimvBase::zoomLevel end) } void rtimvBase::post_zoomLevel() @@ -871,46 +1068,53 @@ void rtimvBase::post_zoomLevel() void rtimvBase::setUserBoxActive(bool usba) { - if (usba) + if(usba) { int idx; float imval; - if (colorBox_i0 > colorBox_i1) + if(colorBox_i0 > colorBox_i1) { idx = colorBox_i0; colorBox_i0 = colorBox_i1; colorBox_i1 = idx; } - if (colorBox_i0 < 0) + if(colorBox_i0 < 0) colorBox_i0 = 0; - if (colorBox_i0 >= (int64_t)m_nx) + if(colorBox_i0 >= (int64_t)m_nx) colorBox_i0 = (int64_t)m_nx - (colorBox_i1 - colorBox_i0); - if (colorBox_i1 <= 0) + if(colorBox_i1 <= 0) colorBox_i1 = 0 + (colorBox_i1 - colorBox_i0); - if (colorBox_i1 > (int64_t)m_nx) + if(colorBox_i1 > (int64_t)m_nx) colorBox_i1 = (int64_t)m_nx - 1; - if (colorBox_j0 > colorBox_j1) + if(colorBox_j0 > colorBox_j1) { idx = colorBox_j0; colorBox_j0 = colorBox_j1; colorBox_j1 = idx; } - if (colorBox_j0 < 0) + if(colorBox_j0 < 0) colorBox_j0 = 0; - if (colorBox_j0 >= (int64_t)m_nx) + if(colorBox_j0 >= (int64_t)m_nx) colorBox_j0 = (int64_t)m_ny - (colorBox_j1 - colorBox_j0); - if (colorBox_j1 <= 0) + if(colorBox_j1 <= 0) colorBox_j1 = 0 + (colorBox_j1 - colorBox_j0); - if (colorBox_j1 > (int64_t)m_ny) + if(colorBox_j1 > (int64_t)m_ny) colorBox_j1 = (int64_t)m_ny - 1; - pixelF _pixel = pixel(); + /*{//mutex scope + std::unique_lock lock(m_rawMutex, std::try_to_lock); + if(!lock.owns_lock()) + { + return; + }*/ + + //pixelF _pixel = pixel(); colorBox_min = std::numeric_limits::max(); colorBox_max = -std::numeric_limits::max(); @@ -918,20 +1122,21 @@ void rtimvBase::setUserBoxActive(bool usba) { for (int j = colorBox_j0; j < colorBox_j1; j++) { - idx = j * m_nx + i; - imval = _pixel(this, idx); // m_imData[idx]; + //idx = j * m_nx + i; + imval = calPixel(j,i); //_pixel(this, idx); // m_imData[idx]; - if (!std::isfinite(imval)) + if(!std::isfinite(imval)) continue; - if (imval < colorBox_min) + if(imval < colorBox_min) colorBox_min = imval; - if (imval > colorBox_max) + if(imval > colorBox_max) colorBox_max = imval; } } + //} //release mutex here. - if (colorBox_min == std::numeric_limits::max() && colorBox_max == -std::numeric_limits::max()) // If all nans + if(colorBox_min == std::numeric_limits::max() && colorBox_max == -std::numeric_limits::max()) // If all nans { colorBox_min = 0; colorBox_max = 0; @@ -956,13 +1161,13 @@ void rtimvBase::set_RealTimeStopped(int rts) { RealTimeStopped = (rts != 0); - if (RealTimeStopped) + if(RealTimeStopped) { - m_timer.stop(); + m_imageTimer.stop(); } else { - m_timer.start(m_timeout); + m_imageTimer.start(m_imageTimeout); } } @@ -981,37 +1186,3 @@ void rtimvBase::updateNC() return; } -void rtimvBase::st_handleSigSegv(int signum, - siginfo_t *siginf, - void *ucont) -{ - static_cast(signum); - static_cast(siginf); - static_cast(ucont); - - char a = 1; - int rv = ::write(sigsegvFd[0], &a, sizeof(a)); - - static_cast(rv); -} - -void rtimvBase::handleSigSegv() -{ - snSegv->setEnabled(false); - - char tmp; - int rv = ::read(sigsegvFd[1], &tmp, sizeof(tmp)); - static_cast(rv); - - std::cerr << "\n\n****** sigbus/sigterm ******\n" - << amChangingimdata << "\n" - << std::endl; - - for (size_t i = 1; i < m_images.size(); ++i) - { - if (m_images[i] != nullptr) - m_images[i]->detach(); - } - - snSegv->setEnabled(true); -} diff --git a/src/rtimvBase.hpp b/src/rtimvBase.hpp index afe1dd0..4471bdb 100644 --- a/src/rtimvBase.hpp +++ b/src/rtimvBase.hpp @@ -34,176 +34,234 @@ #include "colorMaps.hpp" + + class rtimvBase : public QWidget { - Q_OBJECT + Q_OBJECT public: - /// Basic c'tor. Does not startup the images. - /** startup should be called with the list of keys. - */ - rtimvBase( QWidget * Parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags() - ); - - /// Image c'tor, starts up the images. - /** startup should not be called. - */ - rtimvBase( const std::vector & shkeys, ///< [in] The shmim keys used ot access the images. - QWidget * Parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags() - ); + /// Basic c'tor. Does not startup the images. + /** startup should be called with the list of keys. + */ + rtimvBase( QWidget * Parent = nullptr, + Qt::WindowFlags f = Qt::WindowFlags() + ); + + /// Image c'tor, starts up the images. + /** startup should not be called. + */ + rtimvBase( const std::vector & shkeys, ///< [in] The shmim keys used ot access the images. + QWidget * Parent = nullptr, + Qt::WindowFlags f = Qt::WindowFlags() + ); protected: - bool m_mzmqAlways {false}; - std::string m_mzmqServer; - int m_mzmqPort {0}; + bool m_mzmqAlways {false}; + std::string m_mzmqServer; + int m_mzmqPort {0}; public: - /// Start the images checking for updates. - /** - */ - void startup( const std::vector & shkeys /**< [in] The shmim keys used ot access the images.*/); - - /** @name Image Data - * - * @{ - */ + + /** @name The Images - Data + * + * @{ + */ protected: - uint32_t m_nx {0}; ///< The number of pixels in the x (horizontal) direction - uint32_t m_ny {0}; ///< The number of pixels in the y (vertical) direction - std::vector m_images; + uint32_t m_nx {0}; ///< The number of pixels in the x (horizontal) direction + uint32_t m_ny {0}; ///< The number of pixels in the y (vertical) direction + + std::vector m_images; -public: + ///@} - /// Check if an image is currently valid. - /** \returns true if valid - * \returns false otherwise - */ - bool imageValid( size_t n /**< [in] the image number */); +public: - /// Changes the image size, but only if necessary. - void setImsize( uint32_t x, ///< [in] the new x size - uint32_t y ///< [in] the new y size - ); - - /// Called after set_imsize to handle allocations for derived classes - virtual void postSetImsize(); + /** @name The Images + * + * @{ + */ + + /// Configure the image sources and start checking for updates. + /** + */ + void startup( const std::vector & shkeys /**< [in] The shmim keys used ot access the images.*/); + + /// Check if an image is currently valid. + /** \returns true if valid + * \returns false otherwise + */ + bool imageValid( size_t n /**< [in] the image number */); + + /// Changes the image size, but only if necessary. + /** The reallocates m_calData and m_qim + * + */ + void setImsize( uint32_t x, ///< [in] the new x size + uint32_t y ///< [in] the new y size + ); + + /// Called after set_imsize to handle allocations for derived classes + virtual void postSetImsize(); - ///Get the number of x pixels - /** - * \returns the current vvalue of m_nx - */ - uint32_t nx(); + ///Get the number of x pixels + /** + * \returns the current vvalue of m_nx + */ + uint32_t nx(); - ///Get the number of y pixels - /** - * \returns the current vvalue of m_ny - */ - uint32_t ny(); + ///Get the number of y pixels + /** + * \returns the current vvalue of m_ny + */ + uint32_t ny(); - /// @} + /// @} protected: - virtual void onConnect() {} - - /** @name Image Data Update Interval - * - * @{ - */ + + virtual void onConnect() {} + + /** @name Image Update Data + * + * @{ + */ + protected: - QTimer m_timer; ///< When this times out rtimvBase checks for a new image. - int m_timeout {100}; ///targetXc()); targetYcChanged(imv->targetYc()); targetVisibleChanged(imv->targetVisible()); + + ui.imtimerspinBox->setValue(imv->imageTimeout()); + } void rtimvControlPanel::update_panel() @@ -865,7 +868,7 @@ void rtimvControlPanel::on_contrastEntry_editingFinished() void rtimvControlPanel::on_imtimerspinBox_valueChanged(int to) { - imv->timeout(to); + imv->imageTimeout(to); } void rtimvControlPanel::on_statsBoxButton_clicked() diff --git a/src/rtimvGraphicsView.cpp b/src/rtimvGraphicsView.cpp index 596cf3f..2e6f88d 100644 --- a/src/rtimvGraphicsView.cpp +++ b/src/rtimvGraphicsView.cpp @@ -9,6 +9,16 @@ #include "rtimvGraphicsView.hpp" +//#define DEBUG_TRACE + +#ifdef DEBUG_TRACE +#define DEBUG_TRACE_CRUMB std::cerr << __FILE__ << " " << __LINE__ << std::endl; +#define DEBUG_TRACE_VAL(val) std::cerr << __FILE__ << " " << __LINE__ << " " << #val << "=" << val << std::endl; +#else +#define DEBUG_TRACE_CRUMB +#define DEBUG_TRACE_VAL(val) +#endif + #include //Geometries of the various text boxes. @@ -807,13 +817,16 @@ void rtimvGraphicsView::zoomTimerOut() } void rtimvGraphicsView::centerOn( qreal x, - qreal y - ) + qreal y + ) { m_xCen = x; m_yCen = y; - QGraphicsView::centerOn(x,y); + DEBUG_TRACE_VAL(m_xCen) + DEBUG_TRACE_VAL(m_yCen) + + QGraphicsView::centerOn(m_xCen,m_yCen); } void rtimvGraphicsView::mapCenterToScene( float xc, @@ -846,7 +859,7 @@ float rtimvGraphicsView::mouseViewY() return m_mouseViewY; } -void rtimvGraphicsView::zoomLevel( float zl ) +/*void rtimvGraphicsView::zoomLevel( float zl ) { m_zoomLevel = zl; } @@ -854,7 +867,7 @@ void rtimvGraphicsView::zoomLevel( float zl ) float rtimvGraphicsView::zoomLevel() { return m_zoomLevel; -} +}*/ void rtimvGraphicsView::screenZoom( float sz ) { diff --git a/src/rtimvGraphicsView.hpp b/src/rtimvGraphicsView.hpp index 674c44d..1c6e463 100644 --- a/src/rtimvGraphicsView.hpp +++ b/src/rtimvGraphicsView.hpp @@ -8,6 +8,7 @@ #ifndef rtimv_rtimvGraphicsView_hpp #define rtimv_rtimvGraphicsView_hpp + #include #include @@ -502,18 +503,10 @@ class rtimvGraphicsView : public QGraphicsView float mouseViewY(); protected: - float m_zoomLevel; ///< The current zoom level + float m_screenZoom; ///< The current screen zoom factor, the ratio of screen pixels to physical pixels when ZoomLevel==1. public: - ///Set the current zoom level - void zoomLevel( float zl /**< [in] the new zoom level*/ ); - - ///Get the current zoom level - /** - * \returns the current zoom level. - */ - float zoomLevel(); ///Set the current screen zoom void screenZoom( float sz /**< [in] the new screen zoom*/ ); @@ -559,6 +552,13 @@ class rtimvGraphicsView : public QGraphicsView ///@} +public: + + void setStyleSheet(const QString & qss) + { + + QWidget::setStyleSheet(qss); + } }; #endif //rtimv_rtimvGraphicsView_hpp diff --git a/src/rtimvImage.hpp b/src/rtimvImage.hpp index 5d429e3..841ab10 100644 --- a/src/rtimvImage.hpp +++ b/src/rtimvImage.hpp @@ -8,11 +8,26 @@ #ifndef rtimv_rtimvImage_hpp #define rtimv_rtimvImage_hpp +#include + #include #include #include +//#define DEBUG_TRACE + +#ifdef DEBUG_TRACE +#define DEBUG_TRACE_CRUMB std::cerr << __FILE__ << " " << __LINE__ << std::endl; +#define DEBUG_TRACE_ANCHOR(anchor) std::cerr << __FILE__ << " " << __LINE__ << " " << #anchor << std::endl; +#define DEBUG_TRACE_VAL(val) std::cerr << __FILE__ << " " << __LINE__ << " " << #val << "=" << val << std::endl; +#else +#define DEBUG_TRACE_CRUMB +#define DEBUG_TRACE_ANCHOR(anchor) +#define DEBUG_TRACE_VAL(val) +#endif + + #define RTIMVIMAGE_NOUPDATE (0) #define RTIMVIMAGE_AGEUPDATE (1) #define RTIMVIMAGE_IMUPDATE (2) @@ -26,6 +41,13 @@ struct rtimvImage : public QObject { public: + + rtimvImage() = delete; + + rtimvImage( std::mutex * mut ) : m_accessMutex{mut} + {} + + /// Set the image key /** This function sets the image key, and must begin the connection and reading process. * @@ -94,6 +116,9 @@ struct rtimvImage : public QObject */ virtual bool valid() = 0; + ///Mutex for locking access to memory + std::mutex * m_accessMutex {nullptr}; + /// Get the value at pixel n as a float. /** The linear index n is determined by n = y * nx() + x where (x,y) is the pixel coordinate. * diff --git a/src/rtimvInterfaces.hpp b/src/rtimvInterfaces.hpp index 8b17859..902d956 100644 --- a/src/rtimvInterfaces.hpp +++ b/src/rtimvInterfaces.hpp @@ -18,6 +18,25 @@ #include +/// The rtimv namespace +/** + * \todo put everything in this namespace + * + */ +namespace rtimv +{ + +/// Warning levels used to change colors +/** + * \todo put this in an rtimv.hpp file. Or, maybe, rtimvInterfaces.hpp should be rtimv.hpp + */ +enum class warningLevel{ normal, ///< No border, this is fine + caution, ///< Caution: user should pay attention. Default is yellow. + warning, ///< Warning: user should fix something. Default is red. + alert ///< Alert: user must take immediate action. Default is magenta. + }; +} + ///\todo need a separate dictionary file(s) struct rtimvDictBlob { diff --git a/src/rtimvMainWindow.cpp b/src/rtimvMainWindow.cpp index 1ef2303..d5cda04 100644 --- a/src/rtimvMainWindow.cpp +++ b/src/rtimvMainWindow.cpp @@ -53,7 +53,7 @@ rtimvMainWindow::rtimvMainWindow( int argc, m_cenLineHorz = 0; imStats = 0; - m_timer.start(m_timeout); + m_imageTimer.start(m_imageTimeout); m_northArrow = m_qgs->addLine(QLineF(512,400, 512, 624), QColor(RTIMV_DEF_GAGEFONTCOLOR)); m_northArrowTip = m_qgs->addLine(QLineF(512,400, 536, 424), QColor(RTIMV_DEF_GAGEFONTCOLOR)); @@ -137,6 +137,7 @@ rtimvMainWindow::rtimvMainWindow( int argc, } setWindowTitle(m_title.c_str()); + } rtimvMainWindow::~rtimvMainWindow() @@ -264,153 +265,224 @@ void rtimvMainWindow::loadConfig() void rtimvMainWindow::onConnect() { - setWindowTitle(m_title.c_str()); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::onConnect begin) + + setWindowTitle(m_title.c_str()); + DEBUG_TRACE_CRUMB - squareDown(); + squareDown(); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::onConnect end) } void rtimvMainWindow::postSetImsize() -{ - ScreenZoom = std::min((float) ui.graphicsView->viewport()->width()/(float)m_nx,(float)ui.graphicsView->viewport()->height()/(float)m_ny); - zoomLevel(1.0); - set_viewcen(.5, .5); - post_zoomLevel(); - - if(imcp) - { - QTransform transform; - float viewZoom = (float)imcp->ui.viewView->width()/(float)m_nx; +{ + DEBUG_TRACE_ANCHOR(rtimvMainWindow::postSetImsize begin) + + m_screenZoom = std::min( (float) ui.graphicsView->viewport()->width()/(float)m_nx, + (float)ui.graphicsView->viewport()->height()/(float)m_ny ); + + DEBUG_TRACE_VAL(m_screenZoom) + + if(m_qpmi) + { + DEBUG_TRACE_CRUMB + delete m_qpmi; + m_qpmi = nullptr; + } + + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB + + QTransform transform; + float viewZoom = (float)imcp->ui.viewView->width()/(float)m_nx; - transform.scale(viewZoom, viewZoom); - imcp->ui.viewView->setTransform(transform); - } + transform.scale(viewZoom, viewZoom); + imcp->ui.viewView->setTransform(transform); + } - //resize the boxes - float w; - if(m_nx < m_ny) w = m_nx/4; - else w = m_ny/4; - float xc = 0.5*(m_nx)-w/2; - float yc = 0.5*(m_ny)-w/2; + DEBUG_TRACE_CRUMB - std::unordered_set::iterator ubit = m_userBoxes.begin(); - while(ubit != m_userBoxes.end()) - { - StretchBox *sb = *ubit; - sb->setRect(sb->mapRectFromScene(xc, yc, w, w)); - xc += (RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom)*10; - yc += (RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom)*10; - sb->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sb->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); - ++ubit; - } + //resize the boxes + float w; + if(m_nx < m_ny) w = m_nx/4; + else w = m_ny/4; + float xc = 0.5*(m_nx)-w/2; + float yc = 0.5*(m_ny)-w/2; + + std::unordered_set::iterator ubit = m_userBoxes.begin(); + while(ubit != m_userBoxes.end()) + { + StretchBox *sb = *ubit; + sb->setRect(sb->mapRectFromScene(xc, yc, w, w)); + xc += (RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom)*10; + yc += (RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom)*10; + sb->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sb->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); + ++ubit; + } - if(m_statsBox) statsBoxMoved(m_statsBox); - if(m_colorBox) colorBoxMoved(m_colorBox); + if(m_statsBox) statsBoxMoved(m_statsBox); + if(m_colorBox) colorBoxMoved(m_colorBox); - //resize the circles - std::unordered_set::iterator ucit = m_userCircles.begin(); - while(ucit != m_userCircles.end()) - { - StretchCircle *sc = *ucit; - sc->setRect(sc->mapRectFromScene(xc, yc, w, w)); - xc += (RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom)*10; - yc += (RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom)*10; - sc->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sc->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); - ++ucit; - } + //resize the circles + std::unordered_set::iterator ucit = m_userCircles.begin(); + while(ucit != m_userCircles.end()) + { + StretchCircle *sc = *ucit; + sc->setRect(sc->mapRectFromScene(xc, yc, w, w)); + xc += (RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom)*10; + yc += (RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom)*10; + sc->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sc->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); + ++ucit; + } - //resize the lines - std::unordered_set::iterator ulit = m_userLines.begin(); - while(ulit != m_userLines.end()) - { - StretchLine *sl = *ulit; - sl->setLine(0.5*(m_nx)-0.2*m_nx,0.5*(m_ny)-0.2*m_ny, 0.2*(m_nx),0.2*(m_ny)); - sl->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sl->setPenWidth(2*RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); - ++ulit; - } - + //resize the lines + std::unordered_set::iterator ulit = m_userLines.begin(); + while(ulit != m_userLines.end()) + { + StretchLine *sl = *ulit; + sl->setLine(0.5*(m_nx)-0.2*m_nx,0.5*(m_ny)-0.2*m_ny, 0.2*(m_nx),0.2*(m_ny)); + sl->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sl->setPenWidth(2*RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); + ++ulit; + } - setTarget(); + DEBUG_TRACE_CRUMB + + setTarget(); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::postSetImsize end) } void rtimvMainWindow::post_zoomLevel() { - QTransform transform; + DEBUG_TRACE_ANCHOR(rtimvBase::post_zoomLevel begin) + + QTransform transform; - ui.graphicsView->zoomLevel(m_zoomLevel); - ui.graphicsView->screenZoom(ScreenZoom); + DEBUG_TRACE_VAL(m_screenZoom) + + ui.graphicsView->screenZoom(m_screenZoom); + + DEBUG_TRACE_VAL(m_screenZoom) + + transform.scale(m_zoomLevel*m_screenZoom, m_zoomLevel*m_screenZoom); - transform.scale(m_zoomLevel*ScreenZoom, m_zoomLevel*ScreenZoom); + DEBUG_TRACE_VAL(transform.m11()) + + ui.graphicsView->setTransform(transform); + + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB + transform.scale(pointerOverZoom, pointerOverZoom); + imcp->ui.pointerView->setTransform(transform); + } - ui.graphicsView->setTransform(transform); - transform.scale(pointerOverZoom, pointerOverZoom); - if(imcp) imcp->ui.pointerView->setTransform(transform); - change_center(); + DEBUG_TRACE_CRUMB + change_center(); - char zlstr[16]; - snprintf(zlstr,16, "%0.1fx", m_zoomLevel); - ui.graphicsView->zoomText(zlstr); - fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB + char zlstr[16]; + snprintf(zlstr,16, "%0.1fx", m_zoomLevel); + ui.graphicsView->zoomText(zlstr); + + DEBUG_TRACE_CRUMB + fontLuminance(ui.graphicsView->m_zoomText); + + DEBUG_TRACE_ANCHOR(rtimvBase::post_zoomLevel end) } void rtimvMainWindow::postChangeImdata() { - //if(fps_ave > 1.0) ui.graphicsView->fpsGageText( fps_ave ); - - if(saturated) - { - ui.graphicsView->warningText("Saturated!"); - } - else - { - ui.graphicsView->warningText(""); - } + DEBUG_TRACE_ANCHOR(rtimvMainWindow::postChangeImdata begin) + + if(saturated) + { + ui.graphicsView->warningText("Saturated!"); + } + else + { + ui.graphicsView->warningText(""); + } - if(!m_qpmi) //This happens on first time through - { - m_qpmi = m_qgs->addPixmap(m_qpm); - //So we need to initialize the viewport center, etc. - set_viewcen(0.5,0.5); - post_zoomLevel(); - } - else m_qpmi->setPixmap(m_qpm); - - if(m_colorBox) m_qpmi->stackBefore(m_colorBox); - if(m_statsBox) m_qpmi->stackBefore(m_statsBox); - if(m_objCenH) m_qpmi->stackBefore(m_objCenH); - if(m_objCenV) m_qpmi->stackBefore(m_objCenV); - if(m_lineHead) m_qpmi->stackBefore(m_lineHead); - if(m_northArrow) m_qpmi->stackBefore(m_northArrow); - if(m_northArrowTip) m_qpmi->stackBefore(m_northArrowTip); + DEBUG_TRACE_CRUMB - if(imcp) - { - if(imcp->ViewViewMode == ViewViewEnabled) - { - if(!imcp->qpmi_view) imcp->qpmi_view = imcp->qgs_view->addPixmap(m_qpm); - imcp->qpmi_view->setPixmap(m_qpm); + if(!m_qpmi) //This happens on first time through + { + DEBUG_TRACE_CRUMB + m_qpmi = m_qgs->addPixmap(m_qpm); + + DEBUG_TRACE_VAL(m_qpmi) + + //So we need to initialize the viewport center, etc. + DEBUG_TRACE_CRUMB + center(); + DEBUG_TRACE_CRUMB + } + else + { + DEBUG_TRACE_CRUMB + m_qpmi->setPixmap(m_qpm); + DEBUG_TRACE_CRUMB + } + + DEBUG_TRACE_CRUMB + + if(m_colorBox) m_qpmi->stackBefore(m_colorBox); + if(m_statsBox) m_qpmi->stackBefore(m_statsBox); + if(m_objCenH) m_qpmi->stackBefore(m_objCenH); + if(m_objCenV) m_qpmi->stackBefore(m_objCenV); + if(m_lineHead) m_qpmi->stackBefore(m_lineHead); + if(m_northArrow) m_qpmi->stackBefore(m_northArrow); + if(m_northArrowTip) m_qpmi->stackBefore(m_northArrowTip); + + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB + if(imcp->ViewViewMode == ViewViewEnabled) + { + if(!imcp->qpmi_view) imcp->qpmi_view = imcp->qgs_view->addPixmap(m_qpm); + imcp->qpmi_view->setPixmap(m_qpm); - imcp->qpmi_view->stackBefore(imcp->viewLineVert); - } - } - updateMouseCoords(); //This is to update the pixel val box if set. + imcp->qpmi_view->stackBefore(imcp->viewLineVert); + } + } + + DEBUG_TRACE_CRUMB + + updateMouseCoords(); //This is to update the pixel val box if set. - if(imcp) - { - imcp->update_panel(); - } + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB + imcp->update_panel(); + } - if(imStats) - { - imStats->setImdata(); - } + DEBUG_TRACE_CRUMB + + if(imStats) + { + DEBUG_TRACE_CRUMB + imStats->setImdata(); + } + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::postChangeImdata end) - } void rtimvMainWindow::launchControlPanel() @@ -429,36 +501,47 @@ void rtimvMainWindow::launchControlPanel() void rtimvMainWindow::centerNorthArrow() { - if(m_northArrow && m_northArrowTip) - { - m_northArrow->setLine(ui.graphicsView->xCen(), ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel, ui.graphicsView->xCen(), ui.graphicsView->yCen()+.1*m_ny/m_zoomLevel); - - m_northArrow->setTransformOriginPoint ( QPointF(ui.graphicsView->xCen(),ui.graphicsView->yCen()) ); - - m_northArrowTip->setLine(QLineF(ui.graphicsView->xCen(),ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel, ui.graphicsView->xCen() + .02*m_nx/m_zoomLevel,ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel + .012*m_ny/m_zoomLevel)); - m_northArrowTip->setTransformOriginPoint ( QPointF(ui.graphicsView->xCen(),ui.graphicsView->yCen()) ); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::centerNorthArrow begin) - QPen qp = m_northArrow->pen(); - - float wid = 5/(m_zoomLevel*ScreenZoom); - if(wid > 3) wid = 3; - qp.setWidth(wid); + if(m_northArrow && m_northArrowTip) + { + DEBUG_TRACE_CRUMB + m_northArrow->setLine(ui.graphicsView->xCen(), ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel, ui.graphicsView->xCen(), ui.graphicsView->yCen()+.1*m_ny/m_zoomLevel); - m_northArrow->setPen(qp); - m_northArrowTip->setPen(qp); - } + m_northArrow->setTransformOriginPoint ( QPointF(ui.graphicsView->xCen(),ui.graphicsView->yCen()) ); + + m_northArrowTip->setLine(QLineF(ui.graphicsView->xCen(),ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel, ui.graphicsView->xCen() + .02*m_nx/m_zoomLevel,ui.graphicsView->yCen()-.1*m_ny/m_zoomLevel + .012*m_ny/m_zoomLevel)); + m_northArrowTip->setTransformOriginPoint ( QPointF(ui.graphicsView->xCen(),ui.graphicsView->yCen()) ); + + QPen qp = m_northArrow->pen(); + + float wid = 5/(m_zoomLevel*m_screenZoom); + if(wid > 3) wid = 3; + qp.setWidth(wid); + + m_northArrow->setPen(qp); + m_northArrowTip->setPen(qp); + } - updateNorthArrow(); + DEBUG_TRACE_CRUMB + + updateNorthArrow(); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::centerNorthArrow end) } void rtimvMainWindow::updateNorthArrow() { - if(m_northArrow && m_northArrowTip) - { - float ang = northAngle(); - m_northArrow->setRotation(ang); - m_northArrowTip->setRotation(ang); - } + DEBUG_TRACE_ANCHOR(rtimvMainWindow::updateNorthArrow begin) + + if(m_northArrow && m_northArrowTip) + { + float ang = northAngle(); + m_northArrow->setRotation(ang); + m_northArrowTip->setRotation(ang); + } + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::updateNorthArrow end) } float rtimvMainWindow::northAngle() @@ -531,89 +614,152 @@ void rtimvMainWindow::setPointerOverZoom(float poz) void rtimvMainWindow::change_center(bool movezoombox) { - ui.graphicsView->centerOn(ui.graphicsView->xCen(), ui.graphicsView->yCen()); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::change_center begin) + + DEBUG_TRACE_VAL(ui.graphicsView->xCen()); + DEBUG_TRACE_VAL(ui.graphicsView->yCen()); + + ui.graphicsView->centerOn((qreal) ui.graphicsView->xCen(), (qreal) ui.graphicsView->yCen()); - centerNorthArrow(); + DEBUG_TRACE_CRUMB - if(imcp) - { + centerNorthArrow(); + + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB - imcp->viewLineVert->setLine(ui.graphicsView->xCen(), 0, ui.graphicsView->xCen(), m_ny); - imcp->viewLineHorz->setLine(0, ui.graphicsView->yCen(), m_nx, ui.graphicsView->yCen()); + imcp->viewLineVert->setLine(ui.graphicsView->xCen(), 0, ui.graphicsView->xCen(), m_ny); + imcp->viewLineHorz->setLine(0, ui.graphicsView->yCen(), m_nx, ui.graphicsView->yCen()); - if(m_zoomLevel <= 1.0) imcp->viewBox->setVisible(false); - else - { - imcp->viewBox->setVisible(true); - if(movezoombox) - { - QPointF tmpp = imcp->viewBox->mapFromParent(ui.graphicsView->xCen() - .5*m_nx/m_zoomLevel, ui.graphicsView->yCen()-.5*m_ny/m_zoomLevel); - imcp->viewBox->setRect(tmpp.x(), tmpp.y(), m_nx/m_zoomLevel, m_ny/m_zoomLevel); - } + if(m_zoomLevel <= 1.0) imcp->viewBox->setVisible(false); + else + { + imcp->viewBox->setVisible(true); + if(movezoombox) + { + QPointF tmpp = imcp->viewBox->mapFromParent(ui.graphicsView->xCen() - .5*m_nx/m_zoomLevel, ui.graphicsView->yCen()-.5*m_ny/m_zoomLevel); + imcp->viewBox->setRect(tmpp.x(), tmpp.y(), m_nx/m_zoomLevel, m_ny/m_zoomLevel); + } - } - imcp->ui.viewView->centerOn(.5*m_nx, .5*m_ny); - imcp->update_panel(); - } + } + imcp->ui.viewView->centerOn(.5*m_nx, .5*m_ny); + imcp->update_panel(); + } + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::change_center end) + } void rtimvMainWindow::set_viewcen(float x, float y, bool movezoombox) { - QPointF sp( x* m_qpmi->boundingRect().width(), y*m_qpmi->boundingRect().height() ); - QPointF vp = ui.graphicsView->mapFromScene(sp); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::set_viewcen begin) + + if(m_qpmi == nullptr) + { + DEBUG_TRACE_ANCHOR(rtimvMainWindow::set_viewcen early-null) + return; + } + + DEBUG_TRACE_CRUMB + + DEBUG_TRACE_VAL(x) + DEBUG_TRACE_VAL(y) + DEBUG_TRACE_VAL(m_qpmi->boundingRect().width()) + DEBUG_TRACE_VAL(m_qpmi->boundingRect().height()) + + QPointF sp( x* m_qpmi->boundingRect().width(), y*m_qpmi->boundingRect().height() ); + + DEBUG_TRACE_CRUMB + + QPointF vp = ui.graphicsView->mapFromScene(sp); + + DEBUG_TRACE_CRUMB + + ui.graphicsView->mapCenterToScene(vp.x(), vp.y()); - ui.graphicsView->mapCenterToScene(vp.x(), vp.y()); - change_center(movezoombox); + DEBUG_TRACE_CRUMB + + change_center(movezoombox); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::set_viewcen end) } void rtimvMainWindow::squareDown() { - double imrat = ((double)nx())/ny(); - double winrat = ((double) width())/height(); - - ///\todo make threshold responsive to current dimensions so we don't enter loops. - if( fabs( 1.0 - imrat/winrat) < 0.01) return; + DEBUG_TRACE_ANCHOR(rtimvMainWindow::squareDown begin) + + double imrat = ((double)nx())/ny(); + double winrat = ((double) width())/height(); - if(width() <= height()) - { - resize(width(), width()/imrat); - } - else - { - resize(height()*imrat, height()); - } + ///\todo make threshold responsive to current dimensions so we don't enter loops. + if( fabs( 1.0 - imrat/winrat) < 0.01) + { + DEBUG_TRACE_ANCHOR(rtimvMainWindow::squareDown noop) + return; + } + + if(width() <= height()) + { + DEBUG_TRACE_CRUMB + resize(width(), width()/imrat); + } + else + { + DEBUG_TRACE_CRUMB + resize(height()*imrat, height()); + } + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::squareDown end) } void rtimvMainWindow::squareUp() { - double imrat = ((double)nx())/ny(); - double winrat = ((double) width())/height(); + double imrat = (1.0*nx())/ny(); + double winrat = (1.0*width())/height(); - ///\todo make threshold responsive to current dimensions so we don't enter loops. - if( fabs( 1.0 - imrat/winrat) < 0.01) return; + ///\todo make threshold responsive to current dimensions so we don't enter loops. + if( fabs( 1.0 - imrat/winrat) < 0.01) + { + return; + } - if(width() <= height()) - { - resize(height()*imrat, height()); - } - else - { - resize(width(), width()/imrat); - } + if(width() <= height()) + { + resize(height()*imrat, height()); + } + else + { + resize(width(), width()/imrat); + } } -void rtimvMainWindow::changeCenter() -{ - change_center(); -} - void rtimvMainWindow::resizeEvent(QResizeEvent *) { - ScreenZoom = std::min((float)width()/(float)m_nx,(float)height()/(float)m_ny); - change_center(); - ui.graphicsView->setGeometry(0,0,width(), height()); - post_zoomLevel(); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::resizeEvent begin) + + if(m_nx == 0 || m_ny == 0) + { + DEBUG_TRACE_ANCHOR(rtimvMainWindow::resizeEvent early) + ui.graphicsView->setGeometry(0,0,width(), height()); + return; + } + + m_screenZoom = std::min((float)width()/(float)m_nx,(float)height()/(float)m_ny); + + DEBUG_TRACE_VAL(m_screenZoom) + + change_center(); + + ui.graphicsView->setGeometry(0,0,width(), height()); + DEBUG_TRACE_CRUMB + + post_zoomLevel(); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::resizeEvent end) } void rtimvMainWindow::mouseMoveEvent(QMouseEvent *e) @@ -643,83 +789,138 @@ void rtimvMainWindow::nullMouseCoords() void rtimvMainWindow::updateMouseCoords() { - int64_t idx_x, idx_y; //image size are uint32_t, so this allows signed comparison without overflow issues - - if(!m_qpmi) return; - - if(ui.graphicsView->mouseViewX() < 0 || ui.graphicsView->mouseViewY() < 0) - { - nullMouseCoords(); - } - - QPointF pt = ui.graphicsView->mapToScene(ui.graphicsView->mouseViewX(),ui.graphicsView->mouseViewY()); - - float mx = pt.x(); - float my = pt.y(); - - if( mx < 0 || mx > m_qpmi->boundingRect().width() || my < 0 || my > m_qpmi->boundingRect().height() ) - { - nullMouseCoords(); - } - - if(m_userItemSelected) - { - nullMouseCoords(); - userItemMouseCoords(m_userItemMouseViewX, m_userItemMouseViewY); - } - - if(!m_nullMouseCoords) - { - idx_x = ((int64_t)(mx-0)); - if(idx_x < 0) idx_x = 0; - if(idx_x > (int64_t) m_nx-1) idx_x = m_nx-1; - - idx_y = (int)(m_qpmi->boundingRect().height() - (my-0)); - if(idx_y < 0) idx_y = 0; - if(idx_y > (int64_t) m_ny-1) idx_y = m_ny-1; + DEBUG_TRACE_ANCHOR(rtimvMainWindow::updateMouseCoords begin) - pixelF _pixel = pixel(); - - float val = 0; - if(_pixel != nullptr) val = _pixel(this, (int)(idx_y*m_nx) + (int)(idx_x)); - - if(m_showStaticCoords) - { - ui.graphicsView->textCoordX(mx-0.5); - ui.graphicsView->textCoordY(m_qpmi->boundingRect().height() - my-0.5); - ui.graphicsView->textPixelVal( val ); - } + /*std::unique_lock lock(m_accessMutex, std::try_to_lock); + if(!lock.owns_lock()) + { + DEBUG_TRACE_ANCHOR(rtimvMainWindow::updateMouseCoords no-lock) + return; + }*/ - if(m_showToolTipCoords) - { - char valStr[32]; - char posStr[32]; - - if(fabs(val) < 1e-1) - { - snprintf(valStr, sizeof(valStr), "%0.04g", val); - } - else - { - snprintf(valStr, sizeof(valStr), "%0.02f", val); - } + int64_t idx_x, idx_y; //image size are uint32_t, so this allows signed comparison without overflow issues + + if(!m_qpmi) return; + + DEBUG_TRACE_CRUMB - snprintf(posStr, sizeof(posStr), "%0.2f %0.2f", mx-0.5, m_qpmi->boundingRect().height() - my-0.5 ); + if(ui.graphicsView->mouseViewX() < 0 || ui.graphicsView->mouseViewY() < 0) + { + DEBUG_TRACE_CRUMB + nullMouseCoords(); + } + + DEBUG_TRACE_CRUMB + + QPointF pt = ui.graphicsView->mapToScene(ui.graphicsView->mouseViewX(),ui.graphicsView->mouseViewY()); + + DEBUG_TRACE_CRUMB + float mx = pt.x(); + float my = pt.y(); + + if( mx < 0 || mx > m_qpmi->boundingRect().width() || my < 0 || my > m_qpmi->boundingRect().height() ) + { + DEBUG_TRACE_CRUMB + nullMouseCoords(); + } + + if(m_userItemSelected) + { + DEBUG_TRACE_CRUMB + nullMouseCoords(); + DEBUG_TRACE_CRUMB + userItemMouseCoords(m_userItemMouseViewX, m_userItemMouseViewY); + } - ui.graphicsView->showMouseToolTip(valStr, posStr, QPoint(ui.graphicsView->mouseViewX(),ui.graphicsView->mouseViewY())); - fontLuminance(ui.graphicsView->m_mouseCoords); - } + DEBUG_TRACE_CRUMB - if(imcp) - { - if(_pixel != nullptr) - imcp->updateMouseCoords(mx, my, _pixel(this, idx_y*m_nx + idx_x) ); - } - } + if(!m_nullMouseCoords) + { + DEBUG_TRACE_CRUMB + + idx_x = ((int64_t)(mx-0)); + if(idx_x < 0) idx_x = 0; + if(idx_x > (int64_t) m_nx-1) idx_x = m_nx-1; + + + idx_y = (int)(m_qpmi->boundingRect().height() - (my-0)); + if(idx_y < 0) idx_y = 0; + if(idx_y > (int64_t) m_ny-1) idx_y = m_ny-1; + + DEBUG_TRACE_CRUMB +/* + //pixelF _pixel = nullptr; + float val = 0; + + DEBUG_TRACE_CRUMB + //_pixel = pixel(); + + DEBUG_TRACE_CRUMB + + if(_pixel != nullptr) + { + DEBUG_TRACE_CRUMB + DEBUG_TRACE_VAL(m_nx) + DEBUG_TRACE_VAL(m_images[0]->nx()); + DEBUG_TRACE_VAL(m_ny) + DEBUG_TRACE_VAL(m_images[0]->ny()); + DEBUG_TRACE_VAL(idx_x) + DEBUG_TRACE_VAL(idx_y) + val = _pixel(this, (int)(idx_y*m_nx) + (int)(idx_x)); + } +*/ + float val = calPixel(idx_x, idx_y); + + DEBUG_TRACE_CRUMB + + if(m_showStaticCoords) + { + ui.graphicsView->textCoordX(mx-0.5); + ui.graphicsView->textCoordY(m_qpmi->boundingRect().height() - my-0.5); + ui.graphicsView->textPixelVal( val ); + } + + DEBUG_TRACE_CRUMB + + if(m_showToolTipCoords) + { + DEBUG_TRACE_CRUMB + + char valStr[32]; + char posStr[32]; + + if(fabs(val) < 1e-1) + { + snprintf(valStr, sizeof(valStr), "%0.04g", val); + } + else + { + snprintf(valStr, sizeof(valStr), "%0.02f", val); + } + snprintf(posStr, sizeof(posStr), "%0.2f %0.2f", mx-0.5, m_qpmi->boundingRect().height() - my-0.5 ); + ui.graphicsView->showMouseToolTip(valStr, posStr, QPoint(ui.graphicsView->mouseViewX(),ui.graphicsView->mouseViewY())); + DEBUG_TRACE_CRUMB + fontLuminance(ui.graphicsView->m_mouseCoords); + DEBUG_TRACE_CRUMB + } + + DEBUG_TRACE_CRUMB + + if(imcp) + { + DEBUG_TRACE_CRUMB + imcp->updateMouseCoords(mx, my, val ); + } + + } + + DEBUG_TRACE_CRUMB //Adjust bias and contrast if(rightClickDragging) { + DEBUG_TRACE_CRUMB + float dx = ui.graphicsView->mouseViewX() - rightClickStart.x(); float dy = ui.graphicsView->mouseViewY() - rightClickStart.y(); @@ -731,8 +932,8 @@ void rtimvMainWindow::updateMouseCoords() if(!amChangingimdata) changeImdata(); } - -} + DEBUG_TRACE_ANCHOR(rtimvMainWindow::updateMouseCoords end) +} //rtimvMainWindow::updateMouseCoords bool rtimvMainWindow::showToolTipCoords() { @@ -805,7 +1006,6 @@ void rtimvMainWindow::onWheelMoved(int delta) } - void rtimvMainWindow::updateFPS() { updateAge(); @@ -813,8 +1013,11 @@ void rtimvMainWindow::updateFPS() void rtimvMainWindow::updateAge() { - //Check the font luminance to make sure it is visible + //Check the font luminance to make sure it is visibleDEBUG_TRACE_CRUMB + DEBUG_TRACE_CRUMB fontLuminance(); + DEBUG_TRACE_CRUMB + if(m_showFPSGage && m_images[0] != nullptr ) { @@ -881,7 +1084,9 @@ void rtimvMainWindow::userBoxItemSize(StretchBox * sb) ui.graphicsView->m_userItemSize->resize(textSize.width()+5,textSize.height()+5); ui.graphicsView->m_userItemSize->move(qr.x(), qr.y()); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_userItemSize); + DEBUG_TRACE_CRUMB } void rtimvMainWindow::userBoxItemCoords(StretchBox * sb) @@ -917,7 +1122,9 @@ void rtimvMainWindow::userCircleItemSize(StretchCircle * sc) ui.graphicsView->m_userItemSize->resize(textSize.width()+5,textSize.height()+5); ui.graphicsView->m_userItemSize->move(qr.x(), qr.y()); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_userItemSize); + DEBUG_TRACE_CRUMB } void rtimvMainWindow::userCircleItemCoords(StretchCircle * sc) @@ -939,6 +1146,8 @@ void rtimvMainWindow::userItemMouseCoords( float mx, float my ) { + if(m_qpmi == nullptr) return; + int idx_x = ((int64_t)(mx-0)); if(idx_x < 0) idx_x = 0; if(idx_x > (int64_t) m_nx-1) idx_x = m_nx-1; @@ -947,34 +1156,53 @@ void rtimvMainWindow::userItemMouseCoords( float mx, if(idx_y < 0) idx_y = 0; if(idx_y > (int64_t) m_ny-1) idx_y = m_ny-1; - pixelF _pixel = pixel(); - + /*pixelF _pixel = pixel(); float val = 0; - if(_pixel != nullptr) val = _pixel(this, (int)(idx_y*m_nx) + (int)(idx_x)); - - char valStr[32]; - char posStr[32]; - - if(fabs(val) < 1e-1) - { - snprintf(valStr, sizeof(valStr), "%0.04g", val); - } - else + + //Mutex scope { - snprintf(valStr, sizeof(valStr), "%0.02f", val); - } + std::unique_lock lock(m_accessMutex, std::try_to_lock); + if(lock.owns_lock()) + { + _pixel = pixel(); + if(_pixel != nullptr) val = _pixel(this, (int)(idx_y*m_nx) + (int)(idx_x)); + } + } + //Here either _pixel is not null, and val is a good value + // or _pixel is null and we should ignore val + if(_pixel == nullptr) return; +*/ - snprintf(posStr, sizeof(posStr), "%0.2f %0.2f", mx-0.5, m_qpmi->boundingRect().height() - my-0.5 ); + float val = calPixel(idx_x, idx_y); - std::string str = std::string(valStr) + "\n" + posStr; - ui.graphicsView->m_userItemMouseCoords->setPlainText(str.c_str()); + char valStr[32]; + char posStr[32]; + + if(fabs(val) < 1e-1) + { + snprintf(valStr, sizeof(valStr), "%0.04g", val); + } + else + { + snprintf(valStr, sizeof(valStr), "%0.02f", val); + } + + + snprintf(posStr, sizeof(posStr), "%0.2f %0.2f", mx-0.5, m_qpmi->boundingRect().height() - my-0.5 ); + + std::string str = std::string(valStr) + "\n" + posStr; + ui.graphicsView->m_userItemMouseCoords->setPlainText(str.c_str()); + + QFontMetrics fm(ui.graphicsView->m_userItemMouseCoords->currentFont()); + QSize textSize = fm.size(0, str.c_str()); + ui.graphicsView->m_userItemMouseCoords->setGeometry(mx, my, textSize.width()+5,textSize.height()+5); + + DEBUG_TRACE_CRUMB - QFontMetrics fm(ui.graphicsView->m_userItemMouseCoords->currentFont()); - QSize textSize = fm.size(0, str.c_str()); - ui.graphicsView->m_userItemMouseCoords->setGeometry(mx, my, textSize.width()+5,textSize.height()+5); + fontLuminance(ui.graphicsView->m_userItemMouseCoords); - fontLuminance(ui.graphicsView->m_userItemMouseCoords); + DEBUG_TRACE_CRUMB } @@ -1012,8 +1240,8 @@ void rtimvMainWindow::addUserBox() StretchBox * sb = *it.first; sb->setPenColor("lime"); - sb->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sb->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); + sb->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sb->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); sb->setMaintainCenter(true); sb->setStretchable(true); @@ -1046,8 +1274,8 @@ void rtimvMainWindow::addUserCircle() StretchCircle * sc = *it.first; sc->setPenColor("lime"); - sc->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sc->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); + sc->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sc->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); sc->setStretchable(true); sc->setVisible(true); @@ -1079,8 +1307,8 @@ void rtimvMainWindow::addUserLine() StretchLine * sl = *it.first; sl->setPenColor("lime"); - sl->setEdgeTol(RTIMV_EDGETOL_DEFAULT/ScreenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/ScreenZoom); - sl->setPenWidth(2*RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); + sl->setEdgeTol(RTIMV_EDGETOL_DEFAULT/m_screenZoom < RTIMV_EDGETOL_DEFAULT ? RTIMV_EDGETOL_DEFAULT : RTIMV_EDGETOL_DEFAULT/m_screenZoom); + sl->setPenWidth(2*RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); sl->setStretchable(true); sl->setVisible(true); @@ -1147,12 +1375,16 @@ void rtimvMainWindow::targetVisible(bool tv) if(tv) { ui.graphicsView->zoomText("target on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->zoomText("target off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } m_targetVisible = tv; @@ -1286,6 +1518,7 @@ void rtimvMainWindow::statsBoxMoved(StretchBox * sb) static_cast(sb); if(!m_statsBox) return; + if(!m_qpmi) return; QPointF np = m_qpmi->mapFromItem(m_statsBox, QPointF(m_statsBox->rect().x(),m_statsBox->rect().y())); QPointF np2 = m_qpmi->mapFromItem(m_statsBox, QPointF(m_statsBox->rect().x()+m_statsBox->rect().width(),m_statsBox->rect().y()+m_statsBox->rect().height())); @@ -1300,7 +1533,8 @@ void rtimvMainWindow::statsBoxMoved(StretchBox * sb) void rtimvMainWindow::colorBoxMoved(StretchBox * sb) { if(!m_colorBox) return; - + if(!m_qpmi) return; + QRectF newr = sb->rect(); QPointF np = m_qpmi->mapFromItem(m_colorBox, QPointF(newr.x(),newr.y())); @@ -1516,12 +1750,14 @@ void rtimvMainWindow::userLineResized(StretchLine * sl) void rtimvMainWindow::userLineMoved(StretchLine * sl) { + if(!m_qpmi) return; + QPointF np = m_qpmi->mapFromItem(sl, sl->line().p2()); float x = np.x(); float y = np.y(); - ui.graphicsView->m_userItemSize->setGeometry(x*ScreenZoom, y*ScreenZoom-20., 200,40); + ui.graphicsView->m_userItemSize->setGeometry(x*m_screenZoom, y*m_screenZoom-20., 200,40); m_userItemXCen = sl->line().x1(); m_userItemYCen = sl->line().y1(); @@ -1768,12 +2004,16 @@ void rtimvMainWindow::setAutoScale( bool as ) if(m_autoScale) { ui.graphicsView->zoomText("autoscale on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->zoomText("autoscale off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -1791,11 +2031,23 @@ void rtimvMainWindow::toggleAutoScale() void rtimvMainWindow::center() { - set_viewcen(.5, .5); - post_zoomLevel(); - - ui.graphicsView->zoomText("centered"); - fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::center begin) + + set_viewcen(.5, .5); + + DEBUG_TRACE_CRUMB + + post_zoomLevel(); + + DEBUG_TRACE_CRUMB + + ui.graphicsView->zoomText("centered"); + + DEBUG_TRACE_CRUMB + + fontLuminance(ui.graphicsView->m_zoomText); + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::center begin) } void rtimvMainWindow::toggleColorBox() @@ -1814,7 +2066,7 @@ void rtimvMainWindow::toggleColorBox() m_colorBox = new StretchBox(colorBox_i0, colorBox_j0, w, w); m_colorBox->setPenColor("Yellow"); - m_colorBox->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); + m_colorBox->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); m_colorBox->setVisible(false); m_colorBox->setStretchable(true); m_colorBox->setRemovable(false); @@ -1836,7 +2088,9 @@ void rtimvMainWindow::toggleColorBox() setUserBoxActive(true); } ui.graphicsView->zoomText("color box scale"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { @@ -1850,7 +2104,9 @@ void rtimvMainWindow::toggleColorBox() setUserBoxActive(false); } ui.graphicsView->zoomText("global scale"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -1864,7 +2120,7 @@ void rtimvMainWindow::toggleStatsBox() m_statsBox = new StretchBox(0.5*(m_nx)-w/2,0.5*(m_ny)-w/2, w, w); m_statsBox->setPenColor("#3DA5FF"); - m_statsBox->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /ScreenZoom); + m_statsBox->setPenWidth(RTIMV_TOOLLINEWIDTH_DEFAULT /m_screenZoom); m_statsBox->setVisible(false); m_statsBox->setStretchable(true); m_statsBox->setRemovable(true); @@ -1879,7 +2135,9 @@ void rtimvMainWindow::toggleStatsBox() { doHideStatsBox(); ui.graphicsView->zoomText("stats off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB if(imcp) { imcp->statsBoxButtonState = false; @@ -1890,7 +2148,9 @@ void rtimvMainWindow::toggleStatsBox() { doLaunchStatsBox(); ui.graphicsView->zoomText("stats on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB if(imcp) { imcp->statsBoxButtonState = true; @@ -1916,14 +2176,18 @@ void rtimvMainWindow::toggleNorthArrow() m_northArrow->setVisible(false); m_northArrowTip->setVisible(false); ui.graphicsView->zoomText("North Off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { m_northArrow->setVisible(true); m_northArrowTip->setVisible(true); ui.graphicsView->zoomText("North On"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -1934,13 +2198,17 @@ void rtimvMainWindow::showFPSGage( bool sfg ) if(m_showFPSGage) { ui.graphicsView->zoomText("fps gage on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->fpsGageText(""); ui.graphicsView->zoomText("fps gage off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -1962,12 +2230,16 @@ void rtimvMainWindow::setDarkSub( bool ds ) if(m_subtractDark) { ui.graphicsView->zoomText("dark sub. on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->zoomText("dark sub. off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } changeImdata(false); } @@ -1990,12 +2262,16 @@ void rtimvMainWindow::setApplyMask( bool am ) if(m_applyMask) { ui.graphicsView->zoomText("mask on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->zoomText("mask off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } changeImdata(false); } @@ -2018,12 +2294,16 @@ void rtimvMainWindow::setApplySatMask( bool as ) if(m_applySatMask) { ui.graphicsView->zoomText("sat mask on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { ui.graphicsView->zoomText("sat mask off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } changeImdata(false); @@ -2050,13 +2330,17 @@ void rtimvMainWindow::toggleLogLinear() { set_cbStretch(stretchLinear); ui.graphicsView->zoomText("linear stretch"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { set_cbStretch(stretchLog); ui.graphicsView->zoomText("log stretch"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -2065,20 +2349,18 @@ void rtimvMainWindow::toggleTarget() if(m_targetVisible) { targetVisible(false); -/* m_cenLineVert->setVisible(false); - m_cenLineHorz->setVisible(false); - m_targetVisible = false;*/ ui.graphicsView->zoomText("target off"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } else { targetVisible(true); - /*m_cenLineVert->setVisible(true); - m_cenLineHorz->setVisible(true); - m_targetVisible=true;*/ ui.graphicsView->zoomText("target on"); + DEBUG_TRACE_CRUMB fontLuminance(ui.graphicsView->m_zoomText); + DEBUG_TRACE_CRUMB } } @@ -2243,6 +2525,40 @@ void rtimvMainWindow::toggleInfo() } } +void rtimvMainWindow::borderWarningLevel(rtimv::warningLevel & lvl) +{ + m_borderWarningLevel = lvl; + + if(lvl == rtimv::warningLevel::alert) + { + ui.graphicsView->setStyleSheet("#graphicsView {border: 2px solid magenta}"); + int w=width(); + resize(w+1, height()); + resize(w,height()); + } + else if(lvl == rtimv::warningLevel::warning) + { + ui.graphicsView->setStyleSheet("#graphicsView {border: 2px solid red}"); + int w=width(); + resize(w+1, height()); + resize(w,height()); + } + else if(lvl == rtimv::warningLevel::caution) + { + ui.graphicsView->setStyleSheet("#graphicsView {border: 2px solid yellow}"); + int w=width(); + resize(w+1, height()); + resize(w,height()); + } + else //(lvl == rtimv::warningLevel::normal) + { + ui.graphicsView->setStyleSheet("#graphicsView {border: 0px solid black}"); + int w=width(); + resize(w+1, height()); + resize(w,height()); + } +} + template realT sRGBtoLinRGB( int rgb ) { @@ -2278,87 +2594,101 @@ void rtimvMainWindow::fontLuminance( QTextEdit* qte, bool print ) { - - QPointF ptul = ui.graphicsView->mapToScene(qte->x(),qte->y()); - QPointF ptlr = ui.graphicsView->mapToScene(qte->x()+qte->width(),qte->y()+qte->height()); - - unsigned myul = ptul.y(); - if(myul > m_ny-1) myul = 0; - - unsigned mxul = ptul.x(); - if(mxul > m_nx-1) mxul = 0; - - unsigned mylr = ptlr.y(); - if(mylr > m_ny-1) mylr = m_ny-1; - - unsigned mxlr = ptlr.x(); - if(mxlr > m_nx-1) mxlr = m_nx-1; - - if(mxul == 0 && myul == 0 && mxlr == 0 && mylr == 0) return; - if(mxul == mxlr || myul == mylr) return; - - double avgLum = 0; - int N = 0; - for(unsigned x = mxul; x<= mxlr; ++x) - { - for(unsigned y=myul; y<=mylr; ++y) - { - avgLum += pow(m_lightness[ m_qim->pixelIndex(x,y) ],m_lumPwr); - ++N; - } - } - avgLum /= N; - avgLum = pow(avgLum, 1.0/m_lumPwr); + /*std::unique_lock lock(m_accessMutex, std::try_to_lock); + if(!lock.owns_lock()) + { + DEBUG_TRACE_ANCHOR(rtimvMainWindow::fontLuminance early-no-lock) + return; + }*/ - if(print) std::cerr << "avgLum: " << avgLum << "\n"; + DEBUG_TRACE_ANCHOR(rtimvMainWindow::fontLuminance(QTextEdit *, bool) begin) - if(avgLum <= m_lumThresh) - { - qte->setTextBackgroundColor(QColor(0,0,0,0)); - } - else if(avgLum < m_lumMax) - { - int op = (avgLum - m_lumThresh)/(m_lumMax - m_lumThresh) * m_opacityMax + 0.5; - qte->setTextBackgroundColor(QColor(0,0,0,op)); - } - else - { - qte->setTextBackgroundColor(QColor(0,0,0,m_opacityMax)); - } + QPointF ptul = ui.graphicsView->mapToScene(qte->x(),qte->y()); + QPointF ptlr = ui.graphicsView->mapToScene(qte->x()+qte->width(),qte->y()+qte->height()); + + unsigned myul = ptul.y(); + if(myul > m_ny-1) myul = 0; + + unsigned mxul = ptul.x(); + if(mxul > m_nx-1) mxul = 0; + + unsigned mylr = ptlr.y(); + if(mylr > m_ny-1) mylr = m_ny-1; + + unsigned mxlr = ptlr.x(); + if(mxlr > m_nx-1) mxlr = m_nx-1; + + if(mxul == 0 && myul == 0 && mxlr == 0 && mylr == 0) return; + if(mxul == mxlr || myul == mylr) return; + + double avgLum = 0; + int N = 0; + for(unsigned x = mxul; x<= mxlr; ++x) + { + for(unsigned y=myul; y<=mylr; ++y) + { + avgLum += pow(m_lightness[ m_qim->pixelIndex(x,y) ],m_lumPwr); + ++N; + } + } + avgLum /= N; + avgLum = pow(avgLum, 1.0/m_lumPwr); + + if(print) std::cerr << "avgLum: " << avgLum << "\n"; + + if(avgLum <= m_lumThresh) + { + qte->setTextBackgroundColor(QColor(0,0,0,0)); + } + else if(avgLum < m_lumMax) + { + int op = (avgLum - m_lumThresh)/(m_lumMax - m_lumThresh) * m_opacityMax + 0.5; + qte->setTextBackgroundColor(QColor(0,0,0,op)); + } + else + { + qte->setTextBackgroundColor(QColor(0,0,0,m_opacityMax)); + } + + DEBUG_TRACE_ANCHOR(rtimvMainWindow::fontLuminance(QTextEdit *, bool) end) - return; + return; } void rtimvMainWindow::fontLuminance() { - fontLuminance(ui.graphicsView->m_fpsGage); + DEBUG_TRACE_ANCHOR(rtimvMainWindow::fontLuminance() begin) + + fontLuminance(ui.graphicsView->m_fpsGage); - fontLuminance(ui.graphicsView->m_zoomText); + fontLuminance(ui.graphicsView->m_zoomText); - if(!m_nullMouseCoords) - { - if(m_showStaticCoords) - { - fontLuminance(ui.graphicsView->m_textCoordX); - fontLuminance(ui.graphicsView->m_textCoordY); - fontLuminance(ui.graphicsView->m_textPixelVal); - } + if(!m_nullMouseCoords) + { + if(m_showStaticCoords) + { + fontLuminance(ui.graphicsView->m_textCoordX); + fontLuminance(ui.graphicsView->m_textCoordY); + fontLuminance(ui.graphicsView->m_textPixelVal); + } - if(m_showToolTipCoords) - { - fontLuminance(ui.graphicsView->m_mouseCoords); - } - } + if(m_showToolTipCoords) + { + fontLuminance(ui.graphicsView->m_mouseCoords); + } + } - for(size_t n=0; n< ui.graphicsView->m_statusText.size(); ++n) - { - if(ui.graphicsView->m_statusText[n]->toPlainText().size() > 0) fontLuminance(ui.graphicsView->m_statusText[n]); - } + for(size_t n=0; n< ui.graphicsView->m_statusText.size(); ++n) + { + if(ui.graphicsView->m_statusText[n]->toPlainText().size() > 0) fontLuminance(ui.graphicsView->m_statusText[n]); + } - fontLuminance(ui.graphicsView->m_saveBox); + fontLuminance(ui.graphicsView->m_saveBox); - return; + DEBUG_TRACE_ANCHOR(rtimvMainWindow::fontLuminance() end) + + return; } diff --git a/src/rtimvMainWindow.hpp b/src/rtimvMainWindow.hpp index 80e9714..ca693b2 100644 --- a/src/rtimvMainWindow.hpp +++ b/src/rtimvMainWindow.hpp @@ -58,14 +58,13 @@ class rtimvMainWindow : public rtimvBase, public application ~rtimvMainWindow(); -public: virtual void setupConfig(); virtual void loadConfig(); protected: std::string m_title{"rtimv"}; - + public: /// Called on initial connection to the image stream, sets matching aspect ratio. virtual void onConnect(); @@ -104,7 +103,7 @@ class rtimvMainWindow : public rtimvBase, public application QGraphicsScene *m_qgs{nullptr}; QGraphicsPixmapItem *m_qpmi{nullptr}; - float ScreenZoom; + float m_screenZoom; public: QGraphicsScene *get_qgs(); @@ -168,8 +167,11 @@ public slots: /*** The Main View ***/ public: void change_center(bool movezoombox = true); + void set_viewcen(float x, float y, bool movezoombox = true); + float get_xcen() { return ui.graphicsView->xCen(); } + float get_ycen() { return ui.graphicsView->yCen(); } /// Matches the viewport to the same aspect ratio as the image data, by decreasing the area. @@ -191,7 +193,10 @@ public slots: void squareUp(); protected slots: - void changeCenter(); + void changeCenter() + { + change_center(); + } /// Calls changeCenter() so that the display stays centered when user resizes. void resizeEvent(QResizeEvent *); @@ -398,7 +403,7 @@ protected slots: void addStretchCircle(StretchCircle *sc /**< [in] The new StretchCircle to add*/); /// Add a StretchLine to the user lines - /** This addes the StretchLine to the user boxes, and connects + /** This adds the StretchLine to the user boxes, and connects * its rejectMouse signal to the userLineRejectMouse slot so that * the mouse though management works. The remove signal is connected to the * userLineRemove slog. None of the other signals are connected. @@ -498,6 +503,29 @@ protected slots: void toggleInfo(); + /** \name Border Colors + * @{ + */ + +protected: + + rtimv::warningLevel m_borderWarningLevel {rtimv::warningLevel::normal}; + +public slots: + + /// Set the warning level for the border color + /** The levels are + * -0 no warning, uses default border color + * -1 caution, uses caution color (yellow) + * -2 warning, uses warning color (red) + * -3 (or greater) alert, uses alert color (pink) + * + */ + void borderWarningLevel(rtimv::warningLevel & lvl); + + + ///@} + /** \name Font Luminance * * Tools to change the opacity of the overlay font background color based on the diff --git a/src/rtimvStats.cpp b/src/rtimvStats.cpp index 894bb7e..1be8084 100644 --- a/src/rtimvStats.cpp +++ b/src/rtimvStats.cpp @@ -99,6 +99,7 @@ void rtimvStats::calcStats() std::unique_lock lock(m_dataMutex, std::try_to_lock); if(!lock.owns_lock()) return; + /* float (*_pixel)(rtimvBase*, size_t) = m_imv->pixel(); if(_pixel == nullptr) @@ -106,19 +107,19 @@ void rtimvStats::calcStats() m_regionChanged = 0; return; //invalid data } - + */ //copy data so we can be safe from changes to image memory for(size_t i=m_x0; iimageValid(0) == false) //Check every time to be as robust as possible. { m_regionChanged = 0; return; - } - m_imdata(i-m_x0, j-m_y0) = _pixel(m_imv, idx); + }*/ + m_imdata(i-m_x0, j-m_y0) = m_imv->calPixel(i,j); //_pixel(m_imv, idx); } }