diff --git a/src/document/html/parser/link.c b/src/document/html/parser/link.c
index 41b98b4f3..73520a475 100644
--- a/src/document/html/parser/link.c
+++ b/src/document/html/parser/link.c
@@ -40,6 +40,7 @@
#include "globhist/globhist.h"
#include "mime/mime.h"
#include "protocol/uri.h"
+#include "terminal/image.h"
#ifdef CONFIG_KITTY
#include "terminal/kitty.h"
#endif
diff --git a/src/terminal/Makefile b/src/terminal/Makefile
index 317c32172..2b57c99f6 100644
--- a/src/terminal/Makefile
+++ b/src/terminal/Makefile
@@ -11,6 +11,7 @@ OBJS = \
draw.o \
event.o \
hardio.o \
+ image.o \
kbd.o \
screen.o \
tab.o \
diff --git a/src/terminal/image.c b/src/terminal/image.c
new file mode 100644
index 000000000..bfc39f740
--- /dev/null
+++ b/src/terminal/image.c
@@ -0,0 +1,123 @@
+/* Terminal kitty and sixel routines. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef CONFIG_GZIP
+#include
+#endif
+
+#ifdef CONFIG_LIBSIXEL
+#include
+#endif
+
+#include "elinks.h"
+
+#include "terminal/image.h"
+#include "util/base64.h"
+#include "util/memory.h"
+#include "util/string.h"
+
+#if defined(CONFIG_KITTY) || defined(CONFIG_SIXEL)
+#define STB_IMAGE_IMPLEMENTATION
+#include "terminal/stb_image.h"
+#endif
+
+#ifdef CONFIG_KITTY
+unsigned char *
+el_kitty_get_image(char *data, int length, int *outlen, int *width, int *height, int *compressed)
+{
+ ELOG
+ int comp;
+ unsigned char *pixels = stbi_load_from_memory((unsigned char *)data, length, width, height, &comp, KITTY_BYTES_PER_PIXEL);
+ unsigned char *b64;
+
+ if (!pixels) {
+ return NULL;
+ }
+ int size = *width * *height * KITTY_BYTES_PER_PIXEL;
+ *compressed = 0;
+
+#ifdef CONFIG_GZIP
+ unsigned char *complace = (unsigned char *)mem_alloc(size);
+
+ if (complace) {
+ unsigned long compsize = size;
+ int res = compress(complace, &compsize, pixels, size);
+
+ if (res == Z_OK) {
+ *compressed = 1;
+ b64 = base64_encode_bin(complace, compsize, outlen);
+ stbi_image_free(pixels);
+ mem_free(complace);
+ return b64;
+ }
+ mem_free(complace);
+ }
+#endif
+ b64 = base64_encode_bin(pixels, size, outlen);
+ stbi_image_free(pixels);
+
+ return b64;
+}
+#endif
+
+#ifdef CONFIG_LIBSIXEL
+static int
+sixel_write_callback(char *data, int size, void *priv)
+{
+ ELOG
+ struct string *text = priv;
+
+ add_bytes_to_string(text, data, size);
+ return size;
+}
+
+unsigned char *
+el_sixel_get_image(char *data, int length, int *outlen)
+{
+ ELOG
+ int comp;
+ int width;
+ int height;
+ unsigned char *outdata = NULL;
+ unsigned char *pixels = stbi_load_from_memory((unsigned char *)data, length, &width, &height, &comp, 3);
+
+ if (!pixels) {
+ return NULL;
+ }
+ sixel_output_t *output = NULL;
+ sixel_dither_t *dither = NULL;
+
+ struct string ret;
+
+ if (!init_string(&ret)) {
+ goto end;
+ }
+ SIXELSTATUS status = sixel_output_new(&output, sixel_write_callback, &ret, NULL);
+
+ if (SIXEL_FAILED(status)) {
+ goto end;
+ }
+ dither = sixel_dither_get(SIXEL_BUILTIN_XTERM256);
+ sixel_dither_set_pixelformat(dither, SIXEL_PIXELFORMAT_RGB888);
+ status = sixel_encode(pixels, width, height, 3, dither, output);
+ outdata = (unsigned char *)memacpy(ret.source, ret.length);
+
+ if (outdata) {
+ *outlen = ret.length;
+ }
+ done_string(&ret);
+end:
+ stbi_image_free(pixels);
+
+ return outdata;
+}
+#endif
diff --git a/src/terminal/image.h b/src/terminal/image.h
new file mode 100644
index 000000000..192060b54
--- /dev/null
+++ b/src/terminal/image.h
@@ -0,0 +1,20 @@
+#ifndef EL__TERMINAL_IMAGE_H
+#define EL__TERMINAL_IMAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIG_KITTY
+unsigned char *el_kitty_get_image(char *data, int len, int *outlen, int *width, int *height, int *compressed);
+#endif
+
+#ifdef CONFIG_LIBSIXEL
+unsigned char *el_sixel_get_image(char *data, int len, int *outlen);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EL__TERMINAL_IMAGE_H */
diff --git a/src/terminal/kitty.c b/src/terminal/kitty.c
index a57b69976..58c379426 100644
--- a/src/terminal/kitty.c
+++ b/src/terminal/kitty.c
@@ -10,10 +10,6 @@
#include
#include
-#ifdef CONFIG_GZIP
-#include
-#endif
-
#include "elinks.h"
#include "document/document.h"
@@ -26,46 +22,6 @@
#include "util/base64.h"
#include "util/memory.h"
-#define STB_IMAGE_IMPLEMENTATION
-#include "terminal/stb_image.h"
-
-unsigned char *
-el_kitty_get_image(char *data, int length, int *outlen, int *width, int *height, int *compressed)
-{
- ELOG
- int comp;
- unsigned char *pixels = stbi_load_from_memory((unsigned char *)data, length, width, height, &comp, KITTY_BYTES_PER_PIXEL);
- unsigned char *b64;
-
- if (!pixels) {
- return NULL;
- }
- int size = *width * *height * KITTY_BYTES_PER_PIXEL;
- *compressed = 0;
-
-#ifdef CONFIG_GZIP
- unsigned char *complace = (unsigned char *)mem_alloc(size);
-
- if (complace) {
- unsigned long compsize = size;
- int res = compress(complace, &compsize, pixels, size);
-
- if (res == Z_OK) {
- *compressed = 1;
- b64 = base64_encode_bin(complace, compsize, outlen);
- stbi_image_free(pixels);
- mem_free(complace);
- return b64;
- }
- mem_free(complace);
- }
-#endif
- b64 = base64_encode_bin(pixels, size, outlen);
- stbi_image_free(pixels);
-
- return b64;
-}
-
int
add_kitty_image_to_document(struct document *doc, char *data, int datalen, int lineno, struct k_image **imagine, int width, int height)
{
diff --git a/src/terminal/meson.build b/src/terminal/meson.build
index 08c5a075c..586ef9962 100644
--- a/src/terminal/meson.build
+++ b/src/terminal/meson.build
@@ -10,4 +10,4 @@ endif
if conf_data.get('CONFIG_TERMINFO')
srcs += files('terminfo.c')
endif
-srcs += files('color.c', 'draw.c', 'event.c', 'hardio.c', 'kbd.c', 'screen.c', 'tab.c', 'terminal.c', 'window.c')
+srcs += files('color.c', 'draw.c', 'event.c', 'hardio.c', 'image.c', 'kbd.c', 'screen.c', 'tab.c', 'terminal.c', 'window.c')
diff --git a/src/terminal/sixel.c b/src/terminal/sixel.c
index 4fc15c95b..b5b566d3d 100644
--- a/src/terminal/sixel.c
+++ b/src/terminal/sixel.c
@@ -27,11 +27,6 @@
#include "config.h"
#endif
-#ifdef HAVE_MEMFD_CREATE
-#define _GNU_SOURCE /* See feature_test_macros(7) */
-#include
-#endif
-
#include
#include
#include
@@ -1055,76 +1050,3 @@ end:
return dest;
}
-
-unsigned char *
-el_sixel_get_image(char *data, int length, int *outlen)
-{
- ELOG
- SIXELSTATUS status = SIXEL_FALSE;
- sixel_encoder_t *encoder = NULL;
- unsigned char *ret = NULL;
- *outlen = 0;
-
-#ifdef HAVE_MEMFD_CREATE
-#ifdef CONFIG_MEMCOUNT
- init_allocator();
- status = sixel_encoder_new(&encoder, el_sixel_allocator);
-#else
- status = sixel_encoder_new(&encoder, NULL);
-#endif
-
- if (SIXEL_FAILED(status)) {
- goto error;
- }
- int fdout = -1;
-
- encoder->outfd = memfd_create("out.sixel", 0);
- fdout = dup(encoder->outfd);
- encoder->fstatic = 1;
-
- int fdin = memfd_create("input.sixel", 0);
- FILE *f = fdopen(fdin, "wb");
-
- if (!f) {
- goto error;
- }
- fwrite(data, 1, length, f);
- rewind(f);
-
- struct string name;
- if (!init_string(&name)) {
- goto error;
- }
- add_format_to_string(&name, "/proc/self/fd/%d", fdin);
- status = sixel_encoder_encode(encoder, name.source);
- done_string(&name);
-
- if (SIXEL_FAILED(status)) {
- goto error;
- }
-
- struct stat sb;
- fstat(fdout, &sb);
-
- if (sb.st_size > 0) {
- ret = (unsigned char *)mem_alloc(sb.st_size);
-
- if (ret) {
- FILE *f2 = fdopen(fdout, "rb");
- if (f2) {
- rewind(f2);
- *outlen = (int)fread(ret, 1, (size_t)sb.st_size, f2);
- fclose(f2);
- }
- }
- }
- close(fdout);
-
-error:
- if (f) {
- fclose(f);
- }
- sixel_encoder_unref(encoder);
-#endif
- return ret;
-}
diff --git a/src/terminal/sixel.h b/src/terminal/sixel.h
index 74e03f7c3..6099f5ef6 100644
--- a/src/terminal/sixel.h
+++ b/src/terminal/sixel.h
@@ -34,8 +34,6 @@ int add_image_to_document(struct document *doc, struct string *pixels, int linen
struct image *copy_frame(struct image *src, struct el_box *box, int cell_width, int cell_height, int dx, int dy);
-unsigned char *el_sixel_get_image(char *data, int len, int *outlen);
-
#endif
#ifdef __cplusplus