summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/DDSImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/guilib/DDSImage.cpp')
-rw-r--r--xbmc/guilib/DDSImage.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/xbmc/guilib/DDSImage.cpp b/xbmc/guilib/DDSImage.cpp
new file mode 100644
index 0000000..124352d
--- /dev/null
+++ b/xbmc/guilib/DDSImage.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "DDSImage.h"
+
+#include "XBTF.h"
+#include "filesystem/File.h"
+#include "utils/log.h"
+
+#include <algorithm>
+#include <string.h>
+using namespace XFILE;
+
+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;
+}
+
+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;
+ 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))
+ return false;
+
+ // read the header
+ uint32_t magic;
+ if (file.Read(&magic, 4) != 4)
+ return false;
+ if (file.Read(&m_desc, sizeof(m_desc)) != sizeof(m_desc))
+ return false;
+ if (!GetFormat())
+ return false; // not supported
+
+ // allocate our data
+ m_data = new unsigned char[m_desc.linearSize];
+ if (!m_data)
+ return false;
+
+ // and read it in
+ if (file.Read(m_data, m_desc.linearSize) != static_cast<ssize_t>(m_desc.linearSize))
+ return false;
+
+ file.Close();
+ return true;
+}
+
+unsigned int CDDSImage::GetStorageRequirements(unsigned int width, unsigned int height, unsigned int format)
+{
+ 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)
+{
+ 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";
+ }
+}