Path: utzoo!attcan!telly!lethe!geac!alias!dragon!pbreslin From: pbreslin@dragon.tmc.edu (Paul Breslin) Newsgroups: comp.sys.sgi Subject: Re: Trouble with Iris IMG library Message-ID: <806@alias.UUCP> Date: 20 Mar 90 14:27:07 GMT References: <1990Mar19.043628.28976@jarvis.csri.toronto.edu> Sender: news@alias.UUCP Distribution: na Organization: Alias Research Inc., Toronto Canada Lines: 203 >... > Well, here we are several months later, but now I must convert >an Iris IMG file created with Alias's Quickpaint program to our native >RLE file format. ... The Iris image library is capable of storing four "types" of image files. These are (from image.h): CM_NORMAL, CM_DITHERED, CM_SCREEN, CM_COLORMAP. Some of the image tools in 4Dgifts prefer and/or assume CM_NORMAL type, which is the most common type (pixel values are channel intensities). Since QuickPaint operates in colormap mode, it stores images using type CM_SCREEN. Since QuickPaint also allows you to modify the colormap, it saves a secondary file (.M) containing the colormap used to create the image. This .M file is of type CM_COLORMAP. If one of these doesn't exist you usually assume the default NeWS colormap should be used. So, say you wanted to convert a QuickPaint image to RGB format. You should first read in the colormap file. It should be 4 by 256. The X dimension contains the colormap index, R, G, and B. Then to read the image itself, you read in the CM_SCREEN type image whose pixel values represent colormap indices and map them to RGB values using the colormap from above. Here's a program I just created to read in a quickpaint file, convert it to RGB and blast it into a window using lrectwrite. It was created with 4 space tabs and compiled with the command: cc -O qp.c -lgutil -limage -lgl_s -lm -lc_s It's rather sparse on diagnostics. If you turn this into a real tool then please add more of these. It was also whipped together somewhat quickly so I apologize in advance for any errors. I've only tested it on the images in /usr/demos/quickpaint. Also note that the SGI image library has a nasty habit of calling exit. A hack was added to it to trap errors by calling "i_seterror" with an error handling function pointer. I would suggest using this. Locally we've modified the library to be slightly improved in this area. cheers, Paul Breslin Alias Research Inc. -------------------------------------------------------------------- #include #include #include #include typedef struct { unsigned char a, b, g, r; } RGBA; static RGBA *ColorMap; static RGBA *Image; static int Xres, Yres; static char ErrorMsg[256]; extern unsigned char red_map[256]; extern unsigned char green_map[256]; extern unsigned char blue_map[256]; static int LoadColorMap(char *filename) { register IMAGE *cmap; register RGBA *rgbp; register int y; register int index; short rowbuf[4]; char cmapname[512]; sprintf(cmapname, "%s.M", filename); if( !(cmap = iopen(cmapname, "r")) ) return 0; if( cmap->xsize != 4 ) { iclose(cmap); return 0; } rgbp = ColorMap = (RGBA *)malloc(cmap->ysize * sizeof(RGBA)); for( y = 0; y < cmap->ysize; y++ ) if( getrow(cmap, rowbuf, y, 0) >= 0 ) { index = rowbuf[0]; rgbp->r = rowbuf[1]; rgbp->g = rowbuf[2]; rgbp->b = rowbuf[3]; ++rgbp; } iclose(cmap); return 1; } static int LoadImage(char *filename) { register Colorindex *scanline; register RGBA *rgbp; register IMAGE *image; register int y; register int x; register int index; register int file_zsize; if( !(image = iopen(filename,"r")) ) return 0; file_zsize = image->zsize; Xres = image->xsize; Yres = image->ysize; if( file_zsize != 1 ) { sprintf(ErrorMsg, "\"%s\" is not a normal QP file", filename); iclose(image); return 0; } scanline = (Colorindex *)malloc(Xres * sizeof(Colorindex)); rgbp = Image = (RGBA *)malloc(Xres * Yres * sizeof(RGBA)); for( y = 0; y < Yres; ++y ) { if( getrow(image, scanline, y, 0) < 0 ) break; for( x = 0; x < Xres; ++x, ++rgbp ) { index = scanline[x]; if( !ColorMap ) { if( index < 256 ) { rgbp->r = red_map[index]; rgbp->g = green_map[index]; rgbp->b = blue_map[index]; } else { rgbp->r = 0; rgbp->g = 0; rgbp->b = 0; } } else *rgbp = ColorMap[index]; } } iclose(image); free((char *)scanline); return y == Yres; } int main(int argc, char **argv) { Device event; short value; long window; if( argc != 2 ) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } LoadColorMap(argv[1]); if( LoadImage(argv[1]) ) { prefposition(0, Xres - 1, 0, Yres - 1); noborder(); foreground(); if( (window = winopen("Hi")) <= 0 ) return 1; RGBmode(); gconfig(); qdevice(WINQUIT); qdevice(WINSHUT); qenter(REDRAW, window); while( event = qread(&value) ) { switch( event ) { case WINQUIT: case WINSHUT: break; case REDRAW: lrectwrite(0, 0, Xres - 1, Yres - 1, Image); continue; default: continue; } break; } } return 0; }