From 4afacf384d4c59db0fe63892c0ff50d9baa9660e Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 11 Feb 2015 23:39:32 -0800 Subject: [PATCH] Add preliminary forward DCT --- Base/include/FasTC/Image.h | 2 + Base/src/Image.cpp | 75 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/Base/include/FasTC/Image.h b/Base/include/FasTC/Image.h index b1ad2aa..f39ff2e 100644 --- a/Base/include/FasTC/Image.h +++ b/Base/include/FasTC/Image.h @@ -130,6 +130,8 @@ namespace FasTC { Image *channelOne, Image *channelTwo, Image *channelThree); + + extern void DiscreteCosineXForm(Image *img, int blockSize); } // namespace FasTC #endif // __TEXCOMP_IMAGE_H__ diff --git a/Base/src/Image.cpp b/Base/src/Image.cpp index 480273e..7d30edd 100644 --- a/Base/src/Image.cpp +++ b/Base/src/Image.cpp @@ -610,4 +610,79 @@ void SplitChannels(const Image &in, SplitChannelsImpl(in, channelOne, channelTwo, channelThree); } +//////////////////////////////////////////////////////////////////////////////// +// +// Discrete Cosine Transform +// +//////////////////////////////////////////////////////////////////////////////// + +static void DCT(Image *img) { + Image new_img = *img; + + float N = static_cast(img->GetWidth()); + float M = static_cast(img->GetHeight()); + + for (unsigned int v = 0; v < img->GetHeight(); ++v) { + for (unsigned int u = 0; u < img->GetWidth(); ++u) { + new_img(u, v) = 0.0f; + for (unsigned int y = 0; y < img->GetHeight(); ++y) { + for (unsigned int x = 0; x < img->GetWidth(); ++x) { + float fx = static_cast(x); + float fy = static_cast(y); + new_img(u, v) += (*img)(x, y) + * cos((2*fx + 1) / (2 * N)) + * cos((2*fy + 1) / (2 * M)); + } + } + + if (u == 0 && v == 0) { + new_img(u, v) *= 0.5; + } else if (u == 0 || v == 0) { + new_img(u, v) /= sqrt(2); + } + new_img(u, v) *= 0.25; + } + } + + *img = new_img; +} + +extern void DiscreteCosineXForm(Image *img, int blockSize) { + Image block(blockSize, blockSize); + for (unsigned int j = 0; j < img->GetHeight(); j += blockSize) { + for (unsigned int i = 0; i < img->GetWidth(); i += blockSize) { + // Populate block + for (int y = 0; y < blockSize; ++y) { + for (int x = 0; x < blockSize; ++x) { + IPixel xx = std::min(img->GetWidth() - 1, i + x); + IPixel yy = std::min(img->GetHeight() - 1, j + y); + block(x, y) = (*img)(xx, yy); + } + } + + // Transform it + DCT(&block); + + // Put it back in the original image + for (int y = 0; y < blockSize; ++y) { + for (int x = 0; x < blockSize; ++x) { + if (i + x >= img->GetWidth()) { + continue; + } + + if (j + y >= img->GetHeight()) { + continue; + } + + assert (i + x <= img->GetWidth()); + assert (j + y <= img->GetHeight()); + + (*img)(i + x, j + y) = block(x, y); + } + } + } + } +} + + } // namespace FasTC