1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 
8 #include <QDebug>
9 #include <QImageReader>
10 #include <QMapIterator>
11 #include <QObject>
12 
13 #include "commonstrings.h"
14 #include "util_formats.h"
15 
16 #ifdef GMAGICK_FOUND
17 #include <magick/api.h>
18 #include <magick/magick.h>
19 //#include <magick/memory.h>
20 #include <magick/symbols.h>
21 #endif
22 
23 FormatsManager* FormatsManager::m_instance = nullptr;
24 
FormatsManager()25 FormatsManager::FormatsManager()
26 {
27 	m_fmts.insert(FormatsManager::AI,   QStringList() << "ai");
28 	m_fmts.insert(FormatsManager::BMP,  QStringList() << "bmp");
29 	m_fmts.insert(FormatsManager::CVG,  QStringList() << "cvg");
30 	m_fmts.insert(FormatsManager::EPS,  QStringList() << "eps" << "epsf" << "epsi" << "eps2" << "eps3" << "epi" << "ept");
31 	m_fmts.insert(FormatsManager::GIF,  QStringList() << "gif");
32 	m_fmts.insert(FormatsManager::JPEG, QStringList() << "jpg" << "jpeg");
33 	m_fmts.insert(FormatsManager::KRA,  QStringList() << "kra");
34 	m_fmts.insert(FormatsManager::ORA,  QStringList() << "ora");
35 	m_fmts.insert(FormatsManager::PAT,  QStringList() << "pat");
36 	m_fmts.insert(FormatsManager::PCT,  QStringList() << "pct" << "pic" << "pict");
37 	m_fmts.insert(FormatsManager::PDF,  QStringList() << "pdf");
38 	m_fmts.insert(FormatsManager::PGF,  QStringList() << "pgf");
39 	m_fmts.insert(FormatsManager::PNG,  QStringList() << "png");
40 	m_fmts.insert(FormatsManager::PS,   QStringList() << "ps");
41 	m_fmts.insert(FormatsManager::PSD,  QStringList() << "psd");
42 	m_fmts.insert(FormatsManager::SVG,  QStringList() << "svg" << "svgz");
43 	m_fmts.insert(FormatsManager::TIFF, QStringList() << "tif" << "tiff");
44 	m_fmts.insert(FormatsManager::UNICONV, QStringList() << "cdt" << "ccx" << "cmx" << "aff" << "sk" << "sk1" << "plt" << "dxf" << "dst" << "pes" << "exp" << "pcs");
45 	m_fmts.insert(FormatsManager::WMF,  QStringList() << "wmf");
46 	m_fmts.insert(FormatsManager::WPG,  QStringList() << "wpg");
47 	m_fmts.insert(FormatsManager::XFIG, QStringList() << "fig");
48 	m_fmts.insert(FormatsManager::XPM,  QStringList() << "xpm");
49 
50 #ifdef GMAGICK_FOUND
51 	QStringList gmagickformats;
52 	InitializeMagick(0);
53 	ExceptionInfo exception;
54 	MagickInfo **magick_array;
55 	magick_array=GetMagickInfoArray(&exception);
56 	if (!magick_array)
57 		return;
58 	for (int i=0; magick_array[i] != 0; i++)
59 	{
60 		if (magick_array[i]->stealth)
61 			continue;
62 		gmagickformats<<QString(magick_array[i]->name).toLower();
63 	}
64 	MagickFree(magick_array);
65 	//qDebug()<<gmagickformats;
66 	gmagickformats.removeAll("eps");
67 	gmagickformats.removeAll("html");
68 	gmagickformats.removeAll("pdf");
69 	gmagickformats.removeAll("pict");
70 	gmagickformats.removeAll("ps");
71 	gmagickformats.removeAll("psd");
72 	gmagickformats.removeAll("svg");
73 	gmagickformats.removeAll("svgz");
74 	gmagickformats.removeAll("tiff");
75 	gmagickformats.removeAll("txt");
76 	gmagickformats.removeAll("wmf");
77 	gmagickformats.removeAll("wpg");
78 	m_fmts.insert(FormatsManager::GMAGICK, gmagickformats);
79 #endif
80 
81 	m_fmtNames[FormatsManager::AI]   = QObject::tr("Adobe Illustrator");
82 	m_fmtNames[FormatsManager::BMP]  = QObject::tr("BMP");
83 	m_fmtNames[FormatsManager::CVG]  = QObject::tr("Calamus Vector Graphics");
84 	m_fmtNames[FormatsManager::EPS]  = QObject::tr("Encapsulated PostScript");
85 	m_fmtNames[FormatsManager::GIF]  = QObject::tr("GIF");
86 	m_fmtNames[FormatsManager::JPEG] = QObject::tr("JPEG");
87 	m_fmtNames[FormatsManager::KRA]  = QObject::tr("Krita");
88 	m_fmtNames[FormatsManager::ORA]  = QObject::tr("Open Raster");
89 	m_fmtNames[FormatsManager::PAT]  = QObject::tr("Pattern Files");
90 	m_fmtNames[FormatsManager::PDF]  = QObject::tr("PDF Document");
91 	m_fmtNames[FormatsManager::PGF]  = QObject::tr("PGF");
92 	m_fmtNames[FormatsManager::PNG]  = QObject::tr("PNG");
93 	m_fmtNames[FormatsManager::PSD]  = QObject::tr("Adobe Photoshop");
94 	m_fmtNames[FormatsManager::PS]   = QObject::tr("PostScript");
95 	m_fmtNames[FormatsManager::SVG]  = QObject::tr("Scalable Vector Graphics");
96 	m_fmtNames[FormatsManager::TIFF] = QObject::tr("TIFF");
97 	m_fmtNames[FormatsManager::WMF]  = QObject::tr("Windows Meta File");
98 	m_fmtNames[FormatsManager::WPG]  = QObject::tr("WordPerfect Graphics");
99 	m_fmtNames[FormatsManager::XFIG] = QObject::tr("Xfig File");
100 	m_fmtNames[FormatsManager::XPM]  = QObject::tr("XPM");
101 
102 #ifdef GMAGICK_FOUND
103 	m_fmtNames[FormatsManager::GMAGICK] = QObject::tr("GraphicsMagick");
104 #endif
105 	m_fmtNames[FormatsManager::PCT]  = QObject::tr("Macintosh Pict");
106 	m_fmtNames[FormatsManager::QT]  = QObject::tr("Qt Supported File");
107 	m_fmtNames[FormatsManager::UNICONV] = QObject::tr("UniConvertor");
108 
109 
110 	m_fmtMimeTypes.insert(FormatsManager::AI,   QStringList() << "application/illustrator");
111 	m_fmtMimeTypes.insert(FormatsManager::CVG,  QStringList() << "");
112 	m_fmtMimeTypes.insert(FormatsManager::EPS,  QStringList() << "application/postscript");
113 	m_fmtMimeTypes.insert(FormatsManager::GIF,  QStringList() << "image/gif");
114 	m_fmtMimeTypes.insert(FormatsManager::JPEG, QStringList() << "image/jpeg");
115 	m_fmtMimeTypes.insert(FormatsManager::KRA,  QStringList() << "application/x-krita");
116 	m_fmtMimeTypes.insert(FormatsManager::ORA,  QStringList() << "");
117 	m_fmtMimeTypes.insert(FormatsManager::PAT,  QStringList() << "");
118 	m_fmtMimeTypes.insert(FormatsManager::PCT,  QStringList() << "");
119 	m_fmtMimeTypes.insert(FormatsManager::PDF,  QStringList() << "application/pdf");
120 	m_fmtMimeTypes.insert(FormatsManager::PGF,  QStringList() << "image/pgf");
121 	m_fmtMimeTypes.insert(FormatsManager::PNG,  QStringList() << "image/png");
122 	m_fmtMimeTypes.insert(FormatsManager::PS,   QStringList() << "application/postscript");
123 	m_fmtMimeTypes.insert(FormatsManager::PSD,  QStringList() << "application/photoshop");
124 	m_fmtMimeTypes.insert(FormatsManager::QT,   QStringList() << "");
125 	m_fmtMimeTypes.insert(FormatsManager::SVG,  QStringList() << "image/svg+xml");
126 	m_fmtMimeTypes.insert(FormatsManager::TIFF, QStringList() << "image/tiff");
127 	m_fmtMimeTypes.insert(FormatsManager::WMF,  QStringList() << "image/wmf");
128 	m_fmtMimeTypes.insert(FormatsManager::WPG,  QStringList() << "");
129 	m_fmtMimeTypes.insert(FormatsManager::XFIG, QStringList() << "image/x-xfig");
130 	m_fmtMimeTypes.insert(FormatsManager::XPM,  QStringList() << "image/xpm ");
131 
132 	QMapIterator<int, QStringList> i(m_fmts);
133 	while (i.hasNext())
134 	{
135 		i.next();
136 		m_fmtList << i.value().first().toUpper();
137 	}
138 
139 	m_qtSupportedImageFormats = QImageReader::supportedImageFormats();
140 	QStringList qtFmts;
141 	for (int qf = 0; qf < m_qtSupportedImageFormats.count(); qf++)
142 	{
143 		QString fmt = m_qtSupportedImageFormats[qf];
144 		bool found = false;
145 		QMapIterator<int, QStringList> i(m_fmts);
146 		while (i.hasNext())
147 		{
148 			i.next();
149 			if (i.value().contains(fmt))
150 				found = true;
151 		}
152 		if (!found)
153 			qtFmts.append(fmt);
154 	}
155 	m_fmts.insert(FormatsManager::QT, qtFmts);
156 	m_supportedImageFormats = m_qtSupportedImageFormats;
157 	updateSupportedImageFormats(m_supportedImageFormats);
158 }
159 
~FormatsManager()160 FormatsManager::~FormatsManager()
161 {
162 }
163 
instance()164 FormatsManager* FormatsManager::instance()
165 {
166 	if (m_instance == nullptr)
167 		m_instance = new FormatsManager();
168 
169 	return m_instance;
170 }
171 
deleteInstance()172 void FormatsManager::deleteInstance()
173 {
174 	delete m_instance;
175 	m_instance = nullptr;
176 }
177 
imageFormatSupported(const QString & ext)178 void FormatsManager::imageFormatSupported(const QString& ext)
179 {
180 // 	return m_supportedImageFormats.contains(QByteArray(ext).toLatin1());
181 }
182 
updateSupportedImageFormats(QList<QByteArray> & supportedImageFormats)183 void FormatsManager::updateSupportedImageFormats(QList<QByteArray>& supportedImageFormats)
184 {
185 	QMapIterator<int, QStringList> it(m_fmts);
186 	while (it.hasNext())
187 	{
188 		it.next();
189 		QStringListIterator itSL(it.value());
190 		while (itSL.hasNext())
191 		{
192 			QString t(itSL.next());
193 			supportedImageFormats.append(t.toLocal8Bit());
194 		}
195 	}
196 }
197 
nameOfFormat(int type)198 QString FormatsManager::nameOfFormat(int type)
199 {
200 	QMapIterator<int, QString> it(m_fmtNames);
201 	while (it.hasNext())
202 	{
203 		it.next();
204 		if (type & it.key())
205 			return it.value();
206 	}
207 	return QString();
208 }
209 
mimetypeOfFormat(int type)210 QStringList FormatsManager::mimetypeOfFormat(int type)
211 {
212 	QMapIterator<int, QStringList> it(m_fmtMimeTypes);
213 	while (it.hasNext())
214 	{
215 		it.next();
216 		if (type & it.key())
217 			return it.value();
218 	}
219 	return QStringList();
220 }
221 
extensionsForFormat(int type)222 QString FormatsManager::extensionsForFormat(int type)
223 {
224 	QString a;
225 	QString b;
226 	QString c;
227 	fileTypeStrings(type, a, b, c);
228 	return b;
229 }
230 
fileDialogFormatList(int type)231 QString FormatsManager::fileDialogFormatList(int type)
232 {
233 	QString a;
234 	QString b;
235 	QString c;
236 	fileTypeStrings(type, a, b, c);
237 	return a + b + ";;" +c;
238 }
239 
extensionListForFormat(int type,int listType)240 QString FormatsManager::extensionListForFormat(int type, int listType)
241 {
242 	QString nameMatch;
243 	QString separator(listType==0 ? " *." : "|");
244 	QMapIterator<int, QStringList> it(m_fmts);
245 	bool first=true;
246 	int n=0;
247 	while (it.hasNext())
248 	{
249 		it.next();
250 		if (type & it.key())
251 		{
252 			//Just in case the Qt used doesn't support jpeg or gif
253 			if ((JPEG & it.key()) && !m_supportedImageFormats.contains(QByteArray("jpg")))
254 				continue;
255 			if ((GIF & it.key()) && !m_supportedImageFormats.contains(QByteArray("gif")))
256 				continue;
257 			if (first)
258 				first=false;
259 			QStringListIterator itSL(it.value());
260 			while (itSL.hasNext())
261 			{
262 				if (listType==0)
263 					nameMatch += separator;
264 				nameMatch += itSL.next();
265 				if (listType==1 && itSL.hasNext())
266 					nameMatch += separator;
267 			}
268 		}
269 		++n;
270 		if (listType==1 && it.hasNext() && nameMatch.length()>0 && !nameMatch.endsWith(separator))
271 			nameMatch += separator;
272 	}
273 	if (listType==0 && nameMatch.startsWith(" "))
274 		nameMatch.remove(0,1);
275 	if (listType==1 && nameMatch.endsWith("|"))
276 		nameMatch.chop(1);
277 	return nameMatch;
278 }
279 
fileTypeStrings(int type,QString & formatList,QString & formatText,QString & formatAll,bool lowerCaseOnly)280 void FormatsManager::fileTypeStrings(int type, QString& formatList, QString& formatText, QString& formatAll, bool lowerCaseOnly)
281 {
282 	QString allFormats = QObject::tr("All Supported Formats")+" (";
283 	QStringList formats;
284 	QMapIterator<int, QStringList> it(m_fmts);
285 	bool first=true;
286 	int n=0;
287 	while (it.hasNext())
288 	{
289 		it.next();
290 		if (type & it.key())
291 		{
292 			//Just in case the Qt used doesn't support jpeg or gif
293 			if ((JPEG & it.key()) && !m_supportedImageFormats.contains(QByteArray("jpg")))
294 				continue;
295 			if ((GIF & it.key()) && !m_supportedImageFormats.contains(QByteArray("gif")))
296 				continue;
297 			if (first)
298 				first=false;
299 			else
300 			{
301 				allFormats += " ";
302 			}
303 			QString text=m_fmtNames[it.key()] + " (";
304 			QStringListIterator itSL(it.value());
305 			while (itSL.hasNext())
306 			{
307 				QString t("*." + itSL.next());
308 				allFormats += t;
309 				text += t;
310 				if(!lowerCaseOnly)
311 				{
312 					allFormats += " " + t.toUpper();
313 					text += " " + t.toUpper();
314 				}
315 				if (itSL.hasNext())
316 				{
317 					allFormats += " ";
318 					text += " ";
319 				}
320 			}
321 			text += ")";
322 			formats.append(text);
323 		}
324 		++n;
325 	}
326 	formatList+=allFormats + ");;";
327 	formats.sort(Qt::CaseInsensitive);
328 	formatText+=formats.join(";;");
329 	formatAll=QObject::tr("All Files (*)");
330 }
331 
extensionIndicatesEPS(const QString & ext)332 bool extensionIndicatesEPS(const QString &ext)
333 {
334 	QStringList strl;
335 	strl << "eps" << "epsf" << "epsi" << "eps2" << "eps3" << "epi" << "ept";
336 	return strl.contains(ext, Qt::CaseInsensitive);
337 }
338 
extensionIndicatesEPSorPS(const QString & ext)339 bool extensionIndicatesEPSorPS(const QString &ext)
340 {
341 	QStringList strl;
342 	strl << "eps" << "epsf" << "epsi" << "ps" << "eps2" << "eps3" << "epi" << "ept";
343 	return strl.contains(ext, Qt::CaseInsensitive);
344 }
345 
extensionIndicatesJPEG(const QString & ext)346 bool extensionIndicatesJPEG(const QString &ext)
347 {
348 	QStringList strl;
349 	strl << "jpg" << "jpeg";
350 	return strl.contains(ext, Qt::CaseInsensitive);
351 }
352 
extensionIndicatesPDF(const QString & ext)353 bool extensionIndicatesPDF(const QString &ext)
354 {
355 	QStringList strl;
356 	strl << "ai" << "pdf";
357 	return strl.contains(ext, Qt::CaseInsensitive);
358 }
359 
extensionIndicatesPNG(const QString & ext)360 bool extensionIndicatesPNG(const QString &ext)
361 {
362 	QStringList strl;
363 	strl << "png";
364 	return strl.contains(ext, Qt::CaseInsensitive);
365 }
366 
extensionIndicatesPSD(const QString & ext)367 bool extensionIndicatesPSD(const QString &ext)
368 {
369 	QStringList strl;
370 	strl << "psd";
371 	return strl.contains(ext, Qt::CaseInsensitive);
372 }
373 
extensionIndicatesTIFF(const QString & ext)374 bool extensionIndicatesTIFF(const QString &ext)
375 {
376 	QStringList strl;
377 	strl << "tif" << "tiff";
378 	return strl.contains(ext, Qt::CaseInsensitive);
379 }
380 
extensionIndicatesPattern(const QString & ext)381 bool extensionIndicatesPattern(const QString &ext)
382 {
383 	QStringList strl;
384 	strl << "pat";
385 	return strl.contains(ext, Qt::CaseInsensitive);
386 }
387 
getImageType(const QString & filename)388 QString getImageType(const QString& filename)
389 {
390 	QString ret;
391 	QFile f(filename);
392 	QFileInfo fi(f);
393 	if (fi.exists())
394 	{
395 		QByteArray buf(24, ' ');
396 		if (f.open(QIODevice::ReadOnly))
397 		{
398 			f.read(buf.data(), 24);
399 			if ((buf[0] == '%') && (buf[1] == '!') && (buf[2] == 'P') && (buf[3] == 'S') && (buf[4] == '-') && (buf[5] == 'A'))
400 				ret = "eps";
401 			else if ((buf[0] == '\xC5') && (buf[1] == '\xD0') && (buf[2] == '\xD3') && (buf[3] == '\xC6'))
402 				ret = "eps";
403 			else if ((buf[0] == 'G') && (buf[1] == 'I') && (buf[2] == 'F') && (buf[3] == '8'))
404 				ret = "gif";
405 			else if ((buf[0] == '\xFF') && (buf[1] == '\xD8') && (buf[2] == '\xFF'))
406 				ret = "jpg";
407 			else if ((buf[20] == 'G') && (buf[21] == 'P') && (buf[22] == 'A') && (buf[23] == 'T'))
408 				ret = "pat";
409 			else if ((buf[0] == '%') && (buf[1] == 'P') && (buf[2] == 'D') && (buf[3] == 'F'))
410 				ret = "pdf";
411 			else if ((buf[0] == 'P') && (buf[1] == 'G') && (buf[2] == 'F'))
412 				ret = "pgf";
413 			else if ((buf[0] == '\x89') && (buf[1] == 'P') && (buf[2] == 'N') && (buf[3] == 'G'))
414 				ret = "png";
415 			else if ((buf[0] == '8') && (buf[1] == 'B') && (buf[2] == 'P') && (buf[3] == 'S'))
416 				ret = "psd";
417 			else if (((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == '\x2A')) || ((buf[0] == 'M') && (buf[1] == 'M') && (buf[3] == '\x2A')))
418 				ret = "tif";
419 			else if ((buf[0] == '/') && (buf[1] == '*') && (buf[2] == ' ') && (buf[3] == 'X') && (buf[4] == 'P') && (buf[5] == 'M'))
420 				ret = "xpm";
421 			else if ((buf[0] == 'V') && (buf[1] == 'C') && (buf[2] == 'L') && (buf[3] == 'M') && (buf[4] == 'T') && (buf[5] == 'F'))
422 				ret = "svm";
423 			f.close();
424 		}
425 	}
426 	return ret;
427 }
428