2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include <sys/types.h>
25 #include <SDL/SDL_image.h>
26 #include "cmdlineargs.h"
28 #define strncasecmp strnicmp
35 const char *GetFormatString(unsigned int format)
48 void CompressImage(const squish::u8 *brga, int width, int height, squish::u8 *compressed, unsigned int flags, double &colorMSE, double &alphaMSE)
50 squish::CompressImage(brga, width, height, compressed, flags | squish::kSourceBGRA);
51 squish::ComputeMSE(brga, width, height, compressed, flags | squish::kSourceBGRA, colorMSE, alphaMSE);
54 void CompressToDDS(SDL_Surface* image, unsigned int format, CDDSImage &out)
57 SDL_PixelFormat argbFormat;
58 memset(&argbFormat, 0, sizeof(SDL_PixelFormat));
59 argbFormat.BitsPerPixel = 32;
60 argbFormat.BytesPerPixel = 4;
62 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
63 argbFormat.Amask = 0xff000000;
64 argbFormat.Ashift = 24;
65 argbFormat.Rmask = 0x00ff0000;
66 argbFormat.Rshift = 16;
67 argbFormat.Gmask = 0x0000ff00;
68 argbFormat.Gshift = 8;
69 argbFormat.Bmask = 0x000000ff;
70 argbFormat.Bshift = 0;
72 argbFormat.Amask = 0x000000ff;
73 argbFormat.Ashift = 0;
74 argbFormat.Rmask = 0x0000ff00;
75 argbFormat.Rshift = 8;
76 argbFormat.Gmask = 0x00ff0000;
77 argbFormat.Gshift = 16;
78 argbFormat.Bmask = 0xff000000;
79 argbFormat.Bshift = 24;
82 SDL_Surface *argbImage = SDL_ConvertSurface(image, &argbFormat, 0);
84 double colorMSE, alphaMSE;
85 if (format == XB_FMT_DXT1)
86 CompressImage((squish::u8 *)argbImage->pixels, image->w, image->h, out.GetData(), squish::kDxt1, colorMSE, alphaMSE);
87 else if (format == XB_FMT_DXT5)
88 CompressImage((squish::u8 *)argbImage->pixels, image->w, image->h, out.GetData(), squish::kDxt5, colorMSE, alphaMSE);
90 // print some info about the resulting image
91 printf("Size: %dx%d %s in %u bytes. Quality: %5.2f\n", image->w, image->h, GetFormatString(format), out.GetSize(), colorMSE);
93 SDL_FreeSurface(argbImage);
98 puts("Usage: MakeDDS [-oN] input [output]");
99 puts(" -o1 for DXT1");
100 puts(" -o5 for DXT5");
103 void createDDS(const std::string& inputFile, const std::string& outputFile, unsigned int format)
106 SDL_Surface* image = IMG_Load(inputFile.c_str());
109 printf("...unable to load image %s\n", inputFile.c_str());
113 CDDSImage dds(image->w, image->h, format);
114 CompressToDDS(image, format, dds);
116 // write to a DDS file
117 dds.WriteFile(outputFile);
119 SDL_FreeSurface(image);
122 int main(int argc, char* argv[])
125 CmdLineArgs args(argc, (const char**)argv);
127 if (args.size() == 1)
133 std::string inputFile;
134 std::string outputFile;
136 unsigned int format = squish::kDxt1;
137 for (unsigned int i = 1; i < args.size(); ++i)
139 if (!stricmp(args[i], "--help") || !stricmp(args[i], "-?") || !stricmp(args[i], "?"))
144 else if (!strncasecmp(args[i], "-o1", 3))
145 format = XB_FMT_DXT1;
146 else if (!strncasecmp(args[i], "-o5", 3))
147 format = XB_FMT_DXT5;
148 else if (!inputFile.size())
153 else if (!outputFile.size())
155 outputFile = args[i];
160 printf("Unrecognized command line flag: %s\n", args[i]);
164 if (outputFile.empty())
165 { // construct output file from input - rename to .dds
166 size_t pos = inputFile.find_last_of('.');
167 if (pos != std::string::npos)
169 outputFile = inputFile.substr(0, pos);
170 outputFile += ".dds";
180 createDDS(inputFile, outputFile, format);