Commit cd6ad90ac3f508fdf36afd9c0d74f304a5dc2809

Authored by Charles Otto
1 parent 0fc6c503

Fix a crash in Show2 transform

Send a deep copy of the current image to the GUI thread, copy must be called
explicitly or a shallow copy will be done, and subsequent modifications to the
buffer will cause crashes when the GUI thread tries to draw it.
Showing 1 changed file with 16 additions and 15 deletions
sdk/plugins/gui.cpp
@@ -7,7 +7,6 @@ using namespace cv; @@ -7,7 +7,6 @@ using namespace cv;
7 7
8 namespace br 8 namespace br
9 { 9 {
10 -  
11 QImage toQImage(const Mat &mat) 10 QImage toQImage(const Mat &mat)
12 { 11 {
13 // Convert to 8U depth 12 // Convert to 8U depth
@@ -53,28 +52,26 @@ QImage toQImage(const Mat &mat) @@ -53,28 +52,26 @@ QImage toQImage(const Mat &mat)
53 class GUIProxy : public QObject 52 class GUIProxy : public QObject
54 { 53 {
55 Q_OBJECT 54 Q_OBJECT
56 - 55 +public:
57 QLabel * window; 56 QLabel * window;
58 57
59 -public:  
60 GUIProxy() 58 GUIProxy()
61 { 59 {
62 - window =NULL; 60 + window = NULL;
63 } 61 }
64 62
65 public slots: 63 public slots:
66 - void showImage(QPixmap pixmap) 64 +
  65 + void showImage(const QPixmap & input)
67 { 66 {
68 - window->show();  
69 - window->setPixmap(pixmap);  
70 - window->setFixedSize(pixmap.size());  
71 - window->update(); 67 + window->setPixmap(input);
  68 + window->setFixedSize(input.size());
  69 + window->setVisible(true);
72 } 70 }
73 71
74 void createWindow() 72 void createWindow()
75 { 73 {
76 delete window; 74 delete window;
77 - window = NULL;  
78 window = new QLabel(); 75 window = new QLabel();
79 } 76 }
80 }; 77 };
@@ -99,7 +96,7 @@ public: @@ -99,7 +96,7 @@ public:
99 gui->moveToThread(QApplication::instance()->thread()); 96 gui->moveToThread(QApplication::instance()->thread());
100 // Connect our signals to the proxy's slots 97 // Connect our signals to the proxy's slots
101 connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection); 98 connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection);
102 - connect(this, SIGNAL(updateImage(QPixmap)), gui, SLOT(showImage(QPixmap))); 99 + connect(this, SIGNAL(updateImage(QPixmap)), gui,SLOT(showImage(QPixmap)));
103 } 100 }
104 101
105 ~Show2Transform() 102 ~Show2Transform()
@@ -124,9 +121,12 @@ public: @@ -124,9 +121,12 @@ public:
124 121
125 foreach (const Template & t, src) { 122 foreach (const Template & t, src) {
126 foreach(const cv::Mat & m, t) { 123 foreach(const cv::Mat & m, t) {
127 - QImage qImageBuffer = toQImage(m); 124 + qImageBuffer = toQImage(m);
128 displayBuffer.convertFromImage(qImageBuffer); 125 displayBuffer.convertFromImage(qImageBuffer);
129 - emit updateImage(displayBuffer); 126 + // Emit an explicit copy of our pixmap so that the pixmap used
  127 + // by the main thread isn't damaged when we update displayBuffer
  128 + // later.
  129 + emit updateImage(displayBuffer.copy(displayBuffer.rect()));
130 } 130 }
131 } 131 }
132 } 132 }
@@ -134,7 +134,7 @@ public: @@ -134,7 +134,7 @@ public:
134 void finalize(TemplateList & output) 134 void finalize(TemplateList & output)
135 { 135 {
136 (void) output; 136 (void) output;
137 - // todo: hide ui? 137 + // todo: hide window?
138 } 138 }
139 139
140 void init() 140 void init()
@@ -144,11 +144,12 @@ public: @@ -144,11 +144,12 @@ public:
144 144
145 protected: 145 protected:
146 GUIProxy * gui; 146 GUIProxy * gui;
  147 + QImage qImageBuffer;
147 QPixmap displayBuffer; 148 QPixmap displayBuffer;
148 149
149 signals: 150 signals:
150 void needWindow(); 151 void needWindow();
151 - void updateImage(QPixmap input); 152 + void updateImage(const QPixmap & input);
152 }; 153 };
153 154
154 BR_REGISTER(Transform, Show2Transform) 155 BR_REGISTER(Transform, Show2Transform)