From 83e6ebb430c84cf4c77fc27b80fae04caebf8b98 Mon Sep 17 00:00:00 2001 From: kbz_8 Date: Wed, 5 Apr 2023 01:11:49 +0200 Subject: [PATCH] working on xpm support --- Makefile | 4 +- README.md | 3 +- includes/mlx.h | 9 +++-- src/core/application.cpp | 83 ++++++++++++++++++++++++++++++++++++-- src/core/application.h | 7 +++- src/core/bridge.cpp | 10 ++++- src/renderer/pixel_put.cpp | 2 +- src/utils/xpm_reader.h | 64 ----------------------------- test/main.c | 8 ++-- test/run.sh | 2 +- 10 files changed, 110 insertions(+), 82 deletions(-) delete mode 100644 src/utils/xpm_reader.h diff --git a/Makefile b/Makefile index 4ac0111..a0bd7d7 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: maldavid +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2022/10/04 16:43:41 by maldavid #+# #+# # -# Updated: 2023/04/04 13:09:06 by maldavid ### ########.fr # +# Updated: 2023/04/04 16:21:17 by maldavid ### ########.fr # # # # **************************************************************************** # @@ -29,7 +29,7 @@ ifeq ($(TOOLCHAIN), gcc) endif CXXFLAGS = -std=c++17 -O3 -fPIC -INCLUDES = -I./includes -I./src -I./third_party -I/nfs/homes/maldavid/.xmake/packages/l/libsdl/2.26.4/8dfbcb8049e744a597cd5333e1b399cd/include +INCLUDES = -I./includes -I./src -I./third_party ifeq ($(DEBUG), true) CXXFLAGS += -g diff --git a/README.md b/README.md index d1ad42e..771cf72 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ For Arch based distros 3. Compile your project +If you didn't disable Xpm support you'll have to link `libXpm`. You can remove it if you used `#define MLX_NO_XPM` before including `mlx.h` ```bash -clang myApp.c MacroLibX/libmlx.so -lSDL2 +clang myApp.c MacroLibX/libmlx.so -lSDL2 -lXpm ``` diff --git a/includes/mlx.h b/includes/mlx.h index 88c30c8..6ccd485 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2023/04/04 13:43:42 by maldavid ### ########.fr */ +/* Updated: 2023/04/04 20:30:48 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,8 +42,11 @@ int mlx_destroy_image(void* mlx, void* img); void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* height); void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height); void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height); -void* mlx_xpm_file_to_image(void* mlx, char* filename, int* width, int* height); -void* mlx_xpm_to_image(void* mlx, char** xpm_data, int* width, int* height); + +#ifndef MLX_NO_XPM + void* mlx_xpm_file_to_image(void* mlx, char* filename, int* width, int* height); + void* mlx_xpm_to_image(void* mlx, char** xpm_data, int* width, int* height); +#endif int mlx_clear_window(void* mlx, void* win); diff --git a/src/core/application.cpp b/src/core/application.cpp index 0fdf0fb..8bb3798 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2023/04/04 14:54:12 by maldavid ### ########.fr */ +/* Updated: 2023/04/05 01:11:36 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,14 @@ #include #include #include // for LSBFirst -#include +#include +#include + +#ifndef MLX_NO_XPM + #include +#endif + +#include namespace mlx::core { @@ -62,15 +69,85 @@ namespace mlx::core return map; } +#ifndef MLX_NO_XPM + struct SafeXpmImage: public XpmImage // included in + { + ~SafeXpmImage() { XpmFreeXpmImage(this); } + }; + void* Application::newXpmTexture(char** data, int* w, int* h) { + SafeXpmImage xpm_image; + if(XpmCreateXpmImageFromData(data, &xpm_image, nullptr) != XpmSuccess) + { + error::report(e_kind::error, "XPM reader : invalid xpm file"); + return nullptr; + } + + *w = xpm_image.width; + *h = xpm_image.height; + + std::vector formatted_data; + formatted_data.reserve((*w) * (*h) * 4); + uint32_t pixel_color; + for(int i = 0; i < *h; i++) + { + for(int j = 0, k = 0; k < *w; j += 4, k++) + { + pixel_color = -1; + for(int l = 0; l < xpm_image.ncolors; l++) + { + if(std::memcmp(xpm_image.colorTable[l].c_color, &xpm_image.data[(i * (*w)) + k], 1) == 0) + { + pixel_color = l; + break; + } + } + + if(pixel_color < xpm_image.ncolors) + { + formatted_data[(i * (*w)) + j + 0] = xpm_image.colorTable[pixel_color].m_color[0]; + formatted_data[(i * (*w)) + j + 1] = xpm_image.colorTable[pixel_color].m_color[1]; + formatted_data[(i * (*w)) + j + 2] = xpm_image.colorTable[pixel_color].m_color[1]; + formatted_data[(i * (*w)) + j + 3] = 0xFF; + } + else + { + formatted_data[(i * (*w)) + j + 0] = 0xFF; + formatted_data[(i * (*w)) + j + 1] = 0xFF; + formatted_data[(i * (*w)) + j + 2] = 0xFF; + formatted_data[(i * (*w)) + j + 3] = 0xFF; + } + } + } + std::shared_ptr texture = std::make_shared(); - texture->create(pixels.get(), width, height, VK_FORMAT_R8G8B8A8_UNORM); + texture->create(formatted_data.data(), *w, *h, VK_FORMAT_R8G8B8A8_UNORM); TextureID id = _texture_lib.addTextureToLibrary(texture); _texture_ids.push_back(id); return &_texture_ids.back(); } + void* Application::newXpmTexture(std::string filename, int* w, int* h) + { + SafeXpmImage xpm_image; + if(XpmReadFileToXpmImage(filename.c_str(), &xpm_image, nullptr) != XpmSuccess) + { + error::report(e_kind::error, "XPM reader : invalid xpm file"); + return nullptr; + } + + *w = xpm_image.width; + *h = xpm_image.height; + + std::shared_ptr texture = std::make_shared(); + texture->create(reinterpret_cast(xpm_image.data), *w, *h, VK_FORMAT_R8G8B8A8_UNORM); + TextureID id = _texture_lib.addTextureToLibrary(texture); + _texture_ids.push_back(id); + return &_texture_ids.back(); + } +#endif + void Application::destroyTexture(void* ptr) { vkDeviceWaitIdle(Render_Core::get().getDevice().get()); diff --git a/src/core/application.h b/src/core/application.h index 8e104da..aad77e6 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ -/* Updated: 2023/04/04 13:43:04 by maldavid ### ########.fr */ +/* Updated: 2023/04/04 20:53:21 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,8 @@ #include #include +#include +#include #include #include @@ -47,7 +49,10 @@ namespace mlx::core inline void pixelPut(void* win_ptr, int x, int y, int color) const noexcept; void* newTexture(int w, int h); + #ifndef MLX_NO_XPM + void* newXpmTexture(std::string filename, int* w, int* h); void* newXpmTexture(char** data, int* w, int* h); + #endif void* newStbTexture(char* file, int* w, int* h); // stb textures are format managed by stb image (png, jpg, bpm, ...) char* mapTexture(void* img_ptr, int* bits_per_pixel, int* size_line, int* endian); inline void texturePut(void* win_ptr, void* img, int x, int y); diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index 207de52..e93f5fe 100644 --- a/src/core/bridge.cpp +++ b/src/core/bridge.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2023/04/04 13:44:12 by maldavid ### ########.fr */ +/* Updated: 2023/04/04 21:02:29 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,10 @@ #include #include +#ifndef MLX_NO_XPM + #include +#endif + extern "C" { void* mlx_init() @@ -136,15 +140,17 @@ extern "C" return static_cast(mlx)->newStbTexture(filename, width, height); } +#ifndef MLX_NO_XPM void* mlx_xpm_file_to_image(void* mlx, char* filename, int* width, int* height) { - //return static_cast(mlx)->newXpmTexture(filename, width, height); + return static_cast(mlx)->newXpmTexture(std::string(filename), width, height); } void* mlx_xpm_to_image(void* mlx, char** xpm_data, int* width, int* height) { return static_cast(mlx)->newXpmTexture(xpm_data, width, height); } +#endif int mlx_pixel_put(void* mlx, void* win, int x, int y, int color) { diff --git a/src/renderer/pixel_put.cpp b/src/renderer/pixel_put.cpp index cfed47a..c6652d4 100644 --- a/src/renderer/pixel_put.cpp +++ b/src/renderer/pixel_put.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */ -/* Updated: 2023/04/03 14:22:27 by maldavid ### ########.fr */ +/* Updated: 2023/04/05 00:28:29 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/utils/xpm_reader.h b/src/utils/xpm_reader.h deleted file mode 100644 index df98aeb..0000000 --- a/src/utils/xpm_reader.h +++ /dev/null @@ -1,64 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* xpm_reader.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maldavid +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/04/04 14:55:09 by maldavid #+# #+# */ -/* Updated: 2023/04/04 15:39:16 by maldavid ### ########.fr */ -/* */ -/* ************************************************************************** */ - -/** - * https://github.com/clckwrkbdgr/libchthon - * This xpm reader is a modified version of libchthon one - * because xmp readers are as rare as the sun in Scotland. - */ - -#ifndef __MLX_XPM_READER__ -#define __MLX_XPM_READER__ - -#include -#include -#include -#include - -namespace mlx -{ - struct XPMData - { - XPMData(); - }; - - typedef uint32_t Color; - typedef uint8_t ColorComponent; - - Color from_rgb(ColorComponent r, ColorComponent g, ColorComponent b); - uint8_t get_red(Color color); - uint8_t get_green(Color color); - uint8_t get_blue(Color color); - bool is_transparent(Color color); - Color rgb_to_argb(Color color); - - class Pixmap - { - public: - Pixmap(uint32_t w = 1, uint32_t h = 1, uint32_t palette_size = 1); - - void load(const std::vector& xpm_lines); - - Map pixels; - std::vector palette; - - private: - uint32_t _color_count; - uint32_t _row_count; - std::vector _interspaces; - std::vector _colors; - std::vector _values_interspaces; - std::vector>> _colors_interspaces; - }; -} - -#endif diff --git a/test/main.c b/test/main.c index d5064eb..932e357 100644 --- a/test/main.c +++ b/test/main.c @@ -6,14 +6,14 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2023/04/04 14:54:04 by maldavid ### ########.fr */ +/* Updated: 2023/04/04 21:41:32 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include #include "../includes/mlx.h" -static char * exemple_xpm[] = { +static char* exemple_xpm[] = { "24 20 3 1", " c None", ". c #3A32E4", @@ -102,12 +102,12 @@ int main(void) mlx.mlx = mlx_init(); mlx.win = mlx_new_window(mlx.mlx, 400, 400, "My window"); mlx.logo = mlx_png_file_to_image(mlx.mlx, "42_logo.png", &w, &h); - pic = mlx_xpm_to_image(mlx.mlx, exemple_xpm, &w, &h); - mlx_put_image_to_window(mlx.mlx, mlx.win, pic, 20, 20); mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, 0xFFFF00FF); mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo, 200, 200); img = create_image(&mlx); mlx_put_image_to_window(mlx.mlx, mlx.win, img, 200, 20); + pic = mlx_xpm_to_image(mlx.mlx, exemple_xpm, &w, &h); + mlx_put_image_to_window(mlx.mlx, mlx.win, pic, 100, 20); mlx_loop_hook(mlx.mlx, update, &mlx); mlx_loop(mlx.mlx); mlx_destroy_image(mlx.mlx, img); diff --git a/test/run.sh b/test/run.sh index 1b2a692..4975129 100755 --- a/test/run.sh +++ b/test/run.sh @@ -1 +1 @@ -clang main.c ../libmlx.so `/nfs/homes/maldavid/.xmake/packages/l/libsdl/2.26.4/8dfbcb8049e744a597cd5333e1b399cd/bin/sdl2-config --cflags --libs` -g && ./a.out +clang main.c ../libmlx.so -lSDL2 -lXpm -g && ./a.out