File indexing completed on 2025-01-19 03:51:00
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2019-09-22 0007 * Description : HEIF DImg plugin. 0008 * 0009 * SPDX-FileCopyrightText: 2019-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "dimgheifplugin.h" 0016 0017 // Qt includes 0018 0019 #include <QFile> 0020 0021 // KDE includes 0022 0023 #include <klocalizedstring.h> 0024 0025 // Local includes 0026 0027 #include "digikam_debug.h" 0028 #include "digikam_config.h" 0029 #include "digikam_globals.h" 0030 #include "dimgheifloader.h" 0031 #include "dimgheifexportsettings.h" 0032 0033 namespace DigikamHEIFDImgPlugin 0034 { 0035 0036 DImgHEIFPlugin::DImgHEIFPlugin(QObject* const parent) 0037 : DPluginDImg(parent) 0038 { 0039 } 0040 0041 DImgHEIFPlugin::~DImgHEIFPlugin() 0042 { 0043 } 0044 0045 QString DImgHEIFPlugin::name() const 0046 { 0047 return i18nc("@title", "HEIF loader"); 0048 } 0049 0050 QString DImgHEIFPlugin::iid() const 0051 { 0052 return QLatin1String(DPLUGIN_IID); 0053 } 0054 0055 QIcon DImgHEIFPlugin::icon() const 0056 { 0057 return QIcon::fromTheme(QLatin1String("image-x-generic")); 0058 } 0059 0060 QString DImgHEIFPlugin::description() const 0061 { 0062 return i18nc("@info", "An image loader based on Libheif codec"); 0063 } 0064 0065 QString DImgHEIFPlugin::details() const 0066 { 0067 QString x265Notice = i18nc("@info", "This library is not present on your system."); 0068 0069 #ifdef HAVE_X265 0070 0071 int depth = DImgHEIFLoader::x265MaxBitsDepth(); 0072 0073 if (depth != -1) 0074 { 0075 x265Notice = i18nc("@info", "This library is available on your system with a maximum color depth " 0076 "support of %1 bits.", depth); 0077 } 0078 else 0079 { 0080 x265Notice = i18nc("@info", "This library is available on your system but is not able to encode " 0081 "image with a suitable color depth."); 0082 } 0083 0084 #endif 0085 0086 return xi18nc("@info", 0087 "<para>This plugin allows users to load and save image using Libheif codec.</para>" 0088 "<para>High Efficiency Image File Format (HEIF), also known as High Efficiency Image Coding (HEIC), " 0089 "is a file format for individual images and image sequences. It was developed by the " 0090 "Moving Picture Experts Group (MPEG) and it claims that twice as much information can be " 0091 "stored in a HEIF image as in a JPEG image of the same size, resulting in a better quality image. " 0092 "HEIF also supports animation, and is capable of storing more information than an animated GIF " 0093 "at a small fraction of the size.</para>" 0094 "<para>Encoding HEIC is relevant of optional libde265 codec. %1</para>" 0095 "<para>See <a href='https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format'>" 0096 "High Efficiency Image File Format</a> for details.</para>", x265Notice); 0097 } 0098 0099 QString DImgHEIFPlugin::handbookSection() const 0100 { 0101 return QLatin1String("supported_materials"); 0102 } 0103 0104 QString DImgHEIFPlugin::handbookChapter() const 0105 { 0106 return QLatin1String("image_formats"); 0107 } 0108 0109 QString DImgHEIFPlugin::handbookReference() const 0110 { 0111 return QLatin1String("image-heif"); 0112 } 0113 0114 QList<DPluginAuthor> DImgHEIFPlugin::authors() const 0115 { 0116 return QList<DPluginAuthor>() 0117 << DPluginAuthor(QString::fromUtf8("Gilles Caulier"), 0118 QString::fromUtf8("caulier dot gilles at gmail dot com"), 0119 QString::fromUtf8("(C) 2019-2022")) 0120 ; 0121 } 0122 0123 void DImgHEIFPlugin::setup(QObject* const /*parent*/) 0124 { 0125 // Nothing to do 0126 } 0127 0128 QMap<QString, QStringList> DImgHEIFPlugin::extraAboutData() const 0129 { 0130 QMap<QString, QStringList> map; 0131 map.insert(QLatin1String("HEIC"), 0132 QStringList() << i18nc("@title", "High efficiency image coding") 0133 << i18nc("@info: can read file format", "yes") 0134 #ifdef HAVE_X265 0135 << i18nc("@info: can write file format", "yes") 0136 #else 0137 << i18nc("@info: cannot write file format", "no") 0138 #endif 0139 ); 0140 0141 map.insert(QLatin1String("HEIF"), 0142 QStringList() << i18nc("@title", "High efficiency image coding") 0143 << i18nc("@info: can read file format", "yes") 0144 #ifdef HAVE_X265 0145 << i18nc("@info: can write file format", "yes") 0146 #else 0147 << i18nc("@info: cannot write file format", "no") 0148 #endif 0149 ); 0150 0151 return map; 0152 } 0153 0154 bool DImgHEIFPlugin::previewSupported() const 0155 { 0156 return true; 0157 } 0158 0159 QString DImgHEIFPlugin::loaderName() const 0160 { 0161 return QLatin1String("HEIF"); 0162 } 0163 0164 QString DImgHEIFPlugin::typeMimes() const 0165 { 0166 return QLatin1String("HEIC HEIF HIF"); 0167 } 0168 0169 int DImgHEIFPlugin::canRead(const QFileInfo& fileInfo, bool magic) const 0170 { 0171 QString filePath = fileInfo.filePath(); 0172 QString format = fileInfo.suffix().toUpper(); 0173 0174 // First simply check file extension 0175 0176 if (!magic) 0177 { 0178 return (!format.isEmpty() && typeMimes().contains(format)) ? 10 : 0; 0179 } 0180 0181 // In second, we trying to parse file header. 0182 0183 QFile file(filePath); 0184 0185 if (!file.open(QIODevice::ReadOnly)) 0186 { 0187 qCDebug(DIGIKAM_DIMG_LOG) << "Failed to open file " << filePath; 0188 0189 return 0; 0190 } 0191 0192 const qint64 headerLen = 12; 0193 0194 QByteArray header(headerLen, '\0'); 0195 0196 if (file.read((char*)header.data(), headerLen) != headerLen) 0197 { 0198 qCDebug(DIGIKAM_DIMG_LOG) << "Failed to read header of file " << filePath; 0199 0200 return 0; 0201 } 0202 0203 if ( 0204 (memcmp(&header.data()[4], "ftypheic", 8) == 0) || 0205 (memcmp(&header.data()[4], "ftypheix", 8) == 0) || 0206 (memcmp(&header.data()[4], "ftypmif1", 8) == 0) 0207 ) 0208 { 0209 return 10; 0210 } 0211 0212 return 0; 0213 } 0214 0215 int DImgHEIFPlugin::canWrite(const QString& format) const 0216 { 0217 0218 #ifdef HAVE_X265 0219 0220 return typeMimes().contains(format.toUpper()) ? 10 : 0; 0221 0222 #else 0223 0224 Q_UNUSED(format); 0225 0226 return 0; 0227 0228 #endif 0229 } 0230 0231 DImgLoader* DImgHEIFPlugin::loader(DImg* const image, const DRawDecoding&) const 0232 { 0233 return (new DImgHEIFLoader(image)); 0234 } 0235 0236 DImgLoaderSettings* DImgHEIFPlugin::exportWidget(const QString& format) const 0237 { 0238 if (canWrite(format)) 0239 { 0240 return (new DImgHEIFExportSettings()); 0241 } 0242 0243 return nullptr; 0244 } 0245 0246 } // namespace DigikamHEIFDImgPlugin 0247 0248 #include "moc_dimgheifplugin.cpp"