Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include "Image.hpp"
- Image::Image(
- const std::vector<uint32_t>& dataBuffer,
- const std::vector<uint32_t>& extents,
- const uint32_t& downsamplingDegree):
- mDataBuffer(dataBuffer),
- mExtents(extents),
- mDownsamplingDegree(downsamplingDegree)
- {}
- Image::~Image()
- {}
- Image::Image(const Image& rhs):
- mDataBuffer(rhs.mDataBuffer),
- mExtents(rhs.mExtents),
- mDownsamplingDegree(rhs.mDownsamplingDegree)
- {}
- Image& Image::operator=(const Image& rhs)
- {
- mDataBuffer = rhs.mDataBuffer;
- mExtents = rhs.mExtents;
- mDownsamplingDegree = rhs.mDownsamplingDegree;
- return *this;
- }
- Image::Image(Image&& rhs):
- mDataBuffer(std::move(rhs.mDataBuffer)),
- mExtents(std::move(rhs.mExtents)),
- mDownsamplingDegree(std::move(rhs.mDownsamplingDegree))
- {}
- Image& Image::operator=(Image&& rhs)
- {
- mDataBuffer = std::move(rhs.mDataBuffer);
- mExtents = std::move(rhs.mExtents);
- mDownsamplingDegree = std::move(rhs.mDownsamplingDegree);
- return *this;
- }
- void Image::GeneratedDownsampledImages()
- {
- Display();
- std::vector<Image> result;
- uint32_t minimumExtent = GetMinimumLValue(mExtents);
- for (uint32_t i = 1; i <= minimumExtent; i++)
- {
- // TODO: Sping up a thread for every call to GenerateDownsampledImage
- result.push_back(GeneratedDownsampledImage(*this, i));
- result[result.size() - 1].Display();
- }
- }
- void Image::Display()
- {
- if (mDownsamplingDegree == 0)
- {
- std::cout << "Original Image:" << std::endl;
- }
- else
- {
- std::cout << mDownsamplingDegree << "-downsampled image:" << std::endl;
- }
- std::vector<uint32_t> extentIndex;
- for (int i = 0; i < mExtents.size(); i++)
- {
- extentIndex.push_back(0);
- }
- int count = 0;
- do
- {
- uint32_t offset = GetOffsetFromExtents(extentIndex);
- std::cout << mDataBuffer[offset] << " ";
- count++;
- uint32_t modValue = 1;
- for (int i = 0; i < mExtents.size() - 1; i++)
- {
- modValue *= mExtents[i];
- if (count % modValue == 0)
- {
- std::cout << std::endl;
- }
- }
- } while (IncrementExtentIndeces(extentIndex, mExtents));
- std::cout << std::endl;
- }
- bool Image::IncrementExtentIndeces(std::vector<uint32_t>& extents, const std::vector<uint32_t>& extentBounds, const uint32_t& amount)
- {
- bool result = true;
- bool incrementFlag = false;
- int index = extents.size() - 1;
- while (index >= 0) // If index goes negative, then we've incremented all possible values
- {
- if (!incrementFlag)
- { // Prevent incrementing twice if we exceed a dimensional bound
- extents[index] += amount;
- incrementFlag = false;
- }
- if (extents[index] >= extentBounds[index])
- { // Reset this extent value and iterate the next most significant value
- extents[index] = 0;
- index--;
- if (index < 0)
- { // Make sure we don't exceed vector bounds before returning false
- result = false;
- break;
- }
- extents[index] += amount;
- incrementFlag = true; // Flag that we incremented beyond dimension bounds
- }
- else
- { // We haven't hit an extents bounds after this iteration, so we're done
- break;
- }
- }
- return result;
- }
- uint32_t Image::GetOffsetFromExtents(const std::vector<uint32_t>& indexExtents) const
- {
- uint32_t result = 0;
- for (int i = 0; i < mExtents.size(); i++)
- {
- uint32_t extentValue = indexExtents[i];
- for (int j = i + 1; j < mExtents.size(); j++)
- { // Multiply the offset by the max size of all less significant extents
- extentValue *= mExtents[j];
- }
- result += extentValue; // Accumulate total offset
- }
- return result;
- }
- uint32_t Image::GetMinimumLValue(const std::vector<uint32_t>& extents) const
- {
- uint32_t min = 0xFFFFFFFF;
- for (int i = 0; i < extents.size(); i++)
- {
- if (extents[i] < min)
- {
- min = extents[i];
- }
- }
- return log2(min);
- }
- Image Image::GeneratedDownsampledImage(const Image& image, const uint32_t& downsamplingDegree)
- {
- //std::cout << "Processing l-" << downsamplingDegree << " downsampling..." << std::endl;
- uint32_t blockSize = pow(2, downsamplingDegree);
- std::vector<uint32_t> downsampleBuffer;
- std::vector<uint32_t> extentIndex(mExtents.size());
- do
- {
- downsampleBuffer.push_back(ComputeDownsampledChunk(*this, extentIndex, blockSize));
- }
- while (IncrementExtentIndeces(extentIndex, mExtents, blockSize));
- std::vector<uint32_t> downsampledExtents(mExtents.size());
- for (int i = 0; i < mExtents.size(); i++)
- { // Generate the extents of the downsampled image
- downsampledExtents[i] = mExtents[i] / (pow(2, downsamplingDegree));
- }
- return Image(downsampleBuffer, downsampledExtents, downsamplingDegree);
- }
- uint32_t Image::ComputeDownsampledChunk(const Image& image, const std::vector<uint32_t>& offsetExtents, const uint32_t& blockSize)
- {
- std::vector<uint32_t> current(mExtents.size());
- std::vector<uint32_t> bounds(mExtents.size());
- for (int i = 0; i < mExtents.size(); i++)
- { // Establish extents for our local downsampling block
- current[i] = 0;
- bounds[i] = blockSize;
- }
- std::vector<uint32_t> values;
- do
- {
- std::vector<uint32_t> trueIndex(mExtents.size());
- for (int i = 0; i < mExtents.size(); i++)
- { // Generate absolute indeces for our traversal
- trueIndex[i] = offsetExtents[i] + current[i];
- }
- values.push_back(mDataBuffer[GetOffsetFromExtents(trueIndex)]);
- } while (IncrementExtentIndeces(current, bounds));
- std::sort(values.begin(), values.end());
- uint32_t mode = values[0];
- uint32_t modeCount = 0;
- uint32_t currentValue = values[0];
- uint32_t currentCount = 0;
- for (int i = 0; i < values.size(); i++)
- {
- if (currentValue == values[i])
- {
- currentCount++;
- }
- else
- {
- currentValue = values[i];
- }
- if (currentCount > modeCount)
- {
- mode = currentValue;
- modeCount = currentCount;
- currentCount = 1;
- }
- }
- return mode;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement