Blame


1 28994509 2004-04-21 devnull #include <u.h>
2 28994509 2004-04-21 devnull #include <libc.h>
3 28994509 2004-04-21 devnull #include <bio.h>
4 28994509 2004-04-21 devnull #include <draw.h>
5 28994509 2004-04-21 devnull #include <event.h>
6 28994509 2004-04-21 devnull #include "imagefile.h"
7 28994509 2004-04-21 devnull
8 28994509 2004-04-21 devnull int cflag = 0;
9 28994509 2004-04-21 devnull int dflag = 0;
10 28994509 2004-04-21 devnull int eflag = 0;
11 28994509 2004-04-21 devnull int nineflag = 0;
12 28994509 2004-04-21 devnull int threeflag = 0;
13 28994509 2004-04-21 devnull int output = 0;
14 28994509 2004-04-21 devnull ulong outchan = CMAP8;
15 28994509 2004-04-21 devnull Image **allims;
16 28994509 2004-04-21 devnull Image **allmasks;
17 28994509 2004-04-21 devnull int which;
18 28994509 2004-04-21 devnull int defaultcolor = 1;
19 28994509 2004-04-21 devnull
20 28994509 2004-04-21 devnull enum{
21 28994509 2004-04-21 devnull Border = 2,
22 28994509 2004-04-21 devnull Edge = 5
23 28994509 2004-04-21 devnull };
24 28994509 2004-04-21 devnull
25 28994509 2004-04-21 devnull char *show(int, char*);
26 28994509 2004-04-21 devnull
27 28994509 2004-04-21 devnull Rectangle
28 28994509 2004-04-21 devnull imager(void)
29 28994509 2004-04-21 devnull {
30 28994509 2004-04-21 devnull Rectangle r;
31 28994509 2004-04-21 devnull
32 28994509 2004-04-21 devnull if(allims==nil || allims[0]==nil)
33 28994509 2004-04-21 devnull return screen->r;
34 28994509 2004-04-21 devnull r = insetrect(screen->clipr, Edge+Border);
35 28994509 2004-04-21 devnull r.max.x = r.min.x+Dx(allims[0]->r);
36 28994509 2004-04-21 devnull r.max.y = r.min.y+Dy(allims[0]->r);
37 28994509 2004-04-21 devnull return r;
38 28994509 2004-04-21 devnull }
39 28994509 2004-04-21 devnull
40 28994509 2004-04-21 devnull void
41 28994509 2004-04-21 devnull eresized(int new)
42 28994509 2004-04-21 devnull {
43 28994509 2004-04-21 devnull Rectangle r;
44 28994509 2004-04-21 devnull
45 28994509 2004-04-21 devnull if(new && getwindow(display, Refnone) < 0){
46 28994509 2004-04-21 devnull fprint(2, "gif: can't reattach to window\n");
47 28994509 2004-04-21 devnull exits("resize");
48 28994509 2004-04-21 devnull }
49 28994509 2004-04-21 devnull if(allims==nil || allims[which]==nil)
50 28994509 2004-04-21 devnull return;
51 846ec3d2 2006-02-15 devnull r = rectaddpt(allims[0]->r, subpt(screen->r.min, allims[0]->r.min));
52 28a8042c 2006-03-19 devnull if(!new && !winsize)
53 846ec3d2 2006-02-15 devnull drawresizewindow(r);
54 846ec3d2 2006-02-15 devnull r = rectaddpt(r, subpt(allims[which]->r.min, allims[0]->r.min));
55 28994509 2004-04-21 devnull drawop(screen, r, allims[which], allmasks[which], allims[which]->r.min, S);
56 28994509 2004-04-21 devnull flushimage(display, 1);
57 be36ff68 2004-04-29 devnull }
58 be36ff68 2004-04-29 devnull
59 be36ff68 2004-04-29 devnull void
60 be36ff68 2004-04-29 devnull usage(void)
61 be36ff68 2004-04-29 devnull {
62 be36ff68 2004-04-29 devnull fprint(2, "usage: gif -39cdektv -W winsize [file.gif ...]\n");
63 be36ff68 2004-04-29 devnull exits("usage");
64 28994509 2004-04-21 devnull }
65 28994509 2004-04-21 devnull
66 be36ff68 2004-04-29 devnull
67 28994509 2004-04-21 devnull void
68 28994509 2004-04-21 devnull main(int argc, char *argv[])
69 28994509 2004-04-21 devnull {
70 28994509 2004-04-21 devnull int fd, i;
71 28994509 2004-04-21 devnull char *err;
72 28994509 2004-04-21 devnull
73 28994509 2004-04-21 devnull ARGBEGIN{
74 be36ff68 2004-04-29 devnull case 'W':
75 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
76 be36ff68 2004-04-29 devnull break;
77 28994509 2004-04-21 devnull case '3': /* produce encoded, compressed, three-color bitmap file; no display by default */
78 28994509 2004-04-21 devnull threeflag++;
79 28994509 2004-04-21 devnull /* fall through */
80 28994509 2004-04-21 devnull case 't': /* produce encoded, compressed, true-color bitmap file; no display by default */
81 28994509 2004-04-21 devnull cflag++;
82 28994509 2004-04-21 devnull dflag++;
83 28994509 2004-04-21 devnull output++;
84 28994509 2004-04-21 devnull defaultcolor = 0;
85 28994509 2004-04-21 devnull outchan = RGB24;
86 28994509 2004-04-21 devnull break;
87 28994509 2004-04-21 devnull case 'c': /* produce encoded, compressed, bitmap file; no display by default */
88 28994509 2004-04-21 devnull cflag++;
89 28994509 2004-04-21 devnull dflag++;
90 28994509 2004-04-21 devnull output++;
91 28994509 2004-04-21 devnull if(defaultcolor)
92 28994509 2004-04-21 devnull outchan = CMAP8;
93 28994509 2004-04-21 devnull break;
94 28994509 2004-04-21 devnull case 'd': /* suppress display of image */
95 28994509 2004-04-21 devnull dflag++;
96 28994509 2004-04-21 devnull break;
97 28994509 2004-04-21 devnull case 'e': /* disable floyd-steinberg error diffusion */
98 28994509 2004-04-21 devnull eflag++;
99 28994509 2004-04-21 devnull break;
100 28994509 2004-04-21 devnull case 'k': /* force black and white */
101 28994509 2004-04-21 devnull defaultcolor = 0;
102 28994509 2004-04-21 devnull outchan = GREY8;
103 28994509 2004-04-21 devnull break;
104 28994509 2004-04-21 devnull case 'v': /* force RGBV */
105 28994509 2004-04-21 devnull defaultcolor = 0;
106 28994509 2004-04-21 devnull outchan = CMAP8;
107 28994509 2004-04-21 devnull break;
108 28994509 2004-04-21 devnull case '9': /* produce plan 9, uncompressed, bitmap file; no display by default */
109 28994509 2004-04-21 devnull nineflag++;
110 28994509 2004-04-21 devnull dflag++;
111 28994509 2004-04-21 devnull output++;
112 28994509 2004-04-21 devnull if(defaultcolor)
113 28994509 2004-04-21 devnull outchan = CMAP8;
114 28994509 2004-04-21 devnull break;
115 28994509 2004-04-21 devnull default:
116 be36ff68 2004-04-29 devnull usage();
117 28994509 2004-04-21 devnull }ARGEND;
118 28994509 2004-04-21 devnull
119 28994509 2004-04-21 devnull err = nil;
120 28994509 2004-04-21 devnull if(argc == 0)
121 28994509 2004-04-21 devnull err = show(0, "<stdin>");
122 28994509 2004-04-21 devnull else{
123 28994509 2004-04-21 devnull for(i=0; i<argc; i++){
124 28994509 2004-04-21 devnull fd = open(argv[i], OREAD);
125 28994509 2004-04-21 devnull if(fd < 0){
126 28994509 2004-04-21 devnull fprint(2, "gif: can't open %s: %r\n", argv[i]);
127 28994509 2004-04-21 devnull err = "open";
128 28994509 2004-04-21 devnull }else{
129 28994509 2004-04-21 devnull err = show(fd, argv[i]);
130 28994509 2004-04-21 devnull close(fd);
131 28994509 2004-04-21 devnull }
132 28994509 2004-04-21 devnull if(output && argc>1 && err==nil){
133 28994509 2004-04-21 devnull fprint(2, "gif: exiting after one file\n");
134 28994509 2004-04-21 devnull break;
135 28994509 2004-04-21 devnull }
136 28994509 2004-04-21 devnull }
137 28994509 2004-04-21 devnull }
138 28994509 2004-04-21 devnull exits(err);
139 28994509 2004-04-21 devnull }
140 28994509 2004-04-21 devnull
141 28994509 2004-04-21 devnull Image*
142 28994509 2004-04-21 devnull transparency(Rawimage *r, char *name)
143 28994509 2004-04-21 devnull {
144 28994509 2004-04-21 devnull Image *i;
145 28994509 2004-04-21 devnull int j, index;
146 28994509 2004-04-21 devnull uchar *pic, *mpic, *mask;
147 28994509 2004-04-21 devnull
148 28994509 2004-04-21 devnull if((r->gifflags&TRANSP) == 0)
149 28994509 2004-04-21 devnull return nil;
150 28994509 2004-04-21 devnull i = allocimage(display, r->r, GREY8, 0, 0);
151 28994509 2004-04-21 devnull if(i == nil){
152 28994509 2004-04-21 devnull fprint(2, "gif: allocimage for mask of %s failed: %r\n", name);
153 28994509 2004-04-21 devnull return nil;
154 28994509 2004-04-21 devnull }
155 28994509 2004-04-21 devnull pic = r->chans[0];
156 28994509 2004-04-21 devnull mask = malloc(r->chanlen);
157 28994509 2004-04-21 devnull if(mask == nil){
158 28994509 2004-04-21 devnull fprint(2, "gif: malloc for mask of %s failed: %r\n", name);
159 28994509 2004-04-21 devnull freeimage(i);
160 28994509 2004-04-21 devnull return nil;
161 28994509 2004-04-21 devnull }
162 28994509 2004-04-21 devnull index = r->giftrindex;
163 28994509 2004-04-21 devnull mpic = mask;
164 28994509 2004-04-21 devnull for(j=0; j<r->chanlen; j++)
165 28994509 2004-04-21 devnull if(*pic++ == index)
166 28994509 2004-04-21 devnull *mpic++ = 0;
167 28994509 2004-04-21 devnull else
168 28994509 2004-04-21 devnull *mpic++ = 0xFF;
169 28994509 2004-04-21 devnull if(loadimage(i, i->r, mask, r->chanlen) < 0){
170 28994509 2004-04-21 devnull fprint(2, "gif: loadimage for mask of %s failed: %r\n", name);
171 28994509 2004-04-21 devnull free(mask);
172 28994509 2004-04-21 devnull freeimage(i);
173 28994509 2004-04-21 devnull return nil;
174 28994509 2004-04-21 devnull }
175 28994509 2004-04-21 devnull free(mask);
176 28994509 2004-04-21 devnull return i;
177 28994509 2004-04-21 devnull }
178 28994509 2004-04-21 devnull
179 28994509 2004-04-21 devnull /* interleave alpha values of 0xFF in data stream. alpha value comes first, then b g r */
180 28994509 2004-04-21 devnull uchar*
181 28994509 2004-04-21 devnull expand(uchar *u, int chanlen, int nchan)
182 28994509 2004-04-21 devnull {
183 28994509 2004-04-21 devnull int j, k;
184 28994509 2004-04-21 devnull uchar *v, *up, *vp;
185 28994509 2004-04-21 devnull
186 28994509 2004-04-21 devnull v = malloc(chanlen*(nchan+1));
187 28994509 2004-04-21 devnull if(v == nil){
188 28994509 2004-04-21 devnull fprint(2, "gif: malloc fails: %r\n");
189 28994509 2004-04-21 devnull exits("malloc");
190 28994509 2004-04-21 devnull }
191 28994509 2004-04-21 devnull up = u;
192 28994509 2004-04-21 devnull vp = v;
193 28994509 2004-04-21 devnull for(j=0; j<chanlen; j++){
194 28994509 2004-04-21 devnull *vp++ = 0xFF;
195 28994509 2004-04-21 devnull for(k=0; k<nchan; k++)
196 28994509 2004-04-21 devnull *vp++ = *up++;
197 28994509 2004-04-21 devnull }
198 28994509 2004-04-21 devnull return v;
199 28994509 2004-04-21 devnull }
200 28994509 2004-04-21 devnull
201 28994509 2004-04-21 devnull void
202 28994509 2004-04-21 devnull addalpha(Rawimage *i)
203 28994509 2004-04-21 devnull {
204 28994509 2004-04-21 devnull char buf[32];
205 28994509 2004-04-21 devnull
206 28994509 2004-04-21 devnull switch(outchan){
207 28994509 2004-04-21 devnull case CMAP8:
208 28994509 2004-04-21 devnull i->chans[0] = expand(i->chans[0], i->chanlen/1, 1);
209 28994509 2004-04-21 devnull i->chanlen = 2*(i->chanlen/1);
210 28994509 2004-04-21 devnull i->chandesc = CRGBVA16;
211 28994509 2004-04-21 devnull outchan = CHAN2(CMap, 8, CAlpha, 8);
212 28994509 2004-04-21 devnull break;
213 28994509 2004-04-21 devnull
214 28994509 2004-04-21 devnull case GREY8:
215 28994509 2004-04-21 devnull i->chans[0] = expand(i->chans[0], i->chanlen/1, 1);
216 28994509 2004-04-21 devnull i->chanlen = 2*(i->chanlen/1);
217 28994509 2004-04-21 devnull i->chandesc = CYA16;
218 28994509 2004-04-21 devnull outchan = CHAN2(CGrey, 8, CAlpha, 8);
219 28994509 2004-04-21 devnull break;
220 28994509 2004-04-21 devnull
221 28994509 2004-04-21 devnull case RGB24:
222 28994509 2004-04-21 devnull i->chans[0] = expand(i->chans[0], i->chanlen/3, 3);
223 28994509 2004-04-21 devnull i->chanlen = 4*(i->chanlen/3);
224 28994509 2004-04-21 devnull i->chandesc = CRGBA32;
225 28994509 2004-04-21 devnull outchan = RGBA32;
226 28994509 2004-04-21 devnull break;
227 28994509 2004-04-21 devnull
228 28994509 2004-04-21 devnull default:
229 28994509 2004-04-21 devnull chantostr(buf, outchan);
230 28994509 2004-04-21 devnull fprint(2, "gif: can't add alpha to type %s\n", buf);
231 28994509 2004-04-21 devnull exits("err");
232 28994509 2004-04-21 devnull }
233 28994509 2004-04-21 devnull }
234 28994509 2004-04-21 devnull
235 28994509 2004-04-21 devnull /*
236 28994509 2004-04-21 devnull * Called only when writing output. If the output is RGBA32,
237 28994509 2004-04-21 devnull * we must write four bytes per pixel instead of two.
238 28994509 2004-04-21 devnull * There's always at least two: data plus alpha.
239 28994509 2004-04-21 devnull * r is used only for reference; the image is already in c.
240 28994509 2004-04-21 devnull */
241 28994509 2004-04-21 devnull void
242 4e247f10 2011-05-17 rsc blackout(Rawimage *r, Rawimage *c)
243 28994509 2004-04-21 devnull {
244 28994509 2004-04-21 devnull int i, trindex;
245 28994509 2004-04-21 devnull uchar *rp, *cp;
246 28994509 2004-04-21 devnull
247 28994509 2004-04-21 devnull rp = r->chans[0];
248 28994509 2004-04-21 devnull cp = c->chans[0];
249 28994509 2004-04-21 devnull trindex = r->giftrindex;
250 28994509 2004-04-21 devnull if(outchan == RGBA32)
251 28994509 2004-04-21 devnull for(i=0; i<r->chanlen; i++){
252 28994509 2004-04-21 devnull if(*rp == trindex){
253 28994509 2004-04-21 devnull *cp++ = 0x00;
254 4e247f10 2011-05-17 rsc *cp++ = 0x00;
255 4e247f10 2011-05-17 rsc *cp++ = 0x00;
256 4e247f10 2011-05-17 rsc *cp++ = 0x00;
257 28994509 2004-04-21 devnull }else{
258 28994509 2004-04-21 devnull *cp++ = 0xFF;
259 28994509 2004-04-21 devnull cp += 3;
260 28994509 2004-04-21 devnull }
261 28994509 2004-04-21 devnull rp++;
262 28994509 2004-04-21 devnull }
263 28994509 2004-04-21 devnull else
264 28994509 2004-04-21 devnull for(i=0; i<r->chanlen; i++){
265 28994509 2004-04-21 devnull if(*rp == trindex){
266 28994509 2004-04-21 devnull *cp++ = 0x00;
267 4e247f10 2011-05-17 rsc *cp++ = 0x00;
268 28994509 2004-04-21 devnull }else{
269 28994509 2004-04-21 devnull *cp++ = 0xFF;
270 28994509 2004-04-21 devnull cp++;
271 28994509 2004-04-21 devnull }
272 28994509 2004-04-21 devnull rp++;
273 28994509 2004-04-21 devnull }
274 28994509 2004-04-21 devnull }
275 28994509 2004-04-21 devnull
276 28994509 2004-04-21 devnull int
277 28994509 2004-04-21 devnull init(void)
278 28994509 2004-04-21 devnull {
279 28994509 2004-04-21 devnull static int inited;
280 28994509 2004-04-21 devnull
281 28994509 2004-04-21 devnull if(inited == 0){
282 28994509 2004-04-21 devnull if(initdraw(0, 0, 0) < 0){
283 28994509 2004-04-21 devnull fprint(2, "gif: initdraw failed: %r\n");
284 28994509 2004-04-21 devnull return -1;
285 28994509 2004-04-21 devnull }
286 28994509 2004-04-21 devnull einit(Ekeyboard|Emouse);
287 28994509 2004-04-21 devnull inited++;
288 28994509 2004-04-21 devnull }
289 28994509 2004-04-21 devnull return 1;
290 28994509 2004-04-21 devnull }
291 28994509 2004-04-21 devnull
292 28994509 2004-04-21 devnull char*
293 28994509 2004-04-21 devnull show(int fd, char *name)
294 28994509 2004-04-21 devnull {
295 28994509 2004-04-21 devnull Rawimage **images, **rgbv;
296 28994509 2004-04-21 devnull Image **ims, **masks;
297 28994509 2004-04-21 devnull int j, k, n, ch, nloop, loopcount, dt;
298 28994509 2004-04-21 devnull char *err;
299 28994509 2004-04-21 devnull char buf[32];
300 28994509 2004-04-21 devnull
301 28994509 2004-04-21 devnull err = nil;
302 28994509 2004-04-21 devnull images = readgif(fd, CRGB);
303 28994509 2004-04-21 devnull if(images == nil){
304 28994509 2004-04-21 devnull fprint(2, "gif: decode %s failed: %r\n", name);
305 28994509 2004-04-21 devnull return "decode";
306 28994509 2004-04-21 devnull }
307 28994509 2004-04-21 devnull for(n=0; images[n]; n++)
308 28994509 2004-04-21 devnull ;
309 28994509 2004-04-21 devnull ims = malloc((n+1)*sizeof(Image*));
310 28994509 2004-04-21 devnull masks = malloc((n+1)*sizeof(Image*));
311 28994509 2004-04-21 devnull rgbv = malloc((n+1)*sizeof(Rawimage*));
312 28994509 2004-04-21 devnull if(masks==nil || rgbv==nil || ims==nil){
313 28994509 2004-04-21 devnull fprint(2, "gif: malloc of masks for %s failed: %r\n", name);
314 28994509 2004-04-21 devnull err = "malloc";
315 28994509 2004-04-21 devnull goto Return;
316 28994509 2004-04-21 devnull }
317 28994509 2004-04-21 devnull memset(masks, 0, (n+1)*sizeof(Image*));
318 28994509 2004-04-21 devnull memset(ims, 0, (n+1)*sizeof(Image*));
319 28994509 2004-04-21 devnull memset(rgbv, 0, (n+1)*sizeof(Rawimage*));
320 28994509 2004-04-21 devnull if(!dflag){
321 28994509 2004-04-21 devnull if(init() < 0){
322 28994509 2004-04-21 devnull err = "initdraw";
323 28994509 2004-04-21 devnull goto Return;
324 28994509 2004-04-21 devnull }
325 28994509 2004-04-21 devnull if(defaultcolor && screen->depth>8)
326 28994509 2004-04-21 devnull outchan = RGB24;
327 28994509 2004-04-21 devnull }
328 28994509 2004-04-21 devnull
329 28994509 2004-04-21 devnull for(k=0; k<n; k++){
330 28994509 2004-04-21 devnull if(outchan == CMAP8)
331 28994509 2004-04-21 devnull rgbv[k] = torgbv(images[k], !eflag);
332 28994509 2004-04-21 devnull else{
333 28994509 2004-04-21 devnull if(outchan==GREY8 || (images[k]->chandesc==CY && threeflag==0))
334 28994509 2004-04-21 devnull rgbv[k] = totruecolor(images[k], CY);
335 28994509 2004-04-21 devnull else
336 28994509 2004-04-21 devnull rgbv[k] = totruecolor(images[k], CRGB24);
337 28994509 2004-04-21 devnull }
338 28994509 2004-04-21 devnull if(rgbv[k] == nil){
339 28994509 2004-04-21 devnull fprint(2, "gif: converting %s to local format failed: %r\n", name);
340 28994509 2004-04-21 devnull err = "torgbv";
341 28994509 2004-04-21 devnull goto Return;
342 28994509 2004-04-21 devnull }
343 28994509 2004-04-21 devnull if(!dflag){
344 28994509 2004-04-21 devnull masks[k] = transparency(images[k], name);
345 28994509 2004-04-21 devnull if(rgbv[k]->chandesc == CY)
346 28994509 2004-04-21 devnull ims[k] = allocimage(display, rgbv[k]->r, GREY8, 0, 0);
347 28994509 2004-04-21 devnull else
348 28994509 2004-04-21 devnull ims[k] = allocimage(display, rgbv[k]->r, outchan, 0, 0);
349 28994509 2004-04-21 devnull if(ims[k] == nil){
350 28994509 2004-04-21 devnull fprint(2, "gif: allocimage %s failed: %r\n", name);
351 28994509 2004-04-21 devnull err = "allocimage";
352 28994509 2004-04-21 devnull goto Return;
353 28994509 2004-04-21 devnull }
354 28994509 2004-04-21 devnull if(loadimage(ims[k], ims[k]->r, rgbv[k]->chans[0], rgbv[k]->chanlen) < 0){
355 28994509 2004-04-21 devnull fprint(2, "gif: loadimage %s failed: %r\n", name);
356 28994509 2004-04-21 devnull err = "loadimage";
357 28994509 2004-04-21 devnull goto Return;
358 28994509 2004-04-21 devnull }
359 28994509 2004-04-21 devnull }
360 28994509 2004-04-21 devnull }
361 28994509 2004-04-21 devnull
362 28994509 2004-04-21 devnull allims = ims;
363 28994509 2004-04-21 devnull allmasks = masks;
364 28994509 2004-04-21 devnull loopcount = images[0]->gifloopcount;
365 28994509 2004-04-21 devnull if(!dflag){
366 28994509 2004-04-21 devnull nloop = 0;
367 28994509 2004-04-21 devnull do{
368 28994509 2004-04-21 devnull for(k=0; k<n; k++){
369 28994509 2004-04-21 devnull which = k;
370 28994509 2004-04-21 devnull eresized(0);
371 28994509 2004-04-21 devnull dt = images[k]->gifdelay*10;
372 28994509 2004-04-21 devnull if(dt < 50)
373 28994509 2004-04-21 devnull dt = 50;
374 28994509 2004-04-21 devnull while(n==1 || ecankbd()){
375 28994509 2004-04-21 devnull if((ch=ekbd())=='q' || ch==0x7F || ch==0x04) /* an odd, democratic list */
376 28994509 2004-04-21 devnull exits(nil);
377 28994509 2004-04-21 devnull if(ch == '\n')
378 28994509 2004-04-21 devnull goto Out;
379 28994509 2004-04-21 devnull }sleep(dt);
380 28994509 2004-04-21 devnull }
381 28994509 2004-04-21 devnull /* loopcount -1 means no loop (this code's rule), loopcount 0 means loop forever (netscape's rule)*/
382 28994509 2004-04-21 devnull }while(loopcount==0 || ++nloop<loopcount);
383 28994509 2004-04-21 devnull /* loop count has run out */
384 28994509 2004-04-21 devnull ekbd();
385 28994509 2004-04-21 devnull Out:
386 28994509 2004-04-21 devnull drawop(screen, screen->clipr, display->white, nil, ZP, S);
387 28994509 2004-04-21 devnull }
388 28994509 2004-04-21 devnull if(n>1 && output)
389 28994509 2004-04-21 devnull fprint(2, "gif: warning: only writing first image in %d-image GIF %s\n", n, name);
390 28994509 2004-04-21 devnull if(nineflag){
391 28994509 2004-04-21 devnull if(images[0]->gifflags&TRANSP){
392 28994509 2004-04-21 devnull addalpha(rgbv[0]);
393 4e247f10 2011-05-17 rsc blackout(images[0], rgbv[0]);
394 28994509 2004-04-21 devnull }
395 28994509 2004-04-21 devnull chantostr(buf, outchan);
396 28994509 2004-04-21 devnull print("%11s %11d %11d %11d %11d ", buf,
397 28994509 2004-04-21 devnull rgbv[0]->r.min.x, rgbv[0]->r.min.y, rgbv[0]->r.max.x, rgbv[0]->r.max.y);
398 28994509 2004-04-21 devnull if(write(1, rgbv[0]->chans[0], rgbv[0]->chanlen) != rgbv[0]->chanlen){
399 28994509 2004-04-21 devnull fprint(2, "gif: %s: write error %r\n", name);
400 28994509 2004-04-21 devnull return "write";
401 28994509 2004-04-21 devnull }
402 28994509 2004-04-21 devnull }else if(cflag){
403 28994509 2004-04-21 devnull if(images[0]->gifflags&TRANSP){
404 28994509 2004-04-21 devnull addalpha(rgbv[0]);
405 4e247f10 2011-05-17 rsc blackout(images[0], rgbv[0]);
406 28994509 2004-04-21 devnull }
407 28994509 2004-04-21 devnull if(writerawimage(1, rgbv[0]) < 0){
408 28994509 2004-04-21 devnull fprint(2, "gif: %s: write error: %r\n", name);
409 28994509 2004-04-21 devnull return "write";
410 28994509 2004-04-21 devnull }
411 28994509 2004-04-21 devnull }
412 28994509 2004-04-21 devnull
413 28994509 2004-04-21 devnull Return:
414 28994509 2004-04-21 devnull allims = nil;
415 28994509 2004-04-21 devnull allmasks = nil;
416 28994509 2004-04-21 devnull for(k=0; images[k]; k++){
417 28994509 2004-04-21 devnull for(j=0; j<images[k]->nchans; j++)
418 28994509 2004-04-21 devnull free(images[k]->chans[j]);
419 28994509 2004-04-21 devnull free(images[k]->cmap);
420 28994509 2004-04-21 devnull if(rgbv[k])
421 28994509 2004-04-21 devnull free(rgbv[k]->chans[0]);
422 28994509 2004-04-21 devnull freeimage(ims[k]);
423 28994509 2004-04-21 devnull freeimage(masks[k]);
424 28994509 2004-04-21 devnull free(images[k]);
425 28994509 2004-04-21 devnull free(rgbv[k]);
426 28994509 2004-04-21 devnull }
427 28994509 2004-04-21 devnull free(images);
428 28994509 2004-04-21 devnull free(masks);
429 28994509 2004-04-21 devnull free(ims);
430 28994509 2004-04-21 devnull return err;
431 28994509 2004-04-21 devnull }