2012-08-28 02:49:00 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
2012-08-30 21:37:23 +00:00
|
|
|
#include <string.h>
|
2012-08-28 02:49:00 +00:00
|
|
|
|
2012-10-07 04:34:06 +00:00
|
|
|
#include "BlockStats.h"
|
2012-08-28 02:49:00 +00:00
|
|
|
#include "TexComp.h"
|
2012-09-21 16:39:09 +00:00
|
|
|
#include "ImageFile.h"
|
2012-09-21 20:42:15 +00:00
|
|
|
#include "Image.h"
|
2012-08-28 02:49:00 +00:00
|
|
|
|
2012-08-30 21:37:23 +00:00
|
|
|
void PrintUsage() {
|
2012-10-08 22:51:41 +00:00
|
|
|
fprintf(stderr, "Usage: tc [-l] [-q <quality>] [-n <num>] [-simd] [-t <threads> [-j <jobs>]] <imagefile>\n");
|
2012-08-30 21:37:23 +00:00
|
|
|
}
|
|
|
|
|
2012-10-21 18:07:46 +00:00
|
|
|
void ExtractBasename(const char *filename, char *buf, int bufSz) {
|
|
|
|
int len = strlen(filename);
|
|
|
|
const char *end = filename + len;
|
|
|
|
while(--end != filename) {
|
|
|
|
if(*end == '.')
|
|
|
|
{
|
|
|
|
int numChars = end - filename + 1;
|
|
|
|
int toCopy = (numChars > bufSz)? bufSz : numChars;
|
|
|
|
memcpy(buf, filename, toCopy);
|
|
|
|
buf[toCopy - 1] = '\0';
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-28 02:49:00 +00:00
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
2012-08-30 21:37:23 +00:00
|
|
|
int fileArg = 1;
|
2012-09-13 20:32:07 +00:00
|
|
|
if(fileArg == argc) {
|
|
|
|
PrintUsage();
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-08-30 21:37:23 +00:00
|
|
|
|
2012-09-21 22:43:35 +00:00
|
|
|
int numJobs = 0;
|
2012-08-30 21:37:23 +00:00
|
|
|
int quality = 50;
|
|
|
|
int numThreads = 1;
|
2012-09-15 14:29:36 +00:00
|
|
|
int numCompressions = 1;
|
2012-08-30 21:37:23 +00:00
|
|
|
bool bUseSIMD = false;
|
2012-10-08 22:51:41 +00:00
|
|
|
bool bSaveLog = false;
|
2012-08-30 21:37:23 +00:00
|
|
|
|
|
|
|
bool knowArg = false;
|
|
|
|
do {
|
|
|
|
knowArg = false;
|
2012-09-15 14:29:36 +00:00
|
|
|
|
|
|
|
if(strcmp(argv[fileArg], "-n") == 0) {
|
|
|
|
fileArg++;
|
|
|
|
|
|
|
|
if(fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) {
|
|
|
|
PrintUsage();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fileArg++;
|
|
|
|
knowArg = true;
|
2012-09-29 19:35:22 +00:00
|
|
|
continue;
|
2012-09-15 14:29:36 +00:00
|
|
|
}
|
2012-10-08 22:51:41 +00:00
|
|
|
|
|
|
|
if(strcmp(argv[fileArg], "-l") == 0) {
|
|
|
|
fileArg++;
|
|
|
|
bSaveLog = true;
|
|
|
|
knowArg = true;
|
|
|
|
continue;
|
|
|
|
}
|
2012-08-30 21:37:23 +00:00
|
|
|
|
2012-10-08 22:51:41 +00:00
|
|
|
if(strcmp(argv[fileArg], "-simd") == 0) {
|
2012-08-30 21:37:23 +00:00
|
|
|
fileArg++;
|
|
|
|
bUseSIMD = true;
|
|
|
|
knowArg = true;
|
2012-09-29 19:35:22 +00:00
|
|
|
continue;
|
2012-08-30 21:37:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(strcmp(argv[fileArg], "-t") == 0) {
|
|
|
|
fileArg++;
|
|
|
|
|
|
|
|
if(fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) {
|
|
|
|
PrintUsage();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fileArg++;
|
|
|
|
knowArg = true;
|
2012-09-29 19:35:22 +00:00
|
|
|
continue;
|
2012-08-30 21:37:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(strcmp(argv[fileArg], "-q") == 0) {
|
|
|
|
fileArg++;
|
|
|
|
|
2012-08-30 21:46:34 +00:00
|
|
|
if(fileArg == argc || (quality = atoi(argv[fileArg])) < 0) {
|
2012-08-30 21:37:23 +00:00
|
|
|
PrintUsage();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fileArg++;
|
|
|
|
knowArg = true;
|
2012-09-29 19:35:22 +00:00
|
|
|
continue;
|
2012-08-30 21:37:23 +00:00
|
|
|
}
|
|
|
|
|
2012-09-21 22:43:35 +00:00
|
|
|
if(strcmp(argv[fileArg], "-j") == 0) {
|
|
|
|
fileArg++;
|
|
|
|
|
|
|
|
if(fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) {
|
|
|
|
PrintUsage();
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fileArg++;
|
|
|
|
knowArg = true;
|
2012-09-29 19:35:22 +00:00
|
|
|
continue;
|
2012-09-21 22:43:35 +00:00
|
|
|
}
|
|
|
|
|
2012-09-29 19:35:22 +00:00
|
|
|
} while(knowArg && fileArg < argc);
|
2012-08-30 21:37:23 +00:00
|
|
|
|
|
|
|
if(fileArg == argc) {
|
|
|
|
PrintUsage();
|
2012-08-28 02:49:00 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-10-21 18:07:46 +00:00
|
|
|
char basename[256];
|
|
|
|
ExtractBasename(argv[fileArg], basename, 256);
|
|
|
|
|
2012-08-30 21:37:23 +00:00
|
|
|
ImageFile file (argv[fileArg]);
|
2012-10-20 20:54:43 +00:00
|
|
|
if(!file.Load()) {
|
2012-09-21 20:42:15 +00:00
|
|
|
fprintf(stderr, "Error loading file: %s\n", argv[fileArg]);
|
|
|
|
return 1;
|
2012-10-07 04:34:06 +00:00
|
|
|
}
|
|
|
|
|
2012-10-20 23:30:14 +00:00
|
|
|
const Image *img = file.GetImage();
|
|
|
|
|
2012-10-07 04:34:06 +00:00
|
|
|
int numBlocks = (img->GetWidth() * img->GetHeight())/16;
|
2012-10-08 22:51:41 +00:00
|
|
|
BlockStatManager *statManager = NULL;
|
|
|
|
if(bSaveLog) {
|
|
|
|
statManager = new BlockStatManager(numBlocks);
|
|
|
|
}
|
2012-08-28 02:49:00 +00:00
|
|
|
|
|
|
|
SCompressionSettings settings;
|
2012-08-30 21:37:23 +00:00
|
|
|
settings.bUseSIMD = bUseSIMD;
|
|
|
|
settings.iNumThreads = numThreads;
|
2012-08-30 21:46:34 +00:00
|
|
|
settings.iQuality = quality;
|
2012-09-15 14:29:36 +00:00
|
|
|
settings.iNumCompressions = numCompressions;
|
2012-09-21 22:43:35 +00:00
|
|
|
settings.iJobSize = numJobs;
|
2012-10-07 04:34:06 +00:00
|
|
|
settings.pStatManager = statManager;
|
2012-08-30 21:37:23 +00:00
|
|
|
|
2012-09-21 20:42:15 +00:00
|
|
|
CompressedImage *ci = img->Compress(settings);
|
2012-09-19 02:33:18 +00:00
|
|
|
if(NULL == ci) {
|
|
|
|
fprintf(stderr, "Error compressing image!\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2012-10-20 23:37:21 +00:00
|
|
|
|
2012-09-21 20:42:15 +00:00
|
|
|
double PSNR = img->ComputePSNR(*ci);
|
2012-09-18 23:00:20 +00:00
|
|
|
if(PSNR > 0.0) {
|
|
|
|
fprintf(stdout, "PSNR: %.3f\n", PSNR);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "Error computing PSNR\n");
|
|
|
|
}
|
|
|
|
|
2012-10-08 22:51:41 +00:00
|
|
|
if(bSaveLog) {
|
2012-10-21 18:07:46 +00:00
|
|
|
statManager->ToFile(strcat(basename, ".log"));
|
2012-10-08 22:51:41 +00:00
|
|
|
}
|
2012-10-07 04:34:06 +00:00
|
|
|
|
2012-10-20 23:37:21 +00:00
|
|
|
Image cImg (*ci);
|
2012-10-21 18:07:46 +00:00
|
|
|
ImageFile cImgFile (strcat(basename, "-bc7.png"), eFileFormat_PNG, cImg);
|
2012-10-20 23:37:21 +00:00
|
|
|
cImgFile.Write();
|
|
|
|
|
2012-08-28 02:49:00 +00:00
|
|
|
// Cleanup
|
2012-09-19 02:33:18 +00:00
|
|
|
delete ci;
|
2012-10-08 22:51:41 +00:00
|
|
|
if(statManager)
|
|
|
|
delete statManager;
|
2012-09-18 23:00:20 +00:00
|
|
|
|
2012-08-28 02:49:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|