From: Lukas Jiriste Date: Thu, 4 Apr 2024 08:43:55 +0000 (+0200) Subject: Refactor main.c to comply with the 42 Norm X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=4341b648fd371487585656862b5e4499bd5cc67f;p=Digiteq.git Refactor main.c to comply with the 42 Norm --- diff --git a/solution/Makefile b/solution/Makefile index f32afbb..ae4ce4f 100644 --- a/solution/Makefile +++ b/solution/Makefile @@ -14,7 +14,14 @@ LIBSFLAGS := -L/usr/lib -lXext -lX11 -lm -lbsd -LLibft -lft -ljpeg SRCDIR := . -SOURCES := main.c \ +SOURCES := main.c \ + color.c \ + jpeg_handling.c \ + images.c \ + mlx_addition.c \ + event_handling.c \ + convolution.c \ + cleanup.c \ SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES)) diff --git a/solution/cleanup.c b/solution/cleanup.c new file mode 100644 index 0000000..8703b0a --- /dev/null +++ b/solution/cleanup.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* cleanup.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:24:04 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:26:04 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" +#include "libft.h" +#include +#include + +int mlx_close_win(t_mlx_session *s) +{ + mlx_destroy_window(s->mlx, s->mlx_win); + s->mlx_win = NULL; + return (0); +} + +static void free_session(t_mlx_session *s) +{ + mlx_destroy_display(s->mlx); + free(s->mlx); + return ; +} + +void cleanup(t_state *state) +{ + if (state->graph.background.img) + mlx_destroy_image(state->graph.mlx_ses.mlx, + state->graph.background.img); + if (state->graph.red_frame.img) + mlx_destroy_image(state->graph.mlx_ses.mlx, + state->graph.red_frame.img); + if (state->graph.green_frame.img) + mlx_destroy_image(state->graph.mlx_ses.mlx, + state->graph.green_frame.img); + if (state->graph.emoji.img) + mlx_destroy_image(state->graph.mlx_ses.mlx, state->graph.emoji.img); + display_trans_img(&state->graph.mlx_ses, NULL, 0, 0); + ft_vec_free(&state->found, NULL); + free_session(&state->graph.mlx_ses); + return ; +} diff --git a/solution/color.c b/solution/color.c new file mode 100644 index 0000000..7a335db --- /dev/null +++ b/solution/color.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* color.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:16:25 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:18:07 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" + +t_argb uint_to_argb(unsigned int uint_color) +{ + t_argb res; + + res.a = uint_color >> (8 * 3); + res.r = uint_color >> (8 * 2); + res.g = uint_color >> (8 * 1); + res.b = uint_color >> (8 * 0); + return (res); +} + +unsigned int argb_to_uint(t_argb color) +{ + unsigned int res; + + res = 0; + res |= color.a << (8 * 3); + res |= color.r << (8 * 2); + res |= color.g << (8 * 1); + res |= color.b << (8 * 0); + return (res); +} + +// This function probably could do the arithmetic in uint form +// but this way it is more legible I think +unsigned int mix_colors(unsigned int back_uint, unsigned int front_uint) +{ + t_argb back; + t_argb front; + t_argb res; + + back = uint_to_argb(back_uint); + front = uint_to_argb(front_uint); + res.a = front.a - (255 - back.a) * front.a / 255; + res.r = (front.r * (255 - front.a) + + back.r * (255 - back.a) * front.a / 255) / (255 - res.a); + res.g = (front.g * (255 - front.a) + + back.g * (255 - back.a) * front.a / 255) / (255 - res.a); + res.b = (front.b * (255 - front.a) + + back.b * (255 - back.a) * front.a / 255) / (255 - res.a); + return (argb_to_uint(res)); +} diff --git a/solution/convolution.c b/solution/convolution.c new file mode 100644 index 0000000..10f9693 --- /dev/null +++ b/solution/convolution.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* convolution.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:19:26 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:38:58 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" + +static unsigned int sqr_diff(unsigned char a, unsigned char b) +{ + if (a > b) + return ((a - b) * (a - b)); + else + return ((b - a) * (b - a)); +} + +static unsigned int uint_color_sqr_diff(unsigned int uint_color1, + unsigned int uint_color2) +{ + t_argb color1; + t_argb color2; + unsigned int res; + + color1 = uint_to_argb(uint_color1); + color2 = uint_to_argb(uint_color2); + res = 0; + res += sqr_diff(color1.r, color2.r) / 255 + * (255 - color1.a) * (255 - color2.a) / 255; + res += sqr_diff(color1.g, color2.g) / 255 + * (255 - color1.a) * (255 - color2.a) / 255; + res += sqr_diff(color1.b, color2.b) / 255 + * (255 - color1.a) * (255 - color2.a) / 255; + return (res); +} + +int emoji_encountered(t_mlx_data *background, t_mlx_data *emoji, int x, int y) +{ + int i; + int j; + unsigned int *pix_emoji; + unsigned int *pix_back; + unsigned int sqr_diff; + + sqr_diff = 0; + i = 0; + while (i < emoji->width) + { + j = 0; + while (j < emoji->height) + { + pix_emoji = get_mlx_pixel(emoji, i, j); + pix_back = get_mlx_pixel(background, x + i, y + j); + sqr_diff += uint_color_sqr_diff(*pix_emoji, *pix_back); + ++j; + } + ++i; + } + sqr_diff /= emoji->width * emoji->height; + return (sqr_diff < EMOJI_TRESHOLD); +} diff --git a/solution/digiteq.h b/solution/digiteq.h new file mode 100644 index 0000000..01d7719 --- /dev/null +++ b/solution/digiteq.h @@ -0,0 +1,90 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* digiteq.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:14:39 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:36:18 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef DIGITEQ_H +# define DIGITEQ_H + +# include "libft.h" + +# define EMOJI_TRESHOLD 255 +# define FRAME_THICKNESS 2 + +typedef struct s_mlx_session +{ + void *mlx; + void *mlx_win; +} t_mlx_session; + +typedef struct s_mlx_data +{ + void *img; + char *addr; + int bits_per_pixel; + int line_length; + int endian; + int width; + int height; +} t_mlx_data; + +typedef struct s_graphics +{ + t_mlx_session mlx_ses; + t_mlx_data background; + t_mlx_data red_frame; + t_mlx_data green_frame; + t_mlx_data emoji; +} t_graphics; + +typedef struct s_position +{ + int x; + int y; +} t_position; + +typedef struct s_state +{ + t_graphics graph; + t_position pos; + t_vec found; +} t_state; + +typedef struct s_argb +{ + unsigned char a; + unsigned char r; + unsigned char g; + unsigned char b; +} t_argb; + +t_argb uint_to_argb(unsigned int uint_color); +unsigned int argb_to_uint(t_argb color); +unsigned int mix_colors(unsigned int back_uint, unsigned int front_uint); + +int emoji_encountered(t_mlx_data *background, t_mlx_data *emoji, + int x, int y); + +void *mlx_jpeg_file_to_image(void *mlx_ptr, char *filename, + int *width, int *height); + +int mlx_close_win(t_mlx_session *s); +void cleanup(t_state *state); + +unsigned int *get_mlx_pixel(t_mlx_data *img, int x, int y); +int display_trans_img(t_mlx_session *s, t_mlx_data *img, + int x, int y); + +int open_images(t_graphics *graphics, char **argv); + +int mlx_handle_key_press(int keycode, t_mlx_session *s); +int no_event_handle(t_state *state); + +#endif //DIGITEQ_H diff --git a/solution/event_handling.c b/solution/event_handling.c new file mode 100644 index 0000000..6a0c408 --- /dev/null +++ b/solution/event_handling.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* event_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:31:51 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:38:04 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" +#include +#include + +int mlx_handle_key_press(int keycode, t_mlx_session *s) +{ + if (keycode == XK_Escape) + mlx_close_win(s); + return (0); +} + +static void print_green_frames(t_state *state) +{ + t_position pos; + size_t i; + + i = 0; + while (i < state->found.size) + { + pos = *(t_position *)ft_vec_access(&state->found, i); + display_trans_img(&state->graph.mlx_ses, + &state->graph.green_frame, pos.x, pos.y); + ++i; + } + return ; +} + +static void record_found(t_vec *found, t_position pos) +{ + ft_vec_append(found, &pos); + ft_printf("Target at (%4i, %4i).\n", pos.x, pos.y); + return ; +} + +int no_event_handle(t_state *state) +{ + t_graphics *const g = &state->graph; + + if (!g->mlx_ses.mlx_win) + return (0); + if (state->pos.x + g->emoji.width > g->background.width) + { + state->pos.x = 0; + ++state->pos.y; + } + if (state->pos.y + g->emoji.height <= g->background.height) + { + display_trans_img(&g->mlx_ses, &g->background, 0, 0); + print_green_frames(state); + display_trans_img(&g->mlx_ses, &g->red_frame, + state->pos.x, state->pos.y); + if (emoji_encountered(&g->background, &g->emoji, + state->pos.x, state->pos.y)) + record_found(&state->found, state->pos); + ++state->pos.x; + } + else + mlx_close_win(&g->mlx_ses); + return (0); +} diff --git a/solution/images.c b/solution/images.c new file mode 100644 index 0000000..b274d4a --- /dev/null +++ b/solution/images.c @@ -0,0 +1,87 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* images.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:29:22 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:31:33 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" +#include + +static void set_addresses(t_graphics *graphics) +{ + graphics->background.addr = mlx_get_data_addr(graphics->background.img, + &graphics->background.bits_per_pixel, + &graphics->background.line_length, &graphics->background.endian); + graphics->emoji.addr = mlx_get_data_addr(graphics->emoji.img, + &graphics->emoji.bits_per_pixel, + &graphics->emoji.line_length, &graphics->emoji.endian); + return ; +} + +static void fill_frame(t_mlx_data *frame, unsigned int color) +{ + unsigned int *pix; + int x; + int y; + + x = 0; + while (x < frame->width) + { + y = 0; + while (y < frame->height) + { + pix = get_mlx_pixel(frame, x, y); + if (x < FRAME_THICKNESS || y < FRAME_THICKNESS + || frame->width - x <= FRAME_THICKNESS + || frame->height - y <= FRAME_THICKNESS) + *pix = color; + else + *pix = 0xFFFFFFFF; + ++y; + } + ++x; + } + return ; +} + +static t_mlx_data create_frame_img(void *mlx_ptr, + int width, int height, unsigned int color) +{ + t_mlx_data frame; + + frame.img = mlx_new_image(mlx_ptr, width, height); + if (!frame.img) + return (frame); + frame.width = width; + frame.height = height; + frame.addr = mlx_get_data_addr(frame.img, &frame.bits_per_pixel, + &frame.line_length, &frame.endian); + fill_frame(&frame, color); + return (frame); +} + +int open_images(t_graphics *graphics, char **argv) +{ + int res; + + graphics->background.img = mlx_jpeg_file_to_image(graphics->mlx_ses.mlx, + argv[1], &graphics->background.width, + &graphics->background.height); + graphics->emoji.img = mlx_xpm_file_to_image(graphics->mlx_ses.mlx, + "emoji.xpm", &graphics->emoji.width, &graphics->emoji.height); + graphics->red_frame = create_frame_img(graphics->mlx_ses.mlx, + graphics->emoji.width, graphics->emoji.height, 0x80FF0000); + graphics->green_frame = create_frame_img(graphics->mlx_ses.mlx, + graphics->emoji.width, graphics->emoji.height, 0x8000FF00); + res = graphics->background.img && graphics->red_frame.img + && graphics->green_frame.img && graphics->emoji.img; + if (res) + set_addresses(graphics); + return (!res); +} diff --git a/solution/jpeg_handling.c b/solution/jpeg_handling.c new file mode 100644 index 0000000..6529938 --- /dev/null +++ b/solution/jpeg_handling.c @@ -0,0 +1,94 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* jpeg_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:21:40 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:36:49 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" +#include +#include + +#include +#include + +static void decompress_to_image(struct jpeg_decompress_struct *cinfo, + t_mlx_data *img, void *mlx_ptr) +{ + char *dst; + + img->img = mlx_new_image(mlx_ptr, cinfo->output_width, + cinfo->output_height); + img->addr = mlx_get_data_addr(img->img, &img->bits_per_pixel, + &img->line_length, &img->endian); + img->width = cinfo->output_width; + img->height = cinfo->output_height; + dst = img->addr; + while (cinfo->output_scanline < cinfo->output_height) + { + jpeg_read_scanlines(cinfo, (JSAMPROW *)&dst, 1); + dst += img->line_length; + } + return ; +} + +static void flip_alpha(t_mlx_data *img) +{ + unsigned int *pixel; + int x; + int y; + t_argb color; + + x = 0; + while (x < img->width) + { + y = 0; + while (y < img->height) + { + pixel = get_mlx_pixel(img, x, y); + color = uint_to_argb(*pixel); + color.a = 255 - color.a; + *pixel = argb_to_uint(color); + ++y; + } + ++x; + } + return ; +} + +// This function is written as to have +// the same signature as mlx_png_file_to_image +void *mlx_jpeg_file_to_image(void *mlx_ptr, char *filename, + int *width, int *height) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE *source; + t_mlx_data img; + + source = fopen(filename, "rb"); + if (!source) + { + ft_dprintf(STDERR_FILENO, "Can't open %s\n", filename); + return (NULL); + } + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, source); + jpeg_read_header(&cinfo, TRUE); + cinfo.out_color_space = JCS_EXT_BGRA; + jpeg_start_decompress(&cinfo); + *width = cinfo.output_width; + *height = cinfo.output_height; + decompress_to_image(&cinfo, &img, mlx_ptr); + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(source); + flip_alpha(&img); + return (img.img); +} diff --git a/solution/main.c b/solution/main.c index 8144fc1..9443465 100644 --- a/solution/main.c +++ b/solution/main.c @@ -6,464 +6,14 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/02 08:44:53 by ljiriste #+# #+# */ -/* Updated: 2024/04/04 10:13:23 by ljiriste ### ########.fr */ +/* Updated: 2024/04/04 10:38:20 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ +#include "digiteq.h" #include "libft.h" #include -#include -#include #include -#include -#include - -#include -#include - -#define EMOJI_TRESHOLD 255 -#define FRAME_THICKNESS 2 - -typedef struct s_mlx_session -{ - void *mlx; - void *mlx_win; -} t_mlx_session; - -typedef struct s_mlx_data -{ - void *img; - char *addr; - int bits_per_pixel; - int line_length; - int endian; - int width; - int height; -} t_mlx_data; - -typedef struct s_graphics -{ - t_mlx_session mlx_ses; - t_mlx_data background; - t_mlx_data red_frame; - t_mlx_data green_frame; - t_mlx_data emoji; -} t_graphics; - -typedef struct s_position -{ - int x; - int y; -} t_position; - -typedef struct s_state -{ - t_graphics graph; - t_position pos; - t_vec found; -} t_state; - -unsigned int *get_mlx_pixel(t_mlx_data *img, int x, int y) -{ - char *res; - - res = img->addr + y * img->line_length + x * img->bits_per_pixel / CHAR_BIT; - return ((unsigned int *)res); -} - -void decompress_to_image(struct jpeg_decompress_struct *cinfo, - t_mlx_data *img, void *mlx_ptr) -{ - char *dst; - - img->img = mlx_new_image(mlx_ptr, cinfo->output_width, - cinfo->output_height); - img->addr = mlx_get_data_addr(img->img, &img->bits_per_pixel, - &img->line_length, &img->endian); - img->width = cinfo->output_width; - img->height = cinfo->output_height; - dst = img->addr; - while (cinfo->output_scanline < cinfo->output_height) - { - jpeg_read_scanlines(cinfo, (JSAMPROW *)&dst, 1); - dst += img->line_length; - } - return ; -} - -typedef struct s_argb -{ - unsigned char a; - unsigned char r; - unsigned char g; - unsigned char b; -} t_argb; - -t_argb uint_to_argb(unsigned int uint_color) -{ - t_argb res; - - res.a = uint_color >> (8 * 3); - res.r = uint_color >> (8 * 2); - res.g = uint_color >> (8 * 1); - res.b = uint_color >> (8 * 0); - return (res); -} - -unsigned int argb_to_uint(t_argb color) -{ - unsigned int res; - - res = 0; - res |= color.a << (8 * 3); - res |= color.r << (8 * 2); - res |= color.g << (8 * 1); - res |= color.b << (8 * 0); - return (res); -} - -void flip_alpha(t_mlx_data *img) -{ - unsigned int *pixel; - int x; - int y; - t_argb color; - - x = 0; - while (x < img->width) - { - y = 0; - while (y < img->height) - { - pixel = get_mlx_pixel(img, x, y); - color = uint_to_argb(*pixel); - color.a = 255 - color.a; - *pixel = argb_to_uint(color); - ++y; - } - ++x; - } - return ; -} - -// This function is written as to have -// the same signature as mlx_png_file_to_image -void *mlx_jpeg_file_to_image(void *mlx_ptr, char *filename, - int *width, int *height) -{ - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - FILE *source; - t_mlx_data img; - - source = fopen(filename, "rb"); - if (!source) - { - ft_dprintf(STDERR_FILENO, "Can't open %s\n", filename); - return (NULL); - } - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, source); - jpeg_read_header(&cinfo, TRUE); - cinfo.out_color_space = JCS_EXT_BGRA; - jpeg_start_decompress(&cinfo); - *width = cinfo.output_width; - *height = cinfo.output_height; - decompress_to_image(&cinfo, &img, mlx_ptr); - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - fclose(source); - flip_alpha(&img); - return (img.img); -} - -// This function probably could do the arithmetic in uint form -// but this way it is more legible I think -unsigned int mix_colors(unsigned int back_uint, unsigned int front_uint) -{ - t_argb back; - t_argb front; - t_argb res; - - back = uint_to_argb(back_uint); - front = uint_to_argb(front_uint); - res.a = front.a - (255 - back.a) * front.a / 255; - res.r = (front.r * (255 - front.a) - + back.r * (255 - back.a) * front.a / 255) / (255 - res.a); - res.g = (front.g * (255 - front.a) - + back.g * (255 - back.a) * front.a / 255) / (255 - res.a); - res.b = (front.b * (255 - front.a) - + back.b * (255 - back.a) * front.a / 255) / (255 - res.a); - return (argb_to_uint(res)); -} - -void copy_image(t_mlx_data *dest, t_mlx_data *src, int x, int y) -{ - unsigned int *dest_pix; - unsigned int *src_pix; - int i; - int j; - - i = 0; - while (i + x < dest->width && i < src->width) - { - j = 0; - while (j + y < dest->height && j < src->height) - { - dest_pix = get_mlx_pixel(dest, x + i, y + j); - src_pix = get_mlx_pixel(src, i, j); - *dest_pix = mix_colors(*dest_pix, - *src_pix); - ++j; - } - ++i; - } - return ; -} - -// First use has to be with the largest picture, as that initializes the image -int display_trans_img(t_mlx_session *s, t_mlx_data *img, - int x, int y) -{ - static t_mlx_data to_print; - - if (!s->mlx_win) - { - mlx_destroy_image(s->mlx, to_print.img); - return (0); - } - if (!to_print.img) - { - to_print.img = mlx_new_image(s->mlx, img->width, img->height); - if (!to_print.img) - return (1); - to_print.addr = mlx_get_data_addr(to_print.img, - &to_print.bits_per_pixel, &to_print.line_length, - &to_print.endian); - to_print.width = img->width; - to_print.height = img->height; - } - copy_image(&to_print, img, x, y); - mlx_put_image_to_window(s->mlx, s->mlx_win, to_print.img, 0, 0); - return (0); -} - -int mlx_close_win(t_mlx_session *s) -{ - mlx_destroy_window(s->mlx, s->mlx_win); - s->mlx_win = NULL; - return (0); -} - -void free_session(t_mlx_session *s) -{ - mlx_destroy_display(s->mlx); - free(s->mlx); - return ; -} - -void cleanup(t_state *state) -{ - if (state->graph.background.img) - mlx_destroy_image(state->graph.mlx_ses.mlx, - state->graph.background.img); - if (state->graph.red_frame.img) - mlx_destroy_image(state->graph.mlx_ses.mlx, - state->graph.red_frame.img); - if (state->graph.green_frame.img) - mlx_destroy_image(state->graph.mlx_ses.mlx, - state->graph.green_frame.img); - if (state->graph.emoji.img) - mlx_destroy_image(state->graph.mlx_ses.mlx, state->graph.emoji.img); - display_trans_img(&state->graph.mlx_ses, NULL, 0, 0); - ft_vec_free(&state->found, NULL); - free_session(&state->graph.mlx_ses); - return ; -} - -int mlx_handle_key_press(int keycode, t_mlx_session *s) -{ - if (keycode == XK_Escape) - mlx_close_win(s); - return (0); -} - -unsigned int sqr_diff(unsigned char a, unsigned char b) -{ - if (a > b) - return ((a - b) * (a - b)); - else - return ((b - a) * (b - a)); -} - -unsigned int uint_color_sqr_diff(unsigned int uint_color1, - unsigned int uint_color2) -{ - t_argb color1; - t_argb color2; - unsigned int res; - - color1 = uint_to_argb(uint_color1); - color2 = uint_to_argb(uint_color2); - res = 0; - res += sqr_diff(color1.r, color2.r) / 255 - * (255 - color1.a) * (255 - color2.a) / 255; - res += sqr_diff(color1.g, color2.g) / 255 - * (255 - color1.a) * (255 - color2.a) / 255; - res += sqr_diff(color1.b, color2.b) / 255 - * (255 - color1.a) * (255 - color2.a) / 255; - return (res); -} - -int emoji_encountered(t_mlx_data *background, t_mlx_data *emoji, int x, int y) -{ - int i; - int j; - unsigned int *pix_emoji; - unsigned int *pix_back; - unsigned int sqr_diff; - - sqr_diff = 0; - i = 0; - while (i < emoji->width) - { - j = 0; - while (j < emoji->height) - { - pix_emoji = get_mlx_pixel(emoji, i, j); - pix_back = get_mlx_pixel(background, x + i, y + j); - sqr_diff += uint_color_sqr_diff(*pix_emoji, *pix_back); - ++j; - } - ++i; - } - sqr_diff /= emoji->width * emoji->height; - return (sqr_diff < EMOJI_TRESHOLD); -} - -void print_green_frames(t_state *state) -{ - t_position pos; - size_t i; - - i = 0; - while (i < state->found.size) - { - pos = *(t_position *)ft_vec_access(&state->found, i); - display_trans_img(&state->graph.mlx_ses, - &state->graph.green_frame, pos.x, pos.y); - ++i; - } - return ; -} - -void record_found(t_vec *found, t_position pos) -{ - ft_vec_append(found, &pos); - ft_printf("Target at (%4i, %4i).\n", pos.x, pos.y); - return ; -} - -int no_event_handle(t_state *state) -{ - t_graphics *const g = &state->graph; - - if (!g->mlx_ses.mlx_win) - return (0); - if (state->pos.x + g->emoji.width > g->background.width) - { - state->pos.x = 0; - ++state->pos.y; - } - if (state->pos.y + g->emoji.height <= g->background.height) - { - display_trans_img(&g->mlx_ses, &g->background, 0, 0); - print_green_frames(state); - display_trans_img(&g->mlx_ses, &g->red_frame, - state->pos.x, state->pos.y); - if (emoji_encountered(&g->background, &g->emoji, - state->pos.x, state->pos.y)) - record_found(&state->found, state->pos); - ++state->pos.x; - } - else - mlx_close_win(&g->mlx_ses); - return (0); -} - -void set_addresses(t_graphics *graphics) -{ - graphics->background.addr = mlx_get_data_addr(graphics->background.img, - &graphics->background.bits_per_pixel, - &graphics->background.line_length, &graphics->background.endian); - graphics->emoji.addr = mlx_get_data_addr(graphics->emoji.img, - &graphics->emoji.bits_per_pixel, - &graphics->emoji.line_length, &graphics->emoji.endian); - return ; -} - -void fill_frame(t_mlx_data *frame, unsigned int color) -{ - unsigned int *pix; - int x; - int y; - - x = 0; - while (x < frame->width) - { - y = 0; - while (y < frame->height) - { - pix = get_mlx_pixel(frame, x, y); - if (x < FRAME_THICKNESS || y < FRAME_THICKNESS - || frame->width - x <= FRAME_THICKNESS - || frame->height - y <= FRAME_THICKNESS) - *pix = color; - else - *pix = 0xFFFFFFFF; - ++y; - } - ++x; - } - return ; -} - -t_mlx_data create_frame_img(void *mlx_ptr, - int width, int height, unsigned int color) -{ - t_mlx_data frame; - - frame.img = mlx_new_image(mlx_ptr, width, height); - if (!frame.img) - return (frame); - frame.width = width; - frame.height = height; - frame.addr = mlx_get_data_addr(frame.img, &frame.bits_per_pixel, - &frame.line_length, &frame.endian); - fill_frame(&frame, color); - return (frame); -} - -int open_images(t_graphics *graphics, char **argv) -{ - int res; - - graphics->background.img = mlx_jpeg_file_to_image(graphics->mlx_ses.mlx, - argv[1], &graphics->background.width, - &graphics->background.height); - graphics->emoji.img = mlx_xpm_file_to_image(graphics->mlx_ses.mlx, - "emoji.xpm", &graphics->emoji.width, &graphics->emoji.height); - graphics->red_frame = create_frame_img(graphics->mlx_ses.mlx, - graphics->emoji.width, graphics->emoji.height, 0x80FF0000); - graphics->green_frame = create_frame_img(graphics->mlx_ses.mlx, - graphics->emoji.width, graphics->emoji.height, 0x8000FF00); - res = graphics->background.img && graphics->red_frame.img - && graphics->green_frame.img && graphics->emoji.img; - if (res) - set_addresses(graphics); - return (!res); -} int init_state(t_state *state) { diff --git a/solution/mlx_addition.c b/solution/mlx_addition.c new file mode 100644 index 0000000..2642c25 --- /dev/null +++ b/solution/mlx_addition.c @@ -0,0 +1,74 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* mlx_addition.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/04 10:27:01 by ljiriste #+# #+# */ +/* Updated: 2024/04/04 10:37:03 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "digiteq.h" +#include +#include + +unsigned int *get_mlx_pixel(t_mlx_data *img, int x, int y) +{ + char *res; + + res = img->addr + y * img->line_length + x * img->bits_per_pixel / CHAR_BIT; + return ((unsigned int *)res); +} + +static void copy_image(t_mlx_data *dest, t_mlx_data *src, int x, int y) +{ + unsigned int *dest_pix; + unsigned int *src_pix; + int i; + int j; + + i = 0; + while (i + x < dest->width && i < src->width) + { + j = 0; + while (j + y < dest->height && j < src->height) + { + dest_pix = get_mlx_pixel(dest, x + i, y + j); + src_pix = get_mlx_pixel(src, i, j); + *dest_pix = mix_colors(*dest_pix, + *src_pix); + ++j; + } + ++i; + } + return ; +} + +// First use has to be with the largest picture, as that initializes the image +int display_trans_img(t_mlx_session *s, t_mlx_data *img, + int x, int y) +{ + static t_mlx_data to_print; + + if (!s->mlx_win) + { + mlx_destroy_image(s->mlx, to_print.img); + return (0); + } + if (!to_print.img) + { + to_print.img = mlx_new_image(s->mlx, img->width, img->height); + if (!to_print.img) + return (1); + to_print.addr = mlx_get_data_addr(to_print.img, + &to_print.bits_per_pixel, &to_print.line_length, + &to_print.endian); + to_print.width = img->width; + to_print.height = img->height; + } + copy_image(&to_print, img, x, y); + mlx_put_image_to_window(s->mlx, s->mlx_win, to_print.img, 0, 0); + return (0); +}