Beispiel #1
0
bool MetaEngine::setImageProgramId(const QString& program, const QString& version) const
{
    try
    {
        QString software(program);
        software.append(QString::fromLatin1("-"));
        software.append(version);

        // Set program info into Exif.Image.ProcessingSoftware tag (only available with Exiv2 >= 0.14.0).

        d->exifMetadata()["Exif.Image.ProcessingSoftware"] = std::string(software.toLatin1().constData());

        // See B.K.O #142564: Check if Exif.Image.Software already exist. If yes, do not touch this tag.

        if (!d->exifMetadata().empty())
        {
            Exiv2::ExifData exifData(d->exifMetadata());
            Exiv2::ExifKey key("Exif.Image.Software");
            Exiv2::ExifData::iterator it = exifData.findKey(key);

            if (it == exifData.end())
                d->exifMetadata()["Exif.Image.Software"] = std::string(software.toLatin1().constData());
        }

        // set program info into XMP tags.

#ifdef _XMP_SUPPORT_

        if (!d->xmpMetadata().empty())
        {
            // Only create Xmp.xmp.CreatorTool if it do not exist.
            Exiv2::XmpData xmpData(d->xmpMetadata());
            Exiv2::XmpKey key("Xmp.xmp.CreatorTool");
            Exiv2::XmpData::iterator it = xmpData.findKey(key);

            if (it == xmpData.end())
                setXmpTagString("Xmp.xmp.CreatorTool", software, false);
        }

        setXmpTagString("Xmp.tiff.Software", software, false);

#endif // _XMP_SUPPORT_

        // Set program info into IPTC tags.

        d->iptcMetadata()["Iptc.Application2.Program"]        = std::string(program.toLatin1().constData());
        d->iptcMetadata()["Iptc.Application2.ProgramVersion"] = std::string(version.toLatin1().constData());
        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Program identity into image using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
    }

    return false;
}
Beispiel #2
0
bool DMetadata::setItemColorLabel(int colorId) const
{
    if (colorId < NoColorLabel || colorId > WhiteLabel)
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << "Color Label value to write is out of range!";
        return false;
    }

    //qCDebug(DIGIKAM_METAENGINE_LOG) << getFilePath() << " ==> Color Label: " << colorId;

    if (supportXmp())
    {
        if (!setXmpTagString("Xmp.digiKam.ColorLabel", QString::number(colorId)))
        {
            return false;
        }

        // Nikon NX use this XMP tags to store Color Labels
        if (!setXmpTagString("Xmp.photoshop.Urgency", QString::number(colorId)))
        {
            return false;
        }

        // LightRoom use this XMP tags to store Color Labels name
        // Values are limited : see bug #358193.

        QString LRLabel;

        switch(colorId)
        {
            case BlueLabel:
                LRLabel = QLatin1String("Blue");
                break;
            case GreenLabel:
                LRLabel = QLatin1String("Green");
                break;
            case RedLabel:
                LRLabel = QLatin1String("Red");
                break;
            case YellowLabel:
                LRLabel = QLatin1String("Yellow");
                break;
            case MagentaLabel:
                LRLabel = QLatin1String("Purple");
                break;
        }

        if (!LRLabel.isEmpty())
        {
            if (!setXmpTagString("Xmp.xmp.Label", LRLabel))
            {
                return false;
            }
        }
    }

    return true;
}
Beispiel #3
0
bool KExiv2::setImageColorWorkSpace(ImageColorWorkSpace workspace, bool setProgramName) const
{
    if (!setProgramId(setProgramName))
        return false;

    try
    {
        // Set Exif value.

        d->exifMetadata()["Exif.Photo.ColorSpace"] = static_cast<uint16_t>(workspace);

        // Set Xmp value.

#ifdef _XMP_SUPPORT_

        setXmpTagString("Xmp.exif.ColorSpace", QString::number((int)workspace), false);

#endif // _XMP_SUPPORT_

        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError("Cannot set Exif color workspace tag using Exiv2 ", e);
    }
    catch(...)
    {
        kError() << "Default exception from Exiv2";
    }

    return false;
}
Beispiel #4
0
void QExiv2::xmpSetMwgRegionList(const MwgRegionList &regions)
{
	xmpEraseRegions();
	if (regions.isEmpty()) {
		//xmpEraseRegions();
		return;
	}

	// TODO:
    // Check region congruence to image dimensions and the applied dimensions
    setXmpTagString("Xmp.mwg-rs.Regions/mwg-rs:AppliedToDimensions/stDim:w", QString::number(d->image->pixelWidth()));
    setXmpTagString("Xmp.mwg-rs.Regions/mwg-rs:AppliedToDimensions/stDim:h", QString::number(d->image->pixelHeight()));
    setXmpTagString("Xmp.mwg-rs.Regions/mwg-rs:AppliedToDimensions/stDim:unit", QStringLiteral("pixel"));

    setXmpTagBag("Xmp.mwg-rs.Regions/mwg-rs:RegionList");
    for (int i = 0; i < regions.count(); i++) {
		xmpSetMwgRegion(regions.at(i), i + 1);
	}
}
Beispiel #5
0
bool KExiv2::setImageDimensions(const QSize& size, bool setProgramName) const
{
    if (!setProgramId(setProgramName))
        return false;

    try
    {
        // Set Exif values.

        // NOTE: see B.K.O #144604: need to cast to record an unsigned integer value.
        d->exifMetadata()["Exif.Image.ImageWidth"]      = static_cast<uint32_t>(size.width());
        d->exifMetadata()["Exif.Image.ImageLength"]     = static_cast<uint32_t>(size.height());
        d->exifMetadata()["Exif.Photo.PixelXDimension"] = static_cast<uint32_t>(size.width());
        d->exifMetadata()["Exif.Photo.PixelYDimension"] = static_cast<uint32_t>(size.height());

        // Set Xmp values.

#ifdef _XMP_SUPPORT_

        setXmpTagString("Xmp.tiff.ImageWidth",      QString::number(size.width()),  false);
        setXmpTagString("Xmp.tiff.ImageLength",     QString::number(size.height()), false);
        setXmpTagString("Xmp.exif.PixelXDimension", QString::number(size.width()),  false);
        setXmpTagString("Xmp.exif.PixelYDimension", QString::number(size.height()), false);

#endif // _XMP_SUPPORT_

        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError("Cannot set image dimensions using Exiv2 ", e);
    }
    catch(...)
    {
        kError() << "Default exception from Exiv2";
    }

    return false;
}
Beispiel #6
0
bool DMetadata::setItemPickLabel(int pickId) const
{
    if (pickId < NoPickLabel || pickId > AcceptedLabel)
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << "Pick Label value to write is out of range!";
        return false;
    }

    //qCDebug(DIGIKAM_METAENGINE_LOG) << getFilePath() << " ==> Pick Label: " << pickId;

    if (supportXmp())
    {
        if (!setXmpTagString("Xmp.digiKam.PickLabel", QString::number(pickId)))
        {
            return false;
        }
    }

    return true;
}
Beispiel #7
0
// Set metadata mwg-rs regions
// Use write to save changes.
void QExiv2::xmpSetMwgRegion(const MwgRegion &region, int n)
{
	if (n <= 0) {
        qDebug() << Q_FUNC_INFO << "Cannot set index <= 0";
		return;
	}

	QRectF stArea = region.stArea();

	setXmpTagString(MwgRs::regionListTag("Area/stArea:x", n), QString::number(stArea.x()));
	setXmpTagString(MwgRs::regionListTag("Area/stArea:y", n), QString::number(stArea.y()));

	switch (region.shape()) {
	case MwgRs::Point:
		break;
	case MwgRs::Circle:
		setXmpTagString(MwgRs::regionListTag("Area/stArea:d", n), QString::number(stArea.width()));
		break;
	case MwgRs::Rectangle:
	default:
		setXmpTagString(MwgRs::regionListTag("Area/stArea:w", n), QString::number(stArea.width()));
		setXmpTagString(MwgRs::regionListTag("Area/stArea:h", n), QString::number(stArea.height()));
		break;
	}

	setXmpTagString(MwgRs::regionListTag("Area/stArea:unit", n), "normalized");
	setXmpTagString(MwgRs::regionListTag("Name", n), region.name());
	setXmpTagString(MwgRs::regionListTag("Description", n), region.description());

	switch (region.type()) {
	case MwgRs::Pet:
		setXmpTagString(MwgRs::regionListTag("Type", n), "Pet");
		break;
	case MwgRs::Barcode:
		setXmpTagString(MwgRs::regionListTag("Type", n), "Barcode");
		break;
	case MwgRs::Focus:
		setXmpTagString(MwgRs::regionListTag("Type", n), "Focus");
		// XXX: todo set focus usage
		//setXmpTagString(MwgRs::regionListTag("FocusUsage", n), "Focus");
		break;
	case MwgRs::Face:
	default:
		setXmpTagString(MwgRs::regionListTag("Type", n), "Face");
		break;
	}
}
Beispiel #8
0
bool KExiv2::setImageOrientation(ImageOrientation orientation, bool setProgramName) const
{
    if (!setProgramId(setProgramName))
        return false;

    try
    {
        if (orientation < ORIENTATION_UNSPECIFIED || orientation > ORIENTATION_ROT_270)
        {
            kDebug() << "Image orientation value is not correct!";
            return false;
        }

        // Set Exif values.

        d->exifMetadata()["Exif.Image.Orientation"] = static_cast<uint16_t>(orientation);
        kDebug() << "Exif.Image.Orientation tag set to: " << (int)orientation;

        // Set Xmp values.

#ifdef _XMP_SUPPORT_

        setXmpTagString("Xmp.tiff.Orientation", QString::number((int)orientation), false);

#endif // _XMP_SUPPORT_

        // -- Minolta/Sony Cameras ----------------------------------

        // Minolta and Sony camera store image rotation in Makernote.
        // We remove these information to prevent duplicate values.

        Exiv2::ExifData::iterator it;

        Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
        it = d->exifMetadata().findKey(minoltaKey1);
        if (it != d->exifMetadata().end())
        {
            d->exifMetadata().erase(it);
            kDebug() << "Removing Exif.MinoltaCs7D.Rotation tag";
        }

        Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
        it = d->exifMetadata().findKey(minoltaKey2);
        if (it != d->exifMetadata().end())
        {
            d->exifMetadata().erase(it);
            kDebug() << "Removing Exif.MinoltaCs5D.Rotation tag";
        }

        // -- Exif embedded thumbnail ----------------------------------

        Exiv2::ExifKey thumbKey("Exif.Thumbnail.Orientation");
        it = d->exifMetadata().findKey(thumbKey);
        if (it != d->exifMetadata().end() && it->count())
        {
            RotationMatrix operation((KExiv2Iface::KExiv2::ImageOrientation)it->toLong());
            operation *= orientation;
            (*it) = static_cast<uint16_t>(operation.exifOrientation());
        }

        return true;
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError("Cannot set Exif Orientation tag using Exiv2 ", e);
    }
    catch(...)
    {
        kError() << "Default exception from Exiv2";
    }

    return false;
}
Beispiel #9
0
bool DMetadata::setItemRating(int rating, const DMetadataSettingsContainer& settings) const
{
    // NOTE : with digiKam 0.9.x, we have used IPTC Urgency to store Rating.
    // Now this way is obsolete, and we use standard XMP rating tag instead.

    if (rating < RatingMin || rating > RatingMax)
    {
        qCDebug(DIGIKAM_METAENGINE_LOG) << "Rating value to write is out of range!";
        return false;
    }

    //qCDebug(DIGIKAM_METAENGINE_LOG) << getFilePath() << " ==> Rating:" << rating;

    QList<NamespaceEntry> toWrite = settings.getReadMapping(QString::fromUtf8(DM_RATING_CONTAINER));

    if (!settings.unifyReadWrite())
        toWrite = settings.getWriteMapping(QString::fromUtf8(DM_RATING_CONTAINER));

    for (NamespaceEntry entry : toWrite)
    {
        if (entry.isDisabled)
            continue;

        const std::string myStr = entry.namespaceName.toStdString();
        const char* nameSpace   = myStr.data();

        switch(entry.subspace)
        {
            case NamespaceEntry::XMP:
                if (!setXmpTagString(nameSpace, QString::number(entry.convertRatio.at(rating))))
                {
                    qCDebug(DIGIKAM_METAENGINE_LOG) << "Setting rating failed" << nameSpace;
                    return false;
                }
                break;
            case NamespaceEntry::EXIF:
                if (QLatin1String(nameSpace) == QLatin1String("Exif.Image.0x4749"))
                {
                    // Wrapper around rating percents managed by Windows Vista.
                    int ratePercents = 0;

                    switch (rating)
                    {
                        case 0:
                            ratePercents = 0;
                            break;
                        case 1:
                            ratePercents = 1;
                            break;
                        case 2:
                            ratePercents = 25;
                            break;
                        case 3:
                            ratePercents = 50;
                            break;
                        case 4:
                            ratePercents = 75;
                            break;
                        case 5:
                            ratePercents = 99;
                            break;
                    }

                    if (!setExifTagLong(nameSpace, ratePercents))
                    {
                        qCDebug(DIGIKAM_METAENGINE_LOG) << "Setting rating failed" << nameSpace;
                        return false;
                    }
                }
                else
                {
                    if (!setExifTagLong(nameSpace, rating))
                    {
                        qCDebug(DIGIKAM_METAENGINE_LOG) << "Setting rating failed" << nameSpace;
                        return false;
                    }
                }
                break;
            case NamespaceEntry::IPTC: // IPTC rating deprecated
            default:
                break;
        }
    }

    return true;
}