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