OCLint fixes and some housekeeping stuff
// TODO: convert __bra_* and __blk_* to use palette from state
This commit is contained in:
parent
ea6f383b02
commit
2e359443d7
|
@ -0,0 +1,7 @@
|
||||||
|
rule-configurations:
|
||||||
|
- key: SHORT_VARIABLE_NAME
|
||||||
|
value: 1
|
||||||
|
- key: LONG_VARIABLE_NAME
|
||||||
|
value: 25
|
||||||
|
- key: LONG_LINE
|
||||||
|
value: 80
|
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
CFLAGS := -Wall -Wextra -Werror -pedantic -std=c99
|
CFLAGS := -Wall -Wextra -Werror -pedantic -std=c99 -Wno-attributes
|
||||||
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 \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# YAITAA - Yet Another Image To A(NSI) Art (converter).
|
# YAITAA - Yet Another Image To A(NSI) Art (converter)
|
||||||
|
|
||||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9fdbd9f8bc7843df9a6715b72b4da2fd)](https://www.codacy.com/gh/hatkidchan/yaitaa/dashboard?utm_source=github.com&utm_medium=referral&utm_content=hatkidchan/yaitaa&utm_campaign=Badge_Grade)
|
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9fdbd9f8bc7843df9a6715b72b4da2fd)](https://www.codacy.com/gh/hatkidchan/yaitaa/dashboard?utm_source=github.com&utm_medium=referral&utm_content=hatkidchan/yaitaa&utm_campaign=Badge_Grade)
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ recap:
|
||||||
5. Separate binaries for each mode
|
5. Separate binaries for each mode
|
||||||
6. Git submodules. Yay.
|
6. Git submodules. Yay.
|
||||||
|
|
||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
### 1. Make sure that you have C compiler and make
|
### 1. Make sure that you have C compiler and make
|
||||||
|
|
||||||
|
|
100
src/args.c
100
src/args.c
|
@ -1,73 +1,85 @@
|
||||||
#include "version.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>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "version.h"
|
||||||
|
#include "args.h"
|
||||||
|
#include "colors.h"
|
||||||
|
#include "commons.h"
|
||||||
|
#include "mod_blocks.h"
|
||||||
|
#include "mod_braille.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int value;
|
int value;
|
||||||
char *strings[8];
|
char *strings[8];
|
||||||
char *description;
|
char *description;
|
||||||
|
void *unused[2];
|
||||||
} __option_t;
|
} __option_t;
|
||||||
|
|
||||||
int __find_value(const __option_t *options, char *option);
|
int __find_value(const __option_t *options, char *option);
|
||||||
void __print_options(const __option_t *options);
|
void __print_options(const __option_t *options);
|
||||||
|
|
||||||
const __option_t __mode_options[ASC_MOD_ENDL + 1] = {
|
const asc_handler_t asc_handlers[ASC_MOD_ENDL + 1] = {
|
||||||
{ ASC_MOD_BLOCKS,
|
{ ASC_MOD_BLOCKS,
|
||||||
{ "b", "blk", "blocks", NULL },
|
{ "b", "blk", "blocks", NULL },
|
||||||
"Box-drawing characters (\342\226\204) (default)" },
|
"Box-drawing characters (\342\226\204) (default)",
|
||||||
|
mod_blocks_prepare, mod_blocks_main },
|
||||||
{ ASC_MOD_BRAILLE,
|
{ ASC_MOD_BRAILLE,
|
||||||
{ "r", "brl", "braille", NULL },
|
{ "r", "brl", "braille", NULL },
|
||||||
"Braille characters (literally stolen from MineOS)" },
|
"Braille characters (literally stolen from MineOS)",
|
||||||
|
mod_braille_prepare, mod_braille_main },
|
||||||
{ ASC_MOD_GRADIENT,
|
{ ASC_MOD_GRADIENT,
|
||||||
{ "g", "grd", "gradient", NULL },
|
{ "g", "grd", "gradient", NULL },
|
||||||
"Gradient of characters. No matching at all" },
|
"Gradient of characters. No matching at all",
|
||||||
|
NULL, NULL },
|
||||||
{ ASC_MOD_BRUTEFORCE,
|
{ ASC_MOD_BRUTEFORCE,
|
||||||
{ "f", "guess", "bruteforce", NULL },
|
{ "f", "guess", "bruteforce", NULL },
|
||||||
"Looking for best possible character" },
|
"Looking for best possible character",
|
||||||
{ -1, { NULL }, NULL }
|
NULL, NULL },
|
||||||
|
{ -1, { NULL }, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
const __option_t __style_options[ASC_STL_ENDL + 1] = {
|
const __option_t __style_options[ASC_STL_ENDL + 1] = {
|
||||||
{ ASC_STL_BLACKWHITE,
|
{ ASC_STL_BLACKWHITE,
|
||||||
{ "1", "bw", "black-white", "1bit", NULL },
|
{ "1", "bw", "black-white", "1bit", NULL },
|
||||||
"1-bit black/white" },
|
"1-bit black/white", { NULL, NULL } },
|
||||||
{ ASC_STL_ANSI_VGA,
|
{ ASC_STL_ANSI_VGA,
|
||||||
{ "vga", "ansi-vga", NULL },
|
{ "vga", "ansi-vga" },
|
||||||
"VGA palette" },
|
"VGA palette", { NULL, NULL } },
|
||||||
{ ASC_STL_ANSI_XTERM,
|
{ ASC_STL_ANSI_XTERM,
|
||||||
{ "xterm", "ansi-xterm", NULL },
|
{ "xterm", "ansi-xterm", NULL },
|
||||||
"xTerm palette. A bit more rough, compared to VGA" },
|
"xTerm palette. A bit more rough, compared to VGA", { NULL, NULL } },
|
||||||
{ ASC_STL_ANSI_DISCORD,
|
{ ASC_STL_ANSI_DISCORD,
|
||||||
{ "discord", "ansi-discord", NULL },
|
{ "discord", "ansi-discord", NULL },
|
||||||
"Palette in Discord ANSI highlight" },
|
"Palette in Discord ANSI highlight", { NULL, NULL } },
|
||||||
{ ASC_STL_256COLOR,
|
{ ASC_STL_256COLOR,
|
||||||
{ "256", "pal256", "8bit", NULL },
|
{ "256", "pal256", "8bit", NULL },
|
||||||
"256-color palette (default)" },
|
"256-color palette (default)", { NULL, NULL } },
|
||||||
{ ASC_STL_TRUECOLOR,
|
{ ASC_STL_TRUECOLOR,
|
||||||
{ "true", "truecolor", "24bit", NULL },
|
{ "true", "truecolor", "24bit", NULL },
|
||||||
"24-bit RGB (TrueColor)" },
|
"24-bit RGB (TrueColor)", { NULL, NULL } },
|
||||||
{ ASC_STL_PALETTE,
|
{ ASC_STL_PALETTE,
|
||||||
{ "pal", "palette", "custom", NULL },
|
{ "pal", "palette", "custom", NULL },
|
||||||
"Custom palette (specified via -P). Either GIMP palette file or N*3 RGB pixels" },
|
"Custom palette (specified via -P). "\
|
||||||
{ -1, { NULL }, NULL }
|
"Either GIMP palette file or N*3 RGB pixels", { NULL, NULL } },
|
||||||
|
{ -1, { NULL }, NULL, { NULL, NULL } }
|
||||||
};
|
};
|
||||||
|
|
||||||
const __option_t __format_options[ASC_FMT_ENDL + 1] = {
|
const __option_t __format_options[ASC_FMT_ENDL + 1] = {
|
||||||
{ ASC_FMT_ANSI,
|
{ ASC_FMT_ANSI,
|
||||||
{ "ansi", "raw", NULL },
|
{ "ansi", "raw", NULL },
|
||||||
"Output, suitable for terminal (default)" },
|
"Output, suitable for terminal (default)",
|
||||||
|
{ NULL, NULL } },
|
||||||
{ ASC_FMT_HTML,
|
{ ASC_FMT_HTML,
|
||||||
{ "html", NULL },
|
{ "html", NULL },
|
||||||
"Output as HTML table" },
|
"Output as HTML table",
|
||||||
|
{ NULL, NULL } },
|
||||||
{ ASC_FMT_JSON,
|
{ ASC_FMT_JSON,
|
||||||
{ "json", NULL },
|
{ "json", NULL },
|
||||||
"Output as JSON 2D array of characters with properties" },
|
"Output as JSON 2D array of characters with properties",
|
||||||
{ -1, { NULL }, NULL }
|
{ NULL, NULL } },
|
||||||
|
{ -1, { NULL }, NULL, { NULL, NULL } }
|
||||||
};
|
};
|
||||||
|
|
||||||
void usage(int argc, char **argv)
|
void usage(int argc, char **argv)
|
||||||
|
@ -93,7 +105,7 @@ void usage(int argc, char **argv)
|
||||||
fprintf(stderr, "-P PALETTE\tPath to palette file (when -S pal)\n");
|
fprintf(stderr, "-P PALETTE\tPath to palette file (when -S pal)\n");
|
||||||
fprintf(stderr, "\n\n");
|
fprintf(stderr, "\n\n");
|
||||||
fprintf(stderr, "Options for MODE:\n");
|
fprintf(stderr, "Options for MODE:\n");
|
||||||
__print_options(__mode_options);
|
__print_options((const __option_t*)asc_handlers);
|
||||||
fprintf(stderr, "Options for STYLE:\n");
|
fprintf(stderr, "Options for STYLE:\n");
|
||||||
__print_options(__style_options);
|
__print_options(__style_options);
|
||||||
fprintf(stderr, "Options for FORMAT:\n");
|
fprintf(stderr, "Options for FORMAT:\n");
|
||||||
|
@ -112,6 +124,10 @@ void version(int argc, char **argv)
|
||||||
fprintf(stderr, "See LICENSE file for details\n");
|
fprintf(stderr, "See LICENSE file for details\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((annotate("oclint:suppress[high cyclomatic complexity]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[high npath complexity]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[high ncss method]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[long method]")))
|
||||||
int parse_args(int argc, char **argv, asc_args_t *args)
|
int parse_args(int argc, char **argv, asc_args_t *args)
|
||||||
{
|
{
|
||||||
args->input_filename = NULL;
|
args->input_filename = NULL;
|
||||||
|
@ -136,11 +152,9 @@ int parse_args(int argc, char **argv, asc_args_t *args)
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(argc, argv);
|
usage(argc, argv);
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
|
||||||
case 'V':
|
case 'V':
|
||||||
version(argc, argv);
|
version(argc, argv);
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
args->dither = true;
|
args->dither = true;
|
||||||
break;
|
break;
|
||||||
|
@ -160,7 +174,7 @@ int parse_args(int argc, char **argv, asc_args_t *args)
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
{
|
{
|
||||||
int val = __find_value(__mode_options, optarg);
|
int val = __find_value((const __option_t*)asc_handlers, optarg);
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error: invalid mode '%s'\n", optarg);
|
fprintf(stderr, "Error: invalid mode '%s'\n", optarg);
|
||||||
|
@ -209,11 +223,14 @@ int parse_args(int argc, char **argv, asc_args_t *args)
|
||||||
fprintf(stderr, "Error: Unknown parameter -%c\n", optopt);
|
fprintf(stderr, "Error: Unknown parameter -%c\n", optopt);
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: UNREACHABLE: getopt switch gone wrong\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (args->out_style == ASC_STL_PALETTE && args->palette_filename == NULL)
|
if (args->out_style == ASC_STL_PALETTE && args->palette_filename == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error: no palette file provided, but palette mode selected\n");
|
fprintf(stderr, "Error: no palette file provided in palette mode\n");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
if (argc <= optind || argc < 2)
|
if (argc <= optind || argc < 2)
|
||||||
|
@ -225,11 +242,16 @@ int parse_args(int argc, char **argv, asc_args_t *args)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((annotate("oclint:suppress[high cyclomatic complexity]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[high npath complexity]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[high ncss method]")))
|
||||||
|
__attribute__((annotate("oclint:suppress[long method]")))
|
||||||
int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
{
|
{
|
||||||
(void)argc; (void)argv;
|
(void)argc; (void)argv;
|
||||||
state->args = args;
|
state->args = args;
|
||||||
|
|
||||||
|
// Loading image
|
||||||
FILE *image_file;
|
FILE *image_file;
|
||||||
if ((image_file = fopen(args.input_filename, "rb")) == NULL
|
if ((image_file = fopen(args.input_filename, "rb")) == NULL
|
||||||
|| ferror(image_file) != 0)
|
|| ferror(image_file) != 0)
|
||||||
|
@ -239,11 +261,13 @@ int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
args.input_filename, err, strerror(err));
|
args.input_filename, err, strerror(err));
|
||||||
return -100 - err;
|
return -100 - err;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
// Palette configuration
|
||||||
|
switch (args.out_style)
|
||||||
|
{
|
||||||
|
case ASC_STL_PALETTE:
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(args.palette_filename, "rb");
|
FILE *fp = fopen(args.palette_filename, "rb");
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
|
@ -262,10 +286,23 @@ int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if (args.out_style == ASC_STL_256COLOR)
|
case ASC_STL_256COLOR:
|
||||||
make_pal256(&c_palette_256, c_palette_ansi_vga);
|
make_pal256(&c_palette_256, c_palette_ansi_vga);
|
||||||
|
state->palette = &c_palette_256;
|
||||||
|
break;
|
||||||
|
case ASC_STL_ANSI_VGA:
|
||||||
|
case ASC_STL_ANSI_XTERM:
|
||||||
|
case ASC_STL_ANSI_DISCORD:
|
||||||
|
case ASC_STL_BLACKWHITE:
|
||||||
|
state->palette = get_palette_by_id(args.out_style);
|
||||||
|
break;
|
||||||
|
case ASC_STL_TRUECOLOR:
|
||||||
|
case ASC_STL_ENDL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output file configuration
|
||||||
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");
|
||||||
|
@ -276,6 +313,7 @@ int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state)
|
||||||
args.output_filename, err, strerror(err));
|
args.output_filename, err, strerror(err));
|
||||||
return -100 - err;
|
return -100 - err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/args.h
13
src/args.h
|
@ -69,6 +69,19 @@ typedef struct {
|
||||||
FILE *out_file;
|
FILE *out_file;
|
||||||
} asc_state_t;
|
} asc_state_t;
|
||||||
|
|
||||||
|
typedef void (*asc_module_initializer_fn)(asc_state_t *state);
|
||||||
|
typedef void (*asc_module_handler_fn)(asc_state_t state);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int id;
|
||||||
|
char *strings[8];
|
||||||
|
char *description;
|
||||||
|
asc_module_initializer_fn prepare;
|
||||||
|
asc_module_handler_fn main;
|
||||||
|
} asc_handler_t;
|
||||||
|
|
||||||
|
extern const asc_handler_t asc_handlers[ASC_MOD_ENDL + 1];
|
||||||
|
|
||||||
void usage(int argc, char **argv);
|
void usage(int argc, char **argv);
|
||||||
int parse_args(int argc, char **argv, asc_args_t *args);
|
int parse_args(int argc, char **argv, asc_args_t *args);
|
||||||
int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state);
|
int prepare_state(int argc, char **argv, asc_args_t args, asc_state_t *state);
|
||||||
|
|
10
src/colors.c
10
src/colors.c
|
@ -119,6 +119,11 @@ rgba8 pal256_to_rgb(palette_t pal, int ndx)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rgba8 clamp_to_pal(palette_t pal, rgba8 color)
|
||||||
|
{
|
||||||
|
return pal.palette[closest_color(pal, color)];
|
||||||
|
}
|
||||||
|
|
||||||
void make_pal256(palette_t *dst, palette_t ansi)
|
void make_pal256(palette_t *dst, palette_t ansi)
|
||||||
{
|
{
|
||||||
if (dst->n_colors == 256) return;
|
if (dst->n_colors == 256) return;
|
||||||
|
@ -175,12 +180,7 @@ bool load_palette(palette_t *pal, FILE *fp)
|
||||||
if (fread(head, sizeof(char), 12, fp) < 12) return false;
|
if (fread(head, sizeof(char), 12, fp) < 12) return false;
|
||||||
if (fseek(fp, 0, SEEK_SET) != 0) return false;
|
if (fseek(fp, 0, SEEK_SET) != 0) return false;
|
||||||
if (!strncmp(head, "GIMP Palette", 12))
|
if (!strncmp(head, "GIMP Palette", 12))
|
||||||
{
|
|
||||||
return load_palette_gpl(pal, fp);
|
return load_palette_gpl(pal, fp);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return load_palette_raw(pal, fp);
|
return load_palette_raw(pal, fp);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define PURE_BLACK ((rgba8){ 0, 0, 0, 0 })
|
#define PURE_BLACK ((rgba8){ 0, 0, 0, 0 })
|
||||||
|
#define RGBN(c) (c.r << 16 | c.g << 8 | c.b)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
|
@ -41,6 +42,7 @@ extern palette_t c_palette_ansi_xterm;
|
||||||
int color_difference(rgba8 a, rgba8 b);
|
int color_difference(rgba8 a, rgba8 b);
|
||||||
int closest_color(palette_t pal, rgba8 color);
|
int closest_color(palette_t pal, rgba8 color);
|
||||||
rgba8 pal256_to_rgb(palette_t pal, int ndx);
|
rgba8 pal256_to_rgb(palette_t pal, int ndx);
|
||||||
|
rgba8 clamp_to_pal(palette_t pal, rgba8 color);
|
||||||
void make_pal256(palette_t *dst, palette_t ansi);
|
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);
|
||||||
|
|
|
@ -3,41 +3,27 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void m_prepare_dither(asc_state_t *state)
|
void m_prepare_dither(asc_state_t *sta)
|
||||||
{
|
|
||||||
if (state->args.dither)
|
|
||||||
{
|
{
|
||||||
image_t *res = NULL;
|
image_t *res = NULL;
|
||||||
switch (state->args.out_style)
|
switch (sta->args.out_style)
|
||||||
{
|
{
|
||||||
case ASC_STL_BLACKWHITE:
|
case ASC_STL_BLACKWHITE:
|
||||||
res = image_dither(state->image, c_palette_bw);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_VGA:
|
case ASC_STL_ANSI_VGA:
|
||||||
res = image_dither(state->image, c_palette_ansi_vga);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_XTERM:
|
case ASC_STL_ANSI_XTERM:
|
||||||
res = image_dither(state->image, c_palette_ansi_xterm);
|
|
||||||
break;
|
|
||||||
case ASC_STL_ANSI_DISCORD:
|
case ASC_STL_ANSI_DISCORD:
|
||||||
res = image_dither(state->image, c_palette_ansi_discord);
|
|
||||||
break;
|
|
||||||
case ASC_STL_256COLOR:
|
case ASC_STL_256COLOR:
|
||||||
res = image_dither(state->image, c_palette_256);
|
res = image_dither(sta->image, *get_palette_by_id(sta->args.out_style));
|
||||||
break;
|
break;
|
||||||
case ASC_STL_PALETTE:
|
case ASC_STL_PALETTE:
|
||||||
res = image_dither(state->image, *state->palette);
|
res = image_dither(sta->image, *sta->palette);
|
||||||
break;
|
break;
|
||||||
case ASC_STL_TRUECOLOR:
|
case ASC_STL_TRUECOLOR:
|
||||||
case ASC_STL_ENDL:
|
case ASC_STL_ENDL:
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
if (res != NULL)
|
|
||||||
{
|
|
||||||
image_unload(state->image);
|
|
||||||
state->image = res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
image_unload(sta->image);
|
||||||
|
sta->image = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void c_fatal(int code, const char *reason)
|
void c_fatal(int code, const char *reason)
|
||||||
|
@ -45,3 +31,18 @@ void c_fatal(int code, const char *reason)
|
||||||
fprintf(stderr, "Error: %s\n", reason);
|
fprintf(stderr, "Error: %s\n", reason);
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
palette_t *get_palette_by_id(asc_style_t stl)
|
||||||
|
{
|
||||||
|
palette_t *pal = &c_palette_bw;
|
||||||
|
switch (stl)
|
||||||
|
{
|
||||||
|
case ASC_STL_BLACKWHITE: pal = &c_palette_bw; break;
|
||||||
|
case ASC_STL_ANSI_VGA: pal = &c_palette_ansi_vga; break;
|
||||||
|
case ASC_STL_ANSI_XTERM: pal = &c_palette_ansi_xterm; break;
|
||||||
|
case ASC_STL_ANSI_DISCORD: pal = &c_palette_ansi_discord; break;
|
||||||
|
case ASC_STL_256COLOR: pal = &c_palette_256; break;
|
||||||
|
default: c_fatal(9, "[UNREACH] Palette is unset"); break;
|
||||||
|
}
|
||||||
|
return pal;
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,10 @@
|
||||||
|
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
|
#define CLAMP(min, val, max) ((val)>(max)?(max):((val)<(min)?(min):(val)))
|
||||||
|
|
||||||
void c_fatal(int code, const char *reason);
|
void c_fatal(int code, const char *reason);
|
||||||
void m_prepare_dither(asc_state_t *state);
|
void m_prepare_dither(asc_state_t *state);
|
||||||
|
palette_t *get_palette_by_id(asc_style_t stl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef _FMT_STRINGS_H
|
||||||
|
#define _FMT_STRINGS_H
|
||||||
|
|
||||||
|
#define S_JSON_HEAD "{\n \"width\": %d,\n \"height\": %d,\n \"data\": [\n"
|
||||||
|
#define S_JSON_LSTA " [\n"
|
||||||
|
#define S_JSON_PRGB "{ \"char\": \"\\u%04x\", \"fg\": %d, \"bg\": %d }"
|
||||||
|
#define S_JSON_PBLK "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }"
|
||||||
|
#define S_JSON_LEND " ],\n"
|
||||||
|
#define S_JSON_LEND_FINAL " ]\n"
|
||||||
|
#define S_JSON_TAIL "}"
|
||||||
|
|
||||||
|
#define S_HTML_HEAD "<table style=\"border-collapse: collapse;\">\n"
|
||||||
|
#define S_HTML_LSTA "<tr>"
|
||||||
|
#define S_HTML_PCBR "<td style=\"color: rgb(%d, %d, %d); "\
|
||||||
|
"background: rgb(%d, %d, %d);\">&#%d;</td>"
|
||||||
|
#define S_HTML_PBLK "<td style=\"color: rgb(%d, %d, %d); "\
|
||||||
|
"background: rgb(%d, %d, %d);\">%s</td>"
|
||||||
|
#define S_HTML_LEND "</tr>\n"
|
||||||
|
#define S_HTML_TAIL "</table>"
|
||||||
|
|
||||||
|
#define S_ANSI "\033[%d;%dm"
|
||||||
|
#define S_ANSI_S "\033[%d;%dm%s"
|
||||||
|
#define S_ANSI_RGB "\033[38;2;%d;%d;%d;48;2;%d;%d;%dm"
|
||||||
|
#define S_ANSI_256 "\033[38;5;%d;48;5;%dm"
|
||||||
|
|
||||||
|
#endif
|
12
src/image.c
12
src/image.c
|
@ -1,3 +1,4 @@
|
||||||
|
#include "commons.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
#include "stb_image_resize.h"
|
#include "stb_image_resize.h"
|
||||||
|
@ -29,22 +30,19 @@ image_t *image_resize(image_t *img, int width, int height)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((annotate("oclint:suppress[high cyclomatic complexity]")))
|
||||||
void __dither_update_pixel(image_t *img, int x, int y, int err[3], float bias)
|
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;
|
if (x < 0 || x >= img->width || y < 0 || y >= img->height) return;
|
||||||
int i = x + y * img->width;
|
int i = x + y * img->width;
|
||||||
rgba8 pix = img->pixels[i];
|
rgba8 pix = img->pixels[i];
|
||||||
int dst[3] = { pix.r, pix.g, pix.b };
|
int dst[3] = { pix.r, pix.g, pix.b };
|
||||||
dst[0] += (int)(((float)err[0]) * bias);
|
img->pixels[i].r = CLAMP(0, dst[0] + (int)((float)err[0] * bias), 255);
|
||||||
dst[1] += (int)(((float)err[1]) * bias);
|
img->pixels[i].g = CLAMP(0, dst[1] + (int)((float)err[1] * bias), 255);
|
||||||
dst[2] += (int)(((float)err[2]) * bias);
|
img->pixels[i].b = CLAMP(0, dst[2] + (int)((float)err[2] * bias), 255);
|
||||||
img->pixels[i].r = (dst[0] > 255 ? 255 : (dst[0] < 0 ? 0 : dst[0]));
|
|
||||||
img->pixels[i].g = (dst[1] > 255 ? 255 : (dst[1] < 0 ? 0 : dst[1]));
|
|
||||||
img->pixels[i].b = (dst[2] > 255 ? 255 : (dst[2] < 0 ? 0 : dst[2]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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 *image_dither_fn(image_t *img, dither_quantizer_t quantize, void *param)
|
||||||
{
|
{
|
||||||
image_t *res = calloc(1, sizeof(image_t));
|
image_t *res = calloc(1, sizeof(image_t));
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int errno;
|
int err;
|
||||||
rgba8 *pixels;
|
rgba8 *pixels;
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
|
|
25
src/main.c
25
src/main.c
|
@ -22,6 +22,7 @@
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
#include "mod_blocks.h"
|
#include "mod_blocks.h"
|
||||||
#include "mod_braille.h"
|
#include "mod_braille.h"
|
||||||
|
#include "commons.h"
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -35,25 +36,11 @@ int main(int argc, char **argv)
|
||||||
if (res == 1) return 0;
|
if (res == 1) return 0;
|
||||||
if (res < 0) return -res;
|
if (res < 0) return -res;
|
||||||
|
|
||||||
switch (args.mode)
|
asc_handler_t handler = asc_handlers[args.mode];
|
||||||
{
|
if (handler.prepare == NULL)
|
||||||
case ASC_MOD_BLOCKS:
|
c_fatal(12, "this mode is not implemented yet");
|
||||||
mod_blocks_prepare(&state);
|
|
||||||
mod_blocks_main(state);
|
|
||||||
break;
|
|
||||||
case ASC_MOD_BRAILLE:
|
|
||||||
mod_braille_prepare(&state);
|
|
||||||
mod_braille_main(state);
|
|
||||||
break;
|
|
||||||
case ASC_MOD_GRADIENT:
|
|
||||||
fprintf(stderr, "Error: ASC_MOD_GRADIENT is not implemented yet\n");
|
|
||||||
break;
|
|
||||||
case ASC_MOD_BRUTEFORCE:
|
|
||||||
fprintf(stderr, "Error: ASC_MOD_BRUTEFORCE is not implemented yet\n");
|
|
||||||
break;
|
|
||||||
case ASC_MOD_ENDL:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
handler.prepare(&state);
|
||||||
|
handler.main(state);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include "commons.h"
|
#include "commons.h"
|
||||||
|
#include "fmt_strings.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" };
|
||||||
|
@ -16,6 +17,7 @@ void mod_blocks_prepare(asc_state_t *state)
|
||||||
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;
|
||||||
state->image = image_resize(state->source_image, w, h);
|
state->image = image_resize(state->source_image, w, h);
|
||||||
|
if (state->args.dither)
|
||||||
m_prepare_dither(state);
|
m_prepare_dither(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,16 +57,10 @@ void __blk_end_output(asc_state_t state)
|
||||||
void __blk_start_line(FILE *fp, asc_format_t fmt, bool final)
|
void __blk_start_line(FILE *fp, asc_format_t fmt, bool final)
|
||||||
{
|
{
|
||||||
(void)final;
|
(void)final;
|
||||||
switch (fmt)
|
if (fmt == ASC_FMT_JSON)
|
||||||
{
|
fprintf(fp, S_JSON_LSTA);
|
||||||
case ASC_FMT_JSON:
|
else if (fmt == ASC_FMT_HTML)
|
||||||
fprintf(fp, " [\n");
|
fprintf(fp, S_HTML_LSTA);
|
||||||
break;
|
|
||||||
case ASC_FMT_HTML:
|
|
||||||
fprintf(fp, "<tr>");
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __blk_end_line(FILE *fp, asc_format_t fmt, asc_style_t stl, bool final)
|
void __blk_end_line(FILE *fp, asc_format_t fmt, asc_style_t stl, bool final)
|
||||||
|
@ -108,20 +104,15 @@ void __blk_putc_ansi(FILE *fp, asc_format_t fmt, bool final, int ct, int cb, pal
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"%s\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, S_JSON_PBLK, BLOCKS_ESC[1], 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, S_HTML_PBLK, 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, BLOCKS[1]);
|
||||||
bot_rgb.r, bot_rgb.g, bot_rgb.b,
|
|
||||||
BLOCKS[1]);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(fp, "\033[%d;%dm%s",
|
fprintf(fp, S_ANSI_S, ct + (ct >= 8 ? 82 : 30), cb + (cb >= 8 ? 92 : 40),
|
||||||
ct + (ct >= 8 ? 82 : 30),
|
|
||||||
cb + (cb >= 8 ? 92 : 40),
|
|
||||||
BLOCKS[1]);
|
BLOCKS[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -193,17 +184,10 @@ void __blk_put_pixel(asc_state_t state, rgba8 top, rgba8 bot, bool final)
|
||||||
case ASC_STL_ANSI_XTERM:
|
case ASC_STL_ANSI_XTERM:
|
||||||
case ASC_STL_ANSI_DISCORD:
|
case ASC_STL_ANSI_DISCORD:
|
||||||
{
|
{
|
||||||
palette_t pal;
|
palette_t *pal = get_palette_by_id(state.args.out_style);
|
||||||
switch (state.args.out_style)
|
int index_top = closest_color(*pal, top),
|
||||||
{
|
index_bot = closest_color(*pal, bot);
|
||||||
case ASC_STL_ANSI_VGA: pal = c_palette_ansi_vga; break;
|
__blk_putc_ansi(fp, fmt, final, index_top, index_bot, *pal);
|
||||||
case ASC_STL_ANSI_XTERM: pal = c_palette_ansi_xterm; break;
|
|
||||||
case ASC_STL_ANSI_DISCORD: pal = c_palette_ansi_discord; break;
|
|
||||||
default: c_fatal(9, "[UNREACH] Palette is unset"); return;
|
|
||||||
}
|
|
||||||
int index_top = closest_color(pal, top),
|
|
||||||
index_bot = closest_color(pal, bot);
|
|
||||||
__blk_putc_ansi(fp, fmt, final, index_top, index_bot, pal);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_STL_256COLOR:
|
case ASC_STL_256COLOR:
|
||||||
|
@ -219,10 +203,10 @@ void __blk_put_pixel(asc_state_t state, rgba8 top, rgba8 bot, bool final)
|
||||||
case ASC_STL_PALETTE:
|
case ASC_STL_PALETTE:
|
||||||
{
|
{
|
||||||
palette_t *pal = state.palette;
|
palette_t *pal = state.palette;
|
||||||
rgba8 pal_top = pal->palette[closest_color(*pal, top)];
|
__blk_putc_truecolor(fp, fmt, final,
|
||||||
rgba8 pal_bot = pal->palette[closest_color(*pal, bot)];
|
clamp_to_pal(*pal, top), clamp_to_pal(*pal, bot));
|
||||||
__blk_putc_truecolor(fp, fmt, final, pal_top, pal_bot);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case ASC_STL_ENDL:
|
case ASC_STL_ENDL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,31 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include "commons.h"
|
#include "commons.h"
|
||||||
|
#include "fmt_strings.h"
|
||||||
|
|
||||||
int __bra_best_match_i(rgba8 a, rgba8 b, rgba8 t);
|
int __bra_best_match_i(rgba8 a, rgba8 b, rgba8 t);
|
||||||
void __bra_putc_raw(asc_state_t state, uint8_t ch);
|
void __bra_putc_raw(asc_state_t s, uint8_t ch);
|
||||||
void __bra_putc_esc(asc_state_t state, uint8_t ch);
|
void __bra_putc_esc(asc_state_t s, uint8_t ch);
|
||||||
void __bra_start_output(asc_state_t state);
|
void __bra_start_output(asc_state_t s);
|
||||||
void __bra_start_line(asc_state_t state, bool final);
|
void __bra_start_line(asc_state_t s, bool final);
|
||||||
void __bra_put_pixel(asc_state_t sta, rgba8 min, rgba8 max, uint8_t ch, bool final);
|
void __bra_put_pixel(asc_state_t s, rgba8 bg, rgba8 fg, uint8_t ch, bool final);
|
||||||
void __bra_putc_ansi(asc_state_t state, int i_min, int i_max, uint8_t ch, palette_t pal, bool final);
|
void __bra_putc_ansi(asc_state_t s, int bg, int fg, uint8_t ch, palette_t pal, bool final);
|
||||||
void __bra_putc_256(asc_state_t state, int i_min, int i_max, uint8_t ch, bool final);
|
void __bra_putc_256(asc_state_t s, int bg, int fg, uint8_t ch, bool final);
|
||||||
void __bra_putc_true(asc_state_t state, rgba8 min, rgba8 max, uint8_t ch, bool final);
|
void __bra_putc_true(asc_state_t s, rgba8 bg, rgba8 fg, uint8_t ch, bool final);
|
||||||
void __bra_end_line(asc_state_t state, bool final);
|
void __bra_end_line(asc_state_t s, bool final);
|
||||||
void __bra_end_output(asc_state_t state);
|
void __bra_end_output(asc_state_t s);
|
||||||
|
|
||||||
|
void __bra_update2x4(image_t *img, rgba8 block[8], int x, int y)
|
||||||
|
{
|
||||||
|
block[0] = img->pixels[(x + 0) + (y + 0) * img->width];
|
||||||
|
block[3] = img->pixels[(x + 1) + (y + 0) * img->width];
|
||||||
|
block[1] = img->pixels[(x + 0) + (y + 1) * img->width];
|
||||||
|
block[4] = img->pixels[(x + 1) + (y + 1) * img->width];
|
||||||
|
block[2] = img->pixels[(x + 0) + (y + 2) * img->width];
|
||||||
|
block[5] = img->pixels[(x + 1) + (y + 2) * img->width];
|
||||||
|
block[6] = img->pixels[(x + 0) + (y + 3) * img->width];
|
||||||
|
block[7] = img->pixels[(x + 1) + (y + 3) * img->width];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mod_braille_prepare(asc_state_t *state)
|
void mod_braille_prepare(asc_state_t *state)
|
||||||
|
@ -25,6 +38,7 @@ void mod_braille_prepare(asc_state_t *state)
|
||||||
state->args.width * 2, state->args.height * 4, &w, &h);
|
state->args.width * 2, state->args.height * 4, &w, &h);
|
||||||
w = (w / 2) * 2; h = (h / 4) * 4;
|
w = (w / 2) * 2; h = (h / 4) * 4;
|
||||||
state->image = image_resize(state->source_image, w, h);
|
state->image = image_resize(state->source_image, w, h);
|
||||||
|
if (state->args.dither)
|
||||||
m_prepare_dither(state);
|
m_prepare_dither(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +47,7 @@ void mod_braille_main(asc_state_t state)
|
||||||
image_t *img = state.image;
|
image_t *img = state.image;
|
||||||
|
|
||||||
uint8_t braille_char = 0x00;
|
uint8_t braille_char = 0x00;
|
||||||
rgba8 pix2x4[8];
|
rgba8 block[8];
|
||||||
|
|
||||||
rgba8 color_max, color_min;
|
rgba8 color_max, color_min;
|
||||||
int dist_max, dist_min, dist_min_d = 0xffffff, dist;
|
int dist_max, dist_min, dist_min_d = 0xffffff, dist;
|
||||||
|
@ -45,37 +59,30 @@ void mod_braille_main(asc_state_t state)
|
||||||
__bra_start_line(state, final);
|
__bra_start_line(state, final);
|
||||||
for (int x = 0; x < img->width; x += 2)
|
for (int x = 0; x < img->width; x += 2)
|
||||||
{
|
{
|
||||||
pix2x4[0] = img->pixels[(x + 0) + (y + 0) * img->width];
|
__bra_update2x4(img, block, x, y);
|
||||||
pix2x4[3] = img->pixels[(x + 1) + (y + 0) * img->width];
|
color_max = color_min = block[0];
|
||||||
pix2x4[1] = img->pixels[(x + 0) + (y + 1) * img->width];
|
|
||||||
pix2x4[4] = img->pixels[(x + 1) + (y + 1) * img->width];
|
|
||||||
pix2x4[2] = img->pixels[(x + 0) + (y + 2) * img->width];
|
|
||||||
pix2x4[5] = img->pixels[(x + 1) + (y + 2) * img->width];
|
|
||||||
pix2x4[6] = img->pixels[(x + 0) + (y + 3) * img->width];
|
|
||||||
pix2x4[7] = img->pixels[(x + 1) + (y + 3) * img->width];
|
|
||||||
color_max = color_min = pix2x4[0];
|
|
||||||
|
|
||||||
dist_max = 0;
|
dist_max = 0;
|
||||||
dist_min = dist_min_d;
|
dist_min = dist_min_d;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
dist = color_difference(pix2x4[i], PURE_BLACK);
|
dist = color_difference(block[i], PURE_BLACK);
|
||||||
if (dist < dist_min)
|
if (dist < dist_min)
|
||||||
{
|
{
|
||||||
dist_min = dist;
|
dist_min = dist;
|
||||||
color_min = pix2x4[i];
|
color_min = block[i];
|
||||||
}
|
}
|
||||||
if (dist > dist_max)
|
if (dist > dist_max)
|
||||||
{
|
{
|
||||||
dist_max = dist;
|
dist_max = dist;
|
||||||
color_max = pix2x4[i];
|
color_max = block[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
braille_char = 0x00;
|
braille_char = 0x00;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (__bra_best_match_i(color_min, color_max, pix2x4[i]) != 0)
|
if (__bra_best_match_i(color_min, color_max, block[i]) != 0)
|
||||||
{
|
{
|
||||||
braille_char |= (1 << i);
|
braille_char |= (1 << i);
|
||||||
}
|
}
|
||||||
|
@ -107,72 +114,45 @@ void __bra_putc_esc(asc_state_t state, uint8_t ch)
|
||||||
|
|
||||||
void __bra_start_output(asc_state_t state)
|
void __bra_start_output(asc_state_t state)
|
||||||
{
|
{
|
||||||
switch (state.args.out_format)
|
int w = state.image->width / 2, h = state.image->height / 4;
|
||||||
{
|
if (state.args.out_format == ASC_FMT_JSON)
|
||||||
case ASC_FMT_JSON:
|
fprintf(state.out_file, S_JSON_HEAD, w, h);
|
||||||
fprintf(state.out_file, "{\n");
|
else if (state.args.out_format == ASC_FMT_HTML)
|
||||||
fprintf(state.out_file, " \"width\": %d,\n", state.image->width / 2);
|
fprintf(state.out_file, S_HTML_HEAD);
|
||||||
fprintf(state.out_file, " \"height\": %d,\n", state.image->height / 4);
|
|
||||||
fprintf(state.out_file, " \"data\": [");
|
|
||||||
break;
|
|
||||||
case ASC_FMT_HTML:
|
|
||||||
fprintf(state.out_file, "<table style=\"border-collapse: collapse;\">\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_start_line(asc_state_t state, bool final)
|
void __bra_start_line(asc_state_t state, bool final)
|
||||||
{
|
{
|
||||||
(void)final;
|
(void)final;
|
||||||
switch (state.args.out_format)
|
if (state.args.out_format == ASC_FMT_JSON)
|
||||||
{
|
fprintf(state.out_file, S_JSON_LSTA);
|
||||||
case ASC_FMT_JSON:
|
else if (state.args.out_format == ASC_FMT_HTML)
|
||||||
fprintf(state.out_file, " [\n");
|
fprintf(state.out_file, S_HTML_LSTA);
|
||||||
break;
|
|
||||||
case ASC_FMT_HTML:
|
|
||||||
fprintf(state.out_file, "<tr>");
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_put_pixel(asc_state_t state, rgba8 min, rgba8 max, uint8_t ch, bool final)
|
void __bra_put_pixel(asc_state_t s, rgba8 min, rgba8 max, uint8_t ch, bool fin)
|
||||||
{
|
{
|
||||||
switch (state.args.out_style)
|
switch (s.args.out_style)
|
||||||
{
|
{
|
||||||
case ASC_STL_ANSI_VGA:
|
case ASC_STL_ANSI_VGA:
|
||||||
case ASC_STL_ANSI_XTERM:
|
case ASC_STL_ANSI_XTERM:
|
||||||
case ASC_STL_ANSI_DISCORD:
|
case ASC_STL_ANSI_DISCORD:
|
||||||
{
|
{
|
||||||
palette_t pal;
|
palette_t pal = *get_palette_by_id(s.args.out_style);
|
||||||
switch (state.args.out_style)
|
__bra_putc_ansi(s,
|
||||||
{
|
closest_color(pal, min), closest_color(pal, max), ch, pal, fin);
|
||||||
case ASC_STL_ANSI_VGA: pal = c_palette_ansi_vga; break;
|
|
||||||
case ASC_STL_ANSI_XTERM: pal = c_palette_ansi_xterm; break;
|
|
||||||
case ASC_STL_ANSI_DISCORD: pal = c_palette_ansi_discord; break;
|
|
||||||
default: c_fatal(9, "[UNREACH] Palette is unset"); return;
|
|
||||||
}
|
|
||||||
__bra_putc_ansi(state,
|
|
||||||
closest_color(pal, min), closest_color(pal, max), ch, pal, final);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASC_STL_256COLOR:
|
case ASC_STL_256COLOR:
|
||||||
{
|
__bra_putc_256(s, closest_color(c_palette_256, min),
|
||||||
__bra_putc_256(state, closest_color(c_palette_256, min),
|
closest_color(c_palette_256, max), ch, fin);
|
||||||
closest_color(c_palette_256, max), ch, final);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ASC_STL_TRUECOLOR:
|
case ASC_STL_TRUECOLOR:
|
||||||
__bra_putc_true(state, min, max, ch, final);
|
__bra_putc_true(s, min, max, ch, fin);
|
||||||
break;
|
break;
|
||||||
case ASC_STL_PALETTE:
|
case ASC_STL_PALETTE:
|
||||||
{
|
__bra_putc_true(s, clamp_to_pal(*s.palette, min),
|
||||||
palette_t *pal = state.palette;
|
clamp_to_pal(*s.palette, max), ch, fin);
|
||||||
__bra_putc_true(state, pal->palette[closest_color(*pal, min)],
|
|
||||||
pal->palette[closest_color(*pal, max)], ch, final);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ASC_STL_BLACKWHITE:
|
case ASC_STL_BLACKWHITE:
|
||||||
case ASC_STL_ENDL:
|
case ASC_STL_ENDL:
|
||||||
|
@ -180,115 +160,93 @@ void __bra_put_pixel(asc_state_t state, rgba8 min, rgba8 max, uint8_t ch, bool f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_putc_ansi(asc_state_t state, int i_min, int i_max, uint8_t ch, palette_t pal, bool final)
|
void __bra_putc_ansi
|
||||||
|
(asc_state_t s, int bgi, int fgi, uint8_t ch, palette_t pal, bool fin)
|
||||||
{
|
{
|
||||||
rgba8 min_rgb = pal.palette[i_min], max_rgb = pal.palette[i_max];
|
rgba8 bg = pal.palette[bgi], fg = pal.palette[fgi];
|
||||||
int min_int = min_rgb.r << 16 | min_rgb.g << 8 | min_rgb.b;
|
FILE *fp = s.out_file;
|
||||||
int max_int = max_rgb.r << 16 | max_rgb.g << 8 | max_rgb.b;
|
switch (s.args.out_format)
|
||||||
FILE *fp = state.out_file;
|
|
||||||
switch (state.args.out_format)
|
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"\\u28%d\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, S_JSON_PRGB, ch, RGBN(fg), RGBN(bg));
|
||||||
ch, max_int, min_int);
|
if (!fin) 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);\">&#%d;</td>",
|
fprintf(fp, S_HTML_PCBR, fg.r, fg.g, fg.b,
|
||||||
max_rgb.r, max_rgb.g, max_rgb.b, min_rgb.r, min_rgb.g, min_rgb.b,
|
bg.r, bg.g, bg.b, 0x2800 | ch);
|
||||||
0x2800 | ch);
|
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_ANSI:
|
case ASC_FMT_ANSI:
|
||||||
fprintf(fp, "\033[%d;%dm", i_max + (i_max > 8 ? 82 : 30), i_min + (i_min > 8 ? 82 : 30));
|
fprintf(fp, S_ANSI, fgi + (fgi > 8 ? 82 : 30), bgi + (bgi > 8 ? 82 : 30));
|
||||||
__bra_putc_raw(state, ch);
|
__bra_putc_raw(s, ch);
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_ENDL:
|
case ASC_FMT_ENDL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_putc_256(asc_state_t state, int i_min, int i_max, uint8_t ch, bool final)
|
void __bra_putc_256(asc_state_t s, int bgi, int fgi, uint8_t ch, bool final)
|
||||||
{
|
{
|
||||||
rgba8 min_rgb = c_palette_256.palette[i_min];
|
rgba8 bg = c_palette_256.palette[bgi];
|
||||||
rgba8 max_rgb = c_palette_256.palette[i_max];
|
rgba8 fg = c_palette_256.palette[fgi];
|
||||||
int min_int = min_rgb.r << 16 | min_rgb.g << 8 | min_rgb.b;
|
FILE *fp = s.out_file;
|
||||||
int max_int = max_rgb.r << 16 | max_rgb.g << 8 | max_rgb.b;
|
switch (s.args.out_format)
|
||||||
FILE *fp = state.out_file;
|
|
||||||
switch (state.args.out_format)
|
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
case ASC_FMT_JSON:
|
||||||
fprintf(fp, "{ \"char\": \"\\u28%d\", \"fg\": %d, \"bg\": %d }",
|
fprintf(fp, S_JSON_PRGB, 0x2800 | ch, RGBN(fg), RGBN(bg));
|
||||||
ch, max_int, min_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);\">&#%d;</td>",
|
fprintf(fp, S_HTML_PCBR, fg.r, fg.g, fg.b, bg.r, bg.g, bg.b, 0x2800 | ch);
|
||||||
max_rgb.r, max_rgb.g, max_rgb.b, min_rgb.r, min_rgb.g, min_rgb.b,
|
|
||||||
0x2800 | ch);
|
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_ANSI:
|
case ASC_FMT_ANSI:
|
||||||
fprintf(fp, "\033[38;5;%d;48;5;%dm", i_max, i_min);
|
fprintf(fp, S_ANSI_256, fgi, bgi);
|
||||||
__bra_putc_raw(state, ch);
|
__bra_putc_raw(s, ch);
|
||||||
break;
|
break;
|
||||||
case ASC_FMT_ENDL:
|
case ASC_FMT_ENDL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_putc_true(asc_state_t state, rgba8 min, rgba8 max, uint8_t ch, bool final)
|
void __bra_putc_true(asc_state_t s, rgba8 bg, rgba8 fg, uint8_t ch, bool fin)
|
||||||
{
|
{
|
||||||
int max_int = max.r << 16 | max.g << 8 | max.b;
|
int max_int = fg.r << 16 | fg.g << 8 | fg.b;
|
||||||
int min_int = min.r << 16 | min.g << 8 | min.b;
|
int min_int = bg.r << 16 | bg.g << 8 | bg.b;
|
||||||
FILE *fp = state.out_file;
|
FILE *fp = s.out_file;
|
||||||
switch (state.args.out_format)
|
if (s.args.out_format == ASC_FMT_JSON)
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
fprintf(fp, S_JSON_PRGB, 0x2800 | ch, max_int, min_int);
|
||||||
fprintf(fp, "{ \"char\": \"\\u%d\", \"fg\": %d, \"bg\": %d }",
|
if (!fin) fprintf(fp, ", ");
|
||||||
0x2800 | ch, max_int, min_int);
|
}
|
||||||
if (!final) fprintf(fp, ", ");
|
else if (s.args.out_format == ASC_FMT_HTML)
|
||||||
break;
|
{
|
||||||
case ASC_FMT_HTML:
|
fprintf(fp, S_HTML_PCBR, fg.r, fg.g, fg.b, bg.r, bg.g, bg.b, 0x2800 | ch);
|
||||||
fprintf(fp, "<td style=\"color: rgb(%d, %d, %d); background: rgb(%d, %d, %d);\">&#%d;</td>",
|
}
|
||||||
max.r, max.g, max.b, min.r, min.g, min.b, 0x2800 | ch);
|
else
|
||||||
break;
|
{
|
||||||
default:
|
fprintf(fp, S_ANSI_RGB, fg.r, fg.g, fg.b, bg.r, bg.g, bg.b);
|
||||||
fprintf(fp, "\033[38;2;%d;%d;%d;48;2;%d;%d;%dm",
|
__bra_putc_raw(s, ch);
|
||||||
max.r, max.g, max.b, min.r, min.g, min.b);
|
|
||||||
__bra_putc_raw(state, ch);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_end_line(asc_state_t state, bool final)
|
void __bra_end_line(asc_state_t state, bool final)
|
||||||
{
|
{
|
||||||
switch (state.args.out_format)
|
if (state.args.out_format == ASC_FMT_JSON)
|
||||||
|
fprintf(state.out_file, final ? S_JSON_LEND_FINAL : S_JSON_LEND);
|
||||||
|
else if (state.args.out_format == ASC_FMT_HTML)
|
||||||
|
fprintf(state.out_file, S_HTML_LEND);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case ASC_FMT_JSON:
|
|
||||||
fprintf(state.out_file, final ? " ]\n" : " ],\n");
|
|
||||||
break;
|
|
||||||
case ASC_FMT_HTML:
|
|
||||||
fprintf(state.out_file, "</tr>\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (state.args.out_style != ASC_STL_BLACKWHITE)
|
if (state.args.out_style != ASC_STL_BLACKWHITE)
|
||||||
fprintf(state.out_file, "\033[0m");
|
fprintf(state.out_file, "\033[0m");
|
||||||
fprintf(state.out_file, "\n");
|
fprintf(state.out_file, "\n");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bra_end_output(asc_state_t state)
|
void __bra_end_output(asc_state_t state)
|
||||||
{
|
{
|
||||||
switch (state.args.out_format)
|
if (state.args.out_format == ASC_FMT_JSON)
|
||||||
{
|
|
||||||
case ASC_FMT_JSON:
|
|
||||||
fprintf(state.out_file, " ]\n}");
|
fprintf(state.out_file, " ]\n}");
|
||||||
break;
|
else if (state.args.out_format == ASC_FMT_HTML)
|
||||||
case ASC_FMT_HTML:
|
|
||||||
fprintf(state.out_file, "</table>\n");
|
fprintf(state.out_file, "</table>\n");
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue