diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0a467e4..601588a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -10,8 +10,6 @@ list(APPEND HEADERS CommandLineArgs.h data_structures/RawTree.h data_structures/List.h - data_structures/ListT.h - data_structures/ListFactory.h data_structures/Tree.h encoding/ByteUtils.h encoding/StringUtils.h @@ -35,7 +33,6 @@ list(APPEND LIB_INCLUDES CommandLineArgs.cpp data_structures/RawTree.cpp data_structures/Tree.cpp - data_structures/ListFactory.cpp loggers/FileLogger.cpp file_utilities/Directory.cpp file_utilities/File.cpp diff --git a/src/core/data_structures/List.h b/src/core/data_structures/List.h index 8771ab9..86354f5 100644 --- a/src/core/data_structures/List.h +++ b/src/core/data_structures/List.h @@ -1,23 +1,69 @@ #pragma once -#include +#include +#include +#include -class List +class AbstractList { public: - enum class Type - { - UCHAR, - UINT8, - DOUBLE, - COLOR, - LIST, - UNKNOWN - }; - - ~List() = default; - - virtual Type getType() const = 0; + virtual ~AbstractList() = default; virtual std::size_t getLength() const = 0; }; + +template +class List : public AbstractList +{ +public: + List() = default; + + void initializeTo(std::size_t size, T value) + { + mData = std::vector(size, value); + } + + const T* getDataPtr() const + { + return mData.data(); + } + + const std::vector& getData() const + { + return mData; + } + + T getItem(std::size_t index) const + { + if (index < mData.size()) + { + return mData[index]; + } + else + { + const auto msg = "Tried to access out of range index: " + std::to_string(index) + " with size " + std::to_string(mData.size()); + throw std::out_of_range(msg); + } + } + + void setData(const std::vector& data) + { + mData = data; + } + + void setItem(std::size_t index, T item) + { + if (index < mData.size()) + { + mData[index] = item; + } + } + + std::size_t getLength() const override + { + return mData.size(); + } + +private: + std::vector mData; +}; diff --git a/src/core/data_structures/ListFactory.cpp b/src/core/data_structures/ListFactory.cpp deleted file mode 100644 index 4ed1f96..0000000 --- a/src/core/data_structures/ListFactory.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "ListFactory.h" - -#include "ListT.h" -#include "Color.h" - -std::unique_ptr ListFactory::Create(List::Type type, std::size_t size) -{ - std::unique_ptr list; - if (type == List::Type::DOUBLE) - { - list = std::make_unique>(type, size, 0.0); - } - else if (type == List::Type::UCHAR) - { - list = std::make_unique >(type, size, 0); - } - else if (type == List::Type::UINT8) - { - list = std::make_unique>(type, size, 0); - } - else if (type == List::Type::COLOR) - { - list = std::make_unique>(type, size, Color()); - } - return std::move(list); -} \ No newline at end of file diff --git a/src/core/data_structures/ListFactory.h b/src/core/data_structures/ListFactory.h deleted file mode 100644 index 4b96b2a..0000000 --- a/src/core/data_structures/ListFactory.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "List.h" - -#include - -class ListFactory -{ -public: - static std::unique_ptr Create(List::Type type, std::size_t size = 0); -}; \ No newline at end of file diff --git a/src/core/data_structures/ListT.h b/src/core/data_structures/ListT.h deleted file mode 100644 index ea41950..0000000 --- a/src/core/data_structures/ListT.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "List.h" - -#include - -class ListFactory; - -template -class ListT : public List -{ -public: - ListT() = delete; - - ListT(List::Type type, std::size_t size, T value) - : mType(type) - { - if (size > 0) - { - initialize(size, value); - } - } - - virtual Type getType() const override - { - return mType; - } - - const T* getDataPtr() const - { - return mData.data(); - } - - const std::vector& getData() const - { - return mData; - } - - void setData(const std::vector& data) - { - mData = data; - } - - void setDataItem(std::size_t index, T item) - { - if (index < mData.size()) - { - mData[index] = item; - } - } - - void initialize(std::size_t size, T value) - { - mData.resize(size); - for (std::size_t idx = 0; idx < size; idx++) - { - mData[idx] = value; - } - } - - std::size_t getLength() const override - { - return mData.size(); - } - -private: - List::Type mType{ List::Type::UNKNOWN }; - std::vector mData; -}; \ No newline at end of file diff --git a/src/geometry/AbstractGeometricItem.h b/src/geometry/AbstractGeometricItem.h index 1c30503..2004c25 100644 --- a/src/geometry/AbstractGeometricItem.h +++ b/src/geometry/AbstractGeometricItem.h @@ -3,7 +3,8 @@ #include "Bounds.h" #include "Point.h" -class Grid; +template +class SparseGrid; class AbstractGeometricItem { @@ -28,7 +29,7 @@ public: virtual const Point& getLocation() const = 0; - virtual void sample(Grid* grid) const = 0; + virtual void sample(SparseGrid* grid) const = 0; virtual Type getType() const { return Type::UNKNOWN; }; }; diff --git a/src/geometry/CMakeLists.txt b/src/geometry/CMakeLists.txt index 59fa5a2..a0c05d5 100644 --- a/src/geometry/CMakeLists.txt +++ b/src/geometry/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND HEADERS AbstractGeometricItem.h Bounds.h grid/AbstractGrid.h + grid/TypedGrid.h grid/Grid.h grid/SparseGrid.h math/Linalg.h @@ -26,8 +27,6 @@ list(APPEND HEADERS list(APPEND LIB_INCLUDES Transform.cpp grid/AbstractGrid.cpp - grid/Grid.cpp - grid/SparseGrid.cpp math/Linalg.cpp math/Matrix.cpp math/Vector.cpp diff --git a/src/geometry/grid/AbstractGrid.cpp b/src/geometry/grid/AbstractGrid.cpp index 5e0c460..6556593 100644 --- a/src/geometry/grid/AbstractGrid.cpp +++ b/src/geometry/grid/AbstractGrid.cpp @@ -1,11 +1,10 @@ #include "AbstractGrid.h" -#include "ListT.h" - -AbstractGrid::AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType) +AbstractGrid::AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ) : mBounds(bounds), mNumX(numPointsX), - mNumY(numPointsY) + mNumY(numPointsY), + mNumZ(numPointsZ) { } @@ -30,10 +29,4 @@ double AbstractGrid::getYSpacing() const void AbstractGrid::resetBounds(const Bounds& bounds) { mBounds = bounds; - initializeData(mData->getType()); -} - -List::Type AbstractGrid::getDataType() -{ - return mData->getType(); } \ No newline at end of file diff --git a/src/geometry/grid/AbstractGrid.h b/src/geometry/grid/AbstractGrid.h index 822d054..b9902ed 100644 --- a/src/geometry/grid/AbstractGrid.h +++ b/src/geometry/grid/AbstractGrid.h @@ -1,54 +1,28 @@ #pragma once #include "Bounds.h" -#include "List.h" -#include "ListT.h" #include #include -#include class AbstractGrid { public: - AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType = List::Type::DOUBLE); + AbstractGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1); const Bounds& getBounds() const; + virtual std::size_t getDataSize() const = 0; + double getXSpacing() const; double getYSpacing() const; - List::Type getDataType(); - - template - const std::vector getData() const - { - if (!dynamic_cast*>(mData.get())) - { - throw std::logic_error("Invalid data type request for Grid data."); - } - - return dynamic_cast*>(mData.get())->getData(); - - } - - template - void setData(const std::vector indices, const std::vector& values) - { - if (auto list_t = dynamic_cast*>(mData.get())) - { - list_t->setData(indices, values); - } - } - - virtual void initializeData(List::Type dataType) = 0; - void resetBounds(const Bounds& bounds); protected: Bounds mBounds; - std::unique_ptr mData; std::size_t mNumX{ 0 }; std::size_t mNumY{ 0 }; + std::size_t mNumZ{ 0 }; }; \ No newline at end of file diff --git a/src/geometry/grid/Grid.cpp b/src/geometry/grid/Grid.cpp deleted file mode 100644 index 7d280b5..0000000 --- a/src/geometry/grid/Grid.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "Grid.h" - -#include "ListFactory.h" - -Grid::Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType) - : AbstractGrid(bounds, numPointsX, numPointsY, dataType) -{ - initializeData(dataType); -} - -void Grid::initializeData(List::Type dataType) -{ - mData = ListFactory::Create(dataType, mNumX * mNumY); -} \ No newline at end of file diff --git a/src/geometry/grid/Grid.h b/src/geometry/grid/Grid.h index 42c4050..4e343f0 100644 --- a/src/geometry/grid/Grid.h +++ b/src/geometry/grid/Grid.h @@ -1,12 +1,34 @@ #pragma once -#include "AbstractGrid.h" +#include "TypedGrid.h" -class Grid : public AbstractGrid +template +class Grid : public TypedGrid { public: - Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, List::Type dataType = List::Type::DOUBLE); + Grid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1) + : TypedGrid(bounds, numPointsX, numPointsY, numPointsZ) + { + this->mData->initializeTo(numPointsX * numPointsY * numPointsZ, T()); + } -private: - void initializeData(List::Type dataType) override; + T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const override + { + return this->mData->getItem(getOffset(idx, jdx, kdx)); + } + + std::size_t getOffset(std::size_t idx, std::size_t jdx, std::size_t kdx) const + { + return idx * this->mNumZ + jdx * this->mNumX * this->mNumZ + kdx; + } + + void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) override + { + this->mData->setItem(getOffset(idx, jdx, kdx), value); + } + + std::size_t getDataSize() const + { + return this->mData->getLength(); + } }; diff --git a/src/geometry/grid/SparseGrid.cpp b/src/geometry/grid/SparseGrid.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/geometry/grid/SparseGrid.h b/src/geometry/grid/SparseGrid.h index 3f59c93..6e3aa82 100644 --- a/src/geometry/grid/SparseGrid.h +++ b/src/geometry/grid/SparseGrid.h @@ -1,2 +1,15 @@ #pragma once +#include "TypedGrid.h" + +template +class SparseGrid : public TypedGrid +{ +public: + SparseGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY) + : TypedGrid(bounds, numPointsX, numPointsY) + { + + } + +}; \ No newline at end of file diff --git a/src/geometry/grid/TypedGrid.h b/src/geometry/grid/TypedGrid.h new file mode 100644 index 0000000..13aab21 --- /dev/null +++ b/src/geometry/grid/TypedGrid.h @@ -0,0 +1,24 @@ +#pragma once + +#include "List.h" +#include "AbstractGrid.h" + +#include + +template +class TypedGrid : public AbstractGrid +{ +public: + TypedGrid(const Bounds& bounds, std::size_t numPointsX, std::size_t numPointsY, std::size_t numPointsZ = 1) + : AbstractGrid(bounds, numPointsX, numPointsY, numPointsZ), + mData(std::make_unique >()) + { + } + + virtual T getItem(std::size_t idx, std::size_t jdx, std::size_t kdx) const = 0; + + virtual void setItem(std::size_t idx, std::size_t jdx, std::size_t kdx, const T& value) = 0; + +protected: + std::unique_ptr > mData; +}; \ No newline at end of file diff --git a/src/geometry/path/Line.h b/src/geometry/path/Line.h index 87812c8..2db4f99 100644 --- a/src/geometry/path/Line.h +++ b/src/geometry/path/Line.h @@ -18,7 +18,7 @@ public: Bounds getBounds() const override; - void sample(Grid* grid) const override {}; + void sample(SparseGrid* grid) const override {}; private: Point mStartPoint; diff --git a/src/geometry/path/LineSegment.cpp b/src/geometry/path/LineSegment.cpp index d8ebab3..cf8225c 100644 --- a/src/geometry/path/LineSegment.cpp +++ b/src/geometry/path/LineSegment.cpp @@ -27,7 +27,7 @@ const Point& LineSegment::getPoint1() const return mP1; } -void LineSegment::sample(Grid* grid) const +void LineSegment::sample(SparseGrid* grid) const { } diff --git a/src/geometry/path/LineSegment.h b/src/geometry/path/LineSegment.h index 369d017..344a67b 100644 --- a/src/geometry/path/LineSegment.h +++ b/src/geometry/path/LineSegment.h @@ -15,7 +15,7 @@ public: const Point& getPoint1() const; - void sample(Grid* grid) const override; + void sample(SparseGrid* grid) const override; Bounds getBounds() const override; diff --git a/src/geometry/primitives/Circle.cpp b/src/geometry/primitives/Circle.cpp index 640cdd9..8c302ea 100644 --- a/src/geometry/primitives/Circle.cpp +++ b/src/geometry/primitives/Circle.cpp @@ -27,7 +27,7 @@ void Circle::setMinorRadius(double radius) mMinorRadius = radius; } -void Circle::sample(Grid* grid) const +void Circle::sample(SparseGrid* grid) const { } diff --git a/src/geometry/primitives/Circle.h b/src/geometry/primitives/Circle.h index 91d5142..33dee45 100644 --- a/src/geometry/primitives/Circle.h +++ b/src/geometry/primitives/Circle.h @@ -22,7 +22,7 @@ public: void setMinorRadius(double radius); - void sample(Grid* grid) const override; + void sample(SparseGrid* grid) const override; private: double mMinorRadius{ 0.5 }; diff --git a/src/geometry/primitives/Rectangle.cpp b/src/geometry/primitives/Rectangle.cpp index b2747a6..b8a7814 100644 --- a/src/geometry/primitives/Rectangle.cpp +++ b/src/geometry/primitives/Rectangle.cpp @@ -31,7 +31,7 @@ namespace ntk { return { minX , maxX , minY , maxY }; } - void Rectangle::sample(Grid* grid) const + void Rectangle::sample(SparseGrid* grid) const { } diff --git a/src/geometry/primitives/Rectangle.h b/src/geometry/primitives/Rectangle.h index ee9c5c1..ed37cdd 100644 --- a/src/geometry/primitives/Rectangle.h +++ b/src/geometry/primitives/Rectangle.h @@ -19,7 +19,7 @@ public: Type getType() const override; - void sample(Grid* grid) const override; + void sample(SparseGrid* grid) const override; private: Point mBottomLeft; diff --git a/src/graphics/RasterPainter.cpp b/src/graphics/RasterPainter.cpp index 601dcad..5e1f8f4 100644 --- a/src/graphics/RasterPainter.cpp +++ b/src/graphics/RasterPainter.cpp @@ -5,10 +5,12 @@ #include "Grid.h" RasterPainter::RasterPainter(DrawingContext* context) - : AbstractPainter(context), - mGrid(std::make_unique(Bounds{0.0, 0.0, 100.0, 100.0})) + : AbstractPainter(context) { + const auto width = context->getSurface()->getWidth(); + const auto height = context->getSurface()->getHeight(); + mGrid = std::make_unique >(Bounds{ 0.0, 0.0, 100.0, 100.0 }, width, height); } void RasterPainter::paint() diff --git a/src/graphics/RasterPainter.h b/src/graphics/RasterPainter.h index 586e447..d55830f 100644 --- a/src/graphics/RasterPainter.h +++ b/src/graphics/RasterPainter.h @@ -5,6 +5,8 @@ #include class DrawingContext; + +template class Grid; class RasterPainter : public AbstractPainter @@ -15,5 +17,5 @@ public: void paint() override; private: - std::unique_ptr mGrid; + std::unique_ptr > mGrid; }; diff --git a/src/image/CMakeLists.txt b/src/image/CMakeLists.txt index 6816b6b..850c14b 100644 --- a/src/image/CMakeLists.txt +++ b/src/image/CMakeLists.txt @@ -31,7 +31,7 @@ list(APPEND platform_LIB_INCLUDES ) endif() -list(APPEND image_LIBS core compression) +list(APPEND image_LIBS core compression geometry) list(APPEND image_DEFINES "") add_library(image SHARED ${image_LIB_INCLUDES} ${platform_LIB_INCLUDES} ${image_HEADERS}) diff --git a/src/image/Image.cpp b/src/image/Image.cpp index 2d0ea1c..66036b0 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -1,12 +1,13 @@ #include "Image.h" #include "Color.h" +#include "Grid.h" #ifdef _WIN32 #include "Win32WicImage.h" #endif -Image::Image(unsigned width, unsigned height, ImageData::Type dataType) +Image::Image(unsigned width, unsigned height, DataType dataType) : mWidth(width), mHeight(height), mDataType(dataType) @@ -19,38 +20,43 @@ Image::~Image() } -std::unique_ptr Image::Create(unsigned width, unsigned height, ImageData::Type dataType) +std::unique_ptr Image::Create(unsigned width, unsigned height, DataType dataType) { return std::make_unique(width, height, dataType); } void Image::initialize() { - if (mDataType == ImageData::Type::UCHAR || mDataType == ImageData::Type::UNKNOWN) + Bounds bounds(0.0, mWidth, 0.0, mHeight); + if (mDataType == DataType::UCHAR) { - auto data = std::unique_ptr >(); - data->initialize(getBytesPerRow() * mHeight, 0); - mData = std::move(data); + mData = std::make_unique >(bounds, mWidth, mHeight, mNumChannels); } else { - auto data = std::unique_ptr >(); - data->initialize(getBytesPerRow() * mHeight, 0); - mData = std::move(data); + mData = std::make_unique >(bounds, mWidth, mHeight, mNumChannels); } } -void Image::setPixelValue(unsigned idx, unsigned jdx, const Color& color) +void Image::setPixelValues(const Indices& indices, const std::vector& colors) { if (!mData) { initialize(); } - const auto offset = jdx * getBytesPerRow() + idx * 3; - mData->setDataItem(offset, color.getR()); - mData->setDataItem(offset + 1, color.getG()); - mData->setDataItem(offset + 2, color.getB()); + if (mDataType == DataType::UCHAR) + { + auto data_t = getDataT(); + for (std::size_t idx=0; idx< indices.size(); idx++) + { + auto id = indices[idx]; + auto color = colors[idx]; + data_t->setItem(id.first, id.second, 0, color.getR()); + data_t->setItem(id.first, id.second, 1, color.getG()); + data_t->setItem(id.first, id.second, 2, color.getB()); + } + } } unsigned Image::getBytesPerRow() const @@ -83,14 +89,20 @@ PlatformImage* Image::getPlatformImage() return mPlatformImage.get(); } -ImageData* Image::getData() +AbstractGrid* Image::getData() const { return mData.get(); } -unsigned char Image::getAsUnsignedChar(unsigned idx, unsigned jdx) const +template +Grid* Image::getDataT() const { - return mData->getAsUnsignedChar(jdx * getBytesPerRow() + idx); + return dynamic_cast*>(this->mData.get()); +} + +Image::DataType Image::getType() const +{ + return mDataType; } unsigned Image::getNumChannels() const diff --git a/src/image/Image.h b/src/image/Image.h index 94139e9..8167ce8 100644 --- a/src/image/Image.h +++ b/src/image/Image.h @@ -1,19 +1,30 @@ #pragma once #include "PlatformImage.h" -#include "ImageData.h" #include #include class Color; +class AbstractGrid; +template +class Grid; + class Image { public: - Image(unsigned width, unsigned height, ImageData::Type dataType = ImageData::Type::UCHAR); + enum class DataType + { + UCHAR + }; + + using Index = std::pair; + using Indices = std::vector; + + Image(unsigned width, unsigned height, DataType dataType = DataType::UCHAR); ~Image(); - static std::unique_ptr Create(unsigned width, unsigned height, ImageData::Type dataType = ImageData::Type::UCHAR); + static std::unique_ptr Create(unsigned width, unsigned height, DataType dataType = DataType::UCHAR); unsigned getBytesPerRow() const; unsigned getWidth() const; @@ -21,11 +32,15 @@ public: unsigned getBitDepth() const; unsigned getNumChannels() const; - ImageData* getData(); - unsigned char getAsUnsignedChar(unsigned idx, unsigned jdx) const; + AbstractGrid* getData() const; + + template + Grid* getDataT() const; + + DataType getType() const; PlatformImage* getPlatformImage(); - void setPixelValue(unsigned idx, unsigned jdx, const Color& color); + void setPixelValues(const Indices& indices, const std::vector& colors); void setWidth(unsigned width); void setHeight(unsigned height); void setBitDepth(unsigned bitDepth); @@ -39,7 +54,7 @@ private: unsigned mBitDepth{8}; unsigned mNumChannels{4}; - ImageData::Type mDataType; - std::unique_ptr mData; + DataType mDataType; + std::unique_ptr mData; std::unique_ptr mPlatformImage; }; diff --git a/src/image/ImageBitStream.cpp b/src/image/ImageBitStream.cpp index b57f5d7..a433d43 100644 --- a/src/image/ImageBitStream.cpp +++ b/src/image/ImageBitStream.cpp @@ -1,5 +1,7 @@ #include "ImageBitStream.h" +#include "AbstractGrid.h" + ImageBitStream::ImageBitStream(Image* image) : BitStream(), mImage(image) @@ -9,7 +11,7 @@ ImageBitStream::ImageBitStream(Image* image) bool ImageBitStream::isFinished() const { - return mByteOffset == mImage->getData()->getLength(); + return mByteOffset == mImage->getData()->getDataSize(); } std::vector ImageBitStream::peekNextNBytes(unsigned n) const @@ -25,8 +27,9 @@ std::optional ImageBitStream::readNextByte() { return std::nullopt; } - const auto val = mImage->getData()->getAsUnsignedChar(mByteOffset); - return val; + //const auto val = mImage->getData()->getAsUnsignedChar(mByteOffset); + //return val; + return {}; } void ImageBitStream::writeByte(unsigned char data, bool checkOverflow ) @@ -37,6 +40,6 @@ void ImageBitStream::writeByte(unsigned char data, bool checkOverflow ) { return; } - mImage->getData()->setDataItem(mByteOffset, data); + //mImage->getData()->setDataItem(mByteOffset, data); }