Example #1
0
int CPicture::ConvertFile(const CStdString &srcFile, const CStdString &destFile, float rotateDegrees, int width, int height, unsigned int quality, bool mirror)
{
  DllImageLib dll;
  if (!dll.Load()) return false;
  int ret = dll.ConvertFile(srcFile.c_str(), destFile.c_str(), rotateDegrees, width, height, quality, mirror);
  if (ret)
  {
    CLog::Log(LOGERROR, "%s: Error %i converting image %s", __FUNCTION__, ret, srcFile.c_str());
    return ret;
  }
  return ret;
}
Example #2
0
bool CPicture::CreateThumbnailFromMemory(const unsigned char* buffer, int bufSize, const CStdString& extension, const CStdString& thumbFile)
{
  CLog::Log(LOGINFO, "Creating album thumb from memory: %s", thumbFile.c_str());
  DllImageLib dll;
  if (!dll.Load()) return false;
  if (!dll.CreateThumbnailFromMemory((BYTE *)buffer, bufSize, extension.c_str(), thumbFile.c_str(), g_advancedSettings.m_thumbSize, g_advancedSettings.m_thumbSize))
  {
    CLog::Log(LOGERROR, "%s: exception with fileType: %s", __FUNCTION__, extension.c_str());
    return false;
  }
  return true;
}
Example #3
0
bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const CStdString &thumbFile)
{
  CLog::Log(LOGDEBUG, "cached image '%s' size %dx%d", thumbFile.c_str(), width, height);
  if (URIUtils::GetExtension(thumbFile).Equals(".jpg"))
  {
    CJpegIO jpegImage;
    if (jpegImage.CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
      return true;
  }
  DllImageLib dll;
  if (!buffer || !dll.Load()) return false;
  return dll.CreateThumbnailFromSurface((BYTE *)buffer, width, height, stride, thumbFile.c_str());
}
Example #4
0
void CPicture::CreateFolderThumb(const CStdString *thumbs, const CStdString &folderThumb)
{ // we want to mold the thumbs together into one single one
  const char *szThumbs[4];
  for (int i=0; i < 4; i++)
    szThumbs[i] = thumbs[i].c_str();

  DllImageLib dll;
  if (!dll.Load()) return;
  if (!dll.CreateFolderThumbnail(szThumbs, folderThumb.c_str(), g_advancedSettings.m_thumbSize, g_advancedSettings.m_thumbSize))
  {
    CLog::Log(LOGERROR, "%s failed for folder thumb %s", __FUNCTION__, folderThumb.c_str());
  }
}
Example #5
0
bool CBaseTexture::LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType, unsigned int maxWidth, unsigned int maxHeight)
{
  if (!buffer || !size)
    return false;

  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
  if (mimeType == "image/jpeg")
  {
    CJpegIO jpegfile;
    if (jpegfile.Read(buffer, size, maxWidth, maxHeight))
    {
      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
      {
        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
        {
          m_hasAlpha=false;
          ClampToEdge();
          return true;
        }
      }
    }
  }
  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  CStdString ext = mimeType;
  int nPos = ext.Find('/');
  if (nPos > -1)
    ext.Delete(0, nPos + 1);

  if(!dll.LoadImageFromMemory(buffer, size, ext.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
    return false;
  }
  LoadFromImage(image);
  dll.ReleaseImage(&image);

  return true;
}
Example #6
0
bool CPicture::CacheImage(const CStdString& sourceUrl, const CStdString& destFile, int width, int height)
{
  if (width > 0 && height > 0)
  {
    CLog::Log(LOGINFO, "Caching image from: %s to %s with width %i and height %i", sourceUrl.c_str(), destFile.c_str(), width, height);
    
    DllImageLib dll;
    if (!dll.Load()) return false;

    if (URIUtils::IsInternetStream(sourceUrl, true))
    {
      CCurlFile http;
      CStdString data;
      if (http.Get(sourceUrl, data))
      {
        if (!dll.CreateThumbnailFromMemory((BYTE *)data.c_str(), data.GetLength(), URIUtils::GetExtension(sourceUrl).c_str(), destFile.c_str(), width, height))
        {
          CLog::Log(LOGERROR, "%s Unable to create new image %s from image %s", __FUNCTION__, destFile.c_str(), sourceUrl.c_str());
          return false;
        }
        return true;
      }
      return false;
    }

    if (!dll.CreateThumbnail(sourceUrl.c_str(), destFile.c_str(), width, height, g_guiSettings.GetBool("pictures.useexifrotation")))
    {
      CLog::Log(LOGERROR, "%s Unable to create new image %s from image %s", __FUNCTION__, destFile.c_str(), sourceUrl.c_str());
      return false;
    }
    return true;
  }
  else
  {
    CLog::Log(LOGINFO, "Caching image from: %s to %s", sourceUrl.c_str(), destFile.c_str());
    return CFile::Cache(sourceUrl, destFile);
  }
}
Example #7
0
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
                                bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight)
{
  if (URIUtils::GetExtension(texturePath).Equals(".dds"))
  { // special case for DDS images
    CDDSImage image;
    if (image.ReadFile(texturePath))
    {
      Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false);
      return true;
    }
    return false;
  }

#if defined(__APPLE__) && defined(__arm__)
  XFILE::CFile file;
  UInt8 *imageBuff      = NULL;
  int64_t imageBuffSize = 0;

  //open path and read data to buffer
  //this handles advancedsettings.xml pathsubstitution
  //and resulting networking
  if (file.Open(texturePath, 0))
  {
    imageBuffSize =file.GetLength();
    imageBuff = new UInt8[imageBuffSize];
    imageBuffSize = file.Read(imageBuff, imageBuffSize);
    file.Close();
  }
  else
  {
    CLog::Log(LOGERROR, "Texture manager unable to open file %s", texturePath.c_str());
    return false;
  }

  if (imageBuffSize <= 0)
  {
    CLog::Log(LOGERROR, "Texture manager read texture file failed.");
    delete [] imageBuff;
    return false;
  }

  // create the image from buffer;
  CGImageSourceRef imageSource;
  // create a CFDataRef using CFDataCreateWithBytesNoCopy and kCFAllocatorNull for deallocator.
  // this allows us to do a nocopy reference and we handle the free of imageBuff
  CFDataRef cfdata = CFDataCreateWithBytesNoCopy(NULL, imageBuff, imageBuffSize, kCFAllocatorNull);
  imageSource = CGImageSourceCreateWithData(cfdata, NULL);   
    
  if (imageSource == nil)
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", CSpecialProtocol::TranslatePath(texturePath).c_str());
    CFRelease(cfdata);
    delete [] imageBuff;
    return false;
  }

  CGImageRef image = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);

  int rotate = 0;
  if (autoRotate)
  { // get the orientation of the image for displaying it correctly
    CFDictionaryRef imagePropertiesDictionary = CGImageSourceCopyPropertiesAtIndex(imageSource,0, NULL);
    if (imagePropertiesDictionary != nil)
    {
      CFNumberRef orientation = (CFNumberRef)CFDictionaryGetValue(imagePropertiesDictionary, kCGImagePropertyOrientation);
      if (orientation != nil)
      {
        int value = 0;
        CFNumberGetValue(orientation, kCFNumberIntType, &value);
        if (value)
          rotate = value - 1;
      }
      CFRelease(imagePropertiesDictionary);
    }
  }

  CFRelease(imageSource);

  unsigned int width  = CGImageGetWidth(image);
  unsigned int height = CGImageGetHeight(image);

  m_hasAlpha = (CGImageGetAlphaInfo(image) != kCGImageAlphaNone);

  if (originalWidth)
    *originalWidth = width;
  if (originalHeight)
    *originalHeight = height;

  // check texture size limits and limit to screen size - preserving aspectratio of image  
  if ( width > g_Windowing.GetMaxTextureSize() || height > g_Windowing.GetMaxTextureSize() )
  {
    float aspect;

    if ( width > height )
    {
      aspect = (float)width / (float)height;
      width  = g_Windowing.GetWidth();
      height = (float)width / (float)aspect;
    }
    else
    {
      aspect = (float)height / (float)width;
      height = g_Windowing.GetHeight();
      width  = (float)height / (float)aspect;
    }
    CLog::Log(LOGDEBUG, "Texture manager texture clamp:new texture size: %i x %i", width, height);
  }

  // use RGBA to skip swizzling
  Allocate(width, height, XB_FMT_RGBA8);
  m_orientation = rotate;
    
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

  // hw convert jmpeg to RGBA
  CGContextRef context = CGBitmapContextCreate(m_pixels,
    width, height, 8, GetPitch(), colorSpace,
    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

  CGColorSpaceRelease(colorSpace);

  // Flip so that it isn't upside-down
  //CGContextTranslateCTM(context, 0, height);
  //CGContextScaleCTM(context, 1.0f, -1.0f);
  #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
    CGContextClearRect(context, CGRectMake(0, 0, width, height));
  #else
    #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
    // (just a way of checking whether we're running in 10.5 or later)
    if (CGContextDrawLinearGradient == 0)
      CGContextClearRect(context, CGRectMake(0, 0, width, height));
    else
    #endif
      CGContextSetBlendMode(context, kCGBlendModeCopy);
  #endif
  //CGContextSetBlendMode(context, kCGBlendModeCopy);
  CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
  CGContextRelease(context);
  CGImageRelease(image);
  CFRelease(cfdata);
  delete [] imageBuff;
#else
  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
    return false;
  }

  m_hasAlpha = NULL != image.alpha;

  Allocate(image.width, image.height, XB_FMT_A8R8G8B8);
  if (autoRotate && image.exifInfo.Orientation)
    m_orientation = image.exifInfo.Orientation - 1;
  if (originalWidth)
    *originalWidth = image.originalwidth;
  if (originalHeight)
    *originalHeight = image.originalheight;

  unsigned int dstPitch = GetPitch();
  unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes

  unsigned char *dst = m_pixels;
  unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch;

  for (unsigned int y = 0; y < m_imageHeight; y++)
  {
    unsigned char *dst2 = dst;
    unsigned char *src2 = src;
    for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3)
    {
      dst2[0] = src2[0];
      dst2[1] = src2[1];
      dst2[2] = src2[2];
      dst2[3] = 0xff;
    }
    src -= srcPitch;
    dst += dstPitch;
  }

  if(image.alpha)
  {
    dst = m_pixels + 3;
    src = image.alpha + (m_imageHeight - 1) * m_imageWidth;

    for (unsigned int y = 0; y < m_imageHeight; y++)
    {
      unsigned char *dst2 = dst;
      unsigned char *src2 = src;

      for (unsigned int x = 0; x < m_imageWidth; x++,  dst2+=4, src2++)
        *dst2 = *src2;
      src -= m_imageWidth;
      dst += dstPitch;
    }
  }
  dll.ReleaseImage(&image);
#endif

  ClampToEdge();

  return true;
}
Example #8
0
bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width, int height, int stride, const CStdString &thumbFile)
{
  DllImageLib dll;
  if (!buffer || !dll.Load()) return false;
  return dll.CreateThumbnailFromSurface((BYTE *)buffer, width, height, stride, thumbFile.c_str());
}
Example #9
0
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
                                bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight)
{
  if (URIUtils::GetExtension(texturePath).Equals(".dds"))
  { // special case for DDS images
    CDDSImage image;
    if (image.ReadFile(texturePath))
    {
      Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false);
      return true;
    }
    return false;
  }

  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
  if (URIUtils::GetExtension(texturePath).Equals(".jpg") || URIUtils::GetExtension(texturePath).Equals(".tbn"))
  {
    CJpegIO jpegfile;
    if (jpegfile.Open(texturePath, maxWidth, maxHeight))
    {
      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
      {
        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
        {
          if (autoRotate && jpegfile.Orientation())
            m_orientation = jpegfile.Orientation() - 1;
          m_hasAlpha=false;
          ClampToEdge();
          return true;
        }
      }
    }
  }

  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
    return false;
  }

  m_hasAlpha = NULL != image.alpha;

  Allocate(image.width, image.height, XB_FMT_A8R8G8B8);
  if (autoRotate && image.exifInfo.Orientation)
    m_orientation = image.exifInfo.Orientation - 1;
  if (originalWidth)
    *originalWidth = image.originalwidth;
  if (originalHeight)
    *originalHeight = image.originalheight;

  unsigned int dstPitch = GetPitch();
  unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes

  unsigned char *dst = m_pixels;
  unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch;

  for (unsigned int y = 0; y < m_imageHeight; y++)
  {
    unsigned char *dst2 = dst;
    unsigned char *src2 = src;
    for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3)
    {
      dst2[0] = src2[0];
      dst2[1] = src2[1];
      dst2[2] = src2[2];
      dst2[3] = 0xff;
    }
    src -= srcPitch;
    dst += dstPitch;
  }

  if(image.alpha)
  {
    dst = m_pixels + 3;
    src = image.alpha + (m_imageHeight - 1) * m_imageWidth;

    for (unsigned int y = 0; y < m_imageHeight; y++)
    {
      unsigned char *dst2 = dst;
      unsigned char *src2 = src;

      for (unsigned int x = 0; x < m_imageWidth; x++,  dst2+=4, src2++)
        *dst2 = *src2;
      src -= m_imageWidth;
      dst += dstPitch;
    }
  }
  dll.ReleaseImage(&image);

  ClampToEdge();

  return true;
}
Example #10
0
bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate)
{
#if defined(HAS_OMXPLAYER)
  if (URIUtils::GetExtension(texturePath).Equals(".jpg") || 
      URIUtils::GetExtension(texturePath).Equals(".tbn") 
      /*|| URIUtils::GetExtension(texturePath).Equals(".png")*/)
  {
    COMXImage omx_image;

    if(omx_image.ReadFile(texturePath))
    {
      // TODO: we only decode as half width and height. this is a workaround for the PI memory limitation
      if(omx_image.Decode(omx_image.GetWidth() / 2, omx_image.GetHeight() / 2))
      {
        Allocate(omx_image.GetDecodedWidth(), omx_image.GetDecodedHeight(), XB_FMT_A8R8G8B8);

        if(!m_pixels)
        {
          CLog::Log(LOGERROR, "Texture manager (OMX) out of memory");
          omx_image.Close();
          return false;
        }

        m_originalWidth  = omx_image.GetOriginalWidth();
        m_originalHeight = omx_image.GetOriginalHeight();

        m_hasAlpha = omx_image.IsAlpha();

        if (autoRotate && omx_image.GetOrientation())
          m_orientation = omx_image.GetOrientation() - 1;

        if(omx_image.GetDecodedData())
        {
          int size = ( ( GetPitch() * GetRows() ) > omx_image.GetDecodedSize() ) ?
                           omx_image.GetDecodedSize() : ( GetPitch() * GetRows() );

          memcpy(m_pixels, (unsigned char *)omx_image.GetDecodedData(), size);
        }

        omx_image.Close();

        return true;
      }
      else
      {
        omx_image.Close();
      }
    }
  }
#endif
  if (URIUtils::GetExtension(texturePath).Equals(".dds"))
  { // special case for DDS images
    CDDSImage image;
    if (image.ReadFile(texturePath))
    {
      Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false);
      return true;
    }
    return false;
  }

  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
  if (URIUtils::GetExtension(texturePath).Equals(".jpg") || URIUtils::GetExtension(texturePath).Equals(".tbn"))
  {
    CJpegIO jpegfile;
    if (jpegfile.Open(texturePath, maxWidth, maxHeight))
    {
      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
      {
        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
        {
          if (autoRotate && jpegfile.Orientation())
            m_orientation = jpegfile.Orientation() - 1;
          m_hasAlpha=false;
          ClampToEdge();
          return true;
        }
      }
    }
    CLog::Log(LOGDEBUG, "%s - Load of %s failed. Falling back to ImageLib", __FUNCTION__, texturePath.c_str());
  }

  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
    return false;
  }

  LoadFromImage(image, autoRotate);
  dll.ReleaseImage(&image);

  return true;
}
Example #11
0
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
                                bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight)
{
  if (URIUtils::GetExtension(texturePath).Equals(".dds"))
  { // special case for DDS images
    CDDSImage image;
    if (image.ReadFile(texturePath))
    {
      Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false);
      return true;
    }
    return false;
  }

  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
  if (URIUtils::GetExtension(texturePath).Equals(".jpg") || URIUtils::GetExtension(texturePath).Equals(".tbn"))
  {
    CJpegIO jpegfile;
    if (jpegfile.Open(texturePath, maxWidth, maxHeight))
    {
      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
      {
        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
        {
          if (autoRotate && jpegfile.Orientation())
            m_orientation = jpegfile.Orientation() - 1;
          m_hasAlpha=false;
          ClampToEdge();
          return true;
        }
      }
    }
    CLog::Log(LOGDEBUG, "%s - Load of %s failed. Falling back to ImageLib", __FUNCTION__, texturePath.c_str());
  }

  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
    return false;
  }

  if (originalWidth)
    *originalWidth = image.originalwidth;
  if (originalHeight)
    *originalHeight = image.originalheight;

  LoadFromImage(image, autoRotate);
  dll.ReleaseImage(&image);

  return true;
}
Example #12
0
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
                                bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight,
                                unsigned int dstWidth, unsigned int dstHeight)
{
  //Quick and dirty check if the file is DDS file...

  CFile file;
  if (!file.Open(texturePath))
  {  
    CLog::Log(LOGERROR, "%s - Error opening texture file: %s", __FUNCTION__, texturePath.c_str());
    return false;
  }

  // read the header
  uint32_t magic;
  if (file.Read(&magic, 4) != 4)
  {
    CLog::Log(LOGERROR, "%s - Can't read signature from file: %s", __FUNCTION__, texturePath.c_str());
    return false;
  }

  if (strncmp((const char *)&magic, "DDS ", 4) == 0 || CUtil::GetExtension(texturePath).Equals(".dds"))
  { // special case for DDS images
    CDDSImage image;
    CLog::Log(LOGDEBUG, "%s - loading dds file: %s", __FUNCTION__, texturePath.c_str());
    image.ReadFile(texturePath);
    Update(image.GetWidth(), image.GetHeight(), 0, image.GetFormat(), image.GetData(), false);
    return true;
  }

  DllImageLib dll;
  if (!dll.Load())
    return false;

  ImageInfo image;
  memset(&image, 0, sizeof(image));
  //image.width = dstWidth;
  //image.height = dstHeight;

  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();

  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  {
    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
    return false;
  }

  Allocate(image.width, image.height, XB_FMT_B8G8R8A8);
  if (autoRotate && image.exifInfo.Orientation)
    m_orientation = image.exifInfo.Orientation - 1;
  if (originalWidth)
    *originalWidth = image.originalwidth;
  if (originalHeight)
    *originalHeight = image.originalheight;

  unsigned int destPitch = GetPitch();
  unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes

  // test background color for alpha blending
  long  nBkgndIndex;
  RGBQUAD nBkgndColor;
  dll.GetBackgroundColor(&image, &nBkgndColor, &nBkgndIndex);

  for (unsigned int y = 0; y < m_imageHeight; y++)
  {
    unsigned char *dst = m_pixels + y * destPitch;
    unsigned char *src = image.texture + (m_imageHeight - 1 - y) * srcPitch;
    unsigned char *alpha = image.alpha + (m_imageHeight - 1 - y) * m_imageWidth;
    for (unsigned int x = 0; x < m_imageWidth; x++)
    {
      *dst++ = *src++;
      *dst++ = *src++;
      *dst++ = *src++;
      *dst++ = (image.alpha) ? *alpha++ : 0xff;
    }
  }

  if (nBkgndIndex != -1)
  {
    for (unsigned int y = 0; y < m_imageHeight; y++)
    {
      unsigned char *dst = m_pixels + y * destPitch;
      //unsigned char *src = image.texture + (m_imageHeight - 1 - y) * srcPitch;
      //unsigned char *alpha = image.alpha + (m_imageHeight - 1 - y) * m_imageWidth;
      for (unsigned int x = 0; x < m_imageWidth; x++)
      {
        if (*dst == nBkgndColor.rgbBlue
            && *(dst + 1) == nBkgndColor.rgbGreen
            && *(dst + 2) == nBkgndColor.rgbRed)
        {
          *(dst + 3) = 0x00;
        }
        dst += 4;
      }
    }
  }

  dll.ReleaseImage(&image);

  ClampToEdge();

  return true;
}