|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Exif-utilities for harvester |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "harvesterexifutil.h" |
|
19 |
|
20 #include "mdsutils.h" |
|
21 #include "mdeobjectdef.h" |
|
22 #include "mdeconstants.h" |
|
23 #include "mdeproperty.h" |
|
24 #include "tz.h" |
|
25 #include <ExifModify.h> |
|
26 |
|
27 |
|
28 |
|
29 using namespace MdeConstants; |
|
30 |
|
31 const TUint16 KIdColorSpace = 0xA001; |
|
32 const TUint16 KIdResolutionUnit = 0x0128; |
|
33 const TUint16 KIdYbCrPositioning = 0x0213; |
|
34 const TUint16 KIdImageDescription = 0x010E; |
|
35 const TUint16 KIdCopyright = 0x8298; |
|
36 const TUint16 KIdUserComment = 0x9286; |
|
37 const TUint16 KIdDateTime = 0x0132; |
|
38 const TUint16 KIdDateTimeOriginal = 0x9003; |
|
39 const TUint16 KIdDateTimeDigitized = 0x9004; |
|
40 const TUint16 KIdDateTimeModified = 0x132; |
|
41 const TUint16 KIdFNumber = 0x829D; |
|
42 const TUint16 KIdMake = 0x010F; |
|
43 const TUint16 KIdModel = 0x0110; |
|
44 const TUint16 KIdFocalLength = 0x920A; |
|
45 const TUint16 KIdFocalLengthIn35mm = 0xA405; |
|
46 const TUint16 KIdSamplesPerPixel = 0x0115; |
|
47 const TUint16 KIdISOSpeedRatings = 0x8827; |
|
48 const TUint16 KIdComponentsConfig = 0x9101; |
|
49 const TUint16 KIdArtist = 0x013B; |
|
50 const TUint16 KIdPixelXDimension = 0xA002; |
|
51 const TUint16 KIdPixelYDimension = 0xA003; |
|
52 const TUint16 KIdRelatedSoundFile = 0xA004; |
|
53 const TUint16 KIdFocalPlaneResolutionUnit = 0xA210; |
|
54 const TUint16 KIdFocalPlaneXResolution = 0xA20E; |
|
55 const TUint16 KIdFocalPlaneYResolution = 0xA20F; |
|
56 |
|
57 const TUint16 KIdExposureTime = 0x829A; |
|
58 const TUint16 KIdApertureValue = 0x9202; |
|
59 const TUint16 KIdExposureBias = 0x9204; |
|
60 const TUint16 KIdMeteringMode = 0x9207; |
|
61 const TUint16 KIdShutterSpeed = 0x9201; |
|
62 const TUint16 KIdXResolution = 0x011A; |
|
63 const TUint16 KIdYResolution = 0x011B; |
|
64 const TUint16 KIdWhiteBalance = 0xA403; |
|
65 const TUint16 KIdExposureProgram = 0x8822; |
|
66 const TUint16 KIdFlash = 0x9209; |
|
67 const TUint16 KIdOrientation = 0x112; |
|
68 |
|
69 const TUint16 KIdGpsLatitudeRef = 0x1; |
|
70 const TUint16 KIdGpsLatitude = 0x2; |
|
71 const TUint16 KIdGpsLongitudeRef = 0x3; |
|
72 const TUint16 KIdGpsLongitude = 0x4; |
|
73 const TUint16 KIdGpsAltitudeRef = 0x5; |
|
74 const TUint16 KIdGpsAltitude = 0x6; |
|
75 const TUint16 KIdGpsMeasureMode = 0xA; |
|
76 const TUint16 KIdGpsDop = 0xB; |
|
77 const TUint16 KIdGpsMapDatum = 0x12; |
|
78 |
|
79 _LIT( KExifDateTimeFormat, "%F%Y:%M:%D %H:%T:%S\0" ); |
|
80 const TInt KDateBufferSize = 20; |
|
81 const TInt KCoordinateBufferSize = 24; |
|
82 |
|
83 // This is needed for exif description field |
|
84 _LIT8( KAsciiCodeDesignation, "\x41\x53\x43\x49\x49\x00\x00\x00"); |
|
85 _LIT8( KJisCodeDesignation, "\x4A\x49\x53\x00\x00\x00\x00\x00"); |
|
86 _LIT8( KUnicodeCodeDesignation, "\x55\x4E\x49\x43\x4F\x44\x45\x00"); |
|
87 _LIT8( KUnknownCodeDesignation, "\x00\x00\x00\x00\x00\x00\x00\x00"); |
|
88 |
|
89 _LIT8( KNorth, "N\0" ); |
|
90 _LIT8( KSouth, "S\0" ); |
|
91 _LIT8( KEast, "E\0" ); |
|
92 _LIT8( KWest, "W\0" ); |
|
93 _LIT8( KMeasureMode2, "2\0" ); |
|
94 _LIT8( KMeasureMode3, "3\0" ); |
|
95 _LIT8( KMapDatum, "WGS-84\0"); |
|
96 |
|
97 CHarvesterExifUtil::CHarvesterExifUtil() : |
|
98 iSession( NULL ), iDefaultNamespace( NULL ) |
|
99 { |
|
100 } |
|
101 |
|
102 |
|
103 CHarvesterExifUtil::~CHarvesterExifUtil() |
|
104 { |
|
105 } |
|
106 |
|
107 EXPORT_C CHarvesterExifUtil* CHarvesterExifUtil::NewLC() |
|
108 { |
|
109 CHarvesterExifUtil* self = new (ELeave)CHarvesterExifUtil(); |
|
110 CleanupStack::PushL(self); |
|
111 self->ConstructL(); |
|
112 return self; |
|
113 } |
|
114 |
|
115 EXPORT_C CHarvesterExifUtil* CHarvesterExifUtil::NewL() |
|
116 { |
|
117 CHarvesterExifUtil* self=CHarvesterExifUtil::NewLC(); |
|
118 CleanupStack::Pop( self ); // self; |
|
119 return self; |
|
120 } |
|
121 |
|
122 void CHarvesterExifUtil::ConstructL() |
|
123 { |
|
124 |
|
125 } |
|
126 |
|
127 EXPORT_C void CHarvesterExifUtil::SetSession( CMdESession* aSession ) |
|
128 { |
|
129 iSession = aSession; |
|
130 if ( !iDefaultNamespace && aSession ) |
|
131 { |
|
132 TRAP_IGNORE( iDefaultNamespace = &iSession->GetDefaultNamespaceDefL() ); |
|
133 } |
|
134 } |
|
135 |
|
136 |
|
137 EXPORT_C TBool CHarvesterExifUtil::IsValidExifData(TPtr8 aPtr) |
|
138 { |
|
139 WRITELOG( "CHarvesterExifUtil::IsValidExifData start" ); |
|
140 |
|
141 CExifRead* reader = NULL; |
|
142 |
|
143 TRAPD(err, reader = CExifRead::NewL(aPtr, CExifRead::ENoJpeg | CExifRead::ENoTagChecking)); |
|
144 if (err != KErrNone || !reader ) |
|
145 { |
|
146 WRITELOG1( "CHarvesterExifUtil::IsValidExifData - error code: %d", err ); |
|
147 |
|
148 return EFalse; |
|
149 } |
|
150 |
|
151 delete reader; |
|
152 |
|
153 WRITELOG( "CHarvesterExifUtil::IsValidExifData end" ); |
|
154 |
|
155 return ETrue; |
|
156 } |
|
157 |
|
158 void CHarvesterExifUtil::StripNulls( HBufC& aString ) |
|
159 { |
|
160 _LIT( KNull, "\0" ); |
|
161 _LIT( KSpace, " " ); |
|
162 |
|
163 TInt pos( 0 ); |
|
164 while( (pos = aString.Find( KNull ) ) != KErrNotFound ) |
|
165 { |
|
166 aString.Des().Replace( pos, 1, KSpace ); |
|
167 } |
|
168 aString.Des().TrimAll(); |
|
169 } |
|
170 |
|
171 HBufC16* CHarvesterExifUtil::ReadExifTagL( const CExifRead& aReader, TExifIfdType aIFD, TUint16 aTagID ) |
|
172 { |
|
173 HBufC16* destination = NULL; |
|
174 if( aReader.TagExists( aTagID, aIFD ) ) |
|
175 { |
|
176 const CExifTag* tag = aReader.GetTagL( aIFD, aTagID ); |
|
177 destination = CnvUtfConverter::ConvertToUnicodeFromUtf8L( tag->Data() ); |
|
178 StripNulls( *destination ); |
|
179 } |
|
180 return destination; |
|
181 } |
|
182 |
|
183 EXPORT_C TInt CHarvesterExifUtil::ReadExifDataL( CHarvestData& aHd, CFileData& aFileData ) |
|
184 { |
|
185 WRITELOG( "CHarvesterExifUtil::ReadExifDataL()" ); |
|
186 |
|
187 CExifRead* reader = CExifRead::NewL( |
|
188 aFileData.iImageData->Des(), CExifRead::ENoJpeg | CExifRead::ENoTagChecking); |
|
189 CleanupStack::PushL(reader); |
|
190 |
|
191 // Getting description |
|
192 aHd.iDescription16 = ReadExifTagL( *reader, EIfd0, KIdImageDescription ); |
|
193 |
|
194 // Getting UserComment |
|
195 ReadUserCommentL( aHd, reader ); |
|
196 |
|
197 // Getting copyright |
|
198 aHd.iCopyright16 = ReadExifTagL( *reader, EIfd0, KIdCopyright ); |
|
199 |
|
200 // Artist |
|
201 aHd.iArtist = ReadExifTagL( *reader, EIfd0, KIdArtist ); |
|
202 |
|
203 // Getting whitebalance |
|
204 aHd.iStoreWhiteBalance = reader->GetWhiteBalance( aHd.iWhiteBalance ) == KErrNone; |
|
205 |
|
206 // Getting aHd.iFlash |
|
207 aHd.iStoreFlash = reader->GetFlash( aHd.iFlash ) == KErrNone; |
|
208 |
|
209 // Getting exposure |
|
210 aHd.iStoreExposureProgram = reader->GetExposureProgram( aHd.iExposureProgram ) == KErrNone; |
|
211 |
|
212 // Getting width |
|
213 if ( reader->TagExists( KIdPixelXDimension, EIfdExif ) ) |
|
214 { |
|
215 // PixelXDimension tag should be found in EXIF according to the standard. |
|
216 reader->GetPixelXDimension(aHd.iImageWidthExif); |
|
217 } |
|
218 |
|
219 // Getting height |
|
220 if ( reader->TagExists( KIdPixelYDimension, EIfdExif ) ) |
|
221 { |
|
222 // PixelYDimension tag should be found in EXIF according to the standard. |
|
223 reader->GetPixelYDimension(aHd.iImageHeightExif); |
|
224 } |
|
225 |
|
226 // Getting aFileData.iModified date |
|
227 if ( reader->TagExists(KIdDateTime, EIfd0) ) |
|
228 { |
|
229 WRITELOG( "CHarvesterExifUtil::ReadExifDataL() - getting last aFileData.iModified date (exif)" ); |
|
230 aHd.iDateModified8 = reader->GetDateTimeL(); |
|
231 } |
|
232 |
|
233 // Getting original date |
|
234 if ( reader->TagExists(KIdDateTimeOriginal, EIfdExif) ) |
|
235 { |
|
236 WRITELOG( "CHarvesterExifUtil::ReadExifDataL() - getting original date (exif)" ); |
|
237 aHd.iDateOriginal8 = reader->GetDateTimeOriginalL(); |
|
238 } |
|
239 |
|
240 // Getting date & time digitized |
|
241 if ( reader->TagExists(KIdDateTimeDigitized, EIfdExif) ) |
|
242 { |
|
243 WRITELOG( "CHarvesterExifUtil::ReadExifDataL() - getting digitized date (exif)" ); |
|
244 aHd.iDateDigitized8 = reader->GetDateTimeDigitizedL(); |
|
245 } |
|
246 |
|
247 //Getting camera maker |
|
248 aHd.iMake = ReadExifTagL( *reader, EIfd0, KIdMake ); |
|
249 |
|
250 //Getting camera aHd.iModel |
|
251 aHd.iModel = ReadExifTagL( *reader, EIfd0, KIdModel ); |
|
252 |
|
253 //Getting aHd.iOrientation |
|
254 aHd.iStoreOrientation = reader->GetOrientation( aHd.iOrientation ) == KErrNone; |
|
255 |
|
256 //Getting X Resolution |
|
257 ReadXResolutionL( aHd, reader ); |
|
258 |
|
259 //Getting Y Resolution |
|
260 ReadXResolutionL( aHd, reader ); |
|
261 |
|
262 //Getting resolution unit (mandatory tag) |
|
263 reader->GetResolutionUnit( aHd.iResolutionUnit ); |
|
264 |
|
265 //Getting YCbCr Positioning |
|
266 aHd.iStoreYCbCrPositioning = reader->GetYCbCrPositioning( aHd.iYCbCrPositioning ) == KErrNone; |
|
267 |
|
268 //Getting exposure bias value |
|
269 ReadExposureBiasL( aHd, reader ); |
|
270 |
|
271 //Getting exposure time |
|
272 ReadExposureTimeL( aHd, reader ); |
|
273 |
|
274 //Getting FNumber |
|
275 ReadFNumberL( aHd, reader ); |
|
276 |
|
277 //Getting Exif version |
|
278 aHd.iStoreExifVersion = reader->GetExifVersion( aHd.iExifVersion ) == KErrNone; |
|
279 |
|
280 //Getting FlashPix version |
|
281 aHd.iStoreFlashPixVersion = reader->GetFlashPixVersion( aHd.iFlashPixVersion ) == KErrNone; |
|
282 |
|
283 // Shutter speed |
|
284 ReadShutterSpeedL( aHd, reader ); |
|
285 |
|
286 //Getting aHd.iAperture |
|
287 ReadApertureValueL( aHd, reader ); |
|
288 |
|
289 //Getting focal length |
|
290 ReadFocalLengthL( aHd, reader ); |
|
291 |
|
292 // Getting focal length in 35 mm |
|
293 ReadFocalLength35mmL( aHd, reader ); |
|
294 |
|
295 aHd.iStoreColourSpace = reader->GetColorSpace( aHd.iColourSpace ) == KErrNone; |
|
296 |
|
297 aHd.iStoreThumbCompression = reader->GetThumbnailCompression( aHd.iThumbCompression ) == KErrNone; |
|
298 |
|
299 TUint32 numerator = 0; |
|
300 TUint32 denominator = 0; |
|
301 |
|
302 //Getting thumbnail X resolution |
|
303 TInt error = reader->GetThumbnailXResolution( numerator, denominator ); |
|
304 if ( error == KErrNone ) |
|
305 { |
|
306 aHd.iStoreThumbXResolution = ETrue; |
|
307 aHd.iThumbXResolution = 0.0f; |
|
308 if ( denominator > 0) |
|
309 { |
|
310 aHd.iThumbXResolution = numerator / denominator; |
|
311 } |
|
312 } |
|
313 |
|
314 //Getting thumbnail Y resolution |
|
315 error = reader->GetThumbnailYResolution( numerator, denominator ); |
|
316 if ( error == KErrNone ) |
|
317 { |
|
318 aHd.iStoreThumbYResolution = ETrue; |
|
319 aHd.iThumbYResolution = 0.0f; |
|
320 if ( denominator > 0 ) |
|
321 { |
|
322 aHd.iThumbYResolution = numerator / denominator; |
|
323 } |
|
324 } |
|
325 |
|
326 aHd.iStoreThumbResolutionUnit = |
|
327 reader->GetThumbnailResolutionUnit( aHd.iThumbResolutionUnit ) == KErrNone; |
|
328 |
|
329 // Bits per sample and Samples per pixel not recorded in JPEG Exif. |
|
330 if ( reader->TagExists( KIdSamplesPerPixel, EIfd0 ) ) |
|
331 { |
|
332 const CExifTag* tag = reader->GetTagL( EIfd0, KIdSamplesPerPixel ); |
|
333 TPtrC8 tagData = tag->Data(); |
|
334 |
|
335 aHd.iSamplesPerPixel = MdsUtils::ToUInt16L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
336 aHd.iStoreSamplesPerPixel = ETrue; |
|
337 |
|
338 WRITELOG1( "CHarvesterExifUtil::ReadExifDataL() - samples per pixel: %d", aHd.iSamplesPerPixel ); |
|
339 } |
|
340 |
|
341 //Getting ISO speed rating. |
|
342 if ( reader->TagExists(KIdISOSpeedRatings, EIfdExif) ) |
|
343 { |
|
344 HBufC8* iso8 = reader->GetIsoSpeedRatingsL(); |
|
345 |
|
346 if ( iso8 ) |
|
347 { |
|
348 aHd.iStoreIsoSpeedRating = ETrue; |
|
349 aHd.iIsoSpeedRating = iso8->Des()[0]; |
|
350 delete iso8; |
|
351 iso8 = NULL; |
|
352 } |
|
353 } |
|
354 |
|
355 //Getting components configuration |
|
356 if ( reader->TagExists( KIdComponentsConfig, EIfdExif ) ) |
|
357 { |
|
358 const CExifTag* tag = reader->GetTagL( |
|
359 EIfdExif, KIdComponentsConfig ); |
|
360 TPtrC8 tagData = tag->Data(); |
|
361 |
|
362 aHd.iComponentsConfiguration = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
363 aHd.iStoreComponentsConfig = ETrue; |
|
364 } |
|
365 |
|
366 // Getting thumbnail compression |
|
367 aHd.iStoreThumbCompression = |
|
368 reader->GetThumbnailCompression( aHd.iThumbCompression ) == KErrNone; |
|
369 |
|
370 // Getting metering mode |
|
371 aHd.iStoreMeteringMode = reader->GetMeteringMode( aHd.iMeteringMode ) ==KErrNone; |
|
372 |
|
373 // Getting related soundfile |
|
374 aHd.iRelatedSoundFile = ReadExifTagL( *reader, EIfdExif, KIdRelatedSoundFile ); |
|
375 |
|
376 // Getting focal plane resolution unit |
|
377 if ( reader->TagExists(KIdFocalPlaneResolutionUnit, EIfdExif) ) |
|
378 { |
|
379 const CExifTag* tag = reader->GetTagL( |
|
380 EIfdExif, KIdFocalPlaneResolutionUnit ); |
|
381 TPtrC8 tagData = tag->Data(); |
|
382 |
|
383 aHd.iFocalPlaneResolutionUnit = MdsUtils::ToUInt16L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
384 aHd.iStoreFocalPlaneResolutionUnit = ETrue; |
|
385 } |
|
386 |
|
387 // Getting focal plane X resolution |
|
388 ReadFocalXPlaneResolutionL( aHd, reader ); |
|
389 |
|
390 |
|
391 // Getting focal plane Y resolution |
|
392 ReadFocalYPlaneResolutionL( aHd, reader ); |
|
393 |
|
394 // Get GPS tags |
|
395 TBool latitudeExists = EFalse; |
|
396 |
|
397 // latitude |
|
398 ReadGPSLatitudeL( aHd, reader, latitudeExists ); |
|
399 |
|
400 // longitude |
|
401 ReadGPSLongitudeL( aHd, reader, latitudeExists ); |
|
402 |
|
403 // altitude |
|
404 ReadGPSAltitudeL( aHd, reader ); |
|
405 |
|
406 CleanupStack::PopAndDestroy( reader ); |
|
407 return KErrNone; |
|
408 } |
|
409 |
|
410 // --------------------------------------------------------------------------- |
|
411 // Time converting |
|
412 // --------------------------------------------------------------------------- |
|
413 // |
|
414 EXPORT_C TTime CHarvesterExifUtil::ConvertExifDateTimeToSymbianTimeL( |
|
415 const TDesC8& aDateTime ) |
|
416 { |
|
417 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL()" ); |
|
418 |
|
419 TDateTime datetime( 0, EJanuary, 0, 0, 0, 0, 0 ); |
|
420 TBuf<4> text; |
|
421 |
|
422 // Year |
|
423 TPtrC8 textPart = aDateTime.Left(4); |
|
424 TLex8 lex( textPart ); |
|
425 TInt number = 0; |
|
426 TInt error = lex.Val( number ); |
|
427 if ( error != KErrNone ) |
|
428 { |
|
429 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get year" ); |
|
430 User::Leave( error ); |
|
431 } |
|
432 datetime.SetYear( number ); |
|
433 |
|
434 // Month |
|
435 TPtrC8 textPart2 = aDateTime.Mid( 5,2 ); |
|
436 lex.Assign( textPart2 ); |
|
437 error = lex.Val( number ); |
|
438 if ( error != KErrNone ) |
|
439 { |
|
440 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get month" ); |
|
441 User::Leave( error ); |
|
442 } |
|
443 number--; |
|
444 TMonth month = (TMonth) number; |
|
445 datetime.SetMonth( month ); |
|
446 |
|
447 // Day |
|
448 TPtrC8 textPart3 = aDateTime.Mid( 8,2 ); |
|
449 lex.Assign( textPart3 ); |
|
450 error = lex.Val( number ); |
|
451 if ( error != KErrNone ) |
|
452 { |
|
453 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get date" ); |
|
454 User::Leave( error ); |
|
455 } |
|
456 datetime.SetDay( number - 1 ); |
|
457 |
|
458 // Hours |
|
459 TPtrC8 textPart4 = aDateTime.Mid( 11,2 ); |
|
460 lex.Assign( textPart4 ); |
|
461 error = lex.Val( number ); |
|
462 if ( error != KErrNone ) |
|
463 { |
|
464 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get hours" ); |
|
465 User::Leave( error ); |
|
466 } |
|
467 datetime.SetHour( number ); |
|
468 |
|
469 // Minutes |
|
470 TPtrC8 textPart5 = aDateTime.Mid( 14,2 ); |
|
471 lex.Assign( textPart5 ); |
|
472 error = lex.Val( number ); |
|
473 if ( error != KErrNone ) |
|
474 { |
|
475 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get minutes" ); |
|
476 User::Leave( error ); |
|
477 } |
|
478 datetime.SetMinute( number ); |
|
479 |
|
480 // Seconds |
|
481 TPtrC8 textPart6 = aDateTime.Mid( 17,2 ); |
|
482 lex.Assign( textPart6 ); |
|
483 error = lex.Val( number ); |
|
484 if ( error != KErrNone ) |
|
485 { |
|
486 WRITELOG( "CHarvesterImagePluginAO::ConvertExifDateTimeToSymbianTimeL() - couldn't get seconds" ); |
|
487 User::Leave( error ); |
|
488 } |
|
489 datetime.SetSecond( number ); |
|
490 |
|
491 TTime time( datetime ); |
|
492 |
|
493 return time; |
|
494 } |
|
495 |
|
496 void CHarvesterExifUtil::AddPropertyL( CMdEObjectDef& aObjectDef, CMdEObject& aMdeObject, |
|
497 const TDesC& aProperty, TUint16 aValue ) |
|
498 { |
|
499 CMdEPropertyDef& propDef = aObjectDef.GetPropertyDefL( aProperty ); |
|
500 CMdEProperty* mdeProp = NULL; |
|
501 |
|
502 aMdeObject.Property( propDef, mdeProp, 0 ); |
|
503 if ( !mdeProp ) |
|
504 { |
|
505 aMdeObject.AddUint16PropertyL( propDef, aValue ); |
|
506 } |
|
507 } |
|
508 |
|
509 void CHarvesterExifUtil::AddPropertyL( CMdEObjectDef& aObjectDef, CMdEObject& aMdeObject, |
|
510 const TDesC& aProperty, TUint32 aValue ) |
|
511 { |
|
512 CMdEPropertyDef& propDef = aObjectDef.GetPropertyDefL( aProperty ); |
|
513 CMdEProperty* mdeProp = NULL; |
|
514 |
|
515 aMdeObject.Property( propDef, mdeProp, 0 ); |
|
516 if ( !mdeProp ) |
|
517 { |
|
518 aMdeObject.AddUint32PropertyL( propDef, aValue ); |
|
519 } |
|
520 } |
|
521 |
|
522 void CHarvesterExifUtil::SetExifDefaultsL( CMdEObject& aMdeObject, CExifModify& aExifModify ) |
|
523 { |
|
524 const TUint32 KPixPerResolution = 72; |
|
525 const TUint32 KPixPerResDenm = 1; |
|
526 const TUint16 KResUnitInch = 2; |
|
527 const TUint16 KYCbCrPositioning = 1; |
|
528 const TUint8 KCompConf1st = 1; |
|
529 const TUint8 KCompConf2nd = 2; |
|
530 const TUint8 KCompConf3rd = 3; |
|
531 const TUint8 KCompConf4rd = 0; |
|
532 const TUint16 KColorSpaceRGB = 1; |
|
533 |
|
534 CMdEObjectDef& imageDef = iDefaultNamespace->GetObjectDefL( Image::KImageObject ); |
|
535 |
|
536 aExifModify.SetXResolutionL( KPixPerResolution, KPixPerResDenm ); |
|
537 aExifModify.SetYResolutionL( KPixPerResolution, KPixPerResDenm ); |
|
538 |
|
539 AddPropertyL( imageDef, aMdeObject, MediaObject::KResolutionUnitProperty, |
|
540 KResUnitInch ); |
|
541 aExifModify.SetResolutionUnitL( KResUnitInch ); |
|
542 |
|
543 AddPropertyL( imageDef, aMdeObject, Image::KYCbCrPositioningProperty, |
|
544 KYCbCrPositioning ); |
|
545 aExifModify.SetYCbCrPositioningL( KYCbCrPositioning ); |
|
546 |
|
547 TUint32 compUint32( 0 ); |
|
548 TUint8* components = (TUint8*) &compUint32; |
|
549 *(components + 3) = KCompConf4rd; |
|
550 *(components + 2) = KCompConf3rd; |
|
551 *(components + 1) = KCompConf2nd; |
|
552 *components = KCompConf1st; |
|
553 |
|
554 AddPropertyL( imageDef, aMdeObject, Image::KComponentsConfigurationProperty, |
|
555 compUint32 ); |
|
556 aExifModify.SetComponentsConfigurationL( KCompConf1st, KCompConf2nd, |
|
557 KCompConf3rd, KCompConf4rd ); |
|
558 |
|
559 AddPropertyL( imageDef, aMdeObject, Image::KColourSpaceProperty, KColorSpaceRGB ); |
|
560 aExifModify.SetColorSpaceL( KColorSpaceRGB ); |
|
561 } |
|
562 |
|
563 HBufC8* CHarvesterExifUtil::GetPropertyValueLC( const CMdEPropertyDef& aPropDef, |
|
564 const CMdEProperty& aProperty ) |
|
565 { |
|
566 switch( aPropDef.PropertyType() ) |
|
567 { |
|
568 case EPropertyReal32: |
|
569 { |
|
570 TUint32 denominator = 1; |
|
571 if( aPropDef.Name().CompareF( Image::KExposureTimeProperty ) == 0 ) |
|
572 { |
|
573 denominator = 1000000; |
|
574 } |
|
575 else if( aPropDef.Name().CompareF( Image::KApertureValueProperty ) == 0 ) |
|
576 { |
|
577 denominator = 100; |
|
578 } |
|
579 else if( aPropDef.Name().CompareF( Image::KExposureBiasValueProperty ) == 0 ) |
|
580 { |
|
581 denominator = 100; |
|
582 } |
|
583 else if( aPropDef.Name().CompareF( Image::KShutterSpeedValueProperty ) == 0 ) |
|
584 { |
|
585 denominator = 1000; |
|
586 } |
|
587 else if( aPropDef.Name().CompareF( Image::KFNumberProperty ) == 0 ) |
|
588 { |
|
589 denominator = 10; |
|
590 } |
|
591 TUint32 value = TUint32( aProperty.Real32ValueL() * (TReal32)denominator ); |
|
592 |
|
593 HBufC8* buf8 = HBufC8::NewLC( 2 * sizeof(TUint32) ); |
|
594 TPtr8 ptr = buf8->Des(); |
|
595 ptr.Append( (TUint8*)&value, sizeof(TUint32) ); |
|
596 ptr.Append( (TUint8*)&denominator, sizeof(TUint32) ); |
|
597 |
|
598 return buf8; |
|
599 } |
|
600 case EPropertyTime: |
|
601 { |
|
602 TTime time = aProperty.TimeValueL(); |
|
603 if( aPropDef.Name().CompareF( Image::KDateTimeProperty ) == 0 ) |
|
604 { |
|
605 RTz timezone; |
|
606 CleanupClosePushL( timezone ); |
|
607 User::LeaveIfError( timezone.Connect() ); |
|
608 timezone.ConvertToLocalTime( time ); |
|
609 CleanupStack::PopAndDestroy( &timezone ); |
|
610 } |
|
611 HBufC* buf = HBufC::NewLC( KDateBufferSize ); |
|
612 TPtr ptr = buf->Des(); |
|
613 time.FormatL( ptr, KExifDateTimeFormat ); |
|
614 HBufC8* buf8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( ptr ); |
|
615 CleanupStack::PopAndDestroy( buf ); |
|
616 CleanupStack::PushL( buf8 ); |
|
617 return buf8; |
|
618 } |
|
619 case EPropertyText: |
|
620 { |
|
621 TPtrC text = aProperty.TextValueL(); |
|
622 if( aPropDef.Name().CompareF( MediaObject::KCommentProperty ) == 0 ) |
|
623 { |
|
624 const TUint16 bufLength = KUnicodeCodeDesignation.iTypeLength + text.Size(); |
|
625 HBufC8* commentBuf = HBufC8::NewLC( bufLength ); |
|
626 TPtr8 commentPtr = commentBuf->Des(); |
|
627 commentPtr.Append( KUnicodeCodeDesignation ); |
|
628 commentPtr.Append( (TUint8*)text.Ptr(), text.Size() ); |
|
629 return commentBuf; |
|
630 } |
|
631 HBufC8* buf = CnvUtfConverter::ConvertFromUnicodeToUtf8L( text ); |
|
632 CleanupStack::PushL( buf ); |
|
633 return buf; |
|
634 } |
|
635 case EPropertyUint16: |
|
636 { |
|
637 TUint16 value = aProperty.Uint16ValueL(); |
|
638 HBufC8* buf = HBufC8::NewLC( sizeof(value) ); |
|
639 TPtr8 ptr = buf->Des(); |
|
640 ptr.Copy( (TUint8*)(&value), sizeof(value) ); |
|
641 return buf; |
|
642 } |
|
643 default: |
|
644 User::Leave( KErrGeneral ); |
|
645 } |
|
646 return NULL; |
|
647 } |
|
648 |
|
649 CExifTag::TExifTagDataType CHarvesterExifUtil::ExifTagDataType( TUint16 aTagID, const CMdEPropertyDef& aPropDef ) |
|
650 { |
|
651 if( aTagID == KIdUserComment ) |
|
652 { |
|
653 return CExifTag::ETagUndefined; |
|
654 } |
|
655 if( aTagID == KIdShutterSpeed || aTagID == KIdExposureBias ) |
|
656 { |
|
657 return CExifTag::ETagSrational; |
|
658 } |
|
659 switch( aPropDef.PropertyType() ) |
|
660 { |
|
661 case EPropertyBool: |
|
662 case EPropertyInt8: |
|
663 case EPropertyUint8: |
|
664 return CExifTag::ETagByte; |
|
665 case EPropertyInt16: |
|
666 case EPropertyUint16: |
|
667 return CExifTag::ETagShort; |
|
668 case EPropertyUint32: |
|
669 return CExifTag::ETagLong; |
|
670 case EPropertyInt32: |
|
671 return CExifTag::ETagSlong; |
|
672 case EPropertyReal32: |
|
673 return CExifTag::ETagRational; |
|
674 case EPropertyTime: |
|
675 return CExifTag::ETagAscii; |
|
676 case EPropertyText: |
|
677 return CExifTag::ETagAscii; |
|
678 default: |
|
679 return CExifTag::ETagUndefined; |
|
680 } |
|
681 } |
|
682 |
|
683 TBool CHarvesterExifUtil::CompareTag( TPtrC8 aMdeData, const CExifTag* aTag ) |
|
684 { |
|
685 if( aTag->TagInfo().iDataType == CExifTag::ETagRational ) |
|
686 { |
|
687 TUint32 denominator; |
|
688 TUint32 value; |
|
689 TPtrC8 ptr( aTag->Data() ); |
|
690 memcpy( &value, ptr.Ptr(), sizeof(value) ); |
|
691 memcpy( &denominator, ptr.Ptr()+sizeof(value), sizeof(denominator) ); |
|
692 |
|
693 TReal32 tagValue = 0.0f; |
|
694 if ( denominator != 0 ) |
|
695 { |
|
696 tagValue = (TReal32)value / (TReal32)denominator; |
|
697 } |
|
698 ptr.Set( aMdeData ); |
|
699 memcpy( &value, ptr.Ptr(), sizeof(value) ); |
|
700 memcpy( &denominator, ptr.Ptr()+sizeof(value), sizeof(denominator) ); |
|
701 |
|
702 TReal32 mdeValue = 0.0f; |
|
703 if ( denominator != 0 ) |
|
704 { |
|
705 mdeValue = (TReal32)value / (TReal32)denominator; |
|
706 } |
|
707 return Abs( tagValue - mdeValue ) > 0.01f; |
|
708 } |
|
709 else |
|
710 { |
|
711 return aMdeData.CompareF( aTag->Data() ) != 0; |
|
712 } |
|
713 } |
|
714 |
|
715 TBool CHarvesterExifUtil::ModifyExifTagL( CMdEObject& aMdeObject, CExifModify& aExifModify, |
|
716 const TDesC& aProperty, TExifIfdType aIFD, TUint16 aTagID, TBool aRemove ) |
|
717 { |
|
718 CMdEObjectDef& imageDef = iDefaultNamespace->GetObjectDefL( Image::KImageObject ); |
|
719 CMdEPropertyDef& propDef = imageDef.GetPropertyDefL( aProperty ); |
|
720 CMdEProperty* mdeProp = NULL; |
|
721 TBool exifChanged = EFalse; |
|
722 |
|
723 aMdeObject.Property( propDef, mdeProp, 0 ); |
|
724 TBool tagExists = EFalse; |
|
725 if( aRemove ) |
|
726 { |
|
727 tagExists = aExifModify.Reader()->TagExists( aTagID, aIFD ); |
|
728 } |
|
729 if ( mdeProp ) |
|
730 { |
|
731 HBufC8* mdedata = GetPropertyValueLC( propDef, *mdeProp ); |
|
732 TPtrC8 ptr = mdedata->Des(); |
|
733 TBool change = EFalse; |
|
734 const CExifTag* tag = NULL; |
|
735 TRAP_IGNORE( tag = aExifModify.Reader()->GetTagL( aIFD, aTagID ) ); |
|
736 if( !tag ) //create new exif tag |
|
737 { |
|
738 change = ETrue; |
|
739 } |
|
740 else if( CompareTag( ptr, tag ) ) |
|
741 { |
|
742 change = ETrue; |
|
743 } |
|
744 if( change ) |
|
745 { |
|
746 CExifTag::TExifTagDataType type = ExifTagDataType( aTagID, propDef ); |
|
747 TInt len = 1; |
|
748 if( type == CExifTag::ETagUndefined || type == CExifTag::ETagAscii ) |
|
749 { |
|
750 len = ptr.Length(); |
|
751 } |
|
752 TExifTagInfo info( aTagID, type, len ); |
|
753 aExifModify.SetTagL( aIFD, info, ptr ); |
|
754 exifChanged = ETrue; |
|
755 } |
|
756 CleanupStack::PopAndDestroy( mdedata ); |
|
757 } |
|
758 else if( tagExists ) // remove from exif |
|
759 { |
|
760 aExifModify.DeleteTag( aIFD, aTagID ); |
|
761 exifChanged = ETrue; |
|
762 } |
|
763 return exifChanged; |
|
764 } |
|
765 |
|
766 // --------------------------------------------------------------------------- |
|
767 // ComposeExifData |
|
768 // --------------------------------------------------------------------------- |
|
769 // |
|
770 EXPORT_C TInt CHarvesterExifUtil::ComposeExifDataL( CMdEObject& aMdeObject, TPtr8 aImagePtr, HBufC8*& aModified ) |
|
771 { |
|
772 |
|
773 if ( !iSession ) |
|
774 { |
|
775 User::Leave( KErrSessionClosed ); |
|
776 } |
|
777 |
|
778 WRITELOG1( "CHarvesterExifUtil::ComposeExifData() - Compose Start Object ID: %d", aMdeObject.Id() ); |
|
779 TBool exifChanged = EFalse; |
|
780 |
|
781 // 2. try to init EXIF data from image file's data |
|
782 CExifModify* modifyExif = NULL; |
|
783 TInt exifError = KErrNone; |
|
784 TRAP( exifError, modifyExif = CExifModify::NewL( aImagePtr, |
|
785 CExifModify::EModify, CExifModify::ENoJpegParsing ) ); |
|
786 |
|
787 // 3. Is this image format supported? |
|
788 if ( exifError == KErrNotSupported ) |
|
789 { |
|
790 WRITELOG( "CHarvesterExifUtil::ComposeExifData() - Image format not supported (!jpeg)" ); |
|
791 User::Leave( exifError ); |
|
792 } |
|
793 |
|
794 // 4. if image does not contain EXIF data try to create it |
|
795 if ( exifError != KErrNone ) |
|
796 { |
|
797 WRITELOG( "CHarvesterExifUtil::ComposeExifData() - Image doesn't contain EXIF data" ); |
|
798 modifyExif = CExifModify::NewL( aImagePtr, |
|
799 CExifModify::ECreate, CExifModify::ENoJpegParsing ); |
|
800 SetExifDefaultsL( aMdeObject, *modifyExif ); |
|
801 exifChanged = ETrue; |
|
802 } |
|
803 CleanupStack::PushL( modifyExif ); |
|
804 const CExifRead* readExif = modifyExif->Reader(); |
|
805 CMdEObjectDef& imageDef = iDefaultNamespace->GetObjectDefL( Image::KImageObject ); |
|
806 |
|
807 // Set pixel X dimension tag (mandatory) |
|
808 TBool changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
809 MediaObject::KWidthProperty, EIfdExif, KIdPixelXDimension); |
|
810 exifChanged = (exifChanged | changed); |
|
811 |
|
812 // Set pixel Y dimension tag (mandatory) |
|
813 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
814 MediaObject::KHeightProperty, EIfdExif, KIdPixelYDimension); |
|
815 exifChanged = (exifChanged | changed); |
|
816 |
|
817 // Set white balance tag (recommended) |
|
818 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
819 Image::KWhiteBalanceProperty, EIfdExif, KIdWhiteBalance, ETrue ); |
|
820 exifChanged = (exifChanged | changed); |
|
821 |
|
822 // Set flash tag (recommended) |
|
823 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
824 Image::KFlashProperty, EIfdExif, KIdFlash, ETrue ); |
|
825 exifChanged = (exifChanged | changed); |
|
826 |
|
827 // Set exposure program tag (optional) |
|
828 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
829 Image::KExposureProgramProperty, EIfdExif, KIdExposureProgram, ETrue ); |
|
830 exifChanged = (exifChanged | changed); |
|
831 |
|
832 // Set description tag (recommended) |
|
833 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
834 MediaObject::KDescriptionProperty, EIfd0, KIdImageDescription, ETrue ); |
|
835 exifChanged = (exifChanged | changed); |
|
836 |
|
837 // Set user comment tag (optional) |
|
838 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
839 MediaObject::KCommentProperty, EIfdExif, KIdUserComment, ETrue ); |
|
840 exifChanged = (exifChanged | changed); |
|
841 |
|
842 // Set copyright tag (optional) |
|
843 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
844 MediaObject::KCopyrightProperty, EIfd0, KIdCopyright, ETrue ); |
|
845 exifChanged = (exifChanged | changed); |
|
846 |
|
847 // Set DateTimeOriginal tag (optional) |
|
848 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
849 Image::KDateTimeOriginalProperty, EIfdExif, KIdDateTimeOriginal, ETrue ); |
|
850 exifChanged = (exifChanged | changed); |
|
851 |
|
852 // Set DateTimeDigitized tag (optional) |
|
853 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
854 Image::KDateTimeDigitizedProperty, EIfdExif, KIdDateTimeDigitized, ETrue ); |
|
855 exifChanged = (exifChanged | changed); |
|
856 |
|
857 // Set DateTime (_image_ modified) tag (recommended) |
|
858 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
859 Image::KDateTimeProperty, EIfd0, KIdDateTimeModified, ETrue ); |
|
860 exifChanged = (exifChanged | changed); |
|
861 |
|
862 // Set maker tag (optional) |
|
863 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
864 Image::KMakeProperty, EIfd1, KIdMake, ETrue ); |
|
865 exifChanged = (exifChanged | changed); |
|
866 |
|
867 // Set model tag (optional) |
|
868 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
869 Image::KModelProperty, EIfd1, KIdModel, ETrue ); |
|
870 exifChanged = (exifChanged | changed); |
|
871 |
|
872 // Set orientation tag (recommended) |
|
873 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
874 Image::KOrientationProperty, EIfd0, KIdOrientation , ETrue ); |
|
875 exifChanged = (exifChanged | changed); |
|
876 |
|
877 // Set YCbCrPositioning tag (mandatory) |
|
878 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
879 Image::KYCbCrPositioningProperty, EIfd1, KIdYbCrPositioning, EFalse ); |
|
880 exifChanged = (exifChanged | changed); |
|
881 |
|
882 // Set resolution unit tag (mandatory) |
|
883 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
884 MediaObject::KResolutionUnitProperty, EIfd1, KIdResolutionUnit, EFalse ); |
|
885 exifChanged = (exifChanged | changed); |
|
886 |
|
887 // Set ISO speed tag (optional) |
|
888 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
889 Image::KISOSpeedRatingsProperty, EIfdExif, KIdISOSpeedRatings, ETrue ); |
|
890 exifChanged = (exifChanged | changed); |
|
891 |
|
892 // Set related soundfile tag (optional) |
|
893 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
894 Image::KRelatedSoundFileProperty, EIfdExif, KIdRelatedSoundFile, ETrue ); |
|
895 exifChanged = (exifChanged | changed); |
|
896 |
|
897 // Set exposure time tag (recommended) |
|
898 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
899 Image::KExposureTimeProperty, EIfdExif, KIdExposureTime, ETrue ); |
|
900 exifChanged = (exifChanged | changed); |
|
901 |
|
902 // Set aperture value tag (optional) |
|
903 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
904 Image::KApertureValueProperty, EIfdExif, KIdApertureValue, ETrue ); |
|
905 exifChanged = (exifChanged | changed); |
|
906 |
|
907 // Set colour space tag (mandatory) |
|
908 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
909 Image::KColourSpaceProperty, EIfdExif, KIdColorSpace , EFalse ); |
|
910 exifChanged = (exifChanged | changed); |
|
911 |
|
912 // Set exposure bias tag (optional) |
|
913 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
914 Image::KExposureBiasValueProperty, EIfdExif, KIdExposureBias, ETrue ); |
|
915 exifChanged = (exifChanged | changed); |
|
916 |
|
917 // Set metering mode tag (optional) |
|
918 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
919 Image::KMeteringModeProperty, EIfdExif, KIdMeteringMode, ETrue ); |
|
920 exifChanged = (exifChanged | changed); |
|
921 |
|
922 // Set shutter speed tag (optional) |
|
923 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
924 Image::KShutterSpeedValueProperty, EIfdExif, KIdShutterSpeed, ETrue ); |
|
925 exifChanged = (exifChanged | changed); |
|
926 |
|
927 // Set X resolution tag (mandatory) |
|
928 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
929 Image::KXResolutionProperty, EIfd0, KIdXResolution, EFalse ); |
|
930 exifChanged = (exifChanged | changed); |
|
931 |
|
932 // Set Y resolution tag (mandatory) |
|
933 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
934 Image::KYResolutionProperty, EIfd0, KIdYResolution, EFalse ); |
|
935 exifChanged = (exifChanged | changed); |
|
936 |
|
937 // Set F number tag (optional) |
|
938 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
939 Image::KFNumberProperty, EIfdExif, KIdFNumber, ETrue ); |
|
940 exifChanged = (exifChanged | changed); |
|
941 |
|
942 // Set focal length tag (optional) |
|
943 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
944 Image::KFocalLengthProperty, EIfdExif, KIdFocalLength, ETrue ); |
|
945 exifChanged = (exifChanged | changed); |
|
946 |
|
947 // Set focal length in 35 mm film tag (optional) |
|
948 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
949 Image::KFocalLengthIn35mmFilmProperty, EIfdExif, KIdFocalLengthIn35mm, ETrue ); |
|
950 exifChanged = (exifChanged | changed); |
|
951 |
|
952 // Set focal plane resolution unit (optional) |
|
953 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
954 Image::KFocalPlaneResolutionUnitProperty, EIfdExif, KIdFocalPlaneResolutionUnit, ETrue ); |
|
955 exifChanged = (exifChanged | changed); |
|
956 |
|
957 // Set focal plane X resolution (optional) |
|
958 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
959 Image::KFocalPlaneXResolutionProperty, EIfdExif, KIdFocalPlaneXResolution, ETrue ); |
|
960 exifChanged = (exifChanged | changed); |
|
961 |
|
962 // Set focal plane Y resolution (optional) |
|
963 changed = ModifyExifTagL( aMdeObject, *modifyExif, |
|
964 Image::KFocalPlaneYResolutionProperty, EIfdExif, KIdFocalPlaneYResolution, ETrue ); |
|
965 exifChanged = (exifChanged | changed); |
|
966 |
|
967 TUint16 uint16Value( 0 ); |
|
968 TUint32 uint32Value( 0 ); |
|
969 |
|
970 // Set components configuration tag (mandatory) |
|
971 const CMdEPropertyDef& componentsDef = imageDef.GetPropertyDefL( |
|
972 Image::KComponentsConfigurationProperty ); |
|
973 { |
|
974 CMdEProperty* componentsProp = NULL; |
|
975 aMdeObject.Property( componentsDef, componentsProp, 0 ); |
|
976 |
|
977 if ( componentsProp ) |
|
978 { |
|
979 TUint32 componentsValue = componentsProp->Uint32ValueL(); |
|
980 TUint8* components = (TUint8*) &componentsValue; |
|
981 const TUint8 KComponent4th = *(components + 3); |
|
982 const TUint8 KComponent3rd = *(components + 2); |
|
983 const TUint8 KComponent2nd = *(components + 1); |
|
984 const TUint8 KComponent1st = *components; |
|
985 |
|
986 TUint8 exifComponent4th( 0 ); |
|
987 TUint8 exifComponent3rd( 0 ); |
|
988 TUint8 exifComponent2nd( 0 ); |
|
989 TUint8 exifComponent1st( 0 ); |
|
990 |
|
991 exifError = readExif->GetComponentsConfiguration( |
|
992 exifComponent1st, exifComponent2nd, exifComponent3rd, exifComponent4th ); |
|
993 if ( exifError != KErrNone || |
|
994 exifComponent1st != KComponent1st || exifComponent2nd != KComponent2nd || |
|
995 exifComponent3rd != KComponent3rd || exifComponent4th != KComponent4th ) |
|
996 { |
|
997 modifyExif->SetComponentsConfigurationL( |
|
998 KComponent1st, KComponent2nd, KComponent3rd, KComponent4th ); |
|
999 exifChanged = ETrue; |
|
1000 } |
|
1001 } |
|
1002 } |
|
1003 |
|
1004 // Set thumbnail X resolution tag (mandatory) |
|
1005 const CMdEPropertyDef& thumbXDef = imageDef.GetPropertyDefL( |
|
1006 Image::KThumbXResolutionProperty ); |
|
1007 { |
|
1008 CMdEProperty* thumbXProp = NULL; |
|
1009 aMdeObject.Property( thumbXDef, thumbXProp, 0 ); |
|
1010 |
|
1011 if ( thumbXProp ) |
|
1012 { |
|
1013 const TUint32 thumbX = thumbXProp->Uint32ValueL(); |
|
1014 |
|
1015 TUint32 exifDenominator = 0; |
|
1016 exifError = readExif->GetThumbnailXResolution( uint32Value, exifDenominator ); |
|
1017 TUint32 exifThumbXResol = 0; |
|
1018 if ( exifDenominator > 0 ) |
|
1019 { |
|
1020 exifThumbXResol = uint32Value / exifDenominator; |
|
1021 } |
|
1022 |
|
1023 if ( exifError != KErrNone || exifThumbXResol != thumbX ) |
|
1024 { |
|
1025 const TUint32 KDenominator = 1; |
|
1026 modifyExif->SetThumbnailXResolutionL( thumbX, KDenominator ); |
|
1027 exifChanged = ETrue; |
|
1028 } |
|
1029 } |
|
1030 } |
|
1031 |
|
1032 // Set thumbnail Y resolution tag (mandatory) |
|
1033 const CMdEPropertyDef& thumbYDef = imageDef.GetPropertyDefL( |
|
1034 Image::KThumbYResolutionProperty ); |
|
1035 { |
|
1036 CMdEProperty* thumbYProp = NULL; |
|
1037 aMdeObject.Property( thumbYDef, thumbYProp, 0 ); |
|
1038 |
|
1039 if ( thumbYProp ) |
|
1040 { |
|
1041 TUint32 thumbY = TUint32( thumbYProp->Uint32ValueL() ); |
|
1042 TUint32 exifDenominator = 0; |
|
1043 exifError = readExif->GetThumbnailYResolution( uint32Value, exifDenominator ); |
|
1044 TUint32 exifThumbYResol = 0; |
|
1045 if ( exifDenominator > 0 ) |
|
1046 { |
|
1047 exifThumbYResol = uint32Value / exifDenominator; |
|
1048 } |
|
1049 |
|
1050 if ( exifError != KErrNone || exifThumbYResol != thumbY ) |
|
1051 { |
|
1052 const TUint32 KDenominator = 1; |
|
1053 modifyExif->SetThumbnailYResolutionL( thumbY, KDenominator ); |
|
1054 exifChanged = ETrue; |
|
1055 } |
|
1056 } |
|
1057 } |
|
1058 |
|
1059 // Set thumbnail resolution unit tag (mandatory) |
|
1060 const CMdEPropertyDef& thumbResolutionUnitDef = imageDef.GetPropertyDefL( |
|
1061 Image::KThumbResolutionUnitProperty ); |
|
1062 { |
|
1063 CMdEProperty* thumbResolutionUnitProp = NULL; |
|
1064 aMdeObject.Property( thumbResolutionUnitDef, thumbResolutionUnitProp, 0 ); |
|
1065 |
|
1066 if ( thumbResolutionUnitProp ) |
|
1067 { |
|
1068 exifError = readExif->GetThumbnailResolutionUnit( uint16Value ); |
|
1069 const TUint16 thumbnailResolutionUnitValue = |
|
1070 thumbResolutionUnitProp->Uint16ValueL(); |
|
1071 if ( exifError != KErrNone || uint16Value != thumbnailResolutionUnitValue ) |
|
1072 { |
|
1073 modifyExif->SetThumbnailResolutionUnitL( thumbnailResolutionUnitValue ); |
|
1074 exifChanged = ETrue; |
|
1075 } |
|
1076 } |
|
1077 } |
|
1078 |
|
1079 if ( exifChanged ) |
|
1080 { |
|
1081 WRITELOG( "CHarvesterExifUtil::ComposeExifData() - write exif to buffer" ); |
|
1082 aModified = modifyExif->WriteDataL( aImagePtr ); |
|
1083 } |
|
1084 CleanupStack::PopAndDestroy( modifyExif ); |
|
1085 |
|
1086 WRITELOG1( "CHarvesterExifUtil::ComposeExifData() - Compose End Object ID: %d", aMdeObject.Id() ); |
|
1087 |
|
1088 return KErrNone; |
|
1089 } |
|
1090 |
|
1091 // --------------------------------------------------------------------------- |
|
1092 // ComposeLocation |
|
1093 // --------------------------------------------------------------------------- |
|
1094 // |
|
1095 EXPORT_C void CHarvesterExifUtil::ComposeLocationL( CMdEObject* aLocation, TPtr8 aImagePtr, HBufC8*& aModified ) |
|
1096 { |
|
1097 CMdEProperty* latitudeProperty = NULL; |
|
1098 CMdEProperty* longitudeProperty = NULL; |
|
1099 CMdEProperty* altitudeProperty = NULL; |
|
1100 CMdEProperty* qualityProperty = NULL; |
|
1101 |
|
1102 CMdEObjectDef& locationDef = iDefaultNamespace->GetObjectDefL( Location::KLocationObject ); |
|
1103 |
|
1104 aLocation->Property( locationDef.GetPropertyDefL( |
|
1105 Location::KLatitudeProperty ), latitudeProperty, 0 ); |
|
1106 aLocation->Property( locationDef.GetPropertyDefL( |
|
1107 Location::KLongitudeProperty ), longitudeProperty, 0 ); |
|
1108 aLocation->Property( locationDef.GetPropertyDefL( |
|
1109 Location::KAltitudeProperty ), altitudeProperty, 0 ); |
|
1110 aLocation->Property( locationDef.GetPropertyDefL( |
|
1111 Location::KQualityProperty ), qualityProperty, 0 ); |
|
1112 |
|
1113 CExifModify* exifWriter = CExifModify::NewL( aImagePtr, |
|
1114 CExifModify::EModify, CExifModify::ENoJpegParsing ); |
|
1115 CleanupStack::PushL( exifWriter ); |
|
1116 const CExifRead* exifReader = exifWriter->Reader(); |
|
1117 |
|
1118 TBool exifChanged = EFalse; |
|
1119 TBool changed = EFalse; |
|
1120 const TReal KAngleSecond = 1.0 / 3600.0; |
|
1121 TInt exifError( 0 ); |
|
1122 // location data (all fields are optional) |
|
1123 // latitude |
|
1124 const CExifTag* exifLatitudeRefTag = NULL; |
|
1125 TRAP( exifError, exifLatitudeRefTag = exifReader->GetTagL( EIfdGps, KIdGpsLatitudeRef ) ); |
|
1126 if ( latitudeProperty ) |
|
1127 { |
|
1128 TBuf8<2> south( KSouth ); |
|
1129 TBuf8<2> north( KNorth ); |
|
1130 TReal64 latitude = latitudeProperty->Real64ValueL(); |
|
1131 |
|
1132 TReal64 exifLatitude( 0.0 ); |
|
1133 TBuf8<2> exifLatitudeRef; |
|
1134 if ( exifError == KErrNone ) |
|
1135 { |
|
1136 TPtrC8 exifLatitudeRefBuf( exifLatitudeRefTag->Data() ); |
|
1137 exifLatitudeRef.Append( exifLatitudeRefBuf.Ptr(), 2 ); |
|
1138 |
|
1139 if ( latitude < 0 ) |
|
1140 { |
|
1141 if ( south.Compare(exifLatitudeRef) ) |
|
1142 { |
|
1143 changed = ETrue; |
|
1144 } |
|
1145 } |
|
1146 else |
|
1147 { |
|
1148 if ( north.Compare(exifLatitudeRef) ) |
|
1149 { |
|
1150 changed = ETrue; |
|
1151 } |
|
1152 } |
|
1153 |
|
1154 if ( !changed ) |
|
1155 { |
|
1156 TBuf8<KCoordinateBufferSize> exifLatitudeBuf; |
|
1157 const CExifTag* exifLatitudeTag = NULL; |
|
1158 TRAPD( err, exifLatitudeTag = exifReader->GetTagL( EIfdGps, KIdGpsLatitude ) ); |
|
1159 if ( err == KErrNone ) |
|
1160 { |
|
1161 TPtrC8 exifLatitudeTagBuf( exifLatitudeTag->Data() ); |
|
1162 exifLatitudeBuf.Append( exifLatitudeTagBuf.Ptr(), KCoordinateBufferSize ); |
|
1163 MdsUtils::ConvertFromDegreesToDecimalL( exifLatitudeBuf, exifLatitude ); |
|
1164 } |
|
1165 else |
|
1166 { |
|
1167 exifError = err; |
|
1168 } |
|
1169 } |
|
1170 } |
|
1171 |
|
1172 if ( exifError != KErrNone || changed || Abs(exifLatitude - latitude) > KAngleSecond ) |
|
1173 { |
|
1174 // latitude ref (N/S) |
|
1175 if ( latitude < 0 ) |
|
1176 { |
|
1177 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1178 KIdGpsLatitudeRef, CExifTag::ETagAscii, 2 ), south ); |
|
1179 latitude = -latitude; |
|
1180 } |
|
1181 else |
|
1182 { |
|
1183 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1184 KIdGpsLatitudeRef, CExifTag::ETagAscii, 2 ), north ); |
|
1185 } |
|
1186 |
|
1187 TBuf8<KCoordinateBufferSize> latitudeBuf; |
|
1188 MdsUtils::ConvertFromDecimalToDegreesL( latitude, latitudeBuf ); |
|
1189 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1190 KIdGpsLatitude, CExifTag::ETagRational, 3 ), latitudeBuf ); |
|
1191 exifChanged = ETrue; |
|
1192 } |
|
1193 } |
|
1194 else if ( exifError == KErrNone ) |
|
1195 { |
|
1196 exifWriter->DeleteTag( EIfdGps, KIdGpsLatitudeRef ); |
|
1197 exifWriter->DeleteTag( EIfdGps, KIdGpsLatitude ); |
|
1198 exifChanged = ETrue; |
|
1199 } |
|
1200 |
|
1201 changed = EFalse; |
|
1202 |
|
1203 // longitude |
|
1204 const CExifTag* exifLongitudeRefTag = NULL; |
|
1205 TRAP( exifError, exifLongitudeRefTag = exifReader->GetTagL( |
|
1206 EIfdGps, KIdGpsLongitudeRef ) ); |
|
1207 if ( longitudeProperty ) |
|
1208 { |
|
1209 TBuf8<2> west( KWest ); |
|
1210 TBuf8<2> east( KEast ); |
|
1211 TReal64 longitude = longitudeProperty->Real64ValueL(); |
|
1212 |
|
1213 TReal64 exifLongitude( 0.0 ); |
|
1214 TBuf8<2> exifLongitudeRef; |
|
1215 if ( exifError == KErrNone ) |
|
1216 { |
|
1217 TPtrC8 exifLongitudeRefBuf( exifLongitudeRefTag->Data() ); |
|
1218 exifLongitudeRef.Append( exifLongitudeRefBuf.Ptr(), 2 ); |
|
1219 |
|
1220 if ( longitude < 0 ) |
|
1221 { |
|
1222 if ( west.Compare(exifLongitudeRef) ) |
|
1223 { |
|
1224 changed = ETrue; |
|
1225 } |
|
1226 } |
|
1227 else |
|
1228 { |
|
1229 if ( east.Compare(exifLongitudeRef) ) |
|
1230 { |
|
1231 changed = ETrue; |
|
1232 } |
|
1233 } |
|
1234 |
|
1235 if ( !changed ) |
|
1236 { |
|
1237 TBuf8<KCoordinateBufferSize> exifLongitudeBuf; |
|
1238 const CExifTag* exifLongitudeTag = NULL; |
|
1239 TRAPD( err, exifLongitudeTag = exifReader->GetTagL( EIfdGps, KIdGpsLongitude ) ); |
|
1240 if ( err == KErrNone ) |
|
1241 { |
|
1242 TPtrC8 exifLongitudeTagBuf( exifLongitudeTag->Data() ); |
|
1243 exifLongitudeBuf.Append( exifLongitudeTagBuf.Ptr(), KCoordinateBufferSize ); |
|
1244 MdsUtils::ConvertFromDegreesToDecimalL( exifLongitudeBuf, exifLongitude ); |
|
1245 if ( exifLongitudeRef.Compare( KWest ) == 0 ) |
|
1246 { |
|
1247 exifLongitude = -exifLongitude; |
|
1248 } |
|
1249 } |
|
1250 else |
|
1251 { |
|
1252 exifError = err; |
|
1253 } |
|
1254 } |
|
1255 } |
|
1256 |
|
1257 if ( exifError != KErrNone || changed || Abs(exifLongitude - longitude) > KAngleSecond ) |
|
1258 { |
|
1259 // longitude ref (E/W) |
|
1260 if ( longitude < 0 ) |
|
1261 { |
|
1262 exifWriter->SetTagL( EIfdGps, |
|
1263 TExifTagInfo( KIdGpsLongitudeRef, CExifTag::ETagAscii, 2 ), west ); |
|
1264 longitude = -longitude; |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 exifWriter->SetTagL( EIfdGps, |
|
1269 TExifTagInfo( KIdGpsLongitudeRef, CExifTag::ETagAscii, 2 ), east ); |
|
1270 } |
|
1271 |
|
1272 TBuf8<KCoordinateBufferSize> longitudeBuf; |
|
1273 MdsUtils::ConvertFromDecimalToDegreesL( longitude, longitudeBuf ); |
|
1274 exifWriter->SetTagL( EIfdGps, |
|
1275 TExifTagInfo( KIdGpsLongitude, CExifTag::ETagRational, 3 ), longitudeBuf ); |
|
1276 exifChanged = ETrue; |
|
1277 } |
|
1278 } |
|
1279 else if ( exifError == KErrNone ) |
|
1280 { |
|
1281 exifWriter->DeleteTag( EIfdGps, KIdGpsLongitudeRef ); |
|
1282 exifWriter->DeleteTag( EIfdGps, KIdGpsLongitude ); |
|
1283 exifChanged = ETrue; |
|
1284 } |
|
1285 |
|
1286 changed = EFalse; |
|
1287 |
|
1288 // altitude |
|
1289 const CExifTag* exifAltitudeRefTag = NULL; |
|
1290 TRAP( exifError, exifAltitudeRefTag = exifReader->GetTagL( EIfdGps, KIdGpsAltitudeRef ) ); |
|
1291 if ( altitudeProperty ) |
|
1292 { |
|
1293 TReal64 altitude = altitudeProperty->Real64ValueL(); |
|
1294 |
|
1295 TBuf8<8> altitudeBuf; |
|
1296 const TInt32 KAltDenominator = 100; |
|
1297 altitude *= KAltDenominator; |
|
1298 |
|
1299 TUint8 altitudeRef = 0; |
|
1300 TBuf8<1> altRefBuf; |
|
1301 |
|
1302 if ( altitude < 0 ) |
|
1303 { |
|
1304 altitudeRef = 1; |
|
1305 altitude = -altitude; |
|
1306 } |
|
1307 |
|
1308 altRefBuf.Append( &altitudeRef, 1 ); |
|
1309 |
|
1310 TInt32 exifAltitudeValue( 0 ); |
|
1311 TInt32 exifAltDenominator( 0 ); |
|
1312 TReal64 exifAltitude = 0.0f; |
|
1313 TBuf8<1> exifAltitudeRef; |
|
1314 if ( exifError == KErrNone ) |
|
1315 { |
|
1316 TPtrC8 exifAltitudeRefBuf( exifAltitudeRefTag->Data() ); |
|
1317 exifAltitudeRef.Append( exifAltitudeRefBuf.Ptr(), 1 ); |
|
1318 const CExifTag* exifAltitudeTag = NULL; |
|
1319 TRAPD( err, exifAltitudeTag = exifReader->GetTagL( EIfdGps, KIdGpsAltitude ) ); |
|
1320 if ( err == KErrNone ) |
|
1321 { |
|
1322 TPtrC8 exifAltitudeTagBuf( exifAltitudeTag->Data() ); |
|
1323 memcpy( &exifAltitudeValue, exifAltitudeTagBuf.Ptr(), |
|
1324 sizeof(exifAltitudeValue) ); |
|
1325 memcpy( &exifAltDenominator, |
|
1326 exifAltitudeTagBuf.Ptr()+sizeof(exifAltitudeValue), |
|
1327 sizeof(exifAltDenominator) ); |
|
1328 } |
|
1329 else |
|
1330 { |
|
1331 exifError = err; |
|
1332 } |
|
1333 exifAltitude = (TReal64)exifAltitudeValue; |
|
1334 } |
|
1335 |
|
1336 if ( exifError != KErrNone || exifAltitudeRef.Compare(altRefBuf) || |
|
1337 Abs(altitude - exifAltitude) > KAngleSecond ) |
|
1338 { |
|
1339 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1340 KIdGpsAltitudeRef, CExifTag::ETagByte, 1 ), altRefBuf ); |
|
1341 |
|
1342 TInt32 tmpAlt = (TInt32) altitude; |
|
1343 altitudeBuf.Append( (TUint8*) &tmpAlt, 4 ); |
|
1344 altitudeBuf.Append( (TUint8*) &KAltDenominator, 4 ); |
|
1345 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1346 KIdGpsAltitude, CExifTag::ETagRational, 1 ), altitudeBuf ); |
|
1347 exifChanged = ETrue; |
|
1348 |
|
1349 changed = EFalse; |
|
1350 } |
|
1351 // measure mode |
|
1352 const CExifTag* exifMeasureModeTag = NULL; |
|
1353 TRAPD( err, exifMeasureModeTag = exifReader->GetTagL( EIfdGps, KIdGpsMeasureMode ) ); |
|
1354 if ( err == KErrNone ) |
|
1355 { |
|
1356 |
|
1357 TBuf8<2> exifMeasureMode; |
|
1358 TPtrC8 exifMeasureModeBuf( exifMeasureModeTag->Data() ); |
|
1359 exifMeasureMode.Append( exifMeasureModeBuf.Ptr(), 2 ); |
|
1360 |
|
1361 if (altitude == 0) |
|
1362 { |
|
1363 if (exifMeasureMode.Compare(KMeasureMode3)) |
|
1364 { |
|
1365 changed = ETrue; |
|
1366 } |
|
1367 } |
|
1368 else |
|
1369 { |
|
1370 if (exifMeasureMode.Compare(KMeasureMode2)) |
|
1371 { |
|
1372 changed = ETrue; |
|
1373 } |
|
1374 } |
|
1375 } |
|
1376 else |
|
1377 { |
|
1378 exifError = err; |
|
1379 } |
|
1380 |
|
1381 if (err != KErrNone || changed) |
|
1382 { |
|
1383 if (altitude == 0) |
|
1384 { |
|
1385 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1386 KIdGpsMeasureMode, CExifTag::ETagAscii, 2 ), KMeasureMode2 ); |
|
1387 } |
|
1388 else |
|
1389 { |
|
1390 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1391 KIdGpsMeasureMode, CExifTag::ETagAscii, 2 ), KMeasureMode3 ); |
|
1392 } |
|
1393 } |
|
1394 } |
|
1395 else if ( exifError == KErrNone ) |
|
1396 { |
|
1397 exifWriter->DeleteTag( EIfdGps, KIdGpsAltitudeRef ); |
|
1398 exifWriter->DeleteTag( EIfdGps, KIdGpsAltitude ); |
|
1399 exifWriter->DeleteTag( EIfdGps, KIdGpsMeasureMode ); |
|
1400 exifChanged = ETrue; |
|
1401 } |
|
1402 |
|
1403 changed = EFalse; |
|
1404 |
|
1405 // quality, DOP value |
|
1406 const CExifTag* exifQualityTag = NULL; |
|
1407 TRAPD( err, exifQualityTag = exifReader->GetTagL( EIfdGps, KIdGpsDop ) ); |
|
1408 if (qualityProperty) |
|
1409 { |
|
1410 CMdEReal32Property* qualityReal = static_cast<CMdEReal32Property*>(qualityProperty); |
|
1411 TReal32 quality = qualityReal->Value(); |
|
1412 const TInt32 KQualityDenominator = 10; |
|
1413 TBuf8<8> qualityBuf; |
|
1414 TInt32 exifQualityValue( 0 ); |
|
1415 TInt32 exifQualityDenominator( 0 ); |
|
1416 TReal32 exifQuality (0.0f); |
|
1417 quality = quality * KQualityDenominator; |
|
1418 |
|
1419 if ( err == KErrNone ) |
|
1420 { |
|
1421 TPtrC8 exifQualityTagBuf( exifQualityTag->Data() ); |
|
1422 memcpy( &exifQualityValue, exifQualityTagBuf.Ptr(), |
|
1423 sizeof(exifQualityValue) ); |
|
1424 memcpy( &exifQualityDenominator, |
|
1425 exifQualityTagBuf.Ptr()+sizeof(exifQualityValue), |
|
1426 sizeof(exifQualityDenominator) ); |
|
1427 } |
|
1428 else |
|
1429 { |
|
1430 exifError = err; |
|
1431 } |
|
1432 |
|
1433 if (exifQualityDenominator > 0) |
|
1434 { |
|
1435 exifQuality = (TReal32)exifQualityValue; |
|
1436 } |
|
1437 |
|
1438 if (exifError != KErrNone || Abs(quality - exifQuality) > 0.1f) |
|
1439 { |
|
1440 |
|
1441 TInt32 tmpQuality = (TInt32) quality; |
|
1442 qualityBuf.Append( (TUint8*) &tmpQuality, 4 ); |
|
1443 qualityBuf.Append( (TUint8*) &KQualityDenominator, 4 ); |
|
1444 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1445 KIdGpsDop, CExifTag::ETagRational, 1 ), qualityBuf ); |
|
1446 exifChanged = ETrue; |
|
1447 } |
|
1448 } |
|
1449 |
|
1450 const CExifTag* exifDatumTag = NULL; |
|
1451 TRAP( err, exifDatumTag = exifReader->GetTagL( EIfdGps, KIdGpsMapDatum ) ); |
|
1452 TBuf8<7> mapdatum( KMapDatum ); |
|
1453 |
|
1454 |
|
1455 if ( err == KErrNone ) |
|
1456 { |
|
1457 if (exifDatumTag->Data().Compare(mapdatum)) |
|
1458 { |
|
1459 changed = ETrue; |
|
1460 } |
|
1461 } |
|
1462 else |
|
1463 { |
|
1464 exifError = err; |
|
1465 } |
|
1466 |
|
1467 if (exifError != KErrNone || changed) |
|
1468 { |
|
1469 exifWriter->SetTagL( EIfdGps, TExifTagInfo( |
|
1470 KIdGpsMapDatum, CExifTag::ETagAscii, 7 ), mapdatum ); |
|
1471 } |
|
1472 |
|
1473 // write the EXIF data to the image |
|
1474 if ( exifChanged ) |
|
1475 { |
|
1476 aModified = exifWriter->WriteDataL( aImagePtr ); |
|
1477 } |
|
1478 CleanupStack::PopAndDestroy( exifWriter ); |
|
1479 } |
|
1480 |
|
1481 void CHarvesterExifUtil::ReadUserCommentL( CHarvestData& aHd, CExifRead* aReader ) |
|
1482 { |
|
1483 // Getting UserComment |
|
1484 if ( aReader->TagExists(KIdUserComment, EIfdExif ) ) |
|
1485 { |
|
1486 TUint16 KMaxCommentLength = 256; |
|
1487 |
|
1488 HBufC8* comment = aReader->GetUserCommentL(); |
|
1489 CleanupStack::PushL( comment ); |
|
1490 if( comment->Length() >= 8 ) |
|
1491 { |
|
1492 TBuf8<8> commentFormat = comment->Mid( 0,8 ); |
|
1493 |
|
1494 TUint16 commentLength = comment->Length(); |
|
1495 |
|
1496 TPtrC8 userPtr = comment->Mid( 8, commentLength > KMaxCommentLength ? |
|
1497 KMaxCommentLength - 8 : commentLength - 8 ); |
|
1498 |
|
1499 if ( commentFormat.Compare(KUnicodeCodeDesignation) == 0 ) |
|
1500 { |
|
1501 WRITELOG( "CHarvesterExifUtil::ReadUserCommentL() - comment, Unicode encoding" ); |
|
1502 aHd.iComment16 = HBufC::NewL( userPtr.Length() ); |
|
1503 TPtr ptr = aHd.iComment16->Des(); |
|
1504 TPtrC16 ptr16( (TUint16*)(userPtr.Ptr()), (userPtr.Size()/2) ); |
|
1505 ptr.Copy( ptr16 ); |
|
1506 } |
|
1507 else if ( commentFormat.Compare(KAsciiCodeDesignation) == 0 || |
|
1508 commentFormat.Compare(KUnknownCodeDesignation) == 0 || |
|
1509 commentFormat.Compare(KJisCodeDesignation) == 0 ) |
|
1510 { |
|
1511 aHd.iComment16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L( userPtr ); |
|
1512 } |
|
1513 else |
|
1514 { |
|
1515 WRITELOG( "CHarvesterExifUtil::ReadUserCommentL() - unknown comment encoding" ); |
|
1516 } |
|
1517 if( aHd.iComment16 ) |
|
1518 { |
|
1519 StripNulls( *(aHd.iComment16) ); |
|
1520 } |
|
1521 } |
|
1522 CleanupStack::PopAndDestroy( comment ); |
|
1523 comment = NULL; |
|
1524 } |
|
1525 } |
|
1526 |
|
1527 void CHarvesterExifUtil::ReadXResolutionL( CHarvestData& aHd, CExifRead* aReader ) |
|
1528 { |
|
1529 //Getting X Resolution |
|
1530 TUint32 numerator = 0; |
|
1531 TUint32 denominator = 0; |
|
1532 const TInt error = aReader->GetXResolution( numerator, denominator ); |
|
1533 if ( error == KErrNone ) |
|
1534 { |
|
1535 aHd.iStoreXResolution = ETrue; |
|
1536 aHd.iXResolution = 0.0f; |
|
1537 if ( denominator > 0 ) |
|
1538 { |
|
1539 aHd.iXResolution = (TReal32) numerator / (TReal32) denominator; |
|
1540 } |
|
1541 } |
|
1542 } |
|
1543 |
|
1544 void CHarvesterExifUtil::ReadYResolutionL( CHarvestData& aHd, CExifRead* aReader ) |
|
1545 { |
|
1546 //Getting Y Resolution |
|
1547 TUint32 numerator = 0; |
|
1548 TUint32 denominator = 0; |
|
1549 const TInt error = aReader->GetYResolution( numerator, denominator ); |
|
1550 if ( error == KErrNone ) |
|
1551 { |
|
1552 aHd.iStoreYResolution = ETrue; |
|
1553 aHd.iYResolution = 0.0f; |
|
1554 if ( denominator > 0 ) |
|
1555 { |
|
1556 aHd.iYResolution = (TReal32) numerator / (TReal32) denominator; |
|
1557 } |
|
1558 } |
|
1559 } |
|
1560 |
|
1561 void CHarvesterExifUtil::ReadExposureBiasL( CHarvestData& aHd, CExifRead* aReader ) |
|
1562 { |
|
1563 // Getting exposure bias |
|
1564 TInt32 num( 0 ); |
|
1565 TInt32 deno( 0 ); |
|
1566 const TInt error = aReader->GetExposureBiasValue( num, deno ); |
|
1567 if ( error == KErrNone ) |
|
1568 { |
|
1569 aHd.iStoreExposureBias = ETrue; |
|
1570 aHd.iExposureBias = 0.0f; |
|
1571 if ( deno != 0 ) |
|
1572 { |
|
1573 aHd.iExposureBias = (TReal32) num / (TReal32) deno; |
|
1574 } |
|
1575 } |
|
1576 } |
|
1577 |
|
1578 void CHarvesterExifUtil::ReadExposureTimeL( CHarvestData& aHd, CExifRead* aReader ) |
|
1579 { |
|
1580 // Getting exposure time |
|
1581 TUint32 numerator = 0; |
|
1582 TUint32 denominator = 0; |
|
1583 const TInt error = aReader->GetExposureTime( numerator, denominator ); |
|
1584 if ( error == KErrNone ) |
|
1585 { |
|
1586 aHd.iStoreExposureTime = ETrue; |
|
1587 aHd.iExposureTime = 0.0f; |
|
1588 if ( denominator > 0 ) |
|
1589 { |
|
1590 aHd.iExposureTime = (TReal32) numerator / (TReal32) denominator; |
|
1591 } |
|
1592 } |
|
1593 } |
|
1594 |
|
1595 void CHarvesterExifUtil::ReadFNumberL( CHarvestData& aHd, CExifRead* aReader ) |
|
1596 { |
|
1597 //Getting FNumber |
|
1598 if ( aReader->TagExists(KIdFNumber, EIfdExif) ) |
|
1599 { |
|
1600 const CExifTag* tag = aReader->GetTagL( EIfdExif, KIdFNumber ); |
|
1601 TPtrC8 tagData = tag->Data(); |
|
1602 |
|
1603 TUint32 numerator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
1604 TUint32 denominator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ); |
|
1605 if ( denominator == 0 ) |
|
1606 { |
|
1607 denominator = 1; |
|
1608 } |
|
1609 |
|
1610 aHd.iFNumber = (TReal32) numerator / (TReal32) denominator; |
|
1611 aHd.iStoreFNumber = ETrue; |
|
1612 WRITELOG1( "CHarvesterExifUtil::ReadFNumberL() - fnumber %f", aHd.iFNumber ); |
|
1613 } |
|
1614 } |
|
1615 |
|
1616 void CHarvesterExifUtil::ReadShutterSpeedL( CHarvestData& aHd, CExifRead* aReader ) |
|
1617 { |
|
1618 //Getting shutter speed value |
|
1619 TInt32 num( 0 ); |
|
1620 TInt32 deno( 0 ); |
|
1621 const TInt error = aReader->GetShutterSpeedValue( num, deno ); |
|
1622 if ( error == KErrNone ) |
|
1623 { |
|
1624 aHd.iStoreShutterSpeed = ETrue; |
|
1625 aHd.iShutterSpeed = 0.0f; |
|
1626 if ( deno != 0 ) |
|
1627 { |
|
1628 aHd.iShutterSpeed = (TReal32) num / (TReal32) deno; |
|
1629 } |
|
1630 |
|
1631 WRITELOG1( "CHarvesterExifUtil::ReadExifDataL() - shutter speed %f", aHd.iShutterSpeed ); |
|
1632 } |
|
1633 } |
|
1634 |
|
1635 void CHarvesterExifUtil::ReadApertureValueL( CHarvestData& aHd, CExifRead* aReader ) |
|
1636 { |
|
1637 //Getting aHd.iAperture |
|
1638 TUint32 numerator = 0; |
|
1639 TUint32 denominator = 0; |
|
1640 const TInt error = aReader->GetApertureValue( numerator, denominator ); |
|
1641 if ( error == KErrNone ) |
|
1642 { |
|
1643 aHd.iStoreAperture = ETrue; |
|
1644 aHd.iAperture = 0.0f; |
|
1645 if ( denominator > 0 ) |
|
1646 { |
|
1647 aHd.iAperture = (TReal32) numerator / (TReal32) denominator; |
|
1648 } |
|
1649 |
|
1650 WRITELOG1( "CHarvesterExifUtil::ReadExifDataL() - aHd.iAperture %f", aHd.iAperture ); |
|
1651 } |
|
1652 } |
|
1653 |
|
1654 void CHarvesterExifUtil::ReadFocalLengthL( CHarvestData& aHd, CExifRead* aReader ) |
|
1655 { |
|
1656 //Getting focal length |
|
1657 TUint32 numerator = 0; |
|
1658 TUint32 denominator = 0; |
|
1659 if ( aReader->TagExists(KIdFocalLength, EIfdExif) ) |
|
1660 { |
|
1661 const CExifTag* tag = aReader->GetTagL( EIfdExif, KIdFocalLength ); |
|
1662 TPtrC8 tagData = tag->Data(); |
|
1663 |
|
1664 numerator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
1665 denominator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ); |
|
1666 |
|
1667 if ( denominator == 0 ) |
|
1668 { |
|
1669 denominator = 1; |
|
1670 } |
|
1671 |
|
1672 aHd.iFocalLength = (TReal32) numerator / (TReal32) denominator; |
|
1673 aHd.iStoreFocalLength = ETrue; |
|
1674 |
|
1675 WRITELOG1( "CHarvesterExifUtil::ReadExifDataL() - focal length %f", aHd.iFocalLength ); |
|
1676 } |
|
1677 } |
|
1678 |
|
1679 void CHarvesterExifUtil::ReadFocalLength35mmL( CHarvestData& aHd, CExifRead* aReader ) |
|
1680 { |
|
1681 // Getting focal length in 35 mm |
|
1682 if ( aReader->TagExists(KIdFocalLengthIn35mm, EIfdExif) ) |
|
1683 { |
|
1684 const CExifTag* tag = aReader->GetTagL( EIfdExif, KIdFocalLengthIn35mm ); |
|
1685 TPtrC8 tagData = tag->Data(); |
|
1686 |
|
1687 aHd.iFocalLengthIn35mm = MdsUtils::ToUInt16L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
1688 |
|
1689 aHd.iStoreFocalLengthIn35 = ETrue; |
|
1690 |
|
1691 WRITELOG1( "CHarvesterExifUtil::ReadExifDataL() - focal length in 35 mm: %f", aHd.iFocalLengthIn35mm ); |
|
1692 } |
|
1693 } |
|
1694 |
|
1695 void CHarvesterExifUtil::ReadFocalXPlaneResolutionL( CHarvestData& aHd, CExifRead* aReader ) |
|
1696 { |
|
1697 // Getting focal plane X resolution |
|
1698 if ( aReader->TagExists(KIdFocalPlaneXResolution, EIfdExif) ) |
|
1699 { |
|
1700 const CExifTag* tag = aReader->GetTagL( |
|
1701 EIfdExif, KIdFocalPlaneXResolution ); |
|
1702 TPtrC8 tagData = tag->Data(); |
|
1703 |
|
1704 TUint32 numerator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
1705 TUint32 denominator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ); |
|
1706 if ( denominator == 0 ) |
|
1707 { |
|
1708 denominator = 1; |
|
1709 } |
|
1710 |
|
1711 aHd.iFocalPlaneXResolution = (TReal32) numerator / (TReal32) denominator; |
|
1712 aHd.iStoreFocalPlaneXResolution = ETrue; |
|
1713 } |
|
1714 } |
|
1715 |
|
1716 void CHarvesterExifUtil::ReadFocalYPlaneResolutionL( CHarvestData& aHd, CExifRead* aReader ) |
|
1717 { |
|
1718 // Getting focal plane Y resolution |
|
1719 if ( aReader->TagExists(KIdFocalPlaneYResolution, EIfdExif) ) |
|
1720 { |
|
1721 const CExifTag* tag = aReader->GetTagL( |
|
1722 EIfdExif, KIdFocalPlaneYResolution ); |
|
1723 TPtrC8 tagData = tag->Data(); |
|
1724 |
|
1725 TUint32 numerator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() ) ); |
|
1726 TUint32 denominator = MdsUtils::ToUInt32L( CONST_CAST( TUint8*, tagData.Ptr() + 4 ) ); |
|
1727 if ( denominator == 0 ) |
|
1728 { |
|
1729 denominator = 1; |
|
1730 } |
|
1731 |
|
1732 aHd.iFocalPlaneYResolution = (TReal32) numerator / (TReal32) denominator; |
|
1733 aHd.iStoreFocalPlaneYResolution = ETrue; |
|
1734 } |
|
1735 } |
|
1736 |
|
1737 void CHarvesterExifUtil::ReadGPSLatitudeL( CHarvestData& aHd, |
|
1738 CExifRead* aReader, |
|
1739 TBool& aLatitude ) |
|
1740 { |
|
1741 const TInt KCoordinateBufferSize = 24; |
|
1742 |
|
1743 WRITELOG( "CHarvesterExifUtil::ReadGPSLatitudeL() - trying to read GPS Latitude" ); |
|
1744 |
|
1745 // Getting GPS latitude |
|
1746 if ( aReader->TagExists(KIdGpsLatitudeRef, EIfdGps) && |
|
1747 aReader->TagExists(KIdGpsLatitude, EIfdGps) ) |
|
1748 { |
|
1749 WRITELOG( "CHarvesterExifUtil::ReadGPSLatitudeL() - GPS Latitude found" ); |
|
1750 |
|
1751 TReal64 latitude = 0.0; |
|
1752 const CExifTag* refTag = aReader->GetTagL( |
|
1753 EIfdGps, KIdGpsLatitudeRef ); |
|
1754 TBuf8<2> latitudeRef = refTag->Data(); |
|
1755 const CExifTag* latitudeTag = aReader->GetTagL( |
|
1756 EIfdGps, KIdGpsLatitude ); |
|
1757 TBuf8<KCoordinateBufferSize> latitudeBuf = latitudeTag->Data(); |
|
1758 MdsUtils::ConvertFromDegreesToDecimalL( latitudeBuf, latitude ); |
|
1759 if ( latitudeRef == KSouth ) |
|
1760 { |
|
1761 latitude = -latitude; |
|
1762 } |
|
1763 aHd.iGpsLatitude = latitude; |
|
1764 aLatitude = ETrue; |
|
1765 } |
|
1766 |
|
1767 WRITELOG( "CHarvesterExifUtil::ReadGPSLatitudeL() - trying to read GPS Latitude - end" ); |
|
1768 } |
|
1769 |
|
1770 void CHarvesterExifUtil::ReadGPSLongitudeL( CHarvestData& aHd, |
|
1771 CExifRead* aReader, |
|
1772 TBool& aLatitude ) |
|
1773 { |
|
1774 const TInt KCoordinateBufferSize = 24; |
|
1775 |
|
1776 WRITELOG( "CHarvesterExifUtil::ReadGPSLongitudeL() - trying to read GPS Longitude" ); |
|
1777 |
|
1778 // Getting GPS longitude |
|
1779 if ( aReader->TagExists(KIdGpsLongitudeRef, EIfdGps) && |
|
1780 aReader->TagExists(KIdGpsLongitude, EIfdGps) ) |
|
1781 { |
|
1782 WRITELOG( "CHarvesterExifUtil::ReadGPSLatitudeL() - GPS Longitude found" ); |
|
1783 |
|
1784 TReal64 longitude = 0.0; |
|
1785 const CExifTag* refTag = aReader->GetTagL( |
|
1786 EIfdGps, KIdGpsLongitudeRef ); |
|
1787 TBuf8<2> longitudeRef = refTag->Data(); |
|
1788 const CExifTag* longitudeTag = aReader->GetTagL( |
|
1789 EIfdGps, KIdGpsLongitude ); |
|
1790 TBuf8<KCoordinateBufferSize> longitudeBuf = longitudeTag->Data(); |
|
1791 MdsUtils::ConvertFromDegreesToDecimalL( longitudeBuf, longitude ); |
|
1792 if ( longitudeRef == KWest ) |
|
1793 { |
|
1794 longitude = -longitude; |
|
1795 } |
|
1796 aHd.iGpsLongitude = longitude; |
|
1797 if ( aLatitude ) |
|
1798 { |
|
1799 aHd.iStoreGpsLatitudeAndLongitude = ETrue; |
|
1800 } |
|
1801 } |
|
1802 |
|
1803 WRITELOG( "CHarvesterExifUtil::ReadGPSLongitudeL() - trying to read GPS Longitude - end" ); |
|
1804 } |
|
1805 |
|
1806 void CHarvesterExifUtil::ReadGPSAltitudeL( CHarvestData& aHd, CExifRead* aReader ) |
|
1807 { |
|
1808 const TInt KAltitudeBufferSize = 8; |
|
1809 |
|
1810 WRITELOG( "CHarvesterExifUtil::ReadGPSLongitudeL() - trying to read GPS Altitude" ); |
|
1811 |
|
1812 // Getting GPS altitude |
|
1813 if ( aReader->TagExists(KIdGpsAltitudeRef, EIfdGps) && |
|
1814 aReader->TagExists(KIdGpsAltitude, EIfdGps) ) |
|
1815 { |
|
1816 WRITELOG( "CHarvesterExifUtil::ReadGPSLatitudeL() - GPS Altitude found" ); |
|
1817 |
|
1818 const CExifTag* refTag = aReader->GetTagL( |
|
1819 EIfdGps, KIdGpsAltitudeRef ); |
|
1820 TBuf8<1> altitudeRef = refTag->Data(); |
|
1821 const CExifTag* altitudeTag = aReader->GetTagL( |
|
1822 EIfdGps, KIdGpsAltitude ); |
|
1823 TBuf8<KAltitudeBufferSize> altitudeBuf = altitudeTag->Data(); |
|
1824 TInt32 altitude = MdsUtils::ToUInt32L( |
|
1825 CONST_CAST( TUint8*, altitudeBuf.Left(4).Ptr() ) ); |
|
1826 TInt32 denominator = MdsUtils::ToUInt32L( |
|
1827 CONST_CAST( TUint8*, altitudeBuf.Right(4).Ptr() ) ); |
|
1828 TInt8 ref = *((TUint8*) altitudeRef.Ptr()); |
|
1829 |
|
1830 if ( ref == 1 ) |
|
1831 { |
|
1832 altitude = -altitude; |
|
1833 } |
|
1834 |
|
1835 aHd.iGpsAltitude = 0.0f; |
|
1836 if ( denominator != 0 ) |
|
1837 { |
|
1838 aHd.iGpsAltitude = (TReal64)altitude / (TReal64)denominator; |
|
1839 } |
|
1840 |
|
1841 aHd.iStoreGpsAltitude = ETrue; |
|
1842 } |
|
1843 |
|
1844 WRITELOG( "CHarvesterExifUtil::ReadGPSLongitudeL() - trying to read GPS Altitude - end" ); |
|
1845 } |
|
1846 |
|
1847 // End of file |