Integrate decompressor tool improvements submitted by Amorilia.
This commit is contained in:
parent
299ad176fc
commit
4c759f999c
@ -730,6 +730,12 @@ bool DirectDrawSurface::isTextureCube() const
|
|||||||
return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
|
return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DirectDrawSurface::setNormalFlag(bool b)
|
||||||
|
{
|
||||||
|
nvDebugCheck(isValid());
|
||||||
|
header.setNormalFlag(b);
|
||||||
|
}
|
||||||
|
|
||||||
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
|
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
|
||||||
{
|
{
|
||||||
nvDebugCheck(isValid());
|
nvDebugCheck(isValid());
|
||||||
@ -780,7 +786,13 @@ void DirectDrawSurface::readLinearImage(Image * img)
|
|||||||
|
|
||||||
uint byteCount = (header.pf.bitcount + 7) / 8;
|
uint byteCount = (header.pf.bitcount + 7) / 8;
|
||||||
|
|
||||||
if (header.pf.amask != 0)
|
// set image format: RGB or ARGB
|
||||||
|
// alpha channel exists if and only if the alpha mask is non-zero
|
||||||
|
if (header.pf.amask == 0)
|
||||||
|
{
|
||||||
|
img->setFormat(Image::Format_RGB);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
img->setFormat(Image::Format_ARGB);
|
img->setFormat(Image::Format_ARGB);
|
||||||
}
|
}
|
||||||
@ -808,7 +820,20 @@ void DirectDrawSurface::readBlockImage(Image * img)
|
|||||||
{
|
{
|
||||||
nvDebugCheck(stream != NULL);
|
nvDebugCheck(stream != NULL);
|
||||||
nvDebugCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
|
// set image format: RGB or ARGB
|
||||||
|
if (header.pf.fourcc == FOURCC_RXGB ||
|
||||||
|
header.pf.fourcc == FOURCC_ATI1 ||
|
||||||
|
header.pf.fourcc == FOURCC_ATI2 ||
|
||||||
|
header.pf.flags & DDPF_NORMAL)
|
||||||
|
{
|
||||||
|
img->setFormat(Image::Format_RGB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
img->setFormat(Image::Format_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
const uint w = img->width();
|
const uint w = img->width();
|
||||||
const uint h = img->height();
|
const uint h = img->height();
|
||||||
|
|
||||||
|
@ -122,6 +122,8 @@ namespace nv
|
|||||||
bool isTexture2D() const;
|
bool isTexture2D() const;
|
||||||
bool isTexture3D() const;
|
bool isTexture3D() const;
|
||||||
bool isTextureCube() const;
|
bool isTextureCube() const;
|
||||||
|
|
||||||
|
void setNormalFlag(bool b);
|
||||||
|
|
||||||
void mipmap(Image * img, uint f, uint m);
|
void mipmap(Image * img, uint f, uint m);
|
||||||
// void mipmap(FloatImage * img, uint f, uint m);
|
// void mipmap(FloatImage * img, uint f, uint m);
|
||||||
|
@ -31,41 +31,145 @@
|
|||||||
|
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
|
|
||||||
|
#include <time.h> // clock
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
MyAssertHandler assertHandler;
|
MyAssertHandler assertHandler;
|
||||||
MyMessageHandler messageHandler;
|
MyMessageHandler messageHandler;
|
||||||
|
|
||||||
if (argc != 2)
|
bool forcenormal = false;
|
||||||
{
|
bool mipmaps = false;
|
||||||
printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");
|
bool faces = false;
|
||||||
printf("usage: nvdecompress 'ddsfile'\n\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
nv::Path input;
|
||||||
|
nv::Path output;
|
||||||
|
|
||||||
|
// Parse arguments.
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (strcmp("-forcenormal", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
forcenormal = true;
|
||||||
|
}
|
||||||
|
else if (strcmp("-mipmaps", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
mipmaps = true;
|
||||||
|
}
|
||||||
|
else if (strcmp("-faces", argv[i]) == 0)
|
||||||
|
{
|
||||||
|
faces = true;
|
||||||
|
}
|
||||||
|
else if (argv[i][0] != '-')
|
||||||
|
{
|
||||||
|
input = argv[i];
|
||||||
|
|
||||||
|
if (i+1 < argc && argv[i+1][0] != '-')
|
||||||
|
{
|
||||||
|
output = argv[i+1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.copy(input.str());
|
||||||
|
output.stripExtension();
|
||||||
|
output.append(".tga");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("NVIDIA Texture Tools - Copyright NVIDIA Corporation 2007\n\n");
|
||||||
|
|
||||||
|
if (input.isNull())
|
||||||
|
{
|
||||||
|
printf("usage: nvdecompress [options] infile [outfile]\n\n");
|
||||||
|
|
||||||
|
printf("Note: the .tga extension is forced on outfile\n\n");
|
||||||
|
|
||||||
|
printf("Input options:\n");
|
||||||
|
printf(" -forcenormal \tThe input image is a normal map.\n");
|
||||||
|
printf(" -mipmaps \tDecompress all mipmaps.\n");
|
||||||
|
printf(" -faces \tDecompress all faces.\n");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Load surface.
|
// Load surface.
|
||||||
nv::DirectDrawSurface dds(argv[1]);
|
nv::DirectDrawSurface dds(input);
|
||||||
if (!dds.isValid())
|
if (!dds.isValid())
|
||||||
{
|
{
|
||||||
printf("The file '%s' is not a valid DDS file.\n", argv[1]);
|
fprintf(stderr, "The file '%s' is not a valid DDS file.\n", input.str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nv::Path name(argv[1]);
|
|
||||||
name.stripExtension();
|
|
||||||
name.append(".tga");
|
|
||||||
|
|
||||||
nv::StdOutputStream stream(name.str());
|
|
||||||
if (stream.isError()) {
|
|
||||||
printf("Error opening '%s' for writting\n", name.str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @@ TODO: Add command line options to output mipmaps, cubemap faces, etc.
|
|
||||||
nv::Image img;
|
|
||||||
dds.mipmap(&img, 0, 0); // get first image
|
|
||||||
nv::ImageIO::saveTGA(stream, &img);
|
|
||||||
|
|
||||||
|
if (!dds.isSupported() || dds.isTexture3D())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "The file '%s' is not a supported DDS file.\n", input.str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint faceCount;
|
||||||
|
if (dds.isTexture2D())
|
||||||
|
{
|
||||||
|
faceCount = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nvCheck(dds.isTextureCube());
|
||||||
|
faceCount = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mipmapCount = dds.mipmapCount();
|
||||||
|
|
||||||
|
clock_t start = clock();
|
||||||
|
|
||||||
|
// apply arguments
|
||||||
|
if (forcenormal)
|
||||||
|
{
|
||||||
|
dds.setNormalFlag(true);
|
||||||
|
}
|
||||||
|
if (!faces)
|
||||||
|
{
|
||||||
|
faceCount = 1;
|
||||||
|
}
|
||||||
|
if (!mipmaps)
|
||||||
|
{
|
||||||
|
mipmapCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv::Image mipmap;
|
||||||
|
nv::Path name;
|
||||||
|
|
||||||
|
// strip extension, we force the tga extension
|
||||||
|
output.stripExtension();
|
||||||
|
|
||||||
|
// extract faces and mipmaps
|
||||||
|
for (uint f = 0; f < faceCount; f++)
|
||||||
|
{
|
||||||
|
for (uint m = 0; m < mipmapCount; m++)
|
||||||
|
{
|
||||||
|
dds.mipmap(&mipmap, f, m);
|
||||||
|
|
||||||
|
// set output filename, if we are doing faces and/or mipmaps
|
||||||
|
name.copy(output);
|
||||||
|
if (faces) name.appendFormat("_face%d", f);
|
||||||
|
if (mipmaps) name.appendFormat("_mipmap%d", m);
|
||||||
|
name.append(".tga");
|
||||||
|
|
||||||
|
nv::StdOutputStream stream(name.str());
|
||||||
|
if (stream.isError()) {
|
||||||
|
fprintf(stderr, "Error opening '%s' for writting\n", name.str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv::ImageIO::saveTGA(stream, &mipmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_t end = clock();
|
||||||
|
printf("\rtime taken: %.3f seconds\n", float(end-start) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user