1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt scene graph research project.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 // This file was copied from Qt Extended 4.5
43 
44 #ifndef QEXIFIMAGEHEADER_H_
45 #define QEXIFIMAGEHEADER_H_
46 
47 #include <QPair>
48 #include <QVector>
49 #include <QSharedData>
50 #include <QVariant>
51 #include <QSysInfo>
52 #include <QIODevice>
53 
54 typedef QPair<quint32, quint32> QExifURational;
55 typedef QPair<qint32, qint32> QExifSRational;
56 
57 class QExifValuePrivate;
58 
59 class QExifValue {
60 public:
61   enum Type {
62     Byte = 1,
63     Ascii = 2,
64     Short = 3,
65     Long = 4,
66     Rational = 5,
67     Undefined = 7,
68     SignedLong = 9,
69     SignedRational = 10
70   };
71 
72   enum TextEncoding {
73     NoEncoding,
74     AsciiEncoding,
75     JisEncoding,
76     UnicodeEncoding,
77     UndefinedEncoding
78   };
79 
80   QExifValue ();
81   QExifValue (quint8 value);
82   QExifValue (const QVector<quint8> &value);
83   QExifValue (const QString &value, TextEncoding encoding = NoEncoding);
84   QExifValue (quint16 value);
85   QExifValue (const QVector<quint16> &value);
86   QExifValue (quint32 value);
87   QExifValue (const QVector<quint32> &value);
88   QExifValue (const QExifURational &value);
89   QExifValue (const QVector<QExifURational> &value);
90   QExifValue (const QByteArray &value);
91   QExifValue (qint32 value);
92   QExifValue (const QVector<qint32> &value);
93   QExifValue (const QExifSRational &value);
94   QExifValue (const QVector<QExifSRational> &value);
95   QExifValue (const QDateTime &value);
96   QExifValue (const QExifValue &other);
97   QExifValue &operator= (const QExifValue &other);
98   ~QExifValue ();
99 
100   bool operator== (const QExifValue &other) const;
101 
102   bool isNull () const;
103 
104   int type () const;
105   int count () const;
106 
107   TextEncoding encoding () const;
108 
109   quint8 toByte () const;
110   QVector<quint8> toByteVector () const;
111   QString toString () const;
112   quint16 toShort () const;
113   QVector<quint16> toShortVector () const;
114   quint32 toLong () const;
115   QVector<quint32> toLongVector () const;
116   QExifURational toRational () const;
117   QVector<QExifURational> toRationalVector () const;
118   QByteArray toByteArray () const;
119   qint32 toSignedLong () const;
120   QVector<qint32> toSignedLongVector () const;
121   QExifSRational toSignedRational () const;
122   QVector<QExifSRational> toSignedRationalVector () const;
123   QDateTime toDateTime () const;
124 
125 private:
126   QExplicitlySharedDataPointer<QExifValuePrivate> d;
127 };
128 
129 struct ExifIfdHeader;
130 
131 class QExifImageHeaderPrivate;
132 
133 class QExifImageHeader {
134   Q_DISABLE_COPY(QExifImageHeader)
135 
136 public:
137   enum ImageTag {
138     ImageWidth = 0x0100,
139     ImageLength = 0x0101,
140     BitsPerSample = 0x0102,
141     Compression = 0x0103,
142     PhotometricInterpretation = 0x0106,
143     Orientation = 0x0112,
144     SamplesPerPixel = 0x0115,
145     PlanarConfiguration = 0x011C,
146     YCbCrSubSampling = 0x0212,
147     XResolution = 0x011A,
148     YResolution = 0x011B,
149     ResolutionUnit = 0x0128,
150     StripOffsets = 0x0111,
151     RowsPerStrip = 0x0116,
152     StripByteCounts = 0x0117,
153     TransferFunction = 0x012D,
154     WhitePoint = 0x013E,
155     PrimaryChromaciticies = 0x013F,
156     YCbCrCoefficients = 0x0211,
157     ReferenceBlackWhite = 0x0214,
158     DateTime = 0x0132,
159     ImageDescription = 0x010E,
160     Make = 0x010F,
161     Model = 0x0110,
162     Software = 0x0131,
163     Artist = 0x013B,
164     Copyright = 0x8298
165   };
166 
167   enum ExifExtendedTag {
168     ExifVersion = 0x9000,
169     FlashPixVersion = 0xA000,
170     ColorSpace = 0xA001,
171     ComponentsConfiguration = 0x9101,
172     CompressedBitsPerPixel = 0x9102,
173     PixelXDimension = 0xA002,
174     PixelYDimension = 0xA003,
175     MakerNote = 0x927C,
176     UserComment = 0x9286,
177     RelatedSoundFile = 0xA004,
178     DateTimeOriginal = 0x9003,
179     DateTimeDigitized = 0x9004,
180     SubSecTime = 0x9290,
181     SubSecTimeOriginal = 0x9291,
182     SubSecTimeDigitized = 0x9292,
183     ImageUniqueId = 0xA420,
184     ExposureTime = 0x829A,
185     FNumber = 0x829D,
186     ExposureProgram = 0x8822,
187     SpectralSensitivity = 0x8824,
188     ISOSpeedRatings = 0x8827,
189     Oecf = 0x8828,
190     ShutterSpeedValue = 0x9201,
191     ApertureValue = 0x9202,
192     BrightnessValue = 0x9203,
193     ExposureBiasValue = 0x9204,
194     MaxApertureValue = 0x9205,
195     SubjectDistance = 0x9206,
196     MeteringMode = 0x9207,
197     LightSource = 0x9208,
198     Flash = 0x9209,
199     FocalLength = 0x920A,
200     SubjectArea = 0x9214,
201     FlashEnergy = 0xA20B,
202     SpatialFrequencyResponse = 0xA20C,
203     FocalPlaneXResolution = 0xA20E,
204     FocalPlaneYResolution = 0xA20F,
205     FocalPlaneResolutionUnit = 0xA210,
206     SubjectLocation = 0xA214,
207     ExposureIndex = 0xA215,
208     SensingMethod = 0xA217,
209     FileSource = 0xA300,
210     SceneType = 0xA301,
211     CfaPattern = 0xA302,
212     CustomRendered = 0xA401,
213     ExposureMode = 0xA402,
214     WhiteBalance = 0xA403,
215     DigitalZoomRatio = 0xA404,
216     FocalLengthIn35mmFilm = 0xA405,
217     SceneCaptureType = 0xA406,
218     GainControl = 0xA407,
219     Contrast = 0xA408,
220     Saturation = 0xA409,
221     Sharpness = 0xA40A,
222     DeviceSettingDescription = 0xA40B,
223     SubjectDistanceRange = 0x40C
224   };
225 
226   enum GpsTag {
227     GpsVersionId = 0x0000,
228     GpsLatitudeRef = 0x0001,
229     GpsLatitude = 0x0002,
230     GpsLongitudeRef = 0x0003,
231     GpsLongitude = 0x0004,
232     GpsAltitudeRef = 0x0005,
233     GpsAltitude = 0x0006,
234     GpsTimeStamp = 0x0007,
235     GpsSatellites = 0x0008,
236     GpsStatus = 0x0009,
237     GpsMeasureMode = 0x000A,
238     GpsDop = 0x000B,
239     GpsSpeedRef = 0x000C,
240     GpsSpeed = 0x000D,
241     GpsTrackRef = 0x000E,
242     GpsTrack = 0x000F,
243     GpsImageDirectionRef = 0x0010,
244     GpsImageDirection = 0x0011,
245     GpsMapDatum = 0x0012,
246     GpsDestLatitudeRef = 0x0013,
247     GpsDestLatitude = 0x0014,
248     GpsDestLongitudeRef = 0x0015,
249     GpsDestLongitude = 0x0016,
250     GpsDestBearingRef = 0x0017,
251     GpsDestBearing = 0x0018,
252     GpsDestDistanceRef = 0x0019,
253     GpsDestDistance = 0x001A,
254     GpsProcessingMethod = 0x001B,
255     GpsAreaInformation = 0x001C,
256     GpsDateStamp = 0x001D,
257     GpsDifferential = 0x001E
258   };
259 
260   QExifImageHeader ();
261   explicit QExifImageHeader (const QString &fileName);
262   ~QExifImageHeader ();
263 
264   bool loadFromJpeg (const QString &fileName);
265   bool loadFromJpeg (QIODevice *device);
266   bool saveToJpeg (const QString &fileName) const;
267   bool saveToJpeg (QIODevice *device) const;
268 
269   bool read (QIODevice *device);
270   qint64 write (QIODevice *device) const;
271 
272   qint64 size () const;
273 
274   QSysInfo::Endian byteOrder () const;
275 
276   void clear ();
277 
278   QList<ImageTag> imageTags () const;
279   QList<ExifExtendedTag> extendedTags () const;
280   QList<GpsTag> gpsTags () const;
281 
282   bool contains (ImageTag tag) const;
283   bool contains (ExifExtendedTag tag) const;
284   bool contains (GpsTag tag) const;
285 
286   void remove (ImageTag tag);
287   void remove (ExifExtendedTag tag);
288   void remove (GpsTag tag);
289 
290   QExifValue value (ImageTag tag) const;
291   QExifValue value (ExifExtendedTag tag) const;
292   QExifValue value (GpsTag tag) const;
293 
294   void setValue (ImageTag tag, const QExifValue &value);
295   void setValue (ExifExtendedTag tag, const QExifValue &value);
296   void setValue (GpsTag tag, const QExifValue &value);
297 
298   QImage thumbnail () const;
299   void setThumbnail (const QImage &thumbnail);
300 
301 private:
302   enum PrivateTag {
303     ExifIfdPointer = 0x8769,
304     GpsInfoIfdPointer = 0x8825,
305     InteroperabilityIfdPointer = 0xA005,
306     JpegInterchangeFormat = 0x0201,
307     JpegInterchangeFormatLength = 0x0202
308   };
309 
310   QByteArray extractExif (QIODevice *device) const;
311 
312   QList<ExifIfdHeader> readIfdHeaders (QDataStream &stream) const;
313 
314   QExifValue readIfdValue (QDataStream &stream, int startPos, const ExifIfdHeader &header) const;
315   template<typename T>
316   QMap<T, QExifValue> readIfdValues (QDataStream &stream, int startPos, const QList<ExifIfdHeader> &headers) const;
317   template<typename T>
318   QMap<T, QExifValue> readIfdValues (QDataStream &stream, int startPos, const QExifValue &pointer) const;
319 
320   quint32 writeExifHeader (QDataStream &stream, quint16 tag, const QExifValue &value, quint32 offset) const;
321   void writeExifValue (QDataStream &stream, const QExifValue &value) const;
322 
323   template<typename T>
324   quint32 writeExifHeaders (QDataStream &stream, const QMap<T, QExifValue> &values, quint32 offset) const;
325   template<typename T>
326   void writeExifValues (QDataStream &target, const QMap<T, QExifValue> &values) const;
327 
328   quint32 sizeOf (const QExifValue &value) const;
329 
330   template<typename T>
331   quint32 calculateSize (const QMap<T, QExifValue> &values) const;
332 
333   QExifImageHeaderPrivate *d;
334 };
335 
336 #endif // ifndef QEXIFIMAGEHEADER_H_
337