aboutsummaryrefslogtreecommitdiff
path: root/guilib/DDSImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'guilib/DDSImage.cpp')
-rw-r--r--guilib/DDSImage.cpp266
1 files changed, 0 insertions, 266 deletions
diff --git a/guilib/DDSImage.cpp b/guilib/DDSImage.cpp
deleted file mode 100644
index e909978735..0000000000
--- a/guilib/DDSImage.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * 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
- *
- */
-
-#include "DDSImage.h"
-#include "XBTF.h"
-#include "lib/libsquish/squish.h"
-#include "utils/log.h"
-#include <string.h>
-
-#ifndef NO_XBMC_FILESYSTEM
-#include "FileSystem/File.h"
-using namespace XFILE;
-#else
-#include "SimpleFS.h"
-#endif
-
-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;
-}
-
-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) != m_desc.linearSize)
- return false;
-
- file.Close();
- return true;
-}
-
-bool CDDSImage::Create(const std::string &outputFile, unsigned int width, unsigned int height, unsigned int pitch, unsigned char const *brga, double maxMSE)
-{
- if (!Compress(width, height, pitch, brga, maxMSE))
- { // use ARGB
- Allocate(width, height, XB_FMT_A8R8G8B8);
- for (unsigned int i = 0; i < height; i++)
- memcpy(m_data + i * width * 4, brga + i * pitch, min(width * 4, pitch));
- }
- return WriteFile(outputFile);
-}
-
-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;
- }
-}
-
-bool CDDSImage::Compress(unsigned int width, unsigned int height, unsigned int pitch, unsigned char const *brga, double maxMSE)
-{
- // first try DXT1, which is only 4bits/pixel
- Allocate(width, height, XB_FMT_DXT1);
-
- squish::CompressImage(brga, width, height, pitch, m_data, squish::kDxt1 | squish::kSourceBGRA);
- const char *fourCC = NULL;
-
- double colorMSE, alphaMSE;
- squish::ComputeMSE(brga, width, height, pitch, m_data, squish::kDxt1 | squish::kSourceBGRA, colorMSE, alphaMSE);
- if (!maxMSE || (colorMSE < maxMSE && alphaMSE < maxMSE))
- fourCC = "DXT1";
- else
- {
- if (alphaMSE == 0)
- { // no alpha channel, so DXT5YCoCg is going to be the best DXT5 format
- /* squish::CompressImage(brga, width, height, pitch, data2, squish::kDxt5 | squish::kSourceBGRA);
- squish::ComputeMSE(brga, width, height, pitch, m_data, squish::kDxt5 | squish::kSourceBGRA, colorMSE, alphaMSE);
- if (colorMSE < maxMSE && alphaMSE < maxMSE)
- { // success - use it
- compressedSize = squish::GetStorageRequirements(width, height, squish::kDxt5);
- format = XB_FMT_DXT5_YCoCg;
- }
- */
- }
- if (alphaMSE > 0)
- { // try DXT3 and DXT5 - use whichever is better (color is the same as DXT1, but alpha will be different)
- Allocate(width, height, XB_FMT_DXT3);
- squish::CompressImage(brga, width, height, pitch, m_data, squish::kDxt3 | squish::kSourceBGRA);
- squish::ComputeMSE(brga, width, height, pitch, m_data, squish::kDxt3 | squish::kSourceBGRA, colorMSE, alphaMSE);
- if (colorMSE < maxMSE)
- { // color is fine, test DXT5 as well
- double dxt5MSE;
- unsigned char *data2 = new unsigned char[GetStorageRequirements(width, height, XB_FMT_DXT5)];
- squish::CompressImage(brga, width, height, pitch, data2, squish::kDxt5 | squish::kSourceBGRA);
- squish::ComputeMSE(brga, width, height, pitch, data2, squish::kDxt5 | squish::kSourceBGRA, colorMSE, dxt5MSE);
- if (alphaMSE < maxMSE && alphaMSE < dxt5MSE)
- fourCC = "DXT3";
- else if (dxt5MSE < maxMSE)
- { // DXT5 passes
- fourCC = "DXT5";
- std::swap(m_data, data2);
- alphaMSE = dxt5MSE;
- }
- delete[] data2;
- }
- }
- }
- if (fourCC)
- {
- memcpy(&m_desc.pixelFormat.fourcc, fourCC, 4);
- CLog::Log(LOGDEBUG, "%s - using %s (min error is: %2.2f:%2.2f)", __FUNCTION__, fourCC, colorMSE, alphaMSE);
- return true;
- }
- CLog::Log(LOGDEBUG, "%s - no format suitable (min error is: %2.2f:%2.2f)", __FUNCTION__, colorMSE, alphaMSE);
- return false;
-}
-
-bool CDDSImage::Decompress(unsigned char *argb, unsigned int width, unsigned int height, unsigned int pitch, unsigned char const *dxt, unsigned int format)
-{
- if (!argb || !dxt || !(format & XB_FMT_DXT_MASK))
- return false;
-
- if (format == XB_FMT_DXT1)
- squish::DecompressImage(argb, width, height, pitch, dxt, squish::kDxt1 | squish::kSourceBGRA);
- else if (format == XB_FMT_DXT3)
- squish::DecompressImage(argb, width, height, pitch, dxt, squish::kDxt3 | squish::kSourceBGRA);
- else if (format == XB_FMT_DXT5)
- squish::DecompressImage(argb, width, height, pitch, dxt, squish::kDxt5 | squish::kSourceBGRA);
-
- return true;
-}
-
-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";
- }
-}