ref: a86cea4bc4207f2193a2ba5e35730f1a087f5c06
dir: /stl.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "stl.h" static int Bgets(Biobuf *b, u16int *s) { uchar buf[2]; if(Bread(b, buf, 2) != 2){ werrstr("could not get 2 bytes"); return -1; } *s = buf[0] | buf[1] << 8; return 0; } static int Bgetl(Biobuf *b, u32int *l) { uchar buf[4]; if(Bread(b, buf, 4) != 4){ werrstr("could not get 4 bytes"); return -1; } *l = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24; return 0; } static int Bgetf(Biobuf *b, float *f) { u32int l; if(Bgetl(b, &l) < 0){ werrstr("Bgetl: %r"); return -1; } *f = *(float*)&l; return 0; } static int Bgetfv(Biobuf *b, float *f) { int i; for(i = 0; i < 3; i++) if(Bgetf(b, &f[i]) < 0){ werrstr("Bgetf: %r"); return -1; } return 0; } Stl * readstl(int fd) { Biobuf *bin; Stltri *tri; Stl *stl; u32int i, ntris; bin = Bfdopen(fd, OREAD); if(bin == nil){ werrstr("Bfdopen: %r"); return nil; } stl = mallocz(sizeof(Stl), 1); if(stl == nil){ werrstr("mallocz: %r"); goto error; } if(Bread(bin, stl->hdr, sizeof(stl->hdr)) != sizeof(stl->hdr)){ werrstr("Bread: %r"); goto error; } if(Bgetl(bin, &ntris) < 0){ werrstr("Bgetl: %r"); goto error; } for(i = 0; i < ntris; i++){ tri = mallocz(sizeof(Stltri), 1); if(tri == nil){ free(tri); werrstr("mallocz: %r"); goto error; } if(Bgetfv(bin, tri->n) < 0){ free(tri); werrstr("Bgetfv: %r"); goto error; } if(Bgetfv(bin, tri->p0) < 0){ free(tri); werrstr("Bgetfv: %r"); goto error; } if(Bgetfv(bin, tri->p1) < 0){ free(tri); werrstr("Bgetfv: %r"); goto error; } if(Bgetfv(bin, tri->p2) < 0){ free(tri); werrstr("Bgetfv: %r"); goto error; } if(Bgets(bin, &tri->attrlen) < 0){ free(tri); werrstr("Bgets: %r"); goto error; } tri = realloc(tri, sizeof(Stltri) + tri->attrlen); if(tri == nil){ werrstr("realloc: %r"); goto error; } if(Bread(bin, tri->attrs, tri->attrlen) != tri->attrlen){ free(tri); werrstr("Bread: %r"); goto error; } stl->tris = realloc(stl->tris, (stl->ntris+1)*sizeof(*stl->tris)); if(stl->tris == nil){ werrstr("realloc: %r"); goto error; } stl->tris[stl->ntris++] = tri; } Bterm(bin); return stl; error: Bterm(bin); freestl(stl); return nil; } void freestl(Stl *stl) { int i; if(stl == nil) return; for(i = 0; i < stl->ntris; i++) free(stl->tris[i]); free(stl->tris); free(stl); }