Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ build/
Build/
build-*/

# Output directories
output/

# CMake generated files
CMakeFiles/
CMakeCache.txt
Expand Down
13 changes: 2 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ add_library(image_engine_core STATIC
src/ops/rotate.cpp
src/executor.cpp
src/image.cpp
src/load_image.cpp
)

add_library(image_engine_sfml STATIC
src/display_image.cpp
src/image_io.cpp
)

target_include_directories(image_engine_core PUBLIC
Expand All @@ -30,22 +26,17 @@ target_include_directories(image_engine_core PUBLIC

add_sycl_to_target(TARGET image_engine_core)

target_link_libraries(image_engine_sfml PRIVATE
target_link_libraries(image_engine_core PRIVATE
sfml-graphics sfml-window sfml-system
)

target_include_directories(image_engine_sfml PUBLIC
${CMAKE_SOURCE_DIR}/include
)

add_executable(image-engine
src/main.cpp
src/engine_logic.cpp
)

target_link_libraries(image-engine PRIVATE
image_engine_core
image_engine_sfml
)

add_subdirectory(tests)
5 changes: 0 additions & 5 deletions include/display_image.h

This file was deleted.

16 changes: 10 additions & 6 deletions include/executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@ class Executor {
~Executor();

template <typename OpType>
void execute(Image &img, OpType op) {
Image execute(Image &img, OpType op) {
Image out;

if (type == Device::NATIVE_CPU) {
op.apply_native(img);
op.apply_native(img, out);

} else if (type == Device::COMPARE) {
op.apply_native(img);
op.apply_kernel(img, q);
op.apply_kernel(img, q_s);
op.apply_native(img, out);
op.apply_kernel(img, q, out);
op.apply_kernel(img, q_s, out);

} else {
op.apply_kernel(img, q);
op.apply_kernel(img, q, out);
}

return out;
}

private:
Expand Down
9 changes: 9 additions & 0 deletions include/image_io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include <SFML/Graphics.hpp>
#include "image.h"
#include <string>

void display_image(const Image &img);
Image load_image(const std::string &filepath);
void save_image(const std::string &path, const Image &img);
5 changes: 0 additions & 5 deletions include/load_image.h

This file was deleted.

16 changes: 8 additions & 8 deletions include/ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class CropOp {

CropOp(int x, int y, int w, int h) : crop_x(x), crop_y(y), crop_w(w), crop_h(h) {}

void apply_native(Image &img);
void apply_kernel(Image &img, sycl::queue &q);
void apply_native(Image &img, Image &img_out);
void apply_kernel(Image &img, sycl::queue &q, Image &img_out);
};

class BlurOp {
Expand All @@ -23,8 +23,8 @@ class BlurOp {

BlurOp(int p) : percentage(p) {}

void apply_native(Image &img);
void apply_kernel(Image &img, sycl::queue &q);
void apply_native(Image &img, Image &img_out);
void apply_kernel(Image &img, sycl::queue &q, Image &img_out);
};

class RotateOp {
Expand All @@ -33,8 +33,8 @@ class RotateOp {

RotateOp(int a) : angle(a) {}

void apply_native(Image &img);
void apply_kernel(Image &img, sycl::queue &q);
void apply_native(Image &img_in, Image &img_out);
void apply_kernel(Image &img_in, sycl::queue &q, Image &img_out);
};

class ConvolutionOp {
Expand All @@ -60,6 +60,6 @@ class ConvolutionOp {
}
}

void apply_native(Image &img);
void apply_kernel(Image &img, sycl::queue &q);
void apply_native(Image &img, Image &img_out);
void apply_kernel(Image &img, sycl::queue &q, Image &img_out);
};
38 changes: 0 additions & 38 deletions src/display_image.cpp

This file was deleted.

17 changes: 9 additions & 8 deletions src/engine_logic.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#include "engine_config.h"
#include "image.h"
#include "load_image.h"
#include "display_image.h"
#include "image_io.h"
#include "ops.h"
#include "executor.h"
#include "types.h"
#include <print>

void setup_cli(CLI::App &app, AppContext &ctx) {
app.require_subcommand(1);
Expand Down Expand Up @@ -38,18 +36,21 @@ void run_operations(const AppContext &ctx) {

Executor myExe(ctx.type);
Image img = load_image(ctx.filepath);
Image out;
std::string path = "/home/emi/projects/image-engine/output/output.png";

display_image(img);

if (ctx.crop_cmd->parsed()) {
myExe.execute(img, CropOp(ctx.cx, ctx.cy, ctx.cw, ctx.ch));
out = myExe.execute(img, CropOp(ctx.cx, ctx.cy, ctx.cw, ctx.ch));
} else if (ctx.blur_cmd->parsed()) {
myExe.execute(img, BlurOp(ctx.blur_percentage));
out = myExe.execute(img, BlurOp(ctx.blur_percentage));
} else if (ctx.rotate_cmd->parsed()) {
myExe.execute(img, RotateOp(ctx.rotate_angle));
out = myExe.execute(img, RotateOp(ctx.rotate_angle));
} else if (ctx.conv_cmd->parsed()) {
myExe.execute(img, ConvolutionOp(kernel));
out = myExe.execute(img, ConvolutionOp(kernel));
}

display_image(img);
display_image(out);
save_image(path, out);
}
81 changes: 81 additions & 0 deletions src/image_io.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#define STB_IMAGE_IMPLEMENTATION

#include "image.h"
#include "image_io.h"
#include <stb_image.h>
#include <print>
#include <stdexcept>
#include <string>
#include <filesystem>

void display_image(const Image &img) {
sf::ContextSettings settings;
settings.antialiasingLevel = 0;

// Create SFML window
sf::RenderWindow window(sf::VideoMode(800, 600), "Image Viewer", sf::Style::Default, settings);

window.setVerticalSyncEnabled(false);

// Create SFML texture from your LoadedImage
sf::Texture texture;
texture.create(img.width, img.height);
texture.update(img.pixels.data());

sf::Sprite sprite(texture);

while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
}

window.clear(sf::Color::Black);
// Center the sprite in the window
sf::Vector2u winSize = window.getSize();
sf::Vector2u imgSize = texture.getSize();

sprite.setPosition((winSize.x - imgSize.x) * 0.5f, (winSize.y - imgSize.y) * 0.5f);

window.draw(sprite);
window.display();
}
}

Image load_image(const std::string &filepath) {
Image img;

// force RGBA
unsigned char *data = stbi_load(filepath.c_str(), &img.width, &img.height, &img.channels, 4);

// stbi function for throwing the full error
if (!data) {
std::print("Full error: {}\n", stbi_failure_reason());
throw std::runtime_error("Failed to load image: " + filepath);
}

img.channels = 4;
img.pixels.assign(data, data + img.width * img.height * img.channels);

stbi_image_free(data);
return img;
}

void save_image(const std::string &filepath, const Image &img) {
if (img.pixels.empty() || img.width <= 0 || img.height <= 0) {
throw std::runtime_error("Empty image, abort!");
}

std::filesystem::path path(filepath);
if (path.has_parent_path()) {
std::filesystem::create_directories(path.parent_path());
}

sf::Image sfml_img;
sfml_img.create(img.width, img.height, img.pixels.data());

if (!sfml_img.saveToFile(filepath)) {
throw std::runtime_error("Saving error in: " + filepath);
}
}
25 changes: 0 additions & 25 deletions src/load_image.cpp

This file was deleted.

Loading