bool CPicture::CreateTiledThumb(const std::vector<std::string> &files, const std::string &thumb) { if (!files.size()) return false; unsigned int num_across = (unsigned int)ceil(sqrt((float)files.size())); unsigned int num_down = (files.size() + num_across - 1) / num_across; unsigned int tile_width = g_advancedSettings.m_imageRes / num_across; unsigned int tile_height = g_advancedSettings.m_imageRes / num_down; unsigned int tile_gap = 1; bool success = false; // create a buffer for the resulting thumb uint32_t *buffer = (uint32_t *)calloc(g_advancedSettings.m_imageRes * g_advancedSettings.m_imageRes, 4); for (unsigned int i = 0; i < files.size(); ++i) { int x = i % num_across; int y = i / num_across; // load in the image unsigned int width = tile_width - 2*tile_gap, height = tile_height - 2*tile_gap; CBaseTexture *texture = CTexture::LoadFromFile(files[i], width, height, true); if (texture && texture->GetWidth() && texture->GetHeight()) { GetScale(texture->GetWidth(), texture->GetHeight(), width, height); // scale appropriately uint32_t *scaled = new uint32_t[width * height]; if (ScaleImage(texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(), (uint8_t *)scaled, width, height, width * 4)) { if (!texture->GetOrientation() || OrientateImage(scaled, width, height, texture->GetOrientation())) { success = true; // Flag that we at least had one successful image processed // drop into the texture unsigned int posX = x*tile_width + (tile_width - width)/2; unsigned int posY = y*tile_height + (tile_height - height)/2; uint32_t *dest = buffer + posX + posY*g_advancedSettings.m_imageRes; uint32_t *src = scaled; for (unsigned int y = 0; y < height; ++y) { memcpy(dest, src, width*4); dest += g_advancedSettings.m_imageRes; src += width; } } } delete[] scaled; } delete texture; } // now save to a file if (success) success = CreateThumbnailFromSurface((uint8_t *)buffer, g_advancedSettings.m_imageRes, g_advancedSettings.m_imageRes, g_advancedSettings.m_imageRes * 4, thumb); free(buffer); return success; }
CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight) { newHeight = CBaseTexture::PadPow2(newHeight); CBaseTexture* newTexture = new CTexture(m_textureWidth, newHeight, XB_FMT_A8); if (!newTexture || newTexture->GetPixels() == NULL) { CLog::Log(LOGERROR, "GUIFontTTFGL::CacheCharacter: Error creating new cache texture for size %f", m_height); return NULL; } m_textureHeight = newTexture->GetHeight(); m_textureWidth = newTexture->GetWidth(); memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch()); if (m_texture) { unsigned char* src = (unsigned char*) m_texture->GetPixels(); unsigned char* dst = (unsigned char*) newTexture->GetPixels(); for (unsigned int y = 0; y < m_texture->GetHeight(); y++) { memcpy(dst, src, m_texture->GetPitch()); src += m_texture->GetPitch(); dst += newTexture->GetPitch(); } delete m_texture; } return newTexture; }
void CBackgroundPicLoader::Process() { unsigned int totalTime = 0; unsigned int count = 0; while (!m_bStop) { // loop around forever, waiting for the app to call LoadPic if (AbortableWait(m_loadPic,10) == WAIT_SIGNALED) { if (m_pCallback) { unsigned int start = XbmcThreads::SystemClockMillis(); CBaseTexture* texture = CTexture::LoadFromFile(m_strFileName, m_maxWidth, m_maxHeight); totalTime += XbmcThreads::SystemClockMillis() - start; count++; // tell our parent bool bFullSize = false; if (texture) { bFullSize = ((int)texture->GetWidth() < m_maxWidth) && ((int)texture->GetHeight() < m_maxHeight); if (!bFullSize) { int iSize = texture->GetWidth() * texture->GetHeight() - MAX_PICTURE_SIZE; if ((iSize + (int)texture->GetWidth() > 0) || (iSize + (int)texture->GetHeight() > 0)) bFullSize = true; if (!bFullSize && texture->GetWidth() == g_Windowing.GetMaxTextureSize()) bFullSize = true; if (!bFullSize && texture->GetHeight() == g_Windowing.GetMaxTextureSize()) bFullSize = true; } } m_pCallback->OnLoadPic(m_iPic, m_iSlideNumber, m_strFileName, texture, bFullSize); m_isLoading = false; } } } if (count > 0) CLog::Log(LOGDEBUG, "Time for loading %u images: %u ms, average %u ms", count, totalTime, totalTime / count); }
void CBackgroundPicLoader::Process() { unsigned int totalTime = 0; unsigned int count = 0; while (!m_bStop) { // loop around forever, waiting for the app to call LoadPic if (WaitForSingleObject(m_loadPic, 10) == WAIT_OBJECT_0) { if (m_pCallback) { unsigned int start = CTimeUtils::GetTimeMS(); CBaseTexture* texture = new CTexture(); unsigned int originalWidth = 0; unsigned int originalHeight = 0; texture->LoadFromFile(m_strFileName, m_maxWidth, m_maxHeight, g_guiSettings.GetBool("pictures.useexifrotation"), &originalWidth, &originalHeight); totalTime += CTimeUtils::GetTimeMS() - start; count++; // tell our parent bool bFullSize = ((int)texture->GetWidth() < m_maxWidth) && ((int)texture->GetHeight() < m_maxHeight); if (!bFullSize) { int iSize = texture->GetWidth() * texture->GetHeight() - MAX_PICTURE_SIZE; if ((iSize + (int)texture->GetWidth() > 0) || (iSize + (int)texture->GetHeight() > 0)) bFullSize = true; if (!bFullSize && texture->GetWidth() == g_Windowing.GetMaxTextureSize()) bFullSize = true; if (!bFullSize && texture->GetHeight() == g_Windowing.GetMaxTextureSize()) bFullSize = true; } m_pCallback->OnLoadPic(m_iPic, m_iSlideNumber, texture, originalWidth, originalHeight, bFullSize); m_isLoading = false; } } } if (count > 0) CLog::Log(LOGDEBUG, "Time for loading %u images: %u ms, average %u ms", count, totalTime, totalTime / count); }
bool CTextureDDSJob::DoWork() { if (URIUtils::GetExtension(m_original).Equals(".dds")) return false; CBaseTexture *texture = CBaseTexture::LoadFromFile(m_original); if (texture) { // convert to DDS CDDSImage dds; CLog::Log(LOGDEBUG, "Creating DDS version of: %s", m_original.c_str()); bool ret = dds.Create(URIUtils::ReplaceExtension(m_original, ".dds"), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(), texture->GetPixels(), 40); delete texture; return ret; } return false; }
CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight) { newHeight = CBaseTexture::PadPow2(newHeight); CBaseTexture* newTexture = new CTexture(m_textureWidth, newHeight, XB_FMT_A8); if (!newTexture || newTexture->GetPixels() == NULL) { CLog::Log(LOGERROR, "GUIFontTTFGL::CacheCharacter: Error creating new cache texture for size %f", m_height); delete newTexture; return NULL; } m_textureHeight = newTexture->GetHeight(); m_textureScaleY = 1.0f / m_textureHeight; m_textureWidth = newTexture->GetWidth(); m_textureScaleX = 1.0f / m_textureWidth; if (m_textureHeight < newHeight) CLog::Log(LOGWARNING, "%s: allocated new texture with height of %d, requested %d", __FUNCTION__, m_textureHeight, newHeight); m_staticCache.Flush(); m_dynamicCache.Flush(); memset(newTexture->GetPixels(), 0, m_textureHeight * newTexture->GetPitch()); if (m_texture) { m_updateY1 = 0; m_updateY2 = m_texture->GetHeight(); unsigned char* src = (unsigned char*) m_texture->GetPixels(); unsigned char* dst = (unsigned char*) newTexture->GetPixels(); for (unsigned int y = 0; y < m_texture->GetHeight(); y++) { memcpy(dst, src, m_texture->GetPitch()); src += m_texture->GetPitch(); dst += newTexture->GetPitch(); } delete m_texture; } m_textureStatus = TEXTURE_REALLOCATED; return newTexture; }
bool CWinSystemX11::CreateNewWindow(const CStdString& name, bool fullScreen, RESOLUTION_INFO& res, PHANDLE_EVENT_FUNC userFunction) { RESOLUTION_INFO& desktop = g_settings.m_ResInfo[RES_DESKTOP]; if (fullScreen && (res.iWidth != desktop.iWidth || res.iHeight != desktop.iHeight || res.fRefreshRate != desktop.fRefreshRate || res.iScreen != desktop.iScreen)) { //on the first call to SDL_SetVideoMode, SDL stores the current displaymode //SDL restores the displaymode on SDL_QUIT(), if we change the displaymode //before the first call to SDL_SetVideoMode, SDL changes the displaymode back //to the wrong mode on exit CLog::Log(LOGINFO, "CWinSystemX11::CreateNewWindow initializing to desktop resolution first"); if (!SetFullScreen(true, desktop, false)) return false; } if(!SetFullScreen(fullScreen, res, false)) return false; CBaseTexture* iconTexture = CTexture::LoadFromFile("special://xbmc/media/icon.png"); if (iconTexture) SDL_WM_SetIcon(SDL_CreateRGBSurfaceFrom(iconTexture->GetPixels(), iconTexture->GetWidth(), iconTexture->GetHeight(), 32, iconTexture->GetPitch(), 0xff0000, 0x00ff00, 0x0000ff, 0xff000000L), NULL); SDL_WM_SetCaption("XBMC Media Center", NULL); delete iconTexture; // register XRandR Events #if defined(HAS_XRANDR) int iReturn; XRRQueryExtension(m_dpy, &m_RREventBase, &iReturn); XRRSelectInput(m_dpy, m_wmWindow, RRScreenChangeNotifyMask); #endif m_bWindowCreated = true; return true; }
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */) { std::string strPath; static CTextureArray emptyTexture; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return emptyTexture; if (size) // we found the texture { for (int i = 0; i < (int)m_vecTextures.size(); ++i) { CTextureMap *pMap = m_vecTextures[i]; if (pMap->GetName() == strTextureName) { //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); return pMap->GetTexture(); } } // Whoops, not there. return emptyTexture; } for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i) { CTextureMap* pMap = i->first; if (pMap->GetName() == strTextureName && i->second > 0) { m_vecTextures.push_back(pMap); m_unusedTextures.erase(i); return pMap->GetTexture(); } } if (checkBundleOnly && bundle == -1) return emptyTexture; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifdef _DEBUG_TEXTURES int64_t start; start = CurrentHostCounter(); #endif if (bundle >= 0 && StringUtils::EndsWithNoCase(strPath, ".gif")) { CTextureMap* pMap = nullptr; CBaseTexture **pTextures = nullptr; int nLoops = 0, width = 0, height = 0; int* Delay = nullptr; int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay); if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); delete[] pTextures; delete[] Delay; return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; pMap = new CTextureMap(strTextureName, width, height, nLoops); for (int iImage = 0; iImage < nImages; ++iImage) { pMap->Add(pTextures[iImage], Delay[iImage]); maxWidth = std::max(maxWidth, pTextures[iImage]->GetWidth()); maxHeight = std::max(maxHeight, pTextures[iImage]->GetHeight()); } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); delete[] pTextures; delete[] Delay; if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } else if (StringUtils::EndsWithNoCase(strPath, ".gif") || StringUtils::EndsWithNoCase(strPath, ".apng")) { CTextureMap* pMap = nullptr; std::string mimeType; if (StringUtils::EndsWithNoCase(strPath, ".gif")) mimeType = "image/gif"; else if (StringUtils::EndsWithNoCase(strPath, ".apng")) mimeType = "image/apng"; XFILE::CFile file; XFILE::auto_buffer buf; CFFmpegImage anim(mimeType); pMap = new CTextureMap(strTextureName, 0, 0, 0); if (file.LoadFile(strPath, buf) <= 0 || !anim.Initialize((uint8_t*)buf.get(), buf.size()) || !pMap) { CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CURL::GetRedacted(strPath).c_str()); file.Close(); return emptyTexture; } unsigned int maxWidth = 0; unsigned int maxHeight = 0; uint64_t maxMemoryUsage = 91238400;// 1920*1080*4*11 bytes, i.e, a total of approx. 12 full hd frames auto frame = anim.ReadFrame(); while (frame) { CTexture *glTexture = new CTexture(); if (glTexture) { glTexture->LoadFromMemory(anim.Width(), anim.Height(), frame->GetPitch(), XB_FMT_A8R8G8B8, true, frame->m_pImage); pMap->Add(glTexture, frame->m_delay); maxWidth = std::max(maxWidth, glTexture->GetWidth()); maxHeight = std::max(maxHeight, glTexture->GetHeight()); } if (pMap->GetMemoryUsage() <= maxMemoryUsage) { frame = anim.ReadFrame(); } else { CLog::Log(LOGDEBUG, "Memory limit (%" PRIu64 " bytes) exceeded, %i frames extracted from file : %s", (maxMemoryUsage/11)*12,pMap->GetTexture().size(), CURL::GetRedacted(strPath).c_str()); break; } } pMap->SetWidth((int)maxWidth); pMap->SetHeight((int)maxHeight); file.Close(); if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } CBaseTexture *pTexture = NULL; int width = 0, height = 0; if (bundle >= 0) { if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return emptyTexture; } } else { pTexture = CBaseTexture::LoadFromFile(strPath); if (!pTexture) return emptyTexture; width = pTexture->GetWidth(); height = pTexture->GetHeight(); } if (!pTexture) return emptyTexture; CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); pMap->Add(pTexture, 100); m_vecTextures.push_back(pMap); #ifdef _DEBUG_TEXTURES int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return pMap->GetTexture(); }
int CGUITextureManager::Load(const CStdString& strTextureName, bool checkBundleOnly /*= false */) { CStdString strPath; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return 0; if (size) // we found the texture return size; if (checkBundleOnly && bundle == -1) return 0; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifdef _DEBUG int64_t start; start = CurrentHostCounter(); #endif if (strPath.Right(4).ToLower() == ".gif") { CTextureMap* pMap; if (bundle >= 0) { CBaseTexture **pTextures; int nLoops = 0, width = 0, height = 0; int* Delay; int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay); if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } pMap = new CTextureMap(strTextureName, width, height, nLoops); for (int iImage = 0; iImage < nImages; ++iImage) { pMap->Add(pTextures[iImage], Delay[iImage]); } delete [] pTextures; delete [] Delay; } else { CAnimatedGifSet AnimatedGifSet; int iImages = AnimatedGifSet.LoadGIF(strPath.c_str()); if (iImages == 0) { CStdString rootPath = strPath.Left(g_SkinInfo->Path().GetLength()); if (0 == rootPath.CompareNoCase(g_SkinInfo->Path())) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return 0; } int iWidth = AnimatedGifSet.FrameWidth; int iHeight = AnimatedGifSet.FrameHeight; // fixup our palette COLOR *palette = AnimatedGifSet.m_vecimg[0]->Palette; // set the alpha values to fully opaque for (int i = 0; i < 256; i++) palette[i].x = 0xff; // and set the transparent colour if (AnimatedGifSet.m_vecimg[0]->Transparency && AnimatedGifSet.m_vecimg[0]->Transparent >= 0) palette[AnimatedGifSet.m_vecimg[0]->Transparent].x = 0; pMap = new CTextureMap(strTextureName, iWidth, iHeight, AnimatedGifSet.nLoops); for (int iImage = 0; iImage < iImages; iImage++) { CTexture *glTexture = new CTexture(); if (glTexture) { CAnimatedGif* pImage = AnimatedGifSet.m_vecimg[iImage]; glTexture->LoadPaletted(pImage->Width, pImage->Height, pImage->BytesPerRow, XB_FMT_A8R8G8B8, (unsigned char *)pImage->Raster, palette); pMap->Add(glTexture, pImage->Delay); } } // of for (int iImage=0; iImage < iImages; iImage++) } #ifdef _DEBUG int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif m_vecTextures.push_back(pMap); return 1; } // of if (strPath.Right(4).ToLower()==".gif") CBaseTexture *pTexture = NULL; int width = 0, height = 0; if (bundle >= 0) { if (FAILED(m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height))) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return 0; } } else { pTexture = new CTexture(); if(!pTexture->LoadFromFile(strPath)) return 0; width = pTexture->GetWidth(); height = pTexture->GetHeight(); } if (!pTexture) return 0; CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); pMap->Add(pTexture, 100); m_vecTextures.push_back(pMap); #ifdef _DEBUG_TEXTURES int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return 1; }
bool CWinSystemX11::CreateIconPixmap() { int depth; XImage *img = NULL; Visual *vis; XWindowAttributes wndattribs; XVisualInfo visInfo; double rRatio; double gRatio; double bRatio; int outIndex = 0; unsigned int i,j; unsigned char *buf; uint32_t *newBuf = 0; size_t numNewBufBytes; // Get visual Info XGetWindowAttributes(m_dpy, m_glWindow, &wndattribs); visInfo.visualid = wndattribs.visual->visualid; int nvisuals = 0; XVisualInfo* visuals = XGetVisualInfo(m_dpy, VisualIDMask, &visInfo, &nvisuals); if (nvisuals != 1) { CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not find visual"); return false; } visInfo = visuals[0]; XFree(visuals); depth = visInfo.depth; vis = visInfo.visual; if (depth < 15) { CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - no suitable depth"); return false; } rRatio = vis->red_mask / 255.0; gRatio = vis->green_mask / 255.0; bRatio = vis->blue_mask / 255.0; CBaseTexture *iconTexture = CBaseTexture::LoadFromFile("special://xbmc/media/icon256x256.png"); if (!iconTexture) return false; buf = iconTexture->GetPixels(); if (depth>=24) numNewBufBytes = (4 * (iconTexture->GetWidth() * iconTexture->GetHeight())); else numNewBufBytes = (2 * (iconTexture->GetWidth() * iconTexture->GetHeight())); newBuf = (uint32_t*)malloc(numNewBufBytes); if (!newBuf) { CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - malloc failed"); return false; } for (i=0; i<iconTexture->GetHeight();++i) { for (j=0; j<iconTexture->GetWidth();++j) { unsigned int pos = i*iconTexture->GetPitch()+j*4; unsigned int r, g, b; r = (buf[pos+2] * rRatio); g = (buf[pos+1] * gRatio); b = (buf[pos+0] * bRatio); r &= vis->red_mask; g &= vis->green_mask; b &= vis->blue_mask; newBuf[outIndex] = r | g | b; ++outIndex; } } img = XCreateImage(m_dpy, vis, depth,ZPixmap, 0, (char *)newBuf, iconTexture->GetWidth(), iconTexture->GetHeight(), (depth>=24)?32:16, 0); if (!img) { CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - could not create image"); free(newBuf); return false; } if (!XInitImage(img)) { CLog::Log(LOGERROR, "CWinSystemX11::CreateIconPixmap - init image failed"); XDestroyImage(img); return false; } // set byte order union { char c[sizeof(short)]; short s; } order; order.s = 1; if ((1 == order.c[0])) { img->byte_order = LSBFirst; } else { img->byte_order = MSBFirst; } // create icon pixmap from image m_icon = XCreatePixmap(m_dpy, m_glWindow, img->width, img->height, depth); GC gc = XCreateGC(m_dpy, m_glWindow, 0, NULL); XPutImage(m_dpy, m_icon, gc, img, 0, 0, 0, 0, img->width, img->height); XFreeGC(m_dpy, gc); XDestroyImage(img); // this also frees newBuf delete iconTexture; return true; }
const CTextureArray& CGUITextureManager::Load(const std::string& strTextureName, bool checkBundleOnly /*= false */) { std::string strPath; static CTextureArray emptyTexture; int bundle = -1; int size = 0; if (!HasTexture(strTextureName, &strPath, &bundle, &size)) return emptyTexture; if (size) // we found the texture { for (int i = 0; i < (int)m_vecTextures.size(); ++i) { CTextureMap *pMap = m_vecTextures[i]; if (pMap->GetName() == strTextureName) { //CLog::Log(LOGDEBUG, "Total memusage %u", GetMemoryUsage()); return pMap->GetTexture(); } } // Whoops, not there. return emptyTexture; } for (ilistUnused i = m_unusedTextures.begin(); i != m_unusedTextures.end(); ++i) { CTextureMap* pMap = i->first; if (pMap->GetName() == strTextureName && i->second > 0) { m_vecTextures.push_back(pMap); m_unusedTextures.erase(i); return pMap->GetTexture(); } } if (checkBundleOnly && bundle == -1) return emptyTexture; //Lock here, we will do stuff that could break rendering CSingleLock lock(g_graphicsContext); #ifdef _DEBUG_TEXTURES int64_t start; start = CurrentHostCounter(); #endif if (StringUtils::EndsWithNoCase(strPath, ".gif")) { CTextureMap* pMap = nullptr; if (bundle >= 0) { CBaseTexture **pTextures; int nLoops = 0, width = 0, height = 0; int* Delay; int nImages = m_TexBundle[bundle].LoadAnim(strTextureName, &pTextures, width, height, nLoops, &Delay); if (!nImages) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); delete [] pTextures; delete [] Delay; return emptyTexture; } pMap = new CTextureMap(strTextureName, width, height, nLoops); for (int iImage = 0; iImage < nImages; ++iImage) { pMap->Add(pTextures[iImage], Delay[iImage]); } delete [] pTextures; delete [] Delay; } else { #if defined(HAS_GIFLIB) Gif gif; if(!gif.LoadGif(strPath.c_str())) { if (StringUtils::StartsWith(strPath, g_SkinInfo->Path())) CLog::Log(LOGERROR, "Texture manager unable to load file: %s", strPath.c_str()); return emptyTexture; } pMap = new CTextureMap(strTextureName, gif.Width(), gif.Height(), gif.GetNumLoops()); for (auto frame : gif.GetFrames()) { CTexture *glTexture = new CTexture(); if (glTexture) { glTexture->LoadFromMemory(gif.Width(), gif.Height(), gif.GetPitch(), XB_FMT_A8R8G8B8, false, frame->m_pImage); pMap->Add(glTexture, frame->m_delay); } } #endif//HAS_GIFLIB } if (pMap) { m_vecTextures.push_back(pMap); return pMap->GetTexture(); } } // of if (strPath.Right(4).ToLower()==".gif") CBaseTexture *pTexture = NULL; int width = 0, height = 0; if (bundle >= 0) { if (!m_TexBundle[bundle].LoadTexture(strTextureName, &pTexture, width, height)) { CLog::Log(LOGERROR, "Texture manager unable to load bundled file: %s", strTextureName.c_str()); return emptyTexture; } } else { pTexture = CBaseTexture::LoadFromFile(strPath); if (!pTexture) return emptyTexture; width = pTexture->GetWidth(); height = pTexture->GetHeight(); } if (!pTexture) return emptyTexture; CTextureMap* pMap = new CTextureMap(strTextureName, width, height, 0); pMap->Add(pTexture, 100); m_vecTextures.push_back(pMap); #ifdef _DEBUG_TEXTURES int64_t end, freq; end = CurrentHostCounter(); freq = CurrentHostFrequency(); char temp[200]; sprintf(temp, "Load %s: %.1fms%s\n", strPath.c_str(), 1000.f * (end - start) / freq, (bundle >= 0) ? " (bundled)" : ""); OutputDebugString(temp); #endif return pMap->GetTexture(); }