File indexing completed on 2024-05-12 15:55:34
0001 // SPDX-FileCopyrightText: 2003-2012 Jesper K. Pedersen <jesper.pedersen@kdab.com> 0002 // SPDX-FileCopyrightText: 2005 Steffen Hansen <hansen@kde.org> 0003 // SPDX-FileCopyrightText: 2006-2009 Tuomas Suutari <tuomas@nepnep.net> 0004 // SPDX-FileCopyrightText: 2007 Dirk Mueller <mueller@kde.org> 0005 // SPDX-FileCopyrightText: 2007 Laurent Montel <montel@kde.org> 0006 // SPDX-FileCopyrightText: 2007-2012 Jan Kundrát <jkt@flaska.net> 0007 // SPDX-FileCopyrightText: 2010 Miika Turkia <miika.turkia@gmail.com> 0008 // SPDX-FileCopyrightText: 2012 Rex Dieter <rdieter@math.unl.edu> 0009 // SPDX-FileCopyrightText: 2013-2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0010 // SPDX-FileCopyrightText: 2016 Tobias Leupold <tl@stonemx.de> 0011 // SPDX-FileCopyrightText: 2018 Robert Krawitz <rlk@alum.mit.edu> 0012 0013 // SPDX-License-Identifier: GPL-2.0-or-later 0014 0015 #include "FileExtensions.h" 0016 0017 #include <kpabase/SettingsData.h> 0018 #include <kpabase/config-kpa-kdcraw.h> 0019 #ifdef HAVE_KDCRAW 0020 #include <KDCRAW/RawFiles> 0021 #include <libkdcraw_version.h> 0022 #endif 0023 0024 #include <QFileInfo> 0025 #include <QSet> 0026 #include <QString> 0027 0028 namespace 0029 { 0030 void _initializeExtensionLists(QStringList &rawExtensions, QStringList &standardExtensions, QStringList &ignoredExtensions) 0031 { 0032 static QStringList _rawExtensions, _standardExtensions, _ignoredExtensions; 0033 static bool extensionListsInitialized = false; 0034 if (!extensionListsInitialized) { 0035 #ifdef HAVE_KDCRAW 0036 _rawExtensions = QString::fromLatin1(raw_file_extentions).split(QChar::fromLatin1(' '), Qt::SkipEmptyParts); 0037 #endif /* HAVE_KDCRAW */ 0038 for (QStringList::iterator it = _rawExtensions.begin(); it != _rawExtensions.end(); ++it) 0039 (*it).remove(QString::fromUtf8("*.")); 0040 0041 _standardExtensions << QString::fromLatin1("jpg") 0042 << QString::fromLatin1("JPG") 0043 << QString::fromLatin1("jpeg") 0044 << QString::fromLatin1("JPEG") 0045 << QString::fromLatin1("tif") 0046 << QString::fromLatin1("TIF") 0047 << QString::fromLatin1("tiff") 0048 << QString::fromLatin1("TIFF") 0049 << QString::fromLatin1("png") 0050 << QString::fromLatin1("PNG"); 0051 _ignoredExtensions << QString::fromLatin1("thm") // Thumbnails 0052 << QString::fromLatin1("THM") 0053 << QString::fromLatin1("thumb") // thumbnail files 0054 // from dcraw 0055 << QString::fromLatin1("ctg") // Catalog files 0056 << QString::fromLatin1("gz") // Compressed files 0057 << QString::fromLatin1("Z") 0058 << QString::fromLatin1("bz2") 0059 << QString::fromLatin1("zip") 0060 << QString::fromLatin1("xml") 0061 << QString::fromLatin1("XML") 0062 << QString::fromLatin1("html") 0063 << QString::fromLatin1("HTML") 0064 << QString::fromLatin1("htm") 0065 << QString::fromLatin1("HTM") 0066 << QString::fromLatin1("pp3") // RawTherapee Sidecar files 0067 << QString::fromLatin1("PP3") 0068 << QString::fromLatin1("xmp") // Other sidecars 0069 << QString::fromLatin1("XMP") 0070 << QString::fromLatin1("pto") // Hugin sidecars 0071 << QString::fromLatin1("PTO"); 0072 0073 QChar dot(QChar::fromLatin1('.')); 0074 for (QStringList::iterator it = _rawExtensions.begin(); it != _rawExtensions.end(); ++it) 0075 if (!(*it).startsWith(dot)) 0076 *it = dot + *it; 0077 for (QStringList::iterator it = _standardExtensions.begin(); it != _standardExtensions.end(); ++it) 0078 if (!(*it).startsWith(dot)) 0079 *it = dot + *it; 0080 for (QStringList::iterator it = _ignoredExtensions.begin(); it != _ignoredExtensions.end(); ++it) 0081 if (!(*it).startsWith(dot)) 0082 *it = dot + *it; 0083 0084 extensionListsInitialized = true; 0085 } 0086 0087 rawExtensions = _rawExtensions; 0088 standardExtensions = _standardExtensions; 0089 ignoredExtensions = _ignoredExtensions; 0090 } 0091 bool _fileExistsWithExtensions(const DB::FileName &fileName, 0092 const QStringList &extensionList) 0093 { 0094 QString baseFileName = fileName.absolute(); 0095 int extStart = baseFileName.lastIndexOf(QChar::fromLatin1('.')); 0096 // We're interested in xxx.yyy, not .yyy 0097 if (extStart <= 1) 0098 return false; 0099 baseFileName.remove(extStart, baseFileName.length() - extStart); 0100 for (QStringList::ConstIterator it = extensionList.begin(); 0101 it != extensionList.end(); ++it) { 0102 if (QFile::exists(baseFileName + *it)) 0103 return true; 0104 } 0105 return false; 0106 } 0107 0108 bool _fileIsKnownWithExtensions(const DB::FileNameSet &files, 0109 const DB::FileName &fileName, 0110 const QStringList &extensionList) 0111 { 0112 QString baseFileName = fileName.absolute(); 0113 int extStart = baseFileName.lastIndexOf(QChar::fromLatin1('.')); 0114 if (extStart <= 1) 0115 return false; 0116 baseFileName.remove(extStart, baseFileName.length() - extStart); 0117 for (QStringList::ConstIterator it = extensionList.begin(); 0118 it != extensionList.end(); ++it) { 0119 if (files.contains(DB::FileName::fromAbsolutePath(baseFileName + *it))) 0120 return true; 0121 } 0122 return false; 0123 } 0124 0125 bool _fileEndsWithExtensions(const DB::FileName &fileName, 0126 const QStringList &extensionList) 0127 { 0128 for (QStringList::ConstIterator it = extensionList.begin(); 0129 it != extensionList.end(); ++it) { 0130 if (fileName.relative().endsWith(*it, Qt::CaseInsensitive)) 0131 return true; 0132 } 0133 return false; 0134 } 0135 } // namespace 0136 0137 bool KPABase::fileCanBeSkipped(const DB::FileNameSet &loadedFiles, const DB::FileName &imageFile) 0138 { 0139 QStringList _rawExtensions, _standardExtensions, _ignoredExtensions; 0140 _initializeExtensionLists(_rawExtensions, _standardExtensions, _ignoredExtensions); 0141 0142 // We're not interested in thumbnail and other files. 0143 if (_fileEndsWithExtensions(imageFile, _ignoredExtensions)) 0144 return true; 0145 0146 // If we *are* interested in raw files even when other equivalent 0147 // non-raw files are available, then we're interested in this file. 0148 if (!(Settings::SettingsData::instance()->skipRawIfOtherMatches())) 0149 return false; 0150 0151 // If the file ends with something other than a known raw extension, 0152 // we're interested in it. 0153 if (!_fileEndsWithExtensions(imageFile, _rawExtensions)) 0154 return false; 0155 0156 // At this point, the file ends with a known raw extension, and we're 0157 // not interested in raw files when other non-raw files are available. 0158 // So search for an existing file with one of the standard 0159 // extensions. 0160 // 0161 // This may not be the best way to do this, but it's using the 0162 // same algorithm as _mightDecode above. 0163 // -- Robert Krawitz rlk@alum.mit.edu 2007-07-22 0164 0165 return _fileIsKnownWithExtensions(loadedFiles, imageFile, _standardExtensions); 0166 } 0167 0168 bool KPABase::isUsableRawImage(const DB::FileName &imageFile, FileTypePreference preference) 0169 { 0170 QStringList _rawExtensions, _standardExtensions, _ignoredExtensions; 0171 _initializeExtensionLists(_rawExtensions, _standardExtensions, _ignoredExtensions); 0172 0173 if (preference == FileTypePreference::PreferNonRawFile && _fileExistsWithExtensions(imageFile, _standardExtensions)) 0174 return false; 0175 if (_fileEndsWithExtensions(imageFile, _rawExtensions)) 0176 return true; 0177 return false; 0178 } 0179 0180 QStringList KPABase::rawExtensions() 0181 { 0182 QStringList _rawExtensions, _standardExtensions, _ignoredExtensions; 0183 _initializeExtensionLists(_rawExtensions, _standardExtensions, _ignoredExtensions); 0184 return _rawExtensions; 0185 } 0186 0187 bool KPABase::isVideo(const DB::FileName &fileName) 0188 { 0189 QFileInfo fi(fileName.relative()); 0190 QString ext = fi.suffix().toLower(); 0191 return videoExtensions().contains(ext); 0192 } 0193 0194 const QSet<QString> &KPABase::videoExtensions() 0195 { 0196 static QSet<QString> videoExtensions; 0197 if (videoExtensions.empty()) { 0198 videoExtensions.insert(QString::fromLatin1("3gp")); 0199 videoExtensions.insert(QString::fromLatin1("avi")); 0200 videoExtensions.insert(QString::fromLatin1("mp4")); 0201 videoExtensions.insert(QString::fromLatin1("m4v")); 0202 videoExtensions.insert(QString::fromLatin1("mpeg")); 0203 videoExtensions.insert(QString::fromLatin1("mpg")); 0204 videoExtensions.insert(QString::fromLatin1("qt")); 0205 videoExtensions.insert(QString::fromLatin1("mov")); 0206 videoExtensions.insert(QString::fromLatin1("moov")); 0207 videoExtensions.insert(QString::fromLatin1("qtvr")); 0208 videoExtensions.insert(QString::fromLatin1("rv")); 0209 videoExtensions.insert(QString::fromLatin1("3g2")); 0210 videoExtensions.insert(QString::fromLatin1("fli")); 0211 videoExtensions.insert(QString::fromLatin1("flc")); 0212 videoExtensions.insert(QString::fromLatin1("mkv")); 0213 videoExtensions.insert(QString::fromLatin1("mng")); 0214 videoExtensions.insert(QString::fromLatin1("asf")); 0215 videoExtensions.insert(QString::fromLatin1("asx")); 0216 videoExtensions.insert(QString::fromLatin1("wmp")); 0217 videoExtensions.insert(QString::fromLatin1("wmv")); 0218 videoExtensions.insert(QString::fromLatin1("ogm")); 0219 videoExtensions.insert(QString::fromLatin1("rm")); 0220 videoExtensions.insert(QString::fromLatin1("flv")); 0221 videoExtensions.insert(QString::fromLatin1("webm")); 0222 videoExtensions.insert(QString::fromLatin1("mts")); 0223 videoExtensions.insert(QString::fromLatin1("ogg")); 0224 videoExtensions.insert(QString::fromLatin1("ogv")); 0225 videoExtensions.insert(QString::fromLatin1("m2ts")); 0226 } 0227 return videoExtensions; 0228 } 0229 // vi:expandtab:tabstop=4 shiftwidth=4: