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-21
0007  * Description : JPEG 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 "dimgjpegplugin.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 "dimgjpegloader.h"
0031 #include "dimgjpegexportsettings.h"
0032 
0033 namespace DigikamJPEGDImgPlugin
0034 {
0035 
0036 DImgJPEGPlugin::DImgJPEGPlugin(QObject* const parent)
0037     : DPluginDImg(parent)
0038 {
0039 }
0040 
0041 DImgJPEGPlugin::~DImgJPEGPlugin()
0042 {
0043 }
0044 
0045 QString DImgJPEGPlugin::name() const
0046 {
0047     return i18nc("@title", "JPEG loader");
0048 }
0049 
0050 QString DImgJPEGPlugin::iid() const
0051 {
0052     return QLatin1String(DPLUGIN_IID);
0053 }
0054 
0055 QIcon DImgJPEGPlugin::icon() const
0056 {
0057     return QIcon::fromTheme(QLatin1String("image-jpeg"));
0058 }
0059 
0060 QString DImgJPEGPlugin::description() const
0061 {
0062     return i18nc("@info", "An image loader based on Libjpeg codec");
0063 }
0064 
0065 QString DImgJPEGPlugin::details() const
0066 {
0067     return xi18nc("@info", "<para>This plugin allows users to load and save image using Libjpeg codec.</para>"
0068                   "<para>Joint Photographic Experts Group (JPEG) is a commonly used method of lossy "
0069                   "compression for digital images, particularly for those images produced by "
0070                   "digital photography. The degree of compression can be adjusted, allowing "
0071                   "a selectable tradeoff between storage size and image quality.</para>"
0072                   "<para>See <a href='https://en.wikipedia.org/wiki/JPEG'>"
0073                   "Joint Photographic Experts Group documentation</a> for details.</para>"
0074     );
0075 }
0076 
0077 QString DImgJPEGPlugin::handbookSection() const
0078 {
0079     return QLatin1String("supported_materials");
0080 }
0081 
0082 QString DImgJPEGPlugin::handbookChapter() const
0083 {
0084     return QLatin1String("image_formats");
0085 }
0086 
0087 QString DImgJPEGPlugin::handbookReference() const
0088 {
0089     return QLatin1String("image-jpeg");
0090 }
0091 
0092 QList<DPluginAuthor> DImgJPEGPlugin::authors() const
0093 {
0094     return QList<DPluginAuthor>()
0095             << DPluginAuthor(QString::fromUtf8("Renchi Raju"),
0096                              QString::fromUtf8("renchi dot raju at gmail dot com"),
0097                              QString::fromUtf8("(C) 2005"))
0098             << DPluginAuthor(QString::fromUtf8("Gilles Caulier"),
0099                              QString::fromUtf8("caulier dot gilles at gmail dot com"),
0100                              QString::fromUtf8("(C) 2006-2022"))
0101             ;
0102 }
0103 
0104 void DImgJPEGPlugin::setup(QObject* const /*parent*/)
0105 {
0106     // Nothing to do
0107 }
0108 
0109 QString DImgJPEGPlugin::loaderName() const
0110 {
0111     return QLatin1String("JPEG");
0112 }
0113 
0114 QString DImgJPEGPlugin::typeMimes() const
0115 {
0116     return QLatin1String("JPG JPEG JPE");
0117 }
0118 
0119 QMap<QString, QStringList> DImgJPEGPlugin::extraAboutData() const
0120 {
0121     QMap<QString, QStringList> map;
0122     map.insert(QLatin1String("JPG"),  QStringList() << i18nc("@title", "JPEG image")
0123                                                     << i18nc("@info: can read file format",  "yes")
0124                                                     << i18nc("@info: can write file format", "yes")
0125 
0126     );
0127     map.insert(QLatin1String("JPEG"), QStringList() << i18nc("@title", "JPEG image")
0128                                                     << i18nc("@info: can read file format",  "yes")
0129                                                     << i18nc("@info: can write file format", "yes")
0130 
0131     );
0132     map.insert(QLatin1String("JPE"),  QStringList() << i18nc("@title", "JPEG image")
0133                                                     << i18nc("@info: can read file format",  "yes")
0134                                                     << i18nc("@info: can write file format", "yes")
0135 
0136     );
0137 
0138     return map;
0139 }
0140 
0141 int DImgJPEGPlugin::canRead(const QFileInfo& fileInfo, bool magic) const
0142 {
0143     QString filePath = fileInfo.filePath();
0144     QString format   = fileInfo.suffix().toUpper();
0145 
0146     // First simply check file extension
0147 
0148     if (!magic)
0149     {
0150         return (!format.isEmpty() && typeMimes().contains(format)) ? 10 : 0;
0151     }
0152 
0153     // In second, we trying to parse file header.
0154 
0155     QFile file(filePath);
0156 
0157     if (!file.open(QIODevice::ReadOnly))
0158     {
0159         qCDebug(DIGIKAM_DIMG_LOG) << "Failed to open file " << filePath;
0160 
0161         return 0;
0162     }
0163 
0164     const qint64 headerLen = 9;
0165 
0166     QByteArray header(headerLen, '\0');
0167 
0168     if (file.read((char*)header.data(), headerLen) != headerLen)
0169     {
0170         qCDebug(DIGIKAM_DIMG_LOG) << "Failed to read header of file " << filePath;
0171 
0172         return 0;
0173     }
0174 
0175     uchar jpegID[2] = { 0xFF, 0xD8 };
0176 
0177     if (memcmp(header.data(), &jpegID, 2) == 0)
0178     {
0179         return 10;
0180     }
0181 
0182     return 0;
0183 }
0184 
0185 int DImgJPEGPlugin::canWrite(const QString& format) const
0186 {
0187     return typeMimes().contains(format.toUpper()) ? 10 : 0;
0188 }
0189 
0190 DImgLoader* DImgJPEGPlugin::loader(DImg* const image, const DRawDecoding&) const
0191 {
0192     return new DImgJPEGLoader(image);
0193 }
0194 
0195 DImgLoaderSettings* DImgJPEGPlugin::exportWidget(const QString& format) const
0196 {
0197     if (canWrite(format))
0198     {
0199         return (new DImgJPEGExportSettings());
0200     }
0201 
0202     return nullptr;
0203 }
0204 
0205 } // namespace DigikamJPEGDImgPlugin
0206 
0207 #include "moc_dimgjpegplugin.cpp"