1 /* See LICENSE for licence details. */
2 #include <sixel.h>
3
4 enum {
5 SIXEL_COLORS = 256,
6 SIXEL_BPP = 3,
7 };
8
9 struct sixel_t {
10 sixel_output_t *context;
11 sixel_dither_t *dither;
12 };
13
sixel_write_callback(char * data,int size,void * priv)14 int sixel_write_callback(char *data, int size, void *priv)
15 {
16 struct tty_t *tty = (struct tty_t *) priv;
17 char *ptr;
18 ssize_t wsize, left;
19
20 logging(DEBUG, "callback() data size:%d\n", size);
21
22 ptr = data;
23 left = size;
24
25 while (ptr < (data + size)) {
26 wsize = ewrite(tty->fd, ptr, left);
27 ptr += wsize;
28 left -= wsize;
29 }
30
31 return true;
32 }
33
sixel_init(struct tty_t * tty,struct sixel_t * sixel,struct image * img)34 bool sixel_init(struct tty_t *tty, struct sixel_t *sixel, struct image *img)
35 {
36 /* XXX: libsixel only allows 3 bytes per pixel image,
37 we should convert bpp when bpp is 1 or 2 or 4 */
38 if (get_image_channel(img) != SIXEL_BPP)
39 normalize_bpp(img, SIXEL_BPP, true);
40
41 if ((sixel->dither = sixel_dither_create(SIXEL_COLORS)) == NULL) {
42 logging(ERROR, "couldn't create dither\n");
43 return false;
44 }
45
46 /* XXX: use first frame for dither initialize */
47 if (sixel_dither_initialize(sixel->dither, get_current_frame(img),
48 get_image_width(img), get_image_height(img),
49 SIXEL_BPP, LARGE_AUTO, REP_AUTO, QUALITY_AUTO) != 0) {
50 logging(ERROR, "couldn't initialize dither\n");
51 sixel_dither_unref(sixel->dither);
52 return false;
53 }
54 sixel_dither_set_diffusion_type(sixel->dither, DIFFUSE_AUTO);
55 //sixel_dither_set_diffusion_type(sixel->dither, DIFFUSE_NONE);
56
57 if ((sixel->context = sixel_output_create(sixel_write_callback, (void *) tty)) == NULL) {
58 logging(ERROR, "couldn't create sixel context\n");
59 return false;
60 }
61 sixel_output_set_8bit_availability(sixel->context, CSIZE_7BIT);
62
63 return true;
64 }
65
sixel_die(struct sixel_t * sixel)66 void sixel_die(struct sixel_t *sixel)
67 {
68 if (sixel->dither)
69 sixel_dither_unref(sixel->dither);
70
71 if (sixel->context)
72 sixel_output_unref(sixel->context);
73 }
74
sixel_write(struct tty_t * tty,struct sixel_t * sixel,struct image * img)75 void sixel_write(struct tty_t *tty, struct sixel_t *sixel, struct image *img)
76 {
77 (void) tty;
78
79 sixel_encode(get_current_frame(img), get_image_width(img), get_image_height(img),
80 get_image_channel(img), sixel->dither, sixel->context);
81 }
82