From 387086cb4c1bd409ac2ee4eac8b1ded891710cd5 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 4 Aug 2014 15:45:49 -0400 Subject: [PATCH 1/5] Added support for PNG images (both for downloading/saving and loading). --- cockatrice/src/carddatabase.cpp | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index f3bcc14a..f7296f7d 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -129,22 +129,24 @@ void PictureLoader::processLoadQueue() QString setName = ptl.getSetName(); QImage image; - if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg("CUSTOM").arg(correctedName))) { - if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(setName).arg(correctedName))) - //if (!image.load(QString("%1/%2/%3%4.full.jpg").arg(picsPath).arg(setName).arg(correctedName).arg(1))) - if (!image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) { - if (picDownload) { - cardsToDownload.append(ptl); - if (!downloadRunning) - startNextPicDownload(); - } else { - if (ptl.nextSet()) - loadQueue.prepend(ptl); - else - emit imageLoaded(ptl.getCard(), QImage()); - } - } - } + //Supports loading JPG and PNG images; default is JPG + if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg("CUSTOM").arg(correctedName))) + if (!image.load(QString("%1/%2/%3.full.png").arg(picsPath).arg("CUSTOM").arg(correctedName))) + if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(setName).arg(correctedName))) + if (!image.load(QString("%1/%2/%3.full.png").arg(picsPath).arg(setName).arg(correctedName))) + if (!image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) + if (!image.load(QString("%1/%2/%3/%4.full.png").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) { + if (picDownload) { + cardsToDownload.append(ptl); + if (!downloadRunning) + startNextPicDownload(); + } else { + if (ptl.nextSet()) + loadQueue.prepend(ptl); + else + emit imageLoaded(ptl.getCard(), QImage()); + } + } emit imageLoaded(ptl.getCard(), image); } @@ -226,11 +228,13 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) if (!cardBeingDownloaded.getStripped()) suffix = ".full"; - QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + ".jpg"); - if (!newPic.open(QIODevice::WriteOnly)) - return; - newPic.write(picData); - newPic.close(); + //Supports JPG and PNG images; default is JPG + QString extension = ".jpg"; + if (picData.left(8) == QByteArray::fromHex("89504E470D0A1A0A")) + extension = ".png"; + + if (!testImage.save(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension)) + qDebug() << picsPath.toUtf8() + "/downloadedPics/" + cardBeingDownloaded.getSetName().toUtf8() + "/" + cardBeingDownloaded.getCard()->getCorrectedName().toUtf8() + suffix.toUtf8() + extension.toUtf8() + "was not successfully saved."; emit imageLoaded(cardBeingDownloaded.getCard(), testImage); } else if (cardBeingDownloaded.getHq()) { From 75122c3c9d7cf874ff94ce09ed5c1be6db6f177e Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 4 Aug 2014 17:01:58 -0400 Subject: [PATCH 2/5] Switched back to using QFile instead of QImage for saving as QImage's save function adds overhead to the file size, leaving me unsure whether the original image is affected. --- cockatrice/src/carddatabase.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index f7296f7d..583f339f 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -233,8 +233,11 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) if (picData.left(8) == QByteArray::fromHex("89504E470D0A1A0A")) extension = ".png"; - if (!testImage.save(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension)) - qDebug() << picsPath.toUtf8() + "/downloadedPics/" + cardBeingDownloaded.getSetName().toUtf8() + "/" + cardBeingDownloaded.getCard()->getCorrectedName().toUtf8() + suffix.toUtf8() + extension.toUtf8() + "was not successfully saved."; + QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension); + if (!newPic.open(QIODevice::WriteOnly)) + return; + newPic.write(picData); + newPic.close(); emit imageLoaded(cardBeingDownloaded.getCard(), testImage); } else if (cardBeingDownloaded.getHq()) { From 8587b8c3492e4fa7d3690d22bf62e7d9fea51ccf Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Tue, 5 Aug 2014 03:48:30 -0400 Subject: [PATCH 3/5] Refactored the magic bytes into two QLists: one containing a list of QStrings representing the supported extensions, the other containing a list of QByteArrays representing the magic bytes in hex. Refactored the image loading loop to be two nested for loops: the outer loop iterating through the QList of paths to folders in which to search for images and the inner loop iterating through the QList of supported extensions. --- cockatrice/src/carddatabase.cpp | 68 +++++++++++++++++++++------------ cockatrice/src/carddatabase.h | 2 + 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 583f339f..a088975c 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -16,6 +16,10 @@ const int CardDatabase::versionNeeded = 3; +//Specifies image formats and their associated signature bytes (expected first x bytes, in hex) +const QList PictureLoader::imgFormats = QList() << ".png"; +const QList PictureLoader::imgSignatures = QList() << "89504E470D0A1A0A"; + static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set) { xml.writeStartElement("set"); @@ -124,31 +128,42 @@ void PictureLoader::processLoadQueue() } PictureToLoad ptl = loadQueue.takeFirst(); mutex.unlock(); - QString correctedName = ptl.getCard()->getCorrectedName(); - QString picsPath = _picsPath; - QString setName = ptl.getSetName(); + + //The list of paths to the folders in which to search for images + QList picsPaths = QList() << _picsPath + "/CUSTOM/" + ptl.getCard()->getCorrectedName() + ".full" + << _picsPath + "/" + ptl.getSetName() + "/" + ptl.getCard()->getCorrectedName() + ".full" + << _picsPath + "/downloadedPics/" + ptl.getSetName() + "/" + ptl.getCard()->getCorrectedName() + ".full"; QImage image; - //Supports loading JPG and PNG images; default is JPG - if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg("CUSTOM").arg(correctedName))) - if (!image.load(QString("%1/%2/%3.full.png").arg(picsPath).arg("CUSTOM").arg(correctedName))) - if (!image.load(QString("%1/%2/%3.full.jpg").arg(picsPath).arg(setName).arg(correctedName))) - if (!image.load(QString("%1/%2/%3.full.png").arg(picsPath).arg(setName).arg(correctedName))) - if (!image.load(QString("%1/%2/%3/%4.full.jpg").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) - if (!image.load(QString("%1/%2/%3/%4.full.png").arg(picsPath).arg("downloadedPics").arg(setName).arg(correctedName))) { - if (picDownload) { - cardsToDownload.append(ptl); - if (!downloadRunning) - startNextPicDownload(); - } else { - if (ptl.nextSet()) - loadQueue.prepend(ptl); - else - emit imageLoaded(ptl.getCard(), QImage()); - } - } + QString extension; + bool found; + int i, j; + + //Iterates through the list of paths, iterating through imgFormats in each to find the image in any supported format; default is JPG + for (found = false, i = 0; i < picsPaths.length() && !found; i ++) + for (extension = ".jpg", j = 0; !found; j ++) { + //qDebug() << picsPaths.at(i) + extension; + if (image.load(picsPaths.at(i) + extension)) { + emit imageLoaded(ptl.getCard(), image); + found = true; + } + if (j >= imgFormats.length()) + break; + extension = imgFormats.at(j); + } - emit imageLoaded(ptl.getCard(), image); + if (!found) { + if (picDownload) { + cardsToDownload.append(ptl); + if (!downloadRunning) + startNextPicDownload(); + } else { + if (ptl.nextSet()) + loadQueue.prepend(ptl); + else + emit imageLoaded(ptl.getCard(), QImage()); + } + } } } @@ -228,10 +243,13 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) if (!cardBeingDownloaded.getStripped()) suffix = ".full"; - //Supports JPG and PNG images; default is JPG + //Supports JPG and formats specified in imgFormats; default is JPG QString extension = ".jpg"; - if (picData.left(8) == QByteArray::fromHex("89504E470D0A1A0A")) - extension = ".png"; + for (int i = 0; i < imgFormats.length(); i ++) + if (picData.left(QByteArray::fromHex(imgSignatures.at(i)).length()) == QByteArray::fromHex(imgSignatures.at(i))) { + extension = imgFormats.at(i); + break; + } QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension); if (!newPic.open(QIODevice::WriteOnly)) diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index bb151e7d..6ffa6b0e 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -73,6 +73,8 @@ private: bool picDownload, picDownloadHq, downloadRunning, loadQueueRunning; void startNextPicDownload(); QString getPicUrl(CardInfo* card); + static const QList imgFormats; + static const QList imgSignatures; public: PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent = 0); ~PictureLoader(); From 4bb1d28ae710b29a4d64bc9834f010b8ff2ede06 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Tue, 5 Aug 2014 05:40:51 -0400 Subject: [PATCH 4/5] Removed the QLists for determining image format. Instead, using QImageReader, both when downloading/saving and when loading, to determine the correct format (Cockatrice now supports all QImageReader-supported formats). Image loading still uses one for loop to iterate through the QList of paths to folders in which to search for images. --- cockatrice/src/carddatabase.cpp | 60 +++++++++++++-------------------- cockatrice/src/carddatabase.h | 2 -- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index a088975c..8bedf71e 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -13,13 +13,10 @@ #include #include #include +#include const int CardDatabase::versionNeeded = 3; -//Specifies image formats and their associated signature bytes (expected first x bytes, in hex) -const QList PictureLoader::imgFormats = QList() << ".png"; -const QList PictureLoader::imgSignatures = QList() << "89504E470D0A1A0A"; - static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardSet *set) { xml.writeStartElement("set"); @@ -135,22 +132,17 @@ void PictureLoader::processLoadQueue() << _picsPath + "/downloadedPics/" + ptl.getSetName() + "/" + ptl.getCard()->getCorrectedName() + ".full"; QImage image; - QString extension; - bool found; - int i, j; + bool found = false; - //Iterates through the list of paths, iterating through imgFormats in each to find the image in any supported format; default is JPG - for (found = false, i = 0; i < picsPaths.length() && !found; i ++) - for (extension = ".jpg", j = 0; !found; j ++) { - //qDebug() << picsPaths.at(i) + extension; - if (image.load(picsPaths.at(i) + extension)) { - emit imageLoaded(ptl.getCard(), image); - found = true; - } - if (j >= imgFormats.length()) - break; - extension = imgFormats.at(j); + //Iterates through the list of paths, searching for images with the desired name with any QImageReader-supported extension + for (int i = 0; i < picsPaths.length() && !found; i ++) { + QImageReader imgReader; + imgReader.setFileName(picsPaths.at(i)); + if (imgReader.read(&image)) { + emit imageLoaded(ptl.getCard(), image); + found = true; } + } if (!found) { if (picDownload) { @@ -225,32 +217,26 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) qDebug() << "Download failed:" << reply->errorString(); } - const QByteArray &picData = reply->readAll(); + const QByteArray &picData = reply->peek(reply->size()); //peek is used to keep the data in the buffer for use by QImageReader QImage testImage; - if (testImage.loadFromData(picData)) { - if (!QDir(QString(picsPath + "/downloadedPics/")).exists()) { - QDir dir(picsPath); - if (!dir.exists()) - return; - dir.mkdir("downloadedPics"); - } - if (!QDir(QString(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName())).exists()) { - QDir dir(QString(picsPath + "/downloadedPics")); - dir.mkdir(cardBeingDownloaded.getSetName()); + + QImageReader imgReader; + imgReader.setDecideFormatFromContent(true); + imgReader.setDevice(reply); + QString extension = "." + imgReader.format(); //the format is determined prior to reading the QImageReader data into a QImage object, as that wipes the QImageReader buffer + if (extension == ".jpeg") + extension = ".jpg"; + + if (imgReader.read(&testImage)) { + if (!QDir().mkpath(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName())) { + qDebug() << picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + " could not be created."; + return; } QString suffix; if (!cardBeingDownloaded.getStripped()) suffix = ".full"; - //Supports JPG and formats specified in imgFormats; default is JPG - QString extension = ".jpg"; - for (int i = 0; i < imgFormats.length(); i ++) - if (picData.left(QByteArray::fromHex(imgSignatures.at(i)).length()) == QByteArray::fromHex(imgSignatures.at(i))) { - extension = imgFormats.at(i); - break; - } - QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded.getSetName() + "/" + cardBeingDownloaded.getCard()->getCorrectedName() + suffix + extension); if (!newPic.open(QIODevice::WriteOnly)) return; diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index 6ffa6b0e..bb151e7d 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -73,8 +73,6 @@ private: bool picDownload, picDownloadHq, downloadRunning, loadQueueRunning; void startNextPicDownload(); QString getPicUrl(CardInfo* card); - static const QList imgFormats; - static const QList imgSignatures; public: PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent = 0); ~PictureLoader(); From 6502a182e825745edb1db2a32fad45b9660473c0 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Wed, 6 Aug 2014 09:31:22 +0200 Subject: [PATCH 5/5] Support loading of files with wrong extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like M15’s .png that cockatrice wrongly saved as .jpg Additionally, move the QImageReader declaration outside of the inner loop --- cockatrice/src/carddatabase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 8bedf71e..b3d4bca9 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -132,11 +132,12 @@ void PictureLoader::processLoadQueue() << _picsPath + "/downloadedPics/" + ptl.getSetName() + "/" + ptl.getCard()->getCorrectedName() + ".full"; QImage image; + QImageReader imgReader; + imgReader.setDecideFormatFromContent(true); bool found = false; - + //Iterates through the list of paths, searching for images with the desired name with any QImageReader-supported extension for (int i = 0; i < picsPaths.length() && !found; i ++) { - QImageReader imgReader; imgReader.setFileName(picsPaths.at(i)); if (imgReader.read(&image)) { emit imageLoaded(ptl.getCard(), image);