From e249bc3e6952a18a9aaae3b94ebb1a4457103177 Mon Sep 17 00:00:00 2001 From: Wescoeur Date: Sun, 16 Jul 2017 22:29:15 +0200 Subject: [PATCH] fix(QExifImageHeader): use app indentation --- src/utils/QExifImageHeader.cpp | 2225 +++++++++++++++----------------- src/utils/QExifImageHeader.h | 486 ++++--- 2 files changed, 1288 insertions(+), 1423 deletions(-) diff --git a/src/utils/QExifImageHeader.cpp b/src/utils/QExifImageHeader.cpp index f885f5e72..1e7216e7d 100644 --- a/src/utils/QExifImageHeader.cpp +++ b/src/utils/QExifImageHeader.cpp @@ -56,153 +56,136 @@ A synonym for \c QPair representing a signed rational number as stored in EXIF headers. The first integer in the pair is the numerator and the second the denominator. -*/ + */ /*! \typedef QExifURational A synonym for \c QPair representing an unsigned rational number as stored in EXIF headers. The first integer in the pair is the numerator and the second the denominator. -*/ + */ -struct ExifIfdHeader -{ - quint16 tag; - quint16 type; - quint32 count; - union - { - quint32 offset; - quint8 offsetBytes[ 4 ]; - char offsetAscii[ 4 ]; - quint16 offsetShorts[ 2 ]; - }; +struct ExifIfdHeader { + quint16 tag; + quint16 type; + quint32 count; + union { + quint32 offset; + quint8 offsetBytes[4]; + char offsetAscii[4]; + quint16 offsetShorts[2]; + }; }; -QDataStream &operator >>( QDataStream &stream, ExifIfdHeader &header ) -{ - stream >> header.tag; - stream >> header.type; - stream >> header.count; +QDataStream &operator>> (QDataStream &stream, ExifIfdHeader &header) { + stream >> header.tag; + stream >> header.type; + stream >> header.count; - if( header.type == QExifValue::Byte && header.count <= 4 ) - { - stream.readRawData( header.offsetAscii, 4 ); - } - else if( header.type == QExifValue::Ascii && header.count <= 4 ) - { - stream.readRawData( header.offsetAscii, 4 ); - } - else if( header.type == QExifValue::Short && header.count <= 2 ) - { - stream >> header.offsetShorts[ 0 ]; - stream >> header.offsetShorts[ 1 ]; - } - else - { - stream >> header.offset; - } + if (header.type == QExifValue::Byte && header.count <= 4) { + stream.readRawData(header.offsetAscii, 4); + } else if (header.type == QExifValue::Ascii && header.count <= 4) { + stream.readRawData(header.offsetAscii, 4); + } else if (header.type == QExifValue::Short && header.count <= 2) { + stream >> header.offsetShorts[0]; + stream >> header.offsetShorts[1]; + } else { + stream >> header.offset; + } - return stream; + return stream; } - -class QExifValuePrivate : public QSharedData -{ +class QExifValuePrivate : public QSharedData { public: - QExifValuePrivate( quint16 t, int c ) - : type( t ), count( c ) - {} - virtual ~QExifValuePrivate(){} + QExifValuePrivate (quint16 t, int c) + : type(t), count(c) + {} - quint16 type; - int count; + virtual ~QExifValuePrivate () {} + + quint16 type; + int count; }; -class QExifByteValuePrivate : public QExifValuePrivate -{ +class QExifByteValuePrivate : public QExifValuePrivate { public: - QExifByteValuePrivate() - : QExifValuePrivate(QExifValue::Byte, 0) - { ref.ref(); } - QExifByteValuePrivate( const QVector< quint8 > &v ) - : QExifValuePrivate( QExifValue::Byte, v.size() ), value( v ) - {} + QExifByteValuePrivate () + : QExifValuePrivate(QExifValue::Byte, 0) { + ref.ref(); + } - QVector< quint8 > value; + QExifByteValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::Byte, v.size()), value(v) + {} + + QVector value; }; -class QExifUndefinedValuePrivate : public QExifValuePrivate -{ +class QExifUndefinedValuePrivate : public QExifValuePrivate { public: - QExifUndefinedValuePrivate( const QByteArray &v ) - : QExifValuePrivate( QExifValue::Undefined, v.size() ), value( v ) - {} + QExifUndefinedValuePrivate (const QByteArray &v) + : QExifValuePrivate(QExifValue::Undefined, v.size()), value(v) + {} - QByteArray value; + QByteArray value; }; -class QExifAsciiValuePrivate : public QExifValuePrivate -{ +class QExifAsciiValuePrivate : public QExifValuePrivate { public: - QExifAsciiValuePrivate( const QString &v ) - : QExifValuePrivate( QExifValue::Ascii, v.size() + 1 ), value( v ) - {} + QExifAsciiValuePrivate (const QString &v) + : QExifValuePrivate(QExifValue::Ascii, v.size() + 1), value(v) + {} - QString value; + QString value; }; -class QExifShortValuePrivate : public QExifValuePrivate -{ +class QExifShortValuePrivate : public QExifValuePrivate { public: - QExifShortValuePrivate( const QVector< quint16 > &v ) - : QExifValuePrivate( QExifValue::Short, v.size() ), value( v ) - {} + QExifShortValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::Short, v.size()), value(v) + {} - QVector< quint16 > value; + QVector value; }; -class QExifLongValuePrivate : public QExifValuePrivate -{ +class QExifLongValuePrivate : public QExifValuePrivate { public: - QExifLongValuePrivate( const QVector< quint32 > &v ) - : QExifValuePrivate( QExifValue::Long, v.size() ), value( v ) - {} + QExifLongValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::Long, v.size()), value(v) + {} - QVector< quint32 > value; + QVector value; }; -class QExifSignedLongValuePrivate : public QExifValuePrivate -{ +class QExifSignedLongValuePrivate : public QExifValuePrivate { public: - QExifSignedLongValuePrivate( const QVector< qint32 > &v ) - : QExifValuePrivate( QExifValue::SignedLong, v.size() ), value( v ) - {} + QExifSignedLongValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::SignedLong, v.size()), value(v) + {} - QVector< qint32 > value; + QVector value; }; -class QExifRationalValuePrivate : public QExifValuePrivate -{ +class QExifRationalValuePrivate : public QExifValuePrivate { public: - QExifRationalValuePrivate( const QVector< QExifURational > &v ) - : QExifValuePrivate( QExifValue::Rational, v.size() ), value( v ) - {} + QExifRationalValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::Rational, v.size()), value(v) + {} - QVector< QExifURational > value; + QVector value; }; -class QExifSignedRationalValuePrivate : public QExifValuePrivate -{ +class QExifSignedRationalValuePrivate : public QExifValuePrivate { public: - QExifSignedRationalValuePrivate( const QVector< QExifSRational > &v ) - : QExifValuePrivate( QExifValue::SignedRational, v.size() ), value( v ) - {} + QExifSignedRationalValuePrivate (const QVector &v) + : QExifValuePrivate(QExifValue::SignedRational, v.size()), value(v) + {} - QVector< QExifSRational > value; + QVector value; }; -Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) +Q_GLOBAL_STATIC(QExifByteValuePrivate, qExifValuePrivateSharedNull) /*! \class QExifValue @@ -228,7 +211,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) \sa QExifImageHeader \preliminary -*/ + */ /*! \enum QExifValue::Type @@ -243,7 +226,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) \value Undefined An array of 8 bit integers. \value SignedLong A signed 32 bit integer. \value SignedRational Two signed 32 bit integers representing the numerator and denominator of a signed rational number. -*/ + */ /*! \enum QExifValue::TextEncoding @@ -255,481 +238,425 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) \value JisEncoding A JIS X208-1990 string of Undefined type. \value UnicodeEncoding A Unicode string of Undefined type. \value UndefinedEncoding An unspecified string encoding of Undefined type. Assumed to be the local 8-bit encoding. -*/ + */ /*! Constructs a null QExifValue. -*/ -QExifValue::QExifValue() - : d( qExifValuePrivateSharedNull() ) -{ -} + */ +QExifValue::QExifValue () + : d(qExifValuePrivateSharedNull()) +{} /*! Constructs a QExifValue with a \a value of type Byte. -*/ -QExifValue::QExifValue( quint8 value ) - : d( new QExifByteValuePrivate( QVector< quint8 >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (quint8 value) + : d(new QExifByteValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type Byte. -*/ -QExifValue::QExifValue( const QVector< quint8 > &values ) - : d( new QExifByteValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifByteValuePrivate(values)) +{} /*! Constructs a QExifValue with a \a value of type Ascii or Undefined. If the \a encoding is NoEncoding the value will be of type Ascii, otherwise it will be Undefined and the string encoded using the given \a encoding. -*/ -QExifValue::QExifValue( const QString &value, TextEncoding encoding ) - : d( qExifValuePrivateSharedNull() ) -{ - switch( encoding ) - { + */ +QExifValue::QExifValue (const QString &value, TextEncoding encoding) + : d(qExifValuePrivateSharedNull()) { + switch (encoding) { case AsciiEncoding: - d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "ASCII\0\0\0", 8 ) + value.toUtf8() ); - break; - case JisEncoding: - { - QTextCodec *codec = QTextCodec::codecForName( "JIS X 0208" ); - if( codec ) - d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "JIS\0\0\0\0\0", 8 ) + codec->fromUnicode( value ) ); - } - break; - case UnicodeEncoding: - { - QTextCodec *codec = QTextCodec::codecForName( "UTF-16" ); - if( codec ) - d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "UNICODE\0", 8 ) + codec->fromUnicode( value ) ); - } - break; - case UndefinedEncoding: - d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "\0\0\0\0\0\0\0\\0", 8 ) + value.toLocal8Bit() ); - break; - default: - d = new QExifAsciiValuePrivate( value ); + d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("ASCII\0\0\0", 8) + value.toUtf8()); + break; + case JisEncoding: { + QTextCodec *codec = QTextCodec::codecForName("JIS X 0208"); + if (codec) + d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("JIS\0\0\0\0\0", 8) + codec->fromUnicode(value)); } + break; + case UnicodeEncoding: { + QTextCodec *codec = QTextCodec::codecForName("UTF-16"); + if (codec) + d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("UNICODE\0", 8) + codec->fromUnicode(value)); + } + break; + case UndefinedEncoding: + d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("\0\0\0\0\0\0\0\\0", 8) + value.toLocal8Bit()); + break; + default: + d = new QExifAsciiValuePrivate(value); + } } /*! Constructs a QExifValue with a \a value of type Short. -*/ -QExifValue::QExifValue( quint16 value ) - : d( new QExifShortValuePrivate( QVector< quint16 >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (quint16 value) + : d(new QExifShortValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type Short. -*/ -QExifValue::QExifValue( const QVector< quint16 > &values ) - : d( new QExifShortValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifShortValuePrivate(values)) +{} /*! Constructs a QExifValue with a \a value of type Long. -*/ -QExifValue::QExifValue( quint32 value ) - : d( new QExifLongValuePrivate( QVector< quint32 >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (quint32 value) + : d(new QExifLongValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type Long. -*/ -QExifValue::QExifValue( const QVector< quint32 > &values ) - : d( new QExifLongValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifLongValuePrivate(values)) +{} /*! Constructs a QExifValue with a \a value of type Rational. -*/ -QExifValue::QExifValue( const QExifURational &value ) - : d( new QExifRationalValuePrivate( QVector< QExifURational >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (const QExifURational &value) + : d(new QExifRationalValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type Rational. -*/ -QExifValue::QExifValue( const QVector< QExifURational > &values ) - : d( new QExifRationalValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifRationalValuePrivate(values)) +{} /*! Constructs a QExifValue with a \a value of type Undefined. -*/ -QExifValue::QExifValue( const QByteArray &value ) - : d( new QExifUndefinedValuePrivate( value ) ) -{ -} + */ +QExifValue::QExifValue (const QByteArray &value) + : d(new QExifUndefinedValuePrivate(value)) +{} /*! Constructs a QExifValue with a \a value of type SignedLong. -*/ -QExifValue::QExifValue( qint32 value ) - : d( new QExifSignedLongValuePrivate( QVector< qint32 >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (qint32 value) + : d(new QExifSignedLongValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type SignedLong. -*/ -QExifValue::QExifValue( const QVector< qint32 > &values ) - : d( new QExifSignedLongValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifSignedLongValuePrivate(values)) +{} /*! Constructs a QExifValue with a \a value of type SignedRational. -*/ -QExifValue::QExifValue( const QExifSRational &value ) - : d( new QExifSignedRationalValuePrivate( QVector< QExifSRational >( 1, value ) ) ) -{ -} + */ +QExifValue::QExifValue (const QExifSRational &value) + : d(new QExifSignedRationalValuePrivate(QVector(1, value))) +{} /*! Constructs a QExifValue with an array of \a values of type SignedRational. -*/ -QExifValue::QExifValue( const QVector< QExifSRational > &values ) - : d( new QExifSignedRationalValuePrivate( values ) ) -{ -} + */ +QExifValue::QExifValue (const QVector &values) + : d(new QExifSignedRationalValuePrivate(values)) +{} /*! Constructs a QExifValue of type Ascii with an ascii string formatted from a date-time \a value. Date-times are stored as strings in the format \c {yyyy:MM:dd HH:mm:ss}. -*/ -QExifValue::QExifValue( const QDateTime &value ) - : d( new QExifAsciiValuePrivate( value.toString( QLatin1String( "yyyy:MM:dd HH:mm:ss" ) ) ) ) -{ -} + */ +QExifValue::QExifValue (const QDateTime &value) + : d(new QExifAsciiValuePrivate(value.toString(QLatin1String("yyyy:MM:dd HH:mm:ss")))) +{} /*! Constructs a copy of the QExifValue \a other. -*/ -QExifValue::QExifValue( const QExifValue &other ) - : d( other.d ) -{ -} + */ +QExifValue::QExifValue (const QExifValue &other) + : d(other.d) +{} /*! Assigns the value of \a other to a QExifValue. -*/ -QExifValue &QExifValue::operator =( const QExifValue &other ) -{ - d = other.d; + */ +QExifValue &QExifValue::operator= (const QExifValue &other) { + d = other.d; - return *this; + return *this; } /*! Destroys a QExifValue. -*/ -QExifValue::~QExifValue() -{ -} + */ +QExifValue::~QExifValue () +{} /*! Compares a QExifValue to \a other. Returns true if they are the same value and false otherwise. -*/ -bool QExifValue::operator ==( const QExifValue &other ) const -{ - return d == other.d; + */ +bool QExifValue::operator== (const QExifValue &other) const { + return d == other.d; } /*! Returns true if a QExifValue has a null value and false otherwise. -*/ -bool QExifValue::isNull() const -{ - return d == qExifValuePrivateSharedNull(); + */ +bool QExifValue::isNull () const { + return d == qExifValuePrivateSharedNull(); } /*! Returns the type of a QExifValue. -*/ -int QExifValue::type() const -{ - return d->type; + */ +int QExifValue::type () const { + return d->type; } /*! Returns the number of elements in a QExifValue. For ascii strings this is the length of the string including the terminating null. -*/ -int QExifValue::count() const -{ - return d->count; + */ +int QExifValue::count () const { + return d->count; } /*! Returns the encoding of strings stored in Undefined values. -*/ -QExifValue::TextEncoding QExifValue::encoding() const -{ - if( d->type == Undefined && d->count > 8 ) - { - QByteArray value = static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value; + */ +QExifValue::TextEncoding QExifValue::encoding () const { + if (d->type == Undefined && d->count > 8) { + QByteArray value = static_cast(d.constData())->value; - if( value.startsWith( QByteArray::fromRawData( "ASCII\0\0\0", 8 ) ) ) - return AsciiEncoding; - else if( value.startsWith( QByteArray::fromRawData( "JIS\0\0\0\0\0", 8 ) ) ) - return JisEncoding; - else if( value.startsWith( QByteArray::fromRawData( "UNICODE\0", 8 ) ) ) - return UnicodeEncoding; - else if( value.startsWith( QByteArray::fromRawData( "\0\0\0\0\0\0\0\0", 8 ) ) ) - return UndefinedEncoding; - } - return NoEncoding; + if (value.startsWith(QByteArray::fromRawData("ASCII\0\0\0", 8))) + return AsciiEncoding; + else if (value.startsWith(QByteArray::fromRawData("JIS\0\0\0\0\0", 8))) + return JisEncoding; + else if (value.startsWith(QByteArray::fromRawData("UNICODE\0", 8))) + return UnicodeEncoding; + else if (value.startsWith(QByteArray::fromRawData("\0\0\0\0\0\0\0\0", 8))) + return UndefinedEncoding; + } + return NoEncoding; } /*! Returns the value of a single element QExifValue of type Byte. -*/ -quint8 QExifValue::toByte() const -{ - return d->type == Byte && d->count == 1 - ? static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ) - : 0; + */ +quint8 QExifValue::toByte () const { + return d->type == Byte && d->count == 1 + ? static_cast(d.constData())->value.at(0) + : 0; } /*! Returns the value of a multiple element QExifValue of type Byte. -*/ -QVector< quint8 > QExifValue::toByteVector() const -{ - return d->type == Byte - ? static_cast< const QExifByteValuePrivate * >( d.constData() )->value - : QVector< quint8 >(); + */ +QVector QExifValue::toByteVector () const { + return d->type == Byte + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of a QExifValue of type Ascii. -*/ -QString QExifValue::toString() const -{ - switch( d->type ) - { + */ +QString QExifValue::toString () const { + switch (d->type) { case Ascii: - return static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value; - case Undefined: - { - QByteArray string = static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value.mid( 8 ); + return static_cast(d.constData())->value; + case Undefined: { + QByteArray string = static_cast(d.constData())->value.mid(8); - switch( encoding() ) - { - case AsciiEncoding: - return QString::fromUtf8( string.constData(), string.length() ); - case JisEncoding: - { - QTextCodec *codec = QTextCodec::codecForName( "JIS X 0208" ); - if( codec ) - return codec->toUnicode( string ); - } - break; - case UnicodeEncoding: - { - QTextCodec *codec = QTextCodec::codecForName( "UTF-16" ); - if( codec ) - return codec->toUnicode( string ); - } - case UndefinedEncoding: - return QString::fromLocal8Bit( string.constData(), string.length() ); - default: - break; - } + switch (encoding()) { + case AsciiEncoding: + return QString::fromUtf8(string.constData(), string.length()); + case JisEncoding: { + QTextCodec *codec = QTextCodec::codecForName("JIS X 0208"); + if (codec) + return codec->toUnicode(string); } - default: - return QString(); + break; + case UnicodeEncoding: { + QTextCodec *codec = QTextCodec::codecForName("UTF-16"); + if (codec) + return codec->toUnicode(string); + } + case UndefinedEncoding: + return QString::fromLocal8Bit(string.constData(), string.length()); + default: + break; + } } + default: + return QString(); + } } /*! Returns the value of a single element QExifValue of type Byte or Short. -*/ -quint16 QExifValue::toShort() const -{ - if( d->count == 1 ) - { - switch( d->type ) - { - case Byte: - return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); - case Short: - return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); - } + */ +quint16 QExifValue::toShort () const { + if (d->count == 1) { + switch (d->type) { + case Byte: + return static_cast(d.constData())->value.at(0); + case Short: + return static_cast(d.constData())->value.at(0); } - return 0; + } + return 0; } /*! Returns the value of a single element QExifValue of type Short. -*/ -QVector< quint16 > QExifValue::toShortVector() const -{ - return d->type == Short - ? static_cast< const QExifShortValuePrivate * >( d.constData() )->value - : QVector< quint16 >(); + */ +QVector QExifValue::toShortVector () const { + return d->type == Short + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. -*/ -quint32 QExifValue::toLong() const -{ - if( d->count == 1 ) - { - switch( d->type ) - { - case Byte: - return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); - case Short: - return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); - case Long: - return static_cast< const QExifLongValuePrivate * >( d.constData() )->value.at( 0 ); - case SignedLong: - return static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value.at( 0 ); - } + */ +quint32 QExifValue::toLong () const { + if (d->count == 1) { + switch (d->type) { + case Byte: + return static_cast(d.constData())->value.at(0); + case Short: + return static_cast(d.constData())->value.at(0); + case Long: + return static_cast(d.constData())->value.at(0); + case SignedLong: + return static_cast(d.constData())->value.at(0); } - return 0; + } + return 0; } /*! Returns the value of a multiple element QExifValue of type Long. -*/ -QVector< quint32 > QExifValue::toLongVector() const -{ - return d->type == Long - ? static_cast< const QExifLongValuePrivate * >( d.constData() )->value - : QVector< quint32 >(); + */ +QVector QExifValue::toLongVector () const { + return d->type == Long + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of a multiple element QExifValue of type Rational. -*/ -QExifURational QExifValue::toRational() const -{ - return d->type == Rational && d->count == 1 - ? static_cast< const QExifRationalValuePrivate * >( d.constData() )->value.at( 0 ) - : QExifURational(); + */ +QExifURational QExifValue::toRational () const { + return d->type == Rational && d->count == 1 + ? static_cast(d.constData())->value.at(0) + : QExifURational(); } /*! Returns the value of a multiple element QExifValue of type Rational. -*/ -QVector< QExifURational > QExifValue::toRationalVector() const -{ - return d->type == Rational - ? static_cast< const QExifRationalValuePrivate * >( d.constData() )->value - : QVector< QExifURational >(); + */ +QVector QExifValue::toRationalVector () const { + return d->type == Rational + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of a QExifValue of type Undefined. -*/ -QByteArray QExifValue::toByteArray() const -{ - switch( d->type ) - { + */ +QByteArray QExifValue::toByteArray () const { + switch (d->type) { case Ascii: - return static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value.toUtf8(); + return static_cast(d.constData())->value.toUtf8(); case Undefined: - return static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value; + return static_cast(d.constData())->value; default: - return QByteArray(); - } + return QByteArray(); + } } /*! Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. -*/ -qint32 QExifValue::toSignedLong() const -{ - if( d->count == 1 ) - { - switch( d->type ) - { - case Byte: - return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); - case Short: - return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); - case Long: - return static_cast< const QExifLongValuePrivate * >( d.constData() )->value.at( 0 ); - case SignedLong: - return static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value.at( 0 ); - } + */ +qint32 QExifValue::toSignedLong () const { + if (d->count == 1) { + switch (d->type) { + case Byte: + return static_cast(d.constData())->value.at(0); + case Short: + return static_cast(d.constData())->value.at(0); + case Long: + return static_cast(d.constData())->value.at(0); + case SignedLong: + return static_cast(d.constData())->value.at(0); } - return 0; + } + return 0; } /*! Returns the value of a multiple element QExifValue of type SignedLong. -*/ -QVector< qint32 > QExifValue::toSignedLongVector() const -{ - return d->type == SignedLong - ? static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value - : QVector< qint32 >(); + */ +QVector QExifValue::toSignedLongVector () const { + return d->type == SignedLong + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of a single element QExifValue of type SignedRational. -*/ -QExifSRational QExifValue::toSignedRational() const -{ - return d->type == SignedRational && d->count == 1 - ? static_cast< const QExifSignedRationalValuePrivate * >( d.constData() )->value.at( 0 ) - : QExifSRational(); + */ +QExifSRational QExifValue::toSignedRational () const { + return d->type == SignedRational && d->count == 1 + ? static_cast(d.constData())->value.at(0) + : QExifSRational(); } /*! Returns the value of a multiple element QExifValue of type SignedRational. -*/ -QVector< QExifSRational > QExifValue::toSignedRationalVector() const -{ - return d->type == SignedRational - ? static_cast< const QExifSignedRationalValuePrivate * >( d.constData() )->value - : QVector< QExifSRational >(); + */ +QVector QExifValue::toSignedRationalVector () const { + return d->type == SignedRational + ? static_cast(d.constData())->value + : QVector(); } /*! Returns the value of QExifValue storing a date-time. Date-times are stored as ascii strings in the format \c {yyyy:MM:dd HH:mm:ss}. -*/ -QDateTime QExifValue::toDateTime() const -{ - return d->type == Ascii && d->count == 20 - ? QDateTime::fromString( static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value, QLatin1String( "yyyy:MM:dd HH:mm:ss" ) ) - : QDateTime(); + */ +QDateTime QExifValue::toDateTime () const { + return d->type == Ascii && d->count == 20 + ? QDateTime::fromString(static_cast(d.constData())->value, QLatin1String("yyyy:MM:dd HH:mm:ss")) + : QDateTime(); } -class QExifImageHeaderPrivate -{ +class QExifImageHeaderPrivate { public: - QSysInfo::Endian byteOrder; - mutable qint64 size; - QMap imageIfdValues; - QMap exifIfdValues; - QMap gpsIfdValues; + QSysInfo::Endian byteOrder; + mutable qint64 size; + QMap imageIfdValues; + QMap exifIfdValues; + QMap gpsIfdValues; - QSize thumbnailSize; - QByteArray thumbnailData; - QExifValue thumbnailXResolution; - QExifValue thumbnailYResolution; - QExifValue thumbnailResolutionUnit; - QExifValue thumbnailOrientation; + QSize thumbnailSize; + QByteArray thumbnailData; + QExifValue thumbnailXResolution; + QExifValue thumbnailYResolution; + QExifValue thumbnailResolutionUnit; + QExifValue thumbnailOrientation; }; /*! @@ -752,7 +679,7 @@ public: EXIF header data itself. \preliminary -*/ + */ /*! \enum QExifImageHeader::ImageTag @@ -785,7 +712,7 @@ public: \value Software \value Artist \value Copyright -*/ + */ /*! \enum QExifImageHeader::ExifExtendedTag @@ -847,7 +774,7 @@ public: \value Sharpness \value DeviceSettingDescription \value SubjectDistanceRange -*/ + */ /*! \enum QExifImageHeader::GpsTag @@ -884,88 +811,82 @@ public: \value GpsAreaInformation \value GpsDateStamp \value GpsDifferential -*/ + */ /*! Constructs a new EXIF image data editor. -*/ -QExifImageHeader::QExifImageHeader() - : d( new QExifImageHeaderPrivate ) -{ - d->byteOrder = QSysInfo::ByteOrder; - d->size = -1; + */ +QExifImageHeader::QExifImageHeader () + : d(new QExifImageHeaderPrivate) { + d->byteOrder = QSysInfo::ByteOrder; + d->size = -1; } /*! Constructs a new EXIF image data editor and reads the meta-data from a JPEG image with the given \a fileName. -*/ -QExifImageHeader::QExifImageHeader(const QString &fileName) - : d(new QExifImageHeaderPrivate) -{ - d->byteOrder = QSysInfo::ByteOrder; - d->size = -1; + */ +QExifImageHeader::QExifImageHeader (const QString &fileName) + : d(new QExifImageHeaderPrivate) { + d->byteOrder = QSysInfo::ByteOrder; + d->size = -1; - loadFromJpeg(fileName); + loadFromJpeg(fileName); } /*! Destroys an EXIF image data editor. -*/ -QExifImageHeader::~QExifImageHeader() -{ - clear(); + */ +QExifImageHeader::~QExifImageHeader () { + clear(); - delete d; + delete d; } /*! Reads meta-data from a JPEG image with the given \a fileName. Returns true if the data was successfully parsed and false otherwise. -*/ -bool QExifImageHeader::loadFromJpeg(const QString &fileName) -{ - QFile file(fileName); + */ +bool QExifImageHeader::loadFromJpeg (const QString &fileName) { + QFile file(fileName); - if(file.open(QIODevice::ReadOnly)) - return loadFromJpeg(&file); - else - return false; + if (file.open(QIODevice::ReadOnly)) + return loadFromJpeg(&file); + else + return false; } /*! Reads meta-data from an I/O \a device containing a JPEG image. Returns true if the data was successfully parsed and false otherwise. -*/ -bool QExifImageHeader::loadFromJpeg(QIODevice *device) -{ - clear(); + */ +bool QExifImageHeader::loadFromJpeg (QIODevice *device) { + clear(); - QByteArray exifData = extractExif(device); + QByteArray exifData = extractExif(device); - if (!exifData.isEmpty()) { - QBuffer buffer(&exifData); + if (!exifData.isEmpty()) { + QBuffer buffer(&exifData); - return buffer.open(QIODevice::ReadOnly) && read(&buffer); - } + return buffer.open(QIODevice::ReadOnly) && read(&buffer); + } - return false; + return false; } /*! Saves meta-data to a JPEG image with the given \a fileName. Returns true if the data was successfully written. -*/ -bool QExifImageHeader::saveToJpeg(const QString &fileName) const -{ - QFile file(fileName); + */ +bool QExifImageHeader::saveToJpeg (const QString &fileName) const { + QFile file(fileName); - if (file.open(QIODevice::ReadWrite)) - return saveToJpeg(&file); - else - return false; + if (file.open(QIODevice::ReadWrite)) + return saveToJpeg(&file); + else + return false; } /*! @@ -974,997 +895,953 @@ bool QExifImageHeader::saveToJpeg(const QString &fileName) const The device must be non-sequential and already contain a valid JPEG image. Returns true if the data was successfully written. -*/ -bool QExifImageHeader::saveToJpeg(QIODevice *device) const -{ - if( device->isSequential() ) - return false; + */ +bool QExifImageHeader::saveToJpeg (QIODevice *device) const { + if (device->isSequential()) + return false; - QByteArray exif; + QByteArray exif; - { - QBuffer buffer( &exif ); + { + QBuffer buffer(&exif); - if( !buffer.open( QIODevice::WriteOnly ) ) - return false; + if (!buffer.open(QIODevice::WriteOnly)) + return false; - write( &buffer ); + write(&buffer); - buffer.close(); + buffer.close(); - exif = QByteArray::fromRawData( "Exif\0\0", 6 ) + exif; - } + exif = QByteArray::fromRawData("Exif\0\0", 6) + exif; + } - QDataStream stream( device ); + QDataStream stream(device); - stream.setByteOrder( QDataStream::BigEndian ); + stream.setByteOrder(QDataStream::BigEndian); - if( device->read( 2 ) != "\xFF\xD8" ) // Not a valid JPEG image. - return false; + if (device->read(2) != "\xFF\xD8") // Not a valid JPEG image. + return false; - quint16 segmentId; - quint16 segmentLength; + quint16 segmentId; + quint16 segmentLength; + + stream >> segmentId; + stream >> segmentLength; + + if (segmentId == 0xFFE0) { + QByteArray jfif = device->read(segmentLength - 2); + + if (!jfif.startsWith("JFIF")) + return false; stream >> segmentId; stream >> segmentLength; - if( segmentId == 0xFFE0 ) - { - QByteArray jfif = device->read( segmentLength - 2 ); + if (segmentId == 0xFFE1) { + QByteArray oldExif = device->read(segmentLength - 2); - if( !jfif.startsWith( "JFIF" ) ) - return false; + if (!oldExif.startsWith("Exif")) + return false; - stream >> segmentId; - stream >> segmentLength; + int dSize = oldExif.size() - exif.size(); - if( segmentId == 0xFFE1 ) - { - QByteArray oldExif = device->read( segmentLength - 2 ); + if (dSize > 0) + exif += QByteArray(dSize, '\0'); - if( !oldExif.startsWith( "Exif" ) ) - return false; + QByteArray remainder = device->readAll(); - int dSize = oldExif.size() - exif.size(); + device->seek(0); - if( dSize > 0 ) - exif += QByteArray( dSize, '\0' ); + stream << quint16(0xFFD8); // SOI + stream << quint16(0xFFE0); // APP0 + stream << quint16(jfif.size() + 2); + device->write(jfif); + stream << quint16(0xFFE1); // APP1 + stream << quint16(exif.size() + 2); + device->write(exif); + device->write(remainder); + } else { + QByteArray remainder = device->readAll(); - QByteArray remainder = device->readAll(); + device->seek(0); - device->seek( 0 ); - - stream << quint16( 0xFFD8 ); // SOI - stream << quint16( 0xFFE0 ); // APP0 - stream << quint16( jfif.size() + 2 ); - device->write( jfif ); - stream << quint16( 0xFFE1 ); //APP1 - stream << quint16( exif.size() + 2 ); - device->write( exif ); - device->write( remainder ); - } - else - { - QByteArray remainder = device->readAll(); - - device->seek( 0 ); - - stream << quint16( 0xFFD8 ); // SOI - stream << quint16( 0xFFE0 ); // APP0 - stream << quint16( jfif.size() + 2 ); - device->write( jfif ); - stream << quint16( 0xFFE1 ); //APP1 - stream << quint16( exif.size() + 2 ); - device->write( exif ); - stream << quint16( 0xFFE0 ); // APP0 - stream << segmentId; - stream << segmentLength; - device->write( remainder ); - } + stream << quint16(0xFFD8); // SOI + stream << quint16(0xFFE0); // APP0 + stream << quint16(jfif.size() + 2); + device->write(jfif); + stream << quint16(0xFFE1); // APP1 + stream << quint16(exif.size() + 2); + device->write(exif); + stream << quint16(0xFFE0); // APP0 + stream << segmentId; + stream << segmentLength; + device->write(remainder); } - else if( segmentId == 0xFFE1 ) - { - QByteArray oldExif = device->read( segmentLength - 2 ); + } else if (segmentId == 0xFFE1) { + QByteArray oldExif = device->read(segmentLength - 2); - if( !oldExif.startsWith( "Exif" ) ) - return false; + if (!oldExif.startsWith("Exif")) + return false; - int dSize = oldExif.size() - exif.size(); + int dSize = oldExif.size() - exif.size(); - if( dSize > 0 ) - exif += QByteArray( dSize, '\0' ); + if (dSize > 0) + exif += QByteArray(dSize, '\0'); - QByteArray remainder = device->readAll(); + QByteArray remainder = device->readAll(); - device->seek( 0 ); + device->seek(0); - stream << quint16( 0xFFD8 ); // SOI - stream << quint16( 0xFFE1 ); //APP1 - stream << quint16( exif.size() + 2 ); - device->write( exif ); - device->write( remainder ); - } - else - { - QByteArray remainder = device->readAll(); + stream << quint16(0xFFD8); // SOI + stream << quint16(0xFFE1); // APP1 + stream << quint16(exif.size() + 2); + device->write(exif); + device->write(remainder); + } else { + QByteArray remainder = device->readAll(); - device->seek( 0 ); + device->seek(0); - stream << quint16( 0xFFD8 ); // SOI - stream << quint16( 0xFFE1 ); //APP1 - stream << quint16( exif.size() + 2 ); - device->write( exif ); - stream << segmentId; - stream << segmentLength; - device->write( remainder ); - } + stream << quint16(0xFFD8); // SOI + stream << quint16(0xFFE1); // APP1 + stream << quint16(exif.size() + 2); + device->write(exif); + stream << segmentId; + stream << segmentLength; + device->write(remainder); + } - return true; + return true; } /*! Returns the byte order of EXIF file. -*/ -QSysInfo::Endian QExifImageHeader::byteOrder() const -{ - return d->byteOrder; + */ +QSysInfo::Endian QExifImageHeader::byteOrder () const { + return d->byteOrder; } - -quint32 QExifImageHeader::sizeOf(const QExifValue &value) const -{ - switch (value.type()) { +quint32 QExifImageHeader::sizeOf (const QExifValue &value) const { + switch (value.type()) { case QExifValue::Byte: case QExifValue::Undefined: - return value.count() > 4 - ? 12 + value.count() - : 12; + return value.count() > 4 + ? 12 + value.count() + : 12; case QExifValue::Ascii: - return value.count() > 4 - ? 12 + value.count() - : 12; + return value.count() > 4 + ? 12 + value.count() + : 12; case QExifValue::Short: - return value.count() > 2 - ? 12 + value.count() * sizeof(quint16) - : 12; + return value.count() > 2 + ? 12 + value.count() * sizeof(quint16) + : 12; case QExifValue::Long: case QExifValue::SignedLong: - return value.count() > 1 - ? 12 + value.count() * sizeof(quint32) - : 12; + return value.count() > 1 + ? 12 + value.count() * sizeof(quint32) + : 12; case QExifValue::Rational: case QExifValue::SignedRational: - return value.count() > 0 - ? 12 + value.count() * sizeof(quint32) * 2 - : 12; + return value.count() > 0 + ? 12 + value.count() * sizeof(quint32) * 2 + : 12; default: - return 0; - } + return 0; + } } -template -quint32 QExifImageHeader::calculateSize(const QMap &values) const -{ - quint32 size = sizeof(quint16); +template +quint32 QExifImageHeader::calculateSize (const QMap &values) const { + quint32 size = sizeof(quint16); - foreach (const QExifValue &value, values) - size += sizeOf(value); + foreach(const QExifValue &value, values) + size += sizeOf(value); - return size; + return size; } /*! Returns the size of EXIF data in bytes. -*/ -qint64 QExifImageHeader::size() const -{ - if (d->size == -1) { - d->size - = 2 // Byte Order - + 2 // Marker - + 4 // Image Ifd offset - + 12 // ExifIfdPointer Ifd - + 4 // Thumbnail Ifd offset - + calculateSize(d->imageIfdValues) // Image headers and values. - + calculateSize(d->exifIfdValues); // Exif headers and values. + */ +qint64 QExifImageHeader::size () const { + if (d->size == -1) { + d->size = 2 + // Byte Order + 2 + // Marker + 4 + // Image Ifd offset + 12 + // ExifIfdPointer Ifd + 4 + // Thumbnail Ifd offset + calculateSize(d->imageIfdValues) + // Image headers and values. + calculateSize(d->exifIfdValues); // Exif headers and values. - if (!d->gpsIfdValues.isEmpty()) { - d->size - += 12 // GpsInfoIfdPointer Ifd - + calculateSize(d->gpsIfdValues); // Gps headers and values. - } - - if (!d->thumbnailData.isEmpty()) { - d->size - += 2 // Thumbnail Ifd count - + 12 // Compression Ifd - + 20 // XResolution Ifd - + 20 // YResolution Ifd - + 12 // ResolutionUnit Ifd - + 12 // JpegInterchangeFormat Ifd - + 12 // JpegInterchangeFormatLength Ifd - + d->thumbnailData.size(); // Thumbnail data size. - } + if (!d->gpsIfdValues.isEmpty()) { + d->size += 12 + // GpsInfoIfdPointer Ifd + calculateSize(d->gpsIfdValues); // Gps headers and values. } - return d->size; + if (!d->thumbnailData.isEmpty()) { + d->size += 2 + // Thumbnail Ifd count + 12 + // Compression Ifd + 20 + // XResolution Ifd + 20 + // YResolution Ifd + 12 + // ResolutionUnit Ifd + 12 + // JpegInterchangeFormat Ifd + 12 + // JpegInterchangeFormatLength Ifd + d->thumbnailData.size(); // Thumbnail data size. + } + } + + return d->size; } /*! Clears all image meta-data. -*/ -void QExifImageHeader::clear() -{ - d->imageIfdValues.clear(); - d->exifIfdValues.clear(); - d->gpsIfdValues.clear(); - d->thumbnailData.clear(); + */ +void QExifImageHeader::clear () { + d->imageIfdValues.clear(); + d->exifIfdValues.clear(); + d->gpsIfdValues.clear(); + d->thumbnailData.clear(); - d->size = -1; + d->size = -1; } /*! Returns a list of all image tags in an EXIF header. -*/ -QList QExifImageHeader::imageTags() const -{ - return d->imageIfdValues.keys(); + */ +QList QExifImageHeader::imageTags () const { + return d->imageIfdValues.keys(); } /*! Returns a list of all extended EXIF tags in a header. -*/ -QList QExifImageHeader::extendedTags() const -{ - return d->exifIfdValues.keys(); + */ +QList QExifImageHeader::extendedTags () const { + return d->exifIfdValues.keys(); } /*! Returns a list of all GPS tags in an EXIF header. -*/ -QList QExifImageHeader::gpsTags() const -{ - return d->gpsIfdValues.keys(); + */ +QList QExifImageHeader::gpsTags () const { + return d->gpsIfdValues.keys(); } /*! Returns true if an EXIf header contains a value for an image \a tag and false otherwise. -*/ -bool QExifImageHeader::contains(ImageTag tag) const -{ - return d->imageIfdValues.contains(tag); + */ +bool QExifImageHeader::contains (ImageTag tag) const { + return d->imageIfdValues.contains(tag); } /*! Returns true if a header contains a a value for an extended EXIF \a tag and false otherwise. -*/ -bool QExifImageHeader::contains(ExifExtendedTag tag) const -{ - return d->exifIfdValues.contains(tag); + */ +bool QExifImageHeader::contains (ExifExtendedTag tag) const { + return d->exifIfdValues.contains(tag); } /*! Returns true if an EXIf header contains a value for a GPS \a tag and false otherwise. -*/ -bool QExifImageHeader::contains(GpsTag tag) const -{ - return d->gpsIfdValues.contains(tag); + */ +bool QExifImageHeader::contains (GpsTag tag) const { + return d->gpsIfdValues.contains(tag); } /*! Removes the value for an image \a tag. -*/ -void QExifImageHeader::remove(ImageTag tag) -{ - d->imageIfdValues.remove(tag); + */ +void QExifImageHeader::remove (ImageTag tag) { + d->imageIfdValues.remove(tag); - d->size = -1; + d->size = -1; } /*! Removes the value for an extended EXIF \a tag. -*/ -void QExifImageHeader::remove(ExifExtendedTag tag) -{ - d->exifIfdValues.remove(tag); + */ +void QExifImageHeader::remove (ExifExtendedTag tag) { + d->exifIfdValues.remove(tag); - d->size = -1; + d->size = -1; } /*! Removes the value for a GPS \a tag. -*/ -void QExifImageHeader::remove(GpsTag tag) -{ - d->gpsIfdValues.remove(tag); + */ +void QExifImageHeader::remove (GpsTag tag) { + d->gpsIfdValues.remove(tag); - d->size = -1; + d->size = -1; } /*! Returns the value for an image \a tag. -*/ -QExifValue QExifImageHeader::value(ImageTag tag) const -{ - return d->imageIfdValues.value(tag); + */ +QExifValue QExifImageHeader::value (ImageTag tag) const { + return d->imageIfdValues.value(tag); } /*! Returns the value for an extended EXIF \a tag. -*/ -QExifValue QExifImageHeader::value(ExifExtendedTag tag) const -{ - return d->exifIfdValues.value(tag); + */ +QExifValue QExifImageHeader::value (ExifExtendedTag tag) const { + return d->exifIfdValues.value(tag); } /*! Returns the value for a GPS tag. -*/ -QExifValue QExifImageHeader::value(GpsTag tag) const -{ - return d->gpsIfdValues.value(tag); + */ +QExifValue QExifImageHeader::value (GpsTag tag) const { + return d->gpsIfdValues.value(tag); } /*! Sets the \a value for an image \a tag. -*/ -void QExifImageHeader::setValue(ImageTag tag, const QExifValue &value) -{ - d->imageIfdValues[tag] = value; + */ +void QExifImageHeader::setValue (ImageTag tag, const QExifValue &value) { + d->imageIfdValues[tag] = value; - d->size = -1; + d->size = -1; } /*! Sets the \a value for an extended EXIF \a tag. -*/ -void QExifImageHeader::setValue(ExifExtendedTag tag, const QExifValue &value) -{ - d->exifIfdValues[tag] = value; + */ +void QExifImageHeader::setValue (ExifExtendedTag tag, const QExifValue &value) { + d->exifIfdValues[tag] = value; - d->size = -1; + d->size = -1; } /*! Sets the \a value for an GPS \a tag. -*/ -void QExifImageHeader::setValue(GpsTag tag, const QExifValue &value) -{ - d->gpsIfdValues[tag] = value; + */ +void QExifImageHeader::setValue (GpsTag tag, const QExifValue &value) { + d->gpsIfdValues[tag] = value; - d->size = -1; + d->size = -1; } /*! Returns the image thumbnail. -*/ -QImage QExifImageHeader::thumbnail() const -{ - QImage image; + */ +QImage QExifImageHeader::thumbnail () const { + QImage image; - image.loadFromData(d->thumbnailData, "JPG"); + image.loadFromData(d->thumbnailData, "JPG"); - if (!d->thumbnailOrientation.isNull()) { - switch (d->thumbnailOrientation.toShort()) { - case 1: - return image; - case 2: - return image.transformed(QTransform().rotate(180, Qt::YAxis)); - case 3: - return image.transformed(QTransform().rotate(180, Qt::ZAxis)); - case 4: - return image.transformed(QTransform().rotate(180, Qt::XAxis)); - case 5: - return image.transformed(QTransform().rotate(180, Qt::YAxis).rotate(90, Qt::ZAxis)); - case 6: - return image.transformed(QTransform().rotate(90, Qt::ZAxis)); - case 7: - return image.transformed(QTransform().rotate(180, Qt::XAxis).rotate(90, Qt::ZAxis)); - case 8: - return image.transformed(QTransform().rotate(270, Qt::ZAxis)); - } + if (!d->thumbnailOrientation.isNull()) { + switch (d->thumbnailOrientation.toShort()) { + case 1: + return image; + case 2: + return image.transformed(QTransform().rotate(180, Qt::YAxis)); + case 3: + return image.transformed(QTransform().rotate(180, Qt::ZAxis)); + case 4: + return image.transformed(QTransform().rotate(180, Qt::XAxis)); + case 5: + return image.transformed(QTransform().rotate(180, Qt::YAxis).rotate(90, Qt::ZAxis)); + case 6: + return image.transformed(QTransform().rotate(90, Qt::ZAxis)); + case 7: + return image.transformed(QTransform().rotate(180, Qt::XAxis).rotate(90, Qt::ZAxis)); + case 8: + return image.transformed(QTransform().rotate(270, Qt::ZAxis)); } + } - return image; + return image; } /*! Sets the image \a thumbnail. -*/ -void QExifImageHeader::setThumbnail( const QImage &thumbnail ) -{ - if (!thumbnail.isNull()) { - QBuffer buffer; + */ +void QExifImageHeader::setThumbnail (const QImage &thumbnail) { + if (!thumbnail.isNull()) { + QBuffer buffer; - if (buffer.open(QIODevice::WriteOnly) && thumbnail.save(&buffer, "JPG")) { - buffer.close(); + if (buffer.open(QIODevice::WriteOnly) && thumbnail.save(&buffer, "JPG")) { + buffer.close(); - d->thumbnailSize = thumbnail.size(); - d->thumbnailData = buffer.data(); - d->thumbnailOrientation = QExifValue(); - } - } else { - d->thumbnailSize = QSize(); - d->thumbnailData = QByteArray(); + d->thumbnailSize = thumbnail.size(); + d->thumbnailData = buffer.data(); + d->thumbnailOrientation = QExifValue(); } + } else { + d->thumbnailSize = QSize(); + d->thumbnailData = QByteArray(); + } - d->size = -1; + d->size = -1; } -QByteArray QExifImageHeader::extractExif( QIODevice *device ) const -{ - QDataStream stream( device ); +QByteArray QExifImageHeader::extractExif (QIODevice *device) const { + QDataStream stream(device); - stream.setByteOrder( QDataStream::BigEndian ); + stream.setByteOrder(QDataStream::BigEndian); - if( device->read( 2 ) != "\xFF\xD8" ) - return QByteArray(); + if (device->read(2) != "\xFF\xD8") + return QByteArray(); - while( device->read( 2 ) != "\xFF\xE1" ) - { - if( device->atEnd() ) - return QByteArray(); - - quint16 length; - - stream >> length; - - device->seek( device->pos() + length - 2 ); - } + while (device->read(2) != "\xFF\xE1") { + if (device->atEnd()) + return QByteArray(); quint16 length; stream >> length; - if( device->read( 4 ) != "Exif" ) - return QByteArray(); + device->seek(device->pos() + length - 2); + } - device->read( 2 ); + quint16 length; - return device->read( length - 8 ); + stream >> length; + + if (device->read(4) != "Exif") + return QByteArray(); + + device->read(2); + + return device->read(length - 8); } +QList QExifImageHeader::readIfdHeaders (QDataStream &stream) const { + QList headers; -QList QExifImageHeader::readIfdHeaders(QDataStream &stream) const -{ - QList headers; + quint16 count; - quint16 count; + stream >> count; - stream >> count; + for (quint16 i = 0; i < count; i++) { + ExifIfdHeader header; - for (quint16 i = 0; i < count; i++) { - ExifIfdHeader header; + stream >> header; - stream >> header; + headers.append(header); + } - headers.append(header); + return headers; +} + +QExifValue QExifImageHeader::readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const { + switch (header.type) { + case QExifValue::Byte: { + QVector value(header.count); + + if (header.count > 4) { + stream.device()->seek(startPos + header.offset); + + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; + } else { + for (quint32 i = 0; i < header.count; i++) + value[i] = header.offsetBytes[i]; + } + return QExifValue(value); } - - return headers; -} - -QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, const ExifIfdHeader &header) const -{ - switch (header.type) { - case QExifValue::Byte: - { - QVector value( header.count ); - - if (header.count > 4) { - stream.device()->seek(startPos + header.offset); - - for (quint32 i = 0; i < header.count; i++) - stream >> value[i]; - } else { - for( quint32 i = 0; i < header.count; i++ ) - value[ i ] = header.offsetBytes[ i ]; - - } - return QExifValue(value); - } case QExifValue::Undefined: - if (header.count > 4) { - stream.device()->seek(startPos + header.offset); + if (header.count > 4) { + stream.device()->seek(startPos + header.offset); - return QExifValue(stream.device()->read(header.count)); - } else { - return QExifValue(QByteArray::fromRawData(header.offsetAscii, header.count)); - } + return QExifValue(stream.device()->read(header.count)); + } else { + return QExifValue(QByteArray::fromRawData(header.offsetAscii, header.count)); + } case QExifValue::Ascii: - if (header.count > 4) { - stream.device()->seek(startPos + header.offset); + if (header.count > 4) { + stream.device()->seek(startPos + header.offset); - QByteArray ascii = stream.device()->read(header.count); + QByteArray ascii = stream.device()->read(header.count); - return QExifValue(QString::fromUtf8(ascii.constData(), ascii.size() - 1)); - } else { - return QExifValue(QString::fromUtf8(header.offsetAscii, header.count - 1)); - } - case QExifValue::Short: - { - QVector value(header.count); + return QExifValue(QString::fromUtf8(ascii.constData(), ascii.size() - 1)); + } else { + return QExifValue(QString::fromUtf8(header.offsetAscii, header.count - 1)); + } + case QExifValue::Short: { + QVector value(header.count); - if (header.count > 2) { - stream.device()->seek(startPos + header.offset); + if (header.count > 2) { + stream.device()->seek(startPos + header.offset); - for (quint32 i = 0; i < header.count; i++) - stream >> value[i]; - } else { - for (quint32 i = 0; i < header.count; i++) - value[i] = header.offsetShorts[i]; + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; + } else { + for (quint32 i = 0; i < header.count; i++) + value[i] = header.offsetShorts[i]; + } + return QExifValue(value); + } + case QExifValue::Long: { + QVector value(header.count); - } - return QExifValue(value); - } - case QExifValue::Long: - { - QVector value(header.count); + if (header.count > 1) { + stream.device()->seek(startPos + header.offset); - if (header.count > 1) { - stream.device()->seek(startPos + header.offset); + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; + } else if (header.count == 1) { + value[0] = header.offset; + } + return QExifValue(value); + } + case QExifValue::SignedLong: { + QVector value(header.count); - for (quint32 i = 0; i < header.count; i++) - stream >> value[i]; - } else if(header.count == 1) { - value[0] = header.offset; - } - return QExifValue(value); - } - case QExifValue::SignedLong: - { - QVector value(header.count); + if (header.count > 1) { + stream.device()->seek(startPos + header.offset); - if (header.count > 1) { - stream.device()->seek(startPos + header.offset); + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; + } else if (header.count == 1) { + value[0] = header.offset; + } + return QExifValue(value); + } + break; + case QExifValue::Rational: { + QVector value(header.count); - for (quint32 i = 0; i < header.count; i++) - stream >> value[i]; - } else if (header.count == 1) { - value[0] = header.offset; - } - return QExifValue(value); - } - break; - case QExifValue::Rational: - { - QVector value(header.count); + stream.device()->seek(startPos + header.offset); - stream.device()->seek(startPos + header.offset); + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; - for (quint32 i = 0; i < header.count; i++) - stream >> value[i]; + return QExifValue(value); + } + case QExifValue::SignedRational: { + QVector value(header.count); - return QExifValue(value); - } - case QExifValue::SignedRational: - { - QVector value(header.count); + stream.device()->seek(startPos + header.offset); - stream.device()->seek(startPos + header.offset); + for (quint32 i = 0; i < header.count; i++) + stream >> value[i]; - for(quint32 i = 0; i < header.count; i++) - stream >> value[i]; - - return QExifValue(value); - } + return QExifValue(value); + } default: - qWarning() << "Invalid Ifd Type" << header.type; + qWarning() << "Invalid Ifd Type" << header.type; - return QExifValue(); - } + return QExifValue(); + } } -template QMap QExifImageHeader::readIfdValues( - QDataStream &stream, int startPos, const QList &headers) const -{ - QMap values; +template +QMap QExifImageHeader::readIfdValues ( + QDataStream &stream, + int startPos, + const QList &headers +) const { + QMap values; - // This needs to be non-const so it works with gcc3 - QList headers_ = headers; - foreach (const ExifIfdHeader &header, headers_) - values[T(header.tag)] = readIfdValue(stream, startPos, header); + // This needs to be non-const so it works with gcc3 + QList headers_ = headers; + foreach(const ExifIfdHeader &header, headers_) + values[T(header.tag)] = readIfdValue(stream, startPos, header); - return values; + return values; } -template -QMap QExifImageHeader::readIfdValues( - QDataStream &stream, int startPos, const QExifValue &pointer) const -{ - if (pointer.type() == QExifValue::Long && pointer.count() == 1) { - stream.device()->seek(startPos + pointer.toLong()); +template +QMap QExifImageHeader::readIfdValues ( + QDataStream &stream, + int startPos, + const QExifValue &pointer +) const { + if (pointer.type() == QExifValue::Long && pointer.count() == 1) { + stream.device()->seek(startPos + pointer.toLong()); - QList headers = readIfdHeaders(stream); + QList headers = readIfdHeaders(stream); - return readIfdValues(stream, startPos, headers); - } else { - return QMap(); - } + return readIfdValues(stream, startPos, headers); + } else { + return QMap(); + } } - /*! Reads the contents of an EXIF header from an I/O \a device. Returns true if the header was read and false otherwise. \sa loadFromJpeg(), write() -*/ -bool QExifImageHeader::read(QIODevice *device) -{ - clear(); + */ +bool QExifImageHeader::read (QIODevice *device) { + clear(); - int startPos = device->pos(); + int startPos = device->pos(); - QDataStream stream(device); + QDataStream stream(device); - QByteArray byteOrder = device->read(2); + QByteArray byteOrder = device->read(2); - if (byteOrder == "II") { - d->byteOrder = QSysInfo::LittleEndian; + if (byteOrder == "II") { + d->byteOrder = QSysInfo::LittleEndian; - stream.setByteOrder( QDataStream::LittleEndian ); - } else if (byteOrder == "MM") { - d->byteOrder = QSysInfo::BigEndian; + stream.setByteOrder(QDataStream::LittleEndian); + } else if (byteOrder == "MM") { + d->byteOrder = QSysInfo::BigEndian; - stream.setByteOrder( QDataStream::BigEndian ); - } else { - return false; - } + stream.setByteOrder(QDataStream::BigEndian); + } else { + return false; + } - quint16 id; - quint32 offset; + quint16 id; + quint32 offset; - stream >> id; - stream >> offset; + stream >> id; + stream >> offset; - if (id != 0x002A) - return false; + if (id != 0x002A) + return false; + device->seek(startPos + offset); + + QList headers = readIfdHeaders(stream); + + stream >> offset; + + d->imageIfdValues = readIfdValues(stream, startPos, headers); + + QExifValue exifIfdPointer = d->imageIfdValues.take(ImageTag(ExifIfdPointer)); + QExifValue gpsIfdPointer = d->imageIfdValues.take(ImageTag(GpsInfoIfdPointer)); + + d->exifIfdValues = readIfdValues(stream, startPos, exifIfdPointer); + d->gpsIfdValues = readIfdValues(stream, startPos, gpsIfdPointer); + + d->exifIfdValues.remove(ExifExtendedTag(InteroperabilityIfdPointer)); + + if (offset) { device->seek(startPos + offset); - QList headers = readIfdHeaders(stream); + QMap thumbnailIfdValues = readIfdValues( + stream, startPos, readIfdHeaders(stream)); - stream >> offset; + QExifValue jpegOffset = thumbnailIfdValues.value(JpegInterchangeFormat); + QExifValue jpegLength = thumbnailIfdValues.value(JpegInterchangeFormatLength); - d->imageIfdValues = readIfdValues(stream, startPos, headers); + if (jpegOffset.type() == QExifValue::Long && jpegOffset.count() == 1 && + jpegLength.type() == QExifValue::Long && jpegLength.count() == 1) { + device->seek(startPos + jpegOffset.toLong()); - QExifValue exifIfdPointer = d->imageIfdValues.take(ImageTag(ExifIfdPointer)); - QExifValue gpsIfdPointer = d->imageIfdValues.take(ImageTag(GpsInfoIfdPointer)); + d->thumbnailData = device->read(jpegLength.toLong()); - d->exifIfdValues = readIfdValues(stream, startPos, exifIfdPointer); - d->gpsIfdValues = readIfdValues(stream, startPos, gpsIfdPointer); - - d->exifIfdValues.remove(ExifExtendedTag(InteroperabilityIfdPointer)); - - if (offset) { - device->seek(startPos + offset); - - QMap thumbnailIfdValues = readIfdValues( - stream, startPos, readIfdHeaders( stream)); - - QExifValue jpegOffset = thumbnailIfdValues.value(JpegInterchangeFormat); - QExifValue jpegLength = thumbnailIfdValues.value(JpegInterchangeFormatLength); - - if (jpegOffset.type() == QExifValue::Long && jpegOffset.count() == 1 - && jpegLength.type() == QExifValue::Long && jpegLength.count() == 1) - { - device->seek(startPos + jpegOffset.toLong()); - - d->thumbnailData = device->read( jpegLength.toLong() ); - - d->thumbnailXResolution = thumbnailIfdValues.value(XResolution); - d->thumbnailYResolution = thumbnailIfdValues.value(YResolution); - d->thumbnailResolutionUnit = thumbnailIfdValues.value(ResolutionUnit); - d->thumbnailOrientation = thumbnailIfdValues.value(Orientation); - } + d->thumbnailXResolution = thumbnailIfdValues.value(XResolution); + d->thumbnailYResolution = thumbnailIfdValues.value(YResolution); + d->thumbnailResolutionUnit = thumbnailIfdValues.value(ResolutionUnit); + d->thumbnailOrientation = thumbnailIfdValues.value(Orientation); } - return true; + } + return true; } -quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const -{ - stream << tag; - stream << quint16(value.type()); - stream << quint32(value.count()); +quint32 QExifImageHeader::writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const { + stream << tag; + stream << quint16(value.type()); + stream << quint32(value.count()); - switch (value.type()) { + switch (value.type()) { case QExifValue::Byte: - if (value.count() <= 4) { - foreach (quint8 byte, value.toByteVector()) - stream << byte; - for (int j = value.count(); j < 4; j++) - stream << quint8(0); - } else { - stream << offset; + if (value.count() <= 4) { + foreach(quint8 byte, value.toByteVector()) + stream << byte; + for (int j = value.count(); j < 4; j++) + stream << quint8(0); + } else { + stream << offset; - offset += value.count(); - } - break; + offset += value.count(); + } + break; case QExifValue::Undefined: - if (value.count() <= 4) { - stream.device()->write(value.toByteArray()); + if (value.count() <= 4) { + stream.device()->write(value.toByteArray()); - if ( value.count() < 4) - stream.writeRawData("\0\0\0\0", 4 - value.count()); - } else { - stream << offset; + if (value.count() < 4) + stream.writeRawData("\0\0\0\0", 4 - value.count()); + } else { + stream << offset; - offset += value.count(); - } - break; + offset += value.count(); + } + break; case QExifValue::Ascii: - if (value.count() <= 4) { - QByteArray bytes = value.toByteArray(); + if (value.count() <= 4) { + QByteArray bytes = value.toByteArray(); - stream.writeRawData(bytes.constData(), value.count()); - if (value.count() < 4) - stream.writeRawData("\0\0\0\0", 4 - value.count()); - } else { - stream << offset; + stream.writeRawData(bytes.constData(), value.count()); + if (value.count() < 4) + stream.writeRawData("\0\0\0\0", 4 - value.count()); + } else { + stream << offset; - offset += value.count(); - } - break; + offset += value.count(); + } + break; case QExifValue::Short: - if (value.count() <= 2) { - foreach (quint16 shrt, value.toShortVector()) - stream << shrt; - for (int j = value.count(); j < 2; j++) - stream << quint16(0); - } else { - stream << offset; + if (value.count() <= 2) { + foreach(quint16 shrt, value.toShortVector()) + stream << shrt; + for (int j = value.count(); j < 2; j++) + stream << quint16(0); + } else { + stream << offset; - offset += value.count() * sizeof(quint16); - } - break; + offset += value.count() * sizeof(quint16); + } + break; case QExifValue::Long: - if(value.count() == 0) { - stream << quint32(0); - } else if(value.count() == 1) { - stream << value.toLong(); - } else { - stream << offset; - - offset += value.count() * sizeof(quint32); - } - break; - case QExifValue::SignedLong: - if (value.count() == 0) { - stream << quint32( 0 ); - } else if (value.count() == 1) { - stream << value.toSignedLong(); - } else { - stream << offset; - - offset += value.count() * sizeof(qint32); - } - break; - case QExifValue::Rational: - if(value.count() == 0) { - stream << quint32(0); - } else { - stream << offset; - - offset += value.count() * sizeof(quint32) * 2; - } - break; - case QExifValue::SignedRational: - if (value.count() == 0) { - stream << quint32(0); - } else { - stream << offset; - - offset += value.count() * sizeof(qint32) * 2; - } - break; - default: - qWarning() << "Invalid Ifd Type" << value.type(); + if (value.count() == 0) { stream << quint32(0); - } + } else if (value.count() == 1) { + stream << value.toLong(); + } else { + stream << offset; - return offset; -} - -void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &value) const -{ - switch (value.type()) { - case QExifValue::Byte: - if (value.count() > 4) - foreach (quint8 byte, value.toByteVector()) - stream << byte; - break; - case QExifValue::Undefined: - if (value.count() > 4) - stream.device()->write(value.toByteArray()); - break; - case QExifValue::Ascii: - if (value.count() > 4) { - QByteArray bytes = value.toByteArray(); - - stream.writeRawData(bytes.constData(), bytes.size() + 1); - } - break; - case QExifValue::Short: - if (value.count() > 2) - foreach(quint16 shrt, value.toShortVector()) - stream << shrt; - break; - case QExifValue::Long: - if(value.count() > 1) - foreach (quint32 lng, value.toLongVector()) - stream << lng; - break; + offset += value.count() * sizeof(quint32); + } + break; case QExifValue::SignedLong: - if (value.count() > 1) - foreach(qint32 lng, value.toSignedLongVector()) - stream << lng; - break; + if (value.count() == 0) { + stream << quint32(0); + } else if (value.count() == 1) { + stream << value.toSignedLong(); + } else { + stream << offset; + + offset += value.count() * sizeof(qint32); + } + break; case QExifValue::Rational: - if (value.count() > 0) - foreach (QExifURational rational, value.toRationalVector()) - stream << rational; - break; + if (value.count() == 0) { + stream << quint32(0); + } else { + stream << offset; + + offset += value.count() * sizeof(quint32) * 2; + } + break; case QExifValue::SignedRational: - if (value.count() > 0) - foreach (QExifSRational rational, value.toSignedRationalVector()) - stream << rational; - break; + if (value.count() == 0) { + stream << quint32(0); + } else { + stream << offset; + + offset += value.count() * sizeof(qint32) * 2; + } + break; default: - qWarning() << "Invalid Ifd Type" << value.type(); - break; - } + qWarning() << "Invalid Ifd Type" << value.type(); + stream << quint32(0); + } + + return offset; } -template quint32 QExifImageHeader::writeExifHeaders( - QDataStream &stream, const QMap &values, quint32 offset) const -{ - offset += values.count() * 12; +void QExifImageHeader::writeExifValue (QDataStream &stream, const QExifValue &value) const { + switch (value.type()) { + case QExifValue::Byte: + if (value.count() > 4) + foreach(quint8 byte, value.toByteVector()) + stream << byte; + break; + case QExifValue::Undefined: + if (value.count() > 4) + stream.device()->write(value.toByteArray()); + break; + case QExifValue::Ascii: + if (value.count() > 4) { + QByteArray bytes = value.toByteArray(); - for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) - offset = writeExifHeader(stream, i.key(), i.value(), offset); - - return offset; + stream.writeRawData(bytes.constData(), bytes.size() + 1); + } + break; + case QExifValue::Short: + if (value.count() > 2) + foreach(quint16 shrt, value.toShortVector()) + stream << shrt; + break; + case QExifValue::Long: + if (value.count() > 1) + foreach(quint32 lng, value.toLongVector()) + stream << lng; + break; + case QExifValue::SignedLong: + if (value.count() > 1) + foreach(qint32 lng, value.toSignedLongVector()) + stream << lng; + break; + case QExifValue::Rational: + if (value.count() > 0) + foreach(QExifURational rational, value.toRationalVector()) + stream << rational; + break; + case QExifValue::SignedRational: + if (value.count() > 0) + foreach(QExifSRational rational, value.toSignedRationalVector()) + stream << rational; + break; + default: + qWarning() << "Invalid Ifd Type" << value.type(); + break; + } } -template void QExifImageHeader::writeExifValues( - QDataStream &stream, const QMap &values) const -{ - for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) - writeExifValue(stream, i.value()); +template +quint32 QExifImageHeader::writeExifHeaders ( + QDataStream &stream, + const QMap &values, + quint32 offset +) const { + offset += values.count() * 12; + + for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) + offset = writeExifHeader(stream, i.key(), i.value(), offset); + + return offset; +} + +template +void QExifImageHeader::writeExifValues ( + QDataStream &stream, + const QMap &values +) const { + for (typename QMap::const_iterator i = values.constBegin(); i != values.constEnd(); i++) + writeExifValue(stream, i.value()); } /*! Writes an EXIF header to an I/O \a device. Returns the total number of bytes written. -*/ -qint64 QExifImageHeader::write(QIODevice *device) const -{ -//#ifndef QT_NO_DEBUG - qint64 startPos = device->pos(); -//#endif + */ +qint64 QExifImageHeader::write (QIODevice *device) const { + // #ifndef QT_NO_DEBUG + qint64 startPos = device->pos(); + // #endif - QDataStream stream( device ); + QDataStream stream(device); - if (d->byteOrder == QSysInfo::LittleEndian) { - stream.setByteOrder( QDataStream::LittleEndian ); + if (d->byteOrder == QSysInfo::LittleEndian) { + stream.setByteOrder(QDataStream::LittleEndian); - device->write("II", 2); - device->write("\x2A\x00", 2); - device->write("\x08\x00\x00\x00", 4); - } else if (d->byteOrder == QSysInfo::BigEndian) { - stream.setByteOrder(QDataStream::BigEndian); + device->write("II", 2); + device->write("\x2A\x00", 2); + device->write("\x08\x00\x00\x00", 4); + } else if (d->byteOrder == QSysInfo::BigEndian) { + stream.setByteOrder(QDataStream::BigEndian); - device->write("MM", 2); - device->write("\x00\x2A", 2); - device->write("\x00\x00\x00\x08", 4); - } + device->write("MM", 2); + device->write("\x00\x2A", 2); + device->write("\x00\x00\x00\x08", 4); + } - quint16 count = d->imageIfdValues.count() + 1; - quint32 offset = 26; + quint16 count = d->imageIfdValues.count() + 1; + quint32 offset = 26; - if (!d->gpsIfdValues.isEmpty()) { - count++; - offset += 12; - } + if (!d->gpsIfdValues.isEmpty()) { + count++; + offset += 12; + } - stream << count; + stream << count; - offset = writeExifHeaders(stream, d->imageIfdValues, offset); + offset = writeExifHeaders(stream, d->imageIfdValues, offset); - quint32 exifIfdOffset = offset; + quint32 exifIfdOffset = offset; - stream << quint16( ExifIfdPointer ); - stream << quint16( QExifValue::Long ); - stream << quint32( 1 ); - stream << exifIfdOffset; - offset += calculateSize(d->exifIfdValues); + stream << quint16(ExifIfdPointer); + stream << quint16(QExifValue::Long); + stream << quint32(1); + stream << exifIfdOffset; + offset += calculateSize(d->exifIfdValues); - quint32 gpsIfdOffset = offset; + quint32 gpsIfdOffset = offset; - if (!d->gpsIfdValues.isEmpty()) { - stream << quint16(GpsInfoIfdPointer); - stream << quint16(QExifValue::Long); - stream << quint32(1); - stream << gpsIfdOffset; + if (!d->gpsIfdValues.isEmpty()) { + stream << quint16(GpsInfoIfdPointer); + stream << quint16(QExifValue::Long); + stream << quint32(1); + stream << gpsIfdOffset; - d->imageIfdValues.insert(ImageTag(GpsInfoIfdPointer), QExifValue(offset)); + d->imageIfdValues.insert(ImageTag(GpsInfoIfdPointer), QExifValue(offset)); - offset += calculateSize(d->gpsIfdValues); - } + offset += calculateSize(d->gpsIfdValues); + } - if (!d->thumbnailData.isEmpty()) - stream << offset; // Write offset to thumbnail Ifd. - else - stream << quint32(0); + if (!d->thumbnailData.isEmpty()) + stream << offset; // Write offset to thumbnail Ifd. + else + stream << quint32(0); - writeExifValues( stream, d->imageIfdValues ); + writeExifValues(stream, d->imageIfdValues); - Q_ASSERT(startPos + exifIfdOffset == device->pos()); + Q_ASSERT(startPos + exifIfdOffset == device->pos()); - stream << quint16(d->exifIfdValues.count()); + stream << quint16(d->exifIfdValues.count()); - writeExifHeaders(stream, d->exifIfdValues, exifIfdOffset); - writeExifValues(stream, d->exifIfdValues); + writeExifHeaders(stream, d->exifIfdValues, exifIfdOffset); + writeExifValues(stream, d->exifIfdValues); - Q_ASSERT(startPos + gpsIfdOffset == device->pos()); + Q_ASSERT(startPos + gpsIfdOffset == device->pos()); - if (!d->gpsIfdValues.isEmpty()) { - stream << quint16(d->gpsIfdValues.count()); + if (!d->gpsIfdValues.isEmpty()) { + stream << quint16(d->gpsIfdValues.count()); - writeExifHeaders(stream, d->gpsIfdValues, gpsIfdOffset); - writeExifValues(stream, d->gpsIfdValues); - } + writeExifHeaders(stream, d->gpsIfdValues, gpsIfdOffset); + writeExifValues(stream, d->gpsIfdValues); + } + + Q_ASSERT(startPos + offset == device->pos()); + + if (!d->thumbnailData.isEmpty()) { + offset += 86; + + stream << quint16(7); + + QExifValue xResolution = d->thumbnailXResolution.isNull() + ? QExifValue(QExifURational(72, 1)) + : d->thumbnailXResolution; + + QExifValue yResolution = d->thumbnailYResolution.isNull() + ? QExifValue(QExifURational(72, 1)) + : d->thumbnailYResolution; + + QExifValue resolutionUnit = d->thumbnailResolutionUnit.isNull() + ? QExifValue(quint16(2)) + : d->thumbnailResolutionUnit; + + QExifValue orientation = d->thumbnailOrientation.isNull() + ? QExifValue(quint16(0)) + : d->thumbnailOrientation; + + writeExifHeader(stream, Compression, QExifValue(quint16(6)), offset); + + offset = writeExifHeader(stream, XResolution, xResolution, offset); + offset = writeExifHeader(stream, YResolution, yResolution, offset); + + writeExifHeader(stream, ResolutionUnit, resolutionUnit, offset); + writeExifHeader(stream, Orientation, orientation, offset); + writeExifHeader(stream, JpegInterchangeFormat, QExifValue(offset), offset); + writeExifHeader(stream, JpegInterchangeFormatLength, + QExifValue(quint32(d->thumbnailData.size())), offset); + + writeExifValue(stream, xResolution); + writeExifValue(stream, yResolution); Q_ASSERT(startPos + offset == device->pos()); - if (!d->thumbnailData.isEmpty()) { - offset += 86; + device->write(d->thumbnailData); - stream << quint16(7); + offset += d->thumbnailData.size(); + } - QExifValue xResolution = d->thumbnailXResolution.isNull() - ? QExifValue(QExifURational(72, 1)) - : d->thumbnailXResolution; + Q_ASSERT(startPos + offset == device->pos()); - QExifValue yResolution = d->thumbnailYResolution.isNull() - ? QExifValue(QExifURational(72, 1)) - : d->thumbnailYResolution; + d->size = offset; - QExifValue resolutionUnit = d->thumbnailResolutionUnit.isNull() - ? QExifValue(quint16(2)) - : d->thumbnailResolutionUnit; - - QExifValue orientation = d->thumbnailOrientation.isNull() - ? QExifValue(quint16(0)) - : d->thumbnailOrientation; - - writeExifHeader(stream, Compression, QExifValue(quint16(6)), offset); - - offset = writeExifHeader(stream, XResolution, xResolution, offset); - offset = writeExifHeader(stream, YResolution, yResolution, offset); - - writeExifHeader(stream, ResolutionUnit, resolutionUnit, offset); - writeExifHeader(stream, Orientation, orientation, offset); - writeExifHeader(stream, JpegInterchangeFormat, QExifValue(offset), offset); - writeExifHeader(stream, JpegInterchangeFormatLength, - QExifValue(quint32(d->thumbnailData.size())), offset); - - writeExifValue(stream, xResolution); - writeExifValue(stream, yResolution); - - Q_ASSERT(startPos + offset == device->pos()); - - device->write(d->thumbnailData); - - offset += d->thumbnailData.size(); - } - - Q_ASSERT(startPos + offset == device->pos()); - - d->size = offset; - - return offset; + return offset; } diff --git a/src/utils/QExifImageHeader.h b/src/utils/QExifImageHeader.h index 3f24e929b..757320d08 100644 --- a/src/utils/QExifImageHeader.h +++ b/src/utils/QExifImageHeader.h @@ -51,298 +51,286 @@ #include #include -typedef QPair< quint32, quint32 > QExifURational; -typedef QPair< qint32, qint32 > QExifSRational; - -//Q_DECLARE_METATYPE(QExifURational) -//Q_DECLARE_METATYPE(QExifSRational) +typedef QPair QExifURational; +typedef QPair QExifSRational; class QExifValuePrivate; -class QExifValue -{ +class QExifValue { public: - enum Type - { - Byte = 1, - Ascii = 2, - Short = 3, - Long = 4, - Rational = 5, - Undefined = 7, - SignedLong = 9, - SignedRational = 10 - }; + enum Type { + Byte = 1, + Ascii = 2, + Short = 3, + Long = 4, + Rational = 5, + Undefined = 7, + SignedLong = 9, + SignedRational = 10 + }; - enum TextEncoding - { - NoEncoding, - AsciiEncoding, - JisEncoding, - UnicodeEncoding, - UndefinedEncoding - }; + enum TextEncoding { + NoEncoding, + AsciiEncoding, + JisEncoding, + UnicodeEncoding, + UndefinedEncoding + }; - QExifValue(); - QExifValue( quint8 value ); - QExifValue( const QVector< quint8 > &value ); - QExifValue( const QString &value, TextEncoding encoding = NoEncoding ); - QExifValue( quint16 value ); - QExifValue( const QVector< quint16 > &value ); - QExifValue( quint32 value ); - QExifValue( const QVector< quint32 > &value ); - QExifValue( const QExifURational &value ); - QExifValue( const QVector< QExifURational > &value ); - QExifValue( const QByteArray &value ); - QExifValue( qint32 value ); - QExifValue( const QVector< qint32 > &value ); - QExifValue( const QExifSRational &value ); - QExifValue( const QVector< QExifSRational > &value ); - QExifValue( const QDateTime &value ); - QExifValue( const QExifValue &other ); - QExifValue &operator =( const QExifValue &other ); - ~QExifValue(); + QExifValue (); + QExifValue (quint8 value); + QExifValue (const QVector &value); + QExifValue (const QString &value, TextEncoding encoding = NoEncoding); + QExifValue (quint16 value); + QExifValue (const QVector &value); + QExifValue (quint32 value); + QExifValue (const QVector &value); + QExifValue (const QExifURational &value); + QExifValue (const QVector &value); + QExifValue (const QByteArray &value); + QExifValue (qint32 value); + QExifValue (const QVector &value); + QExifValue (const QExifSRational &value); + QExifValue (const QVector &value); + QExifValue (const QDateTime &value); + QExifValue (const QExifValue &other); + QExifValue &operator= (const QExifValue &other); + ~QExifValue (); - bool operator ==( const QExifValue &other ) const; + bool operator== (const QExifValue &other) const; - bool isNull() const; + bool isNull () const; - int type() const; - int count() const; + int type () const; + int count () const; - TextEncoding encoding() const; + TextEncoding encoding () const; - quint8 toByte() const; - QVector< quint8 > toByteVector() const; - QString toString() const; - quint16 toShort() const; - QVector< quint16 > toShortVector() const; - quint32 toLong() const; - QVector< quint32 > toLongVector() const; - QExifURational toRational() const; - QVector< QExifURational > toRationalVector() const; - QByteArray toByteArray() const; - qint32 toSignedLong() const; - QVector< qint32 > toSignedLongVector() const; - QExifSRational toSignedRational() const; - QVector< QExifSRational > toSignedRationalVector() const; - QDateTime toDateTime() const; + quint8 toByte () const; + QVector toByteVector () const; + QString toString () const; + quint16 toShort () const; + QVector toShortVector () const; + quint32 toLong () const; + QVector toLongVector () const; + QExifURational toRational () const; + QVector toRationalVector () const; + QByteArray toByteArray () const; + qint32 toSignedLong () const; + QVector toSignedLongVector () const; + QExifSRational toSignedRational () const; + QVector toSignedRationalVector () const; + QDateTime toDateTime () const; private: - QExplicitlySharedDataPointer< QExifValuePrivate > d; + QExplicitlySharedDataPointer d; }; struct ExifIfdHeader; class QExifImageHeaderPrivate; -class QExifImageHeader -{ - Q_DISABLE_COPY(QExifImageHeader) +class QExifImageHeader { + Q_DISABLE_COPY(QExifImageHeader) + public: - enum ImageTag - { + enum ImageTag { + ImageWidth = 0x0100, + ImageLength = 0x0101, + BitsPerSample = 0x0102, + Compression = 0x0103, + PhotometricInterpretation = 0x0106, + Orientation = 0x0112, + SamplesPerPixel = 0x0115, + PlanarConfiguration = 0x011C, + YCbCrSubSampling = 0x0212, + XResolution = 0x011A, + YResolution = 0x011B, + ResolutionUnit = 0x0128, + StripOffsets = 0x0111, + RowsPerStrip = 0x0116, + StripByteCounts = 0x0117, + TransferFunction = 0x012D, + WhitePoint = 0x013E, + PrimaryChromaciticies = 0x013F, + YCbCrCoefficients = 0x0211, + ReferenceBlackWhite = 0x0214, + DateTime = 0x0132, + ImageDescription = 0x010E, + Make = 0x010F, + Model = 0x0110, + Software = 0x0131, + Artist = 0x013B, + Copyright = 0x8298 + }; - ImageWidth = 0x0100, - ImageLength = 0x0101, - BitsPerSample = 0x0102, - Compression = 0x0103, - PhotometricInterpretation = 0x0106, - Orientation = 0x0112, - SamplesPerPixel = 0x0115, - PlanarConfiguration = 0x011C, - YCbCrSubSampling = 0x0212, - XResolution = 0x011A, - YResolution = 0x011B, - ResolutionUnit = 0x0128, - StripOffsets = 0x0111, - RowsPerStrip = 0x0116, - StripByteCounts = 0x0117, - TransferFunction = 0x012D, - WhitePoint = 0x013E, - PrimaryChromaciticies = 0x013F, - YCbCrCoefficients = 0x0211, - ReferenceBlackWhite = 0x0214, - DateTime = 0x0132, - ImageDescription = 0x010E, - Make = 0x010F, - Model = 0x0110, - Software = 0x0131, - Artist = 0x013B, - Copyright = 0x8298 - }; + enum ExifExtendedTag { + ExifVersion = 0x9000, + FlashPixVersion = 0xA000, + ColorSpace = 0xA001, + ComponentsConfiguration = 0x9101, + CompressedBitsPerPixel = 0x9102, + PixelXDimension = 0xA002, + PixelYDimension = 0xA003, + MakerNote = 0x927C, + UserComment = 0x9286, + RelatedSoundFile = 0xA004, + DateTimeOriginal = 0x9003, + DateTimeDigitized = 0x9004, + SubSecTime = 0x9290, + SubSecTimeOriginal = 0x9291, + SubSecTimeDigitized = 0x9292, + ImageUniqueId = 0xA420, + ExposureTime = 0x829A, + FNumber = 0x829D, + ExposureProgram = 0x8822, + SpectralSensitivity = 0x8824, + ISOSpeedRatings = 0x8827, + Oecf = 0x8828, + ShutterSpeedValue = 0x9201, + ApertureValue = 0x9202, + BrightnessValue = 0x9203, + ExposureBiasValue = 0x9204, + MaxApertureValue = 0x9205, + SubjectDistance = 0x9206, + MeteringMode = 0x9207, + LightSource = 0x9208, + Flash = 0x9209, + FocalLength = 0x920A, + SubjectArea = 0x9214, + FlashEnergy = 0xA20B, + SpatialFrequencyResponse = 0xA20C, + FocalPlaneXResolution = 0xA20E, + FocalPlaneYResolution = 0xA20F, + FocalPlaneResolutionUnit = 0xA210, + SubjectLocation = 0xA214, + ExposureIndex = 0xA215, + SensingMethod = 0xA217, + FileSource = 0xA300, + SceneType = 0xA301, + CfaPattern = 0xA302, + CustomRendered = 0xA401, + ExposureMode = 0xA402, + WhiteBalance = 0xA403, + DigitalZoomRatio = 0xA404, + FocalLengthIn35mmFilm = 0xA405, + SceneCaptureType = 0xA406, + GainControl = 0xA407, + Contrast = 0xA408, + Saturation = 0xA409, + Sharpness = 0xA40A, + DeviceSettingDescription = 0xA40B, + SubjectDistanceRange = 0x40C + }; - enum ExifExtendedTag - { - ExifVersion = 0x9000, - FlashPixVersion = 0xA000, - ColorSpace = 0xA001, - ComponentsConfiguration = 0x9101, - CompressedBitsPerPixel = 0x9102, - PixelXDimension = 0xA002, - PixelYDimension = 0xA003, - MakerNote = 0x927C, - UserComment = 0x9286, - RelatedSoundFile = 0xA004, - DateTimeOriginal = 0x9003, - DateTimeDigitized = 0x9004, - SubSecTime = 0x9290, - SubSecTimeOriginal = 0x9291, - SubSecTimeDigitized = 0x9292, - ImageUniqueId = 0xA420, + enum GpsTag { + GpsVersionId = 0x0000, + GpsLatitudeRef = 0x0001, + GpsLatitude = 0x0002, + GpsLongitudeRef = 0x0003, + GpsLongitude = 0x0004, + GpsAltitudeRef = 0x0005, + GpsAltitude = 0x0006, + GpsTimeStamp = 0x0007, + GpsSatellites = 0x0008, + GpsStatus = 0x0009, + GpsMeasureMode = 0x000A, + GpsDop = 0x000B, + GpsSpeedRef = 0x000C, + GpsSpeed = 0x000D, + GpsTrackRef = 0x000E, + GpsTrack = 0x000F, + GpsImageDirectionRef = 0x0010, + GpsImageDirection = 0x0011, + GpsMapDatum = 0x0012, + GpsDestLatitudeRef = 0x0013, + GpsDestLatitude = 0x0014, + GpsDestLongitudeRef = 0x0015, + GpsDestLongitude = 0x0016, + GpsDestBearingRef = 0x0017, + GpsDestBearing = 0x0018, + GpsDestDistanceRef = 0x0019, + GpsDestDistance = 0x001A, + GpsProcessingMethod = 0x001B, + GpsAreaInformation = 0x001C, + GpsDateStamp = 0x001D, + GpsDifferential = 0x001E + }; - ExposureTime = 0x829A, - FNumber = 0x829D, - ExposureProgram = 0x8822, - SpectralSensitivity = 0x8824, - ISOSpeedRatings = 0x8827, - Oecf = 0x8828, - ShutterSpeedValue = 0x9201, - ApertureValue = 0x9202, - BrightnessValue = 0x9203, - ExposureBiasValue = 0x9204, - MaxApertureValue = 0x9205, - SubjectDistance = 0x9206, - MeteringMode = 0x9207, - LightSource = 0x9208, - Flash = 0x9209, - FocalLength = 0x920A, - SubjectArea = 0x9214, - FlashEnergy = 0xA20B, - SpatialFrequencyResponse = 0xA20C, - FocalPlaneXResolution = 0xA20E, - FocalPlaneYResolution = 0xA20F, - FocalPlaneResolutionUnit = 0xA210, - SubjectLocation = 0xA214, - ExposureIndex = 0xA215, - SensingMethod = 0xA217, - FileSource = 0xA300, - SceneType = 0xA301, - CfaPattern = 0xA302, - CustomRendered = 0xA401, - ExposureMode = 0xA402, - WhiteBalance = 0xA403, - DigitalZoomRatio = 0xA404, - FocalLengthIn35mmFilm = 0xA405, - SceneCaptureType = 0xA406, - GainControl = 0xA407, - Contrast = 0xA408, - Saturation = 0xA409, - Sharpness = 0xA40A, - DeviceSettingDescription = 0xA40B, - SubjectDistanceRange = 0x40C - }; + QExifImageHeader (); + explicit QExifImageHeader (const QString &fileName); + ~QExifImageHeader (); - enum GpsTag - { - GpsVersionId = 0x0000, - GpsLatitudeRef = 0x0001, - GpsLatitude = 0x0002, - GpsLongitudeRef = 0x0003, - GpsLongitude = 0x0004, - GpsAltitudeRef = 0x0005, - GpsAltitude = 0x0006, - GpsTimeStamp = 0x0007, - GpsSatellites = 0x0008, - GpsStatus = 0x0009, - GpsMeasureMode = 0x000A, - GpsDop = 0x000B, - GpsSpeedRef = 0x000C, - GpsSpeed = 0x000D, - GpsTrackRef = 0x000E, - GpsTrack = 0x000F, - GpsImageDirectionRef = 0x0010, - GpsImageDirection = 0x0011, - GpsMapDatum = 0x0012, - GpsDestLatitudeRef = 0x0013, - GpsDestLatitude = 0x0014, - GpsDestLongitudeRef = 0x0015, - GpsDestLongitude = 0x0016, - GpsDestBearingRef = 0x0017, - GpsDestBearing = 0x0018, - GpsDestDistanceRef = 0x0019, - GpsDestDistance = 0x001A, - GpsProcessingMethod = 0x001B, - GpsAreaInformation = 0x001C, - GpsDateStamp = 0x001D, - GpsDifferential = 0x001E - }; + bool loadFromJpeg (const QString &fileName); + bool loadFromJpeg (QIODevice *device); + bool saveToJpeg (const QString &fileName) const; + bool saveToJpeg (QIODevice *device) const; - QExifImageHeader(); - explicit QExifImageHeader(const QString &fileName); - ~QExifImageHeader(); + bool read (QIODevice *device); + qint64 write (QIODevice *device) const; - bool loadFromJpeg(const QString &fileName); - bool loadFromJpeg(QIODevice *device); - bool saveToJpeg(const QString &fileName) const; - bool saveToJpeg(QIODevice *device) const; + qint64 size () const; - bool read(QIODevice *device); - qint64 write(QIODevice *device) const; + QSysInfo::Endian byteOrder () const; - qint64 size() const; + void clear (); - QSysInfo::Endian byteOrder() const; + QList imageTags () const; + QList extendedTags () const; + QList gpsTags () const; - void clear(); + bool contains (ImageTag tag) const; + bool contains (ExifExtendedTag tag) const; + bool contains (GpsTag tag) const; - QList imageTags() const; - QList extendedTags() const; - QList gpsTags() const; + void remove (ImageTag tag); + void remove (ExifExtendedTag tag); + void remove (GpsTag tag); - bool contains(ImageTag tag) const; - bool contains(ExifExtendedTag tag) const; - bool contains(GpsTag tag) const; + QExifValue value (ImageTag tag) const; + QExifValue value (ExifExtendedTag tag) const; + QExifValue value (GpsTag tag) const; - void remove(ImageTag tag); - void remove(ExifExtendedTag tag); - void remove(GpsTag tag); + void setValue (ImageTag tag, const QExifValue &value); + void setValue (ExifExtendedTag tag, const QExifValue &value); + void setValue (GpsTag tag, const QExifValue &value); - QExifValue value(ImageTag tag) const; - QExifValue value(ExifExtendedTag tag) const; - QExifValue value(GpsTag tag) const; - - void setValue(ImageTag tag, const QExifValue &value); - void setValue(ExifExtendedTag tag, const QExifValue &value); - void setValue(GpsTag tag, const QExifValue &value); - - QImage thumbnail() const; - void setThumbnail( const QImage &thumbnail ); + QImage thumbnail () const; + void setThumbnail (const QImage &thumbnail); private: - enum PrivateTag - { - ExifIfdPointer = 0x8769, - GpsInfoIfdPointer = 0x8825, - InteroperabilityIfdPointer = 0xA005, - JpegInterchangeFormat = 0x0201, - JpegInterchangeFormatLength = 0x0202 - }; + enum PrivateTag { + ExifIfdPointer = 0x8769, + GpsInfoIfdPointer = 0x8825, + InteroperabilityIfdPointer = 0xA005, + JpegInterchangeFormat = 0x0201, + JpegInterchangeFormatLength = 0x0202 + }; - QByteArray extractExif( QIODevice *device ) const; + QByteArray extractExif (QIODevice *device) const; - QList< ExifIfdHeader > readIfdHeaders( QDataStream &stream ) const; + QList readIfdHeaders (QDataStream &stream) const; - QExifValue readIfdValue(QDataStream &stream, int startPos, const ExifIfdHeader &header) const; - template QMap readIfdValues( - QDataStream &stream, int startPos, const QList &headers) const; - template QMap readIfdValues( - QDataStream &stream, int startPos, const QExifValue &pointer) const; + QExifValue readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const; + template + QMap readIfdValues (QDataStream &stream, int startPos, const QList &headers) const; + template + QMap readIfdValues (QDataStream &stream, int startPos, const QExifValue &pointer) const; - quint32 writeExifHeader(QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const; - void writeExifValue(QDataStream &stream, const QExifValue &value) const; + quint32 writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const; + void writeExifValue (QDataStream &stream, const QExifValue &value) const; - template quint32 writeExifHeaders( - QDataStream &stream, const QMap &values, quint32 offset) const; - template void writeExifValues( - QDataStream &target, const QMap &values) const; + template + quint32 writeExifHeaders (QDataStream &stream, const QMap &values, quint32 offset) const; + template + void writeExifValues (QDataStream &target, const QMap &values) const; - quint32 sizeOf(const QExifValue &value) const; + quint32 sizeOf (const QExifValue &value) const; - template quint32 calculateSize( - const QMap &values) const; + template + quint32 calculateSize (const QMap &values) const; - QExifImageHeaderPrivate *d; + QExifImageHeaderPrivate *d; }; -#endif +#endif // ifndef QEXIFIMAGEHEADER_H