Started from buttom go to the sky

This commit is contained in:
Raphaël 2024-04-28 19:59:01 +02:00
parent 96215449bd
commit f811e55dea
4781 changed files with 10121 additions and 1743 deletions

View file

@ -0,0 +1,86 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* qoi_decode.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/25 22:33:19 by maiboyer #+# #+# */
/* Updated: 2023/12/25 22:58:27 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef QOI_DECODE_H
# define QOI_DECODE_H
# include "me/img/qoi.h"
# include "me/img/qoi/qoi_utils.h"
typedef struct s_decode_vals
{
t_i32 px_len;
t_i32 chunks_len;
t_i32 px_pos;
t_i32 p;
t_i32 run;
t_i32 b1;
t_i32 b2;
t_i32 vg;
t_u32 header_magic;
t_qoi_rgba index[64];
t_qoi_rgba px;
} t_decode_vals;
static inline void qoi_op_luma_decode(t_decode_vals *vals, const t_u8 *bytes)
{
vals->b2 = bytes[vals->p++];
vals->vg = (vals->b1 & 0x3f) - 32;
vals->px.rgba.r += vals->vg - 8 + ((vals->b2 >> 4) & 0x0f);
vals->px.rgba.g += vals->vg;
vals->px.rgba.b += vals->vg - 8 + (vals->b2 & 0x0f);
}
static inline void qoi_op_diff_decode(t_decode_vals *vals, const t_u8 *bytes)
{
(void)(bytes);
vals->px.rgba.r += ((vals->b1 >> 4) & 0x03) - 2;
vals->px.rgba.g += ((vals->b1 >> 2) & 0x03) - 2;
vals->px.rgba.b += (vals->b1 & 0x03) - 2;
}
static inline void qoi_op_rgba_decode(t_decode_vals *vals, const t_u8 *bytes)
{
vals->px.rgba.r = bytes[vals->p++];
vals->px.rgba.g = bytes[vals->p++];
vals->px.rgba.b = bytes[vals->p++];
vals->px.rgba.a = bytes[vals->p++];
}
static inline void qoi_op_rgb_decode(t_decode_vals *vals, const t_u8 *bytes)
{
vals->px.rgba.r = bytes[vals->p++];
vals->px.rgba.g = bytes[vals->p++];
vals->px.rgba.b = bytes[vals->p++];
}
static inline void qoi_decode_inner_inner(t_decode_vals *vals, \
const t_u8 *bytes)
{
vals->b1 = bytes[vals->p++];
if (vals->b1 == QOI_OP_RGB)
qoi_op_rgb_decode(vals, bytes);
else if (vals->b1 == QOI_OP_RGBA)
qoi_op_rgba_decode(vals, bytes);
else if ((vals->b1 & QOI_MASK_2) == QOI_OP_INDEX)
vals->px = vals->index[vals->b1];
else if ((vals->b1 & QOI_MASK_2) == QOI_OP_DIFF)
qoi_op_diff_decode(vals, bytes);
else if ((vals->b1 & QOI_MASK_2) == QOI_OP_LUMA)
qoi_op_luma_decode(vals, bytes);
else if ((vals->b1 & QOI_MASK_2) == QOI_OP_RUN)
vals->run = (vals->b1 & 0x3f);
vals->index[qoi_color_hash(vals->px) % 64] = vals->px;
}
#endif /* QOI_DECODE_H */

View file

@ -0,0 +1,155 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* qoi_encode.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/25 22:36:06 by maiboyer #+# #+# */
/* Updated: 2023/12/25 22:56:36 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef QOI_ENCODE_H
# define QOI_ENCODE_H
# include "me/img/qoi.h"
# include "me/img/qoi/qoi_utils.h"
typedef struct s_encode_vals
{
t_i32 i;
t_i32 max_size;
t_i32 p;
t_i32 run;
t_i32 px_len;
t_i32 px_end;
t_i32 px_pos;
t_i32 channels;
t_i32 index_pos;
t_qoi_rgba index[64];
t_qoi_rgba px;
t_qoi_rgba px_prev;
} t_encode_vals;
typedef struct s_v
{
t_i8 r;
t_i8 g;
t_i8 b;
t_i8 g_r;
t_i8 g_b;
} t_v;
static inline void qoi_encode_if_thingy1(t_encode_vals *vals,
t_v *v, t_u8 *bytes)
{
v->r = vals->px.rgba.r - vals->px_prev.rgba.r;
v->g = vals->px.rgba.g - vals->px_prev.rgba.g;
v->b = vals->px.rgba.b - vals->px_prev.rgba.b;
v->g_r = v->r - v->g;
v->g_b = v->b - v->g;
if (v->r > -3 && v->r < 2 && v->g > -3 && v->g < 2 && v->b > -3
&& v->b < 2)
bytes[vals->p++] = QOI_OP_DIFF | (v->r + 2) << 4 | (v->g
+ 2) << 2 | (v->b + 2);
else if (v->g_r > -9 && v->g_r < 8 && v->g > -33 && v->g < 32
&& v->g_b > -9 && v->g_b < 8)
{
bytes[vals->p++] = QOI_OP_LUMA | (v->g + 32);
bytes[vals->p++] = (v->g_r + 8) << 4 | (v->g_b + 8);
}
else
{
bytes[vals->p++] = QOI_OP_RGB;
bytes[vals->p++] = vals->px.rgba.r;
bytes[vals->p++] = vals->px.rgba.g;
bytes[vals->p++] = vals->px.rgba.b;
}
}
static inline void qoi_encode_inner_inner_inner(t_encode_vals *vals,
t_v *v, t_u8 *bytes)
{
if (vals->run > 0)
{
bytes[vals->p++] = QOI_OP_RUN | (vals->run - 1);
vals->run = 0;
}
vals->index_pos = qoi_color_hash(vals->px) % 64;
if (vals->index[vals->index_pos].v == vals->px.v)
bytes[vals->p++] = QOI_OP_INDEX | vals->index_pos;
else
{
vals->index[vals->index_pos] = vals->px;
if (vals->px.rgba.a == vals->px_prev.rgba.a)
qoi_encode_if_thingy1(vals, v, bytes);
else
{
bytes[vals->p++] = QOI_OP_RGBA;
bytes[vals->p++] = vals->px.rgba.r;
bytes[vals->p++] = vals->px.rgba.g;
bytes[vals->p++] = vals->px.rgba.b;
bytes[vals->p++] = vals->px.rgba.a;
}
}
}
static inline void qoi_encode_inner_inner(t_encode_vals *vals,
const t_u8 *pixels, t_u8 *bytes)
{
t_v v;
v = (t_v){0};
while (vals->px_pos < vals->px_len)
{
vals->px.rgba.r = pixels[vals->px_pos + 0];
vals->px.rgba.g = pixels[vals->px_pos + 1];
vals->px.rgba.b = pixels[vals->px_pos + 2];
if (vals->channels == 4)
vals->px.rgba.a = pixels[vals->px_pos + 3];
if (vals->px.v == vals->px_prev.v)
{
vals->run++;
if (vals->run == 62 || vals->px_pos == vals->px_end)
{
bytes[vals->p++] = QOI_OP_RUN | (vals->run - 1);
vals->run = 0;
}
}
else
qoi_encode_inner_inner_inner(vals, &v, bytes);
vals->px_prev = vals->px;
vals->px_pos += vals->channels;
}
}
static inline void *qoi_encode_inner(t_encode_vals *vals,
const t_qoi_desc *desc,
const t_u8 *pixels, t_i32 *out_len)
{
t_u8 *bytes;
bytes = (t_u8 *)mem_alloc(vals->max_size);
if (!bytes)
return (NULL);
qoi_write_32(bytes, &vals->p, QOI_MAGIC);
qoi_write_32(bytes, &vals->p, desc->width);
qoi_write_32(bytes, &vals->p, desc->height);
bytes[vals->p++] = desc->channels;
bytes[vals->p++] = desc->colorspace;
mem_set_zero(vals->index, sizeof(vals->index));
vals->px_prev.rgba.a = 255;
vals->px = vals->px_prev;
vals->px_len = desc->width * desc->height * desc->channels;
vals->px_end = vals->px_len - desc->channels;
vals->channels = desc->channels;
qoi_encode_inner_inner(vals, pixels, bytes);
vals->i = 0;
while (vals->i < (t_i32) sizeof(t_u8[8]))
bytes[vals->p++] = ((t_u8[8]){0, 0, 0, 0, 0, 0, 0, 1})[vals->i++];
*out_len = vals->p;
return (bytes);
}
#endif /* QOI_ENCODE_H */

View file

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* qoi_utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/24 18:59:56 by maiboyer #+# #+# */
/* Updated: 2023/12/25 22:33:07 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef QOI_UTILS_H
# define QOI_UTILS_H
# include "me/img/qoi.h"
# include "me/types.h"
# define QOI_OP_INDEX 0x00 /* 00xxxxxx */
# define QOI_OP_DIFF 0x40 /* 01xxxxxx */
# define QOI_OP_LUMA 0x80 /* 10xxxxxx */
# define QOI_OP_RUN 0xc0 /* 11xxxxxx */
# define QOI_OP_RGB 0xfe /* 11111110 */
# define QOI_OP_RGBA 0xff /* 11111111 */
# define QOI_MASK_2 0xc0 /* 11000000 */
# define QOI_MAGIC 0x716f6966u
//(((t_u32)'q') << 24 | ((t_u32)'o') << 16 | ((t_u32)'i') << 8 | ((t_u32)'f'))
# define QOI_HEADER_SIZE 14
/* 2GB is the max file size that this implementation can safely handle. We guard
against anything larger than that, assuming the worst case with 5 bytes per
pixel, rounded down to a nice clean value. 400 million pixels ought to be
enough for anybody. */
# define QOI_PIXELS_MAX 400000000u
typedef union u_qoi_rgba
{
struct s_qoi_rgba
{
t_u8 r;
t_u8 g;
t_u8 b;
t_u8 a;
} rgba;
t_u32 v;
} t_qoi_rgba;
void qoi_write_32(t_u8 *bytes, t_i32 *p, t_u32 v);
t_u32 qoi_read_32(const t_u8 *bytes, t_i32 *p);
static inline t_u32 qoi_color_hash(t_qoi_rgba c)
{
return (c.rgba.r * 3 + c.rgba.g * 5 + c.rgba.b * 7 + c.rgba.a * 11);
}
#endif /* QOI_UTILS_H */