Commit e249bc3e authored by Wescoeur's avatar Wescoeur

fix(QExifImageHeader): use app indentation

parent 8d46bcb1
...@@ -56,153 +56,136 @@ ...@@ -56,153 +56,136 @@
A synonym for \c QPair<qint32,qint32> representing a signed rational number as stored in EXIF A synonym for \c QPair<qint32,qint32> representing a signed rational number as stored in EXIF
headers. The first integer in the pair is the numerator and the second the denominator. headers. The first integer in the pair is the numerator and the second the denominator.
*/ */
/*! /*!
\typedef QExifURational \typedef QExifURational
A synonym for \c QPair<qint32,qint32> representing an unsigned rational number as stored in A synonym for \c QPair<qint32,qint32> representing an unsigned rational number as stored in
EXIF headers. The first integer in the pair is the numerator and the second the denominator. EXIF headers. The first integer in the pair is the numerator and the second the denominator.
*/ */
struct ExifIfdHeader struct ExifIfdHeader {
{
quint16 tag; quint16 tag;
quint16 type; quint16 type;
quint32 count; quint32 count;
union union {
{
quint32 offset; quint32 offset;
quint8 offsetBytes[ 4 ]; quint8 offsetBytes[4];
char offsetAscii[ 4 ]; char offsetAscii[4];
quint16 offsetShorts[ 2 ]; quint16 offsetShorts[2];
}; };
}; };
QDataStream &operator >>( QDataStream &stream, ExifIfdHeader &header ) QDataStream &operator>> (QDataStream &stream, ExifIfdHeader &header) {
{
stream >> header.tag; stream >> header.tag;
stream >> header.type; stream >> header.type;
stream >> header.count; stream >> header.count;
if( header.type == QExifValue::Byte && header.count <= 4 ) if (header.type == QExifValue::Byte && header.count <= 4) {
{ stream.readRawData(header.offsetAscii, 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::Ascii && header.count <= 4 ) } else if (header.type == QExifValue::Short && header.count <= 2) {
{ stream >> header.offsetShorts[0];
stream.readRawData( header.offsetAscii, 4 ); stream >> header.offsetShorts[1];
} } else {
else if( header.type == QExifValue::Short && header.count <= 2 )
{
stream >> header.offsetShorts[ 0 ];
stream >> header.offsetShorts[ 1 ];
}
else
{
stream >> header.offset; stream >> header.offset;
} }
return stream; return stream;
} }
class QExifValuePrivate : public QSharedData {
class QExifValuePrivate : public QSharedData
{
public: public:
QExifValuePrivate( quint16 t, int c ) QExifValuePrivate (quint16 t, int c)
: type( t ), count( c ) : type(t), count(c)
{} {}
virtual ~QExifValuePrivate(){}
virtual ~QExifValuePrivate () {}
quint16 type; quint16 type;
int count; int count;
}; };
class QExifByteValuePrivate : public QExifValuePrivate class QExifByteValuePrivate : public QExifValuePrivate {
{
public: public:
QExifByteValuePrivate() QExifByteValuePrivate ()
: QExifValuePrivate(QExifValue::Byte, 0) : QExifValuePrivate(QExifValue::Byte, 0) {
{ ref.ref(); } ref.ref();
QExifByteValuePrivate( const QVector< quint8 > &v ) }
: QExifValuePrivate( QExifValue::Byte, v.size() ), value( v )
QExifByteValuePrivate (const QVector<quint8> &v)
: QExifValuePrivate(QExifValue::Byte, v.size()), value(v)
{} {}
QVector< quint8 > value; QVector<quint8> value;
}; };
class QExifUndefinedValuePrivate : public QExifValuePrivate class QExifUndefinedValuePrivate : public QExifValuePrivate {
{
public: public:
QExifUndefinedValuePrivate( const QByteArray &v ) QExifUndefinedValuePrivate (const QByteArray &v)
: QExifValuePrivate( QExifValue::Undefined, v.size() ), value( v ) : QExifValuePrivate(QExifValue::Undefined, v.size()), value(v)
{} {}
QByteArray value; QByteArray value;
}; };
class QExifAsciiValuePrivate : public QExifValuePrivate class QExifAsciiValuePrivate : public QExifValuePrivate {
{
public: public:
QExifAsciiValuePrivate( const QString &v ) QExifAsciiValuePrivate (const QString &v)
: QExifValuePrivate( QExifValue::Ascii, v.size() + 1 ), value( v ) : QExifValuePrivate(QExifValue::Ascii, v.size() + 1), value(v)
{} {}
QString value; QString value;
}; };
class QExifShortValuePrivate : public QExifValuePrivate class QExifShortValuePrivate : public QExifValuePrivate {
{
public: public:
QExifShortValuePrivate( const QVector< quint16 > &v ) QExifShortValuePrivate (const QVector<quint16> &v)
: QExifValuePrivate( QExifValue::Short, v.size() ), value( v ) : QExifValuePrivate(QExifValue::Short, v.size()), value(v)
{} {}
QVector< quint16 > value; QVector<quint16> value;
}; };
class QExifLongValuePrivate : public QExifValuePrivate class QExifLongValuePrivate : public QExifValuePrivate {
{
public: public:
QExifLongValuePrivate( const QVector< quint32 > &v ) QExifLongValuePrivate (const QVector<quint32> &v)
: QExifValuePrivate( QExifValue::Long, v.size() ), value( v ) : QExifValuePrivate(QExifValue::Long, v.size()), value(v)
{} {}
QVector< quint32 > value; QVector<quint32> value;
}; };
class QExifSignedLongValuePrivate : public QExifValuePrivate class QExifSignedLongValuePrivate : public QExifValuePrivate {
{
public: public:
QExifSignedLongValuePrivate( const QVector< qint32 > &v ) QExifSignedLongValuePrivate (const QVector<qint32> &v)
: QExifValuePrivate( QExifValue::SignedLong, v.size() ), value( v ) : QExifValuePrivate(QExifValue::SignedLong, v.size()), value(v)
{} {}
QVector< qint32 > value; QVector<qint32> value;
}; };
class QExifRationalValuePrivate : public QExifValuePrivate class QExifRationalValuePrivate : public QExifValuePrivate {
{
public: public:
QExifRationalValuePrivate( const QVector< QExifURational > &v ) QExifRationalValuePrivate (const QVector<QExifURational> &v)
: QExifValuePrivate( QExifValue::Rational, v.size() ), value( v ) : QExifValuePrivate(QExifValue::Rational, v.size()), value(v)
{} {}
QVector< QExifURational > value; QVector<QExifURational> value;
}; };
class QExifSignedRationalValuePrivate : public QExifValuePrivate class QExifSignedRationalValuePrivate : public QExifValuePrivate {
{
public: public:
QExifSignedRationalValuePrivate( const QVector< QExifSRational > &v ) QExifSignedRationalValuePrivate (const QVector<QExifSRational> &v)
: QExifValuePrivate( QExifValue::SignedRational, v.size() ), value( v ) : QExifValuePrivate(QExifValue::SignedRational, v.size()), value(v)
{} {}
QVector< QExifSRational > value; QVector<QExifSRational> value;
}; };
Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) Q_GLOBAL_STATIC(QExifByteValuePrivate, qExifValuePrivateSharedNull)
/*! /*!
\class QExifValue \class QExifValue
...@@ -228,7 +211,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) ...@@ -228,7 +211,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull)
\sa QExifImageHeader \sa QExifImageHeader
\preliminary \preliminary
*/ */
/*! /*!
\enum QExifValue::Type \enum QExifValue::Type
...@@ -243,7 +226,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) ...@@ -243,7 +226,7 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull)
\value Undefined An array of 8 bit integers. \value Undefined An array of 8 bit integers.
\value SignedLong A signed 32 bit integer. \value SignedLong A signed 32 bit integer.
\value SignedRational Two signed 32 bit integers representing the numerator and denominator of a signed rational number. \value SignedRational Two signed 32 bit integers representing the numerator and denominator of a signed rational number.
*/ */
/*! /*!
\enum QExifValue::TextEncoding \enum QExifValue::TextEncoding
...@@ -255,179 +238,158 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull) ...@@ -255,179 +238,158 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull)
\value JisEncoding A JIS X208-1990 string of Undefined type. \value JisEncoding A JIS X208-1990 string of Undefined type.
\value UnicodeEncoding A Unicode 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. \value UndefinedEncoding An unspecified string encoding of Undefined type. Assumed to be the local 8-bit encoding.
*/ */
/*! /*!
Constructs a null QExifValue. Constructs a null QExifValue.
*/ */
QExifValue::QExifValue() QExifValue::QExifValue ()
: d( qExifValuePrivateSharedNull() ) : d(qExifValuePrivateSharedNull())
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type Byte. Constructs a QExifValue with a \a value of type Byte.
*/ */
QExifValue::QExifValue( quint8 value ) QExifValue::QExifValue (quint8 value)
: d( new QExifByteValuePrivate( QVector< quint8 >( 1, value ) ) ) : d(new QExifByteValuePrivate(QVector<quint8>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type Byte. Constructs a QExifValue with an array of \a values of type Byte.
*/ */
QExifValue::QExifValue( const QVector< quint8 > &values ) QExifValue::QExifValue (const QVector<quint8> &values)
: d( new QExifByteValuePrivate( values ) ) : d(new QExifByteValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type Ascii or Undefined. 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 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. encoded using the given \a encoding.
*/ */
QExifValue::QExifValue( const QString &value, TextEncoding encoding ) QExifValue::QExifValue (const QString &value, TextEncoding encoding)
: d( qExifValuePrivateSharedNull() ) : d(qExifValuePrivateSharedNull()) {
{ switch (encoding) {
switch( encoding )
{
case AsciiEncoding: case AsciiEncoding:
d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "ASCII\0\0\0", 8 ) + value.toUtf8() ); d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("ASCII\0\0\0", 8) + value.toUtf8());
break; break;
case JisEncoding: case JisEncoding: {
{ QTextCodec *codec = QTextCodec::codecForName("JIS X 0208");
QTextCodec *codec = QTextCodec::codecForName( "JIS X 0208" ); if (codec)
if( codec ) d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("JIS\0\0\0\0\0", 8) + codec->fromUnicode(value));
d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "JIS\0\0\0\0\0", 8 ) + codec->fromUnicode( value ) );
} }
break; break;
case UnicodeEncoding: case UnicodeEncoding: {
{ QTextCodec *codec = QTextCodec::codecForName("UTF-16");
QTextCodec *codec = QTextCodec::codecForName( "UTF-16" ); if (codec)
if( codec ) d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("UNICODE\0", 8) + codec->fromUnicode(value));
d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "UNICODE\0", 8 ) + codec->fromUnicode( value ) );
} }
break; break;
case UndefinedEncoding: case UndefinedEncoding:
d = new QExifUndefinedValuePrivate( QByteArray::fromRawData( "\0\0\0\0\0\0\0\\0", 8 ) + value.toLocal8Bit() ); d = new QExifUndefinedValuePrivate(QByteArray::fromRawData("\0\0\0\0\0\0\0\\0", 8) + value.toLocal8Bit());
break; break;
default: default:
d = new QExifAsciiValuePrivate( value ); d = new QExifAsciiValuePrivate(value);
} }
} }
/*! /*!
Constructs a QExifValue with a \a value of type Short. Constructs a QExifValue with a \a value of type Short.
*/ */
QExifValue::QExifValue( quint16 value ) QExifValue::QExifValue (quint16 value)
: d( new QExifShortValuePrivate( QVector< quint16 >( 1, value ) ) ) : d(new QExifShortValuePrivate(QVector<quint16>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type Short. Constructs a QExifValue with an array of \a values of type Short.
*/ */
QExifValue::QExifValue( const QVector< quint16 > &values ) QExifValue::QExifValue (const QVector<quint16> &values)
: d( new QExifShortValuePrivate( values ) ) : d(new QExifShortValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type Long. Constructs a QExifValue with a \a value of type Long.
*/ */
QExifValue::QExifValue( quint32 value ) QExifValue::QExifValue (quint32 value)
: d( new QExifLongValuePrivate( QVector< quint32 >( 1, value ) ) ) : d(new QExifLongValuePrivate(QVector<quint32>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type Long. Constructs a QExifValue with an array of \a values of type Long.
*/ */
QExifValue::QExifValue( const QVector< quint32 > &values ) QExifValue::QExifValue (const QVector<quint32> &values)
: d( new QExifLongValuePrivate( values ) ) : d(new QExifLongValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type Rational. Constructs a QExifValue with a \a value of type Rational.
*/ */
QExifValue::QExifValue( const QExifURational &value ) QExifValue::QExifValue (const QExifURational &value)
: d( new QExifRationalValuePrivate( QVector< QExifURational >( 1, value ) ) ) : d(new QExifRationalValuePrivate(QVector<QExifURational>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type Rational. Constructs a QExifValue with an array of \a values of type Rational.
*/ */
QExifValue::QExifValue( const QVector< QExifURational > &values ) QExifValue::QExifValue (const QVector<QExifURational> &values)
: d( new QExifRationalValuePrivate( values ) ) : d(new QExifRationalValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type Undefined. Constructs a QExifValue with a \a value of type Undefined.
*/ */
QExifValue::QExifValue( const QByteArray &value ) QExifValue::QExifValue (const QByteArray &value)
: d( new QExifUndefinedValuePrivate( value ) ) : d(new QExifUndefinedValuePrivate(value))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type SignedLong. Constructs a QExifValue with a \a value of type SignedLong.
*/ */
QExifValue::QExifValue( qint32 value ) QExifValue::QExifValue (qint32 value)
: d( new QExifSignedLongValuePrivate( QVector< qint32 >( 1, value ) ) ) : d(new QExifSignedLongValuePrivate(QVector<qint32>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type SignedLong. Constructs a QExifValue with an array of \a values of type SignedLong.
*/ */
QExifValue::QExifValue( const QVector< qint32 > &values ) QExifValue::QExifValue (const QVector<qint32> &values)
: d( new QExifSignedLongValuePrivate( values ) ) : d(new QExifSignedLongValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue with a \a value of type SignedRational. Constructs a QExifValue with a \a value of type SignedRational.
*/ */
QExifValue::QExifValue( const QExifSRational &value ) QExifValue::QExifValue (const QExifSRational &value)
: d( new QExifSignedRationalValuePrivate( QVector< QExifSRational >( 1, value ) ) ) : d(new QExifSignedRationalValuePrivate(QVector<QExifSRational>(1, value)))
{ {}
}
/*! /*!
Constructs a QExifValue with an array of \a values of type SignedRational. Constructs a QExifValue with an array of \a values of type SignedRational.
*/ */
QExifValue::QExifValue( const QVector< QExifSRational > &values ) QExifValue::QExifValue (const QVector<QExifSRational> &values)
: d( new QExifSignedRationalValuePrivate( values ) ) : d(new QExifSignedRationalValuePrivate(values))
{ {}
}
/*! /*!
Constructs a QExifValue of type Ascii with an ascii string formatted from a date-time \a value. 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}. Date-times are stored as strings in the format \c {yyyy:MM:dd HH:mm:ss}.
*/ */
QExifValue::QExifValue( const QDateTime &value ) QExifValue::QExifValue (const QDateTime &value)
: d( new QExifAsciiValuePrivate( value.toString( QLatin1String( "yyyy:MM:dd HH:mm:ss" ) ) ) ) : d(new QExifAsciiValuePrivate(value.toString(QLatin1String("yyyy:MM:dd HH:mm:ss"))))
{ {}
}
/*! /*!
Constructs a copy of the QExifValue \a other. Constructs a copy of the QExifValue \a other.
*/ */
QExifValue::QExifValue( const QExifValue &other ) QExifValue::QExifValue (const QExifValue &other)
: d( other.d ) : d(other.d)
{ {}
}
/*! /*!
Assigns the value of \a other to a QExifValue. Assigns the value of \a other to a QExifValue.
*/ */
QExifValue &QExifValue::operator =( const QExifValue &other ) QExifValue &QExifValue::operator= (const QExifValue &other) {
{
d = other.d; d = other.d;
return *this; return *this;
...@@ -435,60 +397,53 @@ QExifValue &QExifValue::operator =( const QExifValue &other ) ...@@ -435,60 +397,53 @@ QExifValue &QExifValue::operator =( const QExifValue &other )
/*! /*!
Destroys a QExifValue. Destroys a QExifValue.
*/ */
QExifValue::~QExifValue() QExifValue::~QExifValue ()
{ {}
}
/*! /*!
Compares a QExifValue to \a other. Returns true if they are the same value and false otherwise. Compares a QExifValue to \a other. Returns true if they are the same value and false otherwise.
*/ */
bool QExifValue::operator ==( const QExifValue &other ) const bool QExifValue::operator== (const QExifValue &other) const {
{
return d == other.d; return d == other.d;
} }
/*! /*!
Returns true if a QExifValue has a null value and false otherwise. Returns true if a QExifValue has a null value and false otherwise.
*/ */
bool QExifValue::isNull() const bool QExifValue::isNull () const {
{
return d == qExifValuePrivateSharedNull(); return d == qExifValuePrivateSharedNull();
} }
/*! /*!
Returns the type of a QExifValue. Returns the type of a QExifValue.
*/ */
int QExifValue::type() const int QExifValue::type () const {
{
return d->type; return d->type;
} }
/*! /*!
Returns the number of elements in a QExifValue. For ascii strings this is the length of the string Returns the number of elements in a QExifValue. For ascii strings this is the length of the string
including the terminating null. including the terminating null.
*/ */
int QExifValue::count() const int QExifValue::count () const {
{
return d->count; return d->count;
} }
/*! /*!
Returns the encoding of strings stored in Undefined values. Returns the encoding of strings stored in Undefined values.
*/ */
QExifValue::TextEncoding QExifValue::encoding() const QExifValue::TextEncoding QExifValue::encoding () const {
{ if (d->type == Undefined && d->count > 8) {
if( d->type == Undefined && d->count > 8 ) QByteArray value = static_cast<const QExifUndefinedValuePrivate *>(d.constData())->value;
{
QByteArray value = static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value;
if( value.startsWith( QByteArray::fromRawData( "ASCII\0\0\0", 8 ) ) ) if (value.startsWith(QByteArray::fromRawData("ASCII\0\0\0", 8)))
return AsciiEncoding; return AsciiEncoding;
else if( value.startsWith( QByteArray::fromRawData( "JIS\0\0\0\0\0", 8 ) ) ) else if (value.startsWith(QByteArray::fromRawData("JIS\0\0\0\0\0", 8)))
return JisEncoding; return JisEncoding;
else if( value.startsWith( QByteArray::fromRawData( "UNICODE\0", 8 ) ) ) else if (value.startsWith(QByteArray::fromRawData("UNICODE\0", 8)))
return UnicodeEncoding; return UnicodeEncoding;
else if( value.startsWith( QByteArray::fromRawData( "\0\0\0\0\0\0\0\0", 8 ) ) ) else if (value.startsWith(QByteArray::fromRawData("\0\0\0\0\0\0\0\0", 8)))
return UndefinedEncoding; return UndefinedEncoding;
} }
return NoEncoding; return NoEncoding;
...@@ -496,56 +451,48 @@ QExifValue::TextEncoding QExifValue::encoding() const ...@@ -496,56 +451,48 @@ QExifValue::TextEncoding QExifValue::encoding() const
/*! /*!
Returns the value of a single element QExifValue of type Byte. Returns the value of a single element QExifValue of type Byte.
*/ */
quint8 QExifValue::toByte() const quint8 QExifValue::toByte () const {
{
return d->type == Byte && d->count == 1 return d->type == Byte && d->count == 1
? static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ) ? static_cast<const QExifByteValuePrivate *>(d.constData())->value.at(0)
: 0; : 0;
} }
/*! /*!
Returns the value of a multiple element QExifValue of type Byte. Returns the value of a multiple element QExifValue of type Byte.
*/ */
QVector< quint8 > QExifValue::toByteVector() const QVector<quint8> QExifValue::toByteVector () const {
{
return d->type == Byte return d->type == Byte
? static_cast< const QExifByteValuePrivate * >( d.constData() )->value ? static_cast<const QExifByteValuePrivate *>(d.constData())->value
: QVector< quint8 >(); : QVector<quint8>();
} }
/*! /*!
Returns the value of a QExifValue of type Ascii. Returns the value of a QExifValue of type Ascii.
*/ */
QString QExifValue::toString() const QString QExifValue::toString () const {
{ switch (d->type) {
switch( d->type )
{
case Ascii: case Ascii:
return static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value; return static_cast<const QExifAsciiValuePrivate *>(d.constData())->value;
case Undefined: case Undefined: {
{ QByteArray string = static_cast<const QExifUndefinedValuePrivate *>(d.constData())->value.mid(8);
QByteArray string = static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value.mid( 8 );
switch( encoding() ) switch (encoding()) {
{
case AsciiEncoding: case AsciiEncoding:
return QString::fromUtf8( string.constData(), string.length() ); return QString::fromUtf8(string.constData(), string.length());
case JisEncoding: case JisEncoding: {
{ QTextCodec *codec = QTextCodec::codecForName("JIS X 0208");
QTextCodec *codec = QTextCodec::codecForName( "JIS X 0208" ); if (codec)
if( codec ) return codec->toUnicode(string);
return codec->toUnicode( string );
} }
break; break;
case UnicodeEncoding: case UnicodeEncoding: {
{ QTextCodec *codec = QTextCodec::codecForName("UTF-16");
QTextCodec *codec = QTextCodec::codecForName( "UTF-16" ); if (codec)
if( codec ) return codec->toUnicode(string);
return codec->toUnicode( string );
} }
case UndefinedEncoding: case UndefinedEncoding:
return QString::fromLocal8Bit( string.constData(), string.length() ); return QString::fromLocal8Bit(string.constData(), string.length());
default: default:
break; break;
} }
...@@ -557,17 +504,14 @@ QString QExifValue::toString() const ...@@ -557,17 +504,14 @@ QString QExifValue::toString() const
/*! /*!
Returns the value of a single element QExifValue of type Byte or Short. Returns the value of a single element QExifValue of type Byte or Short.
*/ */
quint16 QExifValue::toShort() const quint16 QExifValue::toShort () const {
{ if (d->count == 1) {
if( d->count == 1 ) switch (d->type) {
{
switch( d->type )
{
case Byte: case Byte:
return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifByteValuePrivate *>(d.constData())->value.at(0);
case Short: case Short:
return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifShortValuePrivate *>(d.constData())->value.at(0);
} }
} }
return 0; return 0;
...@@ -575,31 +519,27 @@ quint16 QExifValue::toShort() const ...@@ -575,31 +519,27 @@ quint16 QExifValue::toShort() const
/*! /*!
Returns the value of a single element QExifValue of type Short. Returns the value of a single element QExifValue of type Short.
*/ */
QVector< quint16 > QExifValue::toShortVector() const QVector<quint16> QExifValue::toShortVector () const {
{
return d->type == Short return d->type == Short
? static_cast< const QExifShortValuePrivate * >( d.constData() )->value ? static_cast<const QExifShortValuePrivate *>(d.constData())->value
: QVector< quint16 >(); : QVector<quint16>();
} }
/*! /*!
Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong.
*/ */
quint32 QExifValue::toLong() const quint32 QExifValue::toLong () const {
{ if (d->count == 1) {
if( d->count == 1 ) switch (d->type) {
{
switch( d->type )
{
case Byte: case Byte:
return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifByteValuePrivate *>(d.constData())->value.at(0);
case Short: case Short:
return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifShortValuePrivate *>(d.constData())->value.at(0);
case Long: case Long:
return static_cast< const QExifLongValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifLongValuePrivate *>(d.constData())->value.at(0);
case SignedLong: case SignedLong:
return static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifSignedLongValuePrivate *>(d.constData())->value.at(0);
} }
} }
return 0; return 0;
...@@ -607,45 +547,40 @@ quint32 QExifValue::toLong() const ...@@ -607,45 +547,40 @@ quint32 QExifValue::toLong() const
/*! /*!
Returns the value of a multiple element QExifValue of type Long. Returns the value of a multiple element QExifValue of type Long.
*/ */
QVector< quint32 > QExifValue::toLongVector() const QVector<quint32> QExifValue::toLongVector () const {
{
return d->type == Long return d->type == Long
? static_cast< const QExifLongValuePrivate * >( d.constData() )->value ? static_cast<const QExifLongValuePrivate *>(d.constData())->value
: QVector< quint32 >(); : QVector<quint32>();
} }
/*! /*!
Returns the value of a multiple element QExifValue of type Rational. Returns the value of a multiple element QExifValue of type Rational.
*/ */
QExifURational QExifValue::toRational() const QExifURational QExifValue::toRational () const {
{
return d->type == Rational && d->count == 1 return d->type == Rational && d->count == 1
? static_cast< const QExifRationalValuePrivate * >( d.constData() )->value.at( 0 ) ? static_cast<const QExifRationalValuePrivate *>(d.constData())->value.at(0)
: QExifURational(); : QExifURational();
} }
/*! /*!
Returns the value of a multiple element QExifValue of type Rational. Returns the value of a multiple element QExifValue of type Rational.
*/ */
QVector< QExifURational > QExifValue::toRationalVector() const QVector<QExifURational> QExifValue::toRationalVector () const {
{
return d->type == Rational return d->type == Rational
? static_cast< const QExifRationalValuePrivate * >( d.constData() )->value ? static_cast<const QExifRationalValuePrivate *>(d.constData())->value
: QVector< QExifURational >(); : QVector<QExifURational>();
} }
/*! /*!
Returns the value of a QExifValue of type Undefined. Returns the value of a QExifValue of type Undefined.
*/ */
QByteArray QExifValue::toByteArray() const QByteArray QExifValue::toByteArray () const {
{ switch (d->type) {
switch( d->type )
{
case Ascii: case Ascii:
return static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value.toUtf8(); return static_cast<const QExifAsciiValuePrivate *>(d.constData())->value.toUtf8();
case Undefined: case Undefined:
return static_cast< const QExifUndefinedValuePrivate * >( d.constData() )->value; return static_cast<const QExifUndefinedValuePrivate *>(d.constData())->value;
default: default:
return QByteArray(); return QByteArray();
} }
...@@ -653,21 +588,18 @@ QByteArray QExifValue::toByteArray() const ...@@ -653,21 +588,18 @@ QByteArray QExifValue::toByteArray() const
/*! /*!
Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong. Returns the value of a single element QExifValue of type Byte, Short, Long, or SignedLong.
*/ */
qint32 QExifValue::toSignedLong() const qint32 QExifValue::toSignedLong () const {
{ if (d->count == 1) {
if( d->count == 1 ) switch (d->type) {
{
switch( d->type )
{
case Byte: case Byte:
return static_cast< const QExifByteValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifByteValuePrivate *>(d.constData())->value.at(0);
case Short: case Short:
return static_cast< const QExifShortValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifShortValuePrivate *>(d.constData())->value.at(0);
case Long: case Long:
return static_cast< const QExifLongValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifLongValuePrivate *>(d.constData())->value.at(0);
case SignedLong: case SignedLong:
return static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value.at( 0 ); return static_cast<const QExifSignedLongValuePrivate *>(d.constData())->value.at(0);
} }
} }
return 0; return 0;
...@@ -675,54 +607,49 @@ qint32 QExifValue::toSignedLong() const ...@@ -675,54 +607,49 @@ qint32 QExifValue::toSignedLong() const
/*! /*!
Returns the value of a multiple element QExifValue of type SignedLong. Returns the value of a multiple element QExifValue of type SignedLong.
*/ */
QVector< qint32 > QExifValue::toSignedLongVector() const QVector<qint32> QExifValue::toSignedLongVector () const {
{
return d->type == SignedLong return d->type == SignedLong
? static_cast< const QExifSignedLongValuePrivate * >( d.constData() )->value ? static_cast<const QExifSignedLongValuePrivate *>(d.constData())->value
: QVector< qint32 >(); : QVector<qint32>();
} }
/*! /*!
Returns the value of a single element QExifValue of type SignedRational. Returns the value of a single element QExifValue of type SignedRational.
*/ */
QExifSRational QExifValue::toSignedRational() const QExifSRational QExifValue::toSignedRational () const {
{
return d->type == SignedRational && d->count == 1 return d->type == SignedRational && d->count == 1
? static_cast< const QExifSignedRationalValuePrivate * >( d.constData() )->value.at( 0 ) ? static_cast<const QExifSignedRationalValuePrivate *>(d.constData())->value.at(0)
: QExifSRational(); : QExifSRational();
} }
/*! /*!
Returns the value of a multiple element QExifValue of type SignedRational. Returns the value of a multiple element QExifValue of type SignedRational.
*/ */
QVector< QExifSRational > QExifValue::toSignedRationalVector() const QVector<QExifSRational> QExifValue::toSignedRationalVector () const {
{
return d->type == SignedRational return d->type == SignedRational
? static_cast< const QExifSignedRationalValuePrivate * >( d.constData() )->value ? static_cast<const QExifSignedRationalValuePrivate *>(d.constData())->value
: QVector< QExifSRational >(); : QVector<QExifSRational>();
} }
/*! /*!
Returns the value of QExifValue storing a date-time. 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}. Date-times are stored as ascii strings in the format \c {yyyy:MM:dd HH:mm:ss}.
*/ */
QDateTime QExifValue::toDateTime() const QDateTime QExifValue::toDateTime () const {
{
return d->type == Ascii && d->count == 20 return d->type == Ascii && d->count == 20
? QDateTime::fromString( static_cast< const QExifAsciiValuePrivate * >( d.constData() )->value, QLatin1String( "yyyy:MM:dd HH:mm:ss" ) ) ? QDateTime::fromString(static_cast<const QExifAsciiValuePrivate *>(d.constData())->value, QLatin1String("yyyy:MM:dd HH:mm:ss"))
: QDateTime(); : QDateTime();
} }
class QExifImageHeaderPrivate class QExifImageHeaderPrivate {
{
public: public:
QSysInfo::Endian byteOrder; QSysInfo::Endian byteOrder;
mutable qint64 size; mutable qint64 size;
QMap<QExifImageHeader::ImageTag, QExifValue > imageIfdValues; QMap<QExifImageHeader::ImageTag, QExifValue> imageIfdValues;
QMap<QExifImageHeader::ExifExtendedTag, QExifValue > exifIfdValues; QMap<QExifImageHeader::ExifExtendedTag, QExifValue> exifIfdValues;
QMap<QExifImageHeader::GpsTag, QExifValue > gpsIfdValues; QMap<QExifImageHeader::GpsTag, QExifValue> gpsIfdValues;
QSize thumbnailSize; QSize thumbnailSize;
QByteArray thumbnailData; QByteArray thumbnailData;
...@@ -752,7 +679,7 @@ public: ...@@ -752,7 +679,7 @@ public:
EXIF header data itself. EXIF header data itself.
\preliminary \preliminary
*/ */
/*! /*!
\enum QExifImageHeader::ImageTag \enum QExifImageHeader::ImageTag
...@@ -785,7 +712,7 @@ public: ...@@ -785,7 +712,7 @@ public:
\value Software \value Software
\value Artist \value Artist
\value Copyright \value Copyright
*/ */
/*! /*!
\enum QExifImageHeader::ExifExtendedTag \enum QExifImageHeader::ExifExtendedTag
...@@ -847,7 +774,7 @@ public: ...@@ -847,7 +774,7 @@ public:
\value Sharpness \value Sharpness
\value DeviceSettingDescription \value DeviceSettingDescription
\value SubjectDistanceRange \value SubjectDistanceRange
*/ */
/*! /*!
\enum QExifImageHeader::GpsTag \enum QExifImageHeader::GpsTag
...@@ -884,24 +811,22 @@ public: ...@@ -884,24 +811,22 @@ public:
\value GpsAreaInformation \value GpsAreaInformation
\value GpsDateStamp \value GpsDateStamp
\value GpsDifferential \value GpsDifferential
*/ */
/*! /*!
Constructs a new EXIF image data editor. Constructs a new EXIF image data editor.
*/ */
QExifImageHeader::QExifImageHeader() QExifImageHeader::QExifImageHeader ()
: d( new QExifImageHeaderPrivate ) : d(new QExifImageHeaderPrivate) {
{
d->byteOrder = QSysInfo::ByteOrder; d->byteOrder = QSysInfo::ByteOrder;
d->size = -1; d->size = -1;
} }
/*! /*!
Constructs a new EXIF image data editor and reads the meta-data from a JPEG image with the given \a fileName. 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) QExifImageHeader::QExifImageHeader (const QString &fileName)
: d(new QExifImageHeaderPrivate) : d(new QExifImageHeaderPrivate) {
{
d->byteOrder = QSysInfo::ByteOrder; d->byteOrder = QSysInfo::ByteOrder;
d->size = -1; d->size = -1;
...@@ -910,9 +835,8 @@ QExifImageHeader::QExifImageHeader(const QString &fileName) ...@@ -910,9 +835,8 @@ QExifImageHeader::QExifImageHeader(const QString &fileName)
/*! /*!
Destroys an EXIF image data editor. Destroys an EXIF image data editor.
*/ */
QExifImageHeader::~QExifImageHeader() QExifImageHeader::~QExifImageHeader () {
{
clear(); clear();
delete d; delete d;
...@@ -922,12 +846,11 @@ QExifImageHeader::~QExifImageHeader() ...@@ -922,12 +846,11 @@ QExifImageHeader::~QExifImageHeader()
Reads meta-data from a JPEG image with the given \a fileName. Reads meta-data from a JPEG image with the given \a fileName.
Returns true if the data was successfully parsed and false otherwise. Returns true if the data was successfully parsed and false otherwise.
*/ */
bool QExifImageHeader::loadFromJpeg(const QString &fileName) bool QExifImageHeader::loadFromJpeg (const QString &fileName) {
{
QFile file(fileName); QFile file(fileName);
if(file.open(QIODevice::ReadOnly)) if (file.open(QIODevice::ReadOnly))
return loadFromJpeg(&file); return loadFromJpeg(&file);
else else
return false; return false;
...@@ -937,9 +860,8 @@ bool QExifImageHeader::loadFromJpeg(const QString &fileName) ...@@ -937,9 +860,8 @@ bool QExifImageHeader::loadFromJpeg(const QString &fileName)
Reads meta-data from an I/O \a device containing a JPEG image. Reads meta-data from an I/O \a device containing a JPEG image.
Returns true if the data was successfully parsed and false otherwise. Returns true if the data was successfully parsed and false otherwise.
*/ */
bool QExifImageHeader::loadFromJpeg(QIODevice *device) bool QExifImageHeader::loadFromJpeg (QIODevice *device) {
{
clear(); clear();
QByteArray exifData = extractExif(device); QByteArray exifData = extractExif(device);
...@@ -957,9 +879,8 @@ bool QExifImageHeader::loadFromJpeg(QIODevice *device) ...@@ -957,9 +879,8 @@ bool QExifImageHeader::loadFromJpeg(QIODevice *device)
Saves meta-data to a JPEG image with the given \a fileName. Saves meta-data to a JPEG image with the given \a fileName.
Returns true if the data was successfully written. Returns true if the data was successfully written.
*/ */
bool QExifImageHeader::saveToJpeg(const QString &fileName) const bool QExifImageHeader::saveToJpeg (const QString &fileName) const {
{
QFile file(fileName); QFile file(fileName);
if (file.open(QIODevice::ReadWrite)) if (file.open(QIODevice::ReadWrite))
...@@ -974,32 +895,31 @@ bool QExifImageHeader::saveToJpeg(const QString &fileName) const ...@@ -974,32 +895,31 @@ bool QExifImageHeader::saveToJpeg(const QString &fileName) const
The device must be non-sequential and already contain a valid JPEG image. The device must be non-sequential and already contain a valid JPEG image.
Returns true if the data was successfully written. Returns true if the data was successfully written.
*/ */
bool QExifImageHeader::saveToJpeg(QIODevice *device) const bool QExifImageHeader::saveToJpeg (QIODevice *device) const {
{ if (device->isSequential())
if( device->isSequential() )
return false; return false;
QByteArray exif; QByteArray exif;
{ {
QBuffer buffer( &exif ); QBuffer buffer(&exif);
if( !buffer.open( QIODevice::WriteOnly ) ) if (!buffer.open(QIODevice::WriteOnly))
return false; 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. if (device->read(2) != "\xFF\xD8") // Not a valid JPEG image.
return false; return false;
quint16 segmentId; quint16 segmentId;
...@@ -1008,95 +928,87 @@ bool QExifImageHeader::saveToJpeg(QIODevice *device) const ...@@ -1008,95 +928,87 @@ bool QExifImageHeader::saveToJpeg(QIODevice *device) const
stream >> segmentId; stream >> segmentId;
stream >> segmentLength; stream >> segmentLength;
if( segmentId == 0xFFE0 ) if (segmentId == 0xFFE0) {
{ QByteArray jfif = device->read(segmentLength - 2);
QByteArray jfif = device->read( segmentLength - 2 );
if( !jfif.startsWith( "JFIF" ) ) if (!jfif.startsWith("JFIF"))
return false; return false;
stream >> segmentId; stream >> segmentId;
stream >> segmentLength; stream >> segmentLength;
if( segmentId == 0xFFE1 ) if (segmentId == 0xFFE1) {
{ QByteArray oldExif = device->read(segmentLength - 2);
QByteArray oldExif = device->read( segmentLength - 2 );
if( !oldExif.startsWith( "Exif" ) ) if (!oldExif.startsWith("Exif"))
return false; return false;
int dSize = oldExif.size() - exif.size(); int dSize = oldExif.size() - exif.size();
if( dSize > 0 ) if (dSize > 0)
exif += QByteArray( 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(0xFFD8); // SOI
stream << quint16( 0xFFE0 ); // APP0 stream << quint16(0xFFE0); // APP0
stream << quint16( jfif.size() + 2 ); stream << quint16(jfif.size() + 2);
device->write( jfif ); device->write(jfif);
stream << quint16( 0xFFE1 ); //APP1 stream << quint16(0xFFE1); // APP1
stream << quint16( exif.size() + 2 ); stream << quint16(exif.size() + 2);
device->write( exif ); device->write(exif);
device->write( remainder ); device->write(remainder);
} } else {
else
{
QByteArray remainder = device->readAll(); QByteArray remainder = device->readAll();
device->seek( 0 ); device->seek(0);
stream << quint16( 0xFFD8 ); // SOI stream << quint16(0xFFD8); // SOI
stream << quint16( 0xFFE0 ); // APP0 stream << quint16(0xFFE0); // APP0
stream << quint16( jfif.size() + 2 ); stream << quint16(jfif.size() + 2);
device->write( jfif ); device->write(jfif);
stream << quint16( 0xFFE1 ); //APP1 stream << quint16(0xFFE1); // APP1
stream << quint16( exif.size() + 2 ); stream << quint16(exif.size() + 2);
device->write( exif ); device->write(exif);
stream << quint16( 0xFFE0 ); // APP0 stream << quint16(0xFFE0); // APP0
stream << segmentId; stream << segmentId;
stream << segmentLength; stream << segmentLength;
device->write( remainder ); device->write(remainder);
}
} }
else if( segmentId == 0xFFE1 ) } else if (segmentId == 0xFFE1) {
{ QByteArray oldExif = device->read(segmentLength - 2);
QByteArray oldExif = device->read( segmentLength - 2 );
if( !oldExif.startsWith( "Exif" ) ) if (!oldExif.startsWith("Exif"))
return false; return false;
int dSize = oldExif.size() - exif.size(); int dSize = oldExif.size() - exif.size();
if( dSize > 0 ) if (dSize > 0)
exif += QByteArray( 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(0xFFD8); // SOI
stream << quint16( 0xFFE1 ); //APP1 stream << quint16(0xFFE1); // APP1
stream << quint16( exif.size() + 2 ); stream << quint16(exif.size() + 2);
device->write( exif ); device->write(exif);
device->write( remainder ); device->write(remainder);
} } else {
else
{
QByteArray remainder = device->readAll(); QByteArray remainder = device->readAll();
device->seek( 0 ); device->seek(0);
stream << quint16( 0xFFD8 ); // SOI stream << quint16(0xFFD8); // SOI
stream << quint16( 0xFFE1 ); //APP1 stream << quint16(0xFFE1); // APP1
stream << quint16( exif.size() + 2 ); stream << quint16(exif.size() + 2);
device->write( exif ); device->write(exif);
stream << segmentId; stream << segmentId;
stream << segmentLength; stream << segmentLength;
device->write( remainder ); device->write(remainder);
} }
return true; return true;
...@@ -1104,15 +1016,12 @@ bool QExifImageHeader::saveToJpeg(QIODevice *device) const ...@@ -1104,15 +1016,12 @@ bool QExifImageHeader::saveToJpeg(QIODevice *device) const
/*! /*!
Returns the byte order of EXIF file. Returns the byte order of EXIF file.
*/ */
QSysInfo::Endian QExifImageHeader::byteOrder() const QSysInfo::Endian QExifImageHeader::byteOrder () const {
{
return d->byteOrder; return d->byteOrder;
} }
quint32 QExifImageHeader::sizeOf (const QExifValue &value) const {
quint32 QExifImageHeader::sizeOf(const QExifValue &value) const
{
switch (value.type()) { switch (value.type()) {
case QExifValue::Byte: case QExifValue::Byte:
case QExifValue::Undefined: case QExifValue::Undefined:
...@@ -1142,12 +1051,11 @@ quint32 QExifImageHeader::sizeOf(const QExifValue &value) const ...@@ -1142,12 +1051,11 @@ quint32 QExifImageHeader::sizeOf(const QExifValue &value) const
} }
} }
template <typename T> template<typename T>
quint32 QExifImageHeader::calculateSize(const QMap<T, QExifValue> &values) const quint32 QExifImageHeader::calculateSize (const QMap<T, QExifValue> &values) const {
{
quint32 size = sizeof(quint16); quint32 size = sizeof(quint16);
foreach (const QExifValue &value, values) foreach(const QExifValue &value, values)
size += sizeOf(value); size += sizeOf(value);
return size; return size;
...@@ -1155,35 +1063,31 @@ quint32 QExifImageHeader::calculateSize(const QMap<T, QExifValue> &values) const ...@@ -1155,35 +1063,31 @@ quint32 QExifImageHeader::calculateSize(const QMap<T, QExifValue> &values) const
/*! /*!
Returns the size of EXIF data in bytes. Returns the size of EXIF data in bytes.
*/ */
qint64 QExifImageHeader::size() const qint64 QExifImageHeader::size () const {
{
if (d->size == -1) { if (d->size == -1) {
d->size d->size = 2 + // Byte Order
= 2 // Byte Order 2 + // Marker
+ 2 // Marker 4 + // Image Ifd offset
+ 4 // Image Ifd offset 12 + // ExifIfdPointer Ifd
+ 12 // ExifIfdPointer Ifd 4 + // Thumbnail Ifd offset
+ 4 // Thumbnail Ifd offset calculateSize(d->imageIfdValues) + // Image headers and values.
+ calculateSize(d->imageIfdValues) // Image headers and values. calculateSize(d->exifIfdValues); // Exif headers and values.
+ calculateSize(d->exifIfdValues); // Exif headers and values.
if (!d->gpsIfdValues.isEmpty()) { if (!d->gpsIfdValues.isEmpty()) {
d->size d->size += 12 + // GpsInfoIfdPointer Ifd
+= 12 // GpsInfoIfdPointer Ifd calculateSize(d->gpsIfdValues); // Gps headers and values.
+ calculateSize(d->gpsIfdValues); // Gps headers and values.
} }
if (!d->thumbnailData.isEmpty()) { if (!d->thumbnailData.isEmpty()) {
d->size d->size += 2 + // Thumbnail Ifd count
+= 2 // Thumbnail Ifd count 12 + // Compression Ifd
+ 12 // Compression Ifd 20 + // XResolution Ifd
+ 20 // XResolution Ifd 20 + // YResolution Ifd
+ 20 // YResolution Ifd 12 + // ResolutionUnit Ifd
+ 12 // ResolutionUnit Ifd 12 + // JpegInterchangeFormat Ifd
+ 12 // JpegInterchangeFormat Ifd 12 + // JpegInterchangeFormatLength Ifd
+ 12 // JpegInterchangeFormatLength Ifd d->thumbnailData.size(); // Thumbnail data size.
+ d->thumbnailData.size(); // Thumbnail data size.
} }
} }
...@@ -1192,9 +1096,8 @@ qint64 QExifImageHeader::size() const ...@@ -1192,9 +1096,8 @@ qint64 QExifImageHeader::size() const
/*! /*!
Clears all image meta-data. Clears all image meta-data.
*/ */
void QExifImageHeader::clear() void QExifImageHeader::clear () {
{
d->imageIfdValues.clear(); d->imageIfdValues.clear();
d->exifIfdValues.clear(); d->exifIfdValues.clear();
d->gpsIfdValues.clear(); d->gpsIfdValues.clear();
...@@ -1205,57 +1108,50 @@ void QExifImageHeader::clear() ...@@ -1205,57 +1108,50 @@ void QExifImageHeader::clear()
/*! /*!
Returns a list of all image tags in an EXIF header. Returns a list of all image tags in an EXIF header.
*/ */
QList<QExifImageHeader::ImageTag> QExifImageHeader::imageTags() const QList<QExifImageHeader::ImageTag> QExifImageHeader::imageTags () const {
{
return d->imageIfdValues.keys(); return d->imageIfdValues.keys();
} }
/*! /*!
Returns a list of all extended EXIF tags in a header. Returns a list of all extended EXIF tags in a header.
*/ */
QList<QExifImageHeader::ExifExtendedTag> QExifImageHeader::extendedTags() const QList<QExifImageHeader::ExifExtendedTag> QExifImageHeader::extendedTags () const {
{
return d->exifIfdValues.keys(); return d->exifIfdValues.keys();
} }
/*! /*!
Returns a list of all GPS tags in an EXIF header. Returns a list of all GPS tags in an EXIF header.
*/ */
QList<QExifImageHeader::GpsTag> QExifImageHeader::gpsTags() const QList<QExifImageHeader::GpsTag> QExifImageHeader::gpsTags () const {
{
return d->gpsIfdValues.keys(); return d->gpsIfdValues.keys();
} }
/*! /*!
Returns true if an EXIf header contains a value for an image \a tag and false otherwise. Returns true if an EXIf header contains a value for an image \a tag and false otherwise.
*/ */
bool QExifImageHeader::contains(ImageTag tag) const bool QExifImageHeader::contains (ImageTag tag) const {
{
return d->imageIfdValues.contains(tag); return d->imageIfdValues.contains(tag);
} }
/*! /*!
Returns true if a header contains a a value for an extended EXIF \a tag and false otherwise. Returns true if a header contains a a value for an extended EXIF \a tag and false otherwise.
*/ */
bool QExifImageHeader::contains(ExifExtendedTag tag) const bool QExifImageHeader::contains (ExifExtendedTag tag) const {
{
return d->exifIfdValues.contains(tag); return d->exifIfdValues.contains(tag);
} }
/*! /*!
Returns true if an EXIf header contains a value for a GPS \a tag and false otherwise. Returns true if an EXIf header contains a value for a GPS \a tag and false otherwise.
*/ */
bool QExifImageHeader::contains(GpsTag tag) const bool QExifImageHeader::contains (GpsTag tag) const {
{
return d->gpsIfdValues.contains(tag); return d->gpsIfdValues.contains(tag);
} }
/*! /*!
Removes the value for an image \a tag. Removes the value for an image \a tag.
*/ */
void QExifImageHeader::remove(ImageTag tag) void QExifImageHeader::remove (ImageTag tag) {
{
d->imageIfdValues.remove(tag); d->imageIfdValues.remove(tag);
d->size = -1; d->size = -1;
...@@ -1263,9 +1159,8 @@ void QExifImageHeader::remove(ImageTag tag) ...@@ -1263,9 +1159,8 @@ void QExifImageHeader::remove(ImageTag tag)
/*! /*!
Removes the value for an extended EXIF \a tag. Removes the value for an extended EXIF \a tag.
*/ */
void QExifImageHeader::remove(ExifExtendedTag tag) void QExifImageHeader::remove (ExifExtendedTag tag) {
{
d->exifIfdValues.remove(tag); d->exifIfdValues.remove(tag);
d->size = -1; d->size = -1;
...@@ -1273,9 +1168,8 @@ void QExifImageHeader::remove(ExifExtendedTag tag) ...@@ -1273,9 +1168,8 @@ void QExifImageHeader::remove(ExifExtendedTag tag)
/*! /*!
Removes the value for a GPS \a tag. Removes the value for a GPS \a tag.
*/ */
void QExifImageHeader::remove(GpsTag tag) void QExifImageHeader::remove (GpsTag tag) {
{
d->gpsIfdValues.remove(tag); d->gpsIfdValues.remove(tag);
d->size = -1; d->size = -1;
...@@ -1283,33 +1177,29 @@ void QExifImageHeader::remove(GpsTag tag) ...@@ -1283,33 +1177,29 @@ void QExifImageHeader::remove(GpsTag tag)
/*! /*!
Returns the value for an image \a tag. Returns the value for an image \a tag.
*/ */
QExifValue QExifImageHeader::value(ImageTag tag) const QExifValue QExifImageHeader::value (ImageTag tag) const {
{
return d->imageIfdValues.value(tag); return d->imageIfdValues.value(tag);
} }
/*! /*!
Returns the value for an extended EXIF \a tag. Returns the value for an extended EXIF \a tag.
*/ */
QExifValue QExifImageHeader::value(ExifExtendedTag tag) const QExifValue QExifImageHeader::value (ExifExtendedTag tag) const {
{
return d->exifIfdValues.value(tag); return d->exifIfdValues.value(tag);
} }
/*! /*!
Returns the value for a GPS tag. Returns the value for a GPS tag.
*/ */
QExifValue QExifImageHeader::value(GpsTag tag) const QExifValue QExifImageHeader::value (GpsTag tag) const {
{
return d->gpsIfdValues.value(tag); return d->gpsIfdValues.value(tag);
} }
/*! /*!
Sets the \a value for an image \a tag. Sets the \a value for an image \a tag.
*/ */
void QExifImageHeader::setValue(ImageTag tag, const QExifValue &value) void QExifImageHeader::setValue (ImageTag tag, const QExifValue &value) {
{
d->imageIfdValues[tag] = value; d->imageIfdValues[tag] = value;
d->size = -1; d->size = -1;
...@@ -1317,9 +1207,8 @@ void QExifImageHeader::setValue(ImageTag tag, const QExifValue &value) ...@@ -1317,9 +1207,8 @@ void QExifImageHeader::setValue(ImageTag tag, const QExifValue &value)
/*! /*!
Sets the \a value for an extended EXIF \a tag. Sets the \a value for an extended EXIF \a tag.
*/ */
void QExifImageHeader::setValue(ExifExtendedTag tag, const QExifValue &value) void QExifImageHeader::setValue (ExifExtendedTag tag, const QExifValue &value) {
{
d->exifIfdValues[tag] = value; d->exifIfdValues[tag] = value;
d->size = -1; d->size = -1;
...@@ -1327,9 +1216,8 @@ void QExifImageHeader::setValue(ExifExtendedTag tag, const QExifValue &value) ...@@ -1327,9 +1216,8 @@ void QExifImageHeader::setValue(ExifExtendedTag tag, const QExifValue &value)
/*! /*!
Sets the \a value for an GPS \a tag. Sets the \a value for an GPS \a tag.
*/ */
void QExifImageHeader::setValue(GpsTag tag, const QExifValue &value) void QExifImageHeader::setValue (GpsTag tag, const QExifValue &value) {
{
d->gpsIfdValues[tag] = value; d->gpsIfdValues[tag] = value;
d->size = -1; d->size = -1;
...@@ -1337,9 +1225,8 @@ void QExifImageHeader::setValue(GpsTag tag, const QExifValue &value) ...@@ -1337,9 +1225,8 @@ void QExifImageHeader::setValue(GpsTag tag, const QExifValue &value)
/*! /*!
Returns the image thumbnail. Returns the image thumbnail.
*/ */
QImage QExifImageHeader::thumbnail() const QImage QExifImageHeader::thumbnail () const {
{
QImage image; QImage image;
image.loadFromData(d->thumbnailData, "JPG"); image.loadFromData(d->thumbnailData, "JPG");
...@@ -1370,9 +1257,8 @@ QImage QExifImageHeader::thumbnail() const ...@@ -1370,9 +1257,8 @@ QImage QExifImageHeader::thumbnail() const
/*! /*!
Sets the image \a thumbnail. Sets the image \a thumbnail.
*/ */
void QExifImageHeader::setThumbnail( const QImage &thumbnail ) void QExifImageHeader::setThumbnail (const QImage &thumbnail) {
{
if (!thumbnail.isNull()) { if (!thumbnail.isNull()) {
QBuffer buffer; QBuffer buffer;
...@@ -1391,42 +1277,38 @@ void QExifImageHeader::setThumbnail( const QImage &thumbnail ) ...@@ -1391,42 +1277,38 @@ void QExifImageHeader::setThumbnail( const QImage &thumbnail )
d->size = -1; d->size = -1;
} }
QByteArray QExifImageHeader::extractExif( QIODevice *device ) const QByteArray QExifImageHeader::extractExif (QIODevice *device) const {
{ QDataStream stream(device);
QDataStream stream( device );
stream.setByteOrder( QDataStream::BigEndian ); stream.setByteOrder(QDataStream::BigEndian);
if( device->read( 2 ) != "\xFF\xD8" ) if (device->read(2) != "\xFF\xD8")
return QByteArray(); return QByteArray();
while( device->read( 2 ) != "\xFF\xE1" ) while (device->read(2) != "\xFF\xE1") {
{ if (device->atEnd())
if( device->atEnd() )
return QByteArray(); return QByteArray();
quint16 length; quint16 length;
stream >> length; stream >> length;
device->seek( device->pos() + length - 2 ); device->seek(device->pos() + length - 2);
} }
quint16 length; quint16 length;
stream >> length; stream >> length;
if( device->read( 4 ) != "Exif" ) if (device->read(4) != "Exif")
return QByteArray(); return QByteArray();
device->read( 2 ); device->read(2);
return device->read( length - 8 ); return device->read(length - 8);
} }
QList<ExifIfdHeader> QExifImageHeader::readIfdHeaders (QDataStream &stream) const {
QList<ExifIfdHeader> QExifImageHeader::readIfdHeaders(QDataStream &stream) const
{
QList<ExifIfdHeader> headers; QList<ExifIfdHeader> headers;
quint16 count; quint16 count;
...@@ -1444,12 +1326,10 @@ QList<ExifIfdHeader> QExifImageHeader::readIfdHeaders(QDataStream &stream) const ...@@ -1444,12 +1326,10 @@ QList<ExifIfdHeader> QExifImageHeader::readIfdHeaders(QDataStream &stream) const
return headers; return headers;
} }
QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, const ExifIfdHeader &header) const QExifValue QExifImageHeader::readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const {
{
switch (header.type) { switch (header.type) {
case QExifValue::Byte: case QExifValue::Byte: {
{ QVector<quint8> value(header.count);
QVector<quint8> value( header.count );
if (header.count > 4) { if (header.count > 4) {
stream.device()->seek(startPos + header.offset); stream.device()->seek(startPos + header.offset);
...@@ -1457,9 +1337,8 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1457,9 +1337,8 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
for (quint32 i = 0; i < header.count; i++) for (quint32 i = 0; i < header.count; i++)
stream >> value[i]; stream >> value[i];
} else { } else {
for( quint32 i = 0; i < header.count; i++ ) for (quint32 i = 0; i < header.count; i++)
value[ i ] = header.offsetBytes[ i ]; value[i] = header.offsetBytes[i];
} }
return QExifValue(value); return QExifValue(value);
} }
...@@ -1481,8 +1360,7 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1481,8 +1360,7 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
} else { } else {
return QExifValue(QString::fromUtf8(header.offsetAscii, header.count - 1)); return QExifValue(QString::fromUtf8(header.offsetAscii, header.count - 1));
} }
case QExifValue::Short: case QExifValue::Short: {
{
QVector<quint16> value(header.count); QVector<quint16> value(header.count);
if (header.count > 2) { if (header.count > 2) {
...@@ -1493,12 +1371,10 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1493,12 +1371,10 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
} else { } else {
for (quint32 i = 0; i < header.count; i++) for (quint32 i = 0; i < header.count; i++)
value[i] = header.offsetShorts[i]; value[i] = header.offsetShorts[i];
} }
return QExifValue(value); return QExifValue(value);
} }
case QExifValue::Long: case QExifValue::Long: {
{
QVector<quint32> value(header.count); QVector<quint32> value(header.count);
if (header.count > 1) { if (header.count > 1) {
...@@ -1506,13 +1382,12 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1506,13 +1382,12 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
for (quint32 i = 0; i < header.count; i++) for (quint32 i = 0; i < header.count; i++)
stream >> value[i]; stream >> value[i];
} else if(header.count == 1) { } else if (header.count == 1) {
value[0] = header.offset; value[0] = header.offset;
} }
return QExifValue(value); return QExifValue(value);
} }
case QExifValue::SignedLong: case QExifValue::SignedLong: {
{
QVector<qint32> value(header.count); QVector<qint32> value(header.count);
if (header.count > 1) { if (header.count > 1) {
...@@ -1526,8 +1401,7 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1526,8 +1401,7 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
return QExifValue(value); return QExifValue(value);
} }
break; break;
case QExifValue::Rational: case QExifValue::Rational: {
{
QVector<QExifURational> value(header.count); QVector<QExifURational> value(header.count);
stream.device()->seek(startPos + header.offset); stream.device()->seek(startPos + header.offset);
...@@ -1537,13 +1411,12 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1537,13 +1411,12 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
return QExifValue(value); return QExifValue(value);
} }
case QExifValue::SignedRational: case QExifValue::SignedRational: {
{
QVector<QExifSRational> value(header.count); QVector<QExifSRational> value(header.count);
stream.device()->seek(startPos + header.offset); stream.device()->seek(startPos + header.offset);
for(quint32 i = 0; i < header.count; i++) for (quint32 i = 0; i < header.count; i++)
stream >> value[i]; stream >> value[i];
return QExifValue(value); return QExifValue(value);
...@@ -1555,23 +1428,28 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con ...@@ -1555,23 +1428,28 @@ QExifValue QExifImageHeader::readIfdValue(QDataStream &stream, int startPos, con
} }
} }
template <typename T> QMap<T, QExifValue> QExifImageHeader::readIfdValues( template<typename T>
QDataStream &stream, int startPos, const QList<ExifIfdHeader> &headers) const QMap<T, QExifValue> QExifImageHeader::readIfdValues (
{ QDataStream &stream,
int startPos,
const QList<ExifIfdHeader> &headers
) const {
QMap<T, QExifValue> values; QMap<T, QExifValue> values;
// This needs to be non-const so it works with gcc3 // This needs to be non-const so it works with gcc3
QList<ExifIfdHeader> headers_ = headers; QList<ExifIfdHeader> headers_ = headers;
foreach (const ExifIfdHeader &header, headers_) foreach(const ExifIfdHeader &header, headers_)
values[T(header.tag)] = readIfdValue(stream, startPos, header); values[T(header.tag)] = readIfdValue(stream, startPos, header);
return values; return values;
} }
template <typename T> template<typename T>
QMap<T, QExifValue> QExifImageHeader::readIfdValues( QMap<T, QExifValue> QExifImageHeader::readIfdValues (
QDataStream &stream, int startPos, const QExifValue &pointer) const QDataStream &stream,
{ int startPos,
const QExifValue &pointer
) const {
if (pointer.type() == QExifValue::Long && pointer.count() == 1) { if (pointer.type() == QExifValue::Long && pointer.count() == 1) {
stream.device()->seek(startPos + pointer.toLong()); stream.device()->seek(startPos + pointer.toLong());
...@@ -1579,20 +1457,18 @@ QMap<T, QExifValue> QExifImageHeader::readIfdValues( ...@@ -1579,20 +1457,18 @@ QMap<T, QExifValue> QExifImageHeader::readIfdValues(
return readIfdValues<T>(stream, startPos, headers); return readIfdValues<T>(stream, startPos, headers);
} else { } else {
return QMap<T, QExifValue >(); return QMap<T, QExifValue>();
} }
} }
/*! /*!
Reads the contents of an EXIF header from an I/O \a device. Reads the contents of an EXIF header from an I/O \a device.
Returns true if the header was read and false otherwise. Returns true if the header was read and false otherwise.
\sa loadFromJpeg(), write() \sa loadFromJpeg(), write()
*/ */
bool QExifImageHeader::read(QIODevice *device) bool QExifImageHeader::read (QIODevice *device) {
{
clear(); clear();
int startPos = device->pos(); int startPos = device->pos();
...@@ -1604,11 +1480,11 @@ bool QExifImageHeader::read(QIODevice *device) ...@@ -1604,11 +1480,11 @@ bool QExifImageHeader::read(QIODevice *device)
if (byteOrder == "II") { if (byteOrder == "II") {
d->byteOrder = QSysInfo::LittleEndian; d->byteOrder = QSysInfo::LittleEndian;
stream.setByteOrder( QDataStream::LittleEndian ); stream.setByteOrder(QDataStream::LittleEndian);
} else if (byteOrder == "MM") { } else if (byteOrder == "MM") {
d->byteOrder = QSysInfo::BigEndian; d->byteOrder = QSysInfo::BigEndian;
stream.setByteOrder( QDataStream::BigEndian ); stream.setByteOrder(QDataStream::BigEndian);
} else { } else {
return false; return false;
} }
...@@ -1642,17 +1518,16 @@ bool QExifImageHeader::read(QIODevice *device) ...@@ -1642,17 +1518,16 @@ bool QExifImageHeader::read(QIODevice *device)
device->seek(startPos + offset); device->seek(startPos + offset);
QMap<quint16, QExifValue> thumbnailIfdValues = readIfdValues<quint16>( QMap<quint16, QExifValue> thumbnailIfdValues = readIfdValues<quint16>(
stream, startPos, readIfdHeaders( stream)); stream, startPos, readIfdHeaders(stream));
QExifValue jpegOffset = thumbnailIfdValues.value(JpegInterchangeFormat); QExifValue jpegOffset = thumbnailIfdValues.value(JpegInterchangeFormat);
QExifValue jpegLength = thumbnailIfdValues.value(JpegInterchangeFormatLength); QExifValue jpegLength = thumbnailIfdValues.value(JpegInterchangeFormatLength);
if (jpegOffset.type() == QExifValue::Long && jpegOffset.count() == 1 if (jpegOffset.type() == QExifValue::Long && jpegOffset.count() == 1 &&
&& jpegLength.type() == QExifValue::Long && jpegLength.count() == 1) jpegLength.type() == QExifValue::Long && jpegLength.count() == 1) {
{
device->seek(startPos + jpegOffset.toLong()); device->seek(startPos + jpegOffset.toLong());
d->thumbnailData = device->read( jpegLength.toLong() ); d->thumbnailData = device->read(jpegLength.toLong());
d->thumbnailXResolution = thumbnailIfdValues.value(XResolution); d->thumbnailXResolution = thumbnailIfdValues.value(XResolution);
d->thumbnailYResolution = thumbnailIfdValues.value(YResolution); d->thumbnailYResolution = thumbnailIfdValues.value(YResolution);
...@@ -1663,8 +1538,7 @@ bool QExifImageHeader::read(QIODevice *device) ...@@ -1663,8 +1538,7 @@ bool QExifImageHeader::read(QIODevice *device)
return true; return true;
} }
quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const quint32 QExifImageHeader::writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const {
{
stream << tag; stream << tag;
stream << quint16(value.type()); stream << quint16(value.type());
stream << quint32(value.count()); stream << quint32(value.count());
...@@ -1672,7 +1546,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1672,7 +1546,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
switch (value.type()) { switch (value.type()) {
case QExifValue::Byte: case QExifValue::Byte:
if (value.count() <= 4) { if (value.count() <= 4) {
foreach (quint8 byte, value.toByteVector()) foreach(quint8 byte, value.toByteVector())
stream << byte; stream << byte;
for (int j = value.count(); j < 4; j++) for (int j = value.count(); j < 4; j++)
stream << quint8(0); stream << quint8(0);
...@@ -1686,7 +1560,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1686,7 +1560,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
if (value.count() <= 4) { if (value.count() <= 4) {
stream.device()->write(value.toByteArray()); stream.device()->write(value.toByteArray());
if ( value.count() < 4) if (value.count() < 4)
stream.writeRawData("\0\0\0\0", 4 - value.count()); stream.writeRawData("\0\0\0\0", 4 - value.count());
} else { } else {
stream << offset; stream << offset;
...@@ -1709,7 +1583,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1709,7 +1583,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
break; break;
case QExifValue::Short: case QExifValue::Short:
if (value.count() <= 2) { if (value.count() <= 2) {
foreach (quint16 shrt, value.toShortVector()) foreach(quint16 shrt, value.toShortVector())
stream << shrt; stream << shrt;
for (int j = value.count(); j < 2; j++) for (int j = value.count(); j < 2; j++)
stream << quint16(0); stream << quint16(0);
...@@ -1720,9 +1594,9 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1720,9 +1594,9 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
} }
break; break;
case QExifValue::Long: case QExifValue::Long:
if(value.count() == 0) { if (value.count() == 0) {
stream << quint32(0); stream << quint32(0);
} else if(value.count() == 1) { } else if (value.count() == 1) {
stream << value.toLong(); stream << value.toLong();
} else { } else {
stream << offset; stream << offset;
...@@ -1732,7 +1606,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1732,7 +1606,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
break; break;
case QExifValue::SignedLong: case QExifValue::SignedLong:
if (value.count() == 0) { if (value.count() == 0) {
stream << quint32( 0 ); stream << quint32(0);
} else if (value.count() == 1) { } else if (value.count() == 1) {
stream << value.toSignedLong(); stream << value.toSignedLong();
} else { } else {
...@@ -1742,7 +1616,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1742,7 +1616,7 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
} }
break; break;
case QExifValue::Rational: case QExifValue::Rational:
if(value.count() == 0) { if (value.count() == 0) {
stream << quint32(0); stream << quint32(0);
} else { } else {
stream << offset; stream << offset;
...@@ -1767,12 +1641,11 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons ...@@ -1767,12 +1641,11 @@ quint32 QExifImageHeader::writeExifHeader(QDataStream &stream, quint16 tag, cons
return offset; return offset;
} }
void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &value) const void QExifImageHeader::writeExifValue (QDataStream &stream, const QExifValue &value) const {
{
switch (value.type()) { switch (value.type()) {
case QExifValue::Byte: case QExifValue::Byte:
if (value.count() > 4) if (value.count() > 4)
foreach (quint8 byte, value.toByteVector()) foreach(quint8 byte, value.toByteVector())
stream << byte; stream << byte;
break; break;
case QExifValue::Undefined: case QExifValue::Undefined:
...@@ -1792,8 +1665,8 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val ...@@ -1792,8 +1665,8 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val
stream << shrt; stream << shrt;
break; break;
case QExifValue::Long: case QExifValue::Long:
if(value.count() > 1) if (value.count() > 1)
foreach (quint32 lng, value.toLongVector()) foreach(quint32 lng, value.toLongVector())
stream << lng; stream << lng;
break; break;
case QExifValue::SignedLong: case QExifValue::SignedLong:
...@@ -1803,12 +1676,12 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val ...@@ -1803,12 +1676,12 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val
break; break;
case QExifValue::Rational: case QExifValue::Rational:
if (value.count() > 0) if (value.count() > 0)
foreach (QExifURational rational, value.toRationalVector()) foreach(QExifURational rational, value.toRationalVector())
stream << rational; stream << rational;
break; break;
case QExifValue::SignedRational: case QExifValue::SignedRational:
if (value.count() > 0) if (value.count() > 0)
foreach (QExifSRational rational, value.toSignedRationalVector()) foreach(QExifSRational rational, value.toSignedRationalVector())
stream << rational; stream << rational;
break; break;
default: default:
...@@ -1817,9 +1690,12 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val ...@@ -1817,9 +1690,12 @@ void QExifImageHeader::writeExifValue(QDataStream &stream, const QExifValue &val
} }
} }
template <typename T> quint32 QExifImageHeader::writeExifHeaders( template<typename T>
QDataStream &stream, const QMap<T, QExifValue> &values, quint32 offset) const quint32 QExifImageHeader::writeExifHeaders (
{ QDataStream &stream,
const QMap<T, QExifValue> &values,
quint32 offset
) const {
offset += values.count() * 12; offset += values.count() * 12;
for (typename QMap<T, QExifValue>::const_iterator i = values.constBegin(); i != values.constEnd(); i++) for (typename QMap<T, QExifValue>::const_iterator i = values.constBegin(); i != values.constEnd(); i++)
...@@ -1828,9 +1704,11 @@ template <typename T> quint32 QExifImageHeader::writeExifHeaders( ...@@ -1828,9 +1704,11 @@ template <typename T> quint32 QExifImageHeader::writeExifHeaders(
return offset; return offset;
} }
template <typename T> void QExifImageHeader::writeExifValues( template<typename T>
QDataStream &stream, const QMap<T, QExifValue> &values) const void QExifImageHeader::writeExifValues (
{ QDataStream &stream,
const QMap<T, QExifValue> &values
) const {
for (typename QMap<T, QExifValue>::const_iterator i = values.constBegin(); i != values.constEnd(); i++) for (typename QMap<T, QExifValue>::const_iterator i = values.constBegin(); i != values.constEnd(); i++)
writeExifValue(stream, i.value()); writeExifValue(stream, i.value());
} }
...@@ -1839,17 +1717,16 @@ template <typename T> void QExifImageHeader::writeExifValues( ...@@ -1839,17 +1717,16 @@ template <typename T> void QExifImageHeader::writeExifValues(
Writes an EXIF header to an I/O \a device. Writes an EXIF header to an I/O \a device.
Returns the total number of bytes written. Returns the total number of bytes written.
*/ */
qint64 QExifImageHeader::write(QIODevice *device) const qint64 QExifImageHeader::write (QIODevice *device) const {
{ // #ifndef QT_NO_DEBUG
//#ifndef QT_NO_DEBUG
qint64 startPos = device->pos(); qint64 startPos = device->pos();
//#endif // #endif
QDataStream stream( device ); QDataStream stream(device);
if (d->byteOrder == QSysInfo::LittleEndian) { if (d->byteOrder == QSysInfo::LittleEndian) {
stream.setByteOrder( QDataStream::LittleEndian ); stream.setByteOrder(QDataStream::LittleEndian);
device->write("II", 2); device->write("II", 2);
device->write("\x2A\x00", 2); device->write("\x2A\x00", 2);
...@@ -1876,9 +1753,9 @@ qint64 QExifImageHeader::write(QIODevice *device) const ...@@ -1876,9 +1753,9 @@ qint64 QExifImageHeader::write(QIODevice *device) const
quint32 exifIfdOffset = offset; quint32 exifIfdOffset = offset;
stream << quint16( ExifIfdPointer ); stream << quint16(ExifIfdPointer);
stream << quint16( QExifValue::Long ); stream << quint16(QExifValue::Long);
stream << quint32( 1 ); stream << quint32(1);
stream << exifIfdOffset; stream << exifIfdOffset;
offset += calculateSize(d->exifIfdValues); offset += calculateSize(d->exifIfdValues);
...@@ -1900,7 +1777,7 @@ qint64 QExifImageHeader::write(QIODevice *device) const ...@@ -1900,7 +1777,7 @@ qint64 QExifImageHeader::write(QIODevice *device) const
else else
stream << quint32(0); stream << quint32(0);
writeExifValues( stream, d->imageIfdValues ); writeExifValues(stream, d->imageIfdValues);
Q_ASSERT(startPos + exifIfdOffset == device->pos()); Q_ASSERT(startPos + exifIfdOffset == device->pos());
......
...@@ -51,19 +51,14 @@ ...@@ -51,19 +51,14 @@
#include <QSysInfo> #include <QSysInfo>
#include <QIODevice> #include <QIODevice>
typedef QPair< quint32, quint32 > QExifURational; typedef QPair<quint32, quint32> QExifURational;
typedef QPair< qint32, qint32 > QExifSRational; typedef QPair<qint32, qint32> QExifSRational;
//Q_DECLARE_METATYPE(QExifURational)
//Q_DECLARE_METATYPE(QExifSRational)
class QExifValuePrivate; class QExifValuePrivate;
class QExifValue class QExifValue {
{
public: public:
enum Type enum Type {
{
Byte = 1, Byte = 1,
Ascii = 2, Ascii = 2,
Short = 3, Short = 3,
...@@ -74,8 +69,7 @@ public: ...@@ -74,8 +69,7 @@ public:
SignedRational = 10 SignedRational = 10
}; };
enum TextEncoding enum TextEncoding {
{
NoEncoding, NoEncoding,
AsciiEncoding, AsciiEncoding,
JisEncoding, JisEncoding,
...@@ -83,66 +77,64 @@ public: ...@@ -83,66 +77,64 @@ public:
UndefinedEncoding UndefinedEncoding
}; };
QExifValue(); QExifValue ();
QExifValue( quint8 value ); QExifValue (quint8 value);
QExifValue( const QVector< quint8 > &value ); QExifValue (const QVector<quint8> &value);
QExifValue( const QString &value, TextEncoding encoding = NoEncoding ); QExifValue (const QString &value, TextEncoding encoding = NoEncoding);
QExifValue( quint16 value ); QExifValue (quint16 value);
QExifValue( const QVector< quint16 > &value ); QExifValue (const QVector<quint16> &value);
QExifValue( quint32 value ); QExifValue (quint32 value);
QExifValue( const QVector< quint32 > &value ); QExifValue (const QVector<quint32> &value);
QExifValue( const QExifURational &value ); QExifValue (const QExifURational &value);
QExifValue( const QVector< QExifURational > &value ); QExifValue (const QVector<QExifURational> &value);
QExifValue( const QByteArray &value ); QExifValue (const QByteArray &value);
QExifValue( qint32 value ); QExifValue (qint32 value);
QExifValue( const QVector< qint32 > &value ); QExifValue (const QVector<qint32> &value);
QExifValue( const QExifSRational &value ); QExifValue (const QExifSRational &value);
QExifValue( const QVector< QExifSRational > &value ); QExifValue (const QVector<QExifSRational> &value);
QExifValue( const QDateTime &value ); QExifValue (const QDateTime &value);
QExifValue( const QExifValue &other ); QExifValue (const QExifValue &other);
QExifValue &operator =( const QExifValue &other ); QExifValue &operator= (const QExifValue &other);
~QExifValue(); ~QExifValue ();
bool operator ==( const QExifValue &other ) const; bool operator== (const QExifValue &other) const;
bool isNull() const; bool isNull () const;
int type() const; int type () const;
int count() const; int count () const;
TextEncoding encoding() const; TextEncoding encoding () const;
quint8 toByte() const; quint8 toByte () const;
QVector< quint8 > toByteVector() const; QVector<quint8> toByteVector () const;
QString toString() const; QString toString () const;
quint16 toShort() const; quint16 toShort () const;
QVector< quint16 > toShortVector() const; QVector<quint16> toShortVector () const;
quint32 toLong() const; quint32 toLong () const;
QVector< quint32 > toLongVector() const; QVector<quint32> toLongVector () const;
QExifURational toRational() const; QExifURational toRational () const;
QVector< QExifURational > toRationalVector() const; QVector<QExifURational> toRationalVector () const;
QByteArray toByteArray() const; QByteArray toByteArray () const;
qint32 toSignedLong() const; qint32 toSignedLong () const;
QVector< qint32 > toSignedLongVector() const; QVector<qint32> toSignedLongVector () const;
QExifSRational toSignedRational() const; QExifSRational toSignedRational () const;
QVector< QExifSRational > toSignedRationalVector() const; QVector<QExifSRational> toSignedRationalVector () const;
QDateTime toDateTime() const; QDateTime toDateTime () const;
private: private:
QExplicitlySharedDataPointer< QExifValuePrivate > d; QExplicitlySharedDataPointer<QExifValuePrivate> d;
}; };
struct ExifIfdHeader; struct ExifIfdHeader;
class QExifImageHeaderPrivate; class QExifImageHeaderPrivate;
class QExifImageHeader class QExifImageHeader {
{
Q_DISABLE_COPY(QExifImageHeader) Q_DISABLE_COPY(QExifImageHeader)
public:
enum ImageTag
{
public:
enum ImageTag {
ImageWidth = 0x0100, ImageWidth = 0x0100,
ImageLength = 0x0101, ImageLength = 0x0101,
BitsPerSample = 0x0102, BitsPerSample = 0x0102,
...@@ -172,8 +164,7 @@ public: ...@@ -172,8 +164,7 @@ public:
Copyright = 0x8298 Copyright = 0x8298
}; };
enum ExifExtendedTag enum ExifExtendedTag {
{
ExifVersion = 0x9000, ExifVersion = 0x9000,
FlashPixVersion = 0xA000, FlashPixVersion = 0xA000,
ColorSpace = 0xA001, ColorSpace = 0xA001,
...@@ -190,7 +181,6 @@ public: ...@@ -190,7 +181,6 @@ public:
SubSecTimeOriginal = 0x9291, SubSecTimeOriginal = 0x9291,
SubSecTimeDigitized = 0x9292, SubSecTimeDigitized = 0x9292,
ImageUniqueId = 0xA420, ImageUniqueId = 0xA420,
ExposureTime = 0x829A, ExposureTime = 0x829A,
FNumber = 0x829D, FNumber = 0x829D,
ExposureProgram = 0x8822, ExposureProgram = 0x8822,
...@@ -233,8 +223,7 @@ public: ...@@ -233,8 +223,7 @@ public:
SubjectDistanceRange = 0x40C SubjectDistanceRange = 0x40C
}; };
enum GpsTag enum GpsTag {
{
GpsVersionId = 0x0000, GpsVersionId = 0x0000,
GpsLatitudeRef = 0x0001, GpsLatitudeRef = 0x0001,
GpsLatitude = 0x0002, GpsLatitude = 0x0002,
...@@ -268,50 +257,49 @@ public: ...@@ -268,50 +257,49 @@ public:
GpsDifferential = 0x001E GpsDifferential = 0x001E
}; };
QExifImageHeader(); QExifImageHeader ();
explicit QExifImageHeader(const QString &fileName); explicit QExifImageHeader (const QString &fileName);
~QExifImageHeader(); ~QExifImageHeader ();
bool loadFromJpeg(const QString &fileName); bool loadFromJpeg (const QString &fileName);
bool loadFromJpeg(QIODevice *device); bool loadFromJpeg (QIODevice *device);
bool saveToJpeg(const QString &fileName) const; bool saveToJpeg (const QString &fileName) const;
bool saveToJpeg(QIODevice *device) const; bool saveToJpeg (QIODevice *device) const;
bool read(QIODevice *device); bool read (QIODevice *device);
qint64 write(QIODevice *device) const; qint64 write (QIODevice *device) const;
qint64 size() const; qint64 size () const;
QSysInfo::Endian byteOrder() const; QSysInfo::Endian byteOrder () const;
void clear(); void clear ();
QList<ImageTag> imageTags() const; QList<ImageTag> imageTags () const;
QList<ExifExtendedTag> extendedTags() const; QList<ExifExtendedTag> extendedTags () const;
QList<GpsTag> gpsTags() const; QList<GpsTag> gpsTags () const;
bool contains(ImageTag tag) const; bool contains (ImageTag tag) const;
bool contains(ExifExtendedTag tag) const; bool contains (ExifExtendedTag tag) const;
bool contains(GpsTag tag) const; bool contains (GpsTag tag) const;
void remove(ImageTag tag); void remove (ImageTag tag);
void remove(ExifExtendedTag tag); void remove (ExifExtendedTag tag);
void remove(GpsTag tag); void remove (GpsTag tag);
QExifValue value(ImageTag tag) const; QExifValue value (ImageTag tag) const;
QExifValue value(ExifExtendedTag tag) const; QExifValue value (ExifExtendedTag tag) const;
QExifValue value(GpsTag tag) const; QExifValue value (GpsTag tag) const;
void setValue(ImageTag tag, const QExifValue &value); void setValue (ImageTag tag, const QExifValue &value);
void setValue(ExifExtendedTag tag, const QExifValue &value); void setValue (ExifExtendedTag tag, const QExifValue &value);
void setValue(GpsTag tag, const QExifValue &value); void setValue (GpsTag tag, const QExifValue &value);
QImage thumbnail() const; QImage thumbnail () const;
void setThumbnail( const QImage &thumbnail ); void setThumbnail (const QImage &thumbnail);
private: private:
enum PrivateTag enum PrivateTag {
{
ExifIfdPointer = 0x8769, ExifIfdPointer = 0x8769,
GpsInfoIfdPointer = 0x8825, GpsInfoIfdPointer = 0x8825,
InteroperabilityIfdPointer = 0xA005, InteroperabilityIfdPointer = 0xA005,
...@@ -319,30 +307,30 @@ private: ...@@ -319,30 +307,30 @@ private:
JpegInterchangeFormatLength = 0x0202 JpegInterchangeFormatLength = 0x0202
}; };
QByteArray extractExif( QIODevice *device ) const; QByteArray extractExif (QIODevice *device) const;
QList< ExifIfdHeader > readIfdHeaders( QDataStream &stream ) const; QList<ExifIfdHeader> readIfdHeaders (QDataStream &stream) const;
QExifValue readIfdValue(QDataStream &stream, int startPos, const ExifIfdHeader &header) const; QExifValue readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const;
template <typename T> QMap<T, QExifValue> readIfdValues( template<typename T>
QDataStream &stream, int startPos, const QList<ExifIfdHeader> &headers) const; QMap<T, QExifValue> readIfdValues (QDataStream &stream, int startPos, const QList<ExifIfdHeader> &headers) const;
template <typename T> QMap<T, QExifValue> readIfdValues( template<typename T>
QDataStream &stream, int startPos, const QExifValue &pointer) const; QMap<T, QExifValue> readIfdValues (QDataStream &stream, int startPos, const QExifValue &pointer) const;
quint32 writeExifHeader(QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const; quint32 writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const;
void writeExifValue(QDataStream &stream, const QExifValue &value) const; void writeExifValue (QDataStream &stream, const QExifValue &value) const;
template <typename T> quint32 writeExifHeaders( template<typename T>
QDataStream &stream, const QMap<T, QExifValue > &values, quint32 offset) const; quint32 writeExifHeaders (QDataStream &stream, const QMap<T, QExifValue> &values, quint32 offset) const;
template <typename T> void writeExifValues( template<typename T>
QDataStream &target, const QMap<T, QExifValue> &values) const; void writeExifValues (QDataStream &target, const QMap<T, QExifValue> &values) const;
quint32 sizeOf(const QExifValue &value) const; quint32 sizeOf (const QExifValue &value) const;
template <typename T> quint32 calculateSize( template<typename T>
const QMap<T, QExifValue> &values) const; quint32 calculateSize (const QMap<T, QExifValue> &values) const;
QExifImageHeaderPrivate *d; QExifImageHeaderPrivate *d;
}; };
#endif #endif // ifndef QEXIFIMAGEHEADER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment