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