forked from hkc/cc-stuff
Compare commits
15 Commits
fb0126547a
...
5662f536d7
Author | SHA1 | Date |
---|---|---|
capta1nseal | 5662f536d7 | |
capta1nseal | 3583a347c2 | |
Casey | a0450a7d59 | |
Casey | d511cc407e | |
Casey | 1e364fe3ea | |
Casey | 33e3c1ad8c | |
Casey | a665f9498d | |
Casey | 094308ce0b | |
Casey | 0afb88e147 | |
Casey | a06361ad4a | |
Casey | c4740b8bfd | |
Casey | 989daae8e8 | |
Casey | bed20ee4d3 | |
Casey | 703a1744b5 | |
Casey | 92eb5b325c |
15
cc-pic.py
15
cc-pic.py
|
@ -74,13 +74,14 @@ class Converter:
|
|||
|
||||
MAX_DIFF = 3 * 255
|
||||
|
||||
def __init__(self, image: Image.Image, palette: list[int] | int = PALETTE_ADAPTIVE):
|
||||
def __init__(self, image: Image.Image, palette: list[int] | int = PALETTE_ADAPTIVE, dither: bool = True):
|
||||
dither_mode = Image.Dither.FLOYDSTEINBERG if dither else Image.Dither.NONE
|
||||
if isinstance(palette, list):
|
||||
img_pal = Image.new("P", (1, 1))
|
||||
img_pal.putpalette(palette)
|
||||
self._img = image.quantize(len(palette) // 3, palette=img_pal)
|
||||
self._img = image.quantize(len(palette) // 3, palette=img_pal, dither=dither_mode)
|
||||
else:
|
||||
self._img = image.convert("P", palette=palette, colors=16)
|
||||
self._img = image.convert("P", palette=palette, colors=16, dither=dither_mode)
|
||||
|
||||
self._imgdata = self._img.load()
|
||||
self._palette: list[int] = self._img.getpalette() or []
|
||||
|
@ -221,6 +222,12 @@ def main():
|
|||
action="store_true",
|
||||
help="Output a Lua script instead of binary image",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-D",
|
||||
dest="nodither",
|
||||
action="store_true",
|
||||
help="Disable dithering"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-W",
|
||||
dest="width",
|
||||
|
@ -391,7 +398,7 @@ def main():
|
|||
else:
|
||||
raise ValueError(f"invalid palette identifier: {args.palette!r}")
|
||||
|
||||
converter = Converter(canv, palette)
|
||||
converter = Converter(canv, palette, dither=not args.nodither)
|
||||
converter._img.save("/tmp/_ccpictmp.png")
|
||||
if args.textmode:
|
||||
with open(args.output_path, "w") as fp:
|
||||
|
|
|
@ -10,8 +10,8 @@ cleanup() {
|
|||
trap cleanup EXIT
|
||||
|
||||
|
||||
export URL="$1";
|
||||
export NAME="$2";
|
||||
export INPUT="$1";
|
||||
export OUTPUT="$(realpath "$2")";
|
||||
export BASE_URL="$3"
|
||||
|
||||
if [ -z "${BASE_URL}" ]; then
|
||||
|
@ -19,24 +19,40 @@ if [ -z "${BASE_URL}" ]; then
|
|||
fi
|
||||
|
||||
|
||||
mkdir -p "${NAME}"
|
||||
mkdir -p "${OUTPUT}"
|
||||
|
||||
export ORIG="$(pwd)";
|
||||
|
||||
cd "${TMP_DIR}"
|
||||
|
||||
yt-dlp "${URL}" -o "${NAME}"
|
||||
<<<<<<< HEAD
|
||||
ffmpeg -i "${INPUT}" -filter_complex "[0:a]channelsplit=channel_layout=stereo[left][right]" -map '[left]' -f s8 -ac 1 -ar 48k "${OUTPUT}/left.s8" -map '[right]' -f s8 -ac 1 -ar 48k "${OUTPUT}/right.s8"
|
||||
ffmpeg -i "${INPUT}" -vf fps=20 frame%04d.png
|
||||
|
||||
<<<<<<< HEAD
|
||||
ls frame*.png | parallel 'echo {}; python3 ${ORIG}/cc-pic.py -W 164 -H 81 -p cover {} ${OUTPUT}/{.}.cpi'
|
||||
=======
|
||||
ffmpeg -i $2.* -filter_complex "[0:a]channelsplit=channel_layout=stereo[left][right]" -map '[left]' -f s8 -ac 1 -ar 48k "${ORIG}/${NAME}/left.s8" -map '[right]' -f s8 -ac 1 -ar 48k "${ORIG}/${NAME}/right.s8"
|
||||
=======
|
||||
yt-dlp "${URL}" -S "+height:720" -f "b" -o "${NAME}"
|
||||
|
||||
ffmpeg -i $2.* -vf fps=20 frame%04d.png
|
||||
rm $2.*
|
||||
ls frame*.png | parallel 'echo {}; python3 ${ORIG}/cc-pic.py -W 164 -H 81 -p cover {} ${ORIG}/${NAME}/{.}.cpi'
|
||||
ffmpeg -i $2* -filter_complex "[0:a]channelsplit=channel_layout=stereo[left][right]" -map '[left]' -f s8 -ac 1 -ar 48k "${ORIG}/${NAME}/left.s8" -map '[right]' -f s8 -ac 1 -ar 48k "${ORIG}/${NAME}/right.s8"
|
||||
>>>>>>> fb01265 (Decrease max video download quality to 720p. Larger downloads were causing errors, slower to process, and unnecessary.)
|
||||
|
||||
ffmpeg -i $2* -vf fps=20 frame%04d.png
|
||||
rm $2*
|
||||
ls frame*.png | parallel 'echo {}; python3 ${ORIG}/cc-pic.py -W 164 -H 81 -p full {} ${ORIG}/${NAME}/{.}.cpi'
|
||||
>>>>>>> 544c8a9 (Swap to -p full.)
|
||||
rm frame*.png
|
||||
|
||||
cd "${ORIG}"
|
||||
|
||||
export FRAME_COUNT="$(ls ${NAME}/*.cpi | wc -l)";
|
||||
export FRAME_COUNT="$(ls ${OUTPUT}/*.cpi | wc -l)";
|
||||
|
||||
printf '{"frame_time": 0.05, "frame_count": %d, "video": "%s", "audio": {"l": "%s", "r": "%s"}}\n' "${FRAME_COUNT}" "${BASE_URL}/frame%04d.cpi" "${BASE_URL}/left.s8" "${BASE_URL}/right.s8" > "${OUTPUT}/info.json"
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#'{"frame_time": 0.05,"frame_count": ${FRAME_COUNT},"video": "${BASE_URL}/${NAME}/frame%04d.cpi","audio": {"l": "${BASE_URL}/${NAME}/left.s8", "r": "${BASE_URL}/${NAME}/right.s8"}}' > "${NAME}/${NAME}.json"
|
||||
printf '{"frame_time": 0.05, "frame_count": %d, "video": "%s", "audio": {"l": "%s", "r": "%s"}}\n' "${FRAME_COUNT}" "${BASE_URL}/${NAME}/frame%04d.cpi" "${BASE_URL}/${NAME}/left.s8" "${BASE_URL}/${NAME}/right.s8" > "${NAME}/${NAME}.json"
|
||||
>>>>>>> 544c8a9 (Swap to -p full.)
|
||||
|
|
635
img2cpi.c
635
img2cpi.c
|
@ -1,4 +1,4 @@
|
|||
// x-run: ~/scripts/runc.sh % -Wall -Wextra -std=c99 -pedantic -lm --- ~/images/boykisser.png cpi-images/boykisser.cpi
|
||||
// x-run: ~/scripts/runc.sh % -Wall -Wextra -lm --- ~/images/boykisser.png cpi-images/boykisser.cpi
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
|
@ -14,11 +14,25 @@
|
|||
|
||||
#define MAX_COLOR_DIFFERENCE 768
|
||||
|
||||
struct rgba { uint8_t r, g, b, a; };
|
||||
union color {
|
||||
struct rgba rgba;
|
||||
uint32_t v;
|
||||
};
|
||||
struct cc_char {
|
||||
unsigned char character;
|
||||
unsigned char bg, fg;
|
||||
};
|
||||
|
||||
const extern char font_atlas[256][11];
|
||||
const extern union color DEFAULT_PALETTE[16], DEFAULT_GRAY_PALETTE[16];
|
||||
|
||||
struct arguments {
|
||||
bool text_mode;
|
||||
bool fast_mode;
|
||||
int width, height;
|
||||
enum cpi_version {
|
||||
CPI_VERSION_AUTO,
|
||||
CPI_VERSION_RAW,
|
||||
CPI_VERSION_0,
|
||||
CPI_VERSION_1,
|
||||
CPI_VERSION_2,
|
||||
|
@ -31,24 +45,37 @@ struct arguments {
|
|||
PLACEMENT_EXTEND,
|
||||
PLACEMENT_FILL
|
||||
} placement;
|
||||
enum palette_type {
|
||||
PALETTE_DEFAULT,
|
||||
PALETTE_DEFAULT_GRAY,
|
||||
PALETTE_AUTO,
|
||||
PALETTE_PATH,
|
||||
PALETTE_LIST
|
||||
} palette_type;
|
||||
char *palette;
|
||||
char *input_path;
|
||||
char *output_path;
|
||||
} args = {
|
||||
.text_mode = false,
|
||||
.width = 4 * 8 - 1,
|
||||
.fast_mode = false,
|
||||
.width = 4 * 8 - 1, // 4x3 blocks screen
|
||||
.height = 3 * 6 - 2,
|
||||
.cpi_version = CPI_VERSION_AUTO,
|
||||
.placement = PLACEMENT_FULL,
|
||||
.input_path = NULL,
|
||||
.output_path = NULL
|
||||
.output_path = NULL,
|
||||
.palette = NULL,
|
||||
.palette_type = PALETTE_DEFAULT // TODO(kc): change to PALETTE_AUTO when
|
||||
// k-means is implemented
|
||||
};
|
||||
|
||||
struct image {
|
||||
int w, h;
|
||||
union color { // Alpha channel is not used, it's just there to align it all
|
||||
struct rgba { uint8_t r, g, b, a; } rgba;
|
||||
uint32_t v;
|
||||
} *pixels;
|
||||
union color *pixels;
|
||||
};
|
||||
|
||||
struct image_pal {
|
||||
int w, h;
|
||||
uint8_t *pixels;
|
||||
};
|
||||
|
||||
bool parse_cmdline(int argc, char **argv);
|
||||
|
@ -56,8 +83,11 @@ void show_help(const char *progname, bool show_all, FILE *fp);
|
|||
struct image *image_load(const char *fp);
|
||||
struct image *image_new(int w, int h);
|
||||
struct image *image_resize(struct image *original, int new_w, int new_h);
|
||||
struct image *image_dither(struct image *original, union color *colors, size_t n_colors);
|
||||
struct image_pal *image_quantize(struct image *original, const union color *colors, size_t n_colors);
|
||||
float get_color_difference(union color a, union color b);
|
||||
float get_color_brightness(union color clr);
|
||||
void image_unload(struct image *img);
|
||||
void get_size_keep_aspect(int w, int h, int dw, int dh, int *ow, int *oh);
|
||||
|
||||
const char *known_file_extensions[] = {
|
||||
".png", ".jpg", ".jpeg", ".jfif", ".jpg", ".gif",
|
||||
|
@ -72,12 +102,19 @@ static const struct optiondocs {
|
|||
struct optiondocs_choice { char *value; char *doc; } *choices;
|
||||
} optiondocs[] = {
|
||||
{ 'h', "help", 0, "Show help", 0 },
|
||||
{ 't', "textmode", 0, "Output Lua script instead of binary", 0 },
|
||||
{ 'f', "fast", 0, "Use fast (old) method for picking characters and colors", 0 },
|
||||
{ 'W', "width", "width", "Width in characters", 0 },
|
||||
{ 'h', "height", "height", "Height in characters", 0 },
|
||||
{ 'P', "palette", "palette", "Use specific palette.\n"
|
||||
" `auto` uses automatic selection\n"
|
||||
" `default` uses default palette\n"
|
||||
" `defaultgray` uses default grayscale palette\n"
|
||||
" `list:#RRGGBB,#RRGGBB,...` uses hard-coded one\n"
|
||||
" `txt:PATH` reads hex colors from each line in a file\n", 0 },
|
||||
{ 'V', "cpi_version", "version", "Force specific version of CPI",
|
||||
(struct optiondocs_choice[]) {
|
||||
{ "-1", "Choose best available" },
|
||||
{ "-2,raw", "Use raw format. No headers, no palette, just characters and colors" },
|
||||
{ "-1,auto", "Choose best available" },
|
||||
{ "0", "OG CPI, 255x255, uncompressed" },
|
||||
{ "1", "CPIv1, huge images, uncompressed" },
|
||||
{ "255", "In-dev version, may not work" },
|
||||
|
@ -102,20 +139,184 @@ int main(int argc, char **argv) {
|
|||
fprintf(stderr, "Fatal error occurred, exiting.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct image *src_image = image_load(args.input_path);
|
||||
if (!src_image) {
|
||||
fprintf(stderr, "Error: failed to open the file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct image *canvas = image_new(args.width * 2, args.height * 3);
|
||||
struct image *canvas;
|
||||
if (args.fast_mode) {
|
||||
canvas = image_new(args.width * 2, args.height * 3);
|
||||
} else {
|
||||
canvas = image_new(args.width * 8, args.height * 11);
|
||||
}
|
||||
|
||||
if (!canvas) {
|
||||
fprintf(stderr, "Error: failed to allocate second image buffer\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// TODO: load palette, maybe calculate it too? k-means?
|
||||
const union color *palette = DEFAULT_PALETTE;
|
||||
switch (args.palette_type) {
|
||||
case PALETTE_DEFAULT: palette = DEFAULT_PALETTE; break;
|
||||
case PALETTE_DEFAULT_GRAY: palette = DEFAULT_GRAY_PALETTE; break;
|
||||
case PALETTE_AUTO: assert(0 && "Not implemented"); break;
|
||||
case PALETTE_LIST: assert(0 && "Not implemented"); break;
|
||||
case PALETTE_PATH: assert(0 && "Not implemented"); break;
|
||||
default: assert(0 && "Unreachable");
|
||||
}
|
||||
|
||||
// TODO: properly scale
|
||||
struct image *scaled_image;
|
||||
{
|
||||
int new_w, new_h;
|
||||
get_size_keep_aspect(src_image->w, src_image->h, canvas->w, canvas->h, &new_w, &new_h);
|
||||
|
||||
scaled_image = image_resize(src_image, new_w, new_h);
|
||||
if (!scaled_image) {
|
||||
fprintf(stderr, "Error: failed to open the file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: position image properly
|
||||
int small_w = scaled_image->w < canvas->w ? scaled_image->w : canvas->w;
|
||||
int small_h = scaled_image->h < canvas->h ? scaled_image->h : canvas->h;
|
||||
for (int y = 0; y < small_h; y++) {
|
||||
memcpy(&canvas->pixels[y * canvas->w],
|
||||
&scaled_image->pixels[y * scaled_image->w],
|
||||
small_w * sizeof(union color));
|
||||
}
|
||||
|
||||
|
||||
// TODO: actually do stuff
|
||||
struct cc_char *characters = calloc(args.width * args.height, sizeof(struct cc_char));
|
||||
|
||||
struct image_pal *quantized_image = image_quantize(canvas, palette, 16);
|
||||
if (!quantized_image) {
|
||||
fprintf(stderr, "Error: failed to open the file\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
FILE *tmp = fopen("/tmp/img.raw", "wb");
|
||||
for (int i = 0; i < quantized_image->w * quantized_image->h; i++) {
|
||||
union color pix = palette[quantized_image->pixels[i]];
|
||||
fputc(pix.rgba.r, tmp);
|
||||
fputc(pix.rgba.g, tmp);
|
||||
fputc(pix.rgba.b, tmp);
|
||||
}
|
||||
fclose(tmp);
|
||||
|
||||
if (args.fast_mode) {
|
||||
// use old 2x3
|
||||
for (int y = 0; y < args.height; y++) {
|
||||
for (int x = 0; x < args.width; x++) {
|
||||
unsigned char darkest_i = 0, brightest_i = 0;
|
||||
float darkest_diff = 0xffffff, brightest_diff = 0;
|
||||
|
||||
for (int oy = 0; oy < 3; oy++) {
|
||||
for (int ox = 0; ox < 2; ox++) {
|
||||
unsigned char pix = quantized_image->pixels[ox + (x + (y * 3 + oy) * args.width) * 2];
|
||||
float brightness = get_color_brightness(palette[pix]);
|
||||
if (brightness >= brightest_diff) {
|
||||
brightest_i = pix;
|
||||
brightest_diff = brightness;
|
||||
}
|
||||
if (brightness <= darkest_diff) {
|
||||
darkest_i = pix;
|
||||
darkest_diff = brightness;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char bitmap = 0;
|
||||
const static unsigned char pixel_bits[3][2] = { { 1, 2}, { 4, 8 }, { 16, 0 } };
|
||||
for (int oy = 0; oy < 3; oy++) {
|
||||
for (int ox = 0; ox < 2; ox++) {
|
||||
if (ox == 1 && oy == 2) continue;
|
||||
unsigned char pix = quantized_image->pixels[ox + (x + (y * 3 + oy) * args.width) * 2];
|
||||
float diff_bg = get_color_difference(palette[darkest_i], palette[pix]);
|
||||
float diff_fg = get_color_difference(palette[brightest_i], palette[pix]);
|
||||
if (diff_fg < diff_bg) {
|
||||
bitmap |= pixel_bits[oy][ox];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char pix = quantized_image->pixels[1 + (x + (y * 3 + 2) * args.width) * 2];
|
||||
float diff_bg = get_color_difference(palette[darkest_i], palette[pix]);
|
||||
float diff_fg = get_color_difference(palette[brightest_i], palette[pix]);
|
||||
if (diff_fg < diff_bg) {
|
||||
bitmap ^= 31;
|
||||
unsigned char tmp = darkest_i;
|
||||
darkest_i = brightest_i;
|
||||
brightest_i = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
characters[x + y * args.width].character = 0x80 + bitmap;
|
||||
characters[x + y * args.width].bg = darkest_i;
|
||||
characters[x + y * args.width].fg = brightest_i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// use new 8x11 character matching
|
||||
for (int y = 0; y < args.height; y++) {
|
||||
for (int x = 0; x < args.width; x++) {
|
||||
// Oh boy...
|
||||
float min_diff = 0xffffff;
|
||||
char closest_sym = 0x00, closest_color = 0xae;
|
||||
for (int sym = 0x01; sym <= 0xFF; sym++) {
|
||||
if (sym == '\t' || sym == '\n' || sym == '\r' || sym == '\x0e') {
|
||||
continue;
|
||||
}
|
||||
for (int color = 0x00; color <= 0xff; color++) {
|
||||
union color cell_bg = palette[color & 0xF],
|
||||
cell_fg = palette[color >> 4];
|
||||
float difference = 0;
|
||||
for (int oy = 0; oy < 11; oy++) {
|
||||
unsigned char sym_line = font_atlas[sym][oy];
|
||||
for (int ox = 0; ox < 8; ox++) {
|
||||
bool lit = sym_line & (0x80 >> ox);
|
||||
union color pixel = palette[quantized_image->pixels[
|
||||
ox + (x + (y * 11 + oy) * args.width) * 8
|
||||
]];
|
||||
difference += get_color_difference(pixel, lit ? cell_fg : cell_bg);
|
||||
}
|
||||
}
|
||||
if (difference <= min_diff) {
|
||||
min_diff = difference;
|
||||
closest_sym = sym;
|
||||
closest_color = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
characters[x + y * args.width].character = closest_sym;
|
||||
characters[x + y * args.width].bg = closest_color & 0xF;
|
||||
characters[x + y * args.width].fg = closest_color >> 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement something other than CPIv0
|
||||
FILE *fp = fopen(args.output_path, "wb");
|
||||
fwrite("CCPI", 1, 4, fp);
|
||||
fputc(args.width, fp);
|
||||
fputc(args.height, fp);
|
||||
fputc(0x00, fp);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
fputc(palette[i].rgba.r, fp);
|
||||
fputc(palette[i].rgba.g, fp);
|
||||
fputc(palette[i].rgba.b, fp);
|
||||
}
|
||||
for (int i = 0; i < args.width * args.height; i++) {
|
||||
fputc(characters[i].character, fp);
|
||||
fputc(characters[i].bg | (characters[i].fg << 4), fp);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
image_unload(src_image);
|
||||
image_unload(canvas);
|
||||
|
@ -125,49 +326,55 @@ int main(int argc, char **argv) {
|
|||
bool parse_cmdline(int argc, char **argv) {
|
||||
static struct option options[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "textmode", no_argument, 0, 't' },
|
||||
{ "fast", no_argument, 0, 'f' },
|
||||
{ "width", required_argument, 0, 'W' },
|
||||
{ "height", required_argument, 0, 'H' },
|
||||
{ "cpi_version", required_argument, 0, 'V' },
|
||||
{ "placement", required_argument, 0, 'p' },
|
||||
{ "palette", required_argument, 0, 'P' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int option_index = 0;
|
||||
int c = getopt_long(argc, argv, "htW:H:V:p:", options, &option_index);
|
||||
int c = getopt_long(argc, argv, "hfW:H:V:p:P:", options, &option_index);
|
||||
if (c == -1) break;
|
||||
if (c == 0) c = options[option_index].val;
|
||||
if (c == '?') break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
case 'h': // --help
|
||||
show_help(argv[0], true, stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
case 't':
|
||||
args.text_mode = true;
|
||||
case 'f': // --fast
|
||||
args.fast_mode = true;
|
||||
if (args.cpi_version != CPI_VERSION_AUTO) {
|
||||
fprintf(stderr, "Warning: text mode ignores version\n");
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
case 'W': // --width
|
||||
args.width = atoi(optarg);
|
||||
break;
|
||||
case 'H':
|
||||
case 'H': // --height
|
||||
args.height = atoi(optarg);
|
||||
break;
|
||||
case 'V':
|
||||
case 'V': // --cpi_version
|
||||
{
|
||||
int v = atoi(optarg);
|
||||
if ((v < -1 || v > 1) && v != 255) {
|
||||
fprintf(stderr, "Error: Invalid CPI version: %d\n", args.cpi_version);
|
||||
return false;
|
||||
if (0 == strcmp(optarg, "auto") || 0 == strcmp(optarg, "-1")) {
|
||||
args.cpi_version = CPI_VERSION_AUTO;
|
||||
} else if (0 == strcmp(optarg, "raw") || 0 == strcmp(optarg, "-2")) {
|
||||
args.cpi_version = CPI_VERSION_RAW;
|
||||
} else if (0 == strcmp(optarg, "0")) {
|
||||
args.cpi_version = CPI_VERSION_0;
|
||||
} else if (0 == strcmp(optarg, "1")) {
|
||||
args.cpi_version = CPI_VERSION_1;
|
||||
} else if (0 == strcmp(optarg, "2")) {
|
||||
args.cpi_version = CPI_VERSION_2;
|
||||
}
|
||||
args.cpi_version = v == -1 ? CPI_VERSION_AUTO : v;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
case 'p': // --placement
|
||||
if (0 == strcmp(optarg, "center")) {
|
||||
args.placement = PLACEMENT_CENTER;
|
||||
} else if (0 == strcmp(optarg, "cover")) {
|
||||
|
@ -185,6 +392,21 @@ bool parse_cmdline(int argc, char **argv) {
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case 'P': // --palette
|
||||
if (0 == strcmp(optarg, "default")) {
|
||||
args.palette_type = PALETTE_DEFAULT;
|
||||
} else if (0 == strcmp(optarg, "defaultgray")) {
|
||||
args.palette_type = PALETTE_DEFAULT_GRAY;
|
||||
} else if (0 == strcmp(optarg, "auto")) {
|
||||
args.palette_type = PALETTE_AUTO;
|
||||
} else if (0 == strncmp(optarg, "list:", 5)) {
|
||||
args.palette_type = PALETTE_LIST;
|
||||
args.palette = &optarg[5];
|
||||
} else {
|
||||
fprintf(stderr, "Error: invaild palette %s\n", optarg);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +497,9 @@ void show_help(const char *progname, bool show_all, FILE *fp) {
|
|||
}
|
||||
if (x > 24) fprintf(fp, "\n%24c", ' ');
|
||||
else fprintf(fp, "%*c", 24 - x, ' ');
|
||||
|
||||
fprintf(fp, "%s\n", doc.doc);
|
||||
|
||||
if (doc.choices) {
|
||||
for (int j = 0; doc.choices[j].value != 0; j++) {
|
||||
fprintf(fp, "%26c", ' ');
|
||||
|
@ -325,3 +549,358 @@ void image_unload(struct image *img) {
|
|||
free(img);
|
||||
}
|
||||
|
||||
void get_size_keep_aspect(int w, int h, int dw, int dh, int *ow, int *oh)
|
||||
{
|
||||
*ow = dw;
|
||||
*oh = dh;
|
||||
float ratio = (float)w / (float)h;
|
||||
float ratio_dst = (float)dw / (float)dh;
|
||||
int tmp_1, tmp_2;
|
||||
if (ratio_dst >= ratio)
|
||||
{
|
||||
tmp_1 = floor(dh * ratio);
|
||||
tmp_2 = ceil(dh * ratio);
|
||||
if (fabsf(ratio - (float)tmp_1 / dh) < fabsf(ratio - (float)tmp_2 / dh))
|
||||
*ow = tmp_1 < 1 ? 1 : tmp_1;
|
||||
else
|
||||
*ow = tmp_2 < 1 ? 1 : tmp_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_1 = floor(dw / ratio);
|
||||
tmp_2 = ceil(dw / ratio);
|
||||
if (tmp_2 == 0 ||
|
||||
fabs(ratio - (float)dw / tmp_1) < fabs(ratio - (float)dw / tmp_2))
|
||||
(*oh) = tmp_1 < 1 ? 1 : tmp_1;
|
||||
else
|
||||
(*oh) = tmp_2 < 1 ? 1 : tmp_2;
|
||||
}
|
||||
}
|
||||
|
||||
struct image_pal *image_quantize(struct image *original, const union color *colors, size_t n_colors) {
|
||||
struct image_pal *out = calloc(1, sizeof(struct image_pal));
|
||||
out->w = original->w;
|
||||
out->h = original->h;
|
||||
out->pixels = calloc(original->w, original->h);
|
||||
|
||||
for (int i = 0; i < out->w * out->h; i++) {
|
||||
int closest_color = 0;
|
||||
float closest_distance = 1e20;
|
||||
for (int color = 0; color < n_colors; color++) {
|
||||
float dist = get_color_difference(colors[color], original->pixels[i]);
|
||||
if (dist <= closest_distance) {
|
||||
closest_distance = dist;
|
||||
closest_color = color;
|
||||
}
|
||||
}
|
||||
out->pixels[i] = closest_color;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
float get_color_difference(union color a, union color b) {
|
||||
int dr = a.rgba.r - b.rgba.r,
|
||||
dg = a.rgba.g - b.rgba.g,
|
||||
db = a.rgba.b - b.rgba.b;
|
||||
return dr * dr + dg * dg + db * db;
|
||||
}
|
||||
|
||||
float get_color_brightness(union color clr) {
|
||||
return get_color_difference(clr, (union color){ .v = 0 });
|
||||
}
|
||||
|
||||
const union color DEFAULT_PALETTE[16] = {
|
||||
{ 0xf0, 0xf0, 0xf0, 0xff },
|
||||
{ 0xf2, 0xb2, 0x33, 0xff },
|
||||
{ 0xe5, 0x7f, 0xd8, 0xff },
|
||||
{ 0x99, 0xb2, 0xf2, 0xff },
|
||||
{ 0xde, 0xde, 0x6c, 0xff },
|
||||
{ 0x7f, 0xcc, 0x19, 0xff },
|
||||
{ 0xf2, 0xb2, 0xcc, 0xff },
|
||||
{ 0x4c, 0x4c, 0x4c, 0xff },
|
||||
{ 0x99, 0x99, 0x99, 0xff },
|
||||
{ 0x4c, 0x99, 0xb2, 0xff },
|
||||
{ 0xb2, 0x66, 0xe5, 0xff },
|
||||
{ 0x33, 0x66, 0xcc, 0xff },
|
||||
{ 0x7f, 0x66, 0x4c, 0xff },
|
||||
{ 0x57, 0xa6, 0x4e, 0xff },
|
||||
{ 0xcc, 0x4c, 0x4c, 0xff },
|
||||
{ 0x11, 0x11, 0x11, 0xff }
|
||||
}, DEFAULT_GRAY_PALETTE[16] = {
|
||||
{ 0xf0, 0xf0, 0xf0, 0xff },
|
||||
{ 0x9d, 0x9d, 0x9d, 0xff },
|
||||
{ 0xbe, 0xbe, 0xbe, 0xff },
|
||||
{ 0xbf, 0xbf, 0xbf, 0xff },
|
||||
{ 0xb8, 0xb8, 0xb8, 0xff },
|
||||
{ 0x76, 0x76, 0x76, 0xff },
|
||||
{ 0xd0, 0xd0, 0xd0, 0xff },
|
||||
{ 0x4c, 0x4c, 0x4c, 0xff },
|
||||
{ 0x99, 0x99, 0x99, 0xff },
|
||||
{ 0x87, 0x87, 0x87, 0xff },
|
||||
{ 0xa9, 0xa9, 0xa9, 0xff },
|
||||
{ 0x77, 0x77, 0x77, 0xff },
|
||||
{ 0x65, 0x65, 0x65, 0xff },
|
||||
{ 0x6e, 0x6e, 0x6e, 0xff },
|
||||
{ 0x76, 0x76, 0x76, 0xff },
|
||||
{ 0x11, 0x11, 0x11, 0xff }
|
||||
};
|
||||
|
||||
const char font_atlas[256][11] = {
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x6c, 0x44, 0x54, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x7c, 0x54, 0x7c, 0x44, 0x6c, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x28, 0x7c, 0x7c, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x38, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x38, 0x10, 0x7c, 0x7c, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x38, 0x7c, 0x7c, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7e, 0x7e, 0x66, 0x42, 0x42, 0x66, 0x7e, 0x7e, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x1c, 0x0c, 0x34, 0x48, 0x48, 0x30, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x10, 0x38, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x3c, 0x24, 0x3c, 0x20, 0x60, 0x60, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x66, 0x66, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x40, 0x70, 0x7c, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x04, 0x1c, 0x7c, 0x1c, 0x04, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x38, 0x7c, 0x10, 0x10, 0x7c, 0x38, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x24, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x54, 0x54, 0x34, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x60, 0x58, 0x44, 0x34, 0x0c, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x38, 0x7c, 0x10, 0x7c, 0x38, 0x10, 0x7c, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x38, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x18, 0x7c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x30, 0x7c, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x24, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x14, 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x3c, 0x40, 0x38, 0x04, 0x78, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x48, 0x08, 0x10, 0x20, 0x24, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x10, 0x34, 0x58, 0x48, 0x34, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x08, 0x04, 0x04, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x24, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x04, 0x08, 0x08, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x04, 0x18, 0x20, 0x44, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x04, 0x18, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x14, 0x24, 0x44, 0x7c, 0x04, 0x04, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x40, 0x78, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x18, 0x20, 0x40, 0x78, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x44, 0x04, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x44, 0x3c, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x04, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x42, 0x5a, 0x5a, 0x5e, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x40, 0x70, 0x40, 0x40, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x40, 0x70, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x40, 0x4c, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x48, 0x70, 0x48, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x6c, 0x54, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x78, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x48, 0x34, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x40, 0x38, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x44, 0x44, 0x44, 0x54, 0x6c, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x40, 0x20, 0x20, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x04, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x10, 0x3c, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x3c, 0x44, 0x44, 0x3c, 0x04, 0x78, 0x00, 0x00, },
|
||||
{ 0x00, 0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, },
|
||||
{ 0x00, 0x20, 0x20, 0x24, 0x28, 0x30, 0x28, 0x24, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x68, 0x54, 0x54, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x58, 0x64, 0x44, 0x78, 0x40, 0x40, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x34, 0x4c, 0x44, 0x3c, 0x04, 0x04, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x58, 0x64, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x3c, 0x40, 0x38, 0x04, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x38, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x44, 0x54, 0x54, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x78, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x7c, 0x08, 0x10, 0x20, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x10, 0x10, 0x20, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x08, 0x08, 0x04, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x24, 0x48, 0x12, 0x24, 0x48, 0x12, 0x24, 0x48, 0x12, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x7f, 0x7f, 0x7f, 0x7f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x38, 0x44, 0x40, 0x44, 0x38, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x18, 0x24, 0x20, 0x78, 0x20, 0x20, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x44, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x28, 0x7c, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x60, 0x58, 0x44, 0x34, 0x0c, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x3c, 0x4a, 0x52, 0x52, 0x4a, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x08, 0x38, 0x48, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x14, 0x28, 0x50, 0x28, 0x14, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x3c, 0x5a, 0x5a, 0x56, 0x42, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x48, 0x48, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x7c, 0x00, 0x00, },
|
||||
{ 0x00, 0x40, 0x20, 0x60, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x20, 0x60, 0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x7a, 0x40, 0x40, 0x00, },
|
||||
{ 0x00, 0x3c, 0x54, 0x54, 0x34, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x20, 0x60, 0x20, 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x50, 0x28, 0x14, 0x28, 0x50, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x48, 0x08, 0x10, 0x2c, 0x2c, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x44, 0x48, 0x08, 0x10, 0x24, 0x28, 0x4c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x64, 0x28, 0x68, 0x10, 0x2c, 0x2c, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x50, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x3c, 0x50, 0x50, 0x78, 0x50, 0x50, 0x5c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x40, 0x40, 0x44, 0x38, 0x08, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x00, 0x38, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x18, 0x00, 0x38, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x38, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x38, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x44, 0x64, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x14, 0x28, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x50, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x00, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x44, 0x28, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x10, 0x18, 0x14, 0x18, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x78, 0x44, 0x58, 0x44, 0x44, 0x44, 0x58, 0x40, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x50, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x2c, 0x52, 0x7c, 0x50, 0x2e, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x08, 0x10, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x18, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x08, 0x3c, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x50, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x38, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x50, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x10, 0x00, 0x7c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x00, 0x00, 0x38, 0x4c, 0x54, 0x64, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x60, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x10, 0x28, 0x00, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x44, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x0c, 0x00, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x78, 0x00, 0x00, },
|
||||
{ 0x00, 0x30, 0x10, 0x18, 0x14, 0x18, 0x10, 0x38, 0x00, 0x00, 0x00, },
|
||||
{ 0x00, 0x28, 0x00, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x78, 0x00, 0x00, },
|
||||
};
|
||||
|
|
31
video.lua
31
video.lua
|
@ -2,6 +2,8 @@ local args = { ... }
|
|||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local ccpi = require("ccpi")
|
||||
|
||||
local EV_NONCE = math.floor(0xFFFFFFFF * math.random())
|
||||
|
||||
settings.define("video.speaker.left", {
|
||||
description = "Speaker ID for left audio channel",
|
||||
default = peripheral.getName(peripheral.find("speaker")),
|
||||
|
@ -86,7 +88,8 @@ if not n_frames and not video_url and not audio_url_l then
|
|||
end
|
||||
end
|
||||
|
||||
print(string.format("Using monitor %s", peripheral.getName(monitor)))
|
||||
local mon_w, mon_h = monitor.getSize()
|
||||
print(string.format("Using monitor %s (%dx%d)", peripheral.getName(monitor), mon_w, mon_h))
|
||||
if speakers.r then
|
||||
print(string.format("Stereo sound: L=%s R=%s", peripheral.getName(speakers.l), peripheral.getName(speakers.r)))
|
||||
else
|
||||
|
@ -183,11 +186,11 @@ for i = 1, loading_concurrency do
|
|||
end
|
||||
|
||||
table.insert(subthreads, function()
|
||||
while #frames ~= n_frames or #audio_frames.l < n_audio_samples do
|
||||
repeat
|
||||
draw_bar(ty - 3, colors.blue, colors.gray, #frames / n_frames, "Loading video [%5d / %5d]", #frames, n_frames)
|
||||
draw_bar(ty - 2, colors.red, colors.gray, #audio_frames.l / n_audio_samples, "Loading audio [%5d / %5d]", #audio_frames.l, n_audio_samples)
|
||||
os.sleep(0.25)
|
||||
end
|
||||
until #frames >= n_frames and #audio_frames.l >= n_audio_samples
|
||||
print()
|
||||
end)
|
||||
|
||||
|
@ -208,14 +211,16 @@ table.insert(subthreads, function()
|
|||
break
|
||||
end
|
||||
end
|
||||
os.queueEvent("playback_ready")
|
||||
os.queueEvent("playback_ready", EV_NONCE)
|
||||
end)
|
||||
|
||||
table.insert(subthreads, function()
|
||||
local is_dfpwm = ({ audio_url_l:find("%.dfpwm") })[2] == #audio_url_l
|
||||
local decode = use_dfpwm and dfpwm.make_decoder() or decode_s8
|
||||
|
||||
os.pullEvent("playback_ready")
|
||||
repeat
|
||||
local _, nonce = os.pullEvent("playback_ready")
|
||||
until nonce == EV_NONCE
|
||||
|
||||
for i = 1, n_audio_samples do
|
||||
local buffer = decode(audio_frames.l[i])
|
||||
|
@ -232,7 +237,9 @@ table.insert(subthreads, function()
|
|||
local is_dfpwm = ({ audio_url_r:find("%.dfpwm") })[2] == #audio_url_r
|
||||
local decode = use_dfpwm and dfpwm.make_decoder() or decode_s8
|
||||
|
||||
os.pullEvent("playback_ready")
|
||||
repeat
|
||||
local _, nonce = os.pullEvent("playback_ready")
|
||||
until nonce == EV_NONCE
|
||||
|
||||
for i = 1, n_audio_samples do
|
||||
local buffer = decode(audio_frames.r[i])
|
||||
|
@ -244,8 +251,9 @@ table.insert(subthreads, function()
|
|||
end)
|
||||
|
||||
table.insert(subthreads, function()
|
||||
os.pullEvent("playback_ready")
|
||||
|
||||
repeat
|
||||
local _, nonce = os.pullEvent("playback_ready")
|
||||
until nonce == EV_NONCE
|
||||
local start_t = os.clock()
|
||||
while not playback_done do
|
||||
local frame = math.floor((os.clock() - start_t) / math.max(0.05, delay))
|
||||
|
@ -253,8 +261,11 @@ table.insert(subthreads, function()
|
|||
term.setBackgroundColor(frame >= #frames and colors.red or colors.gray)
|
||||
term.clearLine()
|
||||
term.write(string.format("Playing frame: %d/%d", frame + 1, #frames))
|
||||
if frames[frame + 1] then
|
||||
ccpi.draw(frames[frame + 1], 1, 1, monitor)
|
||||
local img = frames[frame + 1]
|
||||
if img ~= nil then
|
||||
local x = math.max(math.floor((mon_w - img.w) / 2), 1)
|
||||
local y = math.max(math.floor((mon_h - img.h) / 2), 1)
|
||||
ccpi.draw(img, x, y, monitor)
|
||||
end
|
||||
os.sleep(delay)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue