xref: /plan9/sys/src/cmd/jpg/togif.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include <u.h>
2*7dd7cddfSDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <memdraw.h>
5*7dd7cddfSDavid du Colombier #include <ctype.h>
6*7dd7cddfSDavid du Colombier #include <bio.h>
7*7dd7cddfSDavid du Colombier #include "imagefile.h"
8*7dd7cddfSDavid du Colombier 
9*7dd7cddfSDavid du Colombier void
usage(void)10*7dd7cddfSDavid du Colombier usage(void)
11*7dd7cddfSDavid du Colombier {
12*7dd7cddfSDavid du Colombier 	fprint(2, "usage: togif [-l loopcount] [-c 'comment'] [-d Δt (ms)] [-t transparency-index] [file ... [-d Δt] file ...]\n");
13*7dd7cddfSDavid du Colombier 	exits("usage");
14*7dd7cddfSDavid du Colombier }
15*7dd7cddfSDavid du Colombier 
16*7dd7cddfSDavid du Colombier #define	UNSET (-12345678)
17*7dd7cddfSDavid du Colombier 
18*7dd7cddfSDavid du Colombier void
main(int argc,char * argv[])19*7dd7cddfSDavid du Colombier main(int argc, char *argv[])
20*7dd7cddfSDavid du Colombier {
21*7dd7cddfSDavid du Colombier 	Biobuf bout;
22*7dd7cddfSDavid du Colombier 	Memimage *i, *ni;
23*7dd7cddfSDavid du Colombier 	int fd, j, dt, trans, loop;
24*7dd7cddfSDavid du Colombier 	char buf[256];
25*7dd7cddfSDavid du Colombier 	char *err, *comment, *s;
26*7dd7cddfSDavid du Colombier 
27*7dd7cddfSDavid du Colombier 	comment = nil;
28*7dd7cddfSDavid du Colombier 	dt = -1;
29*7dd7cddfSDavid du Colombier 	trans = -1;
30*7dd7cddfSDavid du Colombier 	loop = UNSET;
31*7dd7cddfSDavid du Colombier 	ARGBEGIN{
32*7dd7cddfSDavid du Colombier 	case 'l':
33*7dd7cddfSDavid du Colombier 		s = ARGF();
34*7dd7cddfSDavid du Colombier 		if(s==nil || (!isdigit(s[0]) && s[0]!='-'))
35*7dd7cddfSDavid du Colombier 			usage();
36*7dd7cddfSDavid du Colombier 		loop = atoi(s);
37*7dd7cddfSDavid du Colombier 		break;
38*7dd7cddfSDavid du Colombier 	case 'c':
39*7dd7cddfSDavid du Colombier 		comment = ARGF();
40*7dd7cddfSDavid du Colombier 		if(comment == nil)
41*7dd7cddfSDavid du Colombier 			usage();
42*7dd7cddfSDavid du Colombier 		break;
43*7dd7cddfSDavid du Colombier 	case 'd':
44*7dd7cddfSDavid du Colombier 		s = ARGF();
45*7dd7cddfSDavid du Colombier 		if(s==nil || !isdigit(s[0]))
46*7dd7cddfSDavid du Colombier 			usage();
47*7dd7cddfSDavid du Colombier 		dt = atoi(s);
48*7dd7cddfSDavid du Colombier 		break;
49*7dd7cddfSDavid du Colombier 	case 't':
50*7dd7cddfSDavid du Colombier 		s = ARGF();
51*7dd7cddfSDavid du Colombier 		if(s==nil || !isdigit(s[0]))
52*7dd7cddfSDavid du Colombier 			usage();
53*7dd7cddfSDavid du Colombier 		trans = atoi(s);
54*7dd7cddfSDavid du Colombier 		if(trans > 255)
55*7dd7cddfSDavid du Colombier 			usage();
56*7dd7cddfSDavid du Colombier 		break;
57*7dd7cddfSDavid du Colombier 	default:
58*7dd7cddfSDavid du Colombier 		usage();
59*7dd7cddfSDavid du Colombier 	}ARGEND
60*7dd7cddfSDavid du Colombier 
61*7dd7cddfSDavid du Colombier 	if(Binit(&bout, 1, OWRITE) < 0)
62*7dd7cddfSDavid du Colombier 		sysfatal("Binit failed: %r");
63*7dd7cddfSDavid du Colombier 
64*7dd7cddfSDavid du Colombier 	memimageinit();
65*7dd7cddfSDavid du Colombier 
66*7dd7cddfSDavid du Colombier 	err = nil;
67*7dd7cddfSDavid du Colombier 
68*7dd7cddfSDavid du Colombier 	if(argc == 0){
69*7dd7cddfSDavid du Colombier 		i = readmemimage(0);
70*7dd7cddfSDavid du Colombier 		if(i == nil)
71*7dd7cddfSDavid du Colombier 			sysfatal("reading input: %r");
72*7dd7cddfSDavid du Colombier 		ni = memonechan(i);
73*7dd7cddfSDavid du Colombier 		if(ni == nil)
74*7dd7cddfSDavid du Colombier 			sysfatal("converting image to RGBV: %r");
75*7dd7cddfSDavid du Colombier 		if(i != ni){
76*7dd7cddfSDavid du Colombier 			freememimage(i);
77*7dd7cddfSDavid du Colombier 			i = ni;
78*7dd7cddfSDavid du Colombier 		}
79*7dd7cddfSDavid du Colombier 		err = memstartgif(&bout, i, -1);
80*7dd7cddfSDavid du Colombier 		if(err == nil){
81*7dd7cddfSDavid du Colombier 			if(comment)
82*7dd7cddfSDavid du Colombier 				err = memwritegif(&bout, i, comment, dt, trans);
83*7dd7cddfSDavid du Colombier 			else{
84*7dd7cddfSDavid du Colombier 				snprint(buf, sizeof buf, "Converted by Plan 9 from <stdin>");
85*7dd7cddfSDavid du Colombier 				err = memwritegif(&bout, i, buf, dt, trans);
86*7dd7cddfSDavid du Colombier 			}
87*7dd7cddfSDavid du Colombier 		}
88*7dd7cddfSDavid du Colombier 	}else{
89*7dd7cddfSDavid du Colombier 		if(loop == UNSET){
90*7dd7cddfSDavid du Colombier 			if(argc == 1)
91*7dd7cddfSDavid du Colombier 				loop = -1;	/* no loop for single image */
92*7dd7cddfSDavid du Colombier 			else
93*7dd7cddfSDavid du Colombier 				loop = 0;	/* the default case: 0 means infinite loop */
94*7dd7cddfSDavid du Colombier 		}
95*7dd7cddfSDavid du Colombier 		for(j=0; j<argc; j++){
96*7dd7cddfSDavid du Colombier 			if(argv[j][0] == '-' && argv[j][1]=='d'){
97*7dd7cddfSDavid du Colombier 				/* time change */
98*7dd7cddfSDavid du Colombier 				if(argv[j][2] == '\0'){
99*7dd7cddfSDavid du Colombier 					s = argv[++j];
100*7dd7cddfSDavid du Colombier 					if(j == argc)
101*7dd7cddfSDavid du Colombier 						usage();
102*7dd7cddfSDavid du Colombier 				}else
103*7dd7cddfSDavid du Colombier 					s = &argv[j][2];
104*7dd7cddfSDavid du Colombier 				if(!isdigit(s[0]))
105*7dd7cddfSDavid du Colombier 					usage();
106*7dd7cddfSDavid du Colombier 				dt = atoi(s);
107*7dd7cddfSDavid du Colombier 				if(j == argc-1)	/* last argument must be file */
108*7dd7cddfSDavid du Colombier 					usage();
109*7dd7cddfSDavid du Colombier 				continue;
110*7dd7cddfSDavid du Colombier 			}
111*7dd7cddfSDavid du Colombier 			fd = open(argv[j], OREAD);
112*7dd7cddfSDavid du Colombier 			if(fd < 0)
113*7dd7cddfSDavid du Colombier 				sysfatal("can't open %s: %r", argv[j]);
114*7dd7cddfSDavid du Colombier 			i = readmemimage(fd);
115*7dd7cddfSDavid du Colombier 			if(i == nil)
116*7dd7cddfSDavid du Colombier 				sysfatal("can't readimage %s: %r", argv[j]);
117*7dd7cddfSDavid du Colombier 			close(fd);
118*7dd7cddfSDavid du Colombier 			ni = memonechan(i);
119*7dd7cddfSDavid du Colombier 			if(ni == nil)
120*7dd7cddfSDavid du Colombier 				sysfatal("converting image to RGBV: %r");
121*7dd7cddfSDavid du Colombier 			if(i != ni){
122*7dd7cddfSDavid du Colombier 				freememimage(i);
123*7dd7cddfSDavid du Colombier 				i = ni;
124*7dd7cddfSDavid du Colombier 			}
125*7dd7cddfSDavid du Colombier 			if(j == 0){
126*7dd7cddfSDavid du Colombier 				err = memstartgif(&bout, i, loop);
127*7dd7cddfSDavid du Colombier 				if(err != nil)
128*7dd7cddfSDavid du Colombier 					break;
129*7dd7cddfSDavid du Colombier 			}
130*7dd7cddfSDavid du Colombier 			if(comment)
131*7dd7cddfSDavid du Colombier 				err = memwritegif(&bout, i, comment, dt, trans);
132*7dd7cddfSDavid du Colombier 			else{
133*7dd7cddfSDavid du Colombier 				snprint(buf, sizeof buf, "Converted by Plan 9 from %s", argv[j]);
134*7dd7cddfSDavid du Colombier 				err = memwritegif(&bout, i, buf, dt, trans);
135*7dd7cddfSDavid du Colombier 			}
136*7dd7cddfSDavid du Colombier 			if(err != nil)
137*7dd7cddfSDavid du Colombier 				break;
138*7dd7cddfSDavid du Colombier 			freememimage(i);
139*7dd7cddfSDavid du Colombier 			comment = nil;
140*7dd7cddfSDavid du Colombier 		}
141*7dd7cddfSDavid du Colombier 	}
142*7dd7cddfSDavid du Colombier 	memendgif(&bout);
143*7dd7cddfSDavid du Colombier 
144*7dd7cddfSDavid du Colombier 	if(err != nil)
145*7dd7cddfSDavid du Colombier 		fprint(2, "togif: %s\n", err);
146*7dd7cddfSDavid du Colombier 	exits(err);
147*7dd7cddfSDavid du Colombier }
148