/* Copyright (C) 2000-2007 by George Williams */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "gimage.h" #include struct sgiheader { short magic; char format; char bpc; unsigned short dim; unsigned short width; unsigned short height; unsigned short chans; long pixmin; long pixmax; char dummy[4]; char imagename[80]; long colormap; char pad[404]; }; #define SGI_MAGIC 474 #define VERBATIM 0 #define RLE 1 static long getlong(FILE *fp) { int ch1, ch2, ch3, ch4; ch1 = fgetc(fp); ch2 = fgetc(fp); ch3=fgetc(fp); ch4=fgetc(fp); return( (ch1<<24) | (ch2<<16) | (ch3<<8) | ch4 ); } static int getshort(FILE *fp) { int ch1, ch2; ch1 = fgetc(fp); ch2 = fgetc(fp); return( (ch1<<8) | ch2); } static void getsgiheader(struct sgiheader *head, FILE *fp) { head->magic = getshort(fp); head->format = getc(fp); head->bpc = getc(fp); head->dim = getshort(fp); head->width = getshort(fp); head->height = getshort(fp); head->chans = getshort(fp); head->pixmin = getlong(fp); head->pixmax = getlong(fp); fread(head->dummy,sizeof(head->dummy),1,fp); fread(head->imagename,sizeof(head->imagename),1,fp); head->colormap = getlong(fp); fread(head->pad,sizeof(head->pad),1,fp); } static void readlongtab(FILE *fp,unsigned long *tab,int tablen) { int i; for ( i=0; ibpc==1?fgetc:getshort; int ch,i,cnt,val; unsigned char *pt; for ( i=0; iwidth); fseek(fp,starttab[cur],0); while (1) { ch = getthingamy(fp); if (( cnt = (ch&0x7f))==0 ) return; if ( ch&0x80 ) { while ( --cnt>=0 ) *pt++ = getthingamy(fp)*255L/header->pixmax; } else { val = getthingamy(fp)*255L/header->pixmax; while ( --cnt>= 0 ) *pt++ = val; } } } static void freeptrtab(unsigned char **ptrtab,int tot) { int i,j; for ( i=0; i3 || header.pixmax>65535 || (header.pixmax>255 && header.bpc==1) || (header.chans!=1 && header.chans!=3 && header.chans!=4) || header.pixmax<0 || header.pixmin<0 || header.pixmin>header.pixmax || header.colormap != 0 ) { fclose(fp); return( NULL ); } ret = GImageCreate(header.dim==3?it_true:it_index,header.width,header.height); base = ret->u.image; if ( header.format==RLE ) { unsigned long *starttab/*, *lengthtab*/; unsigned char **ptrtab; long tablen; tablen = header.height*header.chans; starttab = (unsigned long *)galloc(tablen*sizeof(long)); /*lengthtab = (unsigned long *)galloc(tablen*sizeof(long));*/ ptrtab = (unsigned char **)galloc(tablen*sizeof(unsigned char *)); readlongtab(fp,starttab,tablen); /*readlongtab(fp,lengthtab,tablen);*/ for ( i=0; idata + (header.height-1-i)*base->bytes_per_line,ptrtab[i],header.width); } else { unsigned long *ipt; for ( i=0; idata + (header.height-1-i)*base->bytes_per_line); for ( j=0; jdata + (header.height-1-i)*base->bytes_per_line,header.width,1,fp); if ( header.pixmax!=255 ) { pt = (unsigned char *) (base->data+(header.height-1-i)*base->bytes_per_line); for ( end=pt+header.width; ptdata + (header.height-1-i)*base->bytes_per_line); for ( end=pt+header.width; ptdata + (header.height-1-i)*base->bytes_per_line); rpt = r; gpt = g; bpt = b; for ( iend=ipt+header.width; iptdata + (header.height-1-i)*base->bytes_per_line); rpt = r; gpt = g; bpt = b; for ( iend=ipt+header.width; ipt