diff options
Diffstat (limited to 'guilib/DDSImage.cpp')
-rw-r--r-- | guilib/DDSImage.cpp | 266 |
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"; - } -} |