--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/harvester/harvesterplugins/ImagePlugin/src/harvesterimageplugin.cpp Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,954 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Harvester image plugin
+*
+*/
+
+
+#include <e32base.h>
+#include <e32math.h>
+#include <locationdatatype.h>
+#include <harvesterdata.h>
+
+#include "harvesterlog.h"
+#include "mdsutils.h"
+#include "harvesterexifutil.h"
+#include "harvesterimageplugin.h"
+#include "mdeobjectwrapper.h"
+
+using namespace MdeConstants;
+
+// image mime types
+_LIT( KJpegMime, "image/jpeg" );
+_LIT( KJpeg2000Mime, "image/jp2" );
+_LIT( KJpeg2000_2Mime, "image/jpx" );
+_LIT( KTiffMime, "image/tiff" );
+_LIT( KMsmMime, "application/x-msmetafile" );
+_LIT( KGifMime, "image/gif" );
+_LIT( KXbmpMime, "image/x-bmp" );
+_LIT( KBmpMime, "image/bmp" );
+_LIT( KPngMime, "image/png" );
+_LIT( KMbmMime, "image/x-epoc-mbm" );
+_LIT( KOtaMime, "image/vnd.nokia.ota-bitmap" );
+_LIT( KXotaMime, "image/x-ota-bitmap" );
+_LIT( KWbmpMime, "image/vnd.wap.wbmp" );
+_LIT( KWmfMime, "image/x-wmf" );
+_LIT( KOtbMime, "image/vnd.nokia.ota-bitmap" );
+
+_LIT( KExtJpg, "JPG" );
+_LIT( KExtJpeg, "JPEG" );
+_LIT( KExtJp2, "JP2" );
+_LIT( KExtJ2k, "J2K" );
+_LIT( KExtJpx, "JPX" );
+_LIT( KExtJpf, "JPF" );
+_LIT( KExtMbm, "MBM" );
+_LIT( KExtPng, "PNG" );
+_LIT( KExtGif, "GIF" );
+_LIT( KExtBmp, "BMP" );
+_LIT( KExtTif, "TIF" );
+_LIT( KExtTiff, "TIFF" );
+_LIT( KExtOta, "OTA" );
+_LIT( KExtWbmp, "WBMP" );
+_LIT( KExtWmf, "WMF" );
+_LIT( KExtOtb, "OTB" );
+
+#ifdef MDS_MULTIPLE_STAGE_IMAGE_PROCESSING
+const TUid KBGPSUid = { 0x0ADC2480 };
+#endif
+
+CHarvesterImagePluginPropertyDefs::CHarvesterImagePluginPropertyDefs() : CBase()
+ {
+ }
+
+void CHarvesterImagePluginPropertyDefs::ConstructL(CMdEObjectDef& aObjectDef)
+ {
+ CMdENamespaceDef& nsDef = aObjectDef.NamespaceDef();
+
+ // Image property definitions
+ CMdEObjectDef& objectDef = nsDef.GetObjectDefL( Object::KBaseObject );
+ iCreationDatePropertyDef = &objectDef.GetPropertyDefL( Object::KCreationDateProperty );
+ iLastModifiedDatePropertyDef = &objectDef.GetPropertyDefL( Object::KLastModifiedDateProperty );
+ iSizePropertyDef = &objectDef.GetPropertyDefL( Object::KSizeProperty );
+ iTimeOffsetPropertyDef = &objectDef.GetPropertyDefL( Object::KTimeOffsetProperty );
+ iItemTypePropertyDef = &objectDef.GetPropertyDefL( Object::KItemTypeProperty );
+
+ // Media property definitions
+ CMdEObjectDef& mediaDef = nsDef.GetObjectDefL( MediaObject::KMediaObject );
+ iWidthPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KWidthProperty );
+ iHeightPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KHeightProperty );
+ iDescriptionPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KDescriptionProperty );
+ iCommentPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KCommentProperty );
+ iReleaseDatePropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KReleaseDateProperty );
+ iCopyrightPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KCopyrightProperty );
+ iCaptureDatePropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KCaptureDateProperty );
+ iResolutionUnitPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KResolutionUnitProperty );
+ iArtistPropertyDef = &mediaDef.GetPropertyDefL( MediaObject::KArtistProperty );
+
+ // Image property definitions
+ CMdEObjectDef& imageDef = nsDef.GetObjectDefL( Image::KImageObject );
+ iPixelYDimensionPropertyDef = &imageDef.GetPropertyDefL( Image::KPixelYDimensionProperty );
+ iPixelXDimensionPropertyDef = &imageDef.GetPropertyDefL( Image::KPixelXDimensionProperty );
+ iBitsPerSamplePropertyDef = &imageDef.GetPropertyDefL( Image::KBitsPerSampleProperty );
+ iFrameCountPropertyDef = &imageDef.GetPropertyDefL( Image::KFrameCountProperty );
+ iDateTimeOriginalPropertyDef = &imageDef.GetPropertyDefL( Image::KDateTimeOriginalProperty );
+ iDateTimeDigitizedPropertyDef = &imageDef.GetPropertyDefL( Image::KDateTimeDigitizedProperty );
+ iDateTimePropertyDef = &imageDef.GetPropertyDefL( Image::KDateTimeProperty );
+ iWhiteBalancePropertyDef = &imageDef.GetPropertyDefL( Image::KWhiteBalanceProperty );
+ iFlashPropertyDef = &imageDef.GetPropertyDefL( Image::KFlashProperty );
+ iExposureProgramPropertyDef = &imageDef.GetPropertyDefL( Image::KExposureProgramProperty );
+ iMakePropertyDef = &imageDef.GetPropertyDefL( Image::KMakeProperty );
+ iModelPropertyDef = &imageDef.GetPropertyDefL( Image::KModelProperty );
+ iOrientationPropertyDef = &imageDef.GetPropertyDefL( Image::KOrientationProperty );
+ iXResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KXResolutionProperty );
+ iYResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KYResolutionProperty );
+ iYCbCrPositioningPropertyDef = &imageDef.GetPropertyDefL( Image::KYCbCrPositioningProperty );
+ iExposureTimePropertyDef = &imageDef.GetPropertyDefL( Image::KExposureTimeProperty );
+ iFNumberPropertyDef = &imageDef.GetPropertyDefL( Image::KFNumberProperty );
+ iExifVersionPropertyDef = &imageDef.GetPropertyDefL( Image::KExifVersionProperty );
+ iShutterSpeedValuePropertyDef = &imageDef.GetPropertyDefL( Image::KShutterSpeedValueProperty );
+ iApertureValuePropertyDef = &imageDef.GetPropertyDefL( Image::KApertureValueProperty );
+ iFocalLengthPropertyDef = &imageDef.GetPropertyDefL( Image::KFocalLengthProperty );
+ iFlashPixVersionPropertyDef = &imageDef.GetPropertyDefL( Image::KFlashPixVersionProperty );
+ iColourSpacePropertyDef = &imageDef.GetPropertyDefL( Image::KColourSpaceProperty );
+ iISOSpeedRatingsPropertyDef = &imageDef.GetPropertyDefL( Image::KISOSpeedRatingsProperty );
+ iComponentsConfigurationPropertyDef = &imageDef.GetPropertyDefL( Image::KComponentsConfigurationProperty );
+ iExposureBiasValuePropertyDef = &imageDef.GetPropertyDefL( Image::KExposureBiasValueProperty );
+ iSamplesPerPixelPropertyDef = &imageDef.GetPropertyDefL( Image::KSamplesPerPixelProperty );
+ iThumbCompressionPropertyDef = &imageDef.GetPropertyDefL( Image::KThumbCompressionProperty );
+ iThumbXResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KThumbXResolutionProperty );
+ iThumbYResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KThumbYResolutionProperty );
+ iThumbResolutionUnitPropertyDef = &imageDef.GetPropertyDefL( Image::KThumbResolutionUnitProperty );
+ iFocalLengthIn35mmFilmPropertyDef = &imageDef.GetPropertyDefL( Image::KFocalLengthIn35mmFilmProperty );
+ iMeteringModePropertyDef = &imageDef.GetPropertyDefL( Image::KMeteringModeProperty );
+ iRelatedSoundFilePropertyDef = &imageDef.GetPropertyDefL( Image::KRelatedSoundFileProperty );
+ iFocalPlaneResolutionUnitPropertyDef = &imageDef.GetPropertyDefL( Image::KFocalPlaneResolutionUnitProperty );
+ iFocalPlaneXResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KFocalPlaneXResolutionProperty );
+ iFocalPlaneYResolutionPropertyDef = &imageDef.GetPropertyDefL( Image::KFocalPlaneYResolutionProperty );
+ iDraftPropertyDef = &imageDef.GetPropertyDefL( Image::KDraftProperty );
+ }
+
+CHarvesterImagePluginPropertyDefs* CHarvesterImagePluginPropertyDefs::NewL(CMdEObjectDef& aObjectDef)
+ {
+ CHarvesterImagePluginPropertyDefs* self =
+ new (ELeave) CHarvesterImagePluginPropertyDefs();
+ CleanupStack::PushL( self );
+ self->ConstructL( aObjectDef );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+/**
+* Default constructor
+*/
+CHarvesterImagePlugin::CHarvesterImagePlugin() : CHarvesterPlugin(),
+ iExifUtil( NULL ), iDecoder( NULL ), iPropDefs( NULL )
+ {
+ }
+
+/**
+* Construction
+* @return Harvester image plugin
+*/
+CHarvesterImagePlugin* CHarvesterImagePlugin::NewL()
+ {
+ WRITELOG( "CHarvesterImagePlugin::NewL()" );
+ CHarvesterImagePlugin* self = new (ELeave) CHarvesterImagePlugin();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+/**
+* Destruction
+*/
+CHarvesterImagePlugin::~CHarvesterImagePlugin()
+ {
+ WRITELOG( "CHarvesterImagePlugin::~CHarvesterImagePlugin()" );
+
+ if (iDecoder)
+ {
+ iDecoder->Reset();
+ delete iDecoder;
+ }
+
+ if (iExifUtil)
+ {
+ delete iExifUtil;
+ }
+
+ delete iPropDefs;
+
+ iFbs.Disconnect();
+ }
+
+/**
+* 2nd phase constructor
+*/
+void CHarvesterImagePlugin::ConstructL()
+ {
+ WRITELOG( "CHarvesterImagePlugin::ConstructL()" );
+ iDecoder = CBufferedImageDecoder::NewL( iFs );
+ iExifUtil = CHarvesterExifUtil::NewL();
+ User::LeaveIfError( iFbs.Connect() );
+
+ TLinearOrder< TMimeTypeMapping<TImageMetadataHandling> > cmp(
+ TMimeTypeMapping<TImageMetadataHandling>::CompareFunction);
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJpg(), KJpegMime(), EJpegHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJpeg(), KJpegMime(), EJpegHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtGif(), KGifMime(), EGifHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtBmp(), KBmpMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJpf(), KJpeg2000_2Mime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJpx(), KJpeg2000_2Mime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJp2(), KJpeg2000Mime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtJ2k(), KJpeg2000Mime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtMbm(), KMbmMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtOta(), KOtaMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtPng(), KPngMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtTif(), KTiffMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtTiff(), KTiffMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtWbmp(), KWbmpMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtWmf(), KWmfMime(), EOtherHandling ), cmp ) );
+
+ User::LeaveIfError( iMimeTypeMappings.InsertInOrder( TMimeTypeMapping<TImageMetadataHandling>(
+ KExtOtb(), KOtbMime(), EOtherHandling ), cmp ) );
+ }
+
+void CHarvesterImagePlugin::HarvestL( CHarvesterData* aHD )
+ {
+ WRITELOG( "CHarvesterImagePlugin::HarvestL()" );
+ CMdEObject& mdeObject = aHD->MdeObject();
+
+ CFileData* fileData = CFileData::NewL();
+ CleanupStack::PushL( fileData );
+ CHarvestData* harvestData = CHarvestData::NewL();
+ CleanupStack::PushL( harvestData );
+
+ const TInt errorCode = GatherDataL( mdeObject, *fileData, *harvestData );
+ if ( errorCode == KErrNone || errorCode == KErrCompletion ) // ok, something got harvested
+ {
+ if ( mdeObject.Id() == 0 || mdeObject.Placeholder() ) // is a new object or placeholder
+ {
+ TRAP_IGNORE( HandleObjectPropertiesL( *harvestData, *fileData, *aHD, ETrue ) );
+ }
+ else // not a new object
+ {
+ TRAP_IGNORE( HandleObjectPropertiesL( *harvestData, *fileData, *aHD, EFalse ) );
+ }
+
+ if( harvestData->iStoreGpsLatitudeAndLongitude ||
+ harvestData->iStoreGpsAltitude )
+ {
+ TLocationData* locData = new (ELeave) TLocationData();
+
+ if( harvestData->iStoreGpsAltitude )
+ {
+ locData->iPosition.SetCoordinate(
+ harvestData->iGpsLatitude, harvestData->iGpsLongitude,
+ harvestData->iGpsAltitude);
+ }
+ else
+ {
+ locData->iPosition.SetCoordinate(
+ harvestData->iGpsLatitude, harvestData->iGpsLongitude);
+ }
+
+ // remove unnessesary values
+ locData->iNetworkInfo.iAreaKnown = EFalse;
+
+ TRealX nanX;
+ nanX.SetNaN();
+ nanX.GetTReal( locData->iQuality );
+
+ aHD->SetLocationData( locData );
+ }
+ }
+ else
+ {
+ WRITELOG1( "CHarvesterImagePlugin::HarvestL() - other error: %d", errorCode );
+ TInt convertedError = KErrNone;
+ MdsUtils::ConvertTrapError( errorCode, convertedError );
+ aHD->SetErrorCode( convertedError );
+ WRITELOG1( "CHarvesterImagePlugin::HarvestL() - returning: %d", convertedError );
+ }
+
+ // Delete image data.
+ CleanupStack::PopAndDestroy( 2, fileData );
+ }
+
+// ---------------------------------------------------------------------------
+// GatherData
+// ---------------------------------------------------------------------------
+//
+TInt CHarvesterImagePlugin::GatherDataL( CMdEObject& aMetadataObject,
+ CFileData& aFileData, CHarvestData& aHarvestData )
+ {
+#ifdef _DEBUG
+ TTime dStart, dStop;
+ dStart.UniversalTime();
+ dStop.UniversalTime();
+ WRITELOG1( "CHarvesterImagePlugin::GatherData() start %d us", (TInt)dStop.MicroSecondsFrom(dStart).Int64() );
+#endif
+
+ WRITELOG( "CHarvesterImagePlugin::GatherData()" );
+
+ TBool dataExtracted( aMetadataObject.Id() == 0 || aMetadataObject.Placeholder() );
+ aFileData.iImageDef = &aMetadataObject.Def();
+
+ if( dataExtracted )
+ {
+ CMdEProperty* prop = NULL;
+ CMdEObjectDef& objectDef = *aFileData.iImageDef;
+
+ if( !iPropDefs )
+ {
+ iPropDefs = CHarvesterImagePluginPropertyDefs::NewL( objectDef );
+ }
+
+ aMetadataObject.Property( *iPropDefs->iSizePropertyDef, prop );
+ if( prop )
+ {
+ aFileData.iFileSize = prop->Uint32ValueL();
+ }
+ else
+ {
+ dataExtracted = EFalse;
+ }
+
+ aMetadataObject.Property( *iPropDefs->iLastModifiedDatePropertyDef, prop );
+ if( prop )
+ {
+ aFileData.iModified = prop->TimeValueL();
+ }
+ else
+ {
+ dataExtracted = EFalse;
+ }
+ }
+
+ const TDesC& uri = aMetadataObject.Uri();
+
+ if( !dataExtracted )
+ {
+ TEntry entry;
+ const TInt errorcode = iFs.Entry( uri, entry );
+
+ if ( errorcode != KErrNone )
+ {
+ return errorcode; // metadata cannot be gathered!
+ }
+
+ aFileData.iModified = entry.iModified;
+ aFileData.iFileSize = (TUint)entry.iSize;
+ }
+
+ TPtrC imageFile = uri;
+
+ aFileData.iUri = &imageFile;
+ aFileData.iFrameCount = 1;
+
+ TRAPD( readError, DataFromImageFileL( aFileData ) );
+
+ if ( readError != KErrNone )
+ {
+ WRITELOG1( "CHarvesterImagePlugin::GatherData() - error reading image data, error: %d", readError );
+ return KErrCompletion; // metadata item still can be created, thus KErrCompletion
+ }
+
+ TInt err = KErrNone;
+ if ( aFileData.iExifSupported )
+ {
+ TRAP( err, iExifUtil->ReadExifDataL( aHarvestData, aFileData ) );
+ }
+ if( !aFileData.iExifSupported || err != KErrNone )
+ {
+ // Exif couldn't be found. Open the image with ICL decoder instead.
+ WRITELOG( "CHarvesterImagePlugin::GatherData() - Exif could not be read. Using ICL." );
+
+ iDecoder->Reset();
+
+ TPtr8 imageDataPtr = aFileData.iImageData->Des();
+ TRAP( err, iDecoder->OpenL(imageDataPtr, aFileData.iMime8,
+ CImageDecoder::TOptions( CImageDecoder::EPreferFastDecode | CImageDecoder::EOptionIgnoreExifMetaData ) ) );
+ WRITELOG( "CHarvesterImagePlugin::GatherData() - Image decoder has opened the file." );
+
+ if ( err != KErrNone )
+ {
+ WRITELOG1( "CHarvesterImagePlugin::GatherData() - ERROR: Decoder could not open image data! Code %d", err );
+ return KErrCompletion; // metadata item still can be created, thus KErrCompletion
+ }
+
+ if ( !iDecoder->ValidDecoder() )
+ {
+ // read all remaining data from file
+ TInt64 additionalDataSize = aFileData.iFileSize - aFileData.iImageDataSize;
+ if( additionalDataSize < 0 )
+ {
+ additionalDataSize = 0;
+ }
+
+ HBufC8* additionalData = HBufC8::NewLC( additionalDataSize );
+ if ( additionalData )
+ {
+ TPtr8 addPtr = additionalData->Des();
+ TInt readStatus = iFs.ReadFileSection(
+ *aFileData.iUri, aFileData.iImageDataSize, addPtr, additionalDataSize );
+ if ( readStatus != KErrNone )
+ {
+ CleanupStack::PopAndDestroy( additionalData );
+ return KErrCompletion;
+ }
+
+ // append all remaining data to image decoder
+ TRAP( err, iDecoder->AppendDataL( addPtr ) );
+ if ( err == KErrNone )
+ {
+ TRAP( err, iDecoder->ContinueOpenL() );
+ }
+ CleanupStack::PopAndDestroy( additionalData );
+ }
+
+ if ( err || !iDecoder->ValidDecoder() )
+ {
+ WRITELOG( "CHarvesterImagePlugin::GatherData() - ERROR: no valid decoder" );
+ return KErrCompletion; // metadata item still can be created, thus KErrCompletion
+ }
+ }
+
+ // Get image width, frame count, height and bits per pixel from image decoder.
+ const TFrameInfo info = iDecoder->FrameInfo( 0 );
+ const TSize imageSize = info.iOverallSizeInPixels;
+ const TInt framecount = iDecoder->FrameCount();
+ aFileData.iFrameCount = framecount;
+ aFileData.iImageWidth = imageSize.iWidth;
+ aFileData.iImageHeight = imageSize.iHeight;
+ aFileData.iBitsPerPixel = info.iBitsPerPixel;
+ }
+
+ WRITELOG( "CHarvesterImagePlugin::GatherData() - end" );
+
+#ifdef _DEBUG
+ dStop.UniversalTime();
+ WRITELOG1( "CHarvesterImagePlugin::GatherData() end %d us", (TInt)dStop.MicroSecondsFrom(dStart).Int64() );
+#endif
+
+ return KErrNone;
+ }
+
+///---------------------------------------------------------------------------
+/// DataFromImageFile
+///---------------------------------------------------------------------------
+void CHarvesterImagePlugin::DataFromImageFileL( CFileData& aFileData )
+ {
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL()" );
+
+ TPtrC ext;
+ if( !MdsUtils::GetExt( *aFileData.iUri, ext ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ TMimeTypeMapping<TImageMetadataHandling> finder(ext);
+ TLinearOrder< TMimeTypeMapping<TImageMetadataHandling> > cmp(
+ TMimeTypeMapping<TImageMetadataHandling>::CompareFunction);
+
+ TInt pos = iMimeTypeMappings.FindInOrder( finder, cmp );
+
+ TImageMetadataHandling handler( EOtherHandling );
+
+ if ( pos != KErrNotFound )
+ {
+ handler = iMimeTypeMappings[pos].iHandler;
+ }
+
+ switch( handler )
+ {
+ case EJpegHandling:
+ {
+ aFileData.iJpeg = ETrue;
+ const TInt K64Kb = 65536;
+ aFileData.iImageDataSize = K64Kb;
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - read first 64Kb from JPEG" );
+ break;
+ }
+ case EGifHandling:
+ {
+ aFileData.iJpeg = EFalse;
+ aFileData.iImageDataSize = aFileData.iFileSize;
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - read whole GIF file" );
+ break;
+ }
+ default:
+ {
+ aFileData.iJpeg = EFalse;
+ const TInt K4Kb = 4096;
+ aFileData.iImageDataSize = K4Kb;
+ WRITELOG1( "CHarvesterImagePlugin::DataFromImageFileL() - read first %d bytes from image", aFileData.iImageDataSize );
+ }
+ }
+
+ aFileData.iImageData = HBufC8::NewL( aFileData.iImageDataSize );
+ TPtr8 myImagePtr = aFileData.iImageData->Des();
+
+ const TInt readStatus = iFs.ReadFileSection(
+ *aFileData.iUri, 0, myImagePtr, aFileData.iImageDataSize );
+ if ( readStatus != KErrNone )
+ {
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - ERROR: file could not be read!" );
+ User::Leave( readStatus );
+ }
+
+ // extension was in mapping list, so use that
+ if ( pos != KErrNotFound )
+ {
+ aFileData.iMime8.Copy( iMimeTypeMappings[pos].iMimeType );
+ aFileData.iMime16.Copy( aFileData.iMime8 );
+ }
+ // otherwise try to recognize using image decoder
+ else
+ {
+ CImageDecoder::GetMimeTypeDataL( myImagePtr, aFileData.iMime8 );
+ aFileData.iMime16.Copy( aFileData.iMime8 );
+
+ // Check if MIME type is supported
+ User::LeaveIfError( CheckIfMimeSupported( aFileData.iMime16 ) );
+ }
+
+ // If is jpeg get EXIF data
+ if ( aFileData.iJpeg )
+ {
+ if( iExifUtil->IsValidExifData(myImagePtr) )
+ {
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - exif data found!" );
+ aFileData.iExifSupported = ETrue;
+ }
+ else
+ {
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - no exif data!" );
+ aFileData.iImageDataSize = aFileData.iFileSize;
+ aFileData.iExifSupported = EFalse;
+ }
+ }
+
+ WRITELOG( "CHarvesterImagePlugin::DataFromImageFileL() - reading IMAGE file done!" );
+ }
+
+// ---------------------------------------------------------------------------
+// HandleNewObjectL
+// ---------------------------------------------------------------------------
+//
+void CHarvesterImagePlugin::HandleObjectPropertiesL(
+ CHarvestData& aHd,
+ CFileData& aFileData,
+ CHarvesterData& aHarvesterData,
+ TBool aIsAdd )
+ {
+ WRITELOG( "CHarvesterImagePlugin::HandleObjectPropertiesL() - New MdE object" );
+
+ CMdEObject& mdeObject = aHarvesterData.MdeObject();
+
+ if( !iPropDefs )
+ {
+ iPropDefs = CHarvesterImagePluginPropertyDefs::NewL( mdeObject.Def() );
+ }
+
+ TTimeIntervalSeconds timeOffsetSeconds = User::UTCOffset();
+
+ TTime localModifiedDate = aFileData.iModified + timeOffsetSeconds;
+
+ // Object - Creation date
+ if( ! mdeObject.Placeholder() )
+ {
+ if ( aFileData.iExifSupported && aHd.iDateOriginal8 )
+ {
+ TTime originalTime = iExifUtil->ConvertExifDateTimeToSymbianTimeL(
+ aHd.iDateOriginal8->Des() );
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCreationDatePropertyDef, &originalTime, aIsAdd );
+ }
+ else if ( aIsAdd )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCreationDatePropertyDef, &localModifiedDate, aIsAdd );
+ }
+ }
+
+ // Object - last aFileData.iModified date
+ if( ! mdeObject.Placeholder() )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iLastModifiedDatePropertyDef, &aFileData.iModified, aIsAdd );
+ }
+
+ if( aFileData.iJpeg )
+ {
+ // Time offset
+ TInt16 timeOffsetMinutes = timeOffsetSeconds.Int() / 60;
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iTimeOffsetPropertyDef, &timeOffsetMinutes, aIsAdd );
+ }
+
+ // Object - Size
+ if( ! mdeObject.Placeholder() )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iSizePropertyDef, &aFileData.iFileSize, aIsAdd );
+ }
+
+ // Item Type
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iItemTypePropertyDef, &aFileData.iMime16, aIsAdd );
+
+ // MediaObject - Width
+ if ( aFileData.iExifSupported )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iWidthPropertyDef, &aHd.iImageWidthExif, aIsAdd );
+
+ // If pixelXDimension tag is found, save its value to both Width and PixelXDimension in DB.
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iPixelXDimensionPropertyDef, &aHd.iImageWidthExif, aIsAdd );
+ }
+ else if (aFileData.iImageWidth != 0)
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iWidthPropertyDef, &aFileData.iImageWidth, aIsAdd );
+ }
+
+ // MediaObject - Height
+ if ( aFileData.iExifSupported )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iHeightPropertyDef, &aHd.iImageHeightExif, aIsAdd );
+
+ // If pixelYDimension tag is found, save its value to both Height and PixelYDimension in DB.
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iPixelYDimensionPropertyDef, &aHd.iImageHeightExif, aIsAdd );
+ }
+ else if (aFileData.iImageHeight != 0)
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iHeightPropertyDef, &aFileData.iImageHeight, aIsAdd );
+ }
+
+#ifdef MDS_MULTIPLE_STAGE_IMAGE_PROCESSING
+ TBool draftVal = ETrue;
+ if( aIsAdd )
+ {
+ if( aHarvesterData.Origin() != MdeConstants::Object::ECamera )
+ {
+ draftVal = EFalse;
+ }
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDraftPropertyDef, &draftVal, aIsAdd );
+ }
+ else
+ {
+ if( aHarvesterData.ClientId() == KBGPSUid )
+ {
+ draftVal = EFalse;
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDraftPropertyDef, &draftVal, aIsAdd );
+ }
+ }
+#endif
+
+ // Image - Bits per Sample
+ if (aFileData.iBitsPerPixel != 0)
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iBitsPerSamplePropertyDef, &aFileData.iBitsPerPixel, aIsAdd );
+ }
+
+ // Image - Framecount
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFrameCountPropertyDef, &aFileData.iFrameCount, aIsAdd );
+
+ // If is jpeg write EXIF data
+ if ( aFileData.iExifSupported )
+ {
+ // MediaObject - Description
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDescriptionPropertyDef, aHd.iDescription16, aIsAdd );
+
+ // MediaObject - Comment (user comment)
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCommentPropertyDef, aHd.iComment16, aIsAdd );
+
+ // MediaObject - Release date
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iReleaseDatePropertyDef, &localModifiedDate, aIsAdd );
+
+ // MediaObject - Copyright
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCopyrightPropertyDef, aHd.iCopyright16, aIsAdd );
+
+ // Data & time original
+ if ( aHd.iDateOriginal8 )
+ {
+ TTime originalTime = iExifUtil->ConvertExifDateTimeToSymbianTimeL( aHd.iDateOriginal8->Des() );
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDateTimeOriginalPropertyDef, &originalTime, aIsAdd );
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCaptureDatePropertyDef, &originalTime, aIsAdd );
+ if( originalTime.Int64() == 0 )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCreationDatePropertyDef, &localModifiedDate, EFalse );
+ }
+ else
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iCreationDatePropertyDef, &originalTime, EFalse );
+ }
+ }
+
+ // Date & time digitized
+ if ( aHd.iDateDigitized8 )
+ {
+ TTime digitizedTime = iExifUtil->ConvertExifDateTimeToSymbianTimeL( aHd.iDateDigitized8->Des() );
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDateTimeDigitizedPropertyDef, &digitizedTime, aIsAdd );
+ }
+
+ // Date & time aFileData.iModified (DateTime tag)
+ if ( aHd.iDateModified8 )
+ {
+ TTime modifiedTime = iExifUtil->ConvertExifDateTimeToSymbianTimeL(
+ aHd.iDateModified8->Des() );
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iDateTimePropertyDef, &modifiedTime, aIsAdd );
+ }
+
+ // Artist
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iArtistPropertyDef, aHd.iArtist, aIsAdd );
+
+ // Image - White balance
+ if ( aHd.iStoreWhiteBalance )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iWhiteBalancePropertyDef, &aHd.iWhiteBalance, aIsAdd );
+ }
+
+ // Image - Flash
+ if ( aHd.iStoreFlash )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFlashPropertyDef, &aHd.iFlash, aIsAdd );
+ }
+
+ // Image - Exposure program
+ if ( aHd.iStoreExposureProgram )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iExposureProgramPropertyDef, &aHd.iExposureProgram, aIsAdd );
+ }
+
+ // Make string
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iMakePropertyDef, aHd.iMake, aIsAdd );
+
+ // Model string
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iModelPropertyDef, aHd.iModel, aIsAdd );
+
+ // Orientation
+ if ( aHd.iStoreOrientation )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iOrientationPropertyDef, &aHd.iOrientation, aIsAdd );
+ }
+
+ // X resolution
+ if ( aHd.iStoreXResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iXResolutionPropertyDef, &aHd.iXResolution, aIsAdd );
+ }
+
+ // Y resolution
+ if ( aHd.iStoreYResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iYResolutionPropertyDef, &aHd.iYResolution, aIsAdd );
+ }
+
+ // Resolution unit
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iResolutionUnitPropertyDef, &aHd.iResolutionUnit, aIsAdd );
+
+ // YCbCrPositioning
+ if ( aHd.iStoreYCbCrPositioning )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iYCbCrPositioningPropertyDef, &aHd.iYCbCrPositioning, aIsAdd );
+ }
+
+ // Exposure time
+ if ( aHd.iStoreExposureTime )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iExposureTimePropertyDef, &aHd.iExposureTime, aIsAdd );
+ }
+
+ // F number
+ if ( aHd.iStoreFNumber )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFNumberPropertyDef, &aHd.iFNumber, aIsAdd );
+ }
+
+ // EXIF version
+ if ( aHd.iStoreExifVersion )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iExifVersionPropertyDef, &aHd.iExifVersion, aIsAdd );
+ }
+
+ // Shutter speed
+ if ( aHd.iStoreShutterSpeed )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iShutterSpeedValuePropertyDef, &aHd.iShutterSpeed, aIsAdd );
+ }
+
+ // Aperture
+ if ( aHd.iStoreAperture )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iApertureValuePropertyDef, &aHd.iAperture, aIsAdd );
+ }
+
+ // Focal length
+ if ( aHd.iStoreFocalLength )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFocalLengthPropertyDef, &aHd.iFocalLength, aIsAdd );
+ }
+
+ // FlashPix version
+ if ( aHd.iStoreFlashPixVersion )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFlashPixVersionPropertyDef, &aHd.iFlashPixVersion, aIsAdd );
+ }
+
+ // Colour space
+ if ( aHd.iStoreColourSpace )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iColourSpacePropertyDef, &aHd.iColourSpace, aIsAdd );
+ }
+
+ // ISO speed rating
+ if ( aHd.iStoreIsoSpeedRating )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iISOSpeedRatingsPropertyDef, &aHd.iIsoSpeedRating, aIsAdd );
+ }
+
+ // Components configuration
+ if ( aHd.iStoreComponentsConfig )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iComponentsConfigurationPropertyDef, &aHd.iComponentsConfiguration, aIsAdd );
+ }
+
+ // Exposure bias value
+ if ( aHd.iStoreExposureBias )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iExposureBiasValuePropertyDef, &aHd.iExposureBias, aIsAdd );
+ }
+
+ // Samples per pixel
+ if ( aHd.iStoreSamplesPerPixel )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iSamplesPerPixelPropertyDef, &aHd.iSamplesPerPixel, aIsAdd );
+ }
+
+ // Thumbnail compression
+ if ( aHd.iStoreThumbCompression )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iThumbCompressionPropertyDef, &aHd.iThumbCompression, aIsAdd );
+ }
+
+ // Thumbnail X resolution
+ if ( aHd.iStoreThumbXResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iThumbXResolutionPropertyDef, &aHd.iThumbXResolution, aIsAdd );
+ }
+
+ // Thumbnail Y resolution
+ if ( aHd.iStoreThumbYResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iThumbYResolutionPropertyDef, &aHd.iThumbYResolution, aIsAdd );
+ }
+
+ // Thumbnail resolution unit
+ if ( aHd.iStoreThumbResolutionUnit )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iThumbResolutionUnitPropertyDef, &aHd.iThumbResolutionUnit, aIsAdd );
+ }
+
+ // Focal length in 35 mm
+ if ( aHd.iStoreFocalLengthIn35 )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFocalLengthIn35mmFilmPropertyDef, &aHd.iFocalLengthIn35mm, aIsAdd );
+ }
+
+ // Metering mode
+ if ( aHd.iStoreMeteringMode )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iMeteringModePropertyDef, &aHd.iMeteringMode, aIsAdd );
+ }
+
+ // Related soundfile
+ if ( aHd.iRelatedSoundFile && aHd.iRelatedSoundFile->Length() > 0 )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iRelatedSoundFilePropertyDef, aHd.iRelatedSoundFile, aIsAdd );
+ }
+
+ // Focal plane resolution unit
+ if ( aHd.iStoreFocalPlaneResolutionUnit )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFocalPlaneResolutionUnitPropertyDef, &aHd.iFocalPlaneResolutionUnit, aIsAdd );
+ }
+
+ // Focal plane X resolution
+ if ( aHd.iStoreFocalPlaneXResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFocalPlaneXResolutionPropertyDef, &aHd.iFocalPlaneXResolution, aIsAdd );
+ }
+
+ // Focal plane Y resolution
+ if ( aHd.iStoreFocalPlaneYResolution )
+ {
+ CMdeObjectWrapper::HandleObjectPropertyL(mdeObject, *iPropDefs->iFocalPlaneYResolutionPropertyDef, &aHd.iFocalPlaneYResolution, aIsAdd );
+ }
+ WRITELOG( "CHarvesterImagePlugin::HandleObjectPropertiesL() - All EXIF tags added." );
+ }
+ }
+
+//---------------------------------------------------------------------------
+// CheckIfMimeSupported
+//---------------------------------------------------------------------------
+//
+TInt CHarvesterImagePlugin::CheckIfMimeSupported(const TDesC& aMimeBuf)
+ {
+ if ( MdsUtils::Compare(KJpegMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KJpeg2000Mime, aMimeBuf) == 0
+ || MdsUtils::Compare(KJpeg2000_2Mime, aMimeBuf) == 0
+ || MdsUtils::Compare(KPngMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KGifMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KBmpMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KMsmMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KXbmpMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KWbmpMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KMbmMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KTiffMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KOtaMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KXotaMime, aMimeBuf) == 0
+ || MdsUtils::Compare(KWmfMime, aMimeBuf) == 0 )
+
+ {
+ return KErrNone;
+ }
+
+ return KErrNotSupported;
+ }