Skip to content

Commit

Permalink
Merge pull request #50 from boretom/feature/add-height
Browse files Browse the repository at this point in the history
Fit vertically/adjust to terminal height
Closes #30
  • Loading branch information
posva committed Jul 20, 2020
2 parents d119619 + 860e13b commit 5adb42c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 20 deletions.
20 changes: 11 additions & 9 deletions man/catimg.1
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
.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
is a little program written in C with no dependencies that prints images in the terminal. It supports JPEG, PNG and GIF formats.

.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.
.TP
\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.

.SH AUTHORS
catimg was written by Eduardo San Martin Morote (https://github.com/posva)
.LP
This manual page was written by Jonathan Carter <jcarter@linux.com> and Eduardo San Martin Morote
This manual page was written by Jonathan Carter <jcarter@linux.com>, Eduardo San Martin Morote and Thomas Kupper
56 changes: 47 additions & 9 deletions src/catimg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#include "sh_utils.h"
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>

#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" \
Expand All @@ -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

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);*/
Expand Down
2 changes: 2 additions & 0 deletions src/sh_color.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 2 additions & 2 deletions src/sh_color.h
Original file line number Diff line number Diff line change
Expand Up @@ -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


/**
Expand Down
15 changes: 15 additions & 0 deletions src/sh_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/sh_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5adb42c

Please sign in to comment.