mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2024-11-28 01:04:23 +01:00
Add method for downscaling by averaging nearby pixel values.
This commit is contained in:
parent
8e555b8424
commit
160fbb5e39
@ -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();
|
||||
|
@ -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 New Issue
Block a user