Dithering and palette support
TODO: fix some weird issues with dithering
This commit is contained in:
parent
c2b3a157c4
commit
44418ac242
20
src/args.c
20
src/args.c
|
@ -222,6 +222,26 @@ int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
state->source_image = image_load(image_file);
|
state->source_image = image_load(image_file);
|
||||||
fclose(image_file);
|
fclose(image_file);
|
||||||
|
|
||||||
|
if (args.out_style == ASC_STL_PALETTE)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen(args.palette_filename, "rb");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
int err = errno;
|
||||||
|
fprintf(stderr, "Error: failed to open file %s for reading: %d: %s\n",
|
||||||
|
args.palette_filename, err, strerror(err));
|
||||||
|
return -100 - err;
|
||||||
|
}
|
||||||
|
state->palette = calloc(1, sizeof(palette_t));
|
||||||
|
if (!load_palette(state->palette, fp))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: failed to read palette\n");
|
||||||
|
fclose(fp);
|
||||||
|
return -7;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
|
59
src/colors.c
59
src/colors.c
|
@ -1,5 +1,15 @@
|
||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
palette_t c_palette_bw = {
|
||||||
|
.n_colors = 2,
|
||||||
|
.palette = {
|
||||||
|
{ 0, 0, 0, 0 },
|
||||||
|
{ 255, 255, 255, 0 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
palette_t c_palette_ansi_discord = {
|
palette_t c_palette_ansi_discord = {
|
||||||
.n_colors = 8,
|
.n_colors = 8,
|
||||||
|
@ -124,21 +134,52 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_palette_gpl(palette_t *pal, FILE *fp)
|
bool load_palette_gpl(palette_t *pal, FILE *fp)
|
||||||
{
|
{
|
||||||
(void)pal; (void)fp;
|
static char buf[8192];
|
||||||
// TODO: load GIMP palette file
|
fgets(buf, 8192, fp); // GIMP Palette
|
||||||
|
fgets(buf, 8192, fp); // Name: %s
|
||||||
|
fgets(buf, 8192, fp); // Columns: %d
|
||||||
|
|
||||||
|
pal->n_colors = 0;
|
||||||
|
while (!feof(fp) && pal->n_colors < 256)
|
||||||
|
{
|
||||||
|
fgets(buf, 8192, fp);
|
||||||
|
int r, g, b;
|
||||||
|
if (sscanf(buf, "%d %d %d", &r, &g, &b) == 3)
|
||||||
|
{
|
||||||
|
pal->palette[pal->n_colors].r = r;
|
||||||
|
pal->palette[pal->n_colors].g = g;
|
||||||
|
pal->palette[pal->n_colors].b = b;
|
||||||
|
pal->n_colors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_palette_raw(palette_t *pal, FILE *fp)
|
bool load_palette_raw(palette_t *pal, FILE *fp)
|
||||||
{
|
{
|
||||||
(void)pal; (void)fp;
|
while (!feof(fp))
|
||||||
// TODO: load raw palette file
|
{
|
||||||
|
size_t sz = fread(&pal->palette[pal->n_colors++], 1, sizeof(rgba8), fp);
|
||||||
|
if (sz == 0 && feof(fp)) break;
|
||||||
|
if (sz != sizeof(rgba8)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_palette(palette_t *pal, FILE *fp)
|
bool load_palette(palette_t *pal, FILE *fp)
|
||||||
{
|
{
|
||||||
(void)pal; (void)fp;
|
static char head[16];
|
||||||
// TODO: guess palette file type and load it
|
if (fread(head, sizeof(char), 12, fp) < 12) return false;
|
||||||
|
if (fseek(fp, 0, SEEK_SET) != 0) return false;
|
||||||
|
if (!strncmp(head, "GIMP Palette", 12))
|
||||||
|
{
|
||||||
|
return load_palette_gpl(pal, fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return load_palette_raw(pal, fp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/colors.h
10
src/colors.h
|
@ -2,6 +2,7 @@
|
||||||
#define _COLORS_H_
|
#define _COLORS_H_
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
|
@ -9,9 +10,10 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int n_colors;
|
int n_colors;
|
||||||
rgba8 palette[255];
|
rgba8 palette[256];
|
||||||
} palette_t;
|
} palette_t;
|
||||||
|
|
||||||
|
extern palette_t c_palette_bw;
|
||||||
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;
|
||||||
|
@ -19,9 +21,9 @@ 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);
|
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 load_palette_gpl(palette_t *pal, FILE *fp);
|
bool load_palette_gpl(palette_t *pal, FILE *fp);
|
||||||
void load_palette_raw(palette_t *pal, FILE *fp);
|
bool load_palette_raw(palette_t *pal, FILE *fp);
|
||||||
void load_palette(palette_t *pal, FILE *fp);
|
bool load_palette(palette_t *pal, FILE *fp);
|
||||||
float calc_brightness(rgba8 color);
|
float calc_brightness(rgba8 color);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
59
src/image.c
59
src/image.c
|
@ -16,7 +16,6 @@ image_t *image_load(FILE *file)
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
image_t *image_resize(image_t *img, int width, int height)
|
image_t *image_resize(image_t *img, int width, int height)
|
||||||
{
|
{
|
||||||
image_t *res = calloc(1, sizeof(image_t));
|
image_t *res = calloc(1, sizeof(image_t));
|
||||||
|
@ -30,6 +29,64 @@ image_t *image_resize(image_t *img, int width, int height)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __dither_update_pixel(image_t *img, int x, int y, int err[3], float bias)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= img->width || y < 0 || y >= img->height) return;
|
||||||
|
rgba8 pix = img->pixels[x + y * img->width];
|
||||||
|
int dst[3] = { pix.r, pix.g, pix.b };
|
||||||
|
dst[0] += (int)((float)err[0] * bias);
|
||||||
|
dst[1] += (int)((float)err[1] * bias);
|
||||||
|
dst[2] += (int)((float)err[2] * bias);
|
||||||
|
pix.r = (dst[0] > 255 ? 255 : (dst[0] < 0 ? 0 : dst[0]));
|
||||||
|
pix.g = (dst[1] > 255 ? 255 : (dst[1] < 0 ? 0 : dst[1]));
|
||||||
|
pix.b = (dst[2] > 255 ? 255 : (dst[2] < 0 ? 0 : dst[2]));
|
||||||
|
memcpy(&img->pixels[x + y * img->width], &pix, sizeof(rgba8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: make it work better sometime in future (for some reason it sucks rn)
|
||||||
|
image_t *image_dither_fn(image_t *img, dither_quantizer_t quantize, void *param)
|
||||||
|
{
|
||||||
|
image_t *res = calloc(1, sizeof(image_t));
|
||||||
|
int w = res->width = img->width;
|
||||||
|
int h = res->height = img->height;
|
||||||
|
res->pixels = calloc(img->width * img->height, sizeof(rgba8));
|
||||||
|
memcpy(res->pixels, img->pixels, img->width * img->height * sizeof(rgba8));
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
rgba8 old = res->pixels[x + y * w];
|
||||||
|
rgba8 new = quantize(old, param);
|
||||||
|
res->pixels[x + y * w].r = new.r;
|
||||||
|
res->pixels[x + y * w].g = new.g;
|
||||||
|
res->pixels[x + y * w].b = new.b;
|
||||||
|
int err[3] = {
|
||||||
|
(int)old.r - (int)new.r,
|
||||||
|
(int)old.g - (int)new.g,
|
||||||
|
(int)old.b - (int)new.b
|
||||||
|
};
|
||||||
|
__dither_update_pixel(res, x + 1, y , err, 7.0f / 16.0f);
|
||||||
|
__dither_update_pixel(res, x - 1, y + 1, err, 3.0f / 16.0f);
|
||||||
|
__dither_update_pixel(res, x , y + 1, err, 5.0f / 16.0f);
|
||||||
|
__dither_update_pixel(res, x + 1, y + 1, err, 1.0f / 16.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
rgba8 __image_quantize_pal(rgba8 clr, void *param)
|
||||||
|
{
|
||||||
|
palette_t palette = *(palette_t *)param;
|
||||||
|
int ndx = closest_color(palette, clr);
|
||||||
|
return palette.palette[ndx];
|
||||||
|
}
|
||||||
|
|
||||||
|
image_t *image_dither(image_t *img, palette_t pal)
|
||||||
|
{
|
||||||
|
return image_dither_fn(img, __image_quantize_pal, &pal);
|
||||||
|
}
|
||||||
|
|
||||||
void image_unload(image_t *img)
|
void image_unload(image_t *img)
|
||||||
{
|
{
|
||||||
free(img->pixels);
|
free(img->pixels);
|
||||||
|
|
|
@ -10,8 +10,13 @@ typedef struct {
|
||||||
rgba8 *pixels;
|
rgba8 *pixels;
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
|
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_fn(image_t *img, dither_quantizer_t quantize, void *p);
|
||||||
void image_unload(image_t *img);
|
void image_unload(image_t *img);
|
||||||
|
|
||||||
void get_size_keep_aspect(int w, int h, int dw, int dh, int *ow, int *oh);
|
void get_size_keep_aspect(int w, int h, int dw, int dh, int *ow, int *oh);
|
||||||
|
|
|
@ -3,14 +3,16 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
|
|
||||||
#define BLOCK_TOP "\u2580"
|
const char *BLOCKS[4] = { " ", "\xe2\x96\x80", "\xe2\x96\x84", "\xe2\x96\x88" };
|
||||||
#define BLOCK_BOT "\u2584"
|
const char *BLOCKS_ESC[4] = { " ", "\\u2580", "\\u2584", "\\u2588" };
|
||||||
#define BLOCK_FUL "\u2588"
|
|
||||||
#define BLOCK_NUL " "
|
|
||||||
#define BLOCK_TOP_ESC "\\u2580"
|
rgba8 __to_256(rgba8 c, void *p)
|
||||||
#define BLOCK_BOT_ESC "\\u2584"
|
{
|
||||||
#define BLOCK_FUL_ESC "\\u2588"
|
(void)p;
|
||||||
#define BLOCK_NUL_ESC " "
|
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)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +31,40 @@ void mod_blocks_prepare(asc_state_t *state)
|
||||||
}
|
}
|
||||||
state->image = image_resize(state->source_image, w, h);
|
state->image = image_resize(state->source_image, w, h);
|
||||||
// TODO: dither
|
// TODO: dither
|
||||||
|
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)
|
||||||
|
@ -42,7 +78,7 @@ void __start_output(asc_state_t state)
|
||||||
fprintf(state.out_file, " \"data\": [");
|
fprintf(state.out_file, " \"data\": [");
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_HTML:
|
case ASC_FMT_HTML:
|
||||||
fprintf(state.out_file, "<table>\n");
|
fprintf(state.out_file, "<table style=\"border-collapse: collapse;\">\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -96,18 +132,18 @@ void __end_line(FILE *fp, asc_format_t fmt, asc_style_t stl, bool final)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __putc_bw(char *px, FILE *fp, asc_format_t fmt, bool final)
|
void __putc_bw(int ndx, FILE *fp, asc_format_t fmt, bool final)
|
||||||
{
|
{
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, final ? "\"%s\"" : "\"%s\", ", px);
|
fprintf(fp, final ? "\"%s\"" : "\"%s\", ", BLOCKS_ESC[ndx]);
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_HTML:
|
case ASC_FMT_HTML:
|
||||||
fprintf(fp, "<td>%s</td>", px);
|
fprintf(fp, "<td>%s</td>", BLOCKS[ndx]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "%s", px);
|
fprintf(fp, "%s", BLOCKS[ndx]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,20 +157,20 @@ void __putc_ansi(FILE *fp, asc_format_t fmt, bool final, int ct, int cb, palette
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
||||||
BLOCK_TOP_ESC, top_int, bot_int);
|
BLOCKS_ESC[1], top_int, bot_int);
|
||||||
if (!final) fprintf(fp, ", ");
|
if (!final) fprintf(fp, ", ");
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_HTML:
|
case ASC_FMT_HTML:
|
||||||
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
||||||
top_rgb.r, top_rgb.g, top_rgb.b,
|
top_rgb.r, top_rgb.g, top_rgb.b,
|
||||||
bot_rgb.r, bot_rgb.g, bot_rgb.b,
|
bot_rgb.r, bot_rgb.g, bot_rgb.b,
|
||||||
BLOCK_TOP);
|
BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "\033[%d;%dm%s",
|
fprintf(fp, "\033[%d;%dm%s",
|
||||||
ct + (ct >= 8 ? 82 : 30),
|
ct + (ct >= 8 ? 82 : 30),
|
||||||
cb + (cb >= 8 ? 92 : 40),
|
cb + (cb >= 8 ? 92 : 40),
|
||||||
BLOCK_TOP);
|
BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,17 +184,17 @@ void __putc_256(FILE *fp, asc_format_t fmt, bool final, int ct, int cb, palette_
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
||||||
BLOCK_TOP_ESC, top_int, bot_int);
|
BLOCKS_ESC[1], top_int, bot_int);
|
||||||
if (!final) fprintf(fp, ", ");
|
if (!final) fprintf(fp, ", ");
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_HTML:
|
case ASC_FMT_HTML:
|
||||||
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
||||||
top_rgb.r, top_rgb.g, top_rgb.b,
|
top_rgb.r, top_rgb.g, top_rgb.b,
|
||||||
bot_rgb.r, bot_rgb.g, bot_rgb.b,
|
bot_rgb.r, bot_rgb.g, bot_rgb.b,
|
||||||
BLOCK_TOP);
|
BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "\033[38;5;%d;48;5;%dm%s", ct, cb, BLOCK_TOP);
|
fprintf(fp, "\033[38;5;%d;48;5;%dm%s", ct, cb, BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,16 +207,16 @@ void __putc_truecolor(FILE *fp, asc_format_t fmt, bool final, rgba8 top, rgba8 b
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
||||||
BLOCK_TOP_ESC, top_int, bot_int);
|
BLOCKS_ESC[1], top_int, bot_int);
|
||||||
if (!final) fprintf(fp, ", ");
|
if (!final) fprintf(fp, ", ");
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_HTML:
|
case ASC_FMT_HTML:
|
||||||
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">%s</td>",
|
||||||
top.r, top.g, top.b, bot.r, bot.g, bot.b, BLOCK_TOP);
|
top.r, top.g, top.b, bot.r, bot.g, bot.b, BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "\033[38;2;%d;%d;%d;48;2;%d;%d;%dm%s",
|
fprintf(fp, "\033[38;2;%d;%d;%d;48;2;%d;%d;%dm%s",
|
||||||
top.r, top.g, top.b, bot.r, bot.g, bot.b, BLOCK_TOP);
|
top.r, top.g, top.b, bot.r, bot.g, bot.b, BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,10 +231,10 @@ void __put_pixel(asc_state_t state, rgba8 top, rgba8 bot, bool final)
|
||||||
{
|
{
|
||||||
bool bri_top = calc_brightness(top) > 0.5;
|
bool bri_top = calc_brightness(top) > 0.5;
|
||||||
bool bri_bot = calc_brightness(bot) > 0.5;
|
bool bri_bot = calc_brightness(bot) > 0.5;
|
||||||
if ( bri_top && bri_bot) __putc_bw(BLOCK_FUL_ESC, fp, fmt, final);
|
if ( bri_top && bri_bot) __putc_bw(3, fp, fmt, final);
|
||||||
if (!bri_top && bri_bot) __putc_bw(BLOCK_BOT_ESC, fp, fmt, final);
|
if (!bri_top && bri_bot) __putc_bw(2, fp, fmt, final);
|
||||||
if ( bri_top && !bri_bot) __putc_bw(BLOCK_TOP_ESC, fp, fmt, final);
|
if ( bri_top && !bri_bot) __putc_bw(1, fp, fmt, final);
|
||||||
if (!bri_top && !bri_bot) __putc_bw(BLOCK_NUL_ESC, fp, fmt, final);
|
if (!bri_top && !bri_bot) __putc_bw(0, fp, fmt, final);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_STL_ANSI_VGA:
|
case ASC_STL_ANSI_VGA:
|
||||||
|
@ -225,10 +261,16 @@ void __put_pixel(asc_state_t state, rgba8 top, rgba8 bot, bool final)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_STL_TRUECOLOR:
|
case ASC_STL_TRUECOLOR:
|
||||||
|
__putc_truecolor(fp, fmt, final, top, bot);
|
||||||
|
break;
|
||||||
|
case ASC_STL_PALETTE:
|
||||||
{
|
{
|
||||||
__putc_truecolor(fp, fmt, final, top, bot);
|
palette_t *pal = state.palette;
|
||||||
|
rgba8 pal_top = pal->palette[closest_color(*pal, top)];
|
||||||
|
rgba8 pal_bot = pal->palette[closest_color(*pal, bot)];
|
||||||
|
__putc_truecolor(fp, fmt, final, pal_top, pal_bot);
|
||||||
}
|
}
|
||||||
default:
|
case ASC_STL_ENDL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue