You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

192 lines
5.0 KiB

// David Eberly, Geometric Tools, Redmond WA 98052
// Copyright (c) 1998-2021
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
// https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
// Version: 4.0.2019.08.13
#pragma once
#include <vector>
namespace gte
{
template <typename PixelType>
class Image
{
public:
// Construction and destruction.
virtual ~Image()
{
}
Image()
{
}
Image(std::vector<int> const& dimensions)
{
Reconstruct(dimensions);
}
// Support for copy semantics.
Image(Image const& image)
{
*this = image;
}
Image& operator=(Image const& image)
{
mDimensions = image.mDimensions;
mOffsets = image.mOffsets;
mPixels = image.mPixels;
return *this;
}
// Support for move semantics.
Image(Image&& image)
{
*this = std::move(image);
}
Image& operator=(Image&& image)
{
mDimensions = std::move(image.mDimensions);
mOffsets = std::move(image.mOffsets);
mPixels = std::move(image.mPixels);
return *this;
}
// Support for changing the image dimensions. All pixel data is lost
// by this operation.
void Reconstruct(std::vector<int> const& dimensions)
{
mDimensions.clear();
mOffsets.clear();
mPixels.clear();
if (dimensions.size() > 0)
{
for (auto dim : dimensions)
{
if (dim <= 0)
{
return;
}
}
mDimensions = dimensions;
mOffsets.resize(dimensions.size());
size_t numPixels = 1;
for (size_t d = 0; d < dimensions.size(); ++d)
{
numPixels *= static_cast<size_t>(mDimensions[d]);
}
mOffsets[0] = 1;
for (size_t d = 1; d < dimensions.size(); ++d)
{
mOffsets[d] = static_cast<size_t>(mDimensions[d - 1]) * mOffsets[d - 1];
}
mPixels.resize(numPixels);
}
}
// Access to image data.
inline std::vector<int> const& GetDimensions() const
{
return mDimensions;
}
inline int GetNumDimensions() const
{
return static_cast<int>(mDimensions.size());
}
inline int GetDimension(int d) const
{
return mDimensions[d];
}
inline std::vector<size_t> const& GetOffsets() const
{
return mOffsets;
}
inline size_t GetOffset(int d) const
{
return mOffsets[d];
}
inline std::vector<PixelType> const& GetPixels() const
{
return mPixels;
}
inline std::vector<PixelType>& GetPixels()
{
return mPixels;
}
inline size_t GetNumPixels() const
{
return mPixels.size();
}
// Conversions between n-dim and 1-dim structures. The 'coord' arrays
// must have GetNumDimensions() elements.
size_t GetIndex(int const* coord) const
{
// assert: coord is array of mNumDimensions elements
int const numDimensions = static_cast<int>(mDimensions.size());
size_t index = coord[0];
for (int d = 1; d < numDimensions; ++d)
{
index += mOffsets[d] * coord[d];
}
return index;
}
void GetCoordinates(size_t index, int* coord) const
{
// assert: coord is array of numDimensions elements
int const numDimensions = static_cast<int>(mDimensions.size());
for (int d = 0; d < numDimensions; ++d)
{
coord[d] = index % mDimensions[d];
index /= mDimensions[d];
}
}
// Access the data as a 1-dimensional array. The operator[] functions
// test for valid i when iterator checking is enabled and assert on
// invalid i. The Get() functions test for valid i and clamp when
// invalid; these functions cannot fail.
inline PixelType& operator[] (size_t i)
{
return mPixels[i];
}
inline PixelType const& operator[] (size_t i) const
{
return mPixels[i];
}
PixelType& Get(size_t i)
{
return (i < mPixels.size() ? mPixels[i] : mPixels.front());
}
PixelType const& Get(size_t i) const
{
return (i < mPixels.size() ? mPixels[i] : mPixels.front());
}
protected:
std::vector<int> mDimensions;
std::vector<size_t> mOffsets;
std::vector<PixelType> mPixels;
};
}