aboutsummaryrefslogtreecommitdiff
path: root/source/Game/Image.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-06-03 23:26:44 -0700
committerrtk0c <[email protected]>2022-06-03 23:26:44 -0700
commit60ccc62f4934e44ad5b905fdbcf458302b8d8a09 (patch)
tree02ec83cc8387abfd08bd5ee7ea4e8115f1bfb8d0 /source/Game/Image.cpp
parentc2ef7737536bf1f8c81fcfae95c0183b21c9753f (diff)
Changeset: 63 [WIP] Rename directories
Diffstat (limited to 'source/Game/Image.cpp')
-rw-r--r--source/Game/Image.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/source/Game/Image.cpp b/source/Game/Image.cpp
new file mode 100644
index 0000000..3673acc
--- /dev/null
+++ b/source/Game/Image.cpp
@@ -0,0 +1,101 @@
+#include "Image.hpp"
+
+#include <stb_image.h>
+#include <stb_rect_pack.h>
+#include <cstring>
+
+Image::Image()
+ : mSize{}
+ , mChannels{ 0 } {
+}
+
+bool Image::InitFromImageFile(const char* filePath, int desiredChannels) {
+ // Dimensions of the image in
+ int width, height;
+ // Number of channels that the image has, we'll get `desiredChannels` channels in our output (if it's non-0, which is the default argument)
+ int channels;
+
+ // NOTE: don't free, the data is passed to std::unique_ptr
+ auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, desiredChannels);
+ if (!result) {
+ return false;
+ }
+
+ mData.reset(result);
+ mSize = { width, height };
+ mChannels = desiredChannels == 0 ? channels : desiredChannels;
+ return true;
+}
+
+bool Image::InitFromImageData(std::span<uint8_t> data, int desiredChannels) {
+ int width, height;
+ int channels;
+
+ // NOTE: don't free, the data is passed to std::unique_ptr
+ auto result = (uint8_t*)stbi_load_from_memory(data.data(), data.size(), &width, &height, &channels, desiredChannels);
+ if (!result) {
+ return false;
+ }
+
+ mData.reset(result);
+ mSize = { width, height };
+ mChannels = desiredChannels == 0 ? channels : desiredChannels;
+ return true;
+}
+
+bool Image::InitFromPixels(std::span<uint8_t> pixels, glm::ivec2 dimensions, int channels) {
+ mData = std::make_unique<uint8_t[]>(pixels.size());
+ std::memcpy(mData.get(), pixels.data(), pixels.size());
+ mSize = dimensions;
+ mChannels = channels;
+ return true;
+}
+
+bool Image::InitFromPixels(std::unique_ptr<uint8_t[]> pixels, glm::ivec2 dimensions, int channels) {
+ mData = std::move(pixels);
+ mSize = dimensions;
+ mChannels = channels;
+ return true;
+}
+
+RgbaColor Image::GetPixel(int x, int y) const {
+ size_t offset = (y * mSize.x + x) * mChannels;
+ RgbaColor color;
+ color.r = mData.get()[offset + 0];
+ color.g = mData.get()[offset + 1];
+ color.b = mData.get()[offset + 2];
+ color.a = mData.get()[offset + 3];
+ return color;
+}
+
+void Image::SetPixel(int x, int y, RgbaColor color) {
+ size_t offset = (y * mSize.x + x) * mChannels;
+ mData.get()[offset + 0] = color.r;
+ mData.get()[offset + 1] = color.g;
+ mData.get()[offset + 2] = color.b;
+ mData.get()[offset + 3] = color.a;
+}
+
+uint8_t* Image::GetDataPtr() const {
+ return mData.get();
+}
+
+size_t Image::GetDataLength() const {
+ return mSize.x * mSize.y * mChannels * sizeof(uint8_t);
+}
+
+std::span<uint8_t> Image::GetData() const {
+ return { mData.get(), GetDataLength() };
+}
+
+glm::ivec2 Image::GetSize() const {
+ return mSize;
+}
+
+int Image::GetChannels() const {
+ return mChannels;
+}
+
+bool Image::IsEmpty() const {
+ return mSize.x == 0 || mSize.y == 0;
+}