prevent an unsigned overflow in FT1 has_chars() implementation
[imager.git] / fileformatdocs / SGIIMAGESPEC.txt
CommitLineData
458ef9b3
TC
1
2For Version 1.00 of this spec see:
3
4http://reality.sgi.com/grafica/sgiimage.html
5
6
7
8
9 Draft version 0.97
10
11 The SGI Image File Format
12
13 Paul Haeberli
14
15 paul@sgi.com
16
17 Silicon Graphics Computer Systems
18
19
20
21 This is the definitive document describing the SGI image file format. This
22 is a low level spec that describes the actual byte level format of SGI image
23 files. On SGI machines the preferred way of reading and writing SGI image
24 files is to use the image library -limage. This library provides a set
25 of functions that make it easy to read and write SGI images. If you are
26 on an SGI workstation you can get info on -limage by doing:
27
28 % man 4 rgb
29
30 A note on byte order of values in the SGI image files
31
32 In the following description a notation like bits[7..0] is used to denote
33 a range of bits in a binary value. Bit 0 is the lowest order bit in
34 the value.
35
36 All short values are represented by 2 bytes. The first byte stores the
37 high order 8 bits of the value: bits[15..8]. The second byte stores
38 the low order 8 bits of the value: bits[7..0].
39
40 So, this function will read a short value from the file:
41
42 unsigned short getshort(inf)
43 FILE *inf;
44 {
45 unsigned char buf[2];
46
47 fread(buf,2,1,inf);
48 return (buf[0]<<8)+(buf[1]<<0);
49 }
50
51 All long values are represented by 4 bytes. The first byte stores the
52 high order 8 bits of the value: bits[31..24]. The second byte stores
53 bits[23..16]. The third byte stores bits[15..8]. The forth byte stores
54 the low order 8 bits of the value: bits[7..0].
55
56 So, this function will read a long value from the file:
57
58 static long getlong(inf)
59 FILE *inf;
60 {
61 unsigned char buf[4];
62
63 fread(buf,4,1,inf);
64 return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);
65 }
66
67
68 The general structure of an SGI image file is as shown below:
69
70 The header indicates whether the image is run length encoded (RLE).
71
72 If the image is not run length encoded, this is the structure:
73
74 The Header
75 The Image Data
76
77 If the image is run length encoded, this is the structure:
78
79 The Header
80 The Offset Tables
81 The Image Data
82
83
84 The Header
85
86 The header consists of the following:
87
88 Size | Type | Name | Description
89
90 2 bytes | short | MAGIC | IRIS image file magic number
91 1 byte | char | STORAGE | Storage format
92 1 byte | char | BPC | Number of bytes per pixel channel
93 2 bytes | ushort | DIMENSION | Number of dimensions
94 2 bytes | ushort | XSIZE | X size in pixels
95 2 bytes | ushort | YSIZE | Y size in pixels
96 2 bytes | ushort | ZSIZE | Number of channels
97 4 bytes | long | PIXMIN | Minimum pixel value
98 4 bytes | long | PIXMAX | Maximum pixel value
99 4 bytes | char | DUMMY | Ignored
100 80 bytes | char | IMAGENAME | Image name
101 4 bytes | long | COLORMAP | Colormap ID
102 404 bytes | char | DUMMY | Ignored
103
104
105 Here is a description of each field in the image file header:
106
107 MAGIC - This is the decimal value 474 saved as a short. This
108 identifies the file as an SGI image file.
109
110 STORAGE - specifies whether the image is stored using run
111 length encoding (RLE) or not (VERBATIM). If RLE is used, the value
112 of this byte will be 1. Otherwise the value of this byte will be 0.
113 The only allowed values for this field are 0 or 1.
114
115 BPC - describes the precision that is used to store each
116 channel of an image. This is the number of bytes per pixel
117 component. The majority of SGI image files use 1 byte per
118 pixel component, giving 256 levels. Some SGI image files use
119 2 bytes per component. The only allowed values for this field
120 are 1 or 2.
121
122 DIMENSION - described the number of dimensions in the data stored
123 in the image file. The only allowed values are 1, 2, or 3. If
124 this value is 1, the image file consists of only 1 channel and
125 only 1 scanline (row). The length of this scanline is given by the
126 value of XSIZE below. If this value is 2, the file consists of a
127 single channel with a number of scanlines. The width and height
128 of the image are given by the values of XSIZE and YSIZE below.
129 If this value is 3, the file consists of a number of channels.
130 The width and height of the image are given by the values of
131 XSIZE and YSIZE below. The number of channels is given by the
132 value of ZSIZE below.
133
134 XSIZE - The width of the image in pixels
135
136 YSIZE - The height of the image in pixels
137
138 ZSIZE - The number of channels in the image. B/W (greyscale) images
139 are stored as 2 dimensional images with a ZSIZE or 1. RGB color
140 images are stored as 3 dimensional images with a ZSIZE of 3. An RGB
141 image with an ALPHA channel is stored as a 3 dimensional image with
142 a ZSIZE of 4. There are no inherent limitations in the SGI image
143 file format that would preclude the creation of image files with more
144 than 4 channels.
145
146 PINMIN - The minimum pixel value in the image. The value of
147 0 may be used if no pixel has a value that is smaller than 0.
148
149 PINMAX - The maximum pixel value in the image. The value of
150 255 may be used if no pixel has a value that is greater than 255.
151 This is the value that is considered to be full brightness in
152 the image.
153
154 DUMMY - This 4 bytes of data should be set to 0.
155
156 IMAGENAME - An null terminated ascii string of up to 79 characters
157 terminated by a null may be included here. This is not commonly
158 used.
159
160 COLORMAP - This controls how the pixel values in the file should be
161 interpreted. It can have one of these four values:
162
163 0: NORMAL - The data in the channels represent B/W values
164 for images with 1 channel, RGB values for images with 3
165 channels, and RGBA values for images with 4 channels.
166 Almost all the SGI image files are of this type.
167
168 1: DITHERED - The image will have only 1 channel of data.
169 For each pixel, RGB data is packed into one 8 bit value.
170 3 bits are used for red and green, while blue uses 2 bits.
171 Red data is found in bits[2..0], green data in bits[5..3],
172 and blue data in bits[7..6]. This format is obsolete.
173
174 2: SCREEN - The image will have only 1 channel of data.
175 This format was used to store color-indexed pixels.
176 To convert the pixel values into RGB values a colormap
177 must be used. The appropriate color map varies from
178 image to image. This format is obsolete.
179
180 3: COLORMAP - The image is used to store a color map from
181 an SGI machine. In this case the image is not displayable
182 in the conventional sense.
183
184 DUMMY - This 404 bytes of data should be set to 0. This makes the
185 header exactly 512 bytes.
186
187
188 The Image Data (if not RLE)
189
190 If the image is stored verbatim (without RLE), then image data directly
191 follows the 512 byte header. The data for each scanline of the first
192 channel is written first. If the image has more than 1 channel, all
193 the data for the first channel is written, followed by the remaining
194 channels. If the BPC value is 1, then each scanline is written as XSIZE
195 bytes. If the BPC value is 2, then each scanline is written as XSIZE
196 shorts. These shorts are stored in the byte order described above.
197
198
199 The Offset Tables (if RLE)
200
201 If the image is stored using run length encoding, offset tables
202 follow the header that describe what the file offsets are to the
203 RLE for each scanline. This information only applies if the value
204 for STORAGE above is 1.
205
206 Size | Type | Name | Description
207
208 tablen longs | long | STARTTAB | Start table
209 tablen longs | long | LENGTHTAB | Length table
210
211 One entry in each table is needed for each scanline of RLE data. The
212 total number of scanlines in the image (tablen) is determined by the
213 product of the YSIZE and ZSIZE. There are two tables of longs that
214 are written. Each consists of tablen longs of data. The first
215 table has the file offsets to the RLE data for each scanline in the
216 image. In a file with more than 1 channel (ZSIZE > 1) this table first
217 has all the offsets for the scanlines in the first channel, followed
218 be offsets for the scanlines in the second channel, etc. The second
219 table has the RLE data length for each scanline in the image. In a
220 file with more than 1 channel (ZSIZE > 1) this table first has all the
221 RLE data lengths for the scanlines in the first channel, followed
222 be RLE data lengths for the scanlines in the second channel, etc.
223
224 To find the the file offset, and the number of bytes in the RLE data
225 for a particular scanline, these two arrays may be read in and indexed as
226 follows:
227
228 To read in the tables:
229
230 unsigned long *starttab, *lengthtab;
231
232 tablen = YSIZE*ZSIZE*sizeof(long);
233 starttab = (unsigned long *)mymalloc(tablen);
234 lengthtab = (unsigned long *)mymalloc(tablen);
235 fseek(inf,512,SEEK_SET);
236 readlongtab(inf,starttab);
237 readlongtab(ing,lengthtab);
238
239
240 To find the file offset and RLE data length for a scanline:
241
242 rowno is an integer in the range 0 to YSIZE-1
243 channo is an integer in the range 0 to ZSIZE-1
244
245 rleoffset = starttab[rowno+channo*YSIZE]
246 rlelength = lengthtab[rowno+channo*YSIZE]
247
248 It is possible for two identical rows (scanlines) to share compressed
249 data. A completely white image could be written as a single compressed
250 row and having all table entries point to that row. Another little hack
251 that should work is if you are writing out a RGB RLE file, and a
252 particular scanline is achromatic (greyscale), you could just make the
253 r, g and b rows point to the same data!!
254
255 The Image Data (if RLE)
256
257 This information only applies if the value for STORAGE above is 1. If
258 the image is stored using run length encoding, the image data follows
259 the offset tables above. The RLE data is not in any particular order.
260 The offset tables above are used to locate the rle data for any scanline.
261
262 The RLE data must be read in from the file and expanded into pixel
263 data in the following manner:
264
265 If BPC is 1, then there is one byte per pixel. In this case the
266 RLE data should be read into an array of chars. To expand
267 data, the low order seven bits of the first byte: bits[6..0]
268 are used to form a count. If the high order bit of the first
269 byte is 1: bit[7], then the count is used to specify how many
270 bytes to copy from the RLE data buffer to the destination.
271 Otherwise, if the high order bit of the first byte is 0: bit[7],
272 then the count is used to specify how many times to repeat the
273 value of the following byte, in the destination. This process
274 continues until a count of 0 is found. This should decompress
275 exactly XSIZE pixels.
276
277 Here is example code to decompress a scanline:
278
279 expandrow(optr,iptr,z)
280 unsigned char *optr, *iptr;
281 int z;
282 {
283 unsigned char pixel, count;
284
285 optr += z;
286 while(1) {
287 pixel = *iptr++;
288 if ( !(count = (pixel & 0x7f)) )
289 return;
290 if(pixel & 0x80) {
291 while(count--) {
292 *optr = *iptr++;
293 optr+=4;
294 }
295 } else {
296 pixel = *iptr++;
297 while(count--) {
298 *optr = pixel;
299 optr+=4;
300 }
301 }
302 }
303 }
304
305 If BPC is 2, there is one short (2 bytes) per pixel. In this
306 case the RLE data should be read into an array of shorts. To
307 expand data, the low order seven bits of the first short: bits[6..0]
308 are used to form a count. If bit[7] of the first short is 1, then
309 the count is used to specify how many shorts to copy from the RLE
310 data buffer to the destination. Otherwise, if bit[7] of the first
311 short is 0, then the count is used to specify how many times to
312 repeat the value of the following short, in the destination. This
313 process proceeds until a count of 0 is found. This should decompress
314 exactly XSIZE pixels. Note that the byte order of short data in
315 the input file should be used, as described above.
316
317
318 Implementation notes
319
320 Implementation of both RLE and VERBATIM format for images with
321 BPC of 1 is required since the great majority of SGI images are in
322 this format. Support for images with a 2 BPC is encouraged.
323
324 If the ZSIZE of an image is 1, it is assumed to represent B/W
325 values. If the ZSIZE is 3, it is assumed to represent RGB data,
326 and if ZSIZE is 4, it is assumed to contain RGB data with alpha.
327
328 The origin for all SGI images is the lower left hand corner. The
329 first scanline (row 0) is always the bottom row of the image.
330
331 Naming Conventions
332
333 On SGI systems, SGI image files end with the extension .bw if
334 they are B/W images, they end in .rgb if they contain RGB image
335 data, and end in .rgba if they are RGB images with alpha channel.
336
337 Sometimes the .sgi extension is used as well.
338
339 An example
340
341This program will write out a valid B/W SGI image file:
342
343#include "stdio.h"
344
345#define IXSIZE (23)
346#define IYSIZE (15)
347
348putbyte(outf,val)
349FILE *outf;
350unsigned char val;
351{
352 unsigned char buf[1];
353
354 buf[0] = val;
355 fwrite(buf,1,1,outf);
356}
357
358putshort(outf,val)
359FILE *outf;
360unsigned short val;
361{
362 unsigned char buf[2];
363
364 buf[0] = (val>>8);
365 buf[1] = (val>>0);
366 fwrite(buf,2,1,outf);
367}
368
369static int putlong(outf,val)
370FILE *outf;
371unsigned long val;
372{
373 unsigned char buf[4];
374
375 buf[0] = (val>>24);
376 buf[1] = (val>>16);
377 buf[2] = (val>>8);
378 buf[3] = (val>>0);
379 return fwrite(buf,4,1,outf);
380}
381
382main()
383{
384 FILE *of;
385 char iname[80];
386 unsigned char outbuf[IXSIZE];
387 int i, x, y;
388
389 of = fopen("example.rgb","w");
390 if(!of) {
391 fprintf(stderr,"sgiimage: can't open output file\n");
392 exit(1);
393 }
394 putshort(of,474); /* MAGIC */
395 putbyte(of,0); /* STORAGE is VERBATIM */
396 putbyte(of,1); /* BPC is 1 */
397 putshort(of,2); /* DIMENSION is 2 */
398 putshort(of,IXSIZE); /* XSIZE */
399 putshort(of,IYSIZE); /* YSIZE */
400 putshort(of,1); /* ZSIZE */
401 putlong(of,0); /* PIXMIN is 0 */
402 putlong(of,255); /* PIXMAX is 255 */
403 for(i=0; i<4; i++) /* DUMMY 4 bytes */
404 putbyte(of,0);
405 strcpy(iname,"No Name");
406 fwrite(iname,80,1,of); /* IMAGENAME */
407 putlong(of,0); /* COLORMAP is 0 */
408 for(i=0; i<404; i++) /* DUMMY 404 bytes */
409 putbyte(of,0);
410
411 for(y=0; y<IYSIZE; y++) {
412 for(x=0; x<IXSIZE; x++)
413 outbuf[x] = (255*x)/(IXSIZE-1);
414 fwrite(outbuf,IXSIZE,1,of);
415 }
416 fclose(of);
417}