merge with master
[framework/osp/image-core.git] / src / FMedia_ExifUtil.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include <math.h>
17 #include <libexif/exif-byte-order.h>
18 #include <libexif/exif-data-type.h>
19 #include <libexif/exif-ifd.h>
20 #include <libexif/exif-log.h>
21 #include <libexif/exif-tag.h>
22 #include <libexif/exif-content.h>
23 #include <libexif/exif-mnote-data.h>
24 #include <libexif/exif-mem.h>
25 #include <FBaseSysLog.h>
26 #include "FMedia_ExifUtil.h"
27
28 namespace Tizen { namespace Media
29 {
30
31 const wchar_t* const EXIF_TAG_IMAGE_ORIENTATION = L"Exif.Orientation";
32 const wchar_t* const EXIF_TAG_IMAGE_GPS_ALTITUDE = L"Exif.Gps.Altitude";
33 const wchar_t* const EXIF_TAG_IMAGE_GPS_LONGITUDE = L"Exif.Gps.Longitude";
34 const wchar_t* const EXIF_TAG_IMAGE_GPS_LATITUDE = L"Exif.Gps.Latitude";
35
36 _ExifUtil::_ExifUtil()
37 : __pExifData(null)
38 , __pExifLog(null)
39 , __orientation(-1)
40 , __gpsLongitude(0.0)
41 , __gpsLatitude(0.0)
42 , __gpsAltitude(0.0)
43 , __gpsLongitudeExist(false)
44 , __gpsAltitudeExist(false)
45 , __gpsLatitudeExist(false)
46 , __orientationExist(false)
47 {
48 }
49
50 _ExifUtil::~_ExifUtil()
51 {
52         if (__pExifData)
53         {
54                 exif_data_free(__pExifData);
55         }
56         if (__pExifLog)
57         {
58                 exif_log_free(__pExifLog);
59         }
60 }
61
62 result _ExifUtil::Construct(const byte* pBuf, int length)
63 {
64         result r = E_SUCCESS;
65
66         SysTryCatch(NID_MEDIA, pBuf != null, r = E_INVALID_DATA, E_INVALID_DATA, "[E_INVALID_DATA] Buffer is null. length: %d", length);
67
68         __pExifData = exif_data_new_from_data(pBuf, length);
69         SysTryCatch(NID_MEDIA, __pExifData != null, r = E_INVALID_DATA, E_INVALID_DATA, "[E_INVALID_DATA] exi data is null. length: %d", length);
70
71         __pExifLog = exif_log_new();
72         SysTryCatch(NID_MEDIA, __pExifLog != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] exif_log_new fail");
73
74 #if defined _EXIF_UTIL_LOG_
75         //exif_log_set_func(__pExifLog, _ExifUtil::ExifLogFuncStatic, this);
76         //exif_data_log(__pExifData, __pExifLog);
77 #endif
78         exif_data_foreach_content(__pExifData, _ExifUtil::ForEachContentStatic, this);
79         return r;
80
81 CATCH:
82         if (__pExifLog)
83         {
84                 exif_log_free(__pExifLog);
85         }
86         return r;
87 }
88
89 #if defined _EXIF_UTIL_LOG_
90 //void _ExifUtil::ExifLogFuncStatic(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args, void *data)
91 //{
92 //      ((_ExifUtil*)data)->ExifLogFunc(log, code, domain, format, args);
93 //}
94
95 //void _ExifUtil::ExifLogFunc(ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args)
96 //{
97 //      char msg[1024];
98 //      vsprintf(msg, format, args);
99 //      TLog("ExifLog : %s", msg);
100 //}
101 #endif
102
103 void _ExifUtil::ForEachContentStatic(struct _ExifContent *pContent, void *pUserData)
104 {
105         SysTryReturnVoidResult(NID_MEDIA, pContent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifContent instance is not available.");
106
107         _ExifUtil* pUtil = static_cast<_ExifUtil*>(pUserData);
108         SysTryReturnVoidResult(NID_MEDIA, pUtil != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] _ExifUtil instance is not available.");
109
110         pUtil->ForEachContent(pContent);
111 }
112
113 void _ExifUtil::ForEachContent(struct _ExifContent *pContent)
114 {
115         SysTryReturnVoidResult(NID_MEDIA, pContent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifContent instance is not available.");
116
117         exif_content_log(pContent, __pExifLog);
118         exif_content_dump(pContent, 0);
119
120         exif_content_foreach_entry(pContent, _ExifUtil::ForEachEntryStatic, this);
121 }
122
123 void _ExifUtil::ForEachEntryStatic(struct _ExifEntry *pEntry, void *pUserData)
124 {
125         SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
126
127         _ExifUtil* pUtil = static_cast<_ExifUtil*>(pUserData);
128         SysTryReturnVoidResult(NID_MEDIA, pUtil != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] _ExifUtil instance is not available.");
129
130         pUtil->ForEachEntry(pEntry);
131 }
132
133 void _ExifUtil::ForEachEntry(struct _ExifEntry *pEntry)
134 {
135         SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
136         SysTryReturnVoidResult(NID_MEDIA, pEntry->parent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Entry's parent instance is not available.");
137
138         const ExifByteOrder o = exif_data_get_byte_order (pEntry->parent->parent);
139         ExifRational exifRational;
140
141 #if defined (_EXIF_UTIL_LOG_)
142         char value[1024];
143 #endif
144
145         switch ((int)pEntry->tag)
146         {
147         case EXIF_TAG_ORIENTATION:
148                 if (pEntry->format == EXIF_FORMAT_SHORT && pEntry->size == 2)
149                 {
150                         __orientation = *(short*)(pEntry->data);
151                         __orientationExist = true;
152                 }
153                 break;
154
155         case EXIF_TAG_GPS_LATITUDE:
156                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
157                 {
158                 /*
159                         exifRational = exif_get_rational (pEntry->data, o);
160
161                         if (exifRational.denominator && exifRational.denominator != 1) {
162                                 __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
163                         }
164                         else
165                         {
166                                 __gpsLatitude = (double)exifRational.numerator;
167                         }
168                 */
169                         __gpsLatitude = 0.0;
170                         for (int i = 0; i < (int)pEntry->components; i++)
171                         {
172                                 exifRational = exif_get_rational (pEntry->data + 8 * i, o);
173                                 if (exifRational.denominator)
174                                 {
175                                         __gpsLatitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
176                                 }
177                                 else
178                                 {
179                                         __gpsLatitude += (double)exifRational.numerator / pow((float)60.0, i);
180                                 }
181                         }
182                         __gpsLatitudeExist = true;
183                 }
184                 break;
185
186         case EXIF_TAG_GPS_LONGITUDE:
187                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
188                 {
189                 /*
190                         exifRational = exif_get_rational (pEntry->data, o);
191
192                         if (exifRational.denominator && exifRational.denominator != 1) {
193                                 __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
194                         } else {
195                                 __gpsLatitude = (double)exifRational.numerator;
196                         }
197                 */
198                         __gpsLongitude = 0.0;
199
200                         for (int i = 0; i < (int)pEntry->components; i++)
201                         {
202                                 exifRational = exif_get_rational (pEntry->data + 8 * i, o);
203                                 if (exifRational.denominator && exifRational.denominator != 1)
204                                 {
205                                         __gpsLongitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
206                                 }
207                                 else
208                                 {
209                                         __gpsLongitude += (double)exifRational.numerator / pow((float)60.0, i);
210                                 }
211                         }
212                         __gpsLongitudeExist = true;
213                 }
214                 break;
215
216         case EXIF_TAG_GPS_ALTITUDE:
217                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
218                 {
219                         exifRational = exif_get_rational (pEntry->data, o);
220
221                         if (exifRational.denominator && exifRational.denominator != 1)
222                         {
223                                 __gpsAltitude = (double)exifRational.numerator / (double)exifRational.denominator;
224                         }
225                         else
226                         {
227                                 __gpsAltitude = (double)exifRational.numerator;
228                         }
229                         __gpsAltitudeExist = true;
230                 }
231                 break;
232
233         default:
234                 break;
235         }
236 }
237
238 result _ExifUtil::GetValue(const Tizen::Base::String& key, int &value)
239 {
240         if (key.Equals(EXIF_TAG_IMAGE_ORIENTATION, true))
241         {
242                 SysTryReturn(NID_MEDIA, __orientationExist, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Orientation value was not found.");
243                 value = __orientation;
244         }
245         else
246         {
247                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%S was wrong.", key.GetPointer());
248                 return E_INVALID_ARG;
249         }
250
251         return E_SUCCESS;
252 }
253
254 result _ExifUtil::GetValue(const Tizen::Base::String& key, double &value)
255 {
256         if (key.Equals(EXIF_TAG_IMAGE_GPS_ALTITUDE, true))
257         {
258                 SysTryReturn(NID_MEDIA, __gpsAltitudeExist, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Altitude value was not found.");
259                 value = __gpsAltitude;
260         }
261         else if (key.Equals(EXIF_TAG_IMAGE_GPS_LONGITUDE, true))
262         {
263                 SysTryReturn(NID_MEDIA, __gpsLongitude, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Longitude value was not found.");
264                 value = __gpsLongitude;
265         } else if (key.Equals(EXIF_TAG_IMAGE_GPS_LATITUDE, true))
266         {
267                 SysTryReturn(NID_MEDIA, __gpsLatitude, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] bool instance is not available. Latitude value was not found.");
268                 value = __gpsLatitude;
269         } else
270         {
271                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%S was wrong.", key.GetPointer());
272                 return E_INVALID_ARG;
273         }
274
275         return E_SUCCESS;
276 }
277
278 }}
279