fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Image / FileIO / OSGTGAImageFileType.cpp
blobb9c43c4b36ecd6bc3935ca4b53ae44794dc5eac0
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //-------------------------------
40 // Includes
41 //-------------------------------
43 #ifdef __hpux // prevent int32 clash (model.h/tiff.h)
44 #define _INT32
45 #endif
47 #include <cstdlib>
48 #include <cstdio>
50 #include "OSGConfig.h"
51 #include "OSGBaseFunctions.h"
53 #include "OSGTGAImageFileType.h"
55 #ifdef OSG_WITH_TGA
56 #include <tiffio.h>
57 #endif
58 #include "OSGLog.h"
60 static const OSG::Char8 *suffixArray[] =
62 "tga", "targa"
65 OSG_BEGIN_NAMESPACE
68 /*! \class TGAImageFileType
70 Image File Type to read/write and store/restore Image objects as
71 TGA data.
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)
80 UInt8 dum[18];
82 is.read(reinterpret_cast<char *>(dum), 18);
84 if(is.gcount() != 18)
85 return false;
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];
100 return true;
103 bool TGAImageFileType::readCompressedImageData(std::istream &is,
104 Image *pImage)
106 UInt32 npix = pImage->getWidth() * pImage->getHeight();
107 Int32 rep, len;
108 UChar8 *data = pImage->editData();
109 UInt16 bpp = pImage->getBpp();
110 Char8 c[4];
112 while(npix > 0)
114 rep = is.get();
115 if (rep == EOF)
116 return false;
117 bool repFlag = (rep & 0x80) != 0;
118 rep = (rep & 0x7f) + 1;
119 if (static_cast<UInt32>(rep) > npix)
120 return false;
121 npix -= rep;
123 if (repFlag == true)
125 switch (pImage->getPixelFormat())
127 case Image::OSG_L_PF:
128 is.read(c, 1);
129 if (is.gcount() != 1)
130 return false;
131 for (; rep > 0; --rep)
132 *data++ = c[0];
133 break;
134 case Image::OSG_RGB_PF:
135 is.read(c, 3);
136 if (is.gcount() != 3)
137 return false;
138 for (; rep > 0; --rep)
140 *data++ = c[0];
141 *data++ = c[1];
142 *data++ = c[2];
144 break;
145 case Image::OSG_RGBA_PF:
146 is.read(c, 4);
147 if (is.gcount() != 4)
148 return false;
149 for (; rep > 0; --rep)
151 *data++ = c[0];
152 *data++ = c[1];
153 *data++ = c[2];
154 *data++ = c[3];
156 break;
157 default:
158 FWARNING(("TGA: unknown pixel "
159 "format!?!\n"));
160 return false;
163 else // raw packet
165 len = bpp * rep;
166 is.read(reinterpret_cast<char *>(data), len);
167 if (is.gcount() != len)
168 return false;
169 data += len;
172 return true;
177 TGAImageFileType TGAImageFileType::_the("image/x-targa",
178 suffixArray,
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,
188 std::istream &is,
189 const std::string &mimetype)
191 // read the header
192 TGAHeader header;
194 if(readHeader(is, header) == false)
195 return false;
197 // determine format
198 Image::PixelFormat format = Image::OSG_INVALID_PF;
200 switch(header.imageType & ~0x8)
202 case 1: FWARNING(("TGA: 8-bit image not supported!\n"));
203 break;
205 case 2:
206 switch (header.depth)
208 case 24:
209 format = Image::OSG_RGB_PF;
210 break;
211 case 32:
212 format = Image::OSG_RGBA_PF;
213 break;
214 default:
215 FWARNING(("TGA: Unknown pixel depth %d!\n",
216 header.depth));
217 break;
219 break;
221 case 3:
222 format = Image::OSG_L_PF;
223 break;
226 if(format == Image::OSG_INVALID_PF)
228 FWARNING(("Unsupported image type for TGA file!\n"));
229 return false;
232 // read the image ID
233 UInt8 imageid[256];
235 is.read(reinterpret_cast<char *>(imageid), header.idLength);
237 if(is.gcount() != header.idLength)
238 return false;
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);
251 //delete [] dum;
252 is.ignore(len);
254 if (is.gcount() != len)
255 return false;
258 // read image data
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"));
266 return false;
269 else
271 Int32 len = pImage->getSize();
273 is.read(reinterpret_cast<char *>(pImage->editData()), len);
275 if(is.gcount() != len)
276 return false;
279 // check origin
280 switch (header.descriptor & 0x30)
282 case 0x00: // bottom left, ok!
283 break;
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,
290 dum;
292 for(UInt32 y = pImage->getHeight() / 2; y > 0; --y)
294 for(UInt32 x = bpl; x > 0; --x, ++t, ++b)
296 dum = *t;
297 *t = *b;
298 *b = dum;
300 b -= bpl * 2;
303 break;
304 case 0x10: // bottom right
305 case 0x30: // top right
306 FWARNING(("TGA: origin 0x%d not supported!\n",
307 header.descriptor & 0x30));
308 return false;
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();
319 while (npix--)
321 dum = d[2];
322 d[2] = d[0];
323 d[0] = dum;
324 d += bpp;
328 return true;
331 //-------------------------------------------------------------------------
332 /*! Tries to write the image object to the given fileName.
333 Returns true on success.
336 bool TGAImageFileType::write(const Image *,
337 std::ostream &,
338 const std::string &)
340 SWARNING << getMimeType()
341 << " write is not compiled into the current binary "
342 << std::endl;
344 return true;
347 //-------------------------------------------------------------------------
348 /*! Constructor used for the singleton object
351 TGAImageFileType::TGAImageFileType(const Char8 *mimeType,
352 const Char8 *suffixArray[],
353 UInt16 suffixByteCount) :
354 Inherited(mimeType,
355 suffixArray,
356 suffixByteCount)
360 //-------------------------------------------------------------------------
361 /*! Destructor
364 TGAImageFileType::~TGAImageFileType(void)
368 OSG_END_NAMESPACE