File indexing completed on 2025-04-27 03:58:09

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-07-20
0007  * Description : Loader for thumbnails - Freedesktop.org standard implementation
0008  *
0009  * SPDX-FileCopyrightText: 2003-2005 by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2003-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0011  * SPDX-FileCopyrightText: 2006-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "thumbnailcreator_p.h"
0018 
0019 namespace Digikam
0020 {
0021 
0022 ThumbnailInfo ThumbnailCreator::fileThumbnailInfo(const QString& path)
0023 {
0024     ThumbnailInfo info;
0025 
0026     if (path.isEmpty())
0027     {
0028         return info;
0029     }
0030 
0031     info.filePath     = path;
0032     QFileInfo fileInfo(path);
0033     info.isAccessible = fileInfo.exists();
0034     info.fileName     = fileInfo.fileName();
0035     QString suffix    = fileInfo.suffix().toUpper();
0036 
0037     QMimeDatabase mimeDB;
0038     QString mimeType(mimeDB.mimeTypeForFile(path).name());
0039 
0040     if      (mimeType.startsWith(QLatin1String("image/")) ||
0041              (suffix == QLatin1String("PGF"))             ||
0042              (suffix == QLatin1String("JXL"))             ||
0043              (suffix == QLatin1String("AVIF"))            ||
0044              (suffix == QLatin1String("KRA"))             ||
0045              (suffix == QLatin1String("CR3"))             ||
0046              (suffix == QLatin1String("HIF"))             ||
0047              (suffix == QLatin1String("HEIC"))            ||
0048              (suffix == QLatin1String("HEIF")))
0049     {
0050         info.mimeType = QLatin1String("image");
0051     }
0052     else if (mimeType.startsWith(QLatin1String("video/")))
0053     {
0054         info.mimeType = QLatin1String("video");
0055     }
0056 
0057     if (!info.isAccessible)
0058     {
0059         return info;
0060     }
0061 
0062     info.modificationDate = fileInfo.lastModified();
0063 
0064     return info;
0065 }
0066 
0067 ThumbnailImage ThumbnailCreator::loadFreedesktop(const ThumbnailInfo& info) const
0068 {
0069     QString path;
0070 
0071     if (!info.customIdentifier.isNull())
0072     {
0073         path = info.customIdentifier;
0074     }
0075     else
0076     {
0077         path = info.filePath;
0078     }
0079 
0080     QString uri       = thumbnailUri(path);
0081     QString thumbPath = thumbnailPath(path);
0082     QImage qimage     = loadPNG(thumbPath);
0083 
0084     // NOTE: if thumbnail have not been generated by digiKam (konqueror for example),
0085     // force to recompute it, else we use it.
0086 
0087     if (!qimage.isNull())
0088     {
0089         if ((qimage.text(QLatin1String("Thumb::MTime")) == QString::number(info.modificationDate.toSecsSinceEpoch())) &&
0090             (qimage.text(QLatin1String("Software"))     == d->digiKamFingerPrint))
0091         {
0092             ThumbnailImage imgInfo;
0093             imgInfo.qimage = qimage;
0094 
0095             // is stored rotated. Not needed to rotate.
0096 
0097             imgInfo.exifOrientation = DMetadata::ORIENTATION_NORMAL;
0098 
0099             return imgInfo;
0100         }
0101     }
0102 
0103     return ThumbnailImage();
0104 }
0105 
0106 void ThumbnailCreator::storeFreedesktop(const ThumbnailInfo& info, const ThumbnailImage& image) const
0107 {
0108     QImage qimage = image.qimage;
0109 
0110     QString path;
0111 
0112     if (!info.customIdentifier.isNull())
0113     {
0114         path = info.customIdentifier;
0115     }
0116     else
0117     {
0118         path = info.filePath;
0119     }
0120 
0121     QString uri       = thumbnailUri(path);
0122     QString thumbPath = thumbnailPath(path);
0123 
0124     // required by spec
0125 
0126     if (qimage.format() != QImage::Format_ARGB32)
0127     {
0128         qimage = qimage.convertToFormat(QImage::Format_ARGB32);
0129     }
0130 
0131     qimage.setText(QLatin1String("Thumb::URI"),   uri);
0132     qimage.setText(QLatin1String("Thumb::MTime"), QString::number(info.modificationDate.toSecsSinceEpoch()));
0133     qimage.setText(QLatin1String("Software"),     d->digiKamFingerPrint);
0134 
0135     QTemporaryFile temp;
0136     temp.setFileTemplate(thumbPath + QLatin1String("-digikam-") + QLatin1String("XXXXXX") + QLatin1String(".png"));
0137     temp.setAutoRemove(false);
0138 
0139     if (temp.open())
0140     {
0141         QString tempFileName = temp.fileName();
0142 
0143         if (qimage.save(tempFileName, "PNG", 0))
0144         {
0145             Q_ASSERT(!tempFileName.isEmpty());
0146 
0147             temp.close();
0148 
0149             // remove thumbPath file if it exist
0150 
0151             if ((tempFileName != thumbPath) && QFile::exists(tempFileName) && QFile::exists(thumbPath))
0152             {
0153                 QFile::remove(thumbPath);
0154             }
0155 
0156             if (!QFile::rename(tempFileName, thumbPath))
0157             {
0158                 qCDebug(DIGIKAM_GENERAL_LOG) << "Cannot rename thumb file (" << tempFileName << ")";
0159                 qCDebug(DIGIKAM_GENERAL_LOG) << "to (" << thumbPath << ")...";
0160             }
0161         }
0162     }
0163 }
0164 
0165 void ThumbnailCreator::deleteFromDiskFreedesktop(const QString& filePath) const
0166 {
0167     QFile smallThumb(thumbnailPath(filePath, normalThumbnailDir()));
0168     QFile largeThumb(thumbnailPath(filePath, largeThumbnailDir()));
0169 
0170     smallThumb.remove();
0171     largeThumb.remove();
0172 }
0173 
0174 } // namespace Digikam