mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2024-11-24 00:45:51 +01:00
Merge branch 'master' into DecompressASTC
This commit is contained in:
commit
168c6a0071
@ -111,13 +111,14 @@ void ExtractBasename(const char *filename, char *buf, size_t bufSz) {
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int fileArg = 1;
|
||||
if(fileArg == argc) {
|
||||
if (fileArg == argc) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char decompressedOutput[256]; decompressedOutput[0] = '\0';
|
||||
bool bNoDecompress = false;
|
||||
char decompressedOutput[256];
|
||||
decompressedOutput[0] = '\0';
|
||||
bool bDecompress = true;
|
||||
int numJobs = 0;
|
||||
int quality = 50;
|
||||
int numThreads = 1;
|
||||
@ -134,10 +135,10 @@ int main(int argc, char **argv) {
|
||||
do {
|
||||
knowArg = false;
|
||||
|
||||
if(strcmp(argv[fileArg], "-n") == 0) {
|
||||
if (strcmp(argv[fileArg], "-n") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) {
|
||||
if (fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
@ -147,26 +148,26 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-f") == 0) {
|
||||
if (strcmp(argv[fileArg], "-f") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc) {
|
||||
if (fileArg == argc) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
} else {
|
||||
if(!strcmp(argv[fileArg], "PVRTC")) {
|
||||
if (!strcmp(argv[fileArg], "PVRTC")) {
|
||||
format = FasTC::eCompressionFormat_PVRTC4;
|
||||
} else if(!strcmp(argv[fileArg], "PVRTCLib")) {
|
||||
} else if (!strcmp(argv[fileArg], "PVRTCLib")) {
|
||||
format = FasTC::eCompressionFormat_PVRTC4;
|
||||
bUsePVRTexLib = true;
|
||||
} else if(!strcmp(argv[fileArg], "BPTCLib")) {
|
||||
} else if (!strcmp(argv[fileArg], "BPTCLib")) {
|
||||
format = FasTC::eCompressionFormat_BPTC;
|
||||
bUseNVTT = true;
|
||||
} else if(!strcmp(argv[fileArg], "ETC1")) {
|
||||
} else if (!strcmp(argv[fileArg], "ETC1")) {
|
||||
format = FasTC::eCompressionFormat_ETC1;
|
||||
} else if(!strcmp(argv[fileArg], "DXT1")) {
|
||||
} else if (!strcmp(argv[fileArg], "DXT1")) {
|
||||
format = FasTC::eCompressionFormat_DXT1;
|
||||
} else if(!strcmp(argv[fileArg], "DXT5")) {
|
||||
} else if (!strcmp(argv[fileArg], "DXT5")) {
|
||||
format = FasTC::eCompressionFormat_DXT5;
|
||||
}
|
||||
}
|
||||
@ -176,10 +177,10 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-d") == 0) {
|
||||
if (strcmp(argv[fileArg], "-d") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc) {
|
||||
|
||||
if (fileArg == argc) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
} else {
|
||||
@ -193,38 +194,38 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-nd") == 0) {
|
||||
if (strcmp(argv[fileArg], "-nd") == 0) {
|
||||
fileArg++;
|
||||
bNoDecompress = true;
|
||||
bDecompress = false;
|
||||
knowArg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-l") == 0) {
|
||||
if (strcmp(argv[fileArg], "-l") == 0) {
|
||||
fileArg++;
|
||||
bSaveLog = true;
|
||||
knowArg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-v") == 0) {
|
||||
|
||||
if (strcmp(argv[fileArg], "-v") == 0) {
|
||||
fileArg++;
|
||||
bVerbose = true;
|
||||
knowArg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-simd") == 0) {
|
||||
|
||||
if (strcmp(argv[fileArg], "-simd") == 0) {
|
||||
fileArg++;
|
||||
bUseSIMD = true;
|
||||
knowArg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-t") == 0) {
|
||||
if (strcmp(argv[fileArg], "-t") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) {
|
||||
|
||||
if (fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
@ -234,10 +235,10 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-q") == 0) {
|
||||
if (strcmp(argv[fileArg], "-q") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc || (quality = atoi(argv[fileArg])) < 0) {
|
||||
|
||||
if (fileArg == argc || (quality = atoi(argv[fileArg])) < 0) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
@ -247,10 +248,10 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-j") == 0) {
|
||||
if (strcmp(argv[fileArg], "-j") == 0) {
|
||||
fileArg++;
|
||||
|
||||
if(fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) {
|
||||
|
||||
if (fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
@ -260,16 +261,16 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(strcmp(argv[fileArg], "-a") == 0) {
|
||||
if (strcmp(argv[fileArg], "-a") == 0) {
|
||||
fileArg++;
|
||||
bUseAtomics = true;
|
||||
knowArg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
} while(knowArg && fileArg < argc);
|
||||
} while (knowArg && fileArg < argc);
|
||||
|
||||
if(fileArg == argc) {
|
||||
if (fileArg == argc) {
|
||||
PrintUsage();
|
||||
exit(1);
|
||||
}
|
||||
@ -277,15 +278,14 @@ int main(int argc, char **argv) {
|
||||
char basename[256];
|
||||
ExtractBasename(argv[fileArg], basename, 256);
|
||||
|
||||
ImageFile file (argv[fileArg]);
|
||||
if(!file.Load()) {
|
||||
fprintf(stderr, "Error loading file: %s\n", argv[fileArg]);
|
||||
ImageFile file(argv[fileArg]);
|
||||
if (!file.Load()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FasTC::Image<> img(*file.GetImage());
|
||||
|
||||
if(bVerbose) {
|
||||
if (bVerbose) {
|
||||
fprintf(stdout, "Entropy: %.5f\n", img.ComputeEntropy());
|
||||
fprintf(stdout, "Mean Local Entropy: %.5f\n", img.ComputeMeanLocalEntropy());
|
||||
}
|
||||
@ -293,12 +293,12 @@ int main(int argc, char **argv) {
|
||||
std::ofstream logFile;
|
||||
ThreadSafeStreambuf streamBuf(logFile);
|
||||
std::ostream logStream(&streamBuf);
|
||||
if(bSaveLog) {
|
||||
if (bSaveLog) {
|
||||
char logname[256];
|
||||
sprintf(logname, "%s.log", basename);
|
||||
logFile.open(logname);
|
||||
}
|
||||
|
||||
|
||||
SCompressionSettings settings;
|
||||
settings.format = format;
|
||||
settings.bUseSIMD = bUseSIMD;
|
||||
@ -309,36 +309,40 @@ int main(int argc, char **argv) {
|
||||
settings.iJobSize = numJobs;
|
||||
settings.bUsePVRTexLib = bUsePVRTexLib;
|
||||
settings.bUseNVTT = bUseNVTT;
|
||||
if(bSaveLog) {
|
||||
if (bSaveLog) {
|
||||
settings.logStream = &logStream;
|
||||
} else {
|
||||
settings.logStream = NULL;
|
||||
}
|
||||
|
||||
CompressedImage *ci = CompressImage(&img, settings);
|
||||
if(NULL == ci) {
|
||||
fprintf(stderr, "Error compressing image!\n");
|
||||
if (NULL == ci) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
double PSNR = img.ComputePSNR(ci);
|
||||
if(PSNR > 0.0) {
|
||||
fprintf(stdout, "PSNR: %.3f\n", PSNR);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Error computing PSNR\n");
|
||||
}
|
||||
if (ci->GetWidth() != img.GetWidth() ||
|
||||
ci->GetHeight() != img.GetHeight()) {
|
||||
fprintf(stderr, "Cannot compute image metrics: compressed and uncompressed dimensions differ.\n");
|
||||
} else {
|
||||
double PSNR = img.ComputePSNR(ci);
|
||||
if(PSNR > 0.0) {
|
||||
fprintf(stdout, "PSNR: %.3f\n", PSNR);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Error computing PSNR\n");
|
||||
}
|
||||
|
||||
if(bVerbose) {
|
||||
double SSIM = img.ComputeSSIM(ci);
|
||||
if(SSIM > 0.0) {
|
||||
fprintf(stdout, "SSIM: %.9f\n", SSIM);
|
||||
} else {
|
||||
fprintf(stderr, "Error computing SSIM\n");
|
||||
if(bVerbose) {
|
||||
double SSIM = img.ComputeSSIM(ci);
|
||||
if(SSIM > 0.0) {
|
||||
fprintf(stdout, "SSIM: %.9f\n", SSIM);
|
||||
} else {
|
||||
fprintf(stderr, "Error computing SSIM\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!bNoDecompress) {
|
||||
if(bDecompress) {
|
||||
if(decompressedOutput[0] != '\0') {
|
||||
memcpy(basename, decompressedOutput, 256);
|
||||
} else if(format == FasTC::eCompressionFormat_BPTC) {
|
||||
|
@ -45,16 +45,16 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "ETCCompressor.h"
|
||||
#include "DXTCompressor.h"
|
||||
#include "BPTCCompressor.h"
|
||||
#include "CompressionFormat.h"
|
||||
#include "CompressionFuncs.h"
|
||||
#include "Image.h"
|
||||
#include "DXTCompressor.h"
|
||||
#include "ETCCompressor.h"
|
||||
#include "ImageFile.h"
|
||||
#include "Pixel.h"
|
||||
#include "PVRTCCompressor.h"
|
||||
@ -188,7 +188,10 @@ static double CompressImageInSerial(
|
||||
const SCompressionSettings &settings
|
||||
) {
|
||||
CompressionFunc f = ChooseFuncFromSettings(settings);
|
||||
CompressionFuncWithStats fStats = ChooseFuncFromSettingsWithStats(settings);
|
||||
CompressionFuncWithStats fStats = NULL;
|
||||
if (settings.logStream) {
|
||||
fStats = ChooseFuncFromSettingsWithStats(settings);
|
||||
}
|
||||
|
||||
double cmpTimeTotal = 0.0;
|
||||
|
||||
@ -392,30 +395,51 @@ CompressedImage *CompressImage(
|
||||
) {
|
||||
if(!img) return NULL;
|
||||
|
||||
const uint32 w = img->GetWidth();
|
||||
const uint32 h = img->GetHeight();
|
||||
uint32 width = img->GetWidth();
|
||||
uint32 height = img->GetHeight();
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
|
||||
// Make sure that the width and height of the image is a multiple of
|
||||
// the block size of the format
|
||||
uint32 blockDims[2];
|
||||
FasTC::GetBlockDimensions(settings.format, blockDims);
|
||||
if ((width % blockDims[0]) != 0 || (height % blockDims[1]) != 0) {
|
||||
ReportError("WARNING - Image size is not a multiple of block size. Padding with zeros...");
|
||||
uint32 newWidth = ((width + (blockDims[0] - 1)) / blockDims[0]) * blockDims[0];
|
||||
uint32 newHeight = ((height + (blockDims[1] - 1)) / blockDims[1]) * blockDims[1];
|
||||
|
||||
assert(newWidth > width || newHeight > height);
|
||||
assert(newWidth % blockDims[0] == 0);
|
||||
assert(newHeight % blockDims[1] == 0);
|
||||
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
}
|
||||
|
||||
uint32 dataSz = width * height * 4;
|
||||
uint32 *data = new uint32[dataSz / 4];
|
||||
memset(data, 0, dataSz);
|
||||
|
||||
CompressedImage *outImg = NULL;
|
||||
const unsigned int dataSz = w * h * 4;
|
||||
uint32 *data = new uint32[dataSz / 4];
|
||||
|
||||
assert(dataSz > 0);
|
||||
|
||||
// Allocate data based on the compression method
|
||||
uint32 cmpDataSz = CompressedImage::GetCompressedSize(dataSz, settings.format);
|
||||
|
||||
// Make sure that we have RGBA data...
|
||||
img->ComputePixels();
|
||||
const PixelType *pixels = img->GetPixels();
|
||||
for(uint32 i = 0; i < img->GetNumPixels(); i++) {
|
||||
data[i] = pixels[i].Pack();
|
||||
for(uint32 j = 0; j < img->GetHeight(); j++) {
|
||||
for(uint32 i = 0; i < img->GetWidth(); i++) {
|
||||
data[j * width + i] = (*img)(i, j).Pack();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *cmpData = new unsigned char[cmpDataSz];
|
||||
CompressImageData(reinterpret_cast<uint8 *>(data), w, h, cmpData, cmpDataSz, settings);
|
||||
uint8 *dataPtr = reinterpret_cast<uint8 *>(data);
|
||||
if (CompressImageData(dataPtr, width, height, cmpData, cmpDataSz, settings)) {
|
||||
outImg = new CompressedImage(width, height, settings.format, cmpData);
|
||||
}
|
||||
|
||||
outImg = new CompressedImage(w, h, settings.format, cmpData);
|
||||
|
||||
delete [] data;
|
||||
delete [] cmpData;
|
||||
return outImg;
|
||||
@ -433,7 +457,7 @@ bool CompressImageData(
|
||||
uint8 *compressedData,
|
||||
const uint32 cmpDataSz,
|
||||
const SCompressionSettings &settings
|
||||
) {
|
||||
) {
|
||||
|
||||
uint32 dataSz = width * height * 4;
|
||||
|
||||
@ -471,6 +495,19 @@ bool CompressImageData(
|
||||
}
|
||||
}
|
||||
|
||||
uint32 blockDims[2];
|
||||
FasTC::GetBlockDimensions(settings.format, blockDims);
|
||||
if ((width % blockDims[0]) != 0 || (height % blockDims[1]) != 0) {
|
||||
ReportError("ERROR - CompressImageData: width or height is not multiple of block dimension");
|
||||
return false;
|
||||
} else if (settings.format == FasTC::eCompressionFormat_PVRTC4 &&
|
||||
((width & (width - 1)) != 0 ||
|
||||
(height & (height - 1)) != 0 ||
|
||||
width != height)) {
|
||||
ReportError("ERROR - CompressImageData: PVRTC4 images must be square and power-of-two.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate data based on the compression method
|
||||
uint32 compressedDataSzNeeded =
|
||||
CompressedImage::GetCompressedSize(dataSz, settings.format);
|
||||
|
@ -85,8 +85,8 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 prec;
|
||||
const uint8 *data;
|
||||
uint32 prec = 0;
|
||||
const uint8 *data = NULL;
|
||||
|
||||
switch(ch) {
|
||||
case 0:
|
||||
@ -135,7 +135,7 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) {
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return static_cast<unsigned int>(ret);
|
||||
}
|
||||
else if(prec > 8) {
|
||||
const int32 toShift = prec - 8;
|
||||
@ -164,10 +164,10 @@ bool ImageLoader::LoadFromPixelBuffer(const uint32 *data, bool flipY) {
|
||||
if(flipY)
|
||||
idx = (m_Height - j - 1)*m_Height + i;
|
||||
uint32 pixel = data[idx];
|
||||
m_RedData[pIdx] = pixel & 0xFF;
|
||||
m_GreenData[pIdx] = (pixel >> 8) & 0xFF;
|
||||
m_BlueData[pIdx] = (pixel >> 16) & 0xFF;
|
||||
m_AlphaData[pIdx] = (pixel >> 24) & 0xFF;
|
||||
m_RedData[pIdx] = static_cast<uint8>(pixel & 0xFF);
|
||||
m_GreenData[pIdx] = static_cast<uint8>((pixel >> 8) & 0xFF);
|
||||
m_BlueData[pIdx] = static_cast<uint8>((pixel >> 16) & 0xFF);
|
||||
m_AlphaData[pIdx] = static_cast<uint8>((pixel >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,24 +189,13 @@ FasTC::Image<> *ImageLoader::LoadImage() {
|
||||
m_Width = GetWidth();
|
||||
m_Height = GetHeight();
|
||||
|
||||
// Populate buffer in block stream order... make
|
||||
// sure that width and height are aligned to multiples of four.
|
||||
const unsigned int aw = ((m_Width + 3) >> 2) << 2;
|
||||
const unsigned int ah = ((m_Height + 3) >> 2) << 2;
|
||||
|
||||
// Create RGBA buffer
|
||||
const unsigned int dataSz = 4 * aw * ah;
|
||||
const unsigned int dataSz = 4 * GetWidth() * GetHeight();
|
||||
m_PixelData = new unsigned char[dataSz];
|
||||
|
||||
#ifndef NDEBUG
|
||||
if(aw != m_Width || ah != m_Height)
|
||||
fprintf(stderr, "Warning: Image dimension not multiple of four. "
|
||||
"Space will be filled with black.\n");
|
||||
#endif
|
||||
|
||||
int byteIdx = 0;
|
||||
for(uint32 j = 0; j < ah; j++) {
|
||||
for(uint32 i = 0; i < aw; i++) {
|
||||
for(uint32 j = 0; j < GetHeight(); j++) {
|
||||
for(uint32 i = 0; i < GetWidth(); i++) {
|
||||
|
||||
unsigned int redVal = GetChannelForPixel(i, j, 0);
|
||||
if(redVal == INT_MAX) {
|
||||
@ -239,22 +228,19 @@ FasTC::Image<> *ImageLoader::LoadImage() {
|
||||
}
|
||||
|
||||
// Red channel
|
||||
m_PixelData[byteIdx++] = redVal & 0xFF;
|
||||
m_PixelData[byteIdx++] = static_cast<uint8>(redVal & 0xFF);
|
||||
|
||||
// Green channel
|
||||
m_PixelData[byteIdx++] = greenVal & 0xFF;
|
||||
m_PixelData[byteIdx++] = static_cast<uint8>(greenVal & 0xFF);
|
||||
|
||||
// Blue channel
|
||||
m_PixelData[byteIdx++] = blueVal & 0xFF;
|
||||
m_PixelData[byteIdx++] = static_cast<uint8>(blueVal & 0xFF);
|
||||
|
||||
// Alpha channel
|
||||
m_PixelData[byteIdx++] = alphaVal & 0xFF;
|
||||
m_PixelData[byteIdx++] = static_cast<uint8>(alphaVal & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
m_Width = aw;
|
||||
m_Height = ah;
|
||||
|
||||
uint32 *pixels = reinterpret_cast<uint32 *>(m_PixelData);
|
||||
return new FasTC::Image<>(m_Width, m_Height, pixels);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user