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 //-------------------------------
46 #include "OSGConfig.h"
48 #include "OSGBaseFunctions.h"
55 #include "OSGSGIImageFileType.h"
60 #define INT_MAX numeric_limits<int>::max()
66 static const OSG::Char8
*suffixArray
[] =
68 "rgb", "rgba", "sgi", "bw", "int", "inta"
73 /*! \class SGIImageFileType
75 Image File Type to read/write and store/restore Image objects as
78 All the type specific code is included in the class. Does
79 not depend on external libs.
84 /* the basic reader functions */
86 /* I found these on the net a long time ago. They didn't contain any copyright
87 notice and I couldn't find out where I found them.
88 If you wrote them please let us know (info@opensg.org) so that we can either
89 credit you or remove them if you have a problem with us using them.
94 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
101 unsigned short imagic
;
104 unsigned short xsize
, ysize
, zsize
;
105 unsigned int min
, max
;
106 unsigned int wasteBytes
;
108 unsigned long colorMap
;
110 std::vector
<unsigned char> tmp
;
111 std::vector
<unsigned int> rowStart
;
112 std::vector
<unsigned int> rowSize
;
132 ImageRec(const ImageRec
&other
);
133 void operator =(const ImageRec
&rhs
);
139 ConvertShort(unsigned short *array
, long length
)
144 ptr
= reinterpret_cast<unsigned char *>(array
);
149 *array
++ = (b1
<< 8) | (b2
);
154 ConvertLong(unsigned *array
, unsigned long length
)
156 unsigned long b1
, b2
, b3
, b4
;
159 ptr
= reinterpret_cast<unsigned char *>(array
);
166 *array
++ = (b1
<< 24) | (b2
<< 16) | (b3
<< 8) | (b4
);
170 static bool ImageOpen(ImageRec
&image
, std::istream
&is
)
174 is
.read(reinterpret_cast<char*>(&image
), 12);
176 if(is
.gcount() != 12)
179 bool swapFlag
= !osgIsBigEndian();
182 ConvertShort(&image
.imagic
, 6);
184 if((image
.type
& 0xFF00) == 0x0100)
187 if (is
.gcount() != 512 - 12)
190 int n
= image
.ysize
* image
.zsize
;
191 int len
= n
* sizeof(unsigned);
193 image
.rowStart
.resize(n
);
195 is
.read(reinterpret_cast<char*>(&(image
.rowStart
.front())), len
);
197 if(is
.gcount() != len
)
200 image
.rowSize
.resize(n
);
202 is
.read(reinterpret_cast<char*>(&(image
.rowSize
.front())), len
);
204 if(is
.gcount() != len
)
209 ConvertLong(&(image
.rowStart
.front()), n
);
210 ConvertLong(&(image
.rowSize
.front()), n
);
212 unsigned int maxSize
= 0;
214 for(int i
= 0; i
< n
; ++i
)
216 if(image
.rowSize
[i
] > maxSize
)
217 maxSize
= image
.rowSize
[i
];
220 image
.tmp
.resize(maxSize
);
224 image
.tmp
.resize(image
.xsize
);
230 static bool ImageGetRow(ImageRec
&image
,
236 unsigned char *iPtr
= &(image
.tmp
.front());
237 unsigned char *oPtr
= buf
;
239 if((image
.type
& 0xFF00) == 0x0100)
241 unsigned int row
= y
+ z
* image
.ysize
;
243 image
.is
->seekg(image
.rowStart
[row
], std::ios::beg
);
245 long len
= image
.rowSize
[row
];
247 image
.is
->read(reinterpret_cast<char*>(iPtr
), len
);
249 if(image
.is
->gcount() != len
)
252 int npix
= image
.xsize
;
257 unsigned char pixel
= *iPtr
++;
258 int count
= pixel
& 0x7F;
300 image
.is
->seekg(512 + (y
+ z
* image
.ysize
) * image
.xsize
,
303 image
.is
->read(reinterpret_cast<char*>(iPtr
), image
.xsize
);
305 if(image
.is
->gcount() != image
.xsize
)
308 int count
= image
.xsize
;
320 static const UInt32 zsize2pixelformat
[] =
328 SGIImageFileType
SGIImageFileType::_the("image/x-sgi",
330 sizeof(suffixArray
));
333 //-------------------------------------------------------------------------
334 /*! Tries to fill the image object with the data read from
335 the given input stream. Returns true on success.
338 bool SGIImageFileType::read( Image
*pImage
,
340 const std::string
&mimetype
)
344 if(ImageOpen(img
, is
) == false)
347 if((img
.zsize
< 1) || (img
.zsize
> 4))
350 pImage
->set(zsize2pixelformat
[img
.zsize
- 1], img
.xsize
, img
.ysize
);
352 unsigned char *lptr
= pImage
->editData();
354 unsigned int lineStride
= img
.xsize
* img
.zsize
;
356 for(int y
= 0; y
< img
.ysize
; ++y
)
358 for(int z
= 0; z
< img
.zsize
; ++z
)
360 if(ImageGetRow(img
, lptr
+ z
, y
, z
, img
.zsize
) == false)
370 //-------------------------------------------------------------------------
371 /*! Tries to write the image object to the given fileName.
372 Returns true on success.
375 bool SGIImageFileType::write(const Image
*pImage
,
377 const std::string
&mimetype
)
379 FWARNING(("SGIImageFileType::write: not implemented yet!\n"));
384 bool SGIImageFileType::validateHeader(const Char8
*fileName
, bool &implemented
)
391 FILE *file
= fopen(fileName
, "rb");
398 fread(static_cast<void *>(&magic
), sizeof(magic
), 1, file
);
402 #if BYTE_ORDER == LITTLE_ENDIAN
403 if(magic
== 0xda01) // the magic header is big endian need to swap it.
414 //-------------------------------------------------------------------------
416 Tries to determine the mime type of the data provided by an input stream
417 by searching for magic bytes. Returns the mime type or an empty string
418 when the function could not determine the mime type.
421 std::string
SGIImageFileType::determineMimetypeFromStream(std::istream
&is
)
425 is
.read(filecode
, 2);
426 is
.seekg(-2, std::ios::cur
);
428 return strncmp(filecode
, "\x01\xda", 2) == 0 ?
429 std::string(getMimeType()) : std::string();
432 //-------------------------------------------------------------------------
433 /*! Constructor used for the singleton object
436 SGIImageFileType::SGIImageFileType(const Char8
*mimeType
,
437 const Char8
*suffixArray
[],
438 UInt16 suffixByteCount
) :
440 Inherited(mimeType
, suffixArray
, suffixByteCount
)
444 //-------------------------------------------------------------------------
448 SGIImageFileType::~SGIImageFileType(void)