// X__CacheFile.cpp: implementation of the X__CacheFile class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ap_AggPlusTypes.h" #include "X__CacheFile.h" #include "ap_Mem.h" #include "../CxImage/CxImage/ximage.h" X__CacheFile Z__CacheFile; BOOL if_file_exists(LPCWSTR szwFilename) { HANDLE hFile; hFile=CreateFileW(szwFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE) { if(GetLastError()==ERROR_SHARING_VIOLATION) return(TRUE); //File exists but is open return(FALSE); } CloseHandle(hFile); return(TRUE); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// X__CacheFile::X__CacheFile() { m_dwBuffSizeTotal=0; m_cache_items.reserve(255); } X__CacheFile::~X__CacheFile() { for(unsigned int i=0;im_pBuff); #ifdef _DEBUG assert(m_dwBuffSizeTotal>=pItm->m_dwBuffSize); m_dwBuffSizeTotal-=pItm->m_dwBuffSize; #endif delete(pItm); } /* for(CChain *pc_item=m_cache_items.GetPrev(); pc_item; pc_item=pc_item->GetPrev()) { CItem *pItm=(CItem *) pc_item->GetData(); Aggplus::ap_free(pItm->m_pBuff); #ifdef _DEBUG assert(m_dwBuffSizeTotal>=pItm->m_dwBuffSize); m_dwBuffSizeTotal-=pItm->m_dwBuffSize; #endif delete(pItm); } */ } LPVOID X__CacheFile::GetCreateItemBuff(LPCWSTR szwFilename, DWORD *pdwRetWidth, DWORD *pdwRetHeight) { *pdwRetWidth=*pdwRetHeight=0; if(!if_file_exists(szwFilename)) return(NULL); WIN32_FILE_ATTRIBUTE_DATA FileInfo; if(!GetFileAttributesExW(szwFilename, GetFileExInfoStandard, &FileInfo)) return(NULL); CKey key_search; key_search.m_dwFileSizeLow=FileInfo.nFileSizeLow; key_search.m_dwFileSizeHigh=FileInfo.nFileSizeHigh; key_search.m_ftCreationTime=FileInfo.ftCreationTime; key_search.m_ftLastWriteTime=FileInfo.ftLastWriteTime; //Search Cache for(unsigned int i=0;iGetPrev()) // { // CItem *pItm=(CItem *) pc_item->GetData(); if( memcmp(&(pItm->m_Key), &key_search, sizeof(CKey)) == 0 && wcscmp(pItm->m_wcFilename, szwFilename)==0 ) { GetSystemTimeAsFileTime(&pItm->m_ftLastRequested); *pdwRetWidth=pItm->m_dwWidth; *pdwRetHeight=pItm->m_dwHeight; pItm->m_nUsage++; return(pItm->m_pBuff); } } DWORD dwWidth, dwHeight; void *ppBuff; if(xx_Get_RGBA_from_file(szwFilename, &dwWidth, &dwHeight, &ppBuff)) { if(EnsureFreeSpace(dwWidth*dwHeight*4)) { //Dodadi vo cache i vrati nazad params i buff CItem *pItm=new CItem; wcscpy(pItm->m_wcFilename, szwFilename); memcpy(&(pItm->m_Key), &key_search, sizeof(CKey)); pItm->m_dwWidth=dwWidth; pItm->m_dwHeight=dwHeight; pItm->m_pBuff=ppBuff; pItm->m_dwBuffSize=dwWidth*dwHeight*4; m_dwBuffSizeTotal+=pItm->m_dwBuffSize; GetSystemTimeAsFileTime(&pItm->m_ftLastRequested); pItm->m_nUsage=1; //m_cache_items.Add(pItm); m_cache_items.push_back(pItm); *pdwRetWidth=pItm->m_dwWidth; *pdwRetHeight=pItm->m_dwHeight; //pItm->m_psMemBuff->AddUsage(); //DbgAddLine("X__CacheFile: %.2f Mb %d items", (double(GetBuffSize())/1024.00)/1024.00, GetCount()); return(pItm->m_pBuff); } else { //No free space, return ordinary pointer *pdwRetWidth=dwWidth; *pdwRetHeight=dwHeight; //DbgAddLine("X__CacheFile: %.2f Mb %d items (NO SPACE)", (double(GetBuffSize())/1024.00)/1024.00, GetCount()); return(ppBuff); } } return(NULL); } void X__CacheFile::Release(LPVOID pBuff) { if(!pBuff) return; //Search Cache for(unsigned int i=0;iGetPrev()) // { // CItem *pItm=(CItem *) pc_item->GetData(); if(pItm->m_pBuff == pBuff) { pItm->m_nUsage--; assert(pItm->m_nUsage>=0); //DbgAddLine("X__CacheFile: %.2f Mb %d items (Release usage %d)", (double(GetBuffSize())/1024.00)/1024.00, GetCount(), pItm->m_nUsage); return; } } //Invalid-not in cache Aggplus::ap_free(pBuff); } LPVOID X__CacheFile::GetCreateCopy(LPVOID pSourceBuff, DWORD dwWidth, DWORD dwHeight) { if(!pSourceBuff) return(NULL); //Search Cache for(unsigned int i=0;iGetPrev()) // { // CItem *pItm=(CItem *) pc_item->GetData(); if(pItm->m_pBuff == pSourceBuff) { pItm->m_nUsage++; //DbgAddLine("X__CacheFile: %.2f Mb %d items (Fnd New usage %d)", (double(GetBuffSize())/1024.00)/1024.00, GetCount(), pItm->m_nUsage); return(pSourceBuff); } } //Invalid-not in cache, return ordinary pointer and copy from source LPVOID pRet=Aggplus::ap_malloc16(4*dwWidth*dwHeight); memcpy(pRet, pSourceBuff, 4*dwWidth*dwHeight); //DbgAddLine("X__CacheFile: %.2f Mb %d items (NO Fnd found)", (double(GetBuffSize())/1024.00)/1024.00, GetCount()); return(pRet); } bool X__CacheFile::EnsureFreeSpace(DWORD dwSize) { while(GetBuffSize()+dwSize>GetMaxBuffSize()) { //free some space if I can FILETIME ftLastRequested={0, 0}; GetSystemTimeAsFileTime(&ftLastRequested); //CChain *pc_Found=NULL; //CItem *pc_Found=NULL; int nFound=-1; for(unsigned int i=0;iGetPrev()) // { // CItem *pItm=(CItem *) pc_item->GetData(); if(pItm->m_nUsage==0) { if(CompareFileTime(&ftLastRequested, &(pItm->m_ftLastRequested))>0) { //pc_Found=pc_item; nFound=i; ftLastRequested=pItm->m_ftLastRequested; } } } //if(pc_Found) if(nFound>=0) { //CItem *pItm=(CItem *) pc_Found->GetData(); CItem *pItm=(CItem *) m_cache_items.at(nFound); //DbgAddLine("X__CacheFile: Delete item %d", nLastUsedIndex); assert(m_dwBuffSizeTotal>=pItm->m_dwBuffSize); m_dwBuffSizeTotal-=pItm->m_dwBuffSize; Aggplus::ap_free(pItm->m_pBuff); delete(pItm); //m_cache_items.Remove(pc_Found); m_cache_items.erase(m_cache_items.begin() + nFound); //TRACE("XC:Remove Item\n"); } else { return(false); } } return(true); } BOOL xx_Get_RGBA_from_file(LPCWSTR szwFilename, DWORD *pdwWidth, DWORD *pdwHeight, void **ppBuff) { if(!szwFilename || wcslen(szwFilename)<4) return(FALSE); LPCWSTR wExt=szwFilename+(wcslen(szwFilename)-4); DWORD dwImgType=CXIMAGE_FORMAT_UNKNOWN; if( _wcsicmp(wExt, L".tga")==0) dwImgType=CXIMAGE_FORMAT_TGA; //TGA else if(_wcsicmp(wExt, L".png")==0) dwImgType=CXIMAGE_FORMAT_PNG; //PNG else if(_wcsicmp(wExt, L".bmp")==0) dwImgType=CXIMAGE_FORMAT_BMP; //BMP else if(_wcsicmp(wExt, L".jpg")==0) dwImgType=CXIMAGE_FORMAT_JPG; //JPG else if(_wcsicmp(wExt, L".gif")==0) dwImgType=CXIMAGE_FORMAT_GIF; //GIF BOOL retRes = FALSE; FILE* hFile = NULL; if(dwImgType!=CXIMAGE_FORMAT_UNKNOWN) { CxImage MXimage(dwImgType); if((hFile=_wfopen(szwFilename, L"rb"))==NULL) return FALSE; // For UNICODE support if(MXimage.Decode(hFile,dwImgType)) { DWORD dwWidth=MXimage.GetWidth(); DWORD dwHeight=MXimage.GetHeight(); if(!dwWidth || !dwHeight) { goto endLbl; } *pdwWidth=dwWidth; *pdwHeight=dwHeight; (*ppBuff)=Aggplus::ap_malloc16(4*dwWidth*dwHeight); MXimage.CopyToBuffRGBA32((*ppBuff)); retRes = TRUE; } else { //TRACE(">>>Load Image Error:%s\n", MXimage.GetLastError()); } } endLbl: if (hFile) fclose(hFile); return retRes; }