[comp.graphics] Reading TARGA 24 bit per pixel image files

paul@sgi.SGI.COM (Paul Haeberli) (01/30/88)

/* 
 *	fromtarga - 
 *		Convert from a type 2 ( RGB ) targa image into an IRIS 
 *	image.  Most targa images are displayed directly on monitors 
 *	with no gamma correction.  The typical gamma is about 2.2, so 
 *	you gotta gammawarp the output image by 2.2 to get it into a
 *	linear intensity space.
 *
 *	 	    		Paul Haeberli - 1988
 */
#include "image.h"
#include "stdio.h"

main(argc,argv)
int argc;
char **argv;
{
    if(argc<3) {
	fprintf(stderr,"usage fromtarga targa.img image.rgb\n");
	exit(1);
    }
    fromtarga(argv[1],argv[2]);
}

typedef struct TARGA {
	unsigned char numid;	
	unsigned char maptyp;
	unsigned char imgtyp;	
	short maporig;
	short mapsize;
	unsigned char mapbits;
	short xorig;
	short yorig;
	short xsize;
	short ysize;
	unsigned char pixsize;
	unsigned char imgdes;
} TARGA;

#define MAXIWIDTH	8192

short rbuf[MAXIWIDTH];
short gbuf[MAXIWIDTH];
short bbuf[MAXIWIDTH];

fromtarga(tname,iname)
char *tname, *iname;
{
    int xsize, ysize, zsize;
    int y;
    FILE *inf;
    IMAGE *image;
    TARGA t;

    inf = fopen(tname,"r");
    if(!inf) {
	fprintf(stderr,"totarga: can't open input file %s\n",tname);
	exit(1);
    }
    t.numid = inchar(inf);
    t.maptyp = inchar(inf);
    t.imgtyp = inchar(inf);
    if(t.imgtyp != 2) {
	fprintf(stderr,"totarga: this only works on type 2 images %s\n",tname);
	exit(1);
    }
    t.maporig = inshort(inf);
    t.mapsize = inshort(inf);
    t.mapbits = inchar(inf);
    t.xorig = inshort(inf);
    t.yorig = inshort(inf);
    t.xsize = inshort(inf);
    t.ysize = inshort(inf);
    t.pixsize = inchar(inf);
    t.imgdes = inshort(inf);
    xsize = t.xsize;
    ysize = t.ysize;
    for(y=0; y<t.numid; y++)
	inchar(inf);
    for(y=0; y<t.mapsize; y++) {
	if(t.mapbits == 24) {
	    inchar(inf);
	    inchar(inf);
	    inchar(inf);
	} else if(t.mapbits == 32) {
	    inchar(inf);
	    inchar(inf);
	    inchar(inf);
	    inchar(inf);
	}
    }
    image = iopen(iname,"w",RLE(1),3,xsize,ysize,3);
    if(!image) {
	fprintf(stderr,"totarga: can't open input file %s\n",iname);
	exit(1);
    }
    for(y=0; y<ysize; y++) {
	gettargarow(inf,rbuf,gbuf,bbuf,xsize);
	putrow(image,rbuf,y,0);
	putrow(image,gbuf,y,1);
	putrow(image,bbuf,y,2);
    }
    fclose(inf);
    iclose(image);
}

inchar(inf)
FILE *inf;
{
    return fgetc(inf);
}

inshort(inf)
FILE *inf;
{
    short s;
    int onechar;

    onechar = fgetc(inf)&0xff;
    s = onechar;
    onechar = fgetc(inf)&0xff;
    s |= (onechar&0xff)<<8;
    return s;
}

gettargarow(inf,r,g,b,n,pixsize)
register FILE *inf;
register short *r, *g, *b;
register int n, pixsize;
{
    while(n--) {
	*g = fgetc(inf);
	*r = fgetc(inf);
	fgetc(inf);
	*b = fgetc(inf);
	*r &= 0xff;
	*g &= 0xff;
	*b &= 0xff;
	b++;
	g++;
	r++;
    }
}

printheader(t)
TARGA *t;
{
    fprintf(stderr,"numid %d\n",t->numid);
    fprintf(stderr,"maptype %d\n",t->maptyp);
    fprintf(stderr,"imgtyp %d\n",t->imgtyp);
    fprintf(stderr,"maporig %d mapsize %d \n",t->maporig,t->mapsize);
    fprintf(stderr,"mapbits %d\n",t->mapbits);
    fprintf(stderr,"xorig yorig %d %d\n",t->xorig,t->xorig);
    fprintf(stderr,"xsize ysize %d %d \n",t->xsize,t->ysize);
    fprintf(stderr,"pixsize %d\n",t->pixsize);
    fprintf(stderr,"imgdes %d\n",t->imgdes);
}