USGS

Isis 3.0 Object Programmers' Reference

Home

QtExporter.cpp

00001 #include "QtExporter.h"
00002 
00003 #include <QImage>
00004 #include <QImageWriter>
00005 
00006 #include "Buffer.h"
00007 #include "ExportDescription.h"
00008 #include "FileName.h"
00009 #include "IException.h"
00010 #include "IString.h"
00011 
00012 using namespace Isis;
00013 
00014 
00015 namespace Isis {
00021   QtExporter::QtExporter(QString format) : ImageExporter() {
00022     m_qimage = NULL;
00023     m_format = format;
00024 
00025     // Setup the required extension and world file
00026     if (format == "png")
00027       setExtension("png");
00028     else if (format == "jpeg")
00029       setExtension("jpg");
00030     else if (format == "tiff")
00031       setExtension("tif");
00032     else if (format == "gif")
00033       setExtension("gif");
00034     else if (format == "bmp")
00035       setExtension("bmp");
00036   }
00037 
00038 
00042   QtExporter::~QtExporter() {
00043     delete m_qimage;
00044     m_qimage = NULL;
00045   }
00046 
00047 
00055   void QtExporter::setGrayscale(ExportDescription &desc) {
00056     Cube *cube = setInput(desc);
00057     checkDataSize(cube->sampleCount(), cube->lineCount(), 1);
00058     m_qimage = new QImage(
00059         cube->sampleCount(), cube->lineCount(), QImage::Format_Indexed8);
00060     m_qimage->setNumColors(256);
00061 
00062     // Create the color table (black = 0 to white = 255)
00063     QVector<QRgb> colors;
00064     for (int i = 0; i < 256; i++) colors.push_back(qRgb(i, i, i));
00065     m_qimage->setColorTable(colors);
00066   }
00067 
00068 
00076   void QtExporter::setRgb(ExportDescription &desc) {
00077     Cube *cube = setInput(desc);
00078     checkDataSize(cube->sampleCount(), cube->lineCount(), 3);
00079     m_qimage = new QImage(
00080         cube->sampleCount(), cube->lineCount(), QImage::Format_RGB32);
00081   }
00082 
00083 
00091   void QtExporter::setRgba(ExportDescription &desc) {
00092     Cube *cube = setInput(desc);
00093     checkDataSize(cube->sampleCount(), cube->lineCount(), 4);
00094     m_qimage = new QImage(
00095         cube->sampleCount(), cube->lineCount(), QImage::Format_ARGB32);
00096   }
00097 
00098 
00104   void QtExporter::writeGrayscale(vector<Buffer *> &in) const {
00105     Buffer &grayLine = *in[0];
00106 
00107     // Loop for each column and load the pixel, which will
00108     // be in the range of [0,255]
00109     int l = grayLine.Line() - 1;
00110     for (int s = 0; s < grayLine.SampleDimension(); s++) {
00111       int dn = getPixel(grayLine[s]);
00112 
00113       // Since the plausable "exception" thrown by setPixel cannot be caught,
00114       //  the following if statement does it informally.
00115       m_qimage->setPixel(s, l, dn);
00116       if (!m_qimage->valid(s, l)) {
00117         QString msg = "QT has detected your file size as exceeding 2GB.";
00118         msg += " While your image might be under 2GB, your image labels are more";
00119         msg += " than likely pushing the file size over 2GB.";
00120         throw IException(IException::User, msg, _FILEINFO_);
00121       }
00122     }
00123   }
00124 
00125 
00131   void QtExporter::writeRgb(vector<Buffer *> &in) const {
00132     Buffer &redLine = *in[0];
00133     Buffer &greenLine = *in[1];
00134     Buffer &blueLine = *in[2];
00135 
00136     QRgb *line = (QRgb *) m_qimage->scanLine(redLine.Line() - 1);
00137     for (int s = 0; s < redLine.SampleDimension(); s++) {
00138       int red = getPixel(redLine[s]);
00139       int green = getPixel(greenLine[s]);
00140       int blue = getPixel(blueLine[s]);
00141 
00142       line[s] = qRgb(red, green, blue);
00143     }
00144   }
00145 
00146 
00152   void QtExporter::writeRgba(vector<Buffer *> &in) const {
00153     Buffer &redLine = *in[0];
00154     Buffer &greenLine = *in[1];
00155     Buffer &blueLine = *in[2];
00156     Buffer &alphaLine = *in[3];
00157 
00158     QRgb *line = (QRgb *) m_qimage->scanLine(redLine.Line() - 1);
00159     for (int s = 0; s < redLine.SampleDimension(); s++) {
00160       int red = getPixel(redLine[s]);
00161       int green = getPixel(greenLine[s]);
00162       int blue = getPixel(blueLine[s]);
00163       int alpha = getPixel(alphaLine[s]);
00164 
00165       line[s] = qRgba(red, green, blue, alpha);
00166     }
00167   }
00168 
00169 
00177   void QtExporter::write(FileName outputName, int quality) {
00178     ImageExporter::write(outputName, quality);
00179 
00180     // The return status is wrong for JPEG images, so the code will always
00181     // continue
00182     if (!m_qimage->save(outputName.expanded(), m_format.toAscii().data(),
00183           quality)) {
00184 
00185       QString err = "Unable to save [" + outputName.expanded() +
00186         "] to the disk";
00187       throw IException(IException::Programmer, err, _FILEINFO_);
00188     }
00189   }
00190 
00191 
00200   void QtExporter::checkDataSize(BigInt samples, BigInt lines, int bands) {
00201     // Qt has a 2GB limit on file sizes it can handle
00202     BigInt maxSize = (BigInt) 2 * 1024 * 1024 * 1024;
00203 
00204     BigInt size = samples * lines * bands;
00205     if (size >= maxSize) {
00206       QString gigaBytes = toString(size / (1024.0 * 1024.0 * 1024.0));
00207       QString msg = "Cube exceeds max size of 2GB. Qimage cannot support ";
00208       msg += "that much raw data. Your cube is " + gigaBytes + " GB.";
00209       throw IException(IException::User, msg, _FILEINFO_);
00210     }
00211   }
00212 
00213 
00221   bool QtExporter::canWriteFormat(QString format) {
00222     bool supported = false;
00223     QList<QByteArray> list = QImageWriter::supportedImageFormats();
00224     QList<QByteArray>::Iterator it = list.begin();
00225     while (it != list.end() && !supported) {
00226       if (*it == QString(format)) supported = true;
00227       it++;
00228     }
00229     return supported;
00230   }
00231 };
00232