Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linphone-desktop
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
linphone-desktop
Commits
e249bc3e
Commit
e249bc3e
authored
Jul 16, 2017
by
Wescoeur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(QExifImageHeader): use app indentation
parent
8d46bcb1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1305 additions
and
1440 deletions
+1305
-1440
QExifImageHeader.cpp
src/utils/QExifImageHeader.cpp
+1047
-1170
QExifImageHeader.h
src/utils/QExifImageHeader.h
+258
-270
No files found.
src/utils/QExifImageHeader.cpp
View file @
e249bc3e
...
@@ -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
;
{
quint8
offsetBytes
[
4
];
quint32
offset
;
char
offsetAscii
[
4
];
quint8
offsetBytes
[
4
];
quint16
offsetShorts
[
2
];
char
offsetAscii
[
4
];
};
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
.
offset
;
{
}
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:
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,481 +238,425 @@ Q_GLOBAL_STATIC(QExifByteValuePrivate,qExifValuePrivateSharedNull)
...
@@ -255,481 +238,425 @@ 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"
);
{
if
(
codec
)
QTextCodec
*
codec
=
QTextCodec
::
codecForName
(
"UTF-16"
);
d
=
new
QExifUndefinedValuePrivate
(
QByteArray
::
fromRawData
(
"UNICODE
\0
"
,
8
)
+
codec
->
fromUnicode
(
value
));
if
(
codec
)
}
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
;
}
}
/*!
/*!
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
)))
return
AsciiEncoding
;
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"ASCII
\0\0\0
"
,
8
)
)
)
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"JIS
\0\0\0\0\0
"
,
8
)))
return
AsciiEncoding
;
return
JisEncoding
;
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"JIS
\0\0\0\0\0
"
,
8
)
)
)
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"UNICODE
\0
"
,
8
)))
return
JisEncoding
;
return
UnicodeEncoding
;
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"UNICODE
\0
"
,
8
)
)
)
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"
\0\0\0\0\0\0\0\0
"
,
8
)))
return
UnicodeEncoding
;
return
UndefinedEncoding
;
else
if
(
value
.
startsWith
(
QByteArray
::
fromRawData
(
"
\0\0\0\0\0\0\0\0
"
,
8
)
)
)
}
return
UndefinedEncoding
;
return
NoEncoding
;
}
return
NoEncoding
;
}
}
/*!
/*!
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
:
{
return
QString
::
fromUtf8
(
string
.
constData
(),
string
.
length
());
case
AsciiEncoding
:
case
JisEncoding
:
{
return
QString
::
fromUtf8
(
string
.
constData
(),
string
.
length
()
);
QTextCodec
*
codec
=
QTextCodec
::
codecForName
(
"JIS X 0208"
);
case
JisEncoding
:
if
(
codec
)
{
return
codec
->
toUnicode
(
string
);
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
;
}
}
}
default:
break
;
return
QString
();
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.
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
)
{
{
case
Byte
:
switch
(
d
->
type
)
return
static_cast
<
const
QExifByteValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
{
case
Short
:
case
Byte
:
return
static_cast
<
const
QExifShortValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifByteValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
Short
:
return
static_cast
<
const
QExifShortValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
}
}
}
return
0
;
}
return
0
;
}
}
/*!
/*!
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
)
{
{
case
Byte
:
switch
(
d
->
type
)
return
static_cast
<
const
QExifByteValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
{
case
Short
:
case
Byte
:
return
static_cast
<
const
QExifShortValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifByteValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
Long
:
case
Short
:
return
static_cast
<
const
QExifLongValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifShortValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
SignedLong
:
case
Long
:
return
static_cast
<
const
QExifSignedLongValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifLongValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
SignedLong
:
return
static_cast
<
const
QExifSignedLongValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
}
}
}
return
0
;
}
return
0
;
}
}
/*!
/*!
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
();
}
}
}
}
/*!
/*!
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
)
{
{
case
Byte
:
switch
(
d
->
type
)
return
static_cast
<
const
QExifByteValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
{
case
Short
:
case
Byte
:
return
static_cast
<
const
QExifShortValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifByteValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
Long
:
case
Short
:
return
static_cast
<
const
QExifLongValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifShortValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
SignedLong
:
case
Long
:
return
static_cast
<
const
QExifSignedLongValuePrivate
*>
(
d
.
constData
())
->
value
.
at
(
0
);
return
static_cast
<
const
QExifLongValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
case
SignedLong
:
return
static_cast
<
const
QExifSignedLongValuePrivate
*
>
(
d
.
constData
()
)
->
value
.
at
(
0
);
}
}
}
return
0
;
}
return
0
;
}
}
/*!
/*!
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
;
QExifValue
thumbnailXResolution
;
QExifValue
thumbnailXResolution
;
QExifValue
thumbnailYResolution
;
QExifValue
thumbnailYResolution
;
QExifValue
thumbnailResolutionUnit
;
QExifValue
thumbnailResolutionUnit
;
QExifValue
thumbnailOrientation
;
QExifValue
thumbnailOrientation
;
};
};
/*!
/*!
...
@@ -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,88 +811,82 @@ public:
...
@@ -884,88 +811,82 @@ 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
;
loadFromJpeg
(
fileName
);
loadFromJpeg
(
fileName
);
}
}
/*!
/*!
Destroys an EXIF image data editor.
Destroys an EXIF image data editor.
*/
*/
QExifImageHeader
::~
QExifImageHeader
()
QExifImageHeader
::~
QExifImageHeader
()
{
{
clear
();
clear
();
delete
d
;
delete
d
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
);
if
(
!
exifData
.
isEmpty
())
{
if
(
!
exifData
.
isEmpty
())
{
QBuffer
buffer
(
&
exifData
);
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.
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
))
return
saveToJpeg
(
&
file
);
return
saveToJpeg
(
&
file
);
else
else
return
false
;
return
false
;
}
}
/*!
/*!
...
@@ -974,997 +895,953 @@ bool QExifImageHeader::saveToJpeg(const QString &fileName) const
...
@@ -974,997 +895,953 @@ 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
;
quint16
segmentLength
;
quint16
segmentLength
;
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
(
0xFFE0
);
// APP0
stream
<<
quint16
(
0xFFD8
);
// SOI
stream
<<
quint16
(
jfif
.
size
()
+
2
);
stream
<<
quint16
(
0xFFE0
);
// APP0
device
->
write
(
jfif
);
stream
<<
quint16
(
jfif
.
size
()
+
2
);
stream
<<
quint16
(
0xFFE1
);
// APP1
device
->
write
(
jfif
);
stream
<<
quint16
(
exif
.
size
()
+
2
);
stream
<<
quint16
(
0xFFE1
);
//APP1
device
->
write
(
exif
);
stream
<<
quint16
(
exif
.
size
()
+
2
);
stream
<<
quint16
(
0xFFE0
);
// APP0
device
->
write
(
exif
);
stream
<<
segmentId
;
stream
<<
quint16
(
0xFFE0
);
// APP0
stream
<<
segmentLength
;
stream
<<
segmentId
;
device
->
write
(
remainder
);
stream
<<
segmentLength
;
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
(
0xFFE1
);
//APP1
stream
<<
quint16
(
exif
.
size
()
+
2
);
device
->
write
(
exif
);
stream
<<
segmentId
;
stream
<<
segmentLength
;
device
->
write
(
remainder
);
}
return
true
;
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
;
}
}
/*!
/*!
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
:
return
value
.
count
()
>
4
return
value
.
count
()
>
4
?
12
+
value
.
count
()
?
12
+
value
.
count
()
:
12
;
:
12
;
case
QExifValue
:
:
Ascii
:
case
QExifValue
:
:
Ascii
:
return
value
.
count
()
>
4
return
value
.
count
()
>
4
?
12
+
value
.
count
()
?
12
+
value
.
count
()
:
12
;
:
12
;
case
QExifValue
:
:
Short
:
case
QExifValue
:
:
Short
:
return
value
.
count
()
>
2
return
value
.
count
()
>
2
?
12
+
value
.
count
()
*
sizeof
(
quint16
)
?
12
+
value
.
count
()
*
sizeof
(
quint16
)
:
12
;
:
12
;
case
QExifValue
:
:
Long
:
case
QExifValue
:
:
Long
:
case
QExifValue
:
:
SignedLong
:
case
QExifValue
:
:
SignedLong
:
return
value
.
count
()
>
1
return
value
.
count
()
>
1
?
12
+
value
.
count
()
*
sizeof
(
quint32
)
?
12
+
value
.
count
()
*
sizeof
(
quint32
)
:
12
;
:
12
;
case
QExifValue
:
:
Rational
:
case
QExifValue
:
:
Rational
:
case
QExifValue
:
:
SignedRational
:
case
QExifValue
:
:
SignedRational
:
return
value
.
count
()
>
0
return
value
.
count
()
>
0
?
12
+
value
.
count
()
*
sizeof
(
quint32
)
*
2
?
12
+
value
.
count
()
*
sizeof
(
quint32
)
*
2
:
12
;
:
12
;
default:
default:
return
0
;
return
0
;
}
}
}
}
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
;
}
}
/*!
/*!
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
=
2
+
// Byte Order
d
->
size
2
+
// Marker
=
2
// Byte Order
4
+
// Image Ifd offset
+
2
// Marker
12
+
// ExifIfdPointer Ifd
+
4
// Image Ifd offset
4
+
// Thumbnail Ifd offset
+
12
// ExifIfdPointer Ifd
calculateSize
(
d
->
imageIfdValues
)
+
// Image headers and values.
+
4
// Thumbnail Ifd offset
calculateSize
(
d
->
exifIfdValues
);
// Exif headers and values.
+
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
())
{
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
d
->
size
d
->
size
+=
12
+
// GpsInfoIfdPointer Ifd
+=
2
// Thumbnail Ifd count
calculateSize
(
d
->
gpsIfdValues
);
// Gps headers and values.
+
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
;
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.
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
();
d
->
thumbnailData
.
clear
();
d
->
thumbnailData
.
clear
();
d
->
size
=
-
1
;
d
->
size
=
-
1
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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
;
}
}
/*!
/*!
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"
);
if
(
!
d
->
thumbnailOrientation
.
isNull
())
{
if
(
!
d
->
thumbnailOrientation
.
isNull
())
{
switch
(
d
->
thumbnailOrientation
.
toShort
())
{
switch
(
d
->
thumbnailOrientation
.
toShort
())
{
case
1
:
case
1
:
return
image
;
return
image
;
case
2
:
case
2
:
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
YAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
YAxis
));
case
3
:
case
3
:
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
ZAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
ZAxis
));
case
4
:
case
4
:
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
XAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
XAxis
));
case
5
:
case
5
:
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
YAxis
).
rotate
(
90
,
Qt
::
ZAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
YAxis
).
rotate
(
90
,
Qt
::
ZAxis
));
case
6
:
case
6
:
return
image
.
transformed
(
QTransform
().
rotate
(
90
,
Qt
::
ZAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
90
,
Qt
::
ZAxis
));
case
7
:
case
7
:
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
XAxis
).
rotate
(
90
,
Qt
::
ZAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
180
,
Qt
::
XAxis
).
rotate
(
90
,
Qt
::
ZAxis
));
case
8
:
case
8
:
return
image
.
transformed
(
QTransform
().
rotate
(
270
,
Qt
::
ZAxis
));
return
image
.
transformed
(
QTransform
().
rotate
(
270
,
Qt
::
ZAxis
));
}
}
}
}
return
image
;
return
image
;
}
}
/*!
/*!
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
;
if
(
buffer
.
open
(
QIODevice
::
WriteOnly
)
&&
thumbnail
.
save
(
&
buffer
,
"JPG"
))
{
if
(
buffer
.
open
(
QIODevice
::
WriteOnly
)
&&
thumbnail
.
save
(
&
buffer
,
"JPG"
))
{
buffer
.
close
();
buffer
.
close
();
d
->
thumbnailSize
=
thumbnail
.
size
();
d
->
thumbnailSize
=
thumbnail
.
size
();
d
->
thumbnailData
=
buffer
.
data
();
d
->
thumbnailData
=
buffer
.
data
();
d
->
thumbnailOrientation
=
QExifValue
();
d
->
thumbnailOrientation
=
QExifValue
();
}
}
else
{
d
->
thumbnailSize
=
QSize
();
d
->
thumbnailData
=
QByteArray
();
}
}
}
else
{
d
->
thumbnailSize
=
QSize
();
d
->
thumbnailData
=
QByteArray
();
}
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
>
headers
;
QList
<
ExifIfdHeader
>
QExifImageHeader
::
readIfdHeaders
(
QDataStream
&
stream
)
const
quint16
count
;
{
QList
<
ExifIfdHeader
>
headers
;
quint16
count
;
stream
>>
count
;
stream
>>
count
;
for
(
quint16
i
=
0
;
i
<
count
;
i
++
)
{
ExifIfdHeader
header
;
for
(
quint16
i
=
0
;
i
<
count
;
i
++
)
{
stream
>>
header
;
ExifIfdHeader
header
;
stream
>>
header
;
headers
.
append
(
header
);
}
headers
.
append
(
header
);
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
)
{
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
if
(
header
.
count
>
4
)
{
stream
>>
value
[
i
];
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
}
else
{
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
value
[
i
]
=
header
.
offsetBytes
[
i
];
}
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
return
QExifValue
(
value
);
stream
>>
value
[
i
];
}
}
else
{
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
value
[
i
]
=
header
.
offsetBytes
[
i
];
}
return
QExifValue
(
value
);
}
case
QExifValue
:
:
Undefined
:
case
QExifValue
:
:
Undefined
:
if
(
header
.
count
>
4
)
{
if
(
header
.
count
>
4
)
{
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
return
QExifValue
(
stream
.
device
()
->
read
(
header
.
count
));
return
QExifValue
(
stream
.
device
()
->
read
(
header
.
count
));
}
else
{
}
else
{
return
QExifValue
(
QByteArray
::
fromRawData
(
header
.
offsetAscii
,
header
.
count
));
return
QExifValue
(
QByteArray
::
fromRawData
(
header
.
offsetAscii
,
header
.
count
));
}
}
case
QExifValue
:
:
Ascii
:
case
QExifValue
:
:
Ascii
:
if
(
header
.
count
>
4
)
{
if
(
header
.
count
>
4
)
{
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
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
));
return
QExifValue
(
QString
::
fromUtf8
(
ascii
.
constData
(),
ascii
.
size
()
-
1
));
}
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
)
{
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
];
}
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
:
{
}
QVector
<
quint32
>
value
(
header
.
count
);
case
QExifValue
:
:
Long
:
{
if
(
header
.
count
>
1
)
{
QVector
<
quint32
>
value
(
header
.
count
);
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
if
(
header
.
count
>
1
)
{
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
stream
>>
value
[
i
];
}
else
if
(
header
.
count
==
1
)
{
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
value
[
0
]
=
header
.
offset
;
stream
>>
value
[
i
];
}
}
else
if
(
header
.
count
==
1
)
{
return
QExifValue
(
value
);
value
[
0
]
=
header
.
offset
;
}
}
case
QExifValue
:
:
SignedLong
:
{
return
QExifValue
(
value
);
QVector
<
qint32
>
value
(
header
.
count
);
}
case
QExifValue
:
:
SignedLong
:
if
(
header
.
count
>
1
)
{
{
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
QVector
<
qint32
>
value
(
header
.
count
);
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
if
(
header
.
count
>
1
)
{
stream
>>
value
[
i
];
stream
.
device
()
->
seek
(
startPos
+
header
.
offset
);
}
else
if
(
header
.
count
==
1
)
{
value
[
0
]
=
header
.
offset
;
for
(
quint32
i
=
0
;
i
<
header
.
count
;
i
++
)
}
stream
>>
value
[
i
];
return
QExifValue
(
value
);
}
else
if
(
header
.
count
==
1
)
{
}
value
[
0
]
=
header
.
offset
;
break
;
}
case
QExifValue
:
:
Rational
:
{
return
QExifValue
(
value
);
QVector
<
QExifURational
>
value
(
header
.
count
);
}
break
;
case
QExifValue
:
:
Rational
:
{
QVector
<
QExifURational
>
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
);
}
}
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
);
}
}
default:
default:
qWarning
()
<<
"Invalid Ifd Type"
<<
header
.
type
;
qWarning
()
<<
"Invalid Ifd Type"
<<
header
.
type
;
return
QExifValue
();
return
QExifValue
();
}
}
}
}
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
,
QMap
<
T
,
QExifValue
>
values
;
int
startPos
,
const
QList
<
ExifIfdHeader
>
&
headers
)
const
{
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
,
if
(
pointer
.
type
()
==
QExifValue
::
Long
&&
pointer
.
count
()
==
1
)
{
const
QExifValue
&
pointer
stream
.
device
()
->
seek
(
startPos
+
pointer
.
toLong
());
)
const
{
if
(
pointer
.
type
()
==
QExifValue
::
Long
&&
pointer
.
count
()
==
1
)
{
stream
.
device
()
->
seek
(
startPos
+
pointer
.
toLong
());
QList
<
ExifIfdHeader
>
headers
=
readIfdHeaders
(
stream
);
QList
<
ExifIfdHeader
>
headers
=
readIfdHeaders
(
stream
);
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
();
QDataStream
stream
(
device
);
QDataStream
stream
(
device
);
QByteArray
byteOrder
=
device
->
read
(
2
);
QByteArray
byteOrder
=
device
->
read
(
2
);
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
;
}
}
quint16
id
;
quint16
id
;
quint32
offset
;
quint32
offset
;
stream
>>
id
;
stream
>>
id
;
stream
>>
offset
;
stream
>>
offset
;
if
(
id
!=
0x002A
)
if
(
id
!=
0x002A
)
return
false
;
return
false
;
device
->
seek
(
startPos
+
offset
);
device
->
seek
(
startPos
+
offset
);
QList
<
ExifIfdHeader
>
headers
=
readIfdHeaders
(
stream
);
QList
<
ExifIfdHeader
>
headers
=
readIfdHeaders
(
stream
);
stream
>>
offset
;
stream
>>
offset
;
d
->
imageIfdValues
=
readIfdValues
<
ImageTag
>
(
stream
,
startPos
,
headers
);
d
->
imageIfdValues
=
readIfdValues
<
ImageTag
>
(
stream
,
startPos
,
headers
);
QExifValue
exifIfdPointer
=
d
->
imageIfdValues
.
take
(
ImageTag
(
ExifIfdPointer
));
QExifValue
exifIfdPointer
=
d
->
imageIfdValues
.
take
(
ImageTag
(
ExifIfdPointer
));
QExifValue
gpsIfdPointer
=
d
->
imageIfdValues
.
take
(
ImageTag
(
GpsInfoIfdPointer
));
QExifValue
gpsIfdPointer
=
d
->
imageIfdValues
.
take
(
ImageTag
(
GpsInfoIfdPointer
));
d
->
exifIfdValues
=
readIfdValues
<
ExifExtendedTag
>
(
stream
,
startPos
,
exifIfdPointer
);
d
->
exifIfdValues
=
readIfdValues
<
ExifExtendedTag
>
(
stream
,
startPos
,
exifIfdPointer
);
d
->
gpsIfdValues
=
readIfdValues
<
GpsTag
>
(
stream
,
startPos
,
gpsIfdPointer
);
d
->
gpsIfdValues
=
readIfdValues
<
GpsTag
>
(
stream
,
startPos
,
gpsIfdPointer
);
d
->
exifIfdValues
.
remove
(
ExifExtendedTag
(
InteroperabilityIfdPointer
));
d
->
exifIfdValues
.
remove
(
ExifExtendedTag
(
InteroperabilityIfdPointer
));
if
(
offset
)
{
if
(
offset
)
{
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
);
d
->
thumbnailResolutionUnit
=
thumbnailIfdValues
.
value
(
ResolutionUnit
);
d
->
thumbnailResolutionUnit
=
thumbnailIfdValues
.
value
(
ResolutionUnit
);
d
->
thumbnailOrientation
=
thumbnailIfdValues
.
value
(
Orientation
);
d
->
thumbnailOrientation
=
thumbnailIfdValues
.
value
(
Orientation
);
}
}
}
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
());
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
);
}
else
{
}
else
{
stream
<<
offset
;
stream
<<
offset
;
offset
+=
value
.
count
();
offset
+=
value
.
count
();
}
}
break
;
break
;
case
QExifValue
:
:
Undefined
:
case
QExifValue
:
:
Undefined
:
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
;
offset
+=
value
.
count
();
offset
+=
value
.
count
();
}
}
break
;
break
;
case
QExifValue
:
:
Ascii
:
case
QExifValue
:
:
Ascii
:
if
(
value
.
count
()
<=
4
)
{
if
(
value
.
count
()
<=
4
)
{
QByteArray
bytes
=
value
.
toByteArray
();
QByteArray
bytes
=
value
.
toByteArray
();
stream
.
writeRawData
(
bytes
.
constData
(),
value
.
count
());
stream
.
writeRawData
(
bytes
.
constData
(),
value
.
count
());
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
;
offset
+=
value
.
count
();
offset
+=
value
.
count
();
}
}
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
);
}
else
{
}
else
{
stream
<<
offset
;
stream
<<
offset
;
offset
+=
value
.
count
()
*
sizeof
(
quint16
);
offset
+=
value
.
count
()
*
sizeof
(
quint16
);
}
}
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
;
offset
+=
value
.
count
()
*
sizeof
(
quint32
);
offset
+=
value
.
count
()
*
sizeof
(
quint32
);
}
}
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
{
stream
<<
offset
;
stream
<<
offset
;
offset
+=
value
.
count
()
*
sizeof
(
qint32
);
offset
+=
value
.
count
()
*
sizeof
(
qint32
);
}
}
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
;
offset
+=
value
.
count
()
*
sizeof
(
quint32
)
*
2
;
offset
+=
value
.
count
()
*
sizeof
(
quint32
)
*
2
;
}
}
break
;
break
;
case
QExifValue
:
:
SignedRational
:
case
QExifValue
:
:
SignedRational
:
if
(
value
.
count
()
==
0
)
{
if
(
value
.
count
()
==
0
)
{
stream
<<
quint32
(
0
);
stream
<<
quint32
(
0
);
}
else
{
}
else
{
stream
<<
offset
;
stream
<<
offset
;
offset
+=
value
.
count
()
*
sizeof
(
qint32
)
*
2
;
offset
+=
value
.
count
()
*
sizeof
(
qint32
)
*
2
;
}
}
break
;
break
;
default:
default:
qWarning
()
<<
"Invalid Ifd Type"
<<
value
.
type
();
qWarning
()
<<
"Invalid Ifd Type"
<<
value
.
type
();
stream
<<
quint32
(
0
);
stream
<<
quint32
(
0
);
}
}
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
:
if
(
value
.
count
()
>
4
)
if
(
value
.
count
()
>
4
)
stream
.
device
()
->
write
(
value
.
toByteArray
());
stream
.
device
()
->
write
(
value
.
toByteArray
());
break
;
break
;
case
QExifValue
:
:
Ascii
:
case
QExifValue
:
:
Ascii
:
if
(
value
.
count
()
>
4
)
{
if
(
value
.
count
()
>
4
)
{
QByteArray
bytes
=
value
.
toByteArray
();
QByteArray
bytes
=
value
.
toByteArray
();
stream
.
writeRawData
(
bytes
.
constData
(),
bytes
.
size
()
+
1
);
stream
.
writeRawData
(
bytes
.
constData
(),
bytes
.
size
()
+
1
);
}
}
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
;
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
:
if
(
value
.
count
()
>
1
)
if
(
value
.
count
()
>
1
)
foreach
(
qint32
lng
,
value
.
toSignedLongVector
())
foreach
(
qint32
lng
,
value
.
toSignedLongVector
())
stream
<<
lng
;
stream
<<
lng
;
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:
qWarning
()
<<
"Invalid Ifd Type"
<<
value
.
type
();
qWarning
()
<<
"Invalid Ifd Type"
<<
value
.
type
();
break
;
break
;
}
}
}
}
template
<
typename
T
>
quint32
QExifImageHeader
::
writeExifHeaders
(
template
<
typename
T
>
QDataStream
&
stream
,
const
QMap
<
T
,
QExifValue
>
&
values
,
quint32
offset
)
const
quint32
QExifImageHeader
::
writeExifHeaders
(
{
QDataStream
&
stream
,
offset
+=
values
.
count
()
*
12
;
const
QMap
<
T
,
QExifValue
>
&
values
,
quint32
offset
)
const
{
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
++
)
offset
=
writeExifHeader
(
stream
,
i
.
key
(),
i
.
value
(),
offset
);
offset
=
writeExifHeader
(
stream
,
i
.
key
(),
i
.
value
(),
offset
);
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
,
for
(
typename
QMap
<
T
,
QExifValue
>::
const_iterator
i
=
values
.
constBegin
();
i
!=
values
.
constEnd
();
i
++
)
const
QMap
<
T
,
QExifValue
>
&
values
writeExifValue
(
stream
,
i
.
value
());
)
const
{
for
(
typename
QMap
<
T
,
QExifValue
>::
const_iterator
i
=
values
.
constBegin
();
i
!=
values
.
constEnd
();
i
++
)
writeExifValue
(
stream
,
i
.
value
());
}
}
/*!
/*!
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
);
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
(
"MM"
,
2
);
device
->
write
(
"
\x00\x2A
"
,
2
);
device
->
write
(
"
\x00\x00\x00\x08
"
,
4
);
}
quint16
count
=
d
->
imageIfdValues
.
count
()
+
1
;
QDataStream
stream
(
device
);
quint32
offset
=
26
;
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
if
(
d
->
byteOrder
==
QSysInfo
::
LittleEndian
)
{
count
++
;
stream
.
setByteOrder
(
QDataStream
::
LittleEndian
);
offset
+=
12
;
}
stream
<<
count
;
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
);
offset
=
writeExifHeaders
(
stream
,
d
->
imageIfdValues
,
offset
);
device
->
write
(
"MM"
,
2
);
device
->
write
(
"
\x00\x2A
"
,
2
);
device
->
write
(
"
\x00\x00\x00\x08
"
,
4
);
}
quint32
exifIfdOffset
=
offset
;
quint16
count
=
d
->
imageIfdValues
.
count
()
+
1
;
quint32
offset
=
26
;
stream
<<
quint16
(
ExifIfdPointer
);
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
stream
<<
quint16
(
QExifValue
::
Long
);
count
++
;
stream
<<
quint32
(
1
);
offset
+=
12
;
stream
<<
exifIfdOffset
;
}
offset
+=
calculateSize
(
d
->
exifIfdValues
);
quint32
gpsIfdOffset
=
offse
t
;
stream
<<
coun
t
;
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
offset
=
writeExifHeaders
(
stream
,
d
->
imageIfdValues
,
offset
);
stream
<<
quint16
(
GpsInfoIfdPointer
);
stream
<<
quint16
(
QExifValue
::
Long
);
stream
<<
quint32
(
1
);
stream
<<
gpsIfdOffset
;
d
->
imageIfdValues
.
insert
(
ImageTag
(
GpsInfoIfdPointer
),
QExifValue
(
offset
))
;
quint32
exifIfdOffset
=
offset
;
offset
+=
calculateSize
(
d
->
gpsIfdValues
);
stream
<<
quint16
(
ExifIfdPointer
);
}
stream
<<
quint16
(
QExifValue
::
Long
);
stream
<<
quint32
(
1
);
stream
<<
exifIfdOffset
;
offset
+=
calculateSize
(
d
->
exifIfdValues
);
if
(
!
d
->
thumbnailData
.
isEmpty
())
quint32
gpsIfdOffset
=
offset
;
stream
<<
offset
;
// Write offset to thumbnail Ifd.
else
stream
<<
quint32
(
0
);
writeExifValues
(
stream
,
d
->
imageIfdValues
);
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
stream
<<
quint16
(
GpsInfoIfdPointer
);
stream
<<
quint16
(
QExifValue
::
Long
);
stream
<<
quint32
(
1
);
stream
<<
gpsIfdOffset
;
Q_ASSERT
(
startPos
+
exifIfdOffset
==
device
->
pos
(
));
d
->
imageIfdValues
.
insert
(
ImageTag
(
GpsInfoIfdPointer
),
QExifValue
(
offset
));
stream
<<
quint16
(
d
->
exifIfdValues
.
count
());
offset
+=
calculateSize
(
d
->
gpsIfdValues
);
}
writeExifHeaders
(
stream
,
d
->
exifIfdValues
,
exifIfdOffset
);
if
(
!
d
->
thumbnailData
.
isEmpty
())
writeExifValues
(
stream
,
d
->
exifIfdValues
);
stream
<<
offset
;
// Write offset to thumbnail Ifd.
else
stream
<<
quint32
(
0
);
Q_ASSERT
(
startPos
+
gpsIfdOffset
==
device
->
pos
()
);
writeExifValues
(
stream
,
d
->
imageIfdValues
);
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
Q_ASSERT
(
startPos
+
exifIfdOffset
==
device
->
pos
());
stream
<<
quint16
(
d
->
gpsIfdValues
.
count
());
writeExifHeaders
(
stream
,
d
->
gpsIfdValues
,
gpsIfdOffset
);
stream
<<
quint16
(
d
->
exifIfdValues
.
count
());
writeExifValues
(
stream
,
d
->
gpsIfdValues
);
}
Q_ASSERT
(
startPos
+
offset
==
device
->
pos
());
writeExifHeaders
(
stream
,
d
->
exifIfdValues
,
exifIfdOffset
);
writeExifValues
(
stream
,
d
->
exifIfdValues
);
if
(
!
d
->
thumbnailData
.
isEmpty
())
{
Q_ASSERT
(
startPos
+
gpsIfdOffset
==
device
->
pos
());
offset
+=
86
;
stream
<<
quint16
(
7
);
if
(
!
d
->
gpsIfdValues
.
isEmpty
())
{
stream
<<
quint16
(
d
->
gpsIfdValues
.
count
());
QExifValue
xResolution
=
d
->
thumbnailXResolution
.
isNull
()
writeExifHeaders
(
stream
,
d
->
gpsIfdValues
,
gpsIfdOffset
);
?
QExifValue
(
QExifURational
(
72
,
1
))
writeExifValues
(
stream
,
d
->
gpsIfdValues
);
:
d
->
thumbnailXResolution
;
}
QExifValue
yResolution
=
d
->
thumbnailYResolution
.
isNull
()
Q_ASSERT
(
startPos
+
offset
==
device
->
pos
());
?
QExifValue
(
QExifURational
(
72
,
1
))
:
d
->
thumbnailYResolution
;
QExifValue
resolutionUnit
=
d
->
thumbnailResolutionUnit
.
isNull
()
if
(
!
d
->
thumbnailData
.
isEmpty
())
{
?
QExifValue
(
quint16
(
2
))
offset
+=
86
;
:
d
->
thumbnailResolutionUnit
;
QExifValue
orientation
=
d
->
thumbnailOrientation
.
isNull
()
stream
<<
quint16
(
7
);
?
QExifValue
(
quint16
(
0
))
:
d
->
thumbnailOrientation
;
writeExifHeader
(
stream
,
Compression
,
QExifValue
(
quint16
(
6
)),
offset
);
QExifValue
xResolution
=
d
->
thumbnailXResolution
.
isNull
()
?
QExifValue
(
QExifURational
(
72
,
1
))
:
d
->
thumbnailXResolution
;
offset
=
writeExifHeader
(
stream
,
XResolution
,
xResolution
,
offset
);
QExifValue
yResolution
=
d
->
thumbnailYResolution
.
isNull
()
offset
=
writeExifHeader
(
stream
,
YResolution
,
yResolution
,
offset
);
?
QExifValue
(
QExifURational
(
72
,
1
))
:
d
->
thumbnailYResolution
;
writeExifHeader
(
stream
,
ResolutionUnit
,
resolutionUnit
,
offset
);
QExifValue
resolutionUnit
=
d
->
thumbnailResolutionUnit
.
isNull
()
writeExifHeader
(
stream
,
Orientation
,
orientation
,
offset
);
?
QExifValue
(
quint16
(
2
))
writeExifHeader
(
stream
,
JpegInterchangeFormat
,
QExifValue
(
offset
),
offset
);
:
d
->
thumbnailResolutionUnit
;
writeExifHeader
(
stream
,
JpegInterchangeFormatLength
,
QExifValue
(
quint32
(
d
->
thumbnailData
.
size
())),
offset
);
writeExifValue
(
stream
,
xResolution
);
QExifValue
orientation
=
d
->
thumbnailOrientation
.
isNull
()
writeExifValue
(
stream
,
yResolution
);
?
QExifValue
(
quint16
(
0
))
:
d
->
thumbnailOrientation
;
Q_ASSERT
(
startPos
+
offset
==
device
->
pos
()
);
writeExifHeader
(
stream
,
Compression
,
QExifValue
(
quint16
(
6
)),
offset
);
device
->
write
(
d
->
thumbnailData
);
offset
=
writeExifHeader
(
stream
,
XResolution
,
xResolution
,
offset
);
offset
=
writeExifHeader
(
stream
,
YResolution
,
yResolution
,
offset
);
offset
+=
d
->
thumbnailData
.
size
();
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
());
Q_ASSERT
(
startPos
+
offset
==
device
->
pos
());
d
->
size
=
offset
;
device
->
write
(
d
->
thumbnailData
);
offset
+=
d
->
thumbnailData
.
size
();
}
Q_ASSERT
(
startPos
+
offset
==
device
->
pos
());
d
->
size
=
offset
;
return
offset
;
return
offset
;
}
}
src/utils/QExifImageHeader.h
View file @
e249bc3e
...
@@ -51,298 +51,286 @@
...
@@ -51,298 +51,286 @@
#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
,
Long
=
4
,
Long
=
4
,
Rational
=
5
,
Rational
=
5
,
Undefined
=
7
,
Undefined
=
7
,
SignedLong
=
9
,
SignedLong
=
9
,
SignedRational
=
10
SignedRational
=
10
};
};
enum
TextEncoding
{
enum
TextEncoding
NoEncoding
,
{
AsciiEncoding
,
NoEncoding
,
JisEncoding
,
AsciiEncoding
,
UnicodeEncoding
,
JisEncoding
,
UndefinedEncoding
UnicodeEncoding
,
};
UndefinedEncoding
};
QExifValue
();
QExifValue
(
quint8
value
);
QExifValue
();
QExifValue
(
const
QVector
<
quint8
>
&
value
);
QExifValue
(
quint8
value
);
QExifValue
(
const
QString
&
value
,
TextEncoding
encoding
=
NoEncoding
);
QExifValue
(
const
QVector
<
quint8
>
&
value
);
QExifValue
(
quint16
value
);
QExifValue
(
const
QString
&
value
,
TextEncoding
encoding
=
NoEncoding
);
QExifValue
(
const
QVector
<
quint16
>
&
value
);
QExifValue
(
quint16
value
);
QExifValue
(
quint32
value
);
QExifValue
(
const
QVector
<
quint16
>
&
value
);
QExifValue
(
const
QVector
<
quint32
>
&
value
);
QExifValue
(
quint32
value
);
QExifValue
(
const
QExifURational
&
value
);
QExifValue
(
const
QVector
<
quint32
>
&
value
);
QExifValue
(
const
QVector
<
QExifURational
>
&
value
);
QExifValue
(
const
QExifURational
&
value
);
QExifValue
(
const
QByteArray
&
value
);
QExifValue
(
const
QVector
<
QExifURational
>
&
value
);
QExifValue
(
qint32
value
);
QExifValue
(
const
QByteArray
&
value
);
QExifValue
(
const
QVector
<
qint32
>
&
value
);
QExifValue
(
qint32
value
);
QExifValue
(
const
QExifSRational
&
value
);
QExifValue
(
const
QVector
<
qint32
>
&
value
);
QExifValue
(
const
QVector
<
QExifSRational
>
&
value
);
QExifValue
(
const
QExifSRational
&
value
);
QExifValue
(
const
QDateTime
&
value
);
QExifValue
(
const
QVector
<
QExifSRational
>
&
value
);
QExifValue
(
const
QExifValue
&
other
);
QExifValue
(
const
QDateTime
&
value
);
QExifValue
&
operator
=
(
const
QExifValue
&
other
);
QExifValue
(
const
QExifValue
&
other
);
~
QExifValue
();
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
;
quint8
toByte
()
const
;
QString
toString
()
const
;
QVector
<
quint8
>
toByteVector
()
const
;
quint16
toShort
()
const
;
QString
toString
()
const
;
QVector
<
quint16
>
toShortVector
()
const
;
quint16
toShort
()
const
;
quint32
toLong
()
const
;
QVector
<
quint16
>
toShortVector
()
const
;
QVector
<
quint32
>
toLongVector
()
const
;
quint32
toLong
()
const
;
QExifURational
toRational
()
const
;
QVector
<
quint32
>
toLongVector
()
const
;
QVector
<
QExifURational
>
toRationalVector
()
const
;
QExifURational
toRational
()
const
;
QByteArray
toByteArray
()
const
;
QVector
<
QExifURational
>
toRationalVector
()
const
;
qint32
toSignedLong
()
const
;
QByteArray
toByteArray
()
const
;
QVector
<
qint32
>
toSignedLongVector
()
const
;
qint32
toSignedLong
()
const
;
QExifSRational
toSignedRational
()
const
;
QVector
<
qint32
>
toSignedLongVector
()
const
;
QVector
<
QExifSRational
>
toSignedRationalVector
()
const
;
QExifSRational
toSignedRational
()
const
;
QDateTime
toDateTime
()
const
;
QVector
<
QExifSRational
>
toSignedRationalVector
()
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:
public:
enum
ImageTag
enum
ImageTag
{
{
ImageWidth
=
0x0100
,
ImageLength
=
0x0101
,
ImageWidth
=
0x0100
,
BitsPerSample
=
0x0102
,
ImageLength
=
0x0101
,
Compression
=
0x0103
,
BitsPerSample
=
0x0102
,
PhotometricInterpretation
=
0x0106
,
Compression
=
0x0103
,
Orientation
=
0x0112
,
PhotometricInterpretation
=
0x0106
,
SamplesPerPixel
=
0x0115
,
Orientation
=
0x0112
,
PlanarConfiguration
=
0x011C
,
SamplesPerPixel
=
0x0115
,
YCbCrSubSampling
=
0x0212
,
PlanarConfiguration
=
0x011C
,
XResolution
=
0x011A
,
YCbCrSubSampling
=
0x0212
,
YResolution
=
0x011B
,
XResolution
=
0x011A
,
ResolutionUnit
=
0x0128
,
YResolution
=
0x011B
,
StripOffsets
=
0x0111
,
ResolutionUnit
=
0x0128
,
RowsPerStrip
=
0x0116
,
StripOffsets
=
0x0111
,
StripByteCounts
=
0x0117
,
RowsPerStrip
=
0x0116
,
TransferFunction
=
0x012D
,
StripByteCounts
=
0x0117
,
WhitePoint
=
0x013E
,
TransferFunction
=
0x012D
,
PrimaryChromaciticies
=
0x013F
,
WhitePoint
=
0x013E
,
YCbCrCoefficients
=
0x0211
,
PrimaryChromaciticies
=
0x013F
,
ReferenceBlackWhite
=
0x0214
,
YCbCrCoefficients
=
0x0211
,
DateTime
=
0x0132
,
ReferenceBlackWhite
=
0x0214
,
ImageDescription
=
0x010E
,
DateTime
=
0x0132
,
Make
=
0x010F
,
ImageDescription
=
0x010E
,
Model
=
0x0110
,
Make
=
0x010F
,
Software
=
0x0131
,
Model
=
0x0110
,
Artist
=
0x013B
,
Software
=
0x0131
,
Copyright
=
0x8298
Artist
=
0x013B
,
};
Copyright
=
0x8298
};
enum
ExifExtendedTag
{
ExifVersion
=
0x9000
,
enum
ExifExtendedTag
FlashPixVersion
=
0xA000
,
{
ColorSpace
=
0xA001
,
ExifVersion
=
0x9000
,
ComponentsConfiguration
=
0x9101
,
FlashPixVersion
=
0xA000
,
CompressedBitsPerPixel
=
0x9102
,
ColorSpace
=
0xA001
,
PixelXDimension
=
0xA002
,
ComponentsConfiguration
=
0x9101
,
PixelYDimension
=
0xA003
,
CompressedBitsPerPixel
=
0x9102
,
MakerNote
=
0x927C
,
PixelXDimension
=
0xA002
,
UserComment
=
0x9286
,
PixelYDimension
=
0xA003
,
RelatedSoundFile
=
0xA004
,
MakerNote
=
0x927C
,
DateTimeOriginal
=
0x9003
,
UserComment
=
0x9286
,
DateTimeDigitized
=
0x9004
,
RelatedSoundFile
=
0xA004
,
SubSecTime
=
0x9290
,
DateTimeOriginal
=
0x9003
,
SubSecTimeOriginal
=
0x9291
,
DateTimeDigitized
=
0x9004
,
SubSecTimeDigitized
=
0x9292
,
SubSecTime
=
0x9290
,
ImageUniqueId
=
0xA420
,
SubSecTimeOriginal
=
0x9291
,
ExposureTime
=
0x829A
,
SubSecTimeDigitized
=
0x9292
,
FNumber
=
0x829D
,
ImageUniqueId
=
0xA420
,
ExposureProgram
=
0x8822
,
SpectralSensitivity
=
0x8824
,
ExposureTime
=
0x829A
,
ISOSpeedRatings
=
0x8827
,
FNumber
=
0x829D
,
Oecf
=
0x8828
,
ExposureProgram
=
0x8822
,
ShutterSpeedValue
=
0x9201
,
SpectralSensitivity
=
0x8824
,
ApertureValue
=
0x9202
,
ISOSpeedRatings
=
0x8827
,
BrightnessValue
=
0x9203
,
Oecf
=
0x8828
,
ExposureBiasValue
=
0x9204
,
ShutterSpeedValue
=
0x9201
,
MaxApertureValue
=
0x9205
,
ApertureValue
=
0x9202
,
SubjectDistance
=
0x9206
,
BrightnessValue
=
0x9203
,
MeteringMode
=
0x9207
,
ExposureBiasValue
=
0x9204
,
LightSource
=
0x9208
,
MaxApertureValue
=
0x9205
,
Flash
=
0x9209
,
SubjectDistance
=
0x9206
,
FocalLength
=
0x920A
,
MeteringMode
=
0x9207
,
SubjectArea
=
0x9214
,
LightSource
=
0x9208
,
FlashEnergy
=
0xA20B
,
Flash
=
0x9209
,
SpatialFrequencyResponse
=
0xA20C
,
FocalLength
=
0x920A
,
FocalPlaneXResolution
=
0xA20E
,
SubjectArea
=
0x9214
,
FocalPlaneYResolution
=
0xA20F
,
FlashEnergy
=
0xA20B
,
FocalPlaneResolutionUnit
=
0xA210
,
SpatialFrequencyResponse
=
0xA20C
,
SubjectLocation
=
0xA214
,
FocalPlaneXResolution
=
0xA20E
,
ExposureIndex
=
0xA215
,
FocalPlaneYResolution
=
0xA20F
,
SensingMethod
=
0xA217
,
FocalPlaneResolutionUnit
=
0xA210
,
FileSource
=
0xA300
,
SubjectLocation
=
0xA214
,
SceneType
=
0xA301
,
ExposureIndex
=
0xA215
,
CfaPattern
=
0xA302
,
SensingMethod
=
0xA217
,
CustomRendered
=
0xA401
,
FileSource
=
0xA300
,
ExposureMode
=
0xA402
,
SceneType
=
0xA301
,
WhiteBalance
=
0xA403
,
CfaPattern
=
0xA302
,
DigitalZoomRatio
=
0xA404
,
CustomRendered
=
0xA401
,
FocalLengthIn35mmFilm
=
0xA405
,
ExposureMode
=
0xA402
,
SceneCaptureType
=
0xA406
,
WhiteBalance
=
0xA403
,
GainControl
=
0xA407
,
DigitalZoomRatio
=
0xA404
,
Contrast
=
0xA408
,
FocalLengthIn35mmFilm
=
0xA405
,
Saturation
=
0xA409
,
SceneCaptureType
=
0xA406
,
Sharpness
=
0xA40A
,
GainControl
=
0xA407
,
DeviceSettingDescription
=
0xA40B
,
Contrast
=
0xA408
,
SubjectDistanceRange
=
0x40C
Saturation
=
0xA409
,
};
Sharpness
=
0xA40A
,
DeviceSettingDescription
=
0xA40B
,
enum
GpsTag
{
SubjectDistanceRange
=
0x40C
GpsVersionId
=
0x0000
,
};
GpsLatitudeRef
=
0x0001
,
GpsLatitude
=
0x0002
,
enum
GpsTag
GpsLongitudeRef
=
0x0003
,
{
GpsLongitude
=
0x0004
,
GpsVersionId
=
0x0000
,
GpsAltitudeRef
=
0x0005
,
GpsLatitudeRef
=
0x0001
,
GpsAltitude
=
0x0006
,
GpsLatitude
=
0x0002
,
GpsTimeStamp
=
0x0007
,
GpsLongitudeRef
=
0x0003
,
GpsSatellites
=
0x0008
,
GpsLongitude
=
0x0004
,
GpsStatus
=
0x0009
,
GpsAltitudeRef
=
0x0005
,
GpsMeasureMode
=
0x000A
,
GpsAltitude
=
0x0006
,
GpsDop
=
0x000B
,
GpsTimeStamp
=
0x0007
,
GpsSpeedRef
=
0x000C
,
GpsSatellites
=
0x0008
,
GpsSpeed
=
0x000D
,
GpsStatus
=
0x0009
,
GpsTrackRef
=
0x000E
,
GpsMeasureMode
=
0x000A
,
GpsTrack
=
0x000F
,
GpsDop
=
0x000B
,
GpsImageDirectionRef
=
0x0010
,
GpsSpeedRef
=
0x000C
,
GpsImageDirection
=
0x0011
,
GpsSpeed
=
0x000D
,
GpsMapDatum
=
0x0012
,
GpsTrackRef
=
0x000E
,
GpsDestLatitudeRef
=
0x0013
,
GpsTrack
=
0x000F
,
GpsDestLatitude
=
0x0014
,
GpsImageDirectionRef
=
0x0010
,
GpsDestLongitudeRef
=
0x0015
,
GpsImageDirection
=
0x0011
,
GpsDestLongitude
=
0x0016
,
GpsMapDatum
=
0x0012
,
GpsDestBearingRef
=
0x0017
,
GpsDestLatitudeRef
=
0x0013
,
GpsDestBearing
=
0x0018
,
GpsDestLatitude
=
0x0014
,
GpsDestDistanceRef
=
0x0019
,
GpsDestLongitudeRef
=
0x0015
,
GpsDestDistance
=
0x001A
,
GpsDestLongitude
=
0x0016
,
GpsProcessingMethod
=
0x001B
,
GpsDestBearingRef
=
0x0017
,
GpsAreaInformation
=
0x001C
,
GpsDestBearing
=
0x0018
,
GpsDateStamp
=
0x001D
,
GpsDestDistanceRef
=
0x0019
,
GpsDifferential
=
0x001E
GpsDestDistance
=
0x001A
,
};
GpsProcessingMethod
=
0x001B
,
GpsAreaInformation
=
0x001C
,
QExifImageHeader
();
GpsDateStamp
=
0x001D
,
explicit
QExifImageHeader
(
const
QString
&
fileName
);
GpsDifferential
=
0x001E
~
QExifImageHeader
();
};
bool
loadFromJpeg
(
const
QString
&
fileName
);
QExifImageHeader
();
bool
loadFromJpeg
(
QIODevice
*
device
);
explicit
QExifImageHeader
(
const
QString
&
fileName
);
bool
saveToJpeg
(
const
QString
&
fileName
)
const
;
~
QExifImageHeader
();
bool
saveToJpeg
(
QIODevice
*
device
)
const
;
bool
loadFromJpeg
(
const
QString
&
fileName
);
bool
read
(
QIODevice
*
device
);
bool
loadFromJpeg
(
QIODevice
*
device
);
qint64
write
(
QIODevice
*
device
)
const
;
bool
saveToJpeg
(
const
QString
&
fileName
)
const
;
bool
saveToJpeg
(
QIODevice
*
device
)
const
;
qint64
size
()
const
;
bool
read
(
QIODevice
*
device
);
QSysInfo
::
Endian
byteOrder
()
const
;
qint64
write
(
QIODevice
*
device
)
const
;
void
clear
();
qint64
size
()
const
;
QList
<
ImageTag
>
imageTags
()
const
;
QSysInfo
::
Endian
byteOrder
()
const
;
QList
<
ExifExtendedTag
>
extendedTags
()
const
;
QList
<
GpsTag
>
gpsTags
()
const
;
void
clear
();
bool
contains
(
ImageTag
tag
)
const
;
QList
<
ImageTag
>
imageTags
()
const
;
bool
contains
(
ExifExtendedTag
tag
)
const
;
QList
<
ExifExtendedTag
>
extendedTags
()
const
;
bool
contains
(
GpsTag
tag
)
const
;
QList
<
GpsTag
>
gpsTags
()
const
;
void
remove
(
ImageTag
tag
);
bool
contains
(
ImageTag
tag
)
const
;
void
remove
(
ExifExtendedTag
tag
);
bool
contains
(
ExifExtendedTag
tag
)
const
;
void
remove
(
GpsTag
tag
);
bool
contains
(
GpsTag
tag
)
const
;
QExifValue
value
(
ImageTag
tag
)
const
;
void
remove
(
ImageTag
tag
);
QExifValue
value
(
ExifExtendedTag
tag
)
const
;
void
remove
(
ExifExtendedTag
tag
);
QExifValue
value
(
GpsTag
tag
)
const
;
void
remove
(
GpsTag
tag
);
void
setValue
(
ImageTag
tag
,
const
QExifValue
&
value
);
QExifValue
value
(
ImageTag
tag
)
const
;
void
setValue
(
ExifExtendedTag
tag
,
const
QExifValue
&
value
);
QExifValue
value
(
ExifExtendedTag
tag
)
const
;
void
setValue
(
GpsTag
tag
,
const
QExifValue
&
value
);
QExifValue
value
(
GpsTag
tag
)
const
;
QImage
thumbnail
()
const
;
void
setValue
(
ImageTag
tag
,
const
QExifValue
&
value
);
void
setThumbnail
(
const
QImage
&
thumbnail
);
void
setValue
(
ExifExtendedTag
tag
,
const
QExifValue
&
value
);
void
setValue
(
GpsTag
tag
,
const
QExifValue
&
value
);
QImage
thumbnail
()
const
;
void
setThumbnail
(
const
QImage
&
thumbnail
);
private:
private:
enum
PrivateTag
enum
PrivateTag
{
{
ExifIfdPointer
=
0x8769
,
ExifIfdPointer
=
0x8769
,
GpsInfoIfdPointer
=
0x8825
,
GpsInfoIfdPointer
=
0x8825
,
InteroperabilityIfdPointer
=
0xA005
,
InteroperabilityIfdPointer
=
0xA005
,
JpegInterchangeFormat
=
0x0201
,
JpegInterchangeFormat
=
0x0201
,
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment