Skip to content

Instantly share code, notes, and snippets.

@LYP951018
Last active September 26, 2019 12:50
Show Gist options
  • Save LYP951018/3aba8ed0d40f4eb33e5d84ebb84d3ce6 to your computer and use it in GitHub Desktop.
Save LYP951018/3aba8ed0d40f4eb33e5d84ebb84d3ce6 to your computer and use it in GitHub Desktop.
Transpose blocking
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define _CRT_SECURE_NO_WARNINGS 1
#include <stb_image.h>
#include <stb_image_write.h>
#include <vector>
#include <chrono>
#include <iostream>
void Rotate2701(const unsigned char* input,
int width, int height, unsigned char* output)
{
const std::uint32_t* inputPixels = reinterpret_cast<const std::uint32_t*>(input);
std::uint32_t* outputPixels = reinterpret_cast<std::uint32_t*>(output);
const std::uint32_t kBlockPixelSize = 4;
const std::uint32_t rowBlockCount = width / kBlockPixelSize;
const std::uint32_t colBlockCount = height / kBlockPixelSize;
const auto transpose = [&](int x, int y) {
outputPixels[y + (width - x - 1) * height] = inputPixels[y * width + x];
};
//transpose blocks first
for (int i = 0; i < height - kBlockPixelSize; i += kBlockPixelSize)
{
for (int j = 0; j < width - kBlockPixelSize; j += kBlockPixelSize)
{
for(int k = 0; k < kBlockPixelSize; ++k)
{
int y = i + k;
for (int m = 0; m < kBlockPixelSize; ++m)
{
int x = j + m;
transpose(x, y);
}
}
}
}
//pixels left
int leftXStart = static_cast<int>(rowBlockCount * kBlockPixelSize);
int leftYStart = static_cast<int>(colBlockCount * kBlockPixelSize);
for (int i = leftYStart; i < height; ++i)
{
for (int j = leftXStart; j < width; ++j)
{
transpose(j, i);
}
}
}
void Rotate2702(const unsigned char* input,
int width, int height, unsigned char* output)
{
const std::uint32_t* inputPixels = reinterpret_cast<const std::uint32_t*>(input);
std::uint32_t* outputPixels = reinterpret_cast<std::uint32_t*>(output);
const auto transpose = [&](int x, int y) {
outputPixels[y + (width - x - 1) * height] = inputPixels[y * width + x];
};
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
transpose(j, i);
}
}
}
int main()
{
const char* const inputPath = R"()";
const char* const destPath = R"(.\foo.png)";
int x, y, channels;
unsigned char* inputPixels = stbi_load(inputPath,
&x, &y, &channels, 4);
std::vector<unsigned char> outputPixels(static_cast<std::size_t>(x * y * 4));
auto startTime = std::chrono::high_resolution_clock::now();
Rotate2702(inputPixels, x, y, outputPixels.data());
auto endTime = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
std::cout << "Time elapsed: " << duration << ".\n";
stbi_image_free(inputPixels);
stbi_write_png(destPath, y, x, 4, outputPixels.data(), y * 4);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment