示例#1
0
文件: Texture.cpp 项目: Kr0nZ/boxee
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;
}