1 /* ***** BEGIN LICENSE BLOCK *****
7 * Copyright (c) 2008 BBC Research
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * ***** END LICENSE BLOCK ***** */
29 //SGI file format header
30 // 2 bytes | short | MAGIC | IRIS image file magic number
31 // 1 byte | char | STORAGE | Storage format, 0=VERBATIM, 1=RLE
32 // 1 byte | char | BPC | Number of bytes per pixel channel
33 // 2 bytes | ushort | DIMENSION | Number of dimensions, 1=1 line of XSIZE; 2=1 plane of XSIZE*YSIZE (greyscale image); 3=ZSIZE planes of XSIZE*YSIZE (RGB image)
34 // 2 bytes | ushort | XSIZE | X size in pixels
35 // 2 bytes | ushort | YSIZE | Y size in pixels
36 // 2 bytes | ushort | ZSIZE | Number of channels
37 // 4 bytes | long | PIXMIN | Minimum pixel value
38 // 4 bytes | long | PIXMAX | Maximum pixel value
39 // 4 bytes | char | DUMMY | Ignored
40 // 80 bytes | char | IMAGENAME | Image name
41 // 4 bytes | long | COLORMAP | Colormap ID
42 // 404 bytes | char | DUMMY | Ignored
51 //read a 16 bit value, endian safe
52 inline unsigned short getshort(FILE *inf
)
56 fread(buf
, 2, 1, inf
);
57 return (buf
[0]<<8)+(buf
[1]<<0);
60 //read a 32 bit value, endian safe
61 inline long getlong(FILE *inf
)
65 fread(buf
, 4, 1, inf
);
66 return (buf
[0]<<24)+(buf
[1]<<16)+(buf
[2]<<8)+(buf
[3]<<0);
69 void RawReadersgi::readHeader()
71 _magic
= getshort(infile
);
73 //bail out if this does not look like an SGI file
77 fread(&_storage
, 1, 1, infile
);
78 fread(&_bpc
, 1, 1, infile
);
79 _dimension
= getshort(infile
);
80 _width
= getshort(infile
);
81 _height
= getshort(infile
);
82 _zsize
= getshort(infile
);
83 _pixmin
= getlong(infile
);
84 _pixmax
= getlong(infile
);
85 fseek(infile
, 4, SEEK_CUR
); //skip dummy 4 bytes
86 fread(&_name
, 80, 1, infile
); //80 bytes name
87 _name
[80]='\0'; //force string termination
88 _colormap
= getlong(infile
);
89 fseek(infile
, 404, SEEK_CUR
); //skip dummy 404 bytes
91 //set depth to 8 or 16 bits
96 //we are now 512 bytes into the file, which is the end of the header
98 printf("MAGIC = %d\n", _magic
);
99 printf("STORAGE = %d\n", _storage
);
100 printf("BPC = %d\n", _bpc
);
101 printf("DIMENSIONS = %d\n", _dimension
);
102 printf("XSIZE = %d\n", _width
);
103 printf("YSIZE = %d\n", _height
);
104 printf("ZSIZE = %d\n", _zsize
);
105 printf("PIXMIN = %ld\n", _pixmin
);
106 printf("PIXMAX = %ld\n", _pixmax
);
107 printf("NAME = %s\n", _name
);
108 printf("COLORMAP = %ld\n", _colormap
);
112 void RawReadersgi::read_plane(Array2d
<int> &p
, int ysize
)
115 //note that the scan lines are stored in reverse order, bottom to top of frame
122 unsigned char *inLine
= new unsigned char[p
.width()];
124 for (int y
=ysize
-1; y
>=0; y
--) {
125 linesRead
= fread(inLine
, p
.width(), 1, infile
);
127 for (int x
= 0; x
< p
.width(); x
++)
138 //16 bits per channel
139 unsigned char *inLine
= new unsigned char[p
.width()*2];
141 for (int y
=ysize
-1; y
>=0; y
--) {
143 linesRead
= fread(inLine
, p
.width()*2, 1, infile
);
145 for (int x
= 0; x
< p
.width(); x
++, ptr
+=2)
146 p
[y
][x
] = (ptr
[0] << 8) | ptr
[1];
163 RawFrame
& RawReadersgi::read(RawFrame
&f
)
165 assert(f
.chroma
== RawFrame::CrRGB
);
167 //we don't deal with run length coded files yet
171 switch (_dimension
) {
173 //there is one row of XSIZE pixels
178 //there is one plane of XSIZE * YSIZE
179 read_plane(f
.r
, _height
);
183 //there are ZSIZE planes of XSIZE * YSIZE
186 read_plane(f
.r
, _height
);
187 f
.g
= f
.r
; //copy red plane to blue and green to get greyscale. Inefficient, but works
191 if (_zsize
== 3 || _zsize
== 4) {
193 read_plane(f
.r
, _height
);
194 read_plane(f
.g
, _height
);
195 read_plane(f
.b
, _height
);
203 RawFrame
& RawReadersgi::read()