256-colors palette is now pre-computed on start
That kinda fixes weird issue with vertical stripes
This commit is contained in:
parent
7673f7e239
commit
ee81a72e56
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@ CFLAGS := -Wall -Wextra -Werror -pedantic -std=c99 -ggdb
|
||||||
CLIBS := -lm
|
CLIBS := -lm
|
||||||
INCLUDES := -Isrc
|
INCLUDES := -Isrc
|
||||||
OBJECTS := obj/stb_image.o obj/stb_image_resize.o \
|
OBJECTS := obj/stb_image.o obj/stb_image_resize.o \
|
||||||
obj/colors.o obj/args.o obj/image.o \
|
obj/colors.o obj/args.o obj/image.o obj/commons.o \
|
||||||
obj/mod_blocks.o
|
obj/mod_blocks.o
|
||||||
|
|
||||||
all: lib asciify
|
all: lib asciify
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
#include "colors.h"
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -242,6 +243,9 @@ int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.out_style == ASC_STL_256COLOR)
|
||||||
|
make_pal256(&c_palette_256, c_palette_ansi_vga);
|
||||||
|
|
||||||
state->out_file = stdout;
|
state->out_file = stdout;
|
||||||
if (strcmp(args.output_filename, "-"))
|
if (strcmp(args.output_filename, "-"))
|
||||||
state->out_file = fopen(args.output_filename, "wb");
|
state->out_file = fopen(args.output_filename, "wb");
|
||||||
|
|
38
src/colors.c
38
src/colors.c
|
@ -11,6 +11,10 @@ palette_t c_palette_bw = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
palette_t c_palette_256 = {
|
||||||
|
.n_colors = 0
|
||||||
|
};
|
||||||
|
|
||||||
palette_t c_palette_ansi_discord = {
|
palette_t c_palette_ansi_discord = {
|
||||||
.n_colors = 8,
|
.n_colors = 8,
|
||||||
.palette = {
|
.palette = {
|
||||||
|
@ -89,30 +93,11 @@ int closest_color(palette_t pal, rgba8 color)
|
||||||
return nearest;
|
return nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int closest_256(palette_t pal, rgba8 color)
|
|
||||||
{
|
|
||||||
(void)pal;
|
|
||||||
if (color.r == color.g && color.g == color.b)
|
|
||||||
{
|
|
||||||
if (color.r < 8) return 16;
|
|
||||||
if (color.r > 248) return 231;
|
|
||||||
return 232 + (int)ceil((color.r - 8.0) / 247.0 * 24.0);
|
|
||||||
}
|
|
||||||
int oc = 16;
|
|
||||||
oc += 36 * (int)ceil(color.r / 255.0 * 5.0);
|
|
||||||
oc += 6 * (int)ceil(color.g / 255.0 * 5.0);
|
|
||||||
oc += (int)ceil(color.b / 255.0 * 5.0);
|
|
||||||
return oc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rgba8 pal256_to_rgb(palette_t pal, int ndx)
|
rgba8 pal256_to_rgb(palette_t pal, int ndx)
|
||||||
{
|
{
|
||||||
|
(void)pal;
|
||||||
rgba8 out = { 0, 0, 0, 255 };
|
rgba8 out = { 0, 0, 0, 255 };
|
||||||
if (ndx < 16)
|
if (ndx >= 232)
|
||||||
{
|
|
||||||
return pal.palette[ndx];
|
|
||||||
}
|
|
||||||
else if (ndx >= 232)
|
|
||||||
{
|
{
|
||||||
int l = (ndx - 232) * 255 / 24;
|
int l = (ndx - 232) * 255 / 24;
|
||||||
out.r = out.g = out.b = l;
|
out.r = out.g = out.b = l;
|
||||||
|
@ -129,6 +114,17 @@ rgba8 pal256_to_rgb(palette_t pal, int ndx)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_pal256(palette_t *dst, palette_t ansi)
|
||||||
|
{
|
||||||
|
if (dst->n_colors == 256) return;
|
||||||
|
dst->n_colors = 256;
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
rgba8 res = pal256_to_rgb(ansi, i);
|
||||||
|
memcpy(&dst->palette[i], &res, sizeof(rgba8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float calc_brightness(rgba8 c)
|
float calc_brightness(rgba8 c)
|
||||||
{
|
{
|
||||||
return 0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b;
|
return 0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b;
|
||||||
|
|
|
@ -14,13 +14,14 @@ typedef struct {
|
||||||
} palette_t;
|
} palette_t;
|
||||||
|
|
||||||
extern palette_t c_palette_bw;
|
extern palette_t c_palette_bw;
|
||||||
|
extern palette_t c_palette_256;
|
||||||
extern palette_t c_palette_ansi_discord;
|
extern palette_t c_palette_ansi_discord;
|
||||||
extern palette_t c_palette_ansi_vga;
|
extern palette_t c_palette_ansi_vga;
|
||||||
extern palette_t c_palette_ansi_xterm;
|
extern palette_t c_palette_ansi_xterm;
|
||||||
|
|
||||||
int closest_color(palette_t pal, rgba8 color);
|
int closest_color(palette_t pal, rgba8 color);
|
||||||
int closest_256(palette_t pal, rgba8 color);
|
|
||||||
rgba8 pal256_to_rgb(palette_t pal, int ndx);
|
rgba8 pal256_to_rgb(palette_t pal, int ndx);
|
||||||
|
void make_pal256(palette_t *dst, palette_t ansi);
|
||||||
bool load_palette_gpl(palette_t *pal, FILE *fp);
|
bool load_palette_gpl(palette_t *pal, FILE *fp);
|
||||||
bool load_palette_raw(palette_t *pal, FILE *fp);
|
bool load_palette_raw(palette_t *pal, FILE *fp);
|
||||||
bool load_palette(palette_t *pal, FILE *fp);
|
bool load_palette(palette_t *pal, FILE *fp);
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "colors.h"
|
||||||
|
#include "commons.h"
|
||||||
|
|
||||||
|
void m_prepare_dither(asc_state_t *state)
|
||||||
|
{
|
||||||
|
if (state->args.dither)
|
||||||
|
{
|
||||||
|
image_t *res = NULL;
|
||||||
|
switch (state->args.out_style)
|
||||||
|
{
|
||||||
|
case ASC_STL_BLACKWHITE:
|
||||||
|
res = image_dither(state->image, c_palette_bw);
|
||||||
|
break;
|
||||||
|
case ASC_STL_ANSI_VGA:
|
||||||
|
res = image_dither(state->image, c_palette_ansi_vga);
|
||||||
|
break;
|
||||||
|
case ASC_STL_ANSI_XTERM:
|
||||||
|
res = image_dither(state->image, c_palette_ansi_xterm);
|
||||||
|
break;
|
||||||
|
case ASC_STL_ANSI_DISCORD:
|
||||||
|
res = image_dither(state->image, c_palette_ansi_discord);
|
||||||
|
break;
|
||||||
|
case ASC_STL_256COLOR:
|
||||||
|
res = image_dither(state->image, c_palette_256);
|
||||||
|
break;
|
||||||
|
case ASC_STL_PALETTE:
|
||||||
|
res = image_dither(state->image, *state->palette);
|
||||||
|
break;
|
||||||
|
case ASC_STL_TRUECOLOR:
|
||||||
|
case ASC_STL_ENDL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (res != NULL)
|
||||||
|
{
|
||||||
|
image_unload(state->image);
|
||||||
|
state->image = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _COMMONS_H_
|
||||||
|
#define _COMMONS_H_
|
||||||
|
|
||||||
|
#include "args.h"
|
||||||
|
|
||||||
|
void m_prepare_dither(asc_state_t *state);
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,7 +12,6 @@ typedef struct {
|
||||||
|
|
||||||
typedef rgba8 (*dither_quantizer_t)(rgba8 clr, void *param);
|
typedef rgba8 (*dither_quantizer_t)(rgba8 clr, void *param);
|
||||||
|
|
||||||
|
|
||||||
image_t *image_load(FILE *file);
|
image_t *image_load(FILE *file);
|
||||||
image_t *image_resize(image_t *img, int width, int height);
|
image_t *image_resize(image_t *img, int width, int height);
|
||||||
image_t *image_dither(image_t *img, palette_t palette);
|
image_t *image_dither(image_t *img, palette_t palette);
|
||||||
|
|
|
@ -2,18 +2,12 @@
|
||||||
#include "mod_blocks.h"
|
#include "mod_blocks.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
|
#include "commons.h"
|
||||||
|
|
||||||
const char *BLOCKS[4] = { " ", "\xe2\x96\x80", "\xe2\x96\x84", "\xe2\x96\x88" };
|
const char *BLOCKS[4] = { " ", "\xe2\x96\x80", "\xe2\x96\x84", "\xe2\x96\x88" };
|
||||||
const char *BLOCKS_ESC[4] = { " ", "\\u2580", "\\u2584", "\\u2588" };
|
const char *BLOCKS_ESC[4] = { " ", "\\u2580", "\\u2584", "\\u2588" };
|
||||||
|
|
||||||
|
|
||||||
rgba8 __to_256(rgba8 c, void *p)
|
|
||||||
{
|
|
||||||
(void)p;
|
|
||||||
return pal256_to_rgb(c_palette_ansi_vga, closest_256(c_palette_ansi_vga, c));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mod_blocks_prepare(asc_state_t *state)
|
void mod_blocks_prepare(asc_state_t *state)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
|
@ -21,49 +15,8 @@ void mod_blocks_prepare(asc_state_t *state)
|
||||||
state->source_image->width, state->source_image->height,
|
state->source_image->width, state->source_image->height,
|
||||||
state->args.width, state->args.height * 2, &w, &h);
|
state->args.width, state->args.height * 2, &w, &h);
|
||||||
h = (h / 2) * 2;
|
h = (h / 2) * 2;
|
||||||
if (state->args.verbose)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "src: %dx%d\n",
|
|
||||||
state->source_image->width,
|
|
||||||
state->source_image->height);
|
|
||||||
fprintf(stderr, "tgt: %dx%d\n", state->args.width, state->args.height * 2);
|
|
||||||
fprintf(stderr, "dst: %dx%d\n", w, h);
|
|
||||||
}
|
|
||||||
state->image = image_resize(state->source_image, w, h);
|
state->image = image_resize(state->source_image, w, h);
|
||||||
// TODO: dither
|
m_prepare_dither(state);
|
||||||
if (state->args.dither)
|
|
||||||
{
|
|
||||||
image_t *res = NULL;
|
|
||||||
switch (state->args.out_style)
|
|
||||||
{
|
|
||||||
case ASC_STL_BLACKWHITE:
|
|
||||||
res = image_dither(state->image, c_palette_bw);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_VGA:
|
|
||||||
res = image_dither(state->image, c_palette_ansi_vga);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_XTERM:
|
|
||||||
res = image_dither(state->image, c_palette_ansi_xterm);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_DISCORD:
|
|
||||||
res = image_dither(state->image, c_palette_ansi_discord);
|
|
||||||
break;
|
|
||||||
case ASC_STL_256COLOR:
|
|
||||||
res = image_dither_fn(state->image, __to_256, NULL);
|
|
||||||
break;
|
|
||||||
case ASC_STL_PALETTE:
|
|
||||||
res = image_dither(state->image, *state->palette);
|
|
||||||
break;
|
|
||||||
case ASC_STL_TRUECOLOR:
|
|
||||||
case ASC_STL_ENDL:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (res != NULL)
|
|
||||||
{
|
|
||||||
image_unload(state->image);
|
|
||||||
state->image = res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __start_output(asc_state_t state)
|
void __start_output(asc_state_t state)
|
||||||
|
@ -254,8 +207,8 @@ void __put_pixel(asc_state_t state, rgba8 top, rgba8 bot, bool final)
|
||||||
break;
|
break;
|
||||||
case ASC_STL_256COLOR:
|
case ASC_STL_256COLOR:
|
||||||
{
|
{
|
||||||
int index_top = closest_256(c_palette_ansi_vga, top),
|
int index_top = closest_color(c_palette_256, top),
|
||||||
index_bot = closest_256(c_palette_ansi_vga, bot);
|
index_bot = closest_color(c_palette_256, bot);
|
||||||
__putc_256(fp, fmt, final, index_top, index_bot, c_palette_ansi_vga);
|
__putc_256(fp, fmt, final, index_top, index_bot, c_palette_ansi_vga);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue