Exemple #1
0
bool MetaEngine::Private::saveToXMPSidecar(const QFileInfo& finfo) const
{
    QString filePath = MetaEngine::sidecarFilePathForFile(finfo.filePath());

    if (filePath.isEmpty())
    {
        return false;
    }

    try
    {
        Exiv2::Image::AutoPtr image;
        image = Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, (const char*)(QFile::encodeName(filePath).constData()));
        return saveOperations(finfo, image);
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError(QString::fromLatin1("Cannot save metadata to XMP sidecar using Exiv2 "), e);
        return false;
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
        return false;
    }
}
Exemple #2
0
QString MetaEngine::Private::convertCommentValue(const Exiv2::Exifdatum& exifDatum) const
{
    try
    {
        std::string comment;
        std::string charset;

        comment = exifDatum.toString();

        // libexiv2 will prepend "charset=\"SomeCharset\" " if charset is specified
        // Before conversion to QString, we must know the charset, so we stay with std::string for a while
        if (comment.length() > 8 && comment.substr(0, 8) == "charset=")
        {
            // the prepended charset specification is followed by a blank
            std::string::size_type pos = comment.find_first_of(' ');

            if (pos != std::string::npos)
            {
                // extract string between the = and the blank
                charset = comment.substr(8, pos-8);
                // get the rest of the string after the charset specification
                comment = comment.substr(pos+1);
            }
        }

        if (charset == "\"Unicode\"")
        {
            return QString::fromUtf8(comment.data());
        }
        else if (charset == "\"Jis\"")
        {
            QTextCodec* const codec = QTextCodec::codecForName("JIS7");
            return codec->toUnicode(comment.c_str());
        }
        else if (charset == "\"Ascii\"")
        {
            return QString::fromLatin1(comment.c_str());
        }
        else
        {
            return detectEncodingAndDecode(comment);
        }
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError(QString::fromLatin1("Cannot convert Comment using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
    }

    return QString();
}
Exemple #3
0
int MetaEngine::Private::getXMPTagsListFromPrefix(const QString& pf, MetaEngine::TagsMap& tagsMap) const
{
    int i = 0;

#ifdef _XMP_SUPPORT_

    try
    {
        QList<const Exiv2::XmpPropertyInfo*> tags;
        tags << Exiv2::XmpProperties::propertyList(pf.toLatin1().data());

        for (QList<const Exiv2::XmpPropertyInfo*>::iterator it = tags.begin(); it != tags.end(); ++it)
        {
            while ( (*it) && !QString::fromLatin1((*it)->name_).isNull() )
            {
                QString     key = QLatin1String( Exiv2::XmpKey( pf.toLatin1().data(), (*it)->name_ ).key().c_str() );
                QStringList values;
                values << QString::fromLatin1((*it)->name_)
                       << QString::fromLatin1((*it)->title_)
                       << QString::fromLatin1((*it)->desc_);
                tagsMap.insert(key, values);
                ++(*it);
                i++;
            }
        }
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError(QString::fromLatin1("Cannot get Xmp tags list using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
    }

#else

    Q_UNUSED(pf);
    Q_UNUSED(tagsMap);

#endif // _XMP_SUPPORT_

    return i;
}
Exemple #4
0
bool KExiv2::Private::saveToXMPSidecar(const QFileInfo& finfo) const
{
    QString filePath = KExiv2::sidecarFilePathForFile(finfo.filePath());

    if (filePath.isEmpty())
    {
        return false;
    }

    try
    {
        Exiv2::Image::AutoPtr image;
        image = Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, (const char*)(QFile::encodeName(filePath)));
        return saveOperations(finfo, image);
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError("Cannot save metadata to XMP sidecar using Exiv2 ", e);
        return false;
    }
}
Exemple #5
0
bool KExiv2::Private::saveToFile(const QFileInfo& finfo) const
{
    if (!finfo.isWritable())
    {
        kDebug() << "File '" << finfo.fileName().toAscii().constData() << "' is read only. Metadata not written.";
        return false;
    }

    QStringList rawTiffBasedSupported, rawTiffBasedNotSupported;

    // Raw files supported by Exiv2 0.21
    rawTiffBasedSupported << "dng" << "nef" << "pef" << "orf" << "srw";

    if (Exiv2::testVersion(0,23,0))
    {
        rawTiffBasedSupported << "cr2";
    }

    // Raw files not supported by Exiv2 0.21
    rawTiffBasedNotSupported
        << "3fr" << "arw" << "cr2" << "dcr" << "erf" << "k25"
        << "kdc" << "mos" << "raw" << "sr2" << "srf" << "rw2";

    if (!Exiv2::testVersion(0,23,0))
    {
        rawTiffBasedNotSupported << "cr2";
    }

    QString ext = finfo.suffix().toLower();

    if (!writeRawFiles && (rawTiffBasedSupported.contains(ext) || rawTiffBasedNotSupported.contains(ext)) )
    {
        kDebug() << finfo.fileName()
                 << "is a TIFF based RAW file, writing to such a file is disabled by current settings.";
        return false;
    }

/*
    if (rawTiffBasedNotSupported.contains(ext))
    {
        kDebug() << finfo.fileName()
                 << "is TIFF based RAW file not yet supported. Metadata not saved.";
        return false;
    }

    if (rawTiffBasedSupported.contains(ext) && !writeRawFiles)
    {
        kDebug() << finfo.fileName()
                 << "is TIFF based RAW file supported but writing mode is disabled. "
                 << "Metadata not saved.";
        return false;
    }

    kDebug() << "File Extension: " << ext << " is supported for writing mode";

    bool ret = false;
*/

    try
    {
        Exiv2::Image::AutoPtr image;
        image = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(finfo.filePath())));
        return saveOperations(finfo, image);
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError("Cannot save metadata to image using Exiv2 ", e);
        return false;
    }
}
Exemple #6
0
bool KExiv2::Private::saveOperations(const QFileInfo& finfo, Exiv2::Image::AutoPtr image) const
{
    try
    {
        Exiv2::AccessMode mode;
        bool wroteComment = false, wroteEXIF = false, wroteIPTC = false, wroteXMP = false;

        // We need to load target file metadata to merge with new one. It's mandatory with TIFF format:
        // like all tiff file structure is based on Exif.
        image->readMetadata();

        // Image Comments ---------------------------------

        mode = image->checkMode(Exiv2::mdComment);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setComment(imageComments());
            wroteComment = true;
        }

        // Exif metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdExif);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            if (image->mimeType() == "image/tiff")
            {
                Exiv2::ExifData orgExif = image->exifData();
                Exiv2::ExifData newExif;
                QStringList     untouchedTags;

                // With tiff image we cannot overwrite whole Exif data as well, because
                // image data are stored in Exif container. We need to take a care about
                // to not lost image data.
                untouchedTags << "Exif.Image.ImageWidth";
                untouchedTags << "Exif.Image.ImageLength";
                untouchedTags << "Exif.Image.BitsPerSample";
                untouchedTags << "Exif.Image.Compression";
                untouchedTags << "Exif.Image.PhotometricInterpretation";
                untouchedTags << "Exif.Image.FillOrder";
                untouchedTags << "Exif.Image.SamplesPerPixel";
                untouchedTags << "Exif.Image.StripOffsets";
                untouchedTags << "Exif.Image.RowsPerStrip";
                untouchedTags << "Exif.Image.StripByteCounts";
                untouchedTags << "Exif.Image.XResolution";
                untouchedTags << "Exif.Image.YResolution";
                untouchedTags << "Exif.Image.PlanarConfiguration";
                untouchedTags << "Exif.Image.ResolutionUnit";

                for (Exiv2::ExifData::iterator it = orgExif.begin(); it != orgExif.end(); ++it)
                {
                    if (untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = orgExif[it->key().c_str()];
                    }
                }

                Exiv2::ExifData readedExif = exifMetadata();

                for (Exiv2::ExifData::iterator it = readedExif.begin(); it != readedExif.end(); ++it)
                {
                    if (!untouchedTags.contains(it->key().c_str()))
                    {
                        newExif[it->key().c_str()] = readedExif[it->key().c_str()];
                    }
                }

                image->setExifData(newExif);
            }
            else
            {
                image->setExifData(exifMetadata());
            }

            wroteEXIF = true;
        }

        // Iptc metadata ----------------------------------

        mode = image->checkMode(Exiv2::mdIptc);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
            image->setIptcData(iptcMetadata());
            wroteIPTC = true;
        }

        // Xmp metadata -----------------------------------

        mode = image->checkMode(Exiv2::mdXmp);

        if ((mode == Exiv2::amWrite) || (mode == Exiv2::amReadWrite))
        {
#ifdef _XMP_SUPPORT_
            image->setXmpData(xmpMetadata());
            wroteXMP = true;
#endif
        }

        if (!wroteComment && !wroteEXIF && !wroteIPTC && !wroteXMP)
        {
            kDebug() << "Writing metadata is not supported for file" << finfo.fileName();
            return false;
        }
        else if (!wroteEXIF || !wroteIPTC || !wroteXMP)
        {
            kDebug() << "Support for writing metadata is limited for file" << finfo.fileName()
                     << "EXIF" << wroteEXIF << "IPTC" << wroteIPTC << "XMP" << wroteXMP;
        }

        if (!updateFileTimeStamp)
        {
            // Don't touch access and modification timestamp of file.
            struct stat st;
            ::stat(QFile::encodeName(filePath), &st);

            struct utimbuf ut;
            ut.modtime = st.st_mtime;
            ut.actime  = st.st_atime;

            image->writeMetadata();

            ::utime(QFile::encodeName(filePath), &ut);
        }
        else
        {
            image->writeMetadata();
        }

        return true;
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError("Cannot save metadata using Exiv2 ", e);
    }

    return false;
}
Exemple #7
0
bool MetaEngine::Private::saveToFile(const QFileInfo& finfo) const
{
    if (!finfo.isWritable())
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << "File" << finfo.fileName() << "is read only. Metadata not written.";
        return false;
    }

    QStringList rawTiffBasedSupported, rawTiffBasedNotSupported;

    // Raw files supported by Exiv2 0.21
    rawTiffBasedSupported << QString::fromLatin1("dng")
                          << QString::fromLatin1("nef")
                          << QString::fromLatin1("pef")
                          << QString::fromLatin1("orf")
                          << QString::fromLatin1("srw");

    if (Exiv2::testVersion(0,23,0))
    {
        rawTiffBasedSupported << QString::fromLatin1("cr2");
    }

    // Raw files not supported by Exiv2 0.21
    rawTiffBasedNotSupported << QString::fromLatin1("3fr")
                             << QString::fromLatin1("arw")
                             << QString::fromLatin1("dcr")
                             << QString::fromLatin1("erf")
                             << QString::fromLatin1("k25")
                             << QString::fromLatin1("kdc")
                             << QString::fromLatin1("mos")
                             << QString::fromLatin1("raw")
                             << QString::fromLatin1("sr2")
                             << QString::fromLatin1("srf")
                             << QString::fromLatin1("rw2");

    if (!Exiv2::testVersion(0,23,0))
    {
        rawTiffBasedNotSupported << QString::fromLatin1("cr2");
    }

    QString ext = finfo.suffix().toLower();

    if (!writeRawFiles && (rawTiffBasedSupported.contains(ext) || rawTiffBasedNotSupported.contains(ext)) )
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName()
                               << "is a TIFF based RAW file, writing to such a file is disabled by current settings.";
        return false;
    }

/*
    if (rawTiffBasedNotSupported.contains(ext))
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName()
                               << "is TIFF based RAW file not yet supported. Metadata not saved.";
        return false;
    }

    if (rawTiffBasedSupported.contains(ext) && !writeRawFiles)
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << finfo.fileName()
                               << "is TIFF based RAW file supported but writing mode is disabled. "
                               << "Metadata not saved.";
        return false;
    }

    qCDebug(DIGIKAM_METAENGINE_LOG) << "File Extension: " << ext << " is supported for writing mode";

    bool ret = false;
*/

    try
    {
        Exiv2::Image::AutoPtr image;
        image = Exiv2::ImageFactory::open((const char*)(QFile::encodeName(finfo.filePath()).constData()));
        return saveOperations(finfo, image);
    }
    catch( Exiv2::Error& e )
    {
        printExiv2ExceptionError(QString::fromLatin1("Cannot save metadata to image using Exiv2 "), e);
        return false;
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
        return false;
    }
}