--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/metadatautility/Src/MetaDataParserID3v2.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,752 @@
+/*
+* Copyright (c) 2004 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: This class provides the base class for ID3v2 parsers.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "MetaDataParserID3v2.h"
+#include "MetaDataParserID3v22.h"
+#include "MetaDataParserID3v23.h"
+#include "MetaDataParserID3v24.h"
+#include "MetaDataSourceDescriptor.h"
+
+#include <barsc.h>
+#include <barsread.h>
+#include <TopCharacterSet.rsg>
+#include <data_caging_path_literals.hrh>
+
+// CONSTANTS
+// (ID3v2 specification found in www.id3.org)
+const TInt KID3v2HeaderLength = 10;
+const TInt KID3v2TagLength = 3;
+
+const TInt KMinimumConfidenceRequired = 90;
+const TInt KMinimumJapaneseConfidenceRequired = 75;
+const TUint KParseFromMemory = 1000000;
+
+//Album Type
+const TInt KPictureTypeOther = 0x00;
+const TInt KPictureTypePixel = 0x01;
+const TInt KPictureTypeFileIcon = 0x02;
+const TInt KPictureTypeFrontCover = 0x03;
+const TInt KPictureTypeBackCover = 0x04;
+
+// Album Type priority
+const TInt K1stAlbumArt = KPictureTypeOther;
+const TInt K2ndAlbumArt = KPictureTypeFrontCover;
+const TInt K3rdAlbumArt = KPictureTypeBackCover;
+
+_LIT8( KID3v2Tag, "ID3" );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::CMetaDataParserID3v2
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMetaDataParserID3v2::CMetaDataParserID3v2(
+ CMetaDataSource& aSource )
+ : iSource(&aSource),
+ iParseFromDescriptor(EFalse),
+ iAlbumType(-1),
+ iAlbumPtr(NULL)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::CreateID3v2ParserL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMetaDataParserID3v2* CMetaDataParserID3v2::CreateID3v2ParserL(
+ CMetaDataSource& aSource )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::CreateID3v2ParserL"));
+#endif
+ TInt version = VersionL(aSource);
+
+ CMetaDataParserID3v2* parser = NULL;
+ switch ( version )
+ {
+ case 2:
+ parser = STATIC_CAST( CMetaDataParserID3v2*, CMetaDataParserID3v22::NewL(aSource) );
+ break;
+ case 3:
+ parser = STATIC_CAST( CMetaDataParserID3v2*, CMetaDataParserID3v23::NewL(aSource) );
+ break;
+ case 4:
+ parser = STATIC_CAST( CMetaDataParserID3v2*, CMetaDataParserID3v24::NewL(aSource) );
+ break;
+ default: // KErrNotFound
+ break;
+ }
+ return parser;
+ }
+
+// Destructor
+CMetaDataParserID3v2::~CMetaDataParserID3v2()
+ {
+ if(iAutoDetectChinese || iAutoDetectRussian || iAutoDetectJapanese)
+ {
+ delete iCharacterSet;
+ delete iTopCharacterSet;
+ }
+ if(iParseFromDescriptor)
+ {
+ delete iTag;
+ delete iSourceDes;
+ }
+ if ( iAlbumPtr )
+ {
+ delete iAlbumPtr;
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::ParseL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::ParseL(
+ const RArray<TMetaDataFieldId>& aWantedFields,
+ CMetaDataFieldContainer& aContainer )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::ParseL"));
+#endif
+ iContainer = &aContainer;
+ PrepareToParseL();
+ CRepository *metadataRepository = CRepository::NewL(KCRUidMetadataUtility);
+ TInt err = KErrNone;
+ err = metadataRepository->Get(KMetadataUtilityAutoDetectChineseChars, iAutoDetectChinese);
+ if(err)
+ {
+ iAutoDetectChinese = EFalse;
+ }
+ err = metadataRepository->Get(KMetadataUtilityAutoDetectJapaneseChars, iAutoDetectJapanese);
+ if(err)
+ {
+ iAutoDetectJapanese = EFalse;
+ }
+ delete metadataRepository;
+ TLanguage lang = User::Language();
+ if(lang == ELangRussian || lang == ELangUkrainian)
+ {
+ iAutoDetectRussian = ETrue;
+ }
+ if(iAutoDetectChinese || iAutoDetectRussian || iAutoDetectJapanese)
+ {
+ CreateCharacterSetsL();
+ }
+ // choose if want to parse from descriptor
+ if(iFrameDataSize < KParseFromMemory) // 1Mb
+ {
+ iTag = HBufC8::NewL(iFrameDataSize);
+ TPtr8 des( iTag->Des() );
+ iSource->ReadL(0, des);
+
+ iSourceDes = CMetaDataSourceDescriptor::NewL(des);
+ iSource = iSourceDes;
+ iParseFromDescriptor = ETrue;
+ }
+ if ( aWantedFields.Count() == 0 )
+ {
+ ParseFramesL();
+ }
+ else
+ {
+ ParseFramesL(aWantedFields);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::ParseFramesL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::ParseFramesL()
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::ParseFramesL"));
+#endif
+ TMetaDataFieldId fieldId;
+ TInt frameSize;
+ TInt frameHeaderSize = 0;
+ while ( iFrameOffset < ( iFrameDataSize - 1 ) )
+ {
+ GetNextFieldL(fieldId, frameHeaderSize, frameSize);
+
+ if ( frameHeaderSize == 0 )
+ {
+ // We have hit the padding -> no more fields to read
+ break;
+ }
+
+ if ( frameSize < 0 || frameSize > ( iFrameDataSize - iFrameOffset ) )
+ {
+ // Invalid frame size -> stop
+ break;
+ }
+ TInt err = KErrNone; // ignore err, as some entry may be extracted without exception
+ if ( fieldId != EUnknownMetaDataField )
+ {
+ switch ( fieldId )
+ {
+ case EMetaDataSongTitle:
+ case EMetaDataArtist:
+ case EMetaDataAlbum:
+ case EMetaDataAlbumTrack:
+ case EMetaDataComposer:
+ case EMetaDataCopyright:
+ case EMetaDataOriginalArtist:
+ TRAP(err, GetTextInfoL( fieldId, frameSize ));
+ break;
+
+ case EMetaDataGenre:
+ TRAP(err, GetGenreL( frameSize ));
+ break;
+
+ case EMetaDataYear:
+ TRAP(err, GetTextYearL( frameSize ));
+ break;
+
+ case EMetaDataComment:
+ TRAP(err, GetCommentL( frameSize ));
+ break;
+
+ case EMetaDataUrl:
+ TRAP(err, GetUrlL( frameSize ));
+ break;
+
+ case EMetaDataUserUrl:
+ TRAP(err, GetUserUrlL( frameSize ));
+ break;
+
+ case EMetaDataJpeg:
+ // check for 1st album art
+ if (iAlbumType != K1stAlbumArt)
+ {
+ TRAP(err,GetJpegL( frameSize ));
+ }
+ break;
+
+ case EMetaDataDuration:
+ TRAP(err, GetDurationL( frameSize ));
+ break;
+
+ case EMetaDataDate:
+ TRAP(err, GetTextDateL( frameSize ));
+ break;
+
+ case EMetaDataRating:
+ TRAP(err, GetRatingL( frameSize ));
+ break;
+
+ default:
+ break;
+ }
+ }
+ iFrameOffset += (frameSize + frameHeaderSize);
+ }
+
+ // retrieve the album art
+ TRAPD (error, RetrieveAlbumArtL());
+ if (error)
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::ParseFramesL - RetrieveAlbumArt leave"));
+ #endif
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::ParseFramesL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::ParseFramesL(
+ const RArray<TMetaDataFieldId>& aWantedFields )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::ParseFramesL - 2"));
+#endif
+ TMetaDataFieldId fieldId;
+ TInt frameSize;
+ TInt frameHeaderSize;
+ while ( iFrameOffset < ( iFrameDataSize - 1 ) )
+ {
+ GetNextFieldL(fieldId, frameHeaderSize, frameSize);
+
+ if ( frameHeaderSize == 0 )
+ {
+ // We have hit the padding -> no more fields to read
+ break;
+ }
+
+ if ( frameSize < 0 || frameSize > ( iFrameDataSize - iFrameOffset ) )
+ {
+ // Invalid frame size -> stop
+ break;
+ }
+ TInt err = KErrNone;
+ if ( fieldId != EUnknownMetaDataField )
+ {
+ // Look for it in the wanted field array
+ TInt count( aWantedFields.Count() );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( aWantedFields[ i ] == fieldId )
+ {
+ switch ( fieldId )
+ {
+ case EMetaDataSongTitle:
+ case EMetaDataArtist:
+ case EMetaDataAlbum:
+ case EMetaDataAlbumTrack:
+ case EMetaDataComposer:
+ case EMetaDataCopyright:
+ case EMetaDataOriginalArtist:
+ TRAP(err, GetTextInfoL( fieldId, frameSize ));
+ break;
+
+ case EMetaDataGenre:
+ TRAP(err, GetGenreL( frameSize ));
+ break;
+
+ case EMetaDataYear:
+ TRAP(err, GetTextYearL( frameSize ));
+ break;
+
+ case EMetaDataComment:
+ TRAP(err, GetCommentL( frameSize ));
+ break;
+
+ case EMetaDataUrl:
+ TRAP(err, GetUrlL( frameSize ));
+ break;
+
+ case EMetaDataJpeg:
+ // check for 1st album art
+ if (iAlbumType != K1stAlbumArt)
+ {
+ TRAP(err,GetJpegL( frameSize ));
+ }
+ break;
+
+ case EMetaDataUserUrl:
+ TRAP(err, GetUserUrlL( frameSize ));
+ break;
+
+ case EMetaDataDuration:
+ TRAP(err, GetDurationL( frameSize ));
+ break;
+
+ case EMetaDataDate:
+ TRAP(err, GetTextDateL( frameSize ));
+ break;
+
+ case EMetaDataRating:
+ TRAP(err, GetRatingL( frameSize ));
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ iFrameOffset += (frameSize + frameHeaderSize);
+ }
+
+ // retrieve the album art
+ TRAPD (error, RetrieveAlbumArtL());
+ if (error)
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::ParseFramesL-2 - RetrieveAlbumArt leave"));
+ #endif
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::RetrieveAlbumArtL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::RetrieveAlbumArtL()
+ {
+ // If album art exists, add to container
+ if ( iAlbumPtr != NULL )
+ {
+ TPtr8 des( iAlbumPtr->Des() );
+ TPtrC8 pic = des.Mid(iAlbumOffset);
+ TInt length = pic.Length();
+ if ( length )
+ {
+ iContainer->AppendL( EMetaDataJpeg, pic );
+ }
+
+ // reset the album related variables
+ iAlbumType = -1;
+ iAlbumOffset = 0;
+ delete iAlbumPtr;
+ iAlbumPtr = NULL;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::Handlev2GetGenreL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::HandleV2GetGenreL( TInt aSize, TInt aKID3v2FrameHeaderLength, TInt aKID3v2GenreNameLength )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v2::GetGenreL"));
+ #endif
+
+ HBufC8* frame = HBufC8::NewLC( aSize );
+ TPtr8 des( frame->Des() );
+
+ iSource->ReadL( iFrameOffset + aKID3v2FrameHeaderLength, des, aSize );
+
+ if ( des.Length() < aSize )
+ {
+ // Partial frame
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt encoding = (TInt) (des.Left(1))[0];
+ TPtrC8 info = StripTrailingZeroes( des.Mid(1), encoding);
+ TInt length = info.Length();
+
+ if(length <= 0)
+ {
+ CleanupStack::PopAndDestroy(); // frame
+ return;
+ }
+ else
+ {
+ length = (length > aKID3v2GenreNameLength) ? length : aKID3v2GenreNameLength;
+ }
+
+ HBufC8* genreData = HBufC8::NewLC( length );
+ TPtr8 temp( genreData->Des() );
+ temp.Copy(info);
+
+ if ( encoding == 0 )
+ {
+ if ( temp[0] == KID3v2format )
+ {
+ //temp.Delete(0,1);
+ TLex8 lex(temp.Ptr() + 1);
+ TInt genreID = 0;
+ TInt err = lex.Val(genreID);
+ if(err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(2); // genreData, frame
+ return;
+ }
+ if(genreID >= 0 && genreID <= 125 || genreID == 199)
+ {
+ temp.FillZ(0);
+ MapID3GenreToStringL(genreID,temp);
+ }
+ }
+
+ if( length )
+ {
+ HBufC* data16 = HBufC::NewLC( length );
+ TPtr unicode( data16->Des() );
+ if ( ConvertToUnicodeL(encoding, temp, unicode) == KErrNone )
+ {
+ iContainer->AppendL( EMetaDataGenre, unicode );
+ }
+ CleanupStack::PopAndDestroy(data16); // data16
+ }
+ }
+ else // non ASCII
+ {
+ HBufC* dataGen16 = HBufC::NewLC( length );
+ TPtr unicodeGen( dataGen16->Des() );
+ if ( ConvertToUnicodeL(encoding, temp, unicodeGen) == KErrNone )
+ {
+ if (temp.Length() <= 2)
+ {
+ CleanupStack::PopAndDestroy(3); // dataGen16, genreData, frame
+ return;
+ }
+ temp = temp.Mid(2);
+ if(temp[0] == KID3v2format)
+ {
+ TLex16 lex(unicodeGen.Ptr()+1);
+ TInt val=0;
+ TInt err = lex.Val(val);
+ if(err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(3); // dataGen16, genreData, frame
+ return;
+ }
+
+ if(val >= 0 && val <= 125 || val == 199)
+ {
+ unicodeGen.FillZ(0);
+ MapID3GenreToStringL(val,unicodeGen);
+ }
+ }
+ iContainer->AppendL( EMetaDataGenre, unicodeGen );
+ }
+ CleanupStack::PopAndDestroy(dataGen16); // dataGen16
+ }
+ CleanupStack::PopAndDestroy(genreData); // genreData
+ CleanupStack::PopAndDestroy(frame); // frame
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::VersionL
+// -----------------------------------------------------------------------------
+//
+TInt CMetaDataParserID3v2::VersionL(
+ CMetaDataSource& aSource )
+ {
+ TInt size = 0;
+ aSource.Size( size );
+ if ( size < KID3v2HeaderLength )
+ {
+ // This isn't ID3v2
+ return KErrNotFound;
+ }
+
+ TBuf8<KID3v2HeaderLength> header;
+ aSource.ReadL( header );
+ // ID3v2 header consists of following parts:
+ // - identifier "ID3", 3 bytes
+ // - version, 2 bytes
+ // - flags, 1 byte
+ // - data length, 4 bytes
+
+ if ( header.Left( KID3v2TagLength ).Compare( KID3v2Tag ) != 0 )
+ {
+ return KErrNotFound;
+ }
+
+ TInt frameSize = 0;
+ for ( TInt i = 6; i < 10; i++ )
+ {
+ frameSize <<= 7;
+ frameSize |= header[i] & 0x7f;
+ }
+
+ if ( size < ( frameSize + KID3v2HeaderLength ) )
+ {
+ // Partial ID3v2 tag
+ User::Leave( KErrCorrupt );
+ }
+
+ return (TInt) header[3];
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::CreateCharacterSetsL
+// -----------------------------------------------------------------------------
+//
+void CMetaDataParserID3v2::CreateCharacterSetsL()
+ {
+ // Get list of charconv supported character sets
+ iCharacterSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs);
+ iTopCharacterSet = new (ELeave) CArrayFixFlat<CCnvCharacterSetConverter::SCharacterSet>(12);
+ GenerateTopCharacterSetsL();
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v1::DetectCharacterSetL
+// -----------------------------------------------------------------------------
+//
+TInt CMetaDataParserID3v2::DetectCharacterSetL(
+ const TDesC8& aDesc)
+ {
+ TInt confidence = 0;
+ TInt highestConfidence = 0;
+ TUint charSetId;
+ TUint highestConfidencecharSetId = 0;
+
+ CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC();
+ TInt count = iTopCharacterSet->Count();
+ for ( TInt i=0; i < iTopCharacterSet->Count(); i++)
+ {
+ charSetId = iTopCharacterSet->At(i).Identifier();
+ charSetConv->ConvertibleToCharSetL(confidence, charSetId, *iTopCharacterSet, aDesc);
+ if ( confidence > highestConfidence )
+ {
+ highestConfidence = confidence;
+ highestConfidencecharSetId = charSetId;
+ }
+ }
+ CleanupStack::PopAndDestroy(charSetConv);
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v1::DetectCharacterSetL :-> Confidence[%d] CharSetId[%x]"),
+ highestConfidence, highestConfidencecharSetId);
+#endif
+
+ if ( (highestConfidence >= KMinimumConfidenceRequired) || (iAutoDetectJapanese && highestConfidence >= KMinimumJapaneseConfidenceRequired ))
+ {
+ iCharacterSetId = highestConfidencecharSetId;
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::AutoDetectL
+// -----------------------------------------------------------------------------
+//
+TInt CMetaDataParserID3v2::AutoDetectL(const TDesC8& aDesc,
+ TDes16& aUnicode)
+{
+ if ( iCharacterSetId == 0 )
+ {
+ if ( DetectCharacterSetL(aDesc) == KErrNotFound )
+ {
+ return KErrNotFound;
+ }
+ }
+
+ CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC();
+ TInt state = CCnvCharacterSetConverter::KStateDefault;
+ TInt numOfUnconvertibleChars = 0;
+
+ charSetConv->PrepareToConvertToOrFromL(iCharacterSetId, *iCharacterSet, iFs);
+ TInt retVal = charSetConv->ConvertToUnicode(aUnicode, aDesc, state, numOfUnconvertibleChars);
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v1::ConvertToUnicode :-> Tag Size[%d] Unicode Tag Size[%d]Bytes Unconverted[%d] retVal[%d]"),
+ aDesc.Length(), aUnicode.Length(), numOfUnconvertibleChars, retVal);
+#endif
+ if ( retVal < 0 )
+ {
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return retVal;
+ //return KErrGeneral;
+ }
+
+ if ( retVal > 0 || numOfUnconvertibleChars > 0 )
+ {
+ // This is different character set. Need to auto detect again
+ if ( DetectCharacterSetL(aDesc) == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return KErrNotFound;
+ }
+ state = CCnvCharacterSetConverter::KStateDefault;
+ numOfUnconvertibleChars = 0;
+ charSetConv->PrepareToConvertToOrFromL(iCharacterSetId, *iCharacterSet, iFs);
+ retVal = charSetConv->ConvertToUnicode(aUnicode, aDesc, state, numOfUnconvertibleChars);
+#ifdef _DEBUG
+ RDebug::Print(_L("CMetaDataParserID3v1::ConvertToUnicode :-> Tag Size[%d] Unicode Tag Size[%d]Bytes Unconverted[%d] retVal[%d]"),
+ aDesc.Length(), aUnicode.Length(), numOfUnconvertibleChars, retVal);
+#endif
+ if ( retVal != 0 || numOfUnconvertibleChars > 0 )
+ {
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return KErrGeneral;
+ }
+ }
+ CleanupStack::PopAndDestroy(); // charSetConv
+ return KErrNone;
+}
+
+
+
+// -----------------------------------------------------------------------------
+// CMetaDataParserID3v2::Version()
+// -----------------------------------------------------------------------------
+//
+TID3Version CMetaDataParserID3v2::ID3Version()
+{
+ return EID3Version2;
+}
+
+
+//-----------------------------------------------------------------------------
+// CMetaDataParserID3v2::NeedRetrieveAlbumArt( TInt aPicType )
+//-----------------------------------------------------------------------------
+//
+TBool CMetaDataParserID3v2::NeedRetrieveAlbumArt( TInt aPicType )
+{
+ TBool ret = EFalse;
+
+ switch (iAlbumType)
+ {
+ case K1stAlbumArt :
+ // return EFalse, no need to retrieve another album art
+ break;
+ case K2ndAlbumArt :
+ if (aPicType == K1stAlbumArt)
+ {
+ ret = ETrue;
+ }
+ break;
+ case K3rdAlbumArt :
+ if ((aPicType == K1stAlbumArt) ||
+ (aPicType == K2ndAlbumArt))
+ {
+ ret = ETrue;
+ }
+ break;
+ default:
+ // There is no album art, or it is a priority album art
+ if ((iAlbumType == -1) ||
+ (aPicType == K1stAlbumArt) ||
+ (aPicType == K2ndAlbumArt) ||
+ (aPicType == K3rdAlbumArt))
+ {
+ ret = ETrue;
+ }
+ // if the old one is bad, and the new one is good, use it
+ else
+ {
+ if ( IgnoreAlbumType(iAlbumType) && !IgnoreAlbumType(aPicType) )
+ {
+ // get the new one
+ ret = ETrue;
+ }
+ }
+
+ }
+
+ return ret;
+}
+
+
+//-----------------------------------------------------------------------------
+// CMetaDataParserID3v2::IgnoreAlbumType( TInt aPicType )
+//-----------------------------------------------------------------------------
+//
+TBool CMetaDataParserID3v2::IgnoreAlbumType (TInt aPicType)
+{
+ if (aPicType == KPictureTypePixel || aPicType == KPictureTypeFileIcon)
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+
+}
+// End of File