[comp.sys.sgi] Reading IRIS image files into an array of longs.

paul@manray.sgi.com (Paul Haeberli) (03/12/90)

Ever wonder how to read an IRIS image file into an array of
longs so you can lrectwriteit to the screen?  Here's a short
piece of code that should help you out . . .


/*
 *	rectimg - 
 *		Display a color or black and white image on the iris.  Simple
 *	version for demo use.  This will only work on machines that support
 *	RGB mode.
 *	  		   	Paul Haeberli - 1988
 *
 *	To compile this:
 *
 *		cc rectimg.c -o rectimg -limage -lgl_s
 */
#include "gl.h"
#include "device.h"
#include "gl/image.h"

unsigned long *longimagedata();

IMAGE *image;
int xsize, ysize, zsize;
unsigned long *lptr;

main(argc,argv)
int argc;
char **argv;
{
    short val;

    if( argc<2 ) {
	printf("usage: rectimg inimage\n");
	exit(1);
    } 
    sizeofimage(argv[1],&xsize,&ysize);
    if( xsize > (XMAXSCREEN+1) || ysize > (YMAXSCREEN+1)) {
	printf("rectimg: input image is too big %d %d",xsize,ysize);
	exit(1);
    }
    prefsize(xsize,ysize);
    winopen("rectimg");
    RGBmode();
    gconfig();
    lptr = (unsigned long *)longimagedata(argv[1]);
    drawit();
    while(1) {
	if(qread(&val) == REDRAW)
    	    drawit();
    }
}

drawit()
{
    reshapeviewport();
    lrectwrite(0,0,xsize-1,ysize-1,lptr);
}

/* 
 *	Image library support . . . 
 *
 */
sizeofimage(name, xsize, ysize)
char *name;
int *xsize, *ysize;
{
    IMAGE *image;

    image = iopen(name,"r");
    if(!image) {
	fprintf(stderr,"sizeofimage: can't open image file %s\n",name);
	exit(1);
    }
    *xsize = image->xsize;
    *ysize = image->ysize;
    iclose(image);
}

unsigned long *longimagedata(name)
char *name;
{
    unsigned long *base, *lptr;
    short *rbuf, *gbuf, *bbuf, *abuf;
    IMAGE *image;
    int y;

    image = iopen(name,"r");
    if(!image) {
	fprintf(stderr,"longimagedata: can't open image file %s\n",name);
	exit(1);
    }
    base = (unsigned long *)malloc(image->xsize*image->ysize*sizeof(unsigned long));
    rbuf = (short *)malloc(image->xsize*sizeof(short));
    gbuf = (short *)malloc(image->xsize*sizeof(short));
    bbuf = (short *)malloc(image->xsize*sizeof(short));
    abuf = (short *)malloc(image->xsize*sizeof(short));
    if(!base || !rbuf || !gbuf || !bbuf) {
	fprintf(stderr,"longimagedata: can't malloc enough memory\n");
	exit(1);
    }
    lptr = base;
    for(y=0; y<image->ysize; y++) {
	if(image->zsize>=4) {
	    getrow(image,rbuf,y,0);
	    getrow(image,gbuf,y,1);
	    getrow(image,bbuf,y,2);
	    getrow(image,abuf,y,3);
	    rgbatocpack(rbuf,gbuf,bbuf,abuf,lptr,image->xsize);
	    lptr += image->xsize;
	} else if(image->zsize==3) {
	    getrow(image,rbuf,y,0);
	    getrow(image,gbuf,y,1);
	    getrow(image,bbuf,y,2);
	    rgbtocpack(rbuf,gbuf,bbuf,lptr,image->xsize);
	    lptr += image->xsize;
	} else {
	    getrow(image,rbuf,y,0);
	    bwtocpack(rbuf,lptr,image->xsize);
	    lptr += image->xsize;
	}
    }
    iclose(image);
    free(rbuf);
    free(gbuf);
    free(bbuf);
    free(abuf);
    return base;
}


bwtocpack(b,l,n)
register unsigned short *b;
register unsigned long *l;
register int n;
{
    while(n>=8) {
	l[0] = 0x00010101*b[0];
	l[1] = 0x00010101*b[1];
	l[2] = 0x00010101*b[2];
	l[3] = 0x00010101*b[3];
	l[4] = 0x00010101*b[4];
	l[5] = 0x00010101*b[5];
	l[6] = 0x00010101*b[6];
	l[7] = 0x00010101*b[7];
	l += 8;
	b += 8;
	n -= 8;
    }
    while(n--) 
	*l++ = 0x00010101*(*b++);
}

rgbtocpack(r,g,b,l,n)
register unsigned short *r, *g, *b;
register unsigned long *l;
register int n;
{
    while(n>=8) {
	l[0] = r[0] | (g[0]<<8) | (b[0]<<16);
	l[1] = r[1] | (g[1]<<8) | (b[1]<<16);
	l[2] = r[2] | (g[2]<<8) | (b[2]<<16);
	l[3] = r[3] | (g[3]<<8) | (b[3]<<16);
	l[4] = r[4] | (g[4]<<8) | (b[4]<<16);
	l[5] = r[5] | (g[5]<<8) | (b[5]<<16);
	l[6] = r[6] | (g[6]<<8) | (b[6]<<16);
	l[7] = r[7] | (g[7]<<8) | (b[7]<<16);
	l += 8;
	r += 8;
	g += 8;
	b += 8;
	n -= 8;
    }
    while(n--) 
        *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16);
}

rgbatocpack(r,g,b,a,l,n)
register unsigned short *r, *g, *b, *a;
register unsigned long *l;
register int n;
{
    while(n>=8) {
	l[0] = r[0] | (g[0]<<8) | (b[0]<<16) | (a[0]<<24);
	l[1] = r[1] | (g[1]<<8) | (b[1]<<16) | (a[1]<<24);
	l[2] = r[2] | (g[2]<<8) | (b[2]<<16) | (a[2]<<24);
	l[3] = r[3] | (g[3]<<8) | (b[3]<<16) | (a[3]<<24);
	l[4] = r[4] | (g[4]<<8) | (b[4]<<16) | (a[4]<<24);
	l[5] = r[5] | (g[5]<<8) | (b[5]<<16) | (a[5]<<24);
	l[6] = r[6] | (g[6]<<8) | (b[6]<<16) | (a[6]<<24);
	l[7] = r[7] | (g[7]<<8) | (b[7]<<16) | (a[7]<<24);
	l += 8;
	r += 8;
	g += 8;
	b += 8;
	a += 8;
	n -= 8;
    }
    while(n--) 
        *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16) | ((*a++)<<24);
}