| Bsoft 2.0.5 Bernard's software package

rwTGA.cpp
Go to the documentation of this file.
1
9 #include "rwTGA.h"
10 #include "file_util.h"
11 #include "utilities.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
16 // Given a pointer to packed TGA color data, and the number of bits used
17 // per color return an unpacked 32-bit color.
18 RGB<unsigned char> TGA_to_RGB(const unsigned char * pColorData, unsigned int bitsPerColor )
19 {
20 RGB<unsigned char> color;
21 switch( bitsPerColor )
22 {
23 case 15:
24 // MSB LSB
25 // xRRRRRGG GGGBBBBB
26 color[0] = (pColorData[1] >> 2) & 0x1F;
27 color[1] = ((pColorData[1] << 3) & 0x1C) | ((pColorData[0] >> 5) & 0x07);
28 color[2] = (pColorData[0] & 0x1F);
29
30 // Convert 5-bit channels to 8-bit channels by left shifting by three
31 // and repeating the first three bits to cover the range [0,255] with
32 // even spacing. For example:
33 // channel input bits: 4 3 2 1 0
34 // channel output bits: 4 3 2 1 0 4 3 2
35 color[0] = (color[0] << 3) | (color[0] >> 2);
36 color[1] = (color[1] << 3) | (color[1] >> 2);
37 color[2] = (color[2] << 3) | (color[2] >> 2);
38 break;
39
40 case 24:
41 // MSB LSB
42 // RRRRRRRR GGGGGGGG BBBBBBBB
43 color[0] = pColorData[2];
44 color[1] = pColorData[1];
45 color[2] = pColorData[0];
46 break;
47 }
48
49 return color;
50 }
51
52 // Given a pointer to packed TGA color data, and the number of bits used
53 // per color return an unpacked 32-bit color.
54 RGBA<unsigned char> TGA_to_RGBA(const unsigned char * pColorData, unsigned int bitsPerColor )
55 {
56 RGBA<unsigned char> color;
57 switch( bitsPerColor )
58 {
59 case 15:
60 // MSB LSB
61 // xRRRRRGG GGGBBBBB
62 color[3] = 255;
63 color[0] = (pColorData[1] >> 2) & 0x1F;
64 color[1] = ((pColorData[1] << 3) & 0x1C) | ((pColorData[0] >> 5) & 0x07);
65 color[2] = (pColorData[0] & 0x1F);
66
67 // Convert 5-bit channels to 8-bit channels by left shifting by three
68 // and repeating the first three bits to cover the range [0,255] with
69 // even spacing. For example:
70 // channel input bits: 4 3 2 1 0
71 // channel output bits: 4 3 2 1 0 4 3 2
72 color[0] = (color[0] << 3) | (color[0] >> 2);
73 color[1] = (color[1] << 3) | (color[1] >> 2);
74 color[2] = (color[2] << 3) | (color[2] >> 2);
75 break;
76
77 case 16:
78 // MSB LSB
79 // ARRRRRGG GGGBBBBB
80 color[3] = 255 * ((pColorData[1] & 0x80) >> 7);
81 color[0] = (pColorData[1] >> 2) & 0x1F;
82 color[1] = ((pColorData[1] << 3) & 0x1C) | ((pColorData[0] >> 5) & 0x07);
83 color[2] = (pColorData[0] & 0x1F);
84
85 // Convert 5-bit channels to 8-bit channels by left shifting by three
86 // and repeating the first three bits to cover the range [0,255] with
87 // even spacing. For example:
88 // channel input bits: 4 3 2 1 0
89 // channel output bits: 4 3 2 1 0 4 3 2
90 color[0] = (color[0] << 3) | (color[0] >> 2);
91 color[1] = (color[1] << 3) | (color[1] >> 2);
92 color[2] = (color[2] << 3) | (color[2] >> 2);
93 break;
94
95 case 24:
96 // MSB LSB
97 // RRRRRRRR GGGGGGGG BBBBBBBB
98 color[3] = 255;
99 color[0] = pColorData[2];
100 color[1] = pColorData[1];
101 color[2] = pColorData[0];
102 break;
103
104 case 32:
105 // MSB LSB
106 // AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
107 color[3] = pColorData[3];
108 color[0] = pColorData[2];
109 color[1] = pColorData[1];
110 color[2] = pColorData[0];
111 break;
112 }
113
114 color[3] = 255 - color[3];
115
116 // cout << color << endl;
117
118 return color;
119 }
120
134 int readTGA(Bimage *p, int readdata)
135 {
136 if ( verbose & VERB_DEBUG )
137 cout << "DEBUG readTGA: " << p->file_name() << endl;
138
139 ifstream* fimg = new ifstream(p->file_name());
140 if ( fimg->fail() ) return -1;
141
142 TGAhead* header = new TGAhead;
143 TGAfoot* footer = new TGAfoot;
144
145 // cout << "header size: " << sizeof(TGAhead) << endl;
146 // cout << "footer size: " << sizeof(TGAfoot) << endl;
147
148 fimg->seekg(-25, fimg->end);
149 fimg->read((char *)footer, 25);
150 if ( fimg->fail() ) return -2;
151
152 if ( strncmp(footer->sig, "TRUEVISION-XFILE", 16) == 0 ) {
153 cout << "Footer found" << endl;
154 cout << "Extension offset: " << footer->extoff << endl;
155 cout << "Developer offset: " << footer->devoff << endl;
156 }
157
158 fimg->seekg(0, fimg->beg);
159 fimg->read((char *)header, TGASIZE);
160 if ( fimg->fail() ) return -2;
161
162 char id[256];
163 fimg->read(id, header->idlen);
164 if ( fimg->fail() ) return -3;
165
166 if ( verbose & VERB_DEBUG ) {
167 cout << "DEBUG readTGA: " << id << endl;
168 cout << id << endl;
169 cout << "Image type: " << (int)header->imgtype << endl;
170 cout << "Width: " << header->width << " height: " << header->height << endl;
171 cout << "Pixel depth: " << (int)header->pixeldepth << endl;
172 cout << "Image descriptor: " << (int)header->imgdesc << endl;
173 cout << "Color map: " << header->colmapindex << tab << header->colmaplength
174 << tab << (int)header->colmapbits << endl;
175 }
176
177 p->label(id);
178
179 // Determine byte order and swap bytes if from little-endian machine
180 unsigned char* b = (unsigned char *) header;
181 long i, sb(0);
182 if ( header->imgtype > 11 ) {
183 if ( verbose & VERB_PROCESS )
184 cerr << "Warning: Swapping header byte order for 2-byte types" << endl;
185 sb = 1;
186 for ( i=3; i<6; i+=2 ) swapbytes(b+i, 2);
187 for ( i=8; i<17; i+=2 ) swapbytes(b+i, 2);
188 swapbytes(b+3, 2);
189 }
190
191
192 int entrylen((header->colmapbits-1)/8+1);
193 if ( header->colmaplength ) {
194 char colmap[entrylen*header->colmaplength];
195 fimg->read(colmap, entrylen*header->colmaplength);
196 if ( fimg->fail() ) return -4;
197 }
198
199 // Map the parameters
200 p->size(header->width, header->height, 1);
201 p->images(1);
202 p->channels(1);
203 if ( header->imgtype == 3 ) {
204 switch ( header->pixeldepth ) {
205 case 8: p->data_type(UCharacter); break;
206 case 16: p->data_type(UShort); break;
207 case 32: p->data_type(UInteger);
208 default: p->data_type(UCharacter); break;
209 }
210 } else {
211 p->data_type(UCharacter);
212 if ( header->pixeldepth == 15 || header->pixeldepth == 24 ) {
213 p->channels(3);
214 p->compound_type(TRGB);
215 } else {
216 p->channels(4);
217 p->compound_type(TRGBA);
218 }
219 }
220 if ( verbose & VERB_DEBUG )
221 cout << "DEBUG readTGA: mode=" << header->imgtype << " datatype=" << p->data_type() << endl;
222 p->data_offset(TGASIZE + header->idlen + entrylen*header->colmaplength);
223
224 // Allocating the single sub-image and setting its parameters
225
226 tm* t = p->get_localtime();
227 p->set_time(t);
228
229 unsigned char* nudata;
230 long j, bytes((header->pixeldepth-1)/8+1);
231 long ds(header->width*header->height*bytes);
232
233 if ( readdata ) {
234 nudata = new unsigned char[ds];
235 if ( fread_large(nudata, ds, p->data_offset(), fimg) < 0 ) return -1;
236 if ( sb && bytes > 1 ) swapbytes(ds, nudata, bytes);
237 if ( p->channels() < 3 ) {
238 p->data_assign((unsigned char *) nudata);
239 } else {
240 if ( verbose & VERB_DEBUG )
241 cout << "DEBUG readTGA: converting color data" << endl;
242 p->data_alloc();
243 for ( i=j=0; i<header->width*header->height; i++, j+=bytes )
244 if ( p->channels() == 3 ) p->set(i, TGA_to_RGB(nudata+j, header->pixeldepth));
245 else p->set(i, TGA_to_RGBA(nudata+j, header->pixeldepth));
246 delete[] nudata;
247 }
248 if ( header->imgdesc & 16 ) p->reslice("-xyz");
249 if ( header->imgdesc & 32 ) p->reslice("x-yz");
250 }
251
252 delete header;
253 delete footer;
254
255 fimg->close();
256 delete fimg;
257
258 return 0;
259 }
260
266 int writeTGA(Bimage *p)
267 {
268
269 switch ( p->data_type() ) {
270 case Bit: case UCharacter: case SCharacter:
271 p->change_type(UCharacter); break;
272 case UShort: case Short:
273 p->change_type(UShort); break;
274 case UInteger: case Integer:
275 p->change_type(UInteger); break;
276 case Float: case Double:
277 p->change_type(UInteger); break;
278 default:
279 p->change_type(UCharacter); break;
280 }
281
282 if ( verbose & VERB_DEBUG )
283 cout << "DEBUG writeTGA: header size=" << sizeof(TGAhead) << endl;
284
285 TGAhead* header = new TGAhead;
286 memset(header, 0, sizeof(TGAhead));
287
288 // Map the parameters
289 if ( p->label().length() > 255 ) header->idlen = (unsigned char)255;
290 else header->idlen = p->label().length();
291
292 if ( p->compound_type() == TSimple ) {
293 header->imgtype = 3;
294 header->pixeldepth = p->data_type_size()*8;
295 } else {
296 header->imgtype = 2;
297 header->pixeldepth = p->channels()*8;
298 }
299
300 header->width = p->size()[0];
301 header->height = p->size()[1];
302
303 if ( verbose & VERB_DEBUG )
304 cout << "DEBUG writeTGA: pixeldepth=" << header->pixeldepth << endl;
305
306 long i;
307
308 ofstream fimg(p->file_name());
309 if ( fimg.fail() ) return -1;
310
311 fimg.write((char *)header, TGASIZE);
312 fimg.write((char *)p->label().c_str(), header->idlen);
313 if ( p->data_pointer() ) {
314 char* data = new char[p->alloc_size()];
315 unsigned char* ptr;
316 if ( p->compound_type() < TRGB ) {
317 for ( i=0, ptr=p->data_pointer(); i<p->alloc_size(); i++, ptr++ )
318 data[i] = *ptr;
319 } else {
320 for ( i=0, ptr=p->data_pointer(); i<p->alloc_size(); ptr+=p->channels() ) {
321 data[i++] = ptr[2];
322 data[i++] = ptr[1];
323 data[i++] = ptr[0];
324 if ( p->channels() > 3 ) data[i++] = 255 - ptr[3];
325 }
326 }
327 fimg.write(data, p->alloc_size());
328 delete[] data;
329 }
330
331 fimg.close();
332
333 delete header;
334
335 return 0;
336 }
337
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
RGBA
Definition: Color.h:11
Integer
Definition: utilities.h:154
TGASIZE
#define TGASIZE
Definition: rwTGA.h:13
SCharacter
Definition: utilities.h:150
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
UInteger
Definition: utilities.h:153
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
TGA_to_RGBA
RGBA< unsigned char > TGA_to_RGBA(const unsigned char *pColorData, unsigned int bitsPerColor)
Definition: rwTGA.cpp:54
Double
Definition: utilities.h:158
Bimage::label
void label(string s)
Definition: Bimage.h:235
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
Bimage::set_time
void set_time(time_t t)
Definition: Bimage.h:249
sb
int sb(0)
RGB
Definition: Color.h:24
readTGA
int readTGA(Bimage *p, int readdata)
Reading a Truevision TGA image file format.
Definition: rwTGA.cpp:134
TGA_to_RGB
RGB< unsigned char > TGA_to_RGB(const unsigned char *pColorData, unsigned int bitsPerColor)
Definition: rwTGA.cpp:18
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
file_util.h
Header file for file checking functions.
Bimage::data_offset
long data_offset()
Definition: Bimage.h:265
Bimage::get_localtime
tm * get_localtime()
Definition: Bimage.h:245
Bimage::channels
long channels()
Definition: Bimage.h:371
swapbytes
void swapbytes(unsigned char *v, size_t n)
Swaps bytes.
Definition: utilities.cpp:504
rwTGA.h
Header file for reading and writing Truevision TGA files.
Bimage::reslice
void reslice(const char *order)
Definition: Bimage.h:709
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
TRGB
Definition: Bimage.h:62
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UCharacter
Definition: utilities.h:149
Bit
Definition: utilities.h:148
writeTGA
int writeTGA(Bimage *p)
Writing a Truevision TGA map image file format.
Definition: rwTGA.cpp:266
fread_large
int fread_large(unsigned char *aptr, size_t pagesize, size_t offset, ifstream *fimg)
Reads blocks of memeory no larger than 1Gb.
Definition: file_util.cpp:347
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Short
Definition: utilities.h:152
verbose
int verbose
TRGBA
Definition: Bimage.h:63
UShort
Definition: utilities.h:151
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21