f0a7264e7d08a239cbec723b99c7258e6dbf801e
[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_foreach_entry(pContent, _ExifUtil::ForEachEntryStatic, this);
119 }
120
121 void _ExifUtil::ForEachEntryStatic(struct _ExifEntry *pEntry, void *pUserData)
122 {
123         SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
124
125         _ExifUtil* pUtil = static_cast<_ExifUtil*>(pUserData);
126         SysTryReturnVoidResult(NID_MEDIA, pUtil != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] _ExifUtil instance is not available.");
127
128         pUtil->ForEachEntry(pEntry);
129 }
130
131 void _ExifUtil::ForEachEntry(struct _ExifEntry *pEntry)
132 {
133         SysTryReturnVoidResult(NID_MEDIA, pEntry != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] ExifEntry instance is not available.");
134         SysTryReturnVoidResult(NID_MEDIA, pEntry->parent != null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Entry's parent instance is not available.");
135
136         const ExifByteOrder o = exif_data_get_byte_order (pEntry->parent->parent);
137         ExifRational exifRational;
138
139         switch ((int)pEntry->tag)
140         {
141         case EXIF_TAG_ORIENTATION:
142                 if (pEntry->format == EXIF_FORMAT_SHORT && pEntry->size == 2)
143                 {
144                         __orientation = *(short*)(pEntry->data);
145                         __orientationExist = true;
146                 }
147                 break;
148
149         case EXIF_TAG_GPS_LATITUDE:
150                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
151                 {
152                 /*
153                         exifRational = exif_get_rational (pEntry->data, o);
154
155                         if (exifRational.denominator && exifRational.denominator != 1) {
156                                 __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
157                         }
158                         else
159                         {
160                                 __gpsLatitude = (double)exifRational.numerator;
161                         }
162                 */
163                         __gpsLatitude = 0.0;
164                         for (int i = 0; i < (int)pEntry->components; i++)
165                         {
166                                 exifRational = exif_get_rational (pEntry->data + 8 * i, o);
167                                 if (exifRational.denominator)
168                                 {
169                                         __gpsLatitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
170                                 }
171                                 else
172                                 {
173                                         __gpsLatitude += (double)exifRational.numerator / pow((float)60.0, i);
174                                 }
175                         }
176                         __gpsLatitudeExist = true;
177                 }
178                 break;
179
180         case EXIF_TAG_GPS_LONGITUDE:
181                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
182                 {
183                 /*
184                         exifRational = exif_get_rational (pEntry->data, o);
185
186                         if (exifRational.denominator && exifRational.denominator != 1) {
187                                 __gpsLatitude = (double)exifRational.numerator / (double)exifRational.denominator;
188                         } else {
189                                 __gpsLatitude = (double)exifRational.numerator;
190                         }
191                 */
192                         __gpsLongitude = 0.0;
193
194                         for (int i = 0; i < (int)pEntry->components; i++)
195                         {
196                                 exifRational = exif_get_rational (pEntry->data + 8 * i, o);
197                                 if (exifRational.denominator && exifRational.denominator != 1)
198                                 {
199                                         __gpsLongitude += ((double)exifRational.numerator / (double)exifRational.denominator) / pow((float)60.0, i);
200                                 }
201                                 else
202                                 {
203                                         __gpsLongitude += (double)exifRational.numerator / pow((float)60.0, i);
204                                 }
205                         }
206                         __gpsLongitudeExist = true;
207                 }
208                 break;
209
210         case EXIF_TAG_GPS_ALTITUDE:
211                 if (pEntry->format == EXIF_FORMAT_RATIONAL)
212                 {
213                         exifRational = exif_get_rational (pEntry->data, o);
214
215                         if (exifRational.denominator && exifRational.denominator != 1)
216                         {
217                                 __gpsAltitude = (double)exifRational.numerator / (double)exifRational.denominator;
218                         }
219                         else
220                         {
221                                 __gpsAltitude = (double)exifRational.numerator;
222                         }
223                         __gpsAltitudeExist = true;
224                 }
225                 break;
226
227         default:
228                 break;
229         }
230 }
231
232 result _ExifUtil::GetValue(const Tizen::Base::String& key, int &value)
233 {
234         if (key.Equals(EXIF_TAG_IMAGE_ORIENTATION, true))
235         {
236                 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.");
237                 value = __orientation;
238         }
239         else
240         {
241                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%ls was wrong.", key.GetPointer());
242                 return E_INVALID_ARG;
243         }
244
245         return E_SUCCESS;
246 }
247
248 result _ExifUtil::GetValue(const Tizen::Base::String& key, double &value)
249 {
250         if (key.Equals(EXIF_TAG_IMAGE_GPS_ALTITUDE, true))
251         {
252                 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.");
253                 value = __gpsAltitude;
254         }
255         else if (key.Equals(EXIF_TAG_IMAGE_GPS_LONGITUDE, true))
256         {
257                 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.");
258                 value = __gpsLongitude;
259         } else if (key.Equals(EXIF_TAG_IMAGE_GPS_LATITUDE, true))
260         {
261                 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.");
262                 value = __gpsLatitude;
263         } else
264         {
265                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Key:%ls was wrong.", key.GetPointer());
266                 return E_INVALID_ARG;
267         }
268
269         return E_SUCCESS;
270 }
271
272 }}
273