caesium/compressionthread.cpp
Gary Wang 216e1a9f71 init commit that compiles
Commit the original Caesium 1.7.0 codebase with some adjustment.
You can also get the original source at:

https://sourceforge.net/projects/caesium/files/1.7.0/

Since the file names listed in the Qt resource file have encoding
issue which can cause compile failure, these files get removed.

Adjustments:

+ .gitignore
M icons.qrc
- *.pro.user(.*)
- icons/language/*.png
2021-09-10 10:03:13 +08:00

384 lines
14 KiB
C++

/*******************************************************************************
#
# Copyright (C) 2010-2013 Matteo Paonessa <matteo.paonessa@gmail.com>
#
# This file is part of the Caesium distribution.
#
# Caesium is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# Caesium is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Caesium; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
#
# Author: Matteo Paonessa <matteo.paonessa@gmail.com>
#
# ******************************************************************************/
#include "compressionthread.h"
#include "caesium.h"
#include "ui_caesium.h"
#include "global.h"
#include "imageresize.h"
#include <QSettings>
#include <QFile>
#include <QMessageBox>
#include <QDebug>
#include <QProgressDialog>
#include <windows.h>
#include <afxres.h>
#include <tchar.h>
#include <iostream>
WCHAR *qStringToWideChar(const QString &str)
{
if (str.isNull())
return 0;
WCHAR *result = new WCHAR[str.length() + 1];
for (int i = 0; i < str.length(); ++i)
result[i] = str[i].unicode();
result[str.length()] = 0;
return result;
}
void startProcess(QString argv)
{
WCHAR* exe = qStringToWideChar(argv);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcessW( NULL,
exe,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi )
)
{
return;
}
WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
CompressionThread::CompressionThread(QStringList list, QString orig_dir, QString dir, QString format, QString suffix, QStringList quality, bool checked, QList<int> w, QList<int> h, bool fixed, bool keepARatio, bool notEnlarge, bool resize, bool structure,
QObject *parent)
: QThread(parent)
{
t_list = list;
t_dir = dir;
t_format = format;
t_suffix = suffix;
t_quality = quality;
t_checked = checked;
t_w = w;
t_h = h;
t_fixed = fixed;
t_keepARatio = keepARatio;
t_notEnlarge = notEnlarge;
t_resize = resize;
t_structure = structure;
t_orig_dir = orig_dir;
settings.setIniCodec("UTF-8");
}
QString t_getRatio(int origSize, int newSize)
{
int ratio = newSize * 100 / origSize;
if (ratio <= 100)
{
return QString::number(ratio - 100) + " %";
}
else
{
return "+" + QString::number(ratio - 100) + " %";
}
}
void CompressionThread::run()
{
bool sameFormat = false;
QString t_dir_original = t_dir;
if (t_format == "null")
{
sameFormat = true;
}
bool no_enlarge = settings.value("Preferences/noenlarge").value<bool>();
if (no_enlarge)
{
CompressionThread::noEnlarge();
return;
}
ImageResize imgResize;
for (int i = 0; i < t_list.count(); i++)
{
QString right_dir = "";
QString originalQuality = t_quality.at(i);
QFileInfo info(t_list.at(i));
if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
continue;
}
if (QFile::exists(t_list.at(i)))
{
if (sameFormat)
{
t_format = info.suffix();
if (t_format.toLower() != "jpg")
{
t_quality.replace(i, "1");
}
else
{
t_quality.replace(i, originalQuality);
}
}
int old_size = info.size();
emit processingIcon(i, info.fileName());
QImage image(t_list.at(i));
if (t_resize && t_fixed)
{
image = imgResize.fixedResize(image, t_w.at(i), t_h.at(i), t_keepARatio, t_notEnlarge);
}
else if (t_resize && t_fixed == false)
{
if (t_w.at(i) == -1 && t_h.at(i) == -1)
{
t_w.replace(i, image.width());
t_h.replace(i, image.height());
}
image = imgResize.pergentageResize(image, t_w.at(i), t_h.at(i));
}
if (t_checked)
{
t_dir = info.path();
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else if (t_structure)
{
right_dir = info.path().remove(t_orig_dir.replace('\\', '/'), Qt::CaseSensitive);
right_dir = t_dir_original + right_dir;
right_dir.replace('\\', '/');
t_dir = right_dir;
if (!QDir(t_dir).exists())
{
if (!QDir().mkpath(t_dir))
{
emit errorMessageBox();
return;
}
}
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else
{
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
if (settings.value("Preferences/exif").value<bool>() && t_format.toLower() == "jpg")
{
QString exec = "tools\\exif_copy.exe \"" + t_list.at(i) + "\" \"" + t_dir + "\\" + info.completeBaseName() + t_suffix +"\"";
startProcess(exec);
}
QFile newImage(t_dir + "/" + info.completeBaseName() + t_suffix);
QFileInfo newInfo;
if (QFile::exists(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format))
{
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
newImage.rename(t_dir + "/" + info.completeBaseName() + t_suffix, t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
newInfo.setFile(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
int size = newInfo.size();
QString ratio = t_getRatio(old_size, newInfo.size());
if(settings.value("Preferences/keepdate").value<bool>())
{
CompressionThread::keepDate(t_list.at(i), newInfo.filePath());
}
emit updateUI(i + 1, size, ratio);
}
else
{
emit updateUI(i + 1, -1, "0%");
}
}
exit();
}
void CompressionThread::noEnlarge()
{
ImageResize imgResize;
QString t_dir_original = t_dir;
bool sameFormat = false;
if (t_format == "null")
{
sameFormat = true;
}
for (int i = 0; i < t_list.count(); i++)
{
QString originalQuality = t_quality.at(i);
QString right_dir = "";
QFileInfo info(t_list.at(i));
if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
continue;
}
if (QFile::exists(t_list.at(i)))
{
if (sameFormat)
{
t_format = info.suffix();
if (t_format.toLower() != "jpg")
{
t_quality.replace(i, "1");
}
else
{
t_quality.replace(i, originalQuality);
}
}
int old_size = info.size();
emit processingIcon(i, info.fileName());
QImage image(t_list.at(i));
if (t_resize && t_fixed)
{
image = imgResize.fixedResize(image, t_w.at(i), t_h.at(i), t_keepARatio, t_notEnlarge);
}
else if (t_resize && t_fixed == false)
{
image = imgResize.pergentageResize(image, t_w.at(i), t_h.at(i));
}
if (t_checked)
{
t_dir = info.path();
image.save(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else if (t_structure)
{
right_dir = info.path().remove(t_orig_dir.replace('\\', '/'), Qt::CaseSensitive);
right_dir = t_dir_original + right_dir;
right_dir.replace('\\', '/');
t_dir = right_dir;
if (!QDir(t_dir).exists())
{
if (!QDir().mkdir(t_dir))
{
emit errorMessageBox();
return;
}
}
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else
{
image.save(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
if (settings.value("Preferences/exif").value<bool>() && t_format.toLower() == "jpg")
{
QString exec = "tools\\exif_copy.exe \"" + t_list.at(i) + "\" \"" + t_dir + "\\" + info.completeBaseName() + t_suffix + "." + t_format + "\"";
startProcess(exec);
}
QFileInfo newInfo(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd");
int size = newInfo.size();
QString ratio = t_getRatio(old_size, newInfo.size());
if (newInfo.size() > info.size())
{
size *= -1;
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd");
}
else
{
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
QFile::rename(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
if(settings.value("Preferences/keepdate").value<bool>())
{
CompressionThread::keepDate(t_list.at(i), t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
emit updateUI(i + 1, size, ratio);
}
else if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
}
else
{
emit updateUI(i + 1, -1, "0%");
}
}
}
void CompressionThread::keepDate(QString orig, QString dest)
{
HANDLE hFile, hFile2;
FILETIME ftCreate, ftAccess, ftWrite;
hFile = CreateFile(qStringToWideChar(orig), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite);
hFile2 = CreateFile(qStringToWideChar(dest), FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetFileTime(hFile2, &ftCreate, &ftAccess, &ftWrite);
CloseHandle(hFile);
CloseHandle(hFile2);
}
void CompressionThread::optimizePNG(QString file, int level)
{
QString exec = "tools\\optipng.exe -o" + QString::number(level) + " \"" + file + "\"";
startProcess(exec);
}