diff --git a/man/catimg.1 b/man/catimg.1 index a0e4d9e..073c0e3 100644 --- a/man/catimg.1 +++ b/man/catimg.1 @@ -1,12 +1,11 @@ -.TH CATIMG "1" "January 2017" "catimg" "General Commands Manual" +.TH CATIMG "1" "June 2020" "catimg" "General Commands Manual" .SH NAME catimg \- fast image printing in to your terminal .SH SYNOPSIS .B catimg -[\fIoptions\fP] -\fBimage\fP +[\fB-hct\fP] [\fB-w width\fP | \fB-H height\fP] [\fB-l loops\fP] [\fB-r resolution\fP] image .SH DESCRIPTION .B catimg @@ -14,11 +13,14 @@ is a little program written in C with no dependencies that prints images in the .SH OPTIONS .TP +\fB\-c\fR +Coerce colors to a restricted palette. Allows terminals with limited color support to render a more accurate version of the image than if it was directly done by the terminal itself. +.TP \fB\-h\fR Prints a help message .TP -\fB\-w\fR WIDTH -Specify the width of the displayed image, by default catimg will use the terminal width. +\fB\-H\fR HEIGHT +Specify the height of the displayed image, passing '0' will use terminal height. .TP \fB\-l\fR LOOPS Specify the amount of loops that catimg should repeat a GIF. A value of 1 means that the GIF will be displayed twice. A negative value implies infinity. @@ -26,11 +28,11 @@ Specify the amount of loops that catimg should repeat a GIF. A value of 1 means \fB\-r\fR RESOLUTION Possible values 1 or 2. Force the resolution of the image. By default catimg will check if rendering in higher resolution is possible and do so or use the lower one. .TP -\fB\-c\fR -Convert colors to a restricted palette. This is useful when terminal only support a limited set of colors. This transformation should be more accurate than the one performed by the terminal. -.TP \fB\-t\fR Disables true color (24-bit) support, falling back to 256 color escape codes instead. +.TP +\fB\-w\fR WIDTH +Specify the width of the displayed image. When not provided, catimg will use the terminal width. .SH BUGS Please report any bugs to https://github.com/posva/catimg/issues. @@ -38,4 +40,4 @@ Please report any bugs to https://github.com/posva/catimg/issues. .SH AUTHORS catimg was written by Eduardo San Martin Morote (https://github.com/posva) .LP -This manual page was written by Jonathan Carter and Eduardo San Martin Morote +This manual page was written by Jonathan Carter , Eduardo San Martin Morote and Thomas Kupper diff --git a/src/catimg.c b/src/catimg.c index 151a616..c5bb00a 100644 --- a/src/catimg.c +++ b/src/catimg.c @@ -5,10 +5,12 @@ #include "sh_utils.h" #include #include +#include -#define USAGE "Usage: catimg [-hct] [-w width] [-l loops] [-r resolution] image-file\n\n" \ +#define USAGE "Usage: catimg [-hct] [-w width | -H height] [-l loops] [-r resolution] image-file\n\n" \ " -h: Displays this message\n" \ - " -w: Terminal width by default\n" \ + " -w: Terminal width/columns by default\n" \ + " -H: Terminal height/row by default\n" \ " -l: Loops are only useful with GIF files. A value of 1 means that the GIF will " \ "be displayed twice because it loops once. A negative value means infinite " \ "looping\n" \ @@ -17,6 +19,8 @@ " -c: Convert colors to a restricted palette\n" \ " -t: Disables true color (24-bit) support, falling back to 256 color\n" +#define ERR_WIDTH_OR_HEIGHT "[ERROR] '-w' and '-H' can't be used at the same time\n\n" + // Transparency threshold -- all pixels with alpha below 25%. #define TRANSP_ALPHA 64 @@ -67,13 +71,34 @@ int main(int argc, char *argv[]) int c; opterr = 0; - uint32_t cols = 0, precision = 0; + uint32_t cols = 0, rows = 0, precision = 0; + uint32_t max_cols = 0, max_rows = 0; uint8_t convert = 0; uint8_t true_color = 1; - while ((c = getopt (argc, argv, "w:l:r:hct")) != -1) + uint8_t adjust_to_height = 0, adjust_to_width = 0; + float scale_cols = 0, scale_rows = 0; + + while ((c = getopt (argc, argv, "H:w:l:r:hct")) != -1) switch (c) { + case 'H': + rows = strtol(optarg, &num, 0) >> 1; + if (adjust_to_width) { + // only either adjust to width or adjust to height is allowed, but not both. + printf(ERR_WIDTH_OR_HEIGHT); + printf(USAGE); + exit(1); + } + adjust_to_height = 1; + break; case 'w': cols = strtol(optarg, &num, 0) >> 1; + if (adjust_to_height) { + // only either adjust to width or adjust to height is allowed, but not both. + printf(ERR_WIDTH_OR_HEIGHT); + printf(USAGE); + exit(1); + } + adjust_to_width = 1; break; case 'l': loops = strtol(optarg, &num, 0); @@ -111,18 +136,31 @@ int main(int argc, char *argv[]) precision = 1; } - if (cols < 1) // if precision is 2 we can use the terminal full width. Otherwise we can only use half - cols = terminal_columns() / (2 / precision); + // if precision is 2 we can use the terminal full width/height. Otherwise we can only use half + max_cols = terminal_columns() / (2 / precision); + max_rows = terminal_rows() * 2 / (2 / precision); if (strcmp(file, "-") == 0) { img_load_from_stdin(&img); } else { img_load_from_file(&img, file); } - if (cols < img.width) { - float sc = cols/(float)img.width; - img_resize(&img, sc, sc); + if (cols == 0 && rows == 0) { + scale_cols = max_cols / (float)img.width; + scale_rows = max_rows / (float)img.height; + if (adjust_to_height && scale_rows < scale_cols && max_rows < img.height) + // rows == 0 and adjust_to_height > adjust to height instead of width + img_resize(&img, scale_rows, scale_rows); + else if (max_cols < img.width) + img_resize(&img, scale_cols, scale_cols); + } else if (cols > 0 && cols < img.width) { + scale_cols = cols / (float)img.width; + img_resize(&img, scale_cols, scale_cols); + } else if (rows > 0 && rows < img.height) { + scale_rows = (float)(rows * 2) / (float)img.height; + img_resize(&img, scale_rows, scale_rows); } + if (convert) img_convert_colors(&img); /*printf("Loaded %s: %ux%u. Console width: %u\n", file, img.width, img.height, cols);*/ diff --git a/src/sh_color.c b/src/sh_color.c index 813f5b7..d478953 100644 --- a/src/sh_color.c +++ b/src/sh_color.c @@ -6,6 +6,8 @@ uint32_t color_map[] = { 0x000000, 0x00005F, 0x000080, 0x000087, 0x0000AF, 0x0000D7, 0x0000FF, 0x005F5F, 0x005F87, 0x005FAF, 0x005FD7, 0x005FFF, 0x008000, 0x008080, 0x008700, 0x00875F, 0x008787, 0x0087AF, 0x0087D7, 0x0087FF, 0x00AF00, 0x00AF5F, 0x00AF87, 0x00AFAF, 0x00AFFF, 0x00D700, 0x00D75F, 0x00D787, 0x00D7AF, 0x00D7D7, 0x00D7FF, 0x00FF00, 0x00FF5F, 0x00FF87, 0x00FFAF, 0x00FFD7, 0x00FFFF, 0x121212, 0x1C1C1C, 0x262626, 0x303030, 0x3A3A3A, 0x444444, 0x4E4E4E, 0x585858, 0x005F00, 0x5F0000, 0x5F005F, 0x5F0087, 0x5F00AF, 0x5F00D7, 0x5F00FF, 0x5F5F00, 0x5F5F5F, 0x5F5F87, 0x5F5FAF, 0x5F5FD7, 0x5F5FFF, 0x5F8700, 0x5F875F, 0x5F8787, 0x5F87AF, 0x5F87D7, 0x5F87FF, 0x5FAF00, 0x5FAF5F, 0x5FAF87, 0x5FAFAF, 0x5FAFD7, 0x5FAFFF, 0x5FD700, 0x5FD75F, 0x5FD787, 0x5FD7AF, 0x5FD7D7, 0x5FD7FF, 0x5FFF00, 0x5FFF5F, 0x5FFF87, 0x5FFFAF, 0x5FFFD7, 0x5FFFFF, 0x626262, 0x767676, 0x800000, 0x800080, 0x808000, 0x080808, 0x808080, 0x870000, 0x87005F, 0x870087, 0x8700AF, 0x8700D7, 0x8700FF, 0x875F00, 0x875F5F, 0x875F87, 0x875FAF, 0x875FD7, 0x875FFF, 0x878700, 0x87875F, 0x878787, 0x8787AF, 0x8787D7, 0x8787FF, 0x87AF00, 0x87AF5F, 0x87AF87, 0x87AFAF, 0x87AFD7, 0x87AFFF, 0x87D700, 0x87D75F, 0x87D787, 0x87D7AF, 0x87D7D7, 0x87D7FF, 0x87FF00, 0x87FF5F, 0x87FF87, 0x87FFAF, 0x87FFD7, 0x87FFFF, 0x8A8A8A, 0x949494, 0x9E9E9E, 0xA8A8A8, 0xAF0000, 0xAF005F, 0xAF0087, 0xAF00AF, 0xAF00D7, 0xAF00FF, 0xAF5F00, 0xAF5F5F, 0xAF5F87, 0xAF5FAF, 0xAF5FD7, 0xAF5FFF, 0xAF8700, 0xAF875F, 0xAF8787, 0xAF87AF, 0xAF87D7, 0xAF87FF, 0xAFAF00, 0xAFAF5F, 0xAFAF87, 0xAFAFAF, 0xAFAFD7, 0xAFAFFF, 0x00AFD7, 0xAFD700, 0xAFD75F, 0xAFD787, 0xAFD7AF, 0xAFD7D7, 0xAFD7FF, 0xAFFF00, 0xAFFF5F, 0xAFFF87, 0xAFFFAF, 0xAFFFD7, 0xAFFFFF, 0xB2B2B2, 0xBCBCBC, 0xC0C0C0, 0xC6C6C6, 0xD0D0D0, 0xD70000, 0xD7005F, 0xD70087, 0xD700AF, 0xD700D7, 0xD700FF, 0xD75F00, 0xD75F5F, 0xD75F87, 0xD75FAF, 0xD75FD7, 0xD75FFF, 0xD78700, 0xD7875F, 0xD78787, 0xD787AF, 0xD787D7, 0xD787FF, 0xD7AF00, 0xD7AF5F, 0xD7AF87, 0xD7AFAF, 0xD7AFD7, 0xD7AFFF, 0xD7D700, 0xD7D75F, 0xD7D787, 0xD7D7AF, 0xD7D7D7, 0xD7D7FF, 0xD7FF00, 0xD7FF5F, 0xD7FF87, 0xD7FFAF, 0xD7FFD7, 0xD7FFFF, 0xDADADA, 0xE4E4E4, 0xEEEEEE, 0xFF0000, 0xFF005F, 0xFF0087, 0xFF00AF, 0xFF00D7, 0xFF00FF, 0xFF5F00, 0xFF5F5F, 0xFF5F87, 0xFF5FAF, 0xFF5FD7, 0xFF5FFF, 0xFF8700, 0xFF875F, 0xFF8787, 0xFF87AF, 0xFF87D7, 0xFF87FF, 0xFFAF00, 0xFFAF5F, 0xFFAF87, 0xFFAFAF, 0xFFAFD7, 0xFFAFFF, 0xFFD700, 0xFFD75F, 0xFFD787, 0xFFD7AF, 0xFFD7D7, 0xFFD7FF, 0xFFFF00, 0xFFFF5F, 0xFFFF87, 0xFFFFAF, 0xFFFFD7, 0xFFFFFF }; +color_yuv_t yuv_color_map[N_COLORS]; ///< palette of the terminal colors in YUV format + void rgb2yuv(const color_t *rgb, color_yuv_t *yuv) { diff --git a/src/sh_color.h b/src/sh_color.h index e1585a7..7598fee 100644 --- a/src/sh_color.h +++ b/src/sh_color.h @@ -36,9 +36,9 @@ typedef struct { } color_yuv_t; #define N_COLORS 247 ///< Number of colors in terminal -uint32_t color_map[N_COLORS]; ///< palette of the terminal colors in RGB 0x00RRGGBB +//uint32_t color_map[N_COLORS]; ///< palette of the terminal colors in RGB 0x00RRGGBB // yuv equivalents -color_yuv_t yuv_color_map[N_COLORS]; ///< palette of the terminal colors in YUV format +//color_yuv_t yuv_color_map[N_COLORS]; ///< palette of the terminal colors in YUV format /** diff --git a/src/sh_utils.c b/src/sh_utils.c index 33a1f4b..c2cb3e6 100644 --- a/src/sh_utils.c +++ b/src/sh_utils.c @@ -29,6 +29,21 @@ uint32_t terminal_columns() #endif } +uint32_t terminal_rows() +{ +#ifdef WINDOWS + CONSOLE_SCREEN_BUFFER_INFO csbi; + int ret; + ret = GetConsoleScreenBufferInfo(GetStdHandle( STD_OUTPUT_HANDLE ),&csbi); + return ret?csbi.dwSize.Y:0; +#else + struct winsize win; + ioctl(1, TIOCGWINSZ, &win); + return win.ws_row; +#endif +} + + #define READ_BUF_SIZE 4096 uint32_t read_stdin(unsigned char **ptr) { #ifdef WINDOWS diff --git a/src/sh_utils.h b/src/sh_utils.h index c799d99..9c6a6c7 100644 --- a/src/sh_utils.h +++ b/src/sh_utils.h @@ -32,6 +32,13 @@ */ uint32_t terminal_columns(); +/** + * @brief Get the number of rows for the terminal + * @return the number of rows + */ +uint32_t terminal_rows(); + + /** * @brief Read binary data from stdin * @param ptr Address to the ptr which will be filled with the data