1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //-------------------------------
41 //-------------------------------
43 #ifdef __hpux // prevent int32 clash (model.h/tiff.h)
50 #include "OSGConfig.h"
51 #include "OSGBaseFunctions.h"
53 #include "OSGTGAImageFileType.h"
60 static const OSG::Char8
*suffixArray
[] =
68 /*! \class TGAImageFileType
70 Image File Type to read/write and store/restore Image objects as
73 All the type specific code is included in the class. Does
74 not depend on external libs.
78 bool TGAImageFileType::readHeader(std::istream
&is
, TGAHeader
&header
)
82 is
.read(reinterpret_cast<char *>(dum
), 18);
87 header
.idLength
= dum
[ 0];
88 header
.colorMapType
= dum
[ 1];
89 header
.imageType
= dum
[ 2];
90 header
.cmapFirst
= dum
[ 3] | (dum
[ 4] << 8);
91 header
.cmapLength
= dum
[ 5] | (dum
[ 6] << 8);
92 header
.cmapEntrySize
= dum
[ 7];
93 header
.xOrigin
= dum
[ 8] | (dum
[ 9] << 8);
94 header
.yOrigin
= dum
[10] | (dum
[11] << 8);
95 header
.width
= dum
[12] | (dum
[13] << 8);
96 header
.height
= dum
[14] | (dum
[15] << 8);
97 header
.depth
= dum
[16];
98 header
.descriptor
= dum
[17];
103 bool TGAImageFileType::readCompressedImageData(std::istream
&is
,
106 UInt32 npix
= pImage
->getWidth() * pImage
->getHeight();
108 UChar8
*data
= pImage
->editData();
109 UInt16 bpp
= pImage
->getBpp();
117 bool repFlag
= (rep
& 0x80) != 0;
118 rep
= (rep
& 0x7f) + 1;
119 if (static_cast<UInt32
>(rep
) > npix
)
125 switch (pImage
->getPixelFormat())
127 case Image::OSG_L_PF
:
129 if (is
.gcount() != 1)
131 for (; rep
> 0; --rep
)
134 case Image::OSG_RGB_PF
:
136 if (is
.gcount() != 3)
138 for (; rep
> 0; --rep
)
145 case Image::OSG_RGBA_PF
:
147 if (is
.gcount() != 4)
149 for (; rep
> 0; --rep
)
158 FWARNING(("TGA: unknown pixel "
166 is
.read(reinterpret_cast<char *>(data
), len
);
167 if (is
.gcount() != len
)
177 TGAImageFileType
TGAImageFileType::_the("image/x-targa",
179 sizeof(suffixArray
));
182 //-------------------------------------------------------------------------
183 /*! Tries to fill the image object with the data read from
184 the given fileName. Returns true on success.
187 bool TGAImageFileType::read( Image
*pImage
,
189 const std::string
&mimetype
)
194 if(readHeader(is
, header
) == false)
198 Image::PixelFormat format
= Image::OSG_INVALID_PF
;
200 switch(header
.imageType
& ~0x8)
202 case 1: FWARNING(("TGA: 8-bit image not supported!\n"));
206 switch (header
.depth
)
209 format
= Image::OSG_RGB_PF
;
212 format
= Image::OSG_RGBA_PF
;
215 FWARNING(("TGA: Unknown pixel depth %d!\n",
222 format
= Image::OSG_L_PF
;
226 if(format
== Image::OSG_INVALID_PF
)
228 FWARNING(("Unsupported image type for TGA file!\n"));
235 is
.read(reinterpret_cast<char *>(imageid
), header
.idLength
);
237 if(is
.gcount() != header
.idLength
)
240 imageid
[header
.idLength
] = 0;
242 FDEBUG(("TGA: Image ID '%s'\n", imageid
));
244 // read color map data
245 if(header
.colorMapType
== 1)
247 Int32 len
= osgMin(header
.cmapEntrySize
/ 3, 8) * header
.cmapLength
;
249 //UInt8 * dum = new UInt8 [len];
250 //in.read(reinterpret_cast<char *>(dum), len);
254 if (is
.gcount() != len
)
259 pImage
->set(format
, header
.width
, header
.height
);
261 if((header
.imageType
& 0x8) != 0)
263 if(readCompressedImageData(is
, pImage
) == false)
265 FWARNING(("Unsupported image type for TGA file!\n"));
271 Int32 len
= pImage
->getSize();
273 is
.read(reinterpret_cast<char *>(pImage
->editData()), len
);
275 if(is
.gcount() != len
)
280 switch (header
.descriptor
& 0x30)
282 case 0x00: // bottom left, ok!
284 case 0x20: // top left
285 // do top-bottom swap
287 UInt32 bpl
= pImage
->getBpp() * pImage
->getWidth();
288 UChar8
*t
= pImage
->editData(),
289 *b
= t
+ (pImage
->getHeight() - 1) * bpl
,
292 for(UInt32 y
= pImage
->getHeight() / 2; y
> 0; --y
)
294 for(UInt32 x
= bpl
; x
> 0; --x
, ++t
, ++b
)
304 case 0x10: // bottom right
305 case 0x30: // top right
306 FWARNING(("TGA: origin 0x%d not supported!\n",
307 header
.descriptor
& 0x30));
311 // do BGR -> RGB swap, as GL_BGR_EXT is not supported everywhere
312 if(pImage
->getPixelFormat() == Image::OSG_RGB_PF
||
313 pImage
->getPixelFormat() == Image::OSG_RGBA_PF
)
315 UChar8
*d
= pImage
->editData(), dum
;
316 UInt32 npix
= pImage
->getWidth() * pImage
->getHeight();
317 UInt8 bpp
= pImage
->getBpp();
331 //-------------------------------------------------------------------------
332 /*! Tries to write the image object to the given fileName.
333 Returns true on success.
336 bool TGAImageFileType::write(const Image
*,
340 SWARNING
<< getMimeType()
341 << " write is not compiled into the current binary "
347 //-------------------------------------------------------------------------
348 /*! Constructor used for the singleton object
351 TGAImageFileType::TGAImageFileType(const Char8
*mimeType
,
352 const Char8
*suffixArray
[],
353 UInt16 suffixByteCount
) :
360 //-------------------------------------------------------------------------
364 TGAImageFileType::~TGAImageFileType(void)