示例#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;
}
示例#2
0
    void PgfImage::readMetadata()
    {
#ifdef DEBUG
        std::cerr << "Exiv2::PgfImage::readMetadata: Reading PGF file " << io_->path() << "\n";
#endif
        if (io_->open() != 0)
        {
            throw Error(9, io_->path(), strError());
        }
        IoCloser closer(*io_);
        // Ensure that this is the correct image type
        if (!isPgfType(*io_, true))
        {
            if (io_->error() || io_->eof()) throw Error(14);
            throw Error(3, "PGF");
        }
        clearMetadata();

        readPgfMagicNumber(*io_);

        uint32_t headerSize = readPgfHeaderSize(*io_);

        readPgfHeaderStructure(*io_, &pixelWidth_, &pixelHeight_);

        // And now, the most interresting, the user data byte array where metadata are stored as small image.

        long size = 8 + headerSize - io_->tell();

#ifdef DEBUG
        std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n";
#endif

        if (size < 0) throw Error(20);
        if (size == 0) return;

        DataBuf imgData(size);
        std::memset(imgData.pData_, 0x0, imgData.size_);
        long bufRead = io_->read(imgData.pData_, imgData.size_);
        if (io_->error()) throw Error(14);
        if (bufRead != imgData.size_) throw Error(20);

        Image::AutoPtr image = Exiv2::ImageFactory::open(imgData.pData_, imgData.size_);
        image->readMetadata();
        exifData() = image->exifData();
        iptcData() = image->iptcData();
        xmpData()  = image->xmpData();

    } // PgfImage::readMetadata
示例#3
0
    void Jp2Image::readMetadata()
    {
#ifdef DEBUG
        std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 file " << io_->path() << "\n";
#endif
        if (io_->open() != 0)
        {
            throw Error(9, io_->path(), strError());
        }
        IoCloser closer(*io_);
        // Ensure that this is the correct image type
        if (!isJp2Type(*io_, true))
        {
            if (io_->error() || io_->eof()) throw Error(14);
            throw Error(3, "JPEG-2000");
        }

        long              position  = 0;
        Jp2BoxHeader      box       = {0,0};
        Jp2BoxHeader      subBox    = {0,0};
        Jp2ImageHeaderBox ihdr      = {0,0,0,0,0,0,0,0};
        Jp2UuidBox        uuid      = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

        while (io_->read((byte*)&box, sizeof(box)) == sizeof(box))
        {
            position      = io_->tell();
            box.boxLength = getLong((byte*)&box.boxLength, bigEndian);
#ifdef DEBUG
            std::cout << "Exiv2::Jp2Image::readMetadata: Position: " << position << "\n";
            std::cout << "Exiv2::Jp2Image::readMetadata: Find box type: " << std::string((const char*)&box.boxType)
                      << " lenght: " << box.boxLength << "\n";
#endif
            box.boxType   = getLong((byte*)&box.boxType, bigEndian);

            if (box.boxLength == 0)
            {
#ifdef DEBUG
                std::cout << "Exiv2::Jp2Image::readMetadata: Null Box size has been found. "
                             "This is the last box of file.\n";
#endif
                return;
            }
            if (box.boxLength == 1)
            {
                // FIXME. Special case. the real box size is given in another place.
            }

            switch(box.boxType)
            {
                case kJp2BoxTypeJp2Header:
                {
#ifdef DEBUG
                    std::cout << "Exiv2::Jp2Image::readMetadata: JP2Header box found\n";
#endif

                    if (io_->read((byte*)&subBox, sizeof(subBox)) == sizeof(subBox))
                    {
                        subBox.boxLength = getLong((byte*)&subBox.boxLength, bigEndian);
                        subBox.boxType   = getLong((byte*)&subBox.boxType, bigEndian);

                        if((subBox.boxType == kJp2BoxTypeImageHeader) &&
                           (io_->read((byte*)&ihdr, sizeof(ihdr)) == sizeof(ihdr)))
                        {
#ifdef DEBUG
                           std::cout << "Exiv2::Jp2Image::readMetadata: Ihdr data found\n";
#endif

                            ihdr.imageHeight            = getLong((byte*)&ihdr.imageHeight, bigEndian);
                            ihdr.imageWidth             = getLong((byte*)&ihdr.imageWidth, bigEndian);
                            ihdr.componentCount         = getShort((byte*)&ihdr.componentCount, bigEndian);
                            ihdr.compressionTypeProfile = getShort((byte*)&ihdr.compressionTypeProfile, bigEndian);

                            pixelWidth_  = ihdr.imageWidth;
                            pixelHeight_ = ihdr.imageHeight;
                        }
                    }
                    break;
                }

                case kJp2BoxTypeUuid:
                {
#ifdef DEBUG
                    std::cout << "Exiv2::Jp2Image::readMetadata: UUID box found\n";
#endif

                    if (io_->read((byte*)&uuid, sizeof(uuid)) == sizeof(uuid))
                    {
                        DataBuf rawData;
                        long    bufRead;

                        if(memcmp(uuid.uuid, kJp2UuidExif, sizeof(uuid)) == 0)
                        {
#ifdef DEBUG
                           std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found\n";
#endif

                            // we've hit an embedded Exif block
                            rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid)));
                            bufRead = io_->read(rawData.pData_, rawData.size_);
                            if (io_->error()) throw Error(14);
                            if (bufRead != rawData.size_) throw Error(20);

                            if (rawData.size_ > 0)
                            {
                                // Find the position of Exif header in bytes array.

                                const byte exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
                                long pos = -1;

                                for (long i=0 ; i < rawData.size_-(long)sizeof(exifHeader) ; i++)
                                {
                                    if (memcmp(exifHeader, &rawData.pData_[i], sizeof(exifHeader)) == 0)
                                    {
                                        pos = i;
                                        break;
                                    }
                                }

                                // If found it, store only these data at from this place.

                                if (pos !=-1)
                                {
#ifdef DEBUG
                                    std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos << "\n";
#endif
                                    pos = pos + sizeof(exifHeader);
                                    ByteOrder bo = TiffParser::decode(exifData(),
                                                                      iptcData(),
                                                                      xmpData(),
                                                                      rawData.pData_ + pos,
                                                                      rawData.size_ - pos);
                                    setByteOrder(bo);
                                }
                            }
                            else
                            {
#ifndef SUPPRESS_WARNINGS
                                EXV_WARNING << "Failed to decode Exif metadata.\n";
#endif
                                exifData_.clear();
                            }
                        }
                        else if(memcmp(uuid.uuid, kJp2UuidIptc, sizeof(uuid)) == 0)
                        {
                            // we've hit an embedded IPTC block
#ifdef DEBUG
                           std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found\n";
#endif
                            rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid)));
                            bufRead = io_->read(rawData.pData_, rawData.size_);
                            if (io_->error()) throw Error(14);
                            if (bufRead != rawData.size_) throw Error(20);

                            if (IptcParser::decode(iptcData_, rawData.pData_, rawData.size_))
                            {
#ifndef SUPPRESS_WARNINGS
                                EXV_WARNING << "Failed to decode IPTC metadata.\n";
#endif
                                iptcData_.clear();
                            }
                        }
                        else if(memcmp(uuid.uuid, kJp2UuidXmp, sizeof(uuid)) == 0)
                        {
                            // we've hit an embedded XMP block
#ifdef DEBUG
                           std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found\n";
#endif

                            rawData.alloc(box.boxLength - (sizeof(box) + sizeof(uuid)));
                            bufRead = io_->read(rawData.pData_, rawData.size_);
                            if (io_->error()) throw Error(14);
                            if (bufRead != rawData.size_) throw Error(20);
                            xmpPacket_.assign(reinterpret_cast<char *>(rawData.pData_), rawData.size_);

                            std::string::size_type idx = xmpPacket_.find_first_of('<');
                            if (idx != std::string::npos && idx > 0)
                            {
#ifndef SUPPRESS_WARNINGS
                                EXV_WARNING << "Removing " << static_cast<uint32_t>(idx)
                                            << " characters from the beginning of the XMP packet\n";
#endif
                                xmpPacket_ = xmpPacket_.substr(idx);
                            }

                            if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_))
                            {
#ifndef SUPPRESS_WARNINGS
                                EXV_WARNING << "Failed to decode XMP metadata.\n";
#endif
                            }
                        }
                    }
                    break;
                }

                default:
                {
                    break;
                }
            }

            // Move to the next box.

            io_->seek(static_cast<long>(position - sizeof(box) + box.boxLength), BasicIo::beg);
            if (io_->error() || io_->eof()) throw Error(14);
        }

    } // Jp2Image::readMetadata
示例#4
0
QDateTime KExiv2::getImageDateTime() const
{
    try
    {
        // In first, trying to get Date & time from Exif tags.

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

                if (it != exifData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Exif.Photo.DateTimeOriginal => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::ExifKey key("Exif.Photo.DateTimeDigitized");
                Exiv2::ExifData::iterator it = exifData.findKey(key);

                if (it != exifData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Exif.Photo.DateTimeDigitized => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::ExifKey key("Exif.Image.DateTime");
                Exiv2::ExifData::iterator it = exifData.findKey(key);

                if (it != exifData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Exif.Image.DateTime => " << dateTime;
                        return dateTime;
                    }
                }
            }
        }

        // In second, trying to get Date & time from Xmp tags.

#ifdef _XMP_SUPPORT_

        if (!d->xmpMetadata().empty())
        {
            Exiv2::XmpData xmpData(d->xmpMetadata());
            {
                Exiv2::XmpKey key("Xmp.exif.DateTimeOriginal");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.exif.DateTimeOriginal => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.exif.DateTimeDigitized");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.exif.DateTimeDigitized => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.photoshop.DateCreated");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.photoshop.DateCreated => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.xmp.CreateDate");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.xmp.CreateDate => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.tiff.DateTime");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.tiff.DateTime => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.xmp.ModifyDate");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.xmp.ModifyDate => " << dateTime;
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.xmp.MetadataDate");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(it->toString().c_str(), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Xmp.xmp.MetadataDate => " << dateTime;
                        return dateTime;
                    }
                }
            }
        }

#endif // _XMP_SUPPORT_

        // In third, trying to get Date & time from Iptc tags.

        if (!d->iptcMetadata().empty())
        {
            Exiv2::IptcData iptcData(d->iptcMetadata());

            // Try creation Iptc date & time entries.

            Exiv2::IptcKey keyDateCreated("Iptc.Application2.DateCreated");
            Exiv2::IptcData::iterator it = iptcData.findKey(keyDateCreated);

            if (it != iptcData.end())
            {
                QString IptcDateCreated(it->toString().c_str());
                Exiv2::IptcKey keyTimeCreated("Iptc.Application2.TimeCreated");
                Exiv2::IptcData::iterator it2 = iptcData.findKey(keyTimeCreated);

                if (it2 != iptcData.end())
                {
                    QString IptcTimeCreated(it2->toString().c_str());
                    QDate date = QDate::fromString(IptcDateCreated, Qt::ISODate);
                    QTime time = QTime::fromString(IptcTimeCreated, Qt::ISODate);
                    QDateTime dateTime = QDateTime(date, time);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Iptc.Application2.DateCreated => " << dateTime;
                        return dateTime;
                    }
                }
            }

            // Try digitization Iptc date & time entries.

            Exiv2::IptcKey keyDigitizationDate("Iptc.Application2.DigitizationDate");
            Exiv2::IptcData::iterator it3 = iptcData.findKey(keyDigitizationDate);

            if (it3 != iptcData.end())
            {
                QString IptcDateDigitization(it3->toString().c_str());
                Exiv2::IptcKey keyDigitizationTime("Iptc.Application2.DigitizationTime");
                Exiv2::IptcData::iterator it4 = iptcData.findKey(keyDigitizationTime);

                if (it4 != iptcData.end())
                {
                    QString IptcTimeDigitization(it4->toString().c_str());
                    QDate date = QDate::fromString(IptcDateDigitization, Qt::ISODate);
                    QTime time = QTime::fromString(IptcTimeDigitization, Qt::ISODate);
                    QDateTime dateTime = QDateTime(date, time);

                    if (dateTime.isValid())
                    {
                        kDebug() << "DateTime => Iptc.Application2.DigitizationDate => " << dateTime;
                        return dateTime;
                    }
                }
            }
        }
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError("Cannot parse Exif date & time tag using Exiv2 ", e);
    }
    catch(...)
    {
        kError() << "Default exception from Exiv2";
    }

    return QDateTime();
}
示例#5
0
QDateTime MetaEngine::getDigitizationDateTime(bool fallbackToCreationTime) const
{
    try
    {
        // In first, trying to get Date & time from Exif tags.

        if (!d->exifMetadata().empty())
        {
            // Try Exif date time digitized.

            Exiv2::ExifData exifData(d->exifMetadata());
            Exiv2::ExifKey key("Exif.Photo.DateTimeDigitized");
            Exiv2::ExifData::iterator it = exifData.findKey(key);

            if (it != exifData.end())
            {
                QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate);

                if (dateTime.isValid())
                {
                    qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (Exif digitalized): " << dateTime.toString().toLatin1().constData();
                    return dateTime;
                }
            }
        }

        // In second, we trying XMP

#ifdef _XMP_SUPPORT_

        if (!d->xmpMetadata().empty())
        {
            Exiv2::XmpData xmpData(d->xmpMetadata());
            {
                Exiv2::XmpKey key("Xmp.exif.DateTimeDigitized");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (XMP-Exif digitalized): " << dateTime.toString().toLatin1().constData();
                        return dateTime;
                    }
                }
            }
            {
                Exiv2::XmpKey key("Xmp.video.DateTimeDigitized");
                Exiv2::XmpData::iterator it = xmpData.findKey(key);

                if (it != xmpData.end())
                {
                    QDateTime dateTime = QDateTime::fromString(QString::fromLatin1(it->toString().c_str()), Qt::ISODate);

                    if (dateTime.isValid())
                    {
                        qCDebug(DIGIKAM_METAENGINE_LOG) << "DateTime (XMP-Video digitalized): " << dateTime.toString().toLatin1().constData();
                        return dateTime;
                    }
                }
            }
        }

#endif // _XMP_SUPPORT_

        // In third, trying to get Date & time from Iptc tags.

        if (!d->iptcMetadata().empty())
        {
            // Try digitization Iptc date time entries.

            Exiv2::IptcData iptcData(d->iptcMetadata());
            Exiv2::IptcKey keyDigitizationDate("Iptc.Application2.DigitizationDate");
            Exiv2::IptcData::iterator it = iptcData.findKey(keyDigitizationDate);

            if (it != iptcData.end())
            {
                QString IptcDateDigitization(QString::fromLatin1(it->toString().c_str()));

                Exiv2::IptcKey keyDigitizationTime("Iptc.Application2.DigitizationTime");
                Exiv2::IptcData::iterator it2 = iptcData.findKey(keyDigitizationTime);

                if (it2 != iptcData.end())
                {
                    QString IptcTimeDigitization(QString::fromLatin1(it2->toString().c_str()));

                    QDate date = QDate::fromString(IptcDateDigitization, Qt::ISODate);
                    QTime time = QTime::fromString(IptcTimeDigitization, Qt::ISODate);
                    QDateTime dateTime = QDateTime(date, time);

                    if (dateTime.isValid())
                    {
                        qCDebug(DIGIKAM_METAENGINE_LOG) << "Date (IPTC digitalized): " << dateTime.toString().toLatin1().constData();
                        return dateTime;
                    }
                }
            }
        }
    }
    catch( Exiv2::Error& e )
    {
        d->printExiv2ExceptionError(QString::fromLatin1("Cannot parse Exif digitization date & time tag using Exiv2 "), e);
    }
    catch(...)
    {
        qCCritical(DIGIKAM_METAENGINE_LOG) << "Default exception from Exiv2";
    }

    if (fallbackToCreationTime)
        return getImageDateTime();
    else
        return QDateTime();
}