mirror of
https://github.com/yuzu-emu/FasTC
synced 2024-11-23 17:03:42 +00:00
Merge branch 'CompressPVRTC' of git.cs.unc.edu:pavel/FasTC into CompressPVRTC
This commit is contained in:
commit
3a4a841309
3 changed files with 89 additions and 2 deletions
|
@ -225,6 +225,66 @@ void Image::BilinearUpscale(uint32 xtimes, uint32 ytimes,
|
|||
m_Height = newHeight;
|
||||
}
|
||||
|
||||
static Pixel AveragePixels(const ::std::vector<Pixel> &pixels) {
|
||||
if(pixels.size() == 0) {
|
||||
return Pixel();
|
||||
}
|
||||
|
||||
uint32 sum[4] = {0};
|
||||
::std::vector<Pixel>::const_iterator it;
|
||||
for(it = pixels.begin(); it != pixels.end(); it++) {
|
||||
for(uint32 c = 0; c < 4; c++) {
|
||||
sum[c] += (*it).Component(c);
|
||||
}
|
||||
}
|
||||
|
||||
Pixel result;
|
||||
for(uint32 c = 0; c < 4; c++) {
|
||||
result.Component(c) = sum[c] / pixels.size();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Image::AverageDownscale(uint32 xtimes, uint32 ytimes, EWrapMode wrapMode) {
|
||||
const uint32 w = GetWidth();
|
||||
const uint32 h = GetHeight();
|
||||
|
||||
const uint32 newWidth = w >> xtimes;
|
||||
const uint32 newHeight = h >> ytimes;
|
||||
|
||||
Pixel *downscaledPixels = new Pixel[newWidth * newHeight];
|
||||
|
||||
uint8 bitDepth[4];
|
||||
m_Pixels[0].GetBitDepth(bitDepth);
|
||||
|
||||
uint32 pixelsX = 1 << xtimes;
|
||||
uint32 pixelsY = 1 << ytimes;
|
||||
|
||||
::std::vector<Pixel> toAvg;
|
||||
toAvg.reserve(pixelsX * pixelsY);
|
||||
|
||||
for(uint32 j = 0; j < newHeight; j++) {
|
||||
for(uint32 i = 0; i < newWidth; i++) {
|
||||
uint32 newIdx = j * newWidth + i;
|
||||
|
||||
toAvg.clear();
|
||||
for(uint32 y = j * pixelsY; y < (j+1) * pixelsY; y++) {
|
||||
for(uint32 x = i * pixelsX; x < (i+1) * pixelsX; x++) {
|
||||
toAvg.push_back(GetPixel(x, y, wrapMode));
|
||||
}
|
||||
}
|
||||
|
||||
downscaledPixels[newIdx] = AveragePixels(toAvg);
|
||||
}
|
||||
}
|
||||
|
||||
delete m_Pixels;
|
||||
m_Pixels = downscaledPixels;
|
||||
m_Width = newWidth;
|
||||
m_Height = newHeight;
|
||||
}
|
||||
|
||||
void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes,
|
||||
EWrapMode wrapMode, bool bOffsetNewPixels) {
|
||||
const uint32 w = GetWidth();
|
||||
|
@ -296,7 +356,7 @@ void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes,
|
|||
Iy[idx] = (I[yphidx] - I[ymhidx]) / 2.0f;
|
||||
|
||||
for(uint32 c = 0; c <= 3; c++) {
|
||||
#define CPNT(dx) Pixel::ConvertChannelToFloat(m_Pixels[dx].Component(c), bitDepth[c])
|
||||
#define CPNT(dx) Pixel::ConvertChannelToFloat(m_Pixels[dx].Component(c), bitDepth[c])
|
||||
Ix[c][idx] = (CPNT(xphidx) - CPNT(xmhidx)) / 2.0f;
|
||||
Ixx[c][idx] = (CPNT(xphidx) - 2.0f*CPNT(idx) + CPNT(xmhidx)) / 2.0f;
|
||||
Iyy[c][idx] = (CPNT(yphidx) - 2.0f*CPNT(idx) + CPNT(ymhidx)) / 2.0f;
|
||||
|
@ -348,7 +408,7 @@ void Image::ContentAwareDownscale(uint32 xtimes, uint32 ytimes,
|
|||
result.Component(c) = static_cast<uint8>(Clamp(I0 + 0.25f*It, 0.0f, 1.0f) * scale + 0.5f);
|
||||
}
|
||||
|
||||
downscaledPixels[j * newHeight + i] = result;
|
||||
downscaledPixels[j * newWidth + i] = result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,10 @@ class Image {
|
|||
EWrapMode wrapMode = eWrapMode_Wrap,
|
||||
bool bOffsetNewPixels = false);
|
||||
|
||||
// Downscales the image by using a simple averaging of the neighboring pixel values
|
||||
void AverageDownscale(uint32 xtimes, uint32 ytimes,
|
||||
EWrapMode wrapMode = eWrapMode_Wrap);
|
||||
|
||||
void ComputeHessianEigenvalues(::std::vector<float> &eigOne,
|
||||
::std::vector<float> &eigTwo,
|
||||
EWrapMode wrapMode = eWrapMode_Wrap);
|
||||
|
|
|
@ -279,6 +279,29 @@ TEST(Image, BilinearUpscaleWrapped) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(Image, AverageDownscale) {
|
||||
PVRTCC::Image img(8, 8);
|
||||
for(uint32 j = 0; j < img.GetHeight(); j++) {
|
||||
for(uint32 i = 0; i < img.GetWidth(); i++) {
|
||||
if((i ^ j) & 1) {
|
||||
img(i, j) = PVRTCC::Pixel(0xFF000000);
|
||||
} else {
|
||||
img(i, j) = PVRTCC::Pixel(0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img.AverageDownscale(1, 2);
|
||||
EXPECT_EQ(img.GetWidth(), static_cast<uint32>(4));
|
||||
EXPECT_EQ(img.GetHeight(), static_cast<uint32>(2));
|
||||
|
||||
for(uint32 j = 0; j < img.GetHeight(); j++) {
|
||||
for(uint32 i = 0; i < img.GetWidth(); i++) {
|
||||
EXPECT_EQ(PixelPrinter(0xFF7F7F7F), PixelPrinter(img(i, j).PackRGBA()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Image, ContentAwareDownscale) {
|
||||
PVRTCC::Image img(8, 8);
|
||||
for(uint32 j = 0; j < img.GetHeight(); j++) {
|
||||
|
|
Loading…
Reference in a new issue