Index: guilib/guilib.vcproj
===================================================================
--- guilib/guilib.vcproj (revision 30756)
+++ guilib/guilib.vcproj (working copy)
@@ -675,6 +675,9 @@
RelativePath=".\VisibleEffect.h">
+
+
Index: xbmc.vcproj
===================================================================
--- xbmc.vcproj (revision 30756)
+++ xbmc.vcproj (working copy)
@@ -886,6 +886,12 @@
RelativePath=".\xbmc\DateTime.cpp">
+
+
+
+
+
+
+#include "FileSystem/File.h"
+using namespace XFILE;
+
+using namespace std;
+
+CDDSImage::CDDSImage()
+{
+ m_data = NULL;
+ memset(&m_desc, 0, sizeof(m_desc));
+}
+
+CDDSImage::CDDSImage(unsigned int width, unsigned int height, unsigned int format)
+{
+ m_data = NULL;
+ Allocate(width, height, format);
+}
+
+CDDSImage::~CDDSImage()
+{
+ delete[] m_data;
+}
+
+/*
+ If dds file is marked with our magic mark, read orgWidth and orgHeight, otherwise we read
+ normal width and height (file is a standard dds file and does not contain our modification.
+ See DDSImage.h for details.
+*/
+
+unsigned int CDDSImage::GetOrgWidth() const
+{
+ return (m_desc.xbmcMagic == DD_XBMC_MAGIC) ? m_desc.orgWidth : m_desc.width;
+}
+
+unsigned int CDDSImage::GetOrgHeight() const
+{
+ return (m_desc.xbmcMagic == DD_XBMC_MAGIC) ? m_desc.orgHeight : m_desc.height;
+}
+
+unsigned int CDDSImage::GetWidth() const
+{
+ return m_desc.width;
+}
+
+unsigned int CDDSImage::GetHeight() const
+{
+ return m_desc.height;
+}
+
+unsigned int CDDSImage::GetFormat() const
+{
+ if (m_desc.pixelFormat.flags & DDPF_RGB)
+ return 0; // Not supported
+ if (m_desc.pixelFormat.flags & DDPF_FOURCC)
+ {
+ if (strncmp((const char *)&m_desc.pixelFormat.fourcc, "DXT1", 4) == 0)
+ return XB_FMT_DXT1;
+ /*
+ //We are only supporting DXT1 at this time.
+
+ if (strncmp((const char *)&m_desc.pixelFormat.fourcc, "DXT3", 4) == 0)
+ return XB_FMT_DXT3;
+ if (strncmp((const char *)&m_desc.pixelFormat.fourcc, "DXT5", 4) == 0)
+ return XB_FMT_DXT5;
+ if (strncmp((const char *)&m_desc.pixelFormat.fourcc, "ARGB", 4) == 0)
+ return XB_FMT_A8R8G8B8;
+
+ */
+ }
+ return 0;
+}
+
+unsigned int CDDSImage::GetSize() const
+{
+ return m_desc.linearSize;
+}
+
+unsigned char *CDDSImage::GetData() const
+{
+ return m_data;
+}
+
+bool CDDSImage::ReadFile(const std::string &inputFile)
+{
+ // open the file
+ CFile file;
+ if (!file.Open(inputFile))
+ {
+ CLog::Log(LOGERROR, "%s - CFile.Open failed %s", __FUNCTION__, inputFile.c_str());
+ return false;
+ }
+
+ // read the header
+ uint32_t magic;
+ if (file.Read(&magic, 4) != 4)
+ {
+ CLog::Log(LOGERROR, "%s - Magic Header not found %s", __FUNCTION__, inputFile.c_str());
+ return false;
+ }
+ if (file.Read(&m_desc, sizeof(m_desc)) != sizeof(m_desc))
+ {
+ CLog::Log(LOGERROR, "%s - Description Invalid %s", __FUNCTION__, inputFile.c_str());
+ return false;
+ }
+ if (!GetFormat())
+ {
+ CLog::Log(LOGERROR, "%s - GetFormat returned false %s", __FUNCTION__, inputFile.c_str());
+ return false; // not supported
+ }
+
+ //This is temporary to make sure a "generic" .dds file is not read in at this point
+ //This can get removed once a proper routine is written to dynamically pad to POT (if deemed
+ //that such support is needed)
+ if (m_desc.xbmcMagic != DD_XBMC_MAGIC)
+ {
+ CLog::Log(LOGERROR, "%s - DDS file was not marked for xbmc use %s", __FUNCTION__, inputFile.c_str());
+ return false; // not supported
+ }
+
+ // allocate our data
+ m_data = new unsigned char[m_desc.linearSize];
+ if (!m_data)
+ {
+ CLog::Log(LOGERROR, "%s - No Data %s", __FUNCTION__, inputFile.c_str());
+ return false;
+ }
+
+ // and read it in
+ if (file.Read(m_data, m_desc.linearSize) != m_desc.linearSize)
+ {
+ CLog::Log(LOGERROR, "%s - Data doesn't match header size %s", __FUNCTION__, inputFile.c_str());
+ return false;
+ }
+
+ file.Close();
+ return true;
+}
+
+bool CDDSImage::WriteFile(const std::string &outputFile) const
+{
+ // open the file
+ CFile file;
+ if (!file.OpenForWrite(outputFile, true))
+ return false;
+
+ // write the header
+ file.Write("DDS ", 4);
+ file.Write(&m_desc, sizeof(m_desc));
+ // now the data
+ file.Write(m_data, m_desc.linearSize);
+ file.Close();
+ return true;
+}
+
+unsigned int CDDSImage::GetStorageRequirements(unsigned int width, unsigned int height, unsigned int format) const
+{
+ switch (format)
+ {
+ case XB_FMT_DXT1:
+ return ((width + 3) / 4) * ((height + 3) / 4) * 8;
+ case XB_FMT_DXT3:
+ case XB_FMT_DXT5:
+ return ((width + 3) / 4) * ((height + 3) / 4) * 16;
+ case XB_FMT_A8R8G8B8:
+ default:
+ return width * height * 4;
+ }
+}
+
+void CDDSImage::Allocate(unsigned int width, unsigned int height, unsigned int format)
+{
+ memset(&m_desc, 0, sizeof(m_desc));
+ m_desc.size = sizeof(m_desc);
+ m_desc.flags = ddsd_caps | ddsd_pixelformat | ddsd_width | ddsd_height | ddsd_linearsize;
+ m_desc.height = height;
+ m_desc.width = width;
+ m_desc.linearSize = GetStorageRequirements(width, height, format);
+ m_desc.pixelFormat.size = sizeof(m_desc.pixelFormat);
+ m_desc.pixelFormat.flags = ddpf_fourcc;
+ memcpy(&m_desc.pixelFormat.fourcc, GetFourCC(format), 4);
+ m_desc.caps.flags1 = ddscaps_texture;
+ delete[] m_data;
+ m_data = new unsigned char[m_desc.linearSize];
+}
+
+const char *CDDSImage::GetFourCC(unsigned int format) const
+{
+ switch (format)
+ {
+ case XB_FMT_DXT1:
+ return "DXT1";
+ case XB_FMT_DXT3:
+ return "DXT3";
+ case XB_FMT_DXT5:
+ return "DXT5";
+ case XB_FMT_A8R8G8B8:
+ default:
+ return "ARGB";
+ }
+}
Index: xbmc/DDSImage.h
===================================================================
--- xbmc/DDSImage.h (revision 0)
+++ xbmc/DDSImage.h (revision 0)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include
+#include
+
+class CDDSImage
+{
+public:
+ CDDSImage();
+ CDDSImage(unsigned int width, unsigned int height, unsigned int format);
+ ~CDDSImage();
+
+ unsigned int GetOrgWidth() const;
+ unsigned int GetOrgHeight() const;
+ unsigned int GetWidth() const;
+ unsigned int GetHeight() const;
+ unsigned int GetFormat() const;
+ unsigned int GetSize() const;
+ unsigned char *GetData() const;
+
+ bool ReadFile(const std::string &file);
+
+private:
+ void Allocate(unsigned int width, unsigned int height, unsigned int format);
+ const char *GetFourCC(unsigned int format) const;
+ bool WriteFile(const std::string &file) const;
+ unsigned int GetStorageRequirements(unsigned int width, unsigned int height, unsigned int format) const;
+ enum {
+ ddsd_caps = 0x00000001,
+ ddsd_height = 0x00000002,
+ ddsd_width = 0x00000004,
+ ddsd_pitch = 0x00000008,
+ ddsd_pixelformat = 0x00001000,
+ ddsd_mipmapcount = 0x00020000,
+ ddsd_linearsize = 0x00080000,
+ ddsd_depth = 0x00800000
+ };
+
+ enum {
+ ddpf_alphapixels = 0x00000001,
+ ddpf_fourcc = 0x00000004,
+ ddpf_rgb = 0x00000040
+ };
+
+ enum {
+ ddscaps_complex = 0x00000008,
+ ddscaps_texture = 0x00001000,
+ ddscaps_mipmap = 0x00400000
+ };
+
+ #pragma pack(push, 2)
+ typedef struct
+ {
+ uint32_t size;
+ uint32_t flags;
+ uint32_t fourcc;
+ uint32_t rgbBitCount;
+ uint32_t rBitMask;
+ uint32_t gBitMask;
+ uint32_t bBitMask;
+ uint32_t aBitMask;
+ } ddpixelformat;
+
+#define DDPF_ALPHAPIXELS 0x00000001
+#define DDPF_ALPHA 0x00000002
+#define DDPF_FOURCC 0x00000004
+#define DDPF_RGB 0x00000040
+#define DDPF_YUV 0x00000200
+#define DDPF_LUMINANCE 0x00020000
+
+//XBMC Magic Mark 0x434D4258 = 'XBMC'
+#define DD_XBMC_MAGIC 0x434D4258
+
+ typedef struct
+ {
+ uint32_t flags1;
+ uint32_t flags2;
+ uint32_t reserved[2];
+ } ddcaps2;
+
+ typedef struct
+ {
+ uint32_t size;
+ uint32_t flags;
+ uint32_t height;
+ uint32_t width;
+ uint32_t linearSize;
+ uint32_t depth;
+ uint32_t mipmapcount;
+ /*
+ DDS FILE FORMAT MODIFICATION FOR PRE-PADDED TEXTURES
+
+ Original reserved area:
+ uint32_t reserved[11];
+
+ This modification uses the last 3 dwords of space in the 1st reserved area to store
+ the actual size of the image data (as opposed to the texture size). The DDS file
+ format was not designed to be used pre-padded - this modification was necessary
+ in order to support it. Having the textures pre-padded on disk saves quite a bit of
+ work, since otherwise we would have to manually pad the texture to POT procedurally
+ and then clamp the edges off - this allows us to avoid that. See GetOrgWidth() and
+ GetOrgHeight() in DDSImage.cpp
+ */
+ uint32_t reserved[8];
+ uint32_t xbmcMagic;
+ uint32_t orgWidth;
+ uint32_t orgHeight;
+ /*
+ END DDS FILE FORMAT MODIFICATION
+ */
+ ddpixelformat pixelFormat;
+ ddcaps2 caps;
+ uint32_t reserved2;
+ } ddsurfacedesc2;
+ #pragma pack(pop)
+
+ ddsurfacedesc2 m_desc;
+ unsigned char *m_data;
+};
Index: xbmc/Picture.cpp
===================================================================
--- xbmc/Picture.cpp (revision 30756)
+++ xbmc/Picture.cpp (working copy)
@@ -27,8 +27,11 @@
#include "FileItem.h"
#include "FileSystem/File.h"
#include "FileSystem/FileCurl.h"
+#include "DDSImage.h"
#include "Util.h"
#include "Crc32.h"
+#include
+#include "d3dx8.h"
using namespace XFILE;
@@ -44,6 +47,58 @@
IDirect3DTexture8* CPicture::Load(const CStdString& strFileName, int iMaxWidth, int iMaxHeight)
{
+ /*
+ DDS files are not yet generated by xbmc. This setting simply enables support required
+ to render them properly. They must be created offline currently. We are currently only
+ supporting DXT1 format with no mipmaps that are generated by a utility that marks them
+ correctly for use by xbmc. These DDS files are pre-padded to POT to simplify/speedup
+ handling.
+ */
+ if (g_advancedSettings.m_useddsfanart)
+ {
+ //If a .dds version of the image exists we load it instead.
+ CStdString ddsPath = CUtil::ReplaceExtension(strFileName, ".dds");
+ if (CFile::Exists(ddsPath))
+ {
+ CDDSImage img;
+ if (img.ReadFile(ddsPath))
+ {
+ memset(&m_info, 0, sizeof(ImageInfo));
+ /*
+ GetOrgWidth() and GetOrgHeight() return the actual size of the image stored in the dds file,
+ as opposed to the texture size (which is always POT)
+ */
+ m_info.originalwidth = m_info.width = img.GetOrgWidth();
+ m_info.originalheight = m_info.height = img.GetOrgHeight();
+ LPDIRECT3DTEXTURE8 pTexture = NULL;
+ //Texture is created using GetWidth and GetHeight, which return texture size (always POT)
+ g_graphicsContext.Get3DDevice()->CreateTexture(img.GetWidth(), img.GetHeight(), 1, 0, D3DFMT_DXT1 , D3DPOOL_MANAGED, &pTexture);
+ if (pTexture)
+ {
+ D3DLOCKED_RECT lr;
+ if ( D3D_OK == pTexture->LockRect( 0, &lr, NULL, 0 ))
+ {
+ BYTE *pixels = (BYTE *)lr.pBits;
+ //DDS Textures are always POT and don't need decoding, just memcpy into the texture.
+ memcpy(pixels, img.GetData(), img.GetSize());
+ pTexture->UnlockRect( 0 );
+ }
+ return pTexture;
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "%s - failed to create texture from dds image %s", __FUNCTION__, ddsPath.c_str());
+ //fall through to default image loading code
+ }
+ }
+ else
+ {
+ CLog::Log(LOGERROR, "%s - could not read dds image %s", __FUNCTION__, ddsPath.c_str());
+ //fall through to default image loading code
+ }
+ }
+ }
+
if (!m_dll.Load()) return NULL;
memset(&m_info, 0, sizeof(ImageInfo));
@@ -83,6 +138,7 @@
CLog::Log(LOGERROR, "%s - failed to create texture while loading image %s", __FUNCTION__, strFileName.c_str());
m_dll.ReleaseImage(&m_info);
return pTexture;
+
}
bool CPicture::CreateThumbnail(const CStdString& file, const CStdString& thumbFile, bool checkExistence /*= false*/)
Index: xbmc/XBTF.h
===================================================================
--- xbmc/XBTF.h (revision 0)
+++ xbmc/XBTF.h (revision 0)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2005-2009 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#ifndef XBTF_H_
+#define XBTF_H_
+
+#include
+#include
+#include
+
+#define XBTF_MAGIC "XBTF"
+#define XBTF_VERSION "2"
+
+#define XB_FMT_DXT_MASK 15
+#define XB_FMT_UNKNOWN 0
+#define XB_FMT_DXT1 1
+#define XB_FMT_DXT3 2
+#define XB_FMT_DXT5 4
+#define XB_FMT_DXT5_YCoCg 8
+#define XB_FMT_A8R8G8B8 16
+#define XB_FMT_A8 32
+
+class CXBTFFrame
+{
+public:
+ CXBTFFrame();
+ uint32_t GetWidth() const;
+ void SetWidth(uint32_t width);
+ uint32_t GetFormat() const;
+ void SetFormat(uint32_t format);
+ uint32_t GetHeight() const;
+ void SetHeight(uint32_t height);
+ uint64_t GetUnpackedSize() const;
+ void SetUnpackedSize(uint64_t size);
+ uint64_t GetPackedSize() const;
+ void SetPackedSize(uint64_t size);
+ uint64_t GetOffset() const;
+ void SetOffset(uint64_t offset);
+ uint64_t GetHeaderSize() const;
+ uint32_t GetDuration() const;
+ void SetDuration(uint32_t duration);
+ bool IsPacked() const;
+
+private:
+ uint32_t m_width;
+ uint32_t m_height;
+ uint32_t m_format;
+ uint64_t m_packedSize;
+ uint64_t m_unpackedSize;
+ uint64_t m_offset;
+ uint32_t m_duration;
+};
+
+class CXBTFFile
+{
+public:
+ CXBTFFile();
+ CXBTFFile(const CXBTFFile& ref);
+ char* GetPath();
+ void SetPath(const std::string& path);
+ uint32_t GetLoop() const;
+ void SetLoop(uint32_t loop);
+ std::vector& GetFrames();
+ uint64_t GetHeaderSize() const;
+
+private:
+ char m_path[256];
+ uint32_t m_loop;
+ std::vector m_frames;
+};
+
+class CXBTF
+{
+public:
+ CXBTF();
+ uint64_t GetHeaderSize() const;
+ std::vector& GetFiles();
+
+private:
+ std::vector m_files;
+};
+
+#endif