Skip to content

Commit

Permalink
Closes #5 Added higher resolution and an option for loops
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Oct 4, 2015
1 parent 6390401 commit b188503
Showing 1 changed file with 71 additions and 29 deletions.
100 changes: 71 additions & 29 deletions src/catimg.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sh_image.h"
#include "sh_utils.h"
#include <unistd.h>
#include <signal.h>
#define USAGE printf("Usage catimg [-h] [-w width] img\nBy default w is the terminal width.\n")
#define USAGE printf("Usage catimg [-h] [-w width] [-l loops] [-r resolution] img\nBy default w is the terminal width.\nLoops are only useful with GIF. A value of 1 means that the GIF will be displayed twice. A negative value means infinite looping.\nResolution must be 1 or 2. By default catimg checks for unicode support to use higher resolution\n")

extern char *optarg;
extern int optind;
Expand All @@ -23,6 +24,25 @@ void intHandler() {

int getopt(int argc, char * const argv[], const char *optstring);

uint32_t pixelToInt(const color_t *pixel) {
if (pixel->a == 0)
return 0xffff;
else if (pixel->r == pixel->g && pixel->g == pixel->b)
return 232 + (pixel->r * 23)/255;
else
return (16 + ((pixel->r*5)/255)*36
+ ((pixel->g*5)/255)*6
+ (pixel->b*5)/255);
}

char supportsUTF8() {
const char* LC_ALL = getenv("LC_ALL");
const char* LANG = getenv("LANG");
const char* LC_CTYPE = getenv("LC_CTYPE");
const char* UTF = "UTF-8";
return strstr(LC_ALL, UTF) || strstr(LANG, UTF) || strstr(LC_CTYPE, UTF);
}

int main(int argc, char *argv[])
{
init_hash_colors();
Expand All @@ -31,13 +51,19 @@ int main(int argc, char *argv[])
char *num;
int c;
opterr = 0;
uint32_t cols = terminal_columns() >> 1; // divided by 2 because of 2 chars

while ((c = getopt (argc, argv, "w:h")) != -1)
uint32_t cols = 0, precision = 0;
while ((c = getopt (argc, argv, "w:l:r:h")) != -1)
switch (c) {
case 'w':
cols = strtol(optarg, &num, 0) >> 1;
break;
case 'l':
loops = strtol(optarg, &num, 0);
break;
case 'r':
precision = strtol(optarg, &num, 0);
break;
case 'h':
USAGE;
exit(0);
Expand All @@ -54,6 +80,15 @@ int main(int argc, char *argv[])
exit(1);
}

if (precision == 0 || precision > 2) {
if (supportsUTF8)
precision = 2;
else
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);
img_load_from_file(&img, file);
if (cols < img.width) {
float sc = cols/(float)img.width;
Expand All @@ -71,7 +106,7 @@ int main(int argc, char *argv[])
// Save the cursor position and hide it
printf("\e[s\e[?25l");
while (loop++ < loops || loops < 0) {
uint32_t w = 0, offset = 0;
uint32_t offset = 0;
for (uint32_t frame = 0; frame < img.frames; frame++) {
if (frame > 0 || loop > 0) {
if (frame > 0)
Expand All @@ -80,34 +115,41 @@ int main(int argc, char *argv[])
usleep(img.delays[img.frames - 1] * 10000);
printf("\e[u");
}
uint32_t i, index;
for (i = 0; i < img.width*img.height; i++) {
index = i + offset;
if (img.pixels[index].a == 0) {
printf("\e[m ");
} else {
uint32_t col;
if (img.pixels[index].r == img.pixels[index].g && img.pixels[index].g == img.pixels[index].b)
col = 232 + (img.pixels[index].r*23)/255;
else
col = (16 + ((img.pixels[index].r*5)/255)*36
+ ((img.pixels[index].g*5)/255)*6
+ (img.pixels[index].b*5)/255);

/*printf("(%u,%u,%u)", img.pixels[index].r, img.pixels[index].g, img.pixels[index].b);*/
printf("\e[48;5;%um ", col);
uint32_t index, x, y;
for (y = 0; y < img.height; y += precision) {
for (x = 0; x < img.width; x++) {
index = y * img.width + x + offset;
uint32_t fgCol = pixelToInt(&img.pixels[index]);
if (precision == 2) {
if (y < img.height - 1) {
uint32_t bgCol = pixelToInt(&img.pixels[index + img.width]);
if (fgCol ==0xffff) { // first pixel is transparent
if (bgCol ==0xffff)
printf("\e[m ");
else
printf("\e[0;38;5;%um\u2584", bgCol);
} else {
if (bgCol ==0xffff)
printf("\e[0;38;5;%um\u2580", fgCol);
else
printf("\e[38;5;%u;48;5;%um\u2580", fgCol, bgCol);
}
} else { // this is the last line
if (fgCol ==0xffff)
printf("\e[m ");
else
printf("\e[38;5;%um\u2580", fgCol);
}
} else {
if (fgCol == 0xffff)
printf("\e[m ");
else
printf("\e[48;5;%um ", fgCol);
}
}
w++;
if (w >= img.width) {
w = 0;
printf("\e[m\n");
}
}
offset += i;
if (w != 0 && w < img.width) {
w = 0;
printf("\e[m\n");
}
offset += img.width * img.height;
if (stop) frame = img.frames;
}
}
Expand Down

0 comments on commit b188503

Please sign in to comment.