/* ============================================================
 *
 * This file is a part of digiKam project
 * https://www.digikam.org
 *
 * Date        : 2019-09-22
 * Description : TIFF DImg plugin.
 *
 * Copyright (C) 2020-2022 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation;
 * either version 2, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * ============================================================ */

#include "dimgtiffplugin.h"

// C++ includes

#include <cstdio>

// Qt includes

#include <QFile>

// KDE includes

#include <klocalizedstring.h>

// Local includes

#include "digikam_debug.h"
#include "digikam_config.h"
#include "digikam_globals.h"
#include "dimgtiffloader.h"

namespace DigikamTIFFDImgPlugin
{

DImgTIFFPlugin::DImgTIFFPlugin(QObject* const parent)
    : DPluginDImg(parent)
{
}

DImgTIFFPlugin::~DImgTIFFPlugin()
{
}

QString DImgTIFFPlugin::name() const
{
    return i18n("TIFF loader");
}

QString DImgTIFFPlugin::iid() const
{
    return QLatin1String(DPLUGIN_IID);
}

QIcon DImgTIFFPlugin::icon() const
{
    return QIcon::fromTheme(QLatin1String("image-tiff"));
}

QString DImgTIFFPlugin::description() const
{
    return i18n("An image loader based on Libtiff codec");
}

QString DImgTIFFPlugin::details() const
{
    return i18n("<p>This plugin allows users to load and save image using Libtiff codec.</p>"
                "<p>Tagged Image File Format, abbreviated TIFF or TIF, is a computer file format "
                "for storing raster graphics images, popular among graphic artists, the publishing "
                "industry, and photographers. TIFF is widely supported by scanning, faxing, "
                "word processing, optical character recognition, image manipulation, "
                "desktop publishing, and page-layout applications.</p>"
                "<p>See <a href='https://en.wikipedia.org/wiki/TIFF'>"
                "Tagged Image File Format documentation</a> for details.</p>"
    );
}

QList<DPluginAuthor> DImgTIFFPlugin::authors() const
{
    return QList<DPluginAuthor>()
            << DPluginAuthor(QString::fromUtf8("Renchi Raju"),
                             QString::fromUtf8("renchi dot raju at gmail dot com"),
                             QString::fromUtf8("(C) 2005"))
            << DPluginAuthor(QString::fromUtf8("Gilles Caulier"),
                             QString::fromUtf8("caulier dot gilles at gmail dot com"),
                             QString::fromUtf8("(C) 2006-2021"))
            ;
}

void DImgTIFFPlugin::setup(QObject* const /*parent*/)
{
    // Nothing to do
}

QString DImgTIFFPlugin::loaderName() const
{
    return QLatin1String("TIFF");
}

QString DImgTIFFPlugin::typeMimes() const
{
    return QLatin1String("TIF TIFF");
}

int DImgTIFFPlugin::canRead(const QFileInfo& fileInfo, bool magic) const
{
    QString filePath = fileInfo.filePath();
    QString format   = fileInfo.suffix().toUpper();

    // First simply check file extension

    if (!magic)
    {
        return typeMimes().contains(format) ? 10 : 0;
    }

    // In second, we trying to parse file header.

#ifdef Q_OS_WIN

    FILE* const f = _wfopen((const wchar_t*)filePath.utf16(), L"rb");

#else

    FILE* const f = fopen(filePath.toUtf8().constData(), "rb");

#endif

    if (!f)
    {
        qCDebug(DIGIKAM_DIMG_LOG) << "Failed to open file " << filePath;
        return 0;
    }

    const int headerLen = 9;

    unsigned char header[headerLen];

    if (fread(&header, headerLen, 1, f) != 1)
    {
        qCDebug(DIGIKAM_DIMG_LOG) << "Failed to read header of file " << filePath;
        fclose(f);
        return 0;
    }

    fclose(f);

    uchar tiffBigID[4] = { 0x4D, 0x4D, 0x00, 0x2A };
    uchar tiffLilID[4] = { 0x49, 0x49, 0x2A, 0x00 };

    if (memcmp(&header, &tiffBigID, 4) == 0 ||
        memcmp(&header, &tiffLilID, 4) == 0)
    {
        return 10;
    }

    return 0;
}

int DImgTIFFPlugin::canWrite(const QString& format) const
{
    return typeMimes().contains(format.toUpper()) ? 10 : 0;
}

DImgLoader* DImgTIFFPlugin::loader(DImg* const image, const DRawDecoding&) const
{
    return new DImgTIFFLoader(image);
}

} // namespace DigikamTIFFDImgPlugin
