#include #include #include #include #include #include "mothra.h" typedef struct Pix Pix; struct Pix{ Pix *next; Image *b; int width; int height; char name[NNAME]; }; char *pixcmd[]={ [GIF] "gif -9t", [JPEG] "jpg -9t", [PNG] "png -9t", [BMP] "bmp -9t", }; void storebitmap(Rtext *t, Image *b){ t->b=b; free(t->text); t->text=0; } void getimage(Rtext *t, Www *w){ int pfd[2]; Action *ap; Url url; Image *b; int fd, typ; char err[512]; Pix *p; ap=t->user; seturl(&url, ap->image, w->url->fullname); for(p=w->pix;p!=nil; p=p->next) if(strcmp(ap->image, p->name)==0 && ap->width==p->width && ap->height==p->height){ storebitmap(t, p->b); w->changed=1; return; } fd=urlopen(&url, GET, 0); if(fd==-1){ Err: snprint(err, sizeof(err), "[%s: %r]", url.fullname); free(t->text); t->text=strdup(err); w->changed=1; close(fd); return; } typ = snooptype(fd); if(typ < 0 || typ >= nelem(pixcmd) || pixcmd[typ] == nil){ werrstr("unknown image type"); goto Err; } if((fd = pipeline(pixcmd[typ], fd)) < 0) goto Err; if(ap->width>0 || ap->height>0){ char buf[80]; char *p; p = buf; p += sprint(p, "resize"); if(ap->width>0) p += sprint(p, " -x %d", ap->width); if(ap->height>0) p += sprint(p, " -y %d", ap->height); if((fd = pipeline(buf, fd)) < 0) goto Err; } b=readimage(display, fd, 1); if(b==0){ werrstr("can't read image"); goto Err; } close(fd); p = emallocz(sizeof(Pix), 1); strncpy(p->name, ap->image, sizeof(p->name)); p->b=b; p->width=ap->width; p->height=ap->height; p->next=w->pix; w->pix=p; storebitmap(t, b); w->changed=1; } void getpix(Rtext *t, Www *w){ int i, pid, nworker, worker[NXPROC]; Action *ap; nworker = 0; for(i=0; inext){ ap=t->user; if(ap && ap->image){ pid = rfork(RFFDG|RFPROC|RFMEM); switch(pid){ case -1: fprint(2, "fork: %r\n"); break; case 0: getimage(t, w); exits(0); default: for(i=0; i 0){ if((pid = waitpid()) < 0) break; for(i=0; inext; freeimage(x->b); free(x); } }