SGI图像文件格式

news/2024/12/4 20:13:37/

介绍

这是描述SGI图像文件格式的权威文档。这是一个低级规范,描述了 SGI 图像文件的实际字节级格式。在 SGI 机器上,读取和写入 SGI 图像文件的首选方法是使用图像库 -limage。此库提供了一组函数,使读取和写入 SGI 图像变得容易。如果您使用的是 SGI 工作站,您可以通过以下方式获取有关 -limage 的信息:

% man 4 rgb

关于 SGI 图像文件中值的字节顺序的说明

在下面的描述中,像 bits[7..0] 这样的表示法用于表示二进制值中的位范围。位 0 是值中的最低位。

所有短值均由 2 个字节表示。第一个字节存储高阶 8 位的值:bits[15..8]。第二个字节存储值的低阶 8 位:bits[7..0]。

因此,此函数将从文件中读取一个短值:

    unsigned short getshort(inf)FILE *inf;{unsigned char buf[2];fread(buf,2,1,inf);return (buf[0]<<8)+(buf[1]<<0);}

所有长值都由 4 个字节表示。第一个字节存储高阶 8 位的值:bits[31..24]。第二个字节存储位[23..16]。第三个字节存储位[15..8]。第四个字节存储值的低阶 8 位:bits[7..0]。

此函数将从文件中读取一个长值:

    static long getlong(inf)FILE *inf;{unsigned char buf[4];fread(buf,4,1,inf);return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);}

SGI 图像文件的一般结构

标头指示图像是否为运行长度编码 (RLE)。

如果图像未进行运行长度编码,则结构如下:

 	The HeaderThe Image Data

如果图像是运行长度编码的,则结构如下:

 	The HeaderThe Offset TablesThe Image Data

页眉

标头包含以下内容:

        Size  | Type   | Name      | Description   2 bytes | short  | MAGIC     | IRIS image file magic number1 byte  | char   | STORAGE   | Storage format1 byte  | char   | BPC       | Number of bytes per pixel channel 2 bytes | ushort | DIMENSION | Number of dimensions2 bytes | ushort | XSIZE     | X size in pixels 2 bytes | ushort | YSIZE     | Y size in pixels 2 bytes | ushort | ZSIZE     | Number of channels4 bytes | long   | PIXMIN    | Minimum pixel value4 bytes | long   | PIXMAX    | Maximum pixel value4 bytes | char   | DUMMY     | Ignored80 bytes | char   | IMAGENAME | Image name4 bytes | long   | COLORMAP  | Colormap ID404 bytes | char   | DUMMY     | Ignored

以下是图像文件头中每个字段的说明:

魔术 - 这是保存为短整型的十进制值 474。这会将文件标识为 SGI 映像文件。

存储 - 指定是否使用运行长度编码 (RLE) 或不使用 (逐字) 存储图像。如果使用 RLE,则此字节的值将为 1。否则,此字节的值将为 0。此字段唯一允许的值为 0 或 1。

BPC - 描述用于存储图像的每个通道的精度。这是每个像素分量的字节数。大多数 SGI 图像文件使用每像素 1 个字节的分量,给出 256 个级别。某些 SGI 映像文件每个组件使用 2 个字节。此字段唯一允许的值为 1 或 2。

维度 - 描述存储在图像文件中的数据中的维度数。唯一允许的值为 1、2 或 3。如果此值为 1,则图像文件仅包含 1 个通道和 1 条扫描线(行)。此扫描线的长度由下面的 XSIZE 值给出。如果此值为 2,则文件由具有多个扫描线的单个通道组成。图像的宽度和高度由下面的 XSIZE 和 YSIZE 值给出。如果此值为 3,则文件由多个通道组成。图像的宽度和高度由下面的 XSIZE 和 YSIZE 值给出。通道数由下面的 ZSIZE 值给出。

XSIZE - 图像的宽度(以像素为单位)

YSIZE - 图像的高度(以像素为单位)

ZSIZE - 图像中的通道数。黑白(灰度)图像存储为 ZSIZE 或 1 的二维图像。RGB 彩色图像存储为 ZSIZE 为 3 的三维图像。具有 ALPHA 通道的 RGB 图像存储为 ZSIZE 为 4 的三维图像。SGI图像文件格式并无固有限制,无法创建超过4个通道的图像文件。

PINMIN - 图像中的最小像素值。如果没有像素的值小于 0,则可以使用 0 的值。

PINMAX - 图像中的最大像素值。如果没有像素的值大于 255,则可以使用 255 的值。这是图像中被视为全亮度的值。

虚拟 - 这 4 个字节的数据应设置为 0。

图像名称 - 此处可能包含以空结尾的 ASCII 字符串,该字符串最多包含 79 个字符,以空结尾。这不常用。

颜色映射表 - 这控制应如何解释文件中的像素值。它可以具有以下四个值之一:

0:正常 - 通道中的数据表示具有 1 个通道的图像的黑白值、具有 3 个通道的图像的 RGB 值和具有 4 个通道的图像的 RGBA 值。几乎所有的SGI图像文件都是这种类型的。

1:抖动 - 图像将只有 1 个数据通道。对于每个像素,RGB 数据被打包到一个 8 位值中。3 位用于红色和绿色,而蓝色使用 2 位。红色数据以位[2..0]为单位,绿色数据以位[5..3]为单位,蓝色数据以位[7..6]为单位。此格式已过时。

2:屏幕 - 图像将只有 1 个数据通道。此格式用于存储颜色索引像素。要将像素值转换为 RGB 值,必须使用颜色图。适当的颜色映射因图像而异。此格式已过时。

3:颜色图 - 图像用于存储来自SGI机器的色彩映射。在这种情况下,图像在传统意义上不可显示。

虚拟 - 此 404 字节的数据应设置为 0。这使得标头正好为 512 字节。

图像数据(如果不是 RLE)

如果图像是逐字存储的(没有 RLE),则图像数据直接跟在 512 字节标头之后。首先写入第一个通道的每个扫描线的数据。如果映像具有 1 个以上的通道,则写入第一个通道的所有数据,然后写入其余通道。如果 BPC 值为 1,则每个扫描线都写入为 XSIZE 字节。如果 BPC 值为 2,则每条扫描线都写为 XSIZE 短裤。这些短裤按上述字节顺序存储。

偏移表(如果是 RLE)

如果使用运行长度编码存储图像,则偏移表跟在标题后面,该标头描述了每个扫描线的文件偏移量对 RLE 的偏移量。仅当上述存储的值为 1 时,此信息才适用。

         Size  | Type   | Name      | Description   tablen longs | long   | STARTTAB  | Start tabletablen longs | long   | LENGTHTAB | Length table

RLE 数据的每个扫描行都需要每个表中的一个条目。图像(表n)中的扫描线总数由YSIZE和ZSIZE的乘积决定。写了两个长头表。每个都由表长的数据组成。第一个表具有图像中每条扫描线的 RLE 数据的文件偏移量。在具有 1 个以上通道(ZSIZE > 1)的文件中,此表首先包含第一个通道中扫描线的所有偏移量,然后是第二个通道中扫描线的偏移量,依此类推。第二个表包含图像中每条扫描线的 RLE 数据长度。在具有 1 个以上通道(ZSIZE > 1)的文件中,此表首先包含第一个通道中扫描线的所有 RLE 数据长度,然后是第二个通道中扫描线的 RLE 数据长度,依此类推。

要查找文件偏移量以及特定扫描线的 RLE 数据中的字节数,可以按如下方式读取这两个数组并编制索引:

要在表格中阅读:

    unsigned long *starttab, *lengthtab;tablen = YSIZE*ZSIZE*sizeof(long);starttab = (unsigned long *)mymalloc(tablen);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 范围内的整数

    rleoffset = starttab[rowno+channo*YSIZE]rlelength = lengthtab[rowno+channo*YSIZE]

两个相同的行(扫描线)可以共享压缩数据。可以将完全白色的图像写入单个压缩行,并使所有表条目都指向该行。另一个应该有效的小技巧是,如果您正在写出RGB RLE文件,并且特定的扫描线是消色差的(灰度),则可以使r,g和b行指向相同的数据!

图像数据(如果是 RLE)

仅当上述存储的值为 1 时,此信息才适用。如果使用运行长度编码存储图像,则图像数据遵循上面的偏移表。RLE 数据不按任何特定顺序排列。上面的偏移表用于定位任何扫描线的 rle 数据。

必须按以下方式从文件中读入 RLE 数据并将其扩展为像素数据:

如果 BPC 为 1,则每个像素有一个字节。在这种情况下,应将 RLE 数据读入字符数组。为了扩展数据,第一个字节的低阶七位:bits[6..0]用于形成计数。如果第一个字节的高阶位为 1: bit[7],则计数用于指定要从 RLE 数据缓冲区复制到目标的字节数。否则,如果第一个字节的高阶位为 0: bit[7],则计数用于指定在目标中重复下一个字节的值的次数。此过程一直持续到找到计数 0。这应该完全解压缩 XSIZE 像素。

以下是解压缩扫描线的示例代码:

    expandrow(optr,iptr,z)unsigned char *optr, *iptr;int z;{unsigned char pixel, count;optr += z;while(1) {pixel = *iptr++;if ( !(count = (pixel & 0x7f)) )return;if(pixel & 0x80) {while(count--) *optr++ = *iptr++;} else {pixel = *iptr++;while(count--) *optr++ = pixel;}}}

如果 BPC 为 2,则每个像素有一个短(2 个字节)。在这种情况下,RLE 数据应读入短路数组。为了扩展数据,使用第一个短:bits[6..0]的低阶七位来形成计数。如果第一个短路的 bit[7] 为 1,则计数用于指定要从 RLE 数据缓冲区复制到目标的短路数。否则,如果第一个短裤的 bit[7] 为 0,则计数用于指定在目标中重复下一个短指令的值的次数。此过程将继续,直到找到计数 0。这应该完全解压缩 XSIZE 像素。请注意,应使用输入文件中短数据的字节顺序,如上所述。

实施说明

对于 BPC 为 1 的图像,需要同时实现 RLE 和 VERBATIM 格式,因为绝大多数 SGI 图像都是这种格式。鼓励支持具有 2 BPC 的图像。

如果图像的 ZSIZE 为 1,则假定它表示黑白值。如果 ZSIZE 为 3,则假定它表示 RGB 数据,如果 ZSIZE 为 4,则假定它包含带有 alpha 的 RGB 数据。

所有SGI图像的原点都是左下角。第一条扫描线(第 0 行)始终是图像的底行。

命名约定

在 SGI 系统上,如果 SGI 图像文件是黑白图像,则以扩展名 .bw 结尾,如果包含 RGB 图像数据,则以 .rgb 结尾,如果是带有 alpha 通道的 RGB 图像,则以 .rgba 结尾。

有时也会使用.sgi扩展名。

一个例子

此程序将写出有效的黑白SGI映像文件:

  #include "stdio.h"#define IXSIZE      (23)#define IYSIZE      (15)putbyte(outf,val)FILE *outf;unsigned char val;{unsigned char buf[1];buf[0] = val;fwrite(buf,1,1,outf);}putshort(outf,val)FILE *outf;unsigned short val;{unsigned char buf[2];buf[0] = (val>>8);buf[1] = (val>>0);fwrite(buf,2,1,outf);}static int putlong(outf,val)FILE *outf;unsigned long val;{unsigned char buf[4];buf[0] = (val>>24);buf[1] = (val>>16);buf[2] = (val>>8);buf[3] = (val>>0);return fwrite(buf,4,1,outf);}main(){FILE *of;char iname[80];unsigned char outbuf[IXSIZE];int i, x, y;of = fopen("example.rgb","w");if(!of) {fprintf(stderr,"sgiimage: can't open output file\n");exit(1);}putshort(of,474);       /* MAGIC               */putbyte(of,0);          /* STORAGE is VERBATIM */putbyte(of,1);          /* BPC is 1            */putshort(of,2);         /* DIMENSION is 2      */putshort(of,IXSIZE);    /* XSIZE               */putshort(of,IYSIZE);    /* YSIZE               */putshort(of,1);         /* ZSIZE               */putlong(of,0);          /* PIXMIN is 0         */putlong(of,255);        /* PIXMAX is 255       */for(i=0; i<4; i++)      /* DUMMY 4 bytes       */putbyte(of,0);strcpy(iname,"No Name");fwrite(iname,80,1,of);  /* IMAGENAME           */putlong(of,0);          /* COLORMAP is 0       */for(i=0; i<404; i++)    /* DUMMY 404 bytes     */putbyte(of,0);for(y=0; y<IYSIZE; y++) {for(x=0; x<IXSIZE; x++) outbuf[x] = (255*x)/(IXSIZE-1);fwrite(outbuf,IXSIZE,1,of);}fclose(of);}
  

http://www.ppmy.cn/news/867421.html

相关文章

Windows上python读取grib2文件(不用Linux)

最近在网上下载的NCEP的fnl数据&#xff0c;发现只有grib2文件格式。因为现在处理数据使用的更多的是python&#xff0c;matlab一类的。网上一搜python读取grib文件需要依赖pygrib库&#xff0c;pygrib是欧洲中期天气预报中心(ECMWF)的GRIG API C库的Python接口&#xff0c;通过…

GLB模型压缩

模型压缩一般有两种路线&#xff0c;一个是减小网格体的顶点和面数&#xff0c;一个是减小纹理材质的贴图 本文将会使用https://github.com/CesiumGS/gltf-pipeline提供的工具进行GLTF模型的压缩。按照官网的步骤安装即可&#xff08;一定要有Nodejs&#xff09; 官网有常用命…

lightGBM文件保存

1.使用lightGBM原生的接口保存为txt文件 # 模型训练 gbm lgb.train(params, lgb_train, num_boost_round20, valid_setslgb_eval, early_stopping_rounds5) # 模型保存 gbm.save_model(model.txt) # 模型加载 gbm lgb.Booster(model_filemodel.txt) # 模型预测 y_pred gbm.…

grib1文件解析 python_grib文件解析

一、grib文件简介 WMO是世界气象组织&#xff0c;world meteorology organization。 GRIB是WMO开发的一种用于交换和存储规则分布数据的二进制文件格式。最初GRIB表示“二进制格点”(GRIdded Binary)&#xff0c;后来扩展为“二进制的通用规则分布信息”(General Regularly-dis…

grib2文件格式说明

GRIB是一种二进制编码的名称&#xff0c;用于加工资料的传输和交换&#xff0c;GRIB编码的分析或预报产品是由一系列八位组构成的连续比特流组成。在GRIB2中编码资料主要分为9段。 0段——指示段八位组序号 内容 1—4 GRIB(按照国际电报字符5号…

Gerber文件解析

最近公司准备做pcb板缺陷检测&#xff0c;首先要用C解析GerBer文件&#xff0c;我尝试了使用pcb-tools库&#xff1a;https://github.com/curtacircuitos/pcb-tools。完美配置了环境&#xff0c;接下来就是学习一些Kicad制作GerBer文件的规则解析对应Gerber文件。有个问题不太清…

Windows下xarray+cfgrib读取grib文件

在Windows下读取grib文件&#xff0c;在我上一篇博客Windows上python读取grib2文件&#xff08;不用Linux&#xff09;学习了使用wgrib2处理grib2文件&#xff0c;可以直接读&#xff0c;也可以转化为nc文件&#xff08;转化后python就容易处理了&#xff09;。而对于grib文件&…

grib2 文件结构

GRIB是一种二进制编码的名称&#xff0c;用于加工资料的传输和交换&#xff0c;GRIB编码的分析或预报产品是由一系列八位组构成的连续比特流组成。在GRIB2中编码资料主要分为9段&#xff0c; 0段——指示段 八位组序号 内容 1—4 G…