File indexing completed on 2025-01-19 03:51:02

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2019-09-22
0007  * Description : PNG DImg plugin.
0008  *
0009  * SPDX-FileCopyrightText: 2020-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 "dimgpngplugin.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 "dimgpngloader.h"
0031 #include "dimgpngexportsettings.h"
0032 
0033 namespace DigikamPNGDImgPlugin
0034 {
0035 
0036 DImgPNGPlugin::DImgPNGPlugin(QObject* const parent)
0037     : DPluginDImg(parent)
0038 {
0039 }
0040 
0041 DImgPNGPlugin::~DImgPNGPlugin()
0042 {
0043 }
0044 
0045 QString DImgPNGPlugin::name() const
0046 {
0047     return i18nc("@title", "PNG loader");
0048 }
0049 
0050 QString DImgPNGPlugin::iid() const
0051 {
0052     return QLatin1String(DPLUGIN_IID);
0053 }
0054 
0055 QIcon DImgPNGPlugin::icon() const
0056 {
0057     return QIcon::fromTheme(QLatin1String("image-png"));
0058 }
0059 
0060 QString DImgPNGPlugin::description() const
0061 {
0062     return i18nc("@info", "An image loader based on Libpng codec");
0063 }
0064 
0065 QString DImgPNGPlugin::details() const
0066 {
0067     return xi18nc("@info", "<para>This plugin allows users to load and save image using Libpng codec.</para>"
0068                   "<para>Portable Network Graphics (PNG) is a raster-graphics file-format that supports "
0069                   "lossless data compression. PNG was developed as an improved, non-patented replacement "
0070                   "for Graphics Interchange Format.</para>"
0071                   "<para>See <a href='https://en.wikipedia.org/wiki/Portable_Network_Graphics'>"
0072                   "Portable Network Graphics documentation</a> for details.</para>"
0073     );
0074 }
0075 
0076 QString DImgPNGPlugin::handbookSection() const
0077 {
0078     return QLatin1String("supported_materials");
0079 }
0080 
0081 QString DImgPNGPlugin::handbookChapter() const
0082 {
0083     return QLatin1String("image_formats");
0084 }
0085 
0086 QString DImgPNGPlugin::handbookReference() const
0087 {
0088     return QLatin1String("image-png");
0089 }
0090 
0091 QList<DPluginAuthor> DImgPNGPlugin::authors() const
0092 {
0093     return QList<DPluginAuthor>()
0094             << DPluginAuthor(QString::fromUtf8("Gilles Caulier"),
0095                              QString::fromUtf8("caulier dot gilles at gmail dot com"),
0096                              QString::fromUtf8("(C) 2005-2022"))
0097             ;
0098 }
0099 
0100 void DImgPNGPlugin::setup(QObject* const /*parent*/)
0101 {
0102     // Nothing to do
0103 }
0104 
0105 QString DImgPNGPlugin::loaderName() const
0106 {
0107     return QLatin1String("PNG");
0108 }
0109 
0110 QString DImgPNGPlugin::typeMimes() const
0111 {
0112     return QLatin1String("PNG");
0113 }
0114 
0115 QMap<QString, QStringList> DImgPNGPlugin::extraAboutData() const
0116 {
0117     QMap<QString, QStringList> map;
0118     map.insert(QLatin1String("PNG"), QStringList() << i18nc("@title", "Portable Network Graphic")
0119                                                    << i18nc("@info: can read file format",  "yes")
0120                                                    << i18nc("@info: can write file format", "yes")
0121     );
0122 
0123     return map;
0124 }
0125 
0126 int DImgPNGPlugin::canRead(const QFileInfo& fileInfo, bool magic) const
0127 {
0128     QString filePath = fileInfo.filePath();
0129     QString format   = fileInfo.suffix().toUpper();
0130 
0131     // First simply check file extension
0132 
0133     if (!magic)
0134     {
0135         return (!format.isEmpty() && typeMimes().contains(format)) ? 10 : 0;
0136     }
0137 
0138     // In second, we trying to parse file header.
0139 
0140     QFile file(filePath);
0141 
0142     if (!file.open(QIODevice::ReadOnly))
0143     {
0144         qCDebug(DIGIKAM_DIMG_LOG) << "Failed to open file " << filePath;
0145 
0146         return 0;
0147     }
0148 
0149     const qint64 headerLen = 9;
0150 
0151     QByteArray header(headerLen, '\0');
0152 
0153     if (file.read((char*)header.data(), headerLen) != headerLen)
0154     {
0155         qCDebug(DIGIKAM_DIMG_LOG) << "Failed to read header of file " << filePath;
0156 
0157         return 0;
0158     }
0159 
0160     uchar pngID[8] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
0161 
0162     if (memcmp(header.data(), &pngID, 8) == 0)
0163     {
0164         return 10;
0165     }
0166 
0167     return 0;
0168 }
0169 
0170 int DImgPNGPlugin::canWrite(const QString& format) const
0171 {
0172     return typeMimes().contains(format.toUpper()) ? 10 : 0;
0173 }
0174 
0175 DImgLoader* DImgPNGPlugin::loader(DImg* const image, const DRawDecoding&) const
0176 {
0177     return new DImgPNGLoader(image);
0178 }
0179 
0180 DImgLoaderSettings* DImgPNGPlugin::exportWidget(const QString& format) const
0181 {
0182     if (canWrite(format))
0183     {
0184         return (new DImgPNGExportSettings());
0185     }
0186 
0187     return nullptr;
0188 }
0189 
0190 } // namespace DigikamPNGDImgPlugin
0191 
0192 #include "moc_dimgpngplugin.cpp"