Beispiel #1
0
int JpegContent::dotsPerMeter(const QString& keyName) const
{
    Exiv2::ExifKey keyResUnit("Exif.Image.ResolutionUnit");
    Exiv2::ExifData::iterator it = d->mExifData.findKey(keyResUnit);
    if (it == d->mExifData.end()) {
        return 0;
    }
    int res = it->toLong();
    QString keyVal = "Exif.Image." + keyName;
    Exiv2::ExifKey keyResolution(keyVal.toAscii().data());
    it = d->mExifData.findKey(keyResolution);
    if (it == d->mExifData.end()) {
        return 0;
    }
    // The unit for measuring XResolution and YResolution. The same unit is used for both XResolution and YResolution.
    //     If the image resolution in unknown, 2 (inches) is designated.
    //         Default = 2
    //         2 = inches
    //         3 = centimeters
    //         Other = reserved
    const float INCHESPERMETER = (100. / 2.54);
    switch (res) {
    case 3:  // dots per cm
        return int(it->toLong() * 100);
    default:  // dots per inch
        return int(it->toLong() * INCHESPERMETER);
    }

    return 0;
}
Beispiel #2
0
Orientation JpegContent::orientation() const
{
    Exiv2::ExifKey key("Exif.Image.Orientation");
    Exiv2::ExifData::iterator it = d->mExifData.findKey(key);

    // We do the same checks as in libexiv2's src/crwimage.cpp:
    // http://dev.exiv2.org/projects/exiv2/repository/entry/trunk/src/crwimage.cpp?rev=2681#L1336
    if (it == d->mExifData.end() || it->count() == 0 || it->typeId() != Exiv2::unsignedShort) {
        return NOT_AVAILABLE;
    }
    return Orientation(it->toLong());
}
Beispiel #3
0
 bool _getExiv2Value(Exiv2::ExifData& exifData, std::string keyName, long & value)
 {
     Exiv2::ExifData::iterator itr = exifData.findKey(Exiv2::ExifKey(keyName));
     if (itr != exifData.end() && itr->count())
     {
         value = itr->toLong();
         return true;
     }
     else
     {
         return false;
     };
 };
Beispiel #4
0
QSize KExiv2::getImageDimensions() const
{
    try
    {
        long width=-1, height=-1;

        // Try to get Exif.Photo tags

        Exiv2::ExifData exifData(d->exifMetadata());
        Exiv2::ExifKey key("Exif.Photo.PixelXDimension");
        Exiv2::ExifData::iterator it = exifData.findKey(key);
        if (it != exifData.end() && it->count())
            width = it->toLong();

        Exiv2::ExifKey key2("Exif.Photo.PixelYDimension");
        Exiv2::ExifData::iterator it2 = exifData.findKey(key2);
        if (it2 != exifData.end() && it2->count())
            height = it2->toLong();

        if (width != -1 && height != -1)
            return QSize(width, height);

        // Try to get Exif.Image tags

        width  = -1;
        height = -1;

        Exiv2::ExifKey key3("Exif.Image.ImageWidth");
        Exiv2::ExifData::iterator it3 = exifData.findKey(key3);
        if (it3 != exifData.end() && it3->count())
            width = it3->toLong();

        Exiv2::ExifKey key4("Exif.Image.ImageLength");
        Exiv2::ExifData::iterator it4 = exifData.findKey(key4);
        if (it4 != exifData.end() && it4->count())
            height = it4->toLong();

        if (width != -1 && height != -1)
            return QSize(width, height);

#ifdef _XMP_SUPPORT_

        // Try to get Xmp.tiff tags

        width    = -1;
        height   = -1;
        bool wOk = false;
        bool hOk = false;

        QString str = getXmpTagString("Xmp.tiff.ImageWidth");
        if (!str.isEmpty())
            width = str.toInt(&wOk);

        str = getXmpTagString("Xmp.tiff.ImageLength");
        if (!str.isEmpty())
            height = str.toInt(&hOk);

        if (wOk && hOk)
            return QSize(width, height);

        // Try to get Xmp.exif tags

        width  = -1;
        height = -1;
        wOk    = false;
        hOk    = false;

        str = getXmpTagString("Xmp.exif.PixelXDimension");
        if (!str.isEmpty())
            width = str.toInt(&wOk);

        str = getXmpTagString("Xmp.exif.PixelYDimension");
        if (!str.isEmpty())
            height = str.toInt(&hOk);

        if (wOk && hOk)
            return QSize(width, height);

#endif // _XMP_SUPPORT_

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

    return QSize();
}
Beispiel #5
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 #6
0
KExiv2::ImageOrientation KExiv2::getImageOrientation() const
{
    try
    {
        Exiv2::ExifData exifData(d->exifMetadata());
        Exiv2::ExifData::iterator it;
        long orientation;
        ImageOrientation imageOrient = ORIENTATION_NORMAL;

        // -- Standard Xmp tag --------------------------------

#ifdef _XMP_SUPPORT_

        bool ok = false;
        QString str = getXmpTagString("Xmp.tiff.Orientation");
        if (!str.isEmpty())
        {
            orientation = str.toLong(&ok);
            if (ok)
            {
                kDebug() << "Orientation => Xmp.tiff.Orientation => " << (int)orientation;
                return (ImageOrientation)orientation;
            }
        }

#endif // _XMP_SUPPORT_

        // Because some camera set a wrong standard exif orientation tag,
        // We need to check makernote tags in first!

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

        Exiv2::ExifKey minoltaKey1("Exif.MinoltaCs7D.Rotation");
        it = exifData.findKey(minoltaKey1);

        if (it != exifData.end() && it->count())
        {
            orientation = it->toLong();
            kDebug() << "Orientation => Exif.MinoltaCs7D.Rotation => " << (int)orientation;
            switch(orientation)
            {
                case 76:
                    imageOrient = ORIENTATION_ROT_90;
                    break;
                case 82:
                    imageOrient = ORIENTATION_ROT_270;
                    break;
            }
            return imageOrient;
        }

        Exiv2::ExifKey minoltaKey2("Exif.MinoltaCs5D.Rotation");
        it = exifData.findKey(minoltaKey2);

        if (it != exifData.end() && it->count())
        {
            orientation = it->toLong();
            kDebug() << "Orientation => Exif.MinoltaCs5D.Rotation => " << (int)orientation;
            switch(orientation)
            {
                case 76:
                    imageOrient = ORIENTATION_ROT_90;
                    break;
                case 82:
                    imageOrient = ORIENTATION_ROT_270;
                    break;
            }
            return imageOrient;
        }

        // -- Standard Exif tag --------------------------------

        Exiv2::ExifKey keyStd("Exif.Image.Orientation");
        it = exifData.findKey(keyStd);

        if (it != exifData.end() && it->count())
        {
            orientation = it->toLong();
            kDebug() << "Orientation => Exif.Image.Orientation => " << (int)orientation;
            return (ImageOrientation)orientation;
        }

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

    return ORIENTATION_UNSPECIFIED;
}
Beispiel #7
0
long GalleryUtil::GetNaturalRotation(const QString &filePathString)
{
    long rotateAngle = 0;
#ifdef EXIF_SUPPORT
    QByteArray filePathBA = filePathString.toLocal8Bit();
    const char *filePath = filePathBA.constData();

    try
    {
        char *exifvalue = new char[1024];
        ExifData *data = exif_data_new_from_file (filePath);
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                                                        EXIF_TAG_ORIENTATION);
                ExifByteOrder byteorder = exif_data_get_byte_order (data);

                if (entry)
                {
                    ExifShort v_short = exif_get_short (entry->data, byteorder);
                    VERBOSE(VB_GENERAL|VB_EXTRA, QString("Exif entry=%1").arg(v_short));
                    /* See http://sylvana.net/jpegcrop/exif_orientation.html*/
                    if (v_short == 8)
                    {
                        rotateAngle = -90;
                    }
                    else if (v_short == 6)
                    {
                        rotateAngle = 90;
                    }
                    break;
                }
            }
            exif_data_free(data);
        }
        else
        {
            VERBOSE(VB_FILE, LOC_ERR +
                    QString("Could not load exif data from '%1'")
                    .arg(filePath));
        }
        
        delete [] exifvalue;
        
#if 0
        Exiv2::ExifData exifData;
        int rc = exifData.read(filePath);
        if (!rc)
        {
            Exiv2::ExifKey key = Exiv2::ExifKey("Exif.Image.Orientation");
            Exiv2::ExifData::iterator pos = exifData.findKey(key);
            if (pos != exifData.end())
            {
                long orientation = pos->toLong();
                switch (orientation)
                {
                    case 6:
                        rotateAngle = 90;
                        break;
                    case 8:
                        rotateAngle = -90;
                        break;
                    default:
                        rotateAngle = 0;
                        break;
                }
            }
        }
#endif
    }
    catch (...)
    {
        VERBOSE(VB_IMPORTANT, LOC_ERR +
                QString("Failed to extract EXIF headers from '%1'")
                .arg(filePathString));
    }

#else
    // Shut the compiler up about the unused argument
    (void)filePathString;
#endif // EXIF_SUPPORT
    return rotateAngle;
}