草案版本0.97SGI图像文件格式保罗·海伯里paul@sgi.com硅图形计算机系统这是描述SGI图像文件格式的最终文档。这个是一个低级规范,描述SGI映像的实际字节级格式文件夹。在SGI机器上,读取和写入SGI图像的首选方式文件将使用图像库-limage。此库提供了一组的函数,使其易于读取和写入SGI图像。如果你是在SGI工作站上,您可以通过执行以下操作来获取有关环境的信息:%男4 rgb关于SGI图像文件中值的字节顺序的注释在以下描述中,使用类似位[7..0]的符号表示二进制值中的位范围。位0是中的最低顺序位值。所有短值都用2个字节表示。第一个字节存储值的高阶8位:位[15..8]。第二个字节存储值的低位8位:位[7..0]。因此,此函数将从文件中读取一个短值:无符号短getshort(inf)文件*inf;{无符号字符buf[2];弗雷德(buf,2,1,inf);返回(buf[0]<<8)+(buf[1]<<0);}所有长值都由4个字节表示。第一个字节存储值的高阶8位:位[31..24]。第二个字节存储位[23..16]。第三个字节存储位[15..8]。第四个字节存储值的低位8位:位[7..0]。因此,此函数将从文件中读取一个长值:静态long getlong(inf)文件*inf;{无符号字符buf[4];弗雷德(buf,4,1,inf);return(buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);}SGI图像文件的一般结构如下所示:标题指示图像是否为游程编码(RLE)。如果图像未进行游程编码,则结构如下:标题图像数据如果图像是游程编码的,则结构如下:标题偏移量表图像数据标题标题由以下部分组成:尺寸|类型|名称|说明2字节|短| MAGIC|IRIS图像文件幻数1字节|字符|存储|存储格式1字节|字符| BPC |每个像素通道的字节数2字节|ushort|DIMENSION|维度数2字节|ushort|XSIZE|X大小(像素)2字节|ushort|YSIZE|Y大小(像素)2字节|ushort|ZSIZE|通道数4字节|长| PIXMIN |最小像素值4字节|长| PIXMAX |最大像素值4字节|字符|虚拟|忽略80字节|字符| IMAGENAME |图像名称4字节|长|颜色映射|颜色映射ID404字节|字符|虚拟|忽略以下是图像文件标题中每个字段的描述:魔法-这是保存为短的十进制值474。这个将文件标识为SGI图像文件。STORAGE-指定是否使用run存储图像长度编码(RLE)或非长度编码(VERBATIM)。如果使用RLE,则值这个字节的值为1。否则,该字节的值将为0。此字段只允许0或1值。BPC-描述用于存储每个图像的通道。这是每像素的字节数组件。大多数SGI图像文件使用1字节/像素分量,给出256个级别。一些SGI图像文件使用每个组件2个字节。此字段的唯一允许值是1或2。DIMENSION-描述存储数据中的维度数在图像文件中。唯一允许的值是1、2或3。如果该值为1,图像文件仅由1个通道和只有一条扫描线(行)。扫描线的长度由下面的XSIZE值。如果该值为2,则文件由具有多条扫描线的单通道。宽度和高度图像的大小由下面的XSIZE和YSIZE值给出。如果该值为3,则文件由多个通道组成。图像的宽度和高度由以下值给出下面的XSIZE和YSIZE。通道数由ZSIZE的值如下。XSIZE-以像素为单位的图像宽度YSIZE-图像的高度(像素)ZSIZE—图像中的通道数。黑白(灰度)图像用ZSIZE或1存储为二维图像。RGB颜色图像存储为ZSIZE为3的三维图像。一个RGB具有ALPHA通道的图像被存储为具有ZSIZE为4。SGI映像中没有固有的限制文件格式,这将阻止创建包含更多内容的图像文件超过4个通道。PINMIN-图像中的最小像素值。的价值如果没有像素的值小于0,则可以使用0。PINMAX-图像中的最大像素值。的价值如果没有像素的值大于255,则可以使用255。这是被视为全亮度的值图像。假人-这4个字节的数据应设置为0。IMAGENAME-最多79个字符的以空结尾的ascii字符串此处可以包括以null结尾的。这并不常见已使用。COLORMAP-此选项控制文件中的像素值应如何解释。它可以有以下四个值之一:0:正常-通道中的数据代表B/W值对于具有1个通道的图像,RGB值对于具有3个通道,以及具有4个通道的图像的RGBA值。几乎所有的SGI图像文件都是这种类型的。1:无相干-图像将只有1个通道的数据。对于每个像素,RGB数据被压缩为一个8位值。3位用于红色和绿色,而蓝色使用2位。红色数据以位[2..0]表示,绿色数据以位[5..3]表示,和蓝色数据位[7..6]。此格式已过时。2:屏幕-图像只有一个数据通道。此格式用于存储颜色相关的像素。要将像素值转换为RGB值,请使用颜色贴图必须使用。适当的颜色映射不同于图像到图像。此格式已过时。3:COLORMAP-图像用于存储来自SGI机器。在这种情况下,图像不可显示在传统意义上。DUMMY-这个404字节的数据应该设置为0。这使得标头正好512字节。图像数据(如果不是RLE)如果图像是逐字存储的(没有RLE),则直接存储图像数据遵循512字节的标头。第一个扫描行的数据首先写入通道。如果图像有多个通道,则所有写入第一个通道的数据,然后写入其余通道的数据频道。如果BPC值为1,则每条扫描线都写为XSIZE字节。如果BPC值为2,则每条扫描线都写为XSIZE短裤。这些短路按上述字节顺序存储。偏移表(如果是RLE)如果使用行程编码存储图像,则偏移量表遵循描述文件偏移量的标题每个扫描线的RLE。此信息仅适用于以下情况对于上述存储,为1。尺寸|类型|名称|说明tablen longs|long|STARTTAB|起始表格tablen longs|long|LENGTHTAB|长度表RLE数据的每条扫描线都需要每个表中的一个条目。这个图像(表格)中扫描线的总数由YSIZE和ZSIZE的产品。有两张长桌子已写入。每一个都由一长串数据组成。第一个表中每个扫描线的RLE数据的文件偏移量图像。在具有多个通道(ZSIZE>1)的文件中,此表首先显示在第一个通道中包含扫描线的所有偏移,然后是是第二个通道中扫描线的偏移量等。第二个表具有图像中每个扫描线的RLE数据长度。在一个具有多个通道的文件(ZSIZE>1)此表首先具有所有第一个通道中扫描线的RLE数据长度是第二通道中扫描线的RLE数据长度等。查找文件偏移量和RLE数据中的字节数对于特定的扫描线,这两个数组可以作为跟随:阅读表格:无符号长*starttab,*lengthtab;tablen=YSIZE*ZSIZE*sizeof(长);starttab=(无符号长*)mymalloc(表n);lengthtab=(unsigned long*)mymalloc(tablen);fseek(inf,512,SEEK_SET);readlongtab(inf,starttab);readlongtab(ing,lengthtab);要查找扫描线的文件偏移量和RLE数据长度,请执行以下操作:rowno是0到YSIZE-1范围内的整数channo是0到ZSIZE-1范围内的整数rlewoffset=起始选项卡[rowno+channo*YSIZE]rlelength=长度tab[rowno+channo*YSIZE]两个相同的行(扫描线)可以共享压缩的数据。完全白色的图像可以作为单个压缩文件写入行并使所有表条目都指向该行。又是一个小黑客如果您正在编写一个RGB RLE文件,并且特定扫描线是非彩色的(灰度),您可以将r、 g行和b行指向相同的数据!!图像数据(如果是RLE)此信息仅适用于上述STORAGE值为1的情况。如果图像使用游程编码存储,图像数据如下上面的偏移表。RLE数据没有任何特定的顺序。上面的偏移表用于定位任何扫描线的rle数据。RLE数据必须从文件中读入并扩展为像素数据的格式如下:如果BPC为1,则每个像素有一个字节。在这种情况下RLE数据应读入字符数组。要展开数据,第一个字节的低位七位:位[6..0]用于形成计数。如果第一个的高位字节为1:bit[7],然后使用计数指定数量要从RLE数据缓冲区复制到目标的字节。否则,如果第一个字节的高位是0:bit[7],然后使用计数指定重复目标中以下字节的值。这个过程继续,直到找到计数0。这应该会解压缩精确到XSIZE像素。以下是解压缩扫描线的示例代码:expandrow(optr、iptr、z)无符号字符*optr,*iptr;整数z;{无符号字符像素,计数;optr+=z;而(1){像素=*iptr++;if(!(计数=(像素&0x7f))回报;if(像素&0x80){while(计数--){*optr=*iptr++;optr+=4;}}其他{像素=*iptr++;while(计数--){*optr=像素;optr+=4;}}}}如果BPC为2,则每个像素有一个短(2字节)。在这个如果RLE数据应读入短路数组。收件人展开数据,第一个短的低位七位:位[6..0]用于形成计数。如果第一个短的位[7]是1,则计数用于指定从RLE复制多少条短裤数据缓冲区到目标。否则,如果第一个short为0,则计数用于指定在目的地重复以下short的值。这个进程继续进行,直到找到计数0。这应该会减压精确XSIZE像素。注意,中短数据的字节顺序应该使用如上所述的输入文件。实施说明RLE和VERBATIM格式的图像实现由于大多数SGI图像都位于这种格式。鼓励支持带有2个BPC的图像。如果图像的ZSIZE为1,则假定它表示B/W值。如果ZSIZE为3,则假定它表示RGB数据,如果ZSIZE为4,则假定它包含带alpha的RGB数据。所有SGI图像的原点位于左下角。这个第一条扫描线(第0行)总是图像的最下面一行。命名约定在SGI系统上,如果它们是黑白图像,如果包含rgb图像,则以.rgb结尾如果它们是带有alpha通道的RGB图像,则以.rgba结尾。有时也使用.sgi扩展名。一个例子此程序将写出有效的B/W SGI图像文件:#包括“stdio.h”#定义IXSIZE(23)#定义IYSIZE(15)putbyte(输出,val)文件*输出;无符号字符值;{无符号字符buf[1];buf[0]=val;fwrite(buf,1,1,输出);}putshort(输出,val)文件*输出;无符号短val;{无符号字符buf[2];buf[0]=(val>>8);buf[1]=(val>>0);fwrite(buf,2,1,输出);}静态int putlong(out,val)文件*输出;无符号长val;{无符号字符buf[4];buf[0]=(val>>24);buf[1]=(val>>16);buf[2]=(val>>8);buf[3]=(val>>0);返回fwrite(buf,4,1,out);}main(){文件*,共个;字符名称[80];无符号字符outbuf[IXSIZE];整数i,x,y;of=fopen(“example.rgb”,“w”);如果(第个,共个){fprintf(stderr,“sgiimage:无法打开输出文件”);出口(1);}putshort(共474个);/*魔法*/putbyte(共,0);/*存储是口头的*/putbyte(第个,共个);/*BPC为1*/putshort(第个,共2个);/*尺寸为2*/putshort(的,IXSIZE);/*XSIZE公司*/putshort(of,IYSIZE);/*YSIZE公司*/putshort(第个,共个);/*ZSIZE公司*/putlong(共,0);/*PIXMIN为0*/putlong(第255页);/*PIXMAX为255*/对于(i=0;i<4;i++)/*虚拟4字节*/putbyte(of,0);strcpy(iname,“没有名字”);fwrite(名称,80,1,共);/*IMAGENAME(图像名称)*/putlong(共,0);/*COLORMAP为0*/对于(i=0;i<404;i++)/*DUMMY 404字节*/putbyte(of,0);对于(y=0;y-->