-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathpngyu_execute_pngquant_command.cpp
163 lines (145 loc) · 3.9 KB
/
pngyu_execute_pngquant_command.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "pngyu_execute_pngquant_command.h"
#include <QProcess>
#include <QDir>
#include <QApplication>
#include <QDebug>
namespace pngyu
{
QStringList find_executable_pngquant_from_dir( const QDir &dir )
{
QStringList found_paths;
if( ! dir.exists() )
{
return found_paths;
}
foreach( const QFileInfo &child_file_info, dir.entryInfoList() )
{
if( ! child_file_info.baseName().contains( QRegExp( "pngquant", Qt::CaseInsensitive ) ) ||
! child_file_info.isExecutable() )
{
continue;
}
if( pngyu::is_executable_pnqguant( child_file_info ) )
{
found_paths.push_back( child_file_info.absoluteFilePath() );
}
}
return found_paths;
}
QString pngquant_version( const QString &pngquant_path )
{
QProcess process;
process.setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
process.start( pngquant_path, QStringList() << "--version" );
process.waitForFinished();
const QString &version = process.readAllStandardOutput();
return version.trimmed();
}
bool is_executable_pnqguant( const QFileInfo pngquant_path )
{
if( ! pngquant_path.exists() || ! pngquant_path.isExecutable() || pngquant_path.isBundle() )
{
return false;
}
const QString &version = pngquant_version( pngquant_path.absoluteFilePath() );
return ! version.isEmpty();
}
QStringList find_executable_pngquant()
{
QStringList search_dirs;
#ifdef Q_OS_MACX
search_dirs << ( QApplication::applicationDirPath() + "/../Resources" );
#endif
#ifdef Q_OS_UNIX
search_dirs << "/usr/bin"
<< "/usr/local/bin"
<< "/usr/sbin";
#endif
#ifdef Q_OS_WIN
search_dirs << ( QApplication::applicationDirPath() + "/pngquant" );
#endif
QStringList found_paths;
foreach( const QString &dir, search_dirs )
{
found_paths.append( find_executable_pngquant_from_dir( QDir(dir) ) );
}
return found_paths;
}
QPair<bool,QString> execute_compress(
const QString &pngquant_command )
{
typedef QPair<bool,QString> result_t;
bool compress_succeed = true;
QString error_string;
try
{
QProcess process;
process.setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
process.start( pngquant_command );
if( ! process.waitForStarted() )
{
throw QString( "Error: Process cannot started" );
}
if( ! process.waitForFinished( 30000 ) )
{
throw QString( "Error: Process timeout" );
}
const int exit_code = process.exitCode();
if( process.exitCode() != 0 )
{
throw QString( "Error code : %1\nCause : %2" )
.arg( exit_code )
.arg( QString(process.readAllStandardError()) );
}
}
catch( const QString &e )
{
compress_succeed = false;
error_string = e;
}
return result_t( compress_succeed, error_string );
}
QPair<QByteArray,QString> execute_compress_stdio_mode(
const QString &pngquant_command,
const QByteArray &src_png_data
)
{
typedef QPair<QByteArray,QString> result_t;
QByteArray dst_png_data;
QString error_string;
try
{
if( src_png_data.isEmpty() )
{
throw QString( "Error: Original data is empty" );
}
QProcess process;
process.setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
process.start( pngquant_command );
if( ! process.waitForStarted() )
{
throw QString( "Error: Process cannot started" );
}
process.write( src_png_data );
process.closeWriteChannel();
if( ! process.waitForFinished() )
{
throw QString( "Error: Process timeout" );
}
const int exit_code = process.exitCode();
if( process.exitCode() != 0 )
{
throw QString( "Error code : %1\nCause : %2" )
.arg( exit_code )
.arg( QString(process.readAllStandardError()) );
}
dst_png_data = process.readAllStandardOutput();
}
catch( const QString &e )
{
dst_png_data.clear();
error_string = e;
}
return result_t( dst_png_data, error_string );
}
}