TInt CMusicPlayerImgEngine::GetAlbumArtFilenameHelper(const TSize &aSize, TFileName &aCoverFilename, CImageDecoder **aDecoder) { //do we have this in cache? if(IsInCache(aCoverFilename,aSize)) { LOG(ELogGeneral,-1,"GetAlbumArtFilename-- (%S found in cache)",&aCoverFilename); return 1; //we found it in cache } //else we need to check if this file really exists TEntry entry; if(!iEikEnv->FsSession().Entry(aCoverFilename,entry)) { TRAPD(err,*aDecoder=CImageDecoder::FileNewL(iEikEnv->FsSession(),aCoverFilename)); if(!err) { LOG(ELogGeneral,-1,"GetAlbumArtFilename-- (%S found)",&aCoverFilename); return 0; } else LOG0("Instantiating a CImageDecoder for the found %S failed. Checking other options.",&aCoverFilename); } return -1; }
/******************************************************************************* Name : DetermineBestMethodFill Description : Choose the best fill method depending on different parameters Parameters : All fill parameters (set Height to 1 and pitch to 0 if 1D) Assumptions : Limitations : Returns : Method ID *******************************************************************************/ static stavmem_MethodID_t DetermineBestMethodFill(void * const Pattern_p, void * const DestAddr_p, const U32 PatternWidth, const U32 DestWidth, const U32 PatternHeightFor2D, const U32 PatternPitchFor2D, const U32 DestHeightFor2D, const U32 DestPitchFor2D) { #ifndef STAVMEM_NOT_OPTIMIZED_MEM_ACCESS /* Variable used to avoid methods bypassing cache when cache coherence must be preserved */ BOOL MustCareAboutCache = FALSE; /* Check if there need to care about cache coherence */ #ifdef PRESERVE_CACHE_COHERENCE if (IsInCache(Pattern_p, (void *) ((U32) Pattern_p + PatternWidth - 1 + (PatternPitchFor2D * (PatternHeightFor2D - 1)))) || IsInCache(DestAddr_p, (void *) ((U32) DestAddr_p + DestWidth - 1 + (DestPitchFor2D * (DestHeightFor2D - 1))))) { MustCareAboutCache = TRUE; } #endif /* Now look for the very best method of copy. */ /* Of course, it depends on the chip. The choice below is done for STi5510, and relys on: -the memory address -the size -the cacheability -the CPU use (not considered) -the alignement (not considered) */ #ifdef __AVMEM_ACC_CSTD_H /* For very small sizes, don't loose time cheking methods, use C standard functions */ if (DestWidth < 8) { /* Best choice in that case: memcpy and memmove */ return(STAVMEM_COPY_METHOD_C_STANDARD_FUNC); } #endif /* not def __AVMEM_ACC_CSTD_H */ #ifdef __AVMEM_ACC_MPEG2DBM_H /* MPEG 2D is bypassing cache: it cannot be used if cache coherence has to be maintained */ if (!MustCareAboutCache) { /* Check best cases for MPEG 2D block move */ if (stavmem_MPEG2DBlockMove.CheckIfCanMakeIt.Fill2D(Pattern_p, PatternWidth, PatternHeightFor2D, PatternPitchFor2D, DestAddr_p, DestWidth, DestHeightFor2D, DestPitchFor2D) == ST_NO_ERROR) { return(STAVMEM_COPY_METHOD_MPEG_2D_BLOCK_MOVE); } } #endif /* not def __AVMEM_ACC_MPEG2DBM_H */ #ifdef __AVMEM_ACC_CSTD_H /* Check best cases for C standard functions */ if ((PatternWidth < 512) || /* Choose memcpy for smaller sizes */ /* ((((U32) Pattern_p) >= 0x40000000) && (((U32) Pattern_p) <= 0x4fffffff) &&*/ /* (!IsInCache(Pattern_p, (void *) ((U32) Pattern_p + PatternWidth - 1 + (PatternPitchFor2D * (PatternHeightFor2D - 1))))))*/ /* Choose memcpy when source is DRAM and there's no cache */ (FALSE) /* No more true */ ) { /* Best choice in that case: memcpy and memmove */ return(STAVMEM_COPY_METHOD_C_STANDARD_FUNC); } #endif /* not def __AVMEM_ACC_CSTD_H */ /* No very best method was found: choose a method by default. Caution: this method should always work ! (Check functions NULL in stavmem_MethodOperations_t structure) */ #ifdef __AVMEM_ACC_GPDMA_H /* If GPDMA fails, DetermineBestMethodCopy is called again to choose another method */ if (!stavmem_MemAccessDevice.LastGpdmaTranfertFailed) { /* GPDMA is bypassing cache: it cannot be used if cache coherence has to be maintained */ if (!MustCareAboutCache) { return(STAVMEM_COPY_METHOD_GPDMA); } } #endif /* not def __AVMEM_ACC_GPDMA_H */ #ifdef __AVMEM_ACC_FDMA_H /* If FDMA fails, DetermineBestMethodCopy is called again to choose another method */ if (!stavmem_MemAccessDevice.LastFdmaTranfertFailed) { /* FDMA is bypassing cache: it cannot be used if cache coherence has to be maintained */ if (!MustCareAboutCache) { return(STAVMEM_COPY_METHOD_FDMA); } } #endif /* not def __AVMEM_ACC_FDMA_H */ #ifdef __AVMEM_ACC_BMPERIPH_H /* Block move peripheral is bypassing cache: it cannot be used if cache coherence has to be maintained */ if (!MustCareAboutCache) { return(STAVMEM_COPY_METHOD_BLOCK_MOVE_PERIPHERAL); } #endif /* not def __AVMEM_ACC_BMPERIPH_H */ #ifdef __AVMEM_ACC_CSTD_H return(STAVMEM_COPY_METHOD_C_STANDARD_FUNC); #endif /* not def __AVMEM_ACC_CSTD_H */ #endif /* def STAVMEM_NOT_OPTIMIZED_MEM_ACCESS */ /* No choice of best method: copy with byte pointers */ return(STAVMEM_COPY_METHOD_BYTE_POINTERS); } /* end of DetermineBestMethodFill() */
TInt CMusicPlayerImgEngine::GetAlbumArtFilename(const CMetadata &aMetadata, const TSize &aSize, TFileName &aCoverFilename, CImageDecoder **aDecoder) { /* Function returns KErrNotFound if we find nothing, it returns 0 if we find a file, and it returns 1 if the elemnt is in cache * In aCacheIndex returns the cache index, if found there, or -1. If found in cache, the cache is updated. * If NOT found in cache, aCoverFilename contains the cover filename. If aMetadata.iCover is valid (non-NULL) * then the aCoverFilename is non-existent, e.g. e:\\Music\\Something\\Else.mp3_360.jpg The purpose in this case * would be to identify the image in the cache. * * The algorithm for finding the album art: * 1. Check if there is aMetadata.iCover. If it does, check the cache, update aCoverFilename, return. * 2. Check for KAlbumCoverNameGeneric (cover.jpg) in song's folder. * 3. Check for KAlbumCoverNameGeneric2 (folder.jpg) in song's folder. * 4. If aMetadata artist and album are non-NULL, check the Source/__Covers/Artist-Album.jpg * 5. If enabled in Preferences, create a "hint" Source/__Covers/Artist-Album.hint having 0 bytes * 6. If here, return KErrNotFound */ aMetadata.iFileDirEntry->GetFullPath(aCoverFilename,ETrue); LOG(ELogGeneral,1,"GetAlbumArtFilename++ (%S), iCover=%x",&aCoverFilename,aMetadata.iCover); TInt r,err; TEntry entry; *aDecoder=NULL; if(aMetadata.iCover) { aMetadata.iFileDirEntry->GetFullPath(aCoverFilename); //check if we have this in cache if(IsInCache(aCoverFilename,aSize)) { LOG(ELogGeneral,-1,"GetAlbumArtFilename-- (we have embedded cover, in cache)"); return 1; } else { TRAP(err,*aDecoder=CImageDecoder::DataNewL(iEikEnv->FsSession(),*aMetadata.iCover)); if(!err) { LOG(ELogGeneral,-1,"GetAlbumArtFilename-- (we have embedded cover)"); return 0; } else LOG0("Instantiating a CImageDecoder for the embedded cover failed. Checking other options."); } } //check for KAlbumCoverNameGeneric aMetadata.iFileDirEntry->iParent->GetFullPath(aCoverFilename,ETrue); TInt pathLength=aCoverFilename.Length(); aCoverFilename.Append(KAlbumCoverNameGeneric); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; //check for KAlbumCoverNameGeneric2 aCoverFilename.SetLength(pathLength); aCoverFilename.Append(KAlbumCoverNameGeneric2); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; //if we are here, we need to check if we have valid Artist and Album metadata if(aMetadata.iAlbum && aMetadata.iArtist) { //we can construct Source/__Covers/Artist-Album.jpg aMetadata.iFileDirEntry->GetSource()->GetFullPath(aCoverFilename,ETrue); aCoverFilename.Append(KCoversFolderName); pathLength=aCoverFilename.Length(); if(pathLength+aMetadata.iArtist->Length()+aMetadata.iAlbum->Length()+6<=KMaxFileName) //6= the dash + length of .jpg or .jpeg or .hint { //check for __Covers/Artist-Album.jpg aCoverFilename.Append(*aMetadata.iArtist); aCoverFilename.Append('-'); aCoverFilename.Append(*aMetadata.iAlbum); aCoverFilename.Append(KAlbumCoverExtension); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; //if we are here, the file does not exist! if((iPreferences->iPFlags&CMLauncherPreferences::EPreferencesCreateCoverHintFiles) && (pathLength+KIgnoreFolderName().Length()+aMetadata.iArtist->Length()+aMetadata.iAlbum->Length()+6<=KMaxFileName)) //filename size requirements { //check first if the hint file is in the "IGNORE" folder aCoverFilename.SetLength(pathLength); aCoverFilename.Append(KIgnoreFolderName); aCoverFilename.Append(*aMetadata.iArtist); aCoverFilename.Append('-'); aCoverFilename.Append(*aMetadata.iAlbum); aCoverFilename.Append(KHintFileExtension); if(iEikEnv->FsSession().Entry(aCoverFilename,entry)){ //the hint file was not found in the IGNORE folder //we should create a hint file aCoverFilename.SetLength(pathLength); aCoverFilename.Append(*aMetadata.iArtist); aCoverFilename.Append('-'); aCoverFilename.Append(*aMetadata.iAlbum); aCoverFilename.Append(KHintFileExtension); LOG0("Creating hint file for %S",&aCoverFilename); //first, we try to make the folder if(!iEikEnv->FsSession().MkDir(aCoverFilename.Left(pathLength))){ //set the entry as hidden TTime modifTime; modifTime.UniversalTime(); iEikEnv->FsSession().SetEntry(aCoverFilename.Left(pathLength),modifTime,KEntryAttHidden,0); } //now we create the file, IF it does not exist if(iEikEnv->FsSession().Entry(aCoverFilename,entry)){ RFile f; if((err=f.Create(iEikEnv->FsSession(),aCoverFilename,EFileWrite))){ LOG0("Creating %S hint file failed with error %d",&aCoverFilename,err); } else { LOG0("Hint file %S created successfully!",&aCoverFilename); f.Close(); }; } } } //check __Covers/Album.jpg aCoverFilename.SetLength(pathLength); aCoverFilename.Append(*aMetadata.iAlbum); aCoverFilename.Append(KAlbumCoverExtension); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; //check __Covers/Artist.jpg aCoverFilename.SetLength(pathLength); aCoverFilename.Append(*aMetadata.iArtist); aCoverFilename.Append(KAlbumCoverExtension); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; }//if(pathLength+ ... }//if(aMetadata.iAlbum && aMetadata.iArtist) //if we are here, we did not find a cover art anywhere, so we will use the generic cover art //first, check if the user has specified their own album art, and try to decode that aCoverFilename.Copy(KAlternateGenericAlbumArtName); if((r=GetAlbumArtFilenameHelper(aSize,aCoverFilename,aDecoder))>=0) return r; //if we are here, we will use generic album art LOG(ELogGeneral,-1,"GetAlbumArtFilename-- (no match found, use generic)"); *aDecoder=NULL; return KErrNotFound; }