ref: a1aa7038ba62a46b1173b609e4c884b1919d3949
dir: /flac.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <draw.h> #include "dat.h" #include "fncs.h" enum blocktype{ STREAMINFO, PADDING, APPLICATION, SEEKTABLE, VORBIS_COMMENT, CUESHEET, PICTURE, }; FlacPic* readFlacPic(int fd, vlong offset) { uchar buf[1024]; uint len; FlacPic *pic; pic = emalloc(sizeof(FlacPic)); /* We skip the picture type */ offset+=4; pread(fd, buf, 4, offset); len = bebtoi(buf, 4); offset+=4; pread(fd, buf, len, offset); buf[len] = '\0'; pic->mime = strdup((char*)buf); offset+=len; pread(fd, buf, 4, offset); len = bebtoi(buf, 4); offset+=4; pread(fd, buf, len, offset); buf[len] = '\0'; pic->desc = runesmprint("%s", (char*)buf); offset+=len; pread(fd, buf, 4, offset); pic->p.x = bebtoi(buf, 4); offset+=4; pread(fd, buf, 4, offset); pic->p.y = bebtoi(buf, 4); offset+=4; /*We skip color depth and index */ offset+=8; pread(fd, buf, 4, offset); pic->size = bebtoi(buf, 4); offset+=4; pic->data = emalloc(pic->size); pread(fd, pic->data, pic->size, offset); return pic; } typedef struct{ int fd; uvlong size; uchar *data; } WriteArg; void picwriteproc(void *arg) { int i, n; WriteArg *a = arg; int fd = a->fd; uchar *data = a->data; uvlong towrite = a->size; free(a); for(i = 0;towrite>0;){ n = write(fd, data+i, towrite); i+=n; towrite-=n; } } typedef struct{ int fdin; int fdout; Channel *cpid; char *cmd; } ExecArg; void picexecproc(void *arg) { ExecArg *a = arg; dup(a->fdin, 0); dup(a->fdout, 1); procexecl(a->cpid, a->cmd, a->cmd, "-c", nil); } void picresizeproc(void *arg) { ExecArg *a = arg; dup(a->fdin, 0); dup(a->fdout, 1); procexecl(a->cpid, "/bin/resize", "resize", "-x", "256", "-y", "256", nil); } char* mime2bin(char *mime) { char *slash = strchr(mime, '/'); if(slash==nil) return nil; slash+=1; if(strcmp(slash, "jpeg") == 0) return strdup("/bin/jpg"); if(strcmp(slash, "png") == 0) return strdup("/bin/png"); return nil; } void convFlacPic(FlacPic *pic) { ExecArg *e; WriteArg *w; int convin[2]; int convout[2]; int resize[2]; pipe(convin); pipe(convout); pipe(resize); w = emalloc(sizeof(WriteArg)); w->fd = convin[0]; w->data = pic->data; w->size = pic->size; procrfork(picwriteproc, w, 8192, RFFDG); /* other proc frees w */ e = emalloc(sizeof(ExecArg)); e->cpid = chancreate(sizeof(int), 0); e->fdin = convin[1]; e->fdout = convout[0]; e->cmd = mime2bin(pic->mime); procrfork(picexecproc, e, 8192, RFFDG); recv(e->cpid, nil); chanfree(e->cpid); free(e->cmd); free(e); e = emalloc(sizeof(ExecArg)); e->cpid = chancreate(sizeof(int), 0); e->fdin = convout[1]; e->fdout = resize[0]; procrfork(picresizeproc, e, 8192, RFFDG); recv(e->cpid, nil); chanfree(e->cpid); free(e); pic->i = readimage(display, resize[1], 0); close(convin[0]); close(convin[1]); close(convout[0]); close(convout[1]); close(resize[0]); close(resize[1]); } FlacMeta* readFlacMeta(int fd) { uvlong off; char type; FlacMeta *f; uchar buf[32]; pread(fd, buf, 4, 0); if(memcmp(buf, "fLaC", 4) != 0){ return nil; } off=4; f = emalloc(sizeof(FlacMeta)); while(pread(fd, buf, 1, off)){ type = *buf; off++; pread(fd, buf, 3, off); off+=3; switch(type & 0x7f){ case STREAMINFO: break; case PADDING: break; case APPLICATION: break; case SEEKTABLE: break; case VORBIS_COMMENT: f->com = parseVorbisMeta(fd, off); break; case CUESHEET: break; case PICTURE: f->pic = readFlacPic(fd, off); break; } off+=bebtoi(buf, 3); if((type & 0x80) > 0) break; } return f; }