Refactor main.c to comply with the 42 Norm
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 4 Apr 2024 08:43:55 +0000 (10:43 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 4 Apr 2024 08:43:55 +0000 (10:43 +0200)
solution/Makefile
solution/cleanup.c [new file with mode: 0644]
solution/color.c [new file with mode: 0644]
solution/convolution.c [new file with mode: 0644]
solution/digiteq.h [new file with mode: 0644]
solution/event_handling.c [new file with mode: 0644]
solution/images.c [new file with mode: 0644]
solution/jpeg_handling.c [new file with mode: 0644]
solution/main.c
solution/mlx_addition.c [new file with mode: 0644]

index f32afbb791e055039ec4ef232ce9c37b2154a172..ae4ce4fa4f8d709c3c726d629bae08e6398e623c 100644 (file)
@@ -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 (file)
index 0000000..8703b0a
--- /dev/null
@@ -0,0 +1,49 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   cleanup.c                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 <mlx.h>
+#include <stdlib.h>
+
+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 (file)
index 0000000..7a335db
--- /dev/null
@@ -0,0 +1,56 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   color.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 (file)
index 0000000..10f9693
--- /dev/null
@@ -0,0 +1,66 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   convolution.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 (file)
index 0000000..01d7719
--- /dev/null
@@ -0,0 +1,90 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   digiteq.h                                          :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   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 (file)
index 0000000..6a0c408
--- /dev/null
@@ -0,0 +1,72 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   event_handling.c                                   :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/04 10:31:51 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/04 10:38:04 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "digiteq.h"
+#include <mlx.h>
+#include <X11/keysym.h>
+
+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 (file)
index 0000000..b274d4a
--- /dev/null
@@ -0,0 +1,87 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   images.c                                           :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/04 10:29:22 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/04 10:31:33 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "digiteq.h"
+#include <mlx.h>
+
+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 (file)
index 0000000..6529938
--- /dev/null
@@ -0,0 +1,94 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   jpeg_handling.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/04 10:21:40 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/04 10:36:49 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "digiteq.h"
+#include <mlx.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+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);
+}
index 8144fc1f002d34675ecc69d470a899a323c9ed02..94434653143445ba65365541425e86a295a29ef4 100644 (file)
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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 <mlx.h>
-#include <unistd.h>
-#include <stdlib.h>
 #include <X11/X.h>
-#include <X11/keysym.h>
-#include <limits.h>
-
-#include <stdio.h>
-#include <jpeglib.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;
-
-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 (file)
index 0000000..2642c25
--- /dev/null
@@ -0,0 +1,74 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   mlx_addition.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/04/04 10:27:01 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/04/04 10:37:03 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "digiteq.h"
+#include <mlx.h>
+#include <limits.h>
+
+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);
+}