Merge branch 'master' into DecompressASTC

This commit is contained in:
Pavel Krajcevski 2014-11-03 18:28:44 -05:00
commit 168c6a0071
3 changed files with 131 additions and 104 deletions

View File

@ -116,8 +116,9 @@ int main(int argc, char **argv) {
exit(1); exit(1);
} }
char decompressedOutput[256]; decompressedOutput[0] = '\0'; char decompressedOutput[256];
bool bNoDecompress = false; decompressedOutput[0] = '\0';
bool bDecompress = true;
int numJobs = 0; int numJobs = 0;
int quality = 50; int quality = 50;
int numThreads = 1; int numThreads = 1;
@ -195,7 +196,7 @@ int main(int argc, char **argv) {
if (strcmp(argv[fileArg], "-nd") == 0) { if (strcmp(argv[fileArg], "-nd") == 0) {
fileArg++; fileArg++;
bNoDecompress = true; bDecompress = false;
knowArg = true; knowArg = true;
continue; continue;
} }
@ -279,7 +280,6 @@ int main(int argc, char **argv) {
ImageFile file(argv[fileArg]); ImageFile file(argv[fileArg]);
if (!file.Load()) { if (!file.Load()) {
fprintf(stderr, "Error loading file: %s\n", argv[fileArg]);
return 1; return 1;
} }
@ -317,10 +317,13 @@ int main(int argc, char **argv) {
CompressedImage *ci = CompressImage(&img, settings); CompressedImage *ci = CompressImage(&img, settings);
if (NULL == ci) { if (NULL == ci) {
fprintf(stderr, "Error compressing image!\n");
return 1; return 1;
} }
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); double PSNR = img.ComputePSNR(ci);
if(PSNR > 0.0) { if(PSNR > 0.0) {
fprintf(stdout, "PSNR: %.3f\n", PSNR); fprintf(stdout, "PSNR: %.3f\n", PSNR);
@ -337,8 +340,9 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error computing SSIM\n"); fprintf(stderr, "Error computing SSIM\n");
} }
} }
}
if(!bNoDecompress) { if(bDecompress) {
if(decompressedOutput[0] != '\0') { if(decompressedOutput[0] != '\0') {
memcpy(basename, decompressedOutput, 256); memcpy(basename, decompressedOutput, 256);
} else if(format == FasTC::eCompressionFormat_BPTC) { } else if(format == FasTC::eCompressionFormat_BPTC) {

View File

@ -45,16 +45,16 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <cstdlib>
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <string.h>
#include "ETCCompressor.h"
#include "DXTCompressor.h"
#include "BPTCCompressor.h" #include "BPTCCompressor.h"
#include "CompressionFormat.h"
#include "CompressionFuncs.h" #include "CompressionFuncs.h"
#include "Image.h" #include "DXTCompressor.h"
#include "ETCCompressor.h"
#include "ImageFile.h" #include "ImageFile.h"
#include "Pixel.h" #include "Pixel.h"
#include "PVRTCCompressor.h" #include "PVRTCCompressor.h"
@ -188,7 +188,10 @@ static double CompressImageInSerial(
const SCompressionSettings &settings const SCompressionSettings &settings
) { ) {
CompressionFunc f = ChooseFuncFromSettings(settings); CompressionFunc f = ChooseFuncFromSettings(settings);
CompressionFuncWithStats fStats = ChooseFuncFromSettingsWithStats(settings); CompressionFuncWithStats fStats = NULL;
if (settings.logStream) {
fStats = ChooseFuncFromSettingsWithStats(settings);
}
double cmpTimeTotal = 0.0; double cmpTimeTotal = 0.0;
@ -392,29 +395,50 @@ CompressedImage *CompressImage(
) { ) {
if(!img) return NULL; if(!img) return NULL;
const uint32 w = img->GetWidth(); uint32 width = img->GetWidth();
const uint32 h = img->GetHeight(); 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; 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 // Allocate data based on the compression method
uint32 cmpDataSz = CompressedImage::GetCompressedSize(dataSz, settings.format); uint32 cmpDataSz = CompressedImage::GetCompressedSize(dataSz, settings.format);
// Make sure that we have RGBA data... // Make sure that we have RGBA data...
img->ComputePixels(); img->ComputePixels();
const PixelType *pixels = img->GetPixels(); for(uint32 j = 0; j < img->GetHeight(); j++) {
for(uint32 i = 0; i < img->GetNumPixels(); i++) { for(uint32 i = 0; i < img->GetWidth(); i++) {
data[i] = pixels[i].Pack(); data[j * width + i] = (*img)(i, j).Pack();
}
} }
unsigned char *cmpData = new unsigned char[cmpDataSz]; 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(w, h, settings.format, cmpData); outImg = new CompressedImage(width, height, settings.format, cmpData);
}
delete [] data; delete [] data;
delete [] cmpData; delete [] cmpData;
@ -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 // Allocate data based on the compression method
uint32 compressedDataSzNeeded = uint32 compressedDataSzNeeded =
CompressedImage::GetCompressedSize(dataSz, settings.format); CompressedImage::GetCompressedSize(dataSz, settings.format);

View File

@ -85,8 +85,8 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) {
return 0; return 0;
} }
uint32 prec; uint32 prec = 0;
const uint8 *data; const uint8 *data = NULL;
switch(ch) { switch(ch) {
case 0: 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) { else if(prec > 8) {
const int32 toShift = prec - 8; const int32 toShift = prec - 8;
@ -164,10 +164,10 @@ bool ImageLoader::LoadFromPixelBuffer(const uint32 *data, bool flipY) {
if(flipY) if(flipY)
idx = (m_Height - j - 1)*m_Height + i; idx = (m_Height - j - 1)*m_Height + i;
uint32 pixel = data[idx]; uint32 pixel = data[idx];
m_RedData[pIdx] = pixel & 0xFF; m_RedData[pIdx] = static_cast<uint8>(pixel & 0xFF);
m_GreenData[pIdx] = (pixel >> 8) & 0xFF; m_GreenData[pIdx] = static_cast<uint8>((pixel >> 8) & 0xFF);
m_BlueData[pIdx] = (pixel >> 16) & 0xFF; m_BlueData[pIdx] = static_cast<uint8>((pixel >> 16) & 0xFF);
m_AlphaData[pIdx] = (pixel >> 24) & 0xFF; m_AlphaData[pIdx] = static_cast<uint8>((pixel >> 24) & 0xFF);
} }
} }
@ -189,24 +189,13 @@ FasTC::Image<> *ImageLoader::LoadImage() {
m_Width = GetWidth(); m_Width = GetWidth();
m_Height = GetHeight(); 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 // Create RGBA buffer
const unsigned int dataSz = 4 * aw * ah; const unsigned int dataSz = 4 * GetWidth() * GetHeight();
m_PixelData = new unsigned char[dataSz]; 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; int byteIdx = 0;
for(uint32 j = 0; j < ah; j++) { for(uint32 j = 0; j < GetHeight(); j++) {
for(uint32 i = 0; i < aw; i++) { for(uint32 i = 0; i < GetWidth(); i++) {
unsigned int redVal = GetChannelForPixel(i, j, 0); unsigned int redVal = GetChannelForPixel(i, j, 0);
if(redVal == INT_MAX) { if(redVal == INT_MAX) {
@ -239,22 +228,19 @@ FasTC::Image<> *ImageLoader::LoadImage() {
} }
// Red channel // Red channel
m_PixelData[byteIdx++] = redVal & 0xFF; m_PixelData[byteIdx++] = static_cast<uint8>(redVal & 0xFF);
// Green channel // Green channel
m_PixelData[byteIdx++] = greenVal & 0xFF; m_PixelData[byteIdx++] = static_cast<uint8>(greenVal & 0xFF);
// Blue channel // Blue channel
m_PixelData[byteIdx++] = blueVal & 0xFF; m_PixelData[byteIdx++] = static_cast<uint8>(blueVal & 0xFF);
// Alpha channel // 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); uint32 *pixels = reinterpret_cast<uint32 *>(m_PixelData);
return new FasTC::Image<>(m_Width, m_Height, pixels); return new FasTC::Image<>(m_Width, m_Height, pixels);
} }