Show the first frame of animation gif files.

This commit is contained in:
Araki Ken
2014-09-25 23:21:41 +09:00
committed by Tatsuya Kinoshita
parent e8b2d47358
commit 4a9c976e32

87
terms.c
View File

@@ -484,6 +484,89 @@ put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw,
MOVE(Currentbuf->cursorY,Currentbuf->cursorX);
}
static void
save_gif(const char *path, u_char *header, size_t header_size, u_char *body, size_t body_size)
{
int fd;
if ((fd = open(path, O_WRONLY|O_CREAT, 0600)) >= 0) {
write(fd, header, header_size) ;
write(fd, body, body_size) ;
write(fd, "\x3b" , 1) ;
close(fd) ;
}
}
static u_char *
skip_gif_header(u_char *p)
{
/* Header */
p += 10;
if (*(p) & 0x80) {
p += (3 * (2 << ((*p) & 0x7)));
}
p += 3;
return p;
}
static void
save_first_animation_frame(const char *path)
{
int fd;
struct stat st;
u_char *header;
size_t header_size;
u_char *body;
u_char *p;
ssize_t len;
if ((fd = open( path, O_RDONLY)) < 0) {
return 0;
}
if (fstat( fd, &st) != 0 || ! (header = GC_malloc( st.st_size))){
close( fd);
return 0;
}
len = read(fd, header, st.st_size);
close(fd);
/* Header */
if (len != st.st_size || strncmp(header, "GIF89a", 6) != 0) {
return 0;
}
p = skip_gif_header(header);
header_size = p - header;
/* Application Extension */
if (p[0] == 0x21 && p[1] == 0xff) {
p += 19;
}
/* Other blocks */
body = NULL;
while (p + 2 < header + st.st_size) {
if (*(p++) == 0x21 && *(p++) == 0xf9 && *(p++) == 0x04) {
if( body) {
/* Graphic Control Extension */
save_gif(path, header, header_size, body, p - 3 - body);
break;
}
else {
/* skip the first frame. */
}
body = p - 3;
}
}
return 1;
}
void
put_image_sixel(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh)
{
@@ -492,6 +575,10 @@ put_image_sixel(char *url, int x, int y, int w, int h, int sx, int sy, int sw, i
MOVE(y,x);
flush_tty();
if (!strstr(url, "://")) {
save_first_animation_frame(url);
}
if ((pid = fork()) == 0) {
char *argv[11];
char digit[2][11+1];