Clean image types

This commit is contained in:
James Grogan 2022-11-11 16:32:55 +00:00
parent e7683cd94e
commit c6d03f16d0
18 changed files with 169 additions and 107 deletions

View file

@ -3,9 +3,9 @@
#include <memory> #include <memory>
#include "INativeDrawingSurface.h" #include "INativeDrawingSurface.h"
#include "Image.h"
class Grid; class Grid;
class Image;
class DrawingSurface class DrawingSurface
{ {
@ -26,12 +26,12 @@ public:
void Paint(Grid* grid); void Paint(Grid* grid);
Image* GetAsImage() const; Image<unsigned char>* GetAsImage() const;
private: private:
unsigned mWidth = 0; unsigned mWidth = 0;
unsigned mHeight = 0; unsigned mHeight = 0;
std::unique_ptr<Image> mImageBuffer; std::unique_ptr<Image<unsigned char> > mImageBuffer;
std::unique_ptr<INativeDrawingSurface> mNativeDrawingSurface; std::unique_ptr<INativeDrawingSurface> mNativeDrawingSurface;
}; };

View file

@ -1,91 +1,112 @@
#include "Image.h" #include "Image.h"
Image::Image(unsigned width, unsigned height) #include "Color.h"
template<typename T>
Image<T>::Image(unsigned width, unsigned height)
: mWidth(width), : mWidth(width),
mHeight(height) mHeight(height)
{ {
} }
Image::~Image() template<typename T>
Image<T>::~Image()
{ {
} }
void Image::Initialize() template<typename T>
void Image<T>::initialize()
{ {
mData = std::vector<unsigned char>(GetBytesPerRow()*mHeight, 0); mData = std::vector<T>(getBytesPerRow()*mHeight, 0);
} }
void Image::SetPixelValue(unsigned idx, unsigned jdx, const Color& color) template<typename T>
void Image<T>::setPixelValue(unsigned idx, unsigned jdx, const Color& color)
{ {
if (mData.empty()) if (mData.empty())
{ {
Initialize(); initialize();
} }
mData[jdx*GetBytesPerRow() + idx*3] = static_cast<unsigned char>(color.GetR()); mData[jdx*getBytesPerRow() + idx*3] = static_cast<T>(color.GetR());
mData[jdx*GetBytesPerRow() + idx*3 + 1] = static_cast<unsigned char>(color.GetG()); mData[jdx*getBytesPerRow() + idx*3 + 1] = static_cast<T>(color.GetG());
mData[jdx*GetBytesPerRow() + idx*3 + 2] = static_cast<unsigned char>(color.GetB()); mData[jdx*getBytesPerRow() + idx*3 + 2] = static_cast<T>(color.GetB());
} }
std::unique_ptr<Image> Image::Create(unsigned width, unsigned height) template<typename T>
std::unique_ptr<Image<T> > Image<T>::Create(unsigned width, unsigned height)
{ {
return std::make_unique<Image>(width, height); return std::make_unique<Image<T> >(width, height);
} }
unsigned Image::GetBytesPerRow() const template<typename T>
unsigned Image<T>::getBytesPerRow() const
{ {
const auto bitsPerEntry = mBitDepth <= 8 ? 1 : 2; const auto bitsPerEntry = mBitDepth <= 8 ? 1 : 2;
return mWidth * mNumChannels *bitsPerEntry; return mWidth * mNumChannels *bitsPerEntry;
} }
unsigned Image::GetWidth() const template<typename T>
unsigned Image<T>::getWidth() const
{ {
return mWidth; return mWidth;
} }
unsigned Image::GetHeight() const template<typename T>
unsigned Image<T>::getHeight() const
{ {
return mHeight; return mHeight;
} }
unsigned Image::GetBitDepth() const template<typename T>
unsigned Image<T>::getBitDepth() const
{ {
return mBitDepth; return mBitDepth;
} }
unsigned char Image::GetByte(unsigned idx, unsigned jdx) const template<typename T>
T Image<T>::getByte(unsigned idx, unsigned jdx) const
{ {
return mData[jdx*GetBytesPerRow() + idx]; return mData[jdx*getBytesPerRow() + idx];
} }
unsigned Image::GetNumChannels() const template<typename T>
unsigned Image<T>::getNumChannels() const
{ {
return mNumChannels; return mNumChannels;
} }
void Image::SetData(const std::vector<unsigned char>& data) template<typename T>
void Image<T>::setData(const std::vector<T>& data)
{ {
mData = data; mData = data;
} }
void Image::SetWidth(unsigned width) template<typename T>
void Image<T>::setWidth(unsigned width)
{ {
mWidth = width; mWidth = width;
} }
void Image::SetHeight(unsigned height) template<typename T>
void Image<T>::setHeight(unsigned height)
{ {
mHeight = height; mHeight = height;
} }
void Image::SetBitDepth(unsigned bitDepth) template<typename T>
void Image<T>::setBitDepth(unsigned bitDepth)
{ {
mBitDepth = bitDepth; mBitDepth = bitDepth;
} }
void Image::SetNumChannels(unsigned numChannels) template<typename T>
void Image<T>::setNumChannels(unsigned numChannels)
{ {
mNumChannels = numChannels; mNumChannels = numChannels;
} }
template class Image<unsigned char>;
//template class Image<uint8_t>;

View file

@ -1,43 +1,40 @@
#pragma once #pragma once
#include "Color.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
class Color;
template<typename T>
class Image class Image
{ {
public: public:
Image(unsigned width, unsigned height); Image(unsigned width, unsigned height);
~Image(); ~Image();
static std::unique_ptr<Image> Create(unsigned width, unsigned height); static std::unique_ptr<Image<T> > Create(unsigned width, unsigned height);
unsigned GetBytesPerRow() const; unsigned getBytesPerRow() const;
unsigned GetWidth() const; unsigned getWidth() const;
unsigned GetHeight() const; unsigned getHeight() const;
unsigned GetBitDepth() const; unsigned getBitDepth() const;
unsigned GetNumChannels() const; unsigned getNumChannels() const;
void SetPixelValue(unsigned idx, unsigned jdx, const Color& color); void setPixelValue(unsigned idx, unsigned jdx, const Color& color);
unsigned char GetByte(unsigned idx, unsigned jdx) const; T getByte(unsigned idx, unsigned jdx) const;
void SetData(const std::vector<unsigned char>& data); void setData(const std::vector<T>& data);
void SetWidth(unsigned width); void setWidth(unsigned width);
void SetHeight(unsigned height); void setHeight(unsigned height);
void SetBitDepth(unsigned bitDepth); void setBitDepth(unsigned bitDepth);
void SetNumChannels(unsigned numChannels); void setNumChannels(unsigned numChannels);
private: private:
void Initialize(); void initialize();
unsigned mWidth{1}; unsigned mWidth{1};
unsigned mHeight{1}; unsigned mHeight{1};
unsigned mBitDepth{8}; unsigned mBitDepth{8};
unsigned mNumChannels{1}; unsigned mNumChannels{1};
std::vector<unsigned char> mData; std::vector<T> mData;
}; };
using ImagePtr = std::unique_ptr<Image>;

View file

@ -0,0 +1,26 @@
#pragma once
#include <cstdint>
class ImagePrimitives
{
public:
static void drawCheckerboard(uint8_t* data, int width, int height, int offset = 0)
{
auto pixels = (uint32_t *)&(data)[offset];
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
if ((x + y / 8 * 8) % 16 < 8)
{
pixels[y * width + x] = 0xFF666666;
}
else
{
pixels[y * width + x] = 0xFFEEEEEE;
}
}
}
}
};

View file

@ -108,9 +108,9 @@ void PngReader::logHeader()
std::cout << sstr.str() << std::endl; std::cout << sstr.str() << std::endl;
} }
std::unique_ptr<Image> PngReader::read() std::unique_ptr<Image<unsigned char> > PngReader::read()
{ {
auto image = std::make_unique<Image>(5, 5); auto image = std::make_unique<Image<unsigned char> >(5, 5);
mFile = std::make_unique<File>(mPath); mFile = std::make_unique<File>(mPath);
mFile->Open(true); mFile->Open(true);

View file

@ -5,8 +5,7 @@
#include <vector> #include <vector>
#include "File.h" #include "File.h"
#include "Image.h"
class Image;
class PngReader class PngReader
{ {
@ -14,19 +13,19 @@ public:
~PngReader(); ~PngReader();
void setPath(const std::string& path); void setPath(const std::string& path);
std::unique_ptr<Image> read(); std::unique_ptr<Image<unsigned char> > read();
private: private:
struct IHDRChunk struct IHDRChunk
{ {
unsigned width{0}; unsigned width{0};
unsigned height{0}; unsigned height{0};
char bitDepth{0}; char bitDepth{0};
char colorType{0}; char colorType{0};
char compressionMethod{0}; char compressionMethod{0};
char filterMethod{0}; char filterMethod{0};
char interlaceMethod{0}; char interlaceMethod{0};
}; };
bool readChunk(); bool readChunk();
@ -39,7 +38,7 @@ private:
IHDRChunk mIHDRChunk; IHDRChunk mIHDRChunk;
std::unique_ptr<Image> mWorkingImage; std::unique_ptr<Image<unsigned char> > mWorkingImage;
std::unique_ptr<File> mFile; std::unique_ptr<File> mFile;
std::string mPath; std::string mPath;
}; };

View file

@ -29,7 +29,7 @@ void PngWriter::SetPath(const std::string& path)
mImpl->setPath(path); mImpl->setPath(path);
} }
void PngWriter::Write(const std::unique_ptr<Image>& image) const void PngWriter::Write(const std::unique_ptr<Image<unsigned char> >& image) const
{ {
mImpl->write(image); mImpl->write(image);
//auto fp = fopen(mPath.c_str(), "wb"); //auto fp = fopen(mPath.c_str(), "wb");

View file

@ -3,7 +3,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
class Image; #include "Image.h"
class PngWriterImpl; class PngWriterImpl;
class PngWriter class PngWriter
@ -15,7 +16,7 @@ public:
void SetPath(const std::string& path); void SetPath(const std::string& path);
void Write(const std::unique_ptr<Image>& image) const; void Write(const std::unique_ptr<Image<unsigned char> >& image) const;
private: private:
std::unique_ptr<PngWriterImpl> mImpl; std::unique_ptr<PngWriterImpl> mImpl;

View file

@ -5,7 +5,7 @@ void PngWriterBasic::setPath(const std::string& path)
} }
void PngWriterBasic::write(const std::unique_ptr<Image>& image) const void PngWriterBasic::write(const std::unique_ptr<Image<unsigned char> >& image) const
{ {
} }

View file

@ -7,8 +7,8 @@ class PngWriterBasic : public PngWriterImpl
public: public:
void setPath(const std::string& path) override; void setPath(const std::string& path) override;
void write(const std::unique_ptr<Image>& image) const override; void write(const std::unique_ptr<Image<unsigned char>>& image) const override;
private: private:
std::string mPath; std::string mPath;
}; };

View file

@ -3,7 +3,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
class Image; #include "Image.h"
class PngWriterImpl class PngWriterImpl
{ {
@ -12,5 +12,5 @@ public:
virtual void setPath(const std::string& path) = 0; virtual void setPath(const std::string& path) = 0;
virtual void write(const std::unique_ptr<Image>& image) const = 0; virtual void write(const std::unique_ptr<Image<unsigned char> >& image) const = 0;
}; };

View file

@ -5,11 +5,25 @@
namespace mt namespace mt
{ {
class Screen; class Screen;
class Window;
} }
class IPlatformWindow class IPlatformSurface
{ {
public: public:
virtual ~IPlatformSurface() = default;
virtual void paint(mt::Screen* screen) = 0;
};
class IPlatformWindow : public IPlatformSurface
{
public:
IPlatformWindow(mt::Window* window)
: mWindow(window)
{
}
virtual ~IPlatformWindow() = default; virtual ~IPlatformWindow() = default;
virtual void show() const = 0; virtual void show() const = 0;
@ -17,8 +31,8 @@ public:
virtual void map() const = 0; virtual void map() const = 0;
virtual void clear() const = 0; virtual void clear() const = 0;
protected:
virtual void paint(mt::Screen* screen) const = 0; mt::Window* mWindow{nullptr};
}; };
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>; using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;

View file

@ -14,7 +14,7 @@ namespace mt
Window::Window() Window::Window()
:mWidth(800), :mWidth(800),
mHeight(600), mHeight(600),
mBackingImage(std::make_unique<Image>(mWidth, mHeight)), mBackingImage(std::make_unique<Image<uint8_t> >(mWidth, mHeight)),
mWidget(Widget::Create()) mWidget(Widget::Create())
{ {
mWidget->setBounds(mWidth, mHeight); mWidget->setBounds(mWidth, mHeight);
@ -96,7 +96,7 @@ void Window::SetPlatformWindow(IPlatformWindowPtr window)
mPlatformWindow = std::move(window); mPlatformWindow = std::move(window);
} }
Image* Window::getBackingImage() const Image<uint8_t>* Window::getBackingImage() const
{ {
return mBackingImage.get(); return mBackingImage.get();
} }

View file

@ -1,15 +1,16 @@
#pragma once #pragma once
#include "Widget.h" #include "Widget.h"
#include "Image.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <cstdint>
class PaintEvent; class PaintEvent;
class MouseEvent; class MouseEvent;
class KeyboardEvent; class KeyboardEvent;
class VisualLayer; class VisualLayer;
class Image;
class IPlatformWindow; class IPlatformWindow;
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>; using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;
@ -51,7 +52,7 @@ public:
void SetPlatformWindow(IPlatformWindowPtr window); void SetPlatformWindow(IPlatformWindowPtr window);
Image* getBackingImage() const; Image<uint8_t>* getBackingImage() const;
void map(); void map();
@ -67,7 +68,7 @@ private:
unsigned mWidth {800}; unsigned mWidth {800};
unsigned mHeight {600}; unsigned mHeight {600};
IPlatformWindowPtr mPlatformWindow {nullptr}; IPlatformWindowPtr mPlatformWindow {nullptr};
std::unique_ptr<Image> mBackingImage; std::unique_ptr<Image<uint8_t> > mBackingImage;
}; };
} }

View file

@ -1,9 +1,10 @@
#include "WaylandSurface.h" #include "WaylandSurface.h"
#include "WaylandEglWindowInterface.h" #include "WaylandEglWindowInterface.h"
#include "ImagePrimitives.h"
WaylandSurface::WaylandSurface(mt::Window* window) WaylandSurface::WaylandSurface(mt::Window* window)
: mWindow(window) : IPlatformWindow(window)
{ {
} }
@ -36,17 +37,22 @@ void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_b
mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface); mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface);
xdg_toplevel_set_title(mXdgTopLevel, "Example client"); xdg_toplevel_set_title(mXdgTopLevel, "Example client");
wl_surface_commit(mSurface);
auto region = wl_compositor_create_region(compositor); auto region = wl_compositor_create_region(compositor);
wl_region_add(region, 0, 0, mWindow->GetWidth(), mWindow->GetHeight()); wl_region_add(region, 0, 0, mWindow->GetWidth(), mWindow->GetHeight());
wl_surface_set_opaque_region(mSurface, region); wl_surface_set_opaque_region(mSurface, region);
wl_surface_commit(mSurface);
} }
void WaylandSurface::onConfigure(xdg_surface *xdg_surface, uint32_t serial) void WaylandSurface::onConfigure(xdg_surface *xdg_surface, uint32_t serial)
{ {
xdg_surface_ack_configure(xdg_surface, serial); xdg_surface_ack_configure(xdg_surface, serial);
paint(nullptr);
}
void WaylandSurface::paint(mt::Screen* screen)
{
if (mEglWindowInterface) if (mEglWindowInterface)
{ {
mEglWindowInterface->initialize(mSurface, mWindow->GetWidth(), mWindow->GetHeight()); mEglWindowInterface->initialize(mSurface, mWindow->GetWidth(), mWindow->GetHeight());
@ -77,29 +83,11 @@ wl_buffer* WaylandSurface::drawFrame()
mBuffer->setUpPool(shm_pool_size, width, height, stride); mBuffer->setUpPool(shm_pool_size, width, height, stride);
int offset = 0; int offset = 0;
drawCheckerboard(width, height, offset);
ImagePrimitives::drawCheckerboard(mBuffer->getPoolData(), width, height, offset);
mBuffer->tearDownPool(shm_pool_size); mBuffer->tearDownPool(shm_pool_size);
return mBuffer->getWorkingBuffer(); return mBuffer->getWorkingBuffer();
} }
void WaylandSurface::drawCheckerboard(int width, int height, int offset)
{
uint32_t *pixels = (uint32_t *)&(mBuffer->getPoolData())[offset];
for (int y = 100; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
if ((x + y / 8 * 8) % 16 < 8)
{
pixels[y * width + x] = 0xFF666666;
}
else
{
pixels[y * width + x] = 0xFFEEEEEE;
}
}
}
}

View file

@ -7,6 +7,8 @@
#include "SharedMemory.h" #include "SharedMemory.h"
#include "WaylandBuffer.h" #include "WaylandBuffer.h"
#include "IPlatformWindow.h"
struct wl_surface; struct wl_surface;
struct xdg_surface; struct xdg_surface;
struct xdg_toplevel; struct xdg_toplevel;
@ -14,7 +16,7 @@ struct xdg_toplevel;
class WaylandEglInterface; class WaylandEglInterface;
class WaylandEglWindowInterface; class WaylandEglWindowInterface;
class WaylandSurface class WaylandSurface : public IPlatformWindow
{ {
public: public:
@ -28,9 +30,24 @@ public:
wl_buffer* drawFrame(); wl_buffer* drawFrame();
void drawCheckerboard(int width, int height, int offset); void show() const
{
map();
}
void map() const
{
}
void clear() const
{
}
private: private:
void paint(mt::Screen* screen) override;
mt::Window* mWindow{nullptr}; mt::Window* mWindow{nullptr};
wl_surface* mSurface{nullptr}; wl_surface* mSurface{nullptr};

View file

@ -9,8 +9,8 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection) XcbWindow::XcbWindow(mt::Window* window, int hwnd, xcb_connection_t* connection)
: mHandle(hwnd), : IPlatformWindow(window),
mWindow(window), mHandle(hwnd),
mBackingImage(std::make_unique<XcbImage>()), mBackingImage(std::make_unique<XcbImage>()),
mConnection(connection) mConnection(connection)
{ {
@ -58,7 +58,7 @@ void XcbWindow::show() const
map(); map();
} }
void XcbWindow::paint(mt::Screen* screen) const void XcbWindow::paint(mt::Screen* screen)
{ {
auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen()); auto xcb_screen = dynamic_cast<XcbScreen*>(screen->GetPlatformScreen());
for(const auto& layer : mWindow->GetLayers()) for(const auto& layer : mWindow->GetLayers())

View file

@ -23,17 +23,15 @@ public:
void show() const override; void show() const override;
void paint(mt::Screen* screen) const override; void paint(mt::Screen* screen) override;
void clear() const override; void clear() const override;
void map() const override; void map() const override;
private: private:
int mHandle{-1}; int mHandle{-1};
unsigned mGraphicsContext {0}; unsigned mGraphicsContext {0};
mt::Window* mWindow{nullptr};
xcb_connection_t* mConnection{nullptr}; xcb_connection_t* mConnection{nullptr};
std::unique_ptr<XcbImage> mBackingImage; std::unique_ptr<XcbImage> mBackingImage;
}; };