Isis 3 Programmer Reference
ImageReader.cpp
1#include "ImageReader.h"
2
3#include <QAction>
4#include <QApplication>
5#include <QDebug>
6#include <QFuture>
7#include <QFutureWatcher>
8#include <QInputDialog>
9#include <QList>
10#include <QProgressBar>
11#include <QSettings>
12#include <QString>
13#include <QtConcurrentMap>
14#include <QVariant>
15
16#include "IException.h"
17#include "Image.h"
19#include "IString.h"
20#include "FileName.h"
21#include "ProgressBar.h"
22#include "PvlObject.h"
23
24namespace Isis {
25
35 ImageReader::ImageReader(QMutex *cameraMutex, bool requireFootprints, QObject *parent) :
36 QObject(parent) {
37 m_watcher = NULL;
38
39 m_cameraMutex = cameraMutex;
40 m_requireFootprints = requireFootprints;
41
42 m_progress = new ProgressBar("Reading Images");
43 m_watcher = new QFutureWatcher<Image *>;
44
45 initProgress();
46
47 connect(m_watcher, SIGNAL(resultReadyAt(int)),
48 this, SLOT(imageReady(int)));
49 connect(m_watcher, SIGNAL(finished()),
50 this, SLOT(mappedFinished()));
51
52 m_safeFileOpen = false;
53 m_openFilled = true;
54 m_defaultAlpha = 60;
55
56 m_mappedRunning = false;
57
58 readSettings();
59 }
60
61
66 writeSettings();
67
68 if (m_watcher) {
69 m_watcher->cancel();
70 m_watcher->waitForFinished();
71 }
72
73 delete m_watcher;
74 m_watcher = NULL;
75
76 m_backlog.clear();
77
78 m_cameraMutex = NULL;
79
80 delete m_progress;
81 }
82
83
84 QList<QAction *> ImageReader::actions(ImageDisplayProperties::Property relevantDispProperties) {
85 QList<QAction *> results;
86
87 if (!m_safeFileOpenAct) {
88 m_safeFileOpenAct = new QAction(tr("&Safe File Open"), this);
89 m_safeFileOpenAct->setCheckable(true);
90 m_safeFileOpenAct->setChecked(m_safeFileOpen);
91 m_safeFileOpenAct->setWhatsThis(tr("This lowers the number of "
92 "simulataneously open files drastically in order to stay under the "
93 "operating system limit. Only use this if you are having trouble "
94 "loading large numbers of images."));
95 connect(m_safeFileOpenAct, SIGNAL(toggled(bool)),
96 this, SLOT(setSafeFileOpen(bool)));
97 }
98
99 results.append(m_safeFileOpenAct);
100
101 if ((relevantDispProperties & ImageDisplayProperties::ShowFill) == ImageDisplayProperties::ShowFill) {
102 if (!m_openFilledAct) {
103 m_openFilledAct = new QAction(tr("Default Images &Filled"), this);
104 m_openFilledAct->setCheckable(true);
105 m_openFilledAct->setChecked(m_openFilled);
106 m_openFilledAct->setWhatsThis(tr("When this is enabled, images will be overlayed with "
107 "a color."));
108 connect(m_openFilledAct, SIGNAL(toggled(bool)),
109 this, SLOT(setOpenFilled(bool)));
110 }
111
112 results.append(m_openFilledAct);
113 }
114
115 if ((relevantDispProperties & ImageDisplayProperties::Color) == ImageDisplayProperties::Color) {
116 if (!m_askAlphaAct) {
117 m_askAlphaAct = new QAction(tr("Set Default &Transparency"), this);
118 connect(m_askAlphaAct, SIGNAL(triggered(bool)),
119 this, SLOT(askDefaultAlpha()));
120 }
121
122 results.append(m_askAlphaAct);
123 }
124
125 return results;
126 }
127
128
129 QProgressBar *ImageReader::progress() {
130 return m_progress;
131 }
132
133
134 void ImageReader::askDefaultAlpha() {
135 bool ok = false;
136 int alpha = QInputDialog::getInt(NULL, tr("Transparency Value"),
137 tr("Set the default transparency value\n"
138 "Values are 0 (invisible) to 255 (solid)"),
139 m_defaultAlpha, 0, 255, 1, &ok);
140
141 if(ok) {
142 m_defaultAlpha = alpha;
143 }
144 }
145
146
147 void ImageReader::read(PvlObject imagesObject) {
148 read(imagesObject.beginObject(), imagesObject.endObject());
149 }
150
151
155 void ImageReader::read(QStringList cubeNames) {
156 read(cubeNames.begin(), cubeNames.end());
157 }
158
159
160 void ImageReader::setOpenFilled(bool openFilled) {
161 m_openFilled = openFilled;
162 if (m_openFilledAct) {
163 m_openFilledAct->setChecked(m_openFilled);
164 }
165 }
166
167
168 void ImageReader::setSafeFileOpen(bool safeFileOpen) {
169 m_safeFileOpen = safeFileOpen;
170 if (m_safeFileOpen) {
171 m_safeFileOpenAct->setChecked(m_safeFileOpen);
172 }
173 }
174
175
176 void ImageReader::initProgress() {
177 m_progress->setVisible(false);
178 m_progress->setRange(0, 0);
179 m_progress->setValue(0);
180 }
181
182
183 void ImageReader::start() {
184 if (!m_backlog.isEmpty() && !m_mappedRunning) {
185 m_progress->setVisible(true);
186
187 int maxOpenImages = m_safeFileOpen? 20 : 400;
188 QList<QVariant> culledBacklog = m_backlog.mid(0, maxOpenImages);
189 m_backlog = m_backlog.mid(maxOpenImages);
190
191 QFuture< Image * > images = QtConcurrent::mapped(
192 culledBacklog,
193 VariantToImageFunctor(m_cameraMutex, m_requireFootprints, QThread::currentThread(),
194 m_openFilled, m_defaultAlpha));
195
196 m_watcher->setFuture(images);
197 m_mappedRunning = true;
198 }
199 }
200
201
202 void ImageReader::readSettings() {
203 QSettings settings(
204 FileName("$HOME/.Isis/" + QApplication::applicationName() + "/Image Reader.config")
205 .expanded(),
206 QSettings::NativeFormat);
207
208 m_safeFileOpen = settings.value("safeFileOpen", m_safeFileOpen).toBool();
209 m_openFilled = settings.value("openFilled", m_openFilled).toBool();
210 m_defaultAlpha = settings.value("defaultAlpha", m_defaultAlpha).toInt();
211 }
212
213
214 void ImageReader::writeSettings() {
215 QSettings settings(
216 FileName("$HOME/.Isis/" + QApplication::applicationName() + "/Image Reader.config")
217 .expanded(),
218 QSettings::NativeFormat);
219
220 settings.setValue("safeFileOpen", m_safeFileOpen);
221 settings.setValue("openFilled", m_openFilled);
222 settings.setValue("defaultAlpha", m_defaultAlpha);
223 }
224
225
226 void ImageReader::imageReady(int index) {
227 m_progress->setValue(m_progress->value() + 1);
228 }
229
230
231 void ImageReader::mappedFinished() {
232 ImageList images(m_watcher->future().results());
233
234 // Tracie Sucharski: Go through list & get rid of NULLs. This is a temporary fix to get rid
235 // of seg faulting when something goes wrong. This is not a good solution & needs to be
236 // properly fixed
237 foreach (Image *image, images) {
238 if (!image) {
239 images.removeAll(image);
240 }
241 }
242
243 emit imagesReady(images);
244
245 m_mappedRunning = false;
246 if (!m_backlog.isEmpty()) {
247 start();
248 }
249 else {
250 initProgress();
251 }
252 }
253
254
261 QMutex *cameraMutex, bool requireFootprints, QThread *targetThread, bool openFilled,
262 int defaultAlpha) {
263 m_mutex = cameraMutex;
264 m_targetThread = targetThread;
265 m_openFilled = openFilled;
266 m_defaultAlpha = defaultAlpha;
267 m_requireFootprints = requireFootprints;
268 }
269
270
279 const QVariant &imageData) {
280 Image *result = NULL;
281
282 try {
283 QString fileName;
284 if (imageData.canConvert<QString>()) {
285 fileName = imageData.value<QString>();
286
287 result = new Image(FileName(fileName).expanded());
288 ImageDisplayProperties *prop = result->displayProperties();
289 prop->setShowFill(m_openFilled);
290
291 QColor newColor = prop->getValue(ImageDisplayProperties::Color).value<QColor>();
292 newColor.setAlpha(m_defaultAlpha);
293
294 prop->setColor(newColor);
295 }
296 else if (imageData.canConvert<PvlObject>()) {
297 PvlObject imageObj = imageData.value<PvlObject>();
298 fileName = ((IString)imageObj["FileName"][0]).ToQt();
299 result = new Image(FileName(fileName).expanded());
300 result->fromPvl(imageObj);
301 }
302
303 if (m_requireFootprints) {
304 try {
305 result->initFootprint(m_mutex);
306 }
307 catch (IException &) {
308 throw;
309 }
310 }
311
312 result->moveToThread(m_targetThread);
313 }
314 catch(IException &e) {
315 e.print();
316 result = NULL;
317 }
318
319 return result;
320 }
321}
File name manipulation and expansion.
Definition FileName.h:100
Isis exception class.
Definition IException.h:91
Adds specific functionality to C++ strings.
Definition IString.h:165
This is the GUI communication mechanism for cubes.
Property
This is a list of properties and actions that are possible.
@ ShowFill
True if the cube should show a fill area if possible (bool)
@ Color
The color of the cube, default randomized (QColor)
This represents a cube in a project-based GUI interface.
Definition Image.h:107
void fromPvl(const PvlObject &pvl)
Read the image settings from a Pvl.
Definition Image.cpp:194
bool initFootprint(QMutex *cameraMutex)
Calculate a footprint for this image.
Definition Image.cpp:409
VariantToImageFunctor(QMutex *cameraMutex, bool requireFootprints, QThread *targetThread, bool openFilled, int defaultAlpha)
Create a functor for converting from QVariant to an Image *.
Image * operator()(const QVariant &)
Read the QString filename and make an Image from it.
QPointer< QAction > m_askAlphaAct
Variant Internal Format: (QString|PvlObject).
Definition ImageReader.h:96
ImageReader(QMutex *cameraMutex, bool requireFootprints=true, QObject *parent=NULL)
MosaicWidget constructor.
virtual ~ImageReader()
Free the allocated memory by this object.
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16