Trouble with Iris IMG library

Paul Breslin pbreslin at dragon.tmc.edu
Wed Mar 21 00:27:07 AEST 1990


>...
>    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 <stdio.h>
#include <gl.h>
#include <device.h>
#include <gl/image.h>

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 <quickpaint_file>\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;
}



More information about the Comp.sys.sgi mailing list