Add x86_64-linux-gnu emulator

I wanted a tiny scriptable meltdown proof way to run userspace programs
and visualize how program execution impacts memory. It helps to explain
how things like Actually Portable Executable works. It can show you how
the GCC generated code is going about manipulating matrices and more. I
didn't feel fully comfortable with Qemu and Bochs because I'm not smart
enough to understand them. I wanted something like gVisor but with much
stronger levels of assurances. I wanted a single binary that'll run, on
all major operating systems with an embedded GPL barrier ZIP filesystem
that is tiny enough to transpile to JavaScript and run in browsers too.

https://justine.storage.googleapis.com/emulator625.mp4
This commit is contained in:
Justine Tunney 2020-08-25 04:23:25 -07:00
parent 467504308a
commit f4f4caab0e
1052 changed files with 65667 additions and 7825 deletions

View file

@ -26,7 +26,7 @@
Getting started:
nroff -mandoc -rLL=72n -rLT=78n -Tutf8 <manpage.1 |
tool/viz/ascii2utf8.com
o/tool/viz/ascii2utf8.com
ASCII Bold:

View file

@ -517,7 +517,7 @@ static void LoadFile(const char *path, size_t yn, size_t xn, void *rgb) {
CHECK_NE(-1, fstat(fd, &st));
CHECK_GT(st.st_size, 0);
CHECK_LE(st.st_size, INT_MAX);
LOGIFNEG1(fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL));
/* LOGIFNEG1(fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL)); */
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
CHECK_NOTNULL((data = stbi_load_from_memory(map, st.st_size, &gotx, &goty,

View file

@ -42,8 +42,8 @@ typedef double (*round_f)(double);
typedef unsigned long (*rand_f)(void);
struct Range {
double a;
double b;
long double a;
long double b;
};
short xn_ = 8;
@ -273,7 +273,8 @@ static void *SetRandom(long n, long p[n]) {
return p;
}
static double ConvertRange(double x, double a, double b, double c, double d) {
static long double ConvertRange(long double x, long double a, long double b,
long double c, long double d) {
return (d - c) / (b - a) * (x - a) + c;
}

View file

@ -4,7 +4,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/* clang-format off */
#define CONVROUND(X) ((int)lrint(X))
#define CONVROUND(X) ((int)rint(X))
#define CONVOLVE1X1(COEFFICIENT, DY, DX) (COEFFICIENT * (img[iy[y DY]][ix[x DX]]))
#define CONVOLVE1X12(IMG, COEFFICIENT, DY, DX) (COEFFICIENT * IMG[iy[y DY]][ix[x DX]])

View file

@ -18,13 +18,16 @@
02110-1301 USA
*/
#include "libc/bits/bits.h"
#include "libc/bits/initializer.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "tool/viz/lib/graphic.h"
static int perm[513];
static double lerp(double t, double a, double b) { return a + t * (b - a); }
static double lerp(double t, double a, double b) {
return a + t * (b - a);
}
static double fade(double t) {
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);

View file

@ -79,20 +79,6 @@ o/$(MODE)/tool/viz/lib/resizegraphic.o: \
-DSTACK_FRAME_UNLIMITED \
$(MATHEMATICAL)
#o/$(MODE)/tool/viz/lib/scale.o \
o/$(MODE)/tool/viz/lib/writetoframebuffer.o \
o/$(MODE)/tool/viz/lib/interlace.o \
o/$(MODE)/tool/viz/lib/magicscale.o \
o/$(MODE)/tool/viz/lib/halfblit.o \
o/$(MODE)/tool/viz/lib/byte2float.o \
o/$(MODE)/tool/viz/lib/ycbcr2rgb2.o \
o/$(MODE)/tool/viz/lib/magickernel.o \
o/$(MODE)/tool/viz/lib/lolquist.o \
o/$(MODE)/tool/viz/lib/getxtermcodes.o \
o/$(MODE)/tool/viz/lib/unsharp.o \
o/$(MODE)/tool/viz/lib/gaussian.o: \
CC = $(CLANG)
o/$(MODE)/tool/viz/lib/printmatrix.o: \
OVERRIDE_CFLAGS += \
$(IEEE_MATH)

View file

@ -233,7 +233,7 @@ void YCbCr2Rgb(long yn, long xn, unsigned char RGB[restrict 3][yn][xn],
short y, u, v, r, g, b, A, B, C;
for (i = 0; i < yn; ++i) {
for (j = 0; j < xn; ++j) {
y = Y[i][j];
y = T[Y[i][j]];
u = Cb[i][j] - K[3][1];
v = Cr[i][j] - K[3][1];
r = y + QRS(M, v * K[0][0]);

View file

@ -17,11 +17,19 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/core/twixt8.h"
#include "dsp/scale/scale.h"
#include "dsp/tty/quant.h"
#include "dsp/tty/tty.h"
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/struct/winsize.h"
#include "libc/conv/conv.h"
#include "libc/dce.h"
#include "libc/limits.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
@ -34,51 +42,128 @@
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/madv.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/termios.h"
#include "libc/x/x.h"
#include "third_party/getopt/getopt.h"
#include "third_party/stb/stb_image.h"
#define LERP(X, Y, P) (((X) + (SAR((P) * ((Y) - (X)), 8))) & 0xff)
#include "tool/viz/lib/graphic.h"
static struct Flags {
const char *out;
bool subpixel;
bool unsharp;
bool dither;
bool ruler;
long half;
bool full;
long width;
long height;
enum TtyBlocksSelection blocks;
enum TtyQuantizationAlgorithm quant;
} g_flags;
static noreturn void PrintUsage(int rc, FILE *f) {
fprintf(f, "Usage: %s%s", program_invocation_name, "\
[FLAGS] [PATH]\n\
\n\
Flags:\n\
FLAGS\n\
\n\
-o PATH output path\n\
-w INT manual width\n\
-w INT manual height\n\
-4 unicode blocks\n\
-a ansi color mode\n\
-t true color mode\n\
-2 use half blocks\n\
-3 ibm cp437 blocks\n\
-f display full size\n\
-s unsharp sharpening\n\
-x xterm256 color mode\n\
-d hilbert curve dithering\n\
-r display pixel ruler on sides\n\
-p convert to subpixel layout\n\
-v increases verbosity\n\
-? shows this information\n\
\n\
EXAMPLES\n\
\n\
printimage.com -sxd lemurs.jpg # 256-color dither unsharp\n\
\n\
\n");
exit(rc);
}
static int ParseNumberOption(const char *arg) {
long x;
x = strtol(arg, NULL, 0);
if (!(1 <= x && x <= INT_MAX)) {
fprintf(stderr, "invalid flexidecimal: %s\n\n", arg);
exit(EXIT_FAILURE);
}
return x;
}
static void GetOpts(int *argc, char *argv[]) {
int opt;
struct winsize ws;
g_flags.quant = kTtyQuantTrue;
g_flags.blocks = IsWindows() ? kTtyBlocksCp437 : kTtyBlocksUnicode;
if (*argc == 2 &&
(strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-help") == 0)) {
PrintUsage(EXIT_SUCCESS, stdout);
}
while ((opt = getopt(*argc, argv, "?vpo:")) != -1) {
while ((opt = getopt(*argc, argv, "?vpfrtxads234o:w:h:")) != -1) {
switch (opt) {
case 'o':
g_flags.out = optarg;
break;
case 'v':
++g_loglevel;
case 'd':
g_flags.dither = true;
break;
case 's':
g_flags.unsharp = true;
break;
case 'w':
g_flags.width = ParseNumberOption(optarg);
break;
case 'h':
g_flags.height = ParseNumberOption(optarg);
break;
case 'f':
g_flags.full = true;
break;
case '2':
g_flags.half = true;
break;
case 'r':
g_flags.ruler = true;
break;
case 'p':
g_flags.subpixel = true;
break;
case 'a':
g_flags.quant = kTtyQuantAnsi;
break;
case 'x':
g_flags.quant = kTtyQuantXterm256;
break;
case 't':
g_flags.quant = kTtyQuantTrue;
break;
case '3':
g_flags.blocks = kTtyBlocksCp437;
break;
case '4':
g_flags.blocks = kTtyBlocksUnicode;
break;
case 'v':
++g_loglevel;
break;
case '?':
PrintUsage(EXIT_SUCCESS, stdout);
default:
@ -89,6 +174,16 @@ static void GetOpts(int *argc, char *argv[]) {
if (!g_flags.out) g_flags.out = "-";
argv[(*argc)++] = "-";
}
if (!g_flags.full && (!g_flags.width || !g_flags.width)) {
ws.ws_col = 80;
ws.ws_row = 24;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != -1 ||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
g_flags.width = ws.ws_col * (1 + !g_flags.half);
g_flags.height = ws.ws_row * 2;
}
}
ttyquantsetup(g_flags.quant, kTtyQuantRgb, g_flags.blocks);
}
static unsigned char ChessBoard(unsigned y, unsigned x, unsigned char a,
@ -104,15 +199,6 @@ static unsigned char OutOfBoundsBackground(unsigned y, unsigned x) {
return ChessBoard(y, x, 40, 80);
}
static unsigned char Opacify(long yn, long xn, const unsigned char P[yn][xn],
const unsigned char A[yn][xn], long y, long x) {
if ((0 <= y && y < yn) && (0 <= x && x < xn)) {
return LERP(AlphaBackground(y, x), P[y][x], A[y][x]);
} else {
return OutOfBoundsBackground(y, x);
}
}
static void PrintRulerRight(long yn, long xn, long y, long x,
bool *inout_didhalfy) {
if (y == 0) {
@ -133,8 +219,8 @@ static void PrintRulerRight(long yn, long xn, long y, long x,
}
static void PrintImageImpl(long syn, long sxn, unsigned char RGB[3][syn][sxn],
long y0, long yn, long x0, long xn, bool rule,
long dy, long dx) {
long y0, long yn, long x0, long xn, long dy,
long dx) {
long y, x;
bool didhalfy, didfirstx;
unsigned char a[3], b[3];
@ -157,31 +243,56 @@ static void PrintImageImpl(long syn, long sxn, unsigned char RGB[3][syn][sxn],
b[2], dy > 1 ? u'' : u'');
didfirstx = true;
}
if (rule) PrintRulerRight(yn, xn, y, x, &didhalfy);
if (g_flags.ruler) {
PrintRulerRight(yn, xn, y, x, &didhalfy);
}
}
printf("\e[0m\n");
}
static void PrintImage(long syn, long sxn, unsigned char RGB[3][syn][sxn],
long y0, long yn, long x0, long xn, bool rule) {
PrintImageImpl(syn, sxn, RGB, y0, yn, x0, xn, rule, 2, 1);
long y0, long yn, long x0, long xn) {
PrintImageImpl(syn, sxn, RGB, y0, yn, x0, xn, 2, 1);
}
static void PrintImageLR(long syn, long sxn, unsigned char RGB[3][syn][sxn],
long y0, long yn, long x0, long xn, bool rule) {
PrintImageImpl(syn, sxn, RGB, y0, yn, x0, xn, rule, 1, 2);
long y0, long yn, long x0, long xn) {
PrintImageImpl(syn, sxn, RGB, y0, yn, x0, xn, 1, 2);
}
static void *Deblinterlace(long dyn, long dxn, unsigned char dst[3][dyn][dxn],
long syn, long sxn,
const unsigned char src[syn][sxn][4], long y0,
long syn, long sxn, long scn,
const unsigned char src[syn][sxn][scn], long y0,
long yn, long x0, long xn) {
long y, x;
unsigned char c;
for (y = y0; y < yn; ++y) {
for (x = x0; x < xn; ++x) {
dst[0][y][x] = src[y][x][0];
dst[1][y][x] = src[y][x][1];
dst[2][y][x] = src[y][x][2];
switch (scn) {
case 1:
c = src[y][x][0];
dst[0][y][x] = c;
dst[1][y][x] = c;
dst[2][y][x] = c;
break;
case 2:
c = twixt8(AlphaBackground(y, x), src[y][x][0], src[y][x][1]);
dst[0][y][x] = c;
dst[1][y][x] = c;
dst[2][y][x] = c;
break;
case 3:
dst[0][y][x] = src[y][x][0];
dst[1][y][x] = src[y][x][1];
dst[2][y][x] = src[y][x][2];
break;
case 4:
c = AlphaBackground(y, x);
dst[0][y][x] = twixt8(c, src[y][x][0], src[y][x][3]);
dst[1][y][x] = twixt8(c, src[y][x][1], src[y][x][3]);
dst[2][y][x] = twixt8(c, src[y][x][2], src[y][x][3]);
break;
}
}
}
return dst;
@ -209,32 +320,44 @@ static void *DeblinterlaceSubpixelBgr(long dyn, long dxn,
return dst;
}
static void ProcessImage(long syn, long sxn, unsigned char RGB[syn][sxn][4],
long cn) {
if (g_flags.subpixel) {
PrintImageLR(
syn, sxn * 3,
DeblinterlaceSubpixelBgr(
syn, sxn,
gc(memalign(32, sizeof(unsigned char) * syn * sxn * 3 * 3)), syn,
sxn, RGB, 0, syn, 0, sxn),
0, syn, 0, sxn * 3, true);
static void PrintImageSerious(long yn, long xn, unsigned char RGB[3][yn][xn],
struct TtyRgb TTY[yn][xn], char *vt) {
char *p;
long y, x;
struct TtyRgb bg = {0x12, 0x34, 0x56, 0};
struct TtyRgb fg = {0x12, 0x34, 0x56, 0};
if (g_flags.unsharp) unsharp(3, yn, xn, RGB, yn, xn);
if (g_flags.dither) dither(yn, xn, RGB, yn, xn);
for (y = 0; y < yn; ++y) {
for (x = 0; x < xn; ++x) {
TTY[y][x] = rgb2tty(RGB[0][y][x], RGB[1][y][x], RGB[2][y][x]);
}
}
p = ttyraster(vt, (void *)TTY, yn, xn, bg, fg);
p = stpcpy(p, "\r\e[0m");
ttywrite(STDOUT_FILENO, vt, p - vt);
}
static void ProcessImage(long yn, long xn, unsigned char RGB[3][yn][xn]) {
if (g_flags.half) {
if (g_flags.subpixel) {
PrintImageLR(yn, xn * 3, RGB, 0, yn, 0, xn * 3);
} else {
PrintImage(yn, xn, RGB, 0, yn, 0, xn);
}
} else {
PrintImage(
syn, sxn,
Deblinterlace(syn, sxn,
gc(memalign(32, sizeof(unsigned char) * syn * sxn * 3)),
syn, sxn, RGB, 0, syn, 0, sxn),
0, syn, 0, sxn, true);
PrintImageSerious(
yn, xn, RGB, gc(memalign(32, sizeof(struct TtyRgb) * yn * xn)),
gc(memalign(32, ((yn * xn * strlen("\e[48;2;255;48;2;255m▄")) +
(yn * strlen("\e[0m\r\n")) + 128))));
}
}
void WithImageFile(const char *path,
void fn(long syn, long sxn, unsigned char RGB[syn][sxn][4],
long cn)) {
void fn(long yn, long xn, unsigned char RGB[3][yn][xn])) {
struct stat st;
void *map, *data;
int fd, yn, xn, cn;
void *map, *data, *data2;
int fd, yn, xn, cn, dyn, dxn;
CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path);
CHECK_NE(-1, fstat(fd, &st));
CHECK_GT(st.st_size, 0);
@ -243,17 +366,33 @@ void WithImageFile(const char *path,
CHECK_NE(MAP_FAILED,
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
CHECK_NOTNULL(
(data = stbi_load_from_memory(map, st.st_size, &xn, &yn, &cn, 4)), "%s",
path);
(data = gc(stbi_load_from_memory(map, st.st_size, &xn, &yn, &cn, 0))),
"%s", path);
CHECK_NE(-1, munmap(map, st.st_size));
CHECK_NE(-1, close(fd));
fn(yn, xn, data, 4);
free(data);
if (g_flags.subpixel) {
data = DeblinterlaceSubpixelBgr(yn, xn, gc(memalign(32, yn * xn * 4 * 3)),
yn, xn, data, 0, yn, 0, xn);
xn *= 3;
} else {
data = Deblinterlace(yn, xn, gc(memalign(32, yn * xn * 4)), yn, xn, cn,
data, 0, yn, 0, xn);
cn = 3;
}
if (g_flags.height && g_flags.width) {
dyn = g_flags.height;
dxn = g_flags.width;
data = EzGyarados(3, dyn, dxn, gc(memalign(32, dyn * dxn * 3)), cn, yn, xn,
data, 0, cn, dyn, dxn, yn, xn, 0, 0, 0, 0);
yn = dyn;
xn = dxn;
}
fn(yn, xn, data);
}
int main(int argc, char *argv[]) {
int i;
showcrashreports();
cancolor();
GetOpts(&argc, argv);
stbi_set_unpremultiply_on_load(true);
for (i = optind; i < argc; ++i) {

View file

@ -82,8 +82,7 @@ const struct IdName kNtStartfFlagNames[] = {
};
void PrintStartupInfo(void) {
printf(
"\n\
printf("\n\
\n\
new technology § startup info \n\
\n\
@ -102,7 +101,7 @@ void PrintStartupInfo(void) {
X("%u", dwYCountChars);
X("%u", dwFillAttribute);
printf("%s.%-22s: %s\n", "g_ntstartupinfo", "dwFlags",
recreateflags(kNtStartfFlagNames, g_ntstartupinfo.dwFlags));
RecreateFlags(kNtStartfFlagNames, g_ntstartupinfo.dwFlags));
X("%hu", wShowWindow);
X("%hu", cbReserved2);
X("%s", lpReserved2);
@ -113,8 +112,7 @@ void PrintStartupInfo(void) {
}
void PrintSystemInfo(void) {
printf(
"\n\
printf("\n\
\n\
new technology § system info \n\
\n\
@ -145,8 +143,7 @@ const char *ft2str(enum NtFileType ft) {
}
void PrintStdioInfo(void) {
printf(
"\n\
printf("\n\
\n\
new technology § stdio info \n\
\n\
@ -162,8 +159,7 @@ void PrintStdioInfo(void) {
void PrintTeb(void) {
GetCurrentProcessId();
SetLastError(0x1234);
printf(
"\n\
printf("\n\
\n\
new technology § teb? \n\
\n\
@ -188,8 +184,7 @@ void PrintTeb(void) {
void PrintPeb(void) {
struct NtPeb *peb = NtGetPeb();
printf(
"\n\
printf("\n\
\n\
new technology § peb \n\
\n\
@ -347,8 +342,7 @@ void PrintPeb(void) {
}
void PrintPebLdr(void) {
printf(
"\n\
printf("\n\
\n\
new technology § peb » ldr \n\
\n\
@ -372,8 +366,7 @@ void PrintPebLdr(void) {
void PrintModulesLoadOrder(void) {
{
printf(
"\n\
printf("\n\
\n\
new technology § modules » load order \n\
\n\
@ -447,8 +440,7 @@ void PrintModulesLoadOrder(void) {
void PrintModulesMemoryOrder(void) {
{
printf(
"\n\
printf("\n\
\n\
new technology § modules » memory order \n\
\n\

47
tool/viz/printpixel.c Normal file
View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/quant.h"
#include "dsp/tty/xtermname.h"
#include "libc/conv/conv.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ex.h"
#include "third_party/dtoa/dtoa.h"
int main(int argc, char *argv[]) {
int i;
struct TtyRgb tty;
unsigned rgb, r, g, b;
if (argc < 2) {
fprintf(stderr, "Usage: %s RRGGBB...\n", program_invocation_name);
exit(EX_USAGE);
}
for (i = 1; i < argc; ++i) {
rgb = strtol(argv[i], NULL, 16);
b = (rgb & 0x0000ff) >> 000;
g = (rgb & 0x00ff00) >> 010;
r = (rgb & 0xff0000) >> 020;
tty = rgb2tty(r, g, b);
printf("\e[48;5;%dm \e[0m %d \\e[48;5;%dm %s #%02x%02x%02x\n", tty.xt,
tty.xt, tty.xt, indexdoublenulstring(kXtermName, tty.xt), r, g, b);
}
return 0;
}

View file

@ -330,11 +330,11 @@ static void StrikeDownCrapware(int sig) {
}
static long AsMilliseconds(long double ts) {
return lrintl(ts * 1e3);
return rintl(ts * 1e3);
}
static long AsNanoseconds(long double ts) {
return lrintl(ts * 1e9);
return rintl(ts * 1e9);
}
static long double GetGraceTime(void) {
@ -733,7 +733,7 @@ static void RenderIt(void) {
if (ttymode_ && stats_) {
bpc = bpf = p - vt;
bpc /= wsize_.ws_row * wsize_.ws_col;
sprintf(status_[4], " %s/%s/%s %zu×%zu → %zu×%zu pixels ",
sprintf(status_[4], " %s/%s/%s %d×%d → %u×%u pixels ",
kPrimaries[primaries_].name, DescribeSwing(swing_),
kLightings[lighting_].name, plm_get_width(plm_),
plm_get_height(plm_), g2_->xn, g2_->yn);
@ -1069,7 +1069,7 @@ static void SetQuant(enum TtyQuantizationAlgorithm alg,
enum TtyQuantizationChannels chans,
enum TtyBlocksSelection blocks) {
tuned_ = true;
ttyquantinit(alg, chans, blocks);
ttyquantsetup(alg, chans, blocks);
}
static void SetQuantizationAlgorithm(enum TtyQuantizationAlgorithm alg) {
@ -1516,7 +1516,7 @@ static void PickDefaults(void) {
* strcmp(nulltoempty(getenv("TERM")), "xterm-direct") == 0
*/
if (strcmp(nulltoempty(getenv("TERM")), "xterm-kitty") == 0) {
ttyquantinit(kTtyQuantTrue, TTYQUANT()->chans, kTtyBlocksUnicode);
ttyquantsetup(kTtyQuantTrue, TTYQUANT()->chans, kTtyBlocksUnicode);
}
}

View file

@ -4,12 +4,14 @@
PKGS += TOOL_VIZ
TOOL_VIZ_SRCS := $(wildcard tool/viz/*.c)
TOOL_VIZ_COMS = $(TOOL_VIZ_OBJS:%.o=%.com)
TOOL_VIZ_OBJS = \
$(TOOL_VIZ_SRCS:%=o/$(MODE)/%.zip.o) \
$(TOOL_VIZ_SRCS:%.c=o/$(MODE)/%.o)
TOOL_VIZ_COMS = \
$(TOOL_VIZ_SRCS:%.c=o/$(MODE)/%.com)
TOOL_VIZ_BINS = \
$(TOOL_VIZ_COMS) \
$(TOOL_VIZ_COMS:%=%.dbg)

View file

@ -20,104 +20,16 @@
#include "libc/assert.h"
#include "libc/stdio/stdio.h"
#define DueToGnomeTerminal 1
#define DueToLiteralXterm 1
#define DueToKittyWithPragmataPro 1
#if 0
static void rgb2hsv(T r, T g, T b, T *out_h, T *out_s, T *out_v) {
T c, h, s, v, min, max;
h = NAN;
s = 0;
v = 0;
min = MIN(MIN(r, g), b);
max = MAX(MAX(r, g), b);
if (max > C(0.0)) {
v = max;
c = max - min;
s = c / v;
if (c > C(0.00001)) {
if (r >= max) {
h = (g - b) / c;
} else if (g >= max) {
h = C(2.0) + (b - r) / c;
} else {
h = C(4.0) + (r - g) / c;
}
h *= C(60.0);
if (h < C(0.0)) {
h += C(360.0);
}
}
}
*out_h = h;
*out_s = s;
*out_v = v;
}
static void hsv2rgb(T h, T s, T v, T *out_r, T *out_g, T *out_b) {
long i;
T r, g, b, hh, p, q, t, ff;
if (s <= C(0.0)) {
r = v;
g = v;
b = v;
} else {
hh = h;
if (h >= C(360.0)) hh = 0;
hh /= C(60.0);
i = (long)hh;
ff = hh - i;
p = v * (C(1.0) - s);
q = v * (C(1.0) - (s * ff));
t = v * (C(1.0) - (s * (C(1.0) - ff)));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
default:
r = v;
g = p;
b = q;
break;
}
}
*out_r = r;
*out_g = g;
*out_b = b;
}
#endif
#define DIST(X, Y) ((X) - (Y))
#define SQR(X) ((X) * (X))
#define SUM(X, Y, Z) ((X) + (Y) + (Z))
static const uint8_t kXtermCube[] = {0, 0137, 0207, 0257, 0327, 0377};
static int uncube(int x) {
return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40;
}
static int rgb2xterm256(int r, int g, int b) {
unsigned av, ir, ig, ib, il, qr, qg, qb, ql;
av = (r + g + b) / 3;

View file

@ -70,11 +70,19 @@ void GetOpts(int *argc, char *argv[]) {
}
#define U256F1(X) ((float)((X)&0xffu) * 256.0f)
#define F1U256(X) MAX(MIN(lrintl(roundl(256.0f * (X))), 255), 0)
#define F1U256(X) MAX(MIN((int)rintl(roundl(256.0f * (X))), 255), 0)
forceinline struct TtyRgb getquant(unsigned xt) { return g_ansi2rgb_[xt]; }
forceinline unsigned dist(int x, int y) { return x - y; }
forceinline unsigned sqr(int x) { return x * x; }
forceinline struct TtyRgb getquant(unsigned xt) {
return g_ansi2rgb_[xt];
}
forceinline unsigned dist(int x, int y) {
return x - y;
}
forceinline unsigned sqr(int x) {
return x * x;
}
static unsigned rgb2hsl(unsigned rgba) {
/* this is broken */

View file

@ -17,7 +17,9 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "dsp/tty/xtermname.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
struct Rgb {
uint8_t r, g, b;
@ -430,265 +432,6 @@ const struct Rgb kXtermRgbAppleBg[] = {
{208, 208, 208}, {218, 218, 218}, {228, 228, 228}, {238, 238, 238},
};
const char *const kXtermName[] = {
"Black",
"Maroon",
"Green",
"Olive",
"Navy",
"Purple",
"Teal",
"Silver",
"Grey",
"Red",
"Lime",
"Yellow",
"Blue",
"Fuchsia",
"Aqua",
"White",
"Grey0",
"NavyBlue",
"DarkBlue",
"Blue3",
"Blue3",
"Blue1",
"DarkGreen",
"DeepSkyBlue4",
"DeepSkyBlue4",
"DeepSkyBlue4",
"DodgerBlue3",
"DodgerBlue2",
"Green4",
"SpringGreen4",
"Turquoise4",
"DeepSkyBlue3",
"DeepSkyBlue3",
"DodgerBlue1",
"Green3",
"SpringGreen3",
"DarkCyan",
"LightSeaGreen",
"DeepSkyBlue2",
"DeepSkyBlue1",
"Green3",
"SpringGreen3",
"SpringGreen2",
"Cyan3",
"DarkTurquoise",
"Turquoise2",
"Green1",
"SpringGreen2",
"SpringGreen1",
"MediumSpringGreen",
"Cyan2",
"Cyan1",
"DarkRed",
"DeepPink4",
"Purple4",
"Purple4",
"Purple3",
"BlueViolet",
"Orange4",
"Grey37",
"MediumPurple4",
"SlateBlue3",
"SlateBlue3",
"RoyalBlue1",
"Chartreuse4",
"DarkSeaGreen4",
"PaleTurquoise4",
"SteelBlue",
"SteelBlue3",
"CornflowerBlue",
"Chartreuse3",
"DarkSeaGreen4",
"CadetBlue",
"CadetBlue",
"SkyBlue3",
"SteelBlue1",
"Chartreuse3",
"PaleGreen3",
"SeaGreen3",
"Aquamarine3",
"MediumTurquoise",
"SteelBlue1",
"Chartreuse2",
"SeaGreen2",
"SeaGreen1",
"SeaGreen1",
"Aquamarine1",
"DarkSlateGray2",
"DarkRed",
"DeepPink4",
"DarkMagenta",
"DarkMagenta",
"DarkViolet",
"Purple",
"Orange4",
"LightPink4",
"Plum4",
"MediumPurple3",
"MediumPurple3",
"SlateBlue1",
"Yellow4",
"Wheat4",
"Grey53",
"LightSlateGrey",
"MediumPurple",
"LightSlateBlue",
"Yellow4",
"DarkOliveGreen3",
"DarkSeaGreen",
"LightSkyBlue3",
"LightSkyBlue3",
"SkyBlue2",
"Chartreuse2",
"DarkOliveGreen3",
"PaleGreen3",
"DarkSeaGreen3",
"DarkSlateGray3",
"SkyBlue1",
"Chartreuse1",
"LightGreen",
"LightGreen",
"PaleGreen1",
"Aquamarine1",
"DarkSlateGray1",
"Red3",
"DeepPink4",
"MediumVioletRed",
"Magenta3",
"DarkViolet",
"Purple",
"DarkOrange3",
"IndianRed",
"HotPink3",
"MediumOrchid3",
"MediumOrchid",
"MediumPurple2",
"DarkGoldenrod",
"LightSalmon3",
"RosyBrown",
"Grey63",
"MediumPurple2",
"MediumPurple1",
"Gold3",
"DarkKhaki",
"NavajoWhite3",
"Grey69",
"LightSteelBlue3",
"LightSteelBlue",
"Yellow3",
"DarkOliveGreen3",
"DarkSeaGreen3",
"DarkSeaGreen2",
"LightCyan3",
"LightSkyBlue1",
"GreenYellow",
"DarkOliveGreen2",
"PaleGreen1",
"DarkSeaGreen2",
"DarkSeaGreen1",
"PaleTurquoise1",
"Red3",
"DeepPink3",
"DeepPink3",
"Magenta3",
"Magenta3",
"Magenta2",
"DarkOrange3",
"IndianRed",
"HotPink3",
"HotPink2",
"Orchid",
"MediumOrchid1",
"Orange3",
"LightSalmon3",
"LightPink3",
"Pink3",
"Plum3",
"Violet",
"Gold3",
"LightGoldenrod3",
"Tan",
"MistyRose3",
"Thistle3",
"Plum2",
"Yellow3",
"Khaki3",
"LightGoldenrod2",
"LightYellow3",
"Grey84",
"LightSteelBlue1",
"Yellow2",
"DarkOliveGreen1",
"DarkOliveGreen1",
"DarkSeaGreen1",
"Honeydew2",
"LightCyan1",
"Red1",
"DeepPink2",
"DeepPink1",
"DeepPink1",
"Magenta2",
"Magenta1",
"OrangeRed1",
"IndianRed1",
"IndianRed1",
"HotPink",
"HotPink",
"MediumOrchid1",
"DarkOrange",
"Salmon1",
"LightCoral",
"PaleVioletRed1",
"Orchid2",
"Orchid1",
"Orange1",
"SandyBrown",
"LightSalmon1",
"LightPink1",
"Pink1",
"Plum1",
"Gold1",
"LightGoldenrod2",
"LightGoldenrod2",
"NavajoWhite1",
"MistyRose1",
"Thistle1",
"Yellow1",
"LightGoldenrod1",
"Khaki1",
"Wheat1",
"Cornsilk1",
"Grey100",
"Grey3",
"Grey7",
"Grey11",
"Grey15",
"Grey19",
"Grey23",
"Grey27",
"Grey30",
"Grey35",
"Grey39",
"Grey42",
"Grey46",
"Grey50",
"Grey54",
"Grey58",
"Grey62",
"Grey66",
"Grey70",
"Grey74",
"Grey78",
"Grey82",
"Grey85",
"Grey89",
"Grey93",
};
const struct XtermDb {
struct Rgb rgb;
const char *text;
@ -1213,7 +956,7 @@ int main(int argc, char *argv[]) {
for (i = 0; i < 256; ++i) {
printf("\e[48;5;%dm \e[0m \e[38;5;%dm██\e[0m \e[1;48;5;%dm "
"\e[0m \e[1;38;5;%dm██\e[0m %-6hhu%-18s#%02hhu%02hhu%02hhu\n",
i, i, i, i, i, kXtermName[i]);
i, i, i, i, i, indexdoublenulstring(kXtermName, i));
}
return 0;
}