Isis 3 Programmer Reference
QtExporter.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "QtExporter.h"
8
9#include <QImage>
10#include <QImageWriter>
11
12#include "Buffer.h"
13#include "ExportDescription.h"
14#include "FileName.h"
15#include "IException.h"
16#include "IString.h"
17#include "UserInterface.h"
18
19using namespace Isis;
20
21
22namespace Isis {
29 m_qimage = NULL;
30 m_format = format;
31
32 // Setup the required extension and world file
33 if (format == "png")
34 setExtension("png");
35 else if (format == "jpeg")
36 setExtension("jpg");
37 else if (format == "tiff")
38 setExtension("tif");
39 else if (format == "gif")
40 setExtension("gif");
41 else if (format == "bmp")
42 setExtension("bmp");
43 }
44
45
50 delete m_qimage;
51 m_qimage = NULL;
52 }
53
61 // the Qt exporter only exports unsigned byte
62 if (desc.pixelType() != UnsignedByte) {
63 QString msg = "Invalid pixel type. The Qt exporter for file type [";
64 msg += m_format;
65 msg += "] requires an unsigned byte (i.e. 8BIT) output.";
66 throw IException(IException::Unknown, msg, _FILEINFO_);
67 }
69 }
70
79 initialize(desc);
81 m_qimage = new QImage(samples(), lines(), QImage::Format_Indexed8);
82 m_qimage->setColorCount(256);
83
84 // Create the color table (black = 0 to white = 255)
85 QVector<QRgb> colors;
86 for (int i = 0; i < 256; i++) {
87 colors.push_back(qRgb(i, i, i));
88 }
89 m_qimage->setColorTable(colors);
90 }
91
92
101 initialize(desc);
102 checkDataSize(samples(), lines(), 3);
103 m_qimage = new QImage(samples(), lines(), QImage::Format_RGB32);
104 }
105
106
115 initialize(desc);
116 checkDataSize(samples(), lines(), 4);
117 m_qimage = new QImage(samples(), lines(), QImage::Format_ARGB32);
118 }
119
120
126 void QtExporter::writeGrayscale(vector<Buffer *> &in) const {
127 Buffer &grayLine = *in[0];
128
129 // Loop for each column and load the pixel, which will
130 // be in the range of [0,255]
131 int lineIndex = grayLine.Line() - 1;
132 for (int sampleIndex = 0; sampleIndex < grayLine.SampleDimension(); sampleIndex++) {
133 int pixelValue = outputPixelValue(grayLine[sampleIndex]);
134
135 // Since the plausable "exception" thrown by setPixel cannot be caught,
136 // the following if statement does it informally.
137 m_qimage->setPixel(sampleIndex, lineIndex, pixelValue);
138 if (!m_qimage->valid(sampleIndex, lineIndex)) {
139 QString msg = "Qt has detected your file size as exceeding 2GB.";
140 msg += " While your image might be under 2GB, your image labels are more";
141 msg += " than likely pushing the file size over 2GB.";
142 throw IException(IException::User, msg, _FILEINFO_);
143 }
144 }
145 }
146
147
153 void QtExporter::writeRgb(vector<Buffer *> &in) const {
154 Buffer &redLine = *in[0];
155 Buffer &greenLine = *in[1];
156 Buffer &blueLine = *in[2];
157
158 QRgb *line = (QRgb *) m_qimage->scanLine(redLine.Line() - 1);
159 for (int s = 0; s < redLine.SampleDimension(); s++) {
160 int red = outputPixelValue(redLine[s]);
161 int green = outputPixelValue(greenLine[s]);
162 int blue = outputPixelValue(blueLine[s]);
163
164 line[s] = qRgb(red, green, blue);
165 }
166 }
167
168
174 void QtExporter::writeRgba(vector<Buffer *> &in) const {
175 Buffer &redLine = *in[0];
176 Buffer &greenLine = *in[1];
177 Buffer &blueLine = *in[2];
178 Buffer &alphaLine = *in[3];
179
180 QRgb *line = (QRgb *) m_qimage->scanLine(redLine.Line() - 1);
181 for (int s = 0; s < redLine.SampleDimension(); s++) {
182 int red = outputPixelValue(redLine[s]);
183 int green = outputPixelValue(greenLine[s]);
184 int blue = outputPixelValue(blueLine[s]);
185 int alpha = outputPixelValue(alphaLine[s]);
186
187 line[s] = qRgba(red, green, blue, alpha);
188 }
189 }
190
191
200 void QtExporter::write(FileName outputName, int quality,
201 QString compression, UserInterface *ui) {
202 ImageExporter::write(outputName, quality, compression, ui);
203
204 outputName = outputName.addExtension(extension());
205
206 // The return status is wrong for JPEG images, so the code will always
207 // continue
208 if (!m_qimage->save(outputName.expanded(), m_format.toLatin1().data(),
209 quality)) {
210
211 QString err = "Unable to save [" + outputName.expanded() +
212 "] to the disk";
213 throw IException(IException::Programmer, err, _FILEINFO_);
214 }
215 }
216
217
226 void QtExporter::checkDataSize(BigInt samples, BigInt lines, int bands) {
227 // Qt has a 2GB limit on file sizes it can handle
228 BigInt maxSize = (BigInt) 2 * 1024 * 1024 * 1024;
229
230 BigInt size = samples * lines * bands;
231 if (size >= maxSize) {
232 QString gigaBytes = toString(size / (1024.0 * 1024.0 * 1024.0));
233 QString msg = "Cube exceeds max size of 2GB. Qimage cannot support ";
234 msg += "that much raw data. Your cube is " + gigaBytes + " GB.";
235 throw IException(IException::User, msg, _FILEINFO_);
236 }
237 }
238
239
247 bool QtExporter::canWriteFormat(QString format) {
248 bool supported = false;
249 QList<QByteArray> list = QImageWriter::supportedImageFormats();
250 QList<QByteArray>::Iterator it = list.begin();
251 while (it != list.end() && !supported) {
252 if (*it == QString(format)) supported = true;
253 it++;
254 }
255 return supported;
256 }
257};
258
Buffer for reading and writing cube data.
Definition Buffer.h:53
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition Buffer.cpp:145
Describes how a series of cubes should be exported.
File name manipulation and expansion.
Definition FileName.h:100
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Export Isis cubes into standard formats.
int lines() const
Number of lines (rows) in the output image.
QString extension() const
Gets the extension for the output image.
int bands() const
Number of bands (channels) in the output image.
virtual void write(FileName outputName, int quality=100, QString compression="none", UserInterface *ui=nullptr)
Export the Isis cube channels to the given standard image.
int samples() const
Number of samples (columns) in the output image.
virtual void initialize(ExportDescription &desc)=0
Generic initialization with the export description.
void setExtension(QString extension)
Sets the extension for the output image and generates the extension for the world file from it.
virtual int outputPixelValue(double dn) const
Return the output clamped integer pixel value from the input double-precision DN.
virtual void setGrayscale(ExportDescription &desc)
Set the input with the description generically, check the data size for a single-band image with the ...
QString m_format
The lowercase abbreviated format of the output image.
Definition QtExporter.h:75
virtual void setRgb(ExportDescription &desc)
Set the input with the description generically, check the data size for a three-band image with the e...
virtual void write(FileName outputName, int quality=100, QString compression="none", UserInterface *ui=nullptr)
Let the base ImageExporter handle the generic black-box writing routine, then save the image to disk.
virtual void writeRgba(vector< Buffer * > &in) const
Write a line of RGBA data to the output image.
QtExporter(QString format)
Construct the Qt exporter.
virtual void writeGrayscale(vector< Buffer * > &in) const
Write a line of grayscale data to the output image.
void checkDataSize(BigInt samples, BigInt lines, int bands)
Checks that the data size for an image of the desired dimensions will be less than 2GB.
static bool canWriteFormat(QString format)
Returns true if the format is supported by QImageWriter.
void initialize(ExportDescription &desc)
Generic initialization with the export description.
QImage * m_qimage
Structure holding all output image data in memory.
Definition QtExporter.h:72
virtual void writeRgb(vector< Buffer * > &in) const
Write a line of RGB data to the output image.
virtual void setRgba(ExportDescription &desc)
Set the input with the description generically, check the data size for a four-band image with the es...
virtual ~QtExporter()
Destruct the exporter.
Command Line and Xml loader, validation, and access.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
long long int BigInt
Big int.
Definition Constants.h:49