From c2deffe6c1b506670479cdfe8e527bf779fc79e9 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Aug 2018 21:15:25 -0400 Subject: [PATCH 1/7] Teach PRPShop about PNG compressed mipmaps --- src/PrpShop/PRP/Surface/QMipmap.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index cd0bbaa..007b18c 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -193,6 +193,19 @@ QString getCompressionText(plBitmap* tex) case plBitmap::kAInten88: return "JPEG (Alpha+Greyscale)"; } + } else if (tex->getCompressionType() == plBitmap::kPNGCompression) { + switch (tex->getARGBType()) { + case plBitmap::kRGB8888: + return "PNG (ARGB8888)"; + case plBitmap::kRGB4444: + return "PNG (ARGB4444)"; + case plBitmap::kRGB1555: + return "PNG (ARGB1555)"; + case plBitmap::kInten8: + return "PNG (Greyscale)"; + case plBitmap::kAInten88: + return "PNG (Alpha+Greyscale)"; + } } else { switch (tex->getARGBType()) { case plBitmap::kRGB8888: From a3f3abe079f90402d58f1362cbc2ebb085e4701a Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 19 Aug 2018 21:17:18 -0400 Subject: [PATCH 2/7] Fix non-DXT image channels All Plasma image data, other than DXT, is stored as BGR in plMipmap --- src/PrpShop/PRP/Surface/QMipmap.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 007b18c..1e02e81 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -81,7 +81,7 @@ void QTextureBox::setTexture(plMipmap* tex, int level) fImageData = new unsigned char[size]; tex->DecompressImage(level, fImageData, size); - if (tex->getCompressionType() != plMipmap::kUncompressed) { + if (tex->getCompressionType() == plMipmap::kDirectXCompression) { // Manipulate the data from RGBA to BGRA unsigned int* dp = (unsigned int*)fImageData; for (size_t i=0; i(data); + for (size_t i=0; i> 16 + | (*dp & 0x000000FF) << 16; + dp++; + } +} + static void makeJColorSurface(const plMipmap* tex, hsStream* S) { if (tex->getCompressionType() != plBitmap::kJPEGCompression) { @@ -367,6 +378,7 @@ static void makeJColorSurface(const plMipmap* tex, hsStream* S) // Strip down data to 24 bit color unsigned char* data = new unsigned char[dds.fLinearSize]; tex->extractColorData(data, dds.fLinearSize); + swapColorChannels(data, dds.fLinearSize); dds.setData(dds.fLinearSize, data); delete[] data; @@ -425,6 +437,7 @@ static bool getJColorSurface(const plDDSurface& dds, plMipmap* tex) tex->Create(dds.fWidth, dds.fHeight, 0, plBitmap::kJPEGCompression, plBitmap::kRGB8888); tex->setColorData(dds.getData(), dds.getDataSize()); + swapColorChannels(reinterpret_cast(tex->getImageData()), dds.getDataSize()); return true; } From 1aee4b459190af15c4e5917421a5d8b2e12bd1e5 Mon Sep 17 00:00:00 2001 From: Joseph Davies Date: Fri, 7 Sep 2018 21:16:59 -0700 Subject: [PATCH 3/7] Improve MipMap Import/Export feature. --- src/PrpShop/PRP/Surface/QMipmap.cpp | 315 +++++++++++----------------- src/PrpShop/PRP/Surface/QMipmap.h | 6 +- 2 files changed, 128 insertions(+), 193 deletions(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 1e02e81..01eb756 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -28,6 +28,8 @@ #include #include "QLinkLabel.h" #include "QPlasmaUtils.h" +#include +#include /* Helpers */ static QString getExportDir() @@ -47,6 +49,33 @@ static void setExportDir(const QString& filename) settings.setValue("ExportDir", dir.absolutePath()); } +unsigned char* getTextureData(plMipmap *tex, size_t level=0) +{ + unsigned char *imageData; + + if (level >= tex->getNumLevels()) + level = tex->getNumLevels() - 1; + + size_t size = tex->GetUncompressedSize(level); + imageData = new unsigned char[size]; + tex->DecompressImage(level, imageData, size); + + if (tex->getCompressionType() == plMipmap::kDirectXCompression) { + // Manipulate the data from RGBA to BGRA + unsigned int* dp = (unsigned int*)imageData; + for (size_t i = 0; i < size; i += 4) { + //unsigned int alpha = doAlpha ? (*dp & 0xFF000000) : 0xFF000000; + *dp = (*dp & 0xFF000000) + | (*dp & 0x00FF0000) >> 16 + | (*dp & 0x0000FF00) + | (*dp & 0x000000FF) << 16; + dp++; + } + } + + return imageData; +} + /* QTextureBox */ QTextureBox::~QTextureBox() { @@ -67,8 +96,6 @@ void QTextureBox::setTexture(plMipmap* tex, int level) return; } - if (level >= (int)tex->getNumLevels()) - level = tex->getNumLevels() - 1; if (level < 0) { fImage = NULL; fImageData = NULL; @@ -77,22 +104,7 @@ void QTextureBox::setTexture(plMipmap* tex, int level) return; } - size_t size = tex->GetUncompressedSize(level); - fImageData = new unsigned char[size]; - tex->DecompressImage(level, fImageData, size); - - if (tex->getCompressionType() == plMipmap::kDirectXCompression) { - // Manipulate the data from RGBA to BGRA - unsigned int* dp = (unsigned int*)fImageData; - for (size_t i=0; i> 16 - | (*dp & 0x0000FF00) - | (*dp & 0x000000FF) << 16; - dp++; - } - } + fImageData = getTextureData(tex, level); fImage = new QImage(fImageData, tex->getLevelWidth(level), tex->getLevelHeight(level), QImage::Format_ARGB32); resize(tex->getLevelWidth(level), tex->getLevelHeight(level)); @@ -311,10 +323,8 @@ QMipmap::QMipmap(plCreatable* pCre, QWidget* parent) fPreviewLink->setCreatable(tex, tr("Preview")); fPreviewLink->setForceType(kPreviewMipmap); - QLinkLabel* xDDSLink = new QLinkLabel(tr("Export DDS..."), this); - QLinkLabel* iDDSLink = new QLinkLabel(tr("Import DDS..."), this); - QLinkLabel* xJPGLink = new QLinkLabel(tr("Export Jpeg..."), this); - QLinkLabel* iJPGLink = new QLinkLabel(tr("Import Jpeg..."), this); + QLinkLabel* xPort = new QLinkLabel(tr("Export Image..."), this); + QLinkLabel* iPort = new QLinkLabel(tr("Import Image..."), this); QGridLayout* layout = new QGridLayout(this); layout->setContentsMargins(8, 8, 8, 8); @@ -322,23 +332,11 @@ QMipmap::QMipmap(plCreatable* pCre, QWidget* parent) layout->addWidget(grpProps, 1, 0, 1, 2); layout->addWidget(fPreviewLink, 2, 0, 1, 2); layout->addItem(new QSpacerItem(0, 8, QSizePolicy::Minimum, QSizePolicy::Minimum), 3, 0, 1, 2); - layout->addWidget(xDDSLink, 4, 0); - layout->addWidget(iDDSLink, 5, 0); - layout->addWidget(xJPGLink, 4, 1); - layout->addWidget(iJPGLink, 5, 1); - - if (tex->getCompressionType() == plBitmap::kJPEGCompression) { - xDDSLink->setEnabled(false); - xJPGLink->setEnabled(true); - } else { - xDDSLink->setEnabled(true); - xJPGLink->setEnabled(false); - } + layout->addWidget(xPort, 4, 0); + layout->addWidget(iPort, 5, 0); - connect(xDDSLink, &QLinkLabel::activated, this, &QMipmap::onExportDDS); - connect(xJPGLink, &QLinkLabel::activated, this, &QMipmap::onExportJPEG); - connect(iDDSLink, &QLinkLabel::activated, this, &QMipmap::onImportDDS); - connect(iJPGLink, &QLinkLabel::activated, this, &QMipmap::onImportJPEG); + connect(xPort, &QLinkLabel::activated, this, &QMipmap::onExportImage); + connect(iPort, &QLinkLabel::activated, this, &QMipmap::onImportImage); } static void swapColorChannels(unsigned char* data, size_t size) @@ -470,186 +468,125 @@ static bool getJAlphaSurface(const plDDSurface& dds, plMipmap* tex) return true; } -void QMipmap::onExportDDS() -{ - plMipmap* tex = plMipmap::Convert(fCreatable); - QString filename = st2qstr(tex->getKey()->getName()) - .replace(QRegularExpression("[?:/\\*\"<>|]"), "_"); - filename = QFileDialog::getSaveFileName(this, tr("Export DDS"), getExportDir() + "/" + filename, - "DDS Files (*.dds)"); - if (filename.isEmpty()) - return; - - hsFileStream S; - if (!S.open(qstr2st(filename), fmCreate)) { - QMessageBox::critical(this, tr("Error exporting DDS"), - tr("Error: Could not open file %1 for writing").arg(filename), - QMessageBox::Ok); - return; - } - try { - plDDSurface dds; - dds.setFromMipmap(tex); - dds.write(&S); - } catch (hsException& ex) { - QMessageBox::critical(this, tr("Error exporting DDS"), - QString::fromUtf8(ex.what()), QMessageBox::Ok); - } - S.close(); - - setExportDir(filename); -} - -void QMipmap::onExportJPEG() -{ +void QMipmap::onExportImage() { QString exportDir = getExportDir(); - plMipmap* tex = plMipmap::Convert(fCreatable); + exportDir.append("/" + st2qstr(tex->getKey()->getName()) .replace(QRegularExpression("[?:/\\*\"<>|]"), "_")); - QString filter = tex->isImageJPEG() ? "JPEG Files (*.jpg)" : "DDS Files (*.dds)"; - QString filename = QFileDialog::getSaveFileName(this, tr("Export JPEG Image"), - exportDir, filter); + QString filter = tr("DDS Files (*.dds);;JPEG Files (*.jpg *.jpeg);;PNG Files (*.png)"); + QString filename = QFileDialog::getSaveFileName(this, tr("Export Image"), exportDir, filter); + if (filename.isEmpty()) return; - exportDir.append("_ALPHA"); - filter = tex->isAlphaJPEG() ? "JPEG Files (*.jpg)" : "DDS Files (*.dds)"; - QString alphaFname = QFileDialog::getSaveFileName(this, tr("Export JPEG Alpha"), - exportDir, filter); - if (alphaFname.isEmpty()) - return; + QString file_ext = QFileInfo(filename).suffix(); + if (file_ext == "dds") { + hsFileStream S; + if (!S.open(qstr2st(filename), fmCreate)) { + QMessageBox::critical(this, tr("Error exporting DDS"), + tr("Error: Could not open file %1 for writing").arg(filename), + QMessageBox::Ok); + return; + } - hsFileStream S; - if (!S.open(qstr2st(filename), fmCreate)) { - QMessageBox::critical(this, tr("Error exporting JPEG"), - tr("Error: Could not open file %1 for writing").arg(filename), - QMessageBox::Ok); - return; - } - if (tex->isImageJPEG()) - S.write(tex->getJpegSize(), tex->getJpegImage()); - else - makeJColorSurface(tex, &S); - S.close(); + try { + plDDSurface dds; + dds.setFromMipmap(tex); + dds.write(&S); - if (!S.open(qstr2st(alphaFname), fmCreate)) { - QMessageBox::critical(this, tr("Error exporting JPEG"), - tr("Error: Could not open file %1 for writing").arg(alphaFname), - QMessageBox::Ok); - return; + S.close(); + } catch (hsException& ex) { + QMessageBox::critical(this, tr("Error exporting DDS"), + QString::fromUtf8(ex.what()), QMessageBox::Ok); + } } - if (tex->isAlphaJPEG()) - S.write(tex->getJpegAlphaSize(), tex->getJpegAlpha()); - else - makeJAlphaSurface(tex, &S); - S.close(); - - setExportDir(filename); -} - -void QMipmap::onImportDDS() -{ - plMipmap* tex = plMipmap::Convert(fCreatable); - QString filename = QFileDialog::getOpenFileName(this, tr("Import DDS"), getExportDir(), - "DDS Files (*.dds)"); - if (filename.isEmpty()) - return; + else if (file_ext == "jpg" || file_ext == "jpeg") { + hsFileStream S; + if (!S.open(qstr2st(filename), fmCreate)) { + QMessageBox::critical(this, tr("Error exporting JPEG"), + tr("Error: Could not open file %1 for writing").arg(filename), + QMessageBox::Ok); + return; + } - hsFileStream S; - if (!S.open(qstr2st(filename), fmRead)) { - QMessageBox::critical(this, tr("Error importing DDS"), - tr("Error: Could not open file %1 for reading").arg(filename), - QMessageBox::Ok); - return; + if (tex->isImageJPEG()) { + S.write(tex->getJpegSize(), tex->getJpegImage()); + } else { + size_t image_size = tex->GetUncompressedSize(0); + auto image_data = new unsigned char[image_size]; + tex->DecompressImage(0, image_data, image_size); + plJPEG::CompressJPEG(&S, (void*)(image_data), image_size, tex->getWidth(), tex->getHeight(), tex->getBPP()); + delete[] image_data; + } + S.close(); } - try { - plDDSurface dds; - dds.read(&S); - plMipmap* newTex = dds.createMipmap(); - tex->CopyFrom(newTex); - delete newTex; - } catch (hsException& ex) { - QMessageBox::critical(this, tr("Error importing DDS"), - QString::fromUtf8(ex.what()), QMessageBox::Ok); + else if (file_ext == "png") { + hsFileStream S; + if (!S.open(qstr2st(filename), fmCreate)) { + QMessageBox::critical(this, tr("Error exporting PNG"), + tr("Error: Could not open file %1 for writing").arg(filename), + QMessageBox::Ok); + return; + } + + try { + auto imageData = getTextureData(tex); + plPNG::CompressPNG(&S, imageData, tex->GetUncompressedSize(0), tex->getLevelWidth(0), tex->getLevelHeight(0), tex->getBPP()); + } catch (hsException& ex) { + QMessageBox::critical(this, tr("Error exporting PNG"), + QString::fromUtf8(ex.what()), QMessageBox::Ok); + } + S.close(); } - S.close(); setExportDir(filename); } -void QMipmap::onImportJPEG() +void QMipmap::onImportImage() { - QString exportDir = getExportDir(); - + QString importDir = getExportDir(); plMipmap* tex = plMipmap::Convert(fCreatable); - QString filename = QFileDialog::getOpenFileName(this, tr("Import JPEG"), exportDir, - "JPEG Files (*.jpg *.jpeg *.dds)"); + + importDir.append("/" + st2qstr(tex->getKey()->getName()) + .replace(QRegularExpression("[?:/\\*\"<>|]"), "_")); + QString filter = tr("DDS Files (*.dds);;JPEG Files (*.jpg *.jpeg);;PNG Files (*.png)"); + QString filename = QFileDialog::getOpenFileName(this, tr("Import Image"), importDir, filter); + if (filename.isEmpty()) return; - QString alphaFname = QFileDialog::getOpenFileName(this, tr("Import JPEG Alpha"), exportDir, - "JPEG Files (*.jpg *.jpeg *.dds)"); - if (alphaFname.isEmpty()) - return; - plMipmap newTex; hsFileStream S; - bool valid = true; if (!S.open(qstr2st(filename), fmRead)) { - QMessageBox::critical(this, tr("Error importing JPEG"), - tr("Error: Could not open file %1 for reading").arg(filename), - QMessageBox::Ok); - valid = false; - } - if (filename.toLower().endsWith(".dds")) { - try { - plDDSurface dds; - dds.read(&S); - if (!getJColorSurface(dds, &newTex)) - valid = false; - } catch (hsException& ex) { - QMessageBox::critical(this, tr("Error importing JPEG"), - QString::fromUtf8(ex.what()), QMessageBox::Ok); - valid = false; - } - } else { - unsigned char* data = new unsigned char[S.size()]; - S.read(S.size(), data); - QImage imgTemp(filename); - newTex.Create(imgTemp.width(), imgTemp.height(), 0, plBitmap::kJPEGCompression, - plBitmap::kRGB8888); - newTex.setImageJPEG(data, S.size()); - delete[] data; + QMessageBox::critical(this, tr("Error importing image"), + tr("Error: Could not open file %1 for reading").arg(filename), + QMessageBox::Ok); + return; } - S.close(); - if (!S.open(qstr2st(alphaFname), fmRead)) { - QMessageBox::critical(this, tr("Error importing JPEG"), - tr("Error: Could not open file %1 for reading").arg(alphaFname), - QMessageBox::Ok); - valid = false; - } - if (alphaFname.toLower().endsWith(".dds")) { - try { + try { + QString file_ext = QFileInfo(filename).suffix(); + if (file_ext == "dds") { plDDSurface dds; dds.read(&S); - if (!getJAlphaSurface(dds, &newTex)) - valid = false; - } catch (hsException& ex) { - QMessageBox::critical(this, tr("Error importing JPEG"), - QString::fromUtf8(ex.what()), QMessageBox::Ok); - valid = false; + plMipmap* newTex = dds.createMipmap(); + tex->CopyFrom(newTex); + delete newTex; } - } else { - unsigned char* data = new unsigned char[S.size()]; - S.read(S.size(), data); - newTex.setAlphaJPEG(data, S.size()); - delete[] data; + else if (file_ext == "jpg" || file_ext == "jpeg") { + plMipmap* newTex = plJPEG::DecompressJPEG(&S); + tex->CopyFrom(newTex); + delete newTex; + } + else if (file_ext == "png") { + plMipmap* newTex = plPNG::DecompressPNG(&S); + tex->CopyFrom(newTex); + delete newTex; + } + } + catch (hsException& ex) { + QMessageBox::critical(this, tr("Error importing image"), + QString::fromUtf8(ex.what()), QMessageBox::Ok); } S.close(); - - if (valid) - tex->CopyFrom(&newTex); - - setExportDir(filename); } diff --git a/src/PrpShop/PRP/Surface/QMipmap.h b/src/PrpShop/PRP/Surface/QMipmap.h index 0858a26..5d00738 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.h +++ b/src/PrpShop/PRP/Surface/QMipmap.h @@ -86,10 +86,8 @@ class QMipmap : public QCreatable QMipmap(plCreatable* pCre, QWidget* parent = NULL); private slots: - void onExportDDS(); - void onExportJPEG(); - void onImportDDS(); - void onImportJPEG(); + void onExportImage(); + void onImportImage(); }; QString getCompressionText(plBitmap* tex); From 387ccc3befdd0d38b542bbae31f556794fc20afd Mon Sep 17 00:00:00 2001 From: Joseph Davies Date: Sun, 23 Oct 2022 12:52:37 -0700 Subject: [PATCH 4/7] Remove deprecated DDS<->JPG conversion functions. --- src/PrpShop/PRP/Surface/QMipmap.cpp | 129 ---------------------------- 1 file changed, 129 deletions(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 01eb756..2917473 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -339,135 +339,6 @@ QMipmap::QMipmap(plCreatable* pCre, QWidget* parent) connect(iPort, &QLinkLabel::activated, this, &QMipmap::onImportImage); } -static void swapColorChannels(unsigned char* data, size_t size) -{ - unsigned int* dp = reinterpret_cast(data); - for (size_t i=0; i> 16 - | (*dp & 0x000000FF) << 16; - dp++; - } -} - -static void makeJColorSurface(const plMipmap* tex, hsStream* S) -{ - if (tex->getCompressionType() != plBitmap::kJPEGCompression) { - QMessageBox::critical(NULL, QObject::tr("Error exporting JPEG"), - QObject::tr("Texture is not in a supported export format"), - QMessageBox::Ok); - return; - } - - plDDSurface dds; - dds.fFlags = plDDSurface::DDSD_CAPS | plDDSurface::DDSD_HEIGHT - | plDDSurface::DDSD_WIDTH | plDDSurface::DDSD_PIXELFORMAT - | plDDSurface::DDSD_LINEARSIZE; - dds.fCaps = plDDSurface::DDSCAPS_TEXTURE; - dds.fHeight = tex->getHeight(); - dds.fWidth = tex->getWidth(); - dds.fLinearSize = dds.fHeight * dds.fWidth * 3; - dds.fPixelFormat.fFlags = plDDSurface::DDPF_RGB; - dds.fPixelFormat.fBitDepth = 24; - dds.fPixelFormat.fRBitMask = 0xFF0000; - dds.fPixelFormat.fGBitMask = 0x00FF00; - dds.fPixelFormat.fBBitMask = 0x0000FF; - - // Strip down data to 24 bit color - unsigned char* data = new unsigned char[dds.fLinearSize]; - tex->extractColorData(data, dds.fLinearSize); - swapColorChannels(data, dds.fLinearSize); - dds.setData(dds.fLinearSize, data); - delete[] data; - - dds.write(S); -} - -static void makeJAlphaSurface(const plMipmap* tex, hsStream* S) -{ - if (tex->getCompressionType() != plBitmap::kJPEGCompression) { - QMessageBox::critical(NULL, QObject::tr("Error exporting JPEG"), - QObject::tr("Texture is not in a supported export format"), - QMessageBox::Ok); - return; - } - - plDDSurface dds; - dds.fFlags = plDDSurface::DDSD_CAPS | plDDSurface::DDSD_HEIGHT - | plDDSurface::DDSD_WIDTH | plDDSurface::DDSD_PIXELFORMAT - | plDDSurface::DDSD_LINEARSIZE; - dds.fCaps = plDDSurface::DDSCAPS_TEXTURE; - dds.fHeight = tex->getHeight(); - dds.fWidth = tex->getWidth(); - dds.fLinearSize = dds.fHeight * dds.fWidth; - dds.fPixelFormat.fFlags = plDDSurface::DDPF_LUMINANCE; - dds.fPixelFormat.fBitDepth = 8; - dds.fPixelFormat.fLuminanceBitMask = 0xFF; - - // Strip down data to alpha luminance - unsigned char* data = new unsigned char[dds.fLinearSize]; - tex->extractAlphaData(data, dds.fLinearSize); - dds.setData(dds.fLinearSize, data); - delete[] data; - - dds.write(S); -} - -static bool getJColorSurface(const plDDSurface& dds, plMipmap* tex) -{ - if ((dds.fFlags & plDDSurface::DDSD_HEIGHT) == 0 || - (dds.fFlags & plDDSurface::DDSD_WIDTH) == 0 || - (dds.fFlags & plDDSurface::DDSD_PIXELFORMAT) == 0) { - QMessageBox::critical(NULL, QObject::tr("Error importing JPEG"), - QObject::tr("DDSurface does not contain required fields"), - QMessageBox::Ok); - return false; - } - if ((dds.fPixelFormat.fFlags & plDDSurface::DDPF_RGB) == 0 || - (dds.fPixelFormat.fBitDepth != 24) || - (dds.fPixelFormat.fRBitMask != 0xFF0000) || - (dds.fPixelFormat.fGBitMask != 0x00FF00) || - (dds.fPixelFormat.fBBitMask != 0x0000FF)) { - QMessageBox::critical(NULL, QObject::tr("Error importing JPEG"), - QObject::tr("DDS file should be in RGB888 format")); - return false; - } - - tex->Create(dds.fWidth, dds.fHeight, 0, plBitmap::kJPEGCompression, plBitmap::kRGB8888); - tex->setColorData(dds.getData(), dds.getDataSize()); - swapColorChannels(reinterpret_cast(tex->getImageData()), dds.getDataSize()); - return true; -} - -static bool getJAlphaSurface(const plDDSurface& dds, plMipmap* tex) -{ - if ((dds.fFlags & plDDSurface::DDSD_HEIGHT) == 0 || - (dds.fFlags & plDDSurface::DDSD_WIDTH) == 0 || - (dds.fFlags & plDDSurface::DDSD_PIXELFORMAT) == 0) { - QMessageBox::critical(NULL, QObject::tr("Error importing JPEG"), - QObject::tr("DDSurface does not contain required fields"), - QMessageBox::Ok); - return false; - } - if ((dds.fPixelFormat.fFlags & plDDSurface::DDPF_LUMINANCE) == 0 || - (dds.fPixelFormat.fBitDepth != 8) || - (dds.fPixelFormat.fLuminanceBitMask != 0xFF)) { - QMessageBox::critical(NULL, QObject::tr("Error importing JPEG"), - QObject::tr("DDS file should be in Luminance 8-bit format"), - QMessageBox::Ok); - return false; - } - - if (tex->getWidth() != dds.fWidth || tex->getHeight() != dds.fHeight) { - QMessageBox::critical(NULL, QObject::tr("Error importing JPEG"), - QObject::tr("Alpha DDS size does not match image size"), - QMessageBox::Ok); - return false; - } - tex->setAlphaData(dds.getData(), dds.getDataSize()); - return true; -} - void QMipmap::onExportImage() { QString exportDir = getExportDir(); plMipmap* tex = plMipmap::Convert(fCreatable); From f1bcd975c27750084b07f031f935f63db4f62f5f Mon Sep 17 00:00:00 2001 From: Joseph Davies Date: Wed, 6 Mar 2024 10:36:20 -0800 Subject: [PATCH 5/7] Default to all supported image formats for import filter. --- src/PrpShop/PRP/Surface/QMipmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 2917473..09f6b52 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -421,7 +421,7 @@ void QMipmap::onImportImage() importDir.append("/" + st2qstr(tex->getKey()->getName()) .replace(QRegularExpression("[?:/\\*\"<>|]"), "_")); - QString filter = tr("DDS Files (*.dds);;JPEG Files (*.jpg *.jpeg);;PNG Files (*.png)"); + QString filter = tr("All Images (*.dds *.jpg *.jpeg *.png);;DDS Files (*.dds);;JPEG Files (*.jpg *.jpeg);;PNG Files (*.png)"); QString filename = QFileDialog::getOpenFileName(this, tr("Import Image"), importDir, filter); if (filename.isEmpty()) From 5a2d2710ed319cd5caf591a2015e891d71ac1dfe Mon Sep 17 00:00:00 2001 From: Joseph Davies Date: Sat, 9 Mar 2024 15:19:41 -0800 Subject: [PATCH 6/7] Consolidate byte-swapping for color components. Co-authored-by: Michael Hansen --- src/PrpShop/PRP/Surface/QMipmap.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 09f6b52..19b7787 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -65,9 +65,8 @@ unsigned char* getTextureData(plMipmap *tex, size_t level=0) unsigned int* dp = (unsigned int*)imageData; for (size_t i = 0; i < size; i += 4) { //unsigned int alpha = doAlpha ? (*dp & 0xFF000000) : 0xFF000000; - *dp = (*dp & 0xFF000000) + *dp = (*dp & 0xFF00FF00) | (*dp & 0x00FF0000) >> 16 - | (*dp & 0x0000FF00) | (*dp & 0x000000FF) << 16; dp++; } From 642139b84e9d897766733cbaa1ec49e8a49928ee Mon Sep 17 00:00:00 2001 From: Joseph Davies Date: Tue, 12 Nov 2024 05:38:48 -0800 Subject: [PATCH 7/7] Add cleanup suggestions from code review. --- src/PrpShop/PRP/Surface/QMipmap.cpp | 48 ++++++++++------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/PrpShop/PRP/Surface/QMipmap.cpp b/src/PrpShop/PRP/Surface/QMipmap.cpp index 19b7787..dad9813 100644 --- a/src/PrpShop/PRP/Surface/QMipmap.cpp +++ b/src/PrpShop/PRP/Surface/QMipmap.cpp @@ -51,13 +51,11 @@ static void setExportDir(const QString& filename) unsigned char* getTextureData(plMipmap *tex, size_t level=0) { - unsigned char *imageData; - if (level >= tex->getNumLevels()) level = tex->getNumLevels() - 1; size_t size = tex->GetUncompressedSize(level); - imageData = new unsigned char[size]; + unsigned char* imageData = new unsigned char[size]; tex->DecompressImage(level, imageData, size); if (tex->getCompressionType() == plMipmap::kDirectXCompression) { @@ -350,7 +348,7 @@ void QMipmap::onExportImage() { if (filename.isEmpty()) return; - QString file_ext = QFileInfo(filename).suffix(); + QString file_ext = QFileInfo(filename).suffix().toLower(); if (file_ext == "dds") { hsFileStream S; if (!S.open(qstr2st(filename), fmCreate)) { @@ -370,8 +368,7 @@ void QMipmap::onExportImage() { QMessageBox::critical(this, tr("Error exporting DDS"), QString::fromUtf8(ex.what()), QMessageBox::Ok); } - } - else if (file_ext == "jpg" || file_ext == "jpeg") { + } else if (file_ext == "jpg" || file_ext == "jpeg") { hsFileStream S; if (!S.open(qstr2st(filename), fmCreate)) { QMessageBox::critical(this, tr("Error exporting JPEG"), @@ -384,14 +381,11 @@ void QMipmap::onExportImage() { S.write(tex->getJpegSize(), tex->getJpegImage()); } else { size_t image_size = tex->GetUncompressedSize(0); - auto image_data = new unsigned char[image_size]; - tex->DecompressImage(0, image_data, image_size); - plJPEG::CompressJPEG(&S, (void*)(image_data), image_size, tex->getWidth(), tex->getHeight(), tex->getBPP()); - delete[] image_data; + auto image_data = std::make_unique(image_size); + tex->DecompressImage(0, image_data.get(), image_size); + plJPEG::CompressJPEG(&S, image_data.get(), image_size, tex->getWidth(), tex->getHeight(), tex->getBPP()); } - S.close(); - } - else if (file_ext == "png") { + } else if (file_ext == "png") { hsFileStream S; if (!S.open(qstr2st(filename), fmCreate)) { QMessageBox::critical(this, tr("Error exporting PNG"), @@ -407,7 +401,6 @@ void QMipmap::onExportImage() { QMessageBox::critical(this, tr("Error exporting PNG"), QString::fromUtf8(ex.what()), QMessageBox::Ok); } - S.close(); } setExportDir(filename); @@ -435,28 +428,21 @@ void QMipmap::onImportImage() } try { - QString file_ext = QFileInfo(filename).suffix(); + QString file_ext = QFileInfo(filename).suffix().toLower(); if (file_ext == "dds") { plDDSurface dds; dds.read(&S); - plMipmap* newTex = dds.createMipmap(); - tex->CopyFrom(newTex); - delete newTex; + std::unique_ptr newTex(dds.createMipmap()); + tex->CopyFrom(newTex.get()); + } else if (file_ext == "jpg" || file_ext == "jpeg") { + std::unique_ptr newTex(plJPEG::DecompressJPEG(&S)); + tex->CopyFrom(newTex.get()); + } else if (file_ext == "png") { + std::unique_ptr newTex(plPNG::DecompressPNG(&S)); + tex->CopyFrom(newTex.get()); } - else if (file_ext == "jpg" || file_ext == "jpeg") { - plMipmap* newTex = plJPEG::DecompressJPEG(&S); - tex->CopyFrom(newTex); - delete newTex; - } - else if (file_ext == "png") { - plMipmap* newTex = plPNG::DecompressPNG(&S); - tex->CopyFrom(newTex); - delete newTex; - } - } - catch (hsException& ex) { + } catch (hsException& ex) { QMessageBox::critical(this, tr("Error importing image"), QString::fromUtf8(ex.what()), QMessageBox::Ok); } - S.close(); }