#include #include #include #ifdef __sgi #include #endif #include "st2.h" #define RED(h,x,y) (h.data[(y)*(h.cols*4) + (x)*4 + 0]) #define GREEN(h,x,y) (h.data[(y)*(h.cols*4) + (x)*4 + 1]) #define BLUE(h,x,y) (h.data[(y)*(h.cols*4) + (x)*4 + 2]) #define ALPHA(h,x,y) (h.data[(y)*(h.cols*4) + (x)*4 + 3]) #define LUMINANCE(h,x,y) (.3086*(RED(h,x,y)) + .6094*(GREEN(h,x,y)) + .0820*(BLUE(h,x,y))) fb frameBuffer[NUM_FRAMEBUFFERS]; void st2_error(const char *str, ...) { va_list args; va_start(args,str); fprintf (stderr,"COS ST2 error: "); vfprintf(stderr,str,args); printf ("\n"); va_end(args); exit(-1); } void *st2_malloc(int bytes) { void *new = calloc(1,bytes); if (!new) st2_error("Out of memory in st2_malloc"); return new; } #define st2_free(p) \ { \ if ((p)==NULL) st2_error("Attempted to free a NULL pointer.");\ free(p);\ p = NULL; \ } void colorSet(Color *c, unsigned char r, unsigned char g, unsigned char b) { if (!c) st2_error("NULL Color pointer passed to colorSet."); R(c) = r; G(c) = g; B(c) = b; A(c) = 0; } void colorSetA(Color *c, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { if (!c) st2_error("NULL Color pointer passed to colorSetA."); R(c) = r; G(c) = g; B(c) = b; A(c) = a; } void colorGray(Color *c, Color *g) { unsigned char lum = .3086*R(c) + .6094*G(c) + .0820*B(c); R(g) = G(g) = B(g) = lum; } static int fb_call_has_been_made = 0; static void fb_firsttime(void) { int i; if (!fb_call_has_been_made) { fb_call_has_been_made = 1; for (i=0;i= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbIsInitialized: %d",fbHandle); return frameBuffer[fbHandle].initialized; } int fbRows(int fbHandle) { fb_firsttime(); if (fbHandle < 0 || fbHandle >= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbRows: %d",fbHandle); if (!frameBuffer[fbHandle].initialized) st2_error("uninitialized framebuffer referenced in fbRows: %d",fbHandle); return frameBuffer[fbHandle].rows; } int fbCols(int fbHandle) { fb_firsttime(); if (fbHandle < 0 || fbHandle >= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbCols: %d",fbHandle); if (!frameBuffer[fbHandle].initialized) st2_error("uninitialized framebuffer referenced in fbRows: %d",fbHandle); return frameBuffer[fbHandle].cols; } int fbInit(int fbWidth, int fbHeight) { static int fbIndex = 0; fb_firsttime(); if (fbIndex >= NUM_FRAMEBUFFERS) st2_error("Too many framebuffers allocated."); if (fbWidth < 0) st2_error("Negative width in fbInit."); if (fbHeight < 0) st2_error("Negative height in fbInit."); frameBuffer[fbIndex].initialized = 1; frameBuffer[fbIndex].rows = fbHeight; frameBuffer[fbIndex].cols = fbWidth; frameBuffer[fbIndex].data = st2_malloc(fbHeight*fbWidth*4); return fbIndex++; } void fbFree(int fbHandle) { fb_firsttime(); if (!frameBuffer[fbHandle].initialized) st2_error("Attempt to free a non-initialized framebuffer: %d",fbHandle); frameBuffer[fbHandle].initialized = 0; frameBuffer[fbHandle].rows = 0; frameBuffer[fbHandle].cols = 0; st2_free(frameBuffer[fbHandle].data); } void fbPutColor(int fbHandle, int x, int y, Color *c) { fb_firsttime(); if (fbHandle < 0 || fbHandle >= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbPutColor: %d",fbHandle); if (!frameBuffer[fbHandle].initialized) st2_error("Attempt to write to a non-initialized framebuffer: %d",fbHandle); if (x < 0) st2_error("negative x value in fbPutColor."); if (y < 0) st2_error("negative y value in fbPutColor."); if (x >= frameBuffer[fbHandle].cols) st2_error("x value too large in fbPutColor."); if (y >= frameBuffer[fbHandle].rows) st2_error("y value too large in fbPutColor."); if (!c) st2_error("NULL Color pointer in fbPutColor."); RED(frameBuffer[fbHandle],x,y) = R(c); GREEN(frameBuffer[fbHandle],x,y) = G(c); BLUE(frameBuffer[fbHandle],x,y) = B(c); ALPHA(frameBuffer[fbHandle],x,y) = A(c); } void fbGetColor(int fbHandle, int x, int y, Color *c) { fb_firsttime(); if (fbHandle < 0 || fbHandle >= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbGetColor: %d",fbHandle); if (!frameBuffer[fbHandle].initialized) st2_error("Attempt to read from a non-initialized framebuffer: %d",fbHandle); if (x < 0) st2_error("negative x value in fbGetColor."); if (y < 0) st2_error("negative y value in fbGetColor."); if (x >= frameBuffer[fbHandle].cols) st2_error("x value too large in fbGetColor."); if (y >= frameBuffer[fbHandle].rows) st2_error("y value too large in fbGetColor."); if (!c) st2_error("NULL Color pointer in fbGetColor."); R(c) = RED(frameBuffer[fbHandle],x,y); G(c) = GREEN(frameBuffer[fbHandle],x,y); B(c) = BLUE(frameBuffer[fbHandle],x,y); A(c) = ALPHA(frameBuffer[fbHandle],x,y); } void fbWrite(int fbHandle, char *filename) { FILE *fp; int i,j; fb_firsttime(); if (fbHandle < 0 || fbHandle >= NUM_FRAMEBUFFERS) st2_error("Bogus fbHandle in fbWrite: %d",fbHandle); if (!frameBuffer[fbHandle].initialized) st2_error("Attempt to read from a non-initialized framebuffer: %d",fbHandle); if ((fp = fopen(filename,"wb"))==NULL) st2_error("Can't open image file %s for writing in binary mode.",filename); fprintf(fp,"P6\n%d %d\n255\n",frameBuffer[fbHandle].cols,frameBuffer[fbHandle].rows); for (i=frameBuffer[fbHandle].rows-1;i>=0;i--) { for (j=0;j= NUM_FRAMEBUFFERS) st2_error("Bogus destination fbHandle in fbCopy: %d",fbHandleDest); if (fbHandleSrc < 0 || fbHandleSrc >= NUM_FRAMEBUFFERS) st2_error("Bogus source fbHandle in fbCopy: %d",fbHandleSrc); if (!frameBuffer[fbHandleSrc].initialized) st2_error("Attempt to copy from a non-initialized framebuffer: %d",fbHandleSrc); if (frameBuffer[fbHandleDest].initialized) fbFree(fbHandleDest); frameBuffer[fbHandleDest].cols=frameBuffer[fbHandleSrc].cols; frameBuffer[fbHandleDest].rows=frameBuffer[fbHandleSrc].rows; frameBuffer[fbHandleDest].data = st2_malloc(frameBuffer[fbHandleDest].rows*frameBuffer[fbHandleDest].cols*4); memcpy(frameBuffer[fbHandleDest].data, frameBuffer[fbHandleSrc].data, frameBuffer[fbHandleSrc].rows*frameBuffer[fbHandleSrc].cols*4); } #ifdef __sgi static void DSOerror(void) { char *str = dlerror(); if (str) st2_error (str); } #endif DSO dsoOpen(char *filename) { #ifdef __sgi DSO d = dlopen(filename,RTLD_LAZY); DSOerror(); return d; #else st2_error("DSO functions only supported on SGI machines."); return NULL; /* Not reached */ #endif } void *dsoGetSymbol(DSO d, char *symbolName) { #ifdef __sgi void *ret = dlsym(d,symbolName); DSOerror(); return ret; #else st2_error("DSO functions only supported on SGI machines."); return NULL; /* Not reached */ #endif } void dsoClose(DSO d) { #ifdef __sgi dlclose(d); DSOerror(); #else st2_error("DSO functions only supported on SGI machines."); #endif }