/*
* Copyright (C) 2005-2013 Team XBMC
* http://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, see
* .
*
*/
#include
#include
#include
#include
#include
#include "cmdlineargs.h"
#ifdef TARGET_WINDOWS
#define strncasecmp strnicmp
#endif
#include "DDSImage.h"
#include "XBTF.h"
#undef main
const char *GetFormatString(unsigned int format)
{
switch (format)
{
case squish::kDxt1:
return "DXT1 ";
case squish::kDxt5:
return "YCoCg";
default:
return "?????";
}
}
void CompressImage(const squish::u8 *brga, int width, int height, squish::u8 *compressed, unsigned int flags, double &colorMSE, double &alphaMSE)
{
squish::CompressImage(brga, width, height, compressed, flags | squish::kSourceBGRA);
squish::ComputeMSE(brga, width, height, compressed, flags | squish::kSourceBGRA, colorMSE, alphaMSE);
}
void CompressToDDS(SDL_Surface* image, unsigned int format, CDDSImage &out)
{
// Convert to ARGB
SDL_PixelFormat argbFormat;
memset(&argbFormat, 0, sizeof(SDL_PixelFormat));
argbFormat.BitsPerPixel = 32;
argbFormat.BytesPerPixel = 4;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
argbFormat.Amask = 0xff000000;
argbFormat.Ashift = 24;
argbFormat.Rmask = 0x00ff0000;
argbFormat.Rshift = 16;
argbFormat.Gmask = 0x0000ff00;
argbFormat.Gshift = 8;
argbFormat.Bmask = 0x000000ff;
argbFormat.Bshift = 0;
#else
argbFormat.Amask = 0x000000ff;
argbFormat.Ashift = 0;
argbFormat.Rmask = 0x0000ff00;
argbFormat.Rshift = 8;
argbFormat.Gmask = 0x00ff0000;
argbFormat.Gshift = 16;
argbFormat.Bmask = 0xff000000;
argbFormat.Bshift = 24;
#endif
SDL_Surface *argbImage = SDL_ConvertSurface(image, &argbFormat, 0);
double colorMSE, alphaMSE;
if (format == XB_FMT_DXT1)
CompressImage((squish::u8 *)argbImage->pixels, image->w, image->h, out.GetData(), squish::kDxt1, colorMSE, alphaMSE);
else if (format == XB_FMT_DXT5)
CompressImage((squish::u8 *)argbImage->pixels, image->w, image->h, out.GetData(), squish::kDxt5, colorMSE, alphaMSE);
// print some info about the resulting image
printf("Size: %dx%d %s in %u bytes. Quality: %5.2f\n", image->w, image->h, GetFormatString(format), out.GetSize(), colorMSE);
SDL_FreeSurface(argbImage);
}
void Usage()
{
puts("Usage: MakeDDS [-oN] input [output]");
puts(" -o1 for DXT1");
puts(" -o5 for DXT5");
}
void createDDS(const std::string& inputFile, const std::string& outputFile, unsigned int format)
{
// Load the image
SDL_Surface* image = IMG_Load(inputFile.c_str());
if (!image)
{
printf("...unable to load image %s\n", inputFile.c_str());
return;
}
CDDSImage dds(image->w, image->h, format);
CompressToDDS(image, format, dds);
// write to a DDS file
dds.WriteFile(outputFile);
SDL_FreeSurface(image);
}
int main(int argc, char* argv[])
{
bool valid = false;
CmdLineArgs args(argc, (const char**)argv);
if (args.size() == 1)
{
Usage();
return 1;
}
std::string inputFile;
std::string outputFile;
unsigned int format = squish::kDxt1;
for (unsigned int i = 1; i < args.size(); ++i)
{
if (!stricmp(args[i], "--help") || !stricmp(args[i], "-?") || !stricmp(args[i], "?"))
{
Usage();
return 1;
}
else if (!strncasecmp(args[i], "-o1", 3))
format = XB_FMT_DXT1;
else if (!strncasecmp(args[i], "-o5", 3))
format = XB_FMT_DXT5;
else if (!inputFile.size())
{
inputFile = args[i];
valid = true;
}
else if (!outputFile.size())
{
outputFile = args[i];
valid = true;
}
else
{
printf("Unrecognized command line flag: %s\n", args[i]);
}
}
if (outputFile.empty())
{ // construct output file from input - rename to .dds
size_t pos = inputFile.find_last_of('.');
if (pos != std::string::npos)
{
outputFile = inputFile.substr(0, pos);
outputFile += ".dds";
}
}
if (!valid)
{
Usage();
return 1;
}
createDDS(inputFile, outputFile, format);
}