1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2007 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 #include "OSGOSBImageElement.h"
41 #include "OSGOSBRootElement.h"
43 #include "OSGImageFileHandler.h"
47 /*-------------------------------------------------------------------------*/
49 /*-------------------------------------------------------------------------*/
51 /*-------------------------------------------------------------------------*/
54 OSBElementRegistrationHelper
<OSBImageElement
>
55 OSBImageElement::_regHelper
=
56 OSBElementRegistrationHelper
<OSBImageElement
>("Image");
58 const UInt8
OSBImageElement::FlagPixelDataCompressedMask
;
59 const UInt8
OSBImageElement::FlagPixelDataCompressed
;
60 const UInt8
OSBImageElement::FlagPixelDataOutOfLineMask
;
61 const UInt8
OSBImageElement::FlagPixelDataOutOfLine
;
63 /*-------------------------------------------------------------------------*/
66 OSBImageElement::OSBImageElement(OSBRootElement
*root
)
67 : Inherited (root
, OSGOSBHeaderVersion200
),
68 _hasJPEGSupport(false ),
69 _version (OSGOSBHeaderVersion200
)
73 /*-------------------------------------------------------------------------*/
76 OSBImageElement::~OSBImageElement(void)
80 /*-------------------------------------------------------------------------*/
84 OSBImageElement::read(const std::string
&typeName
)
86 OSG_OSB_LOG(("OSBImageElement::read [%s]\n", typeName
.c_str()));
88 const OSBRootElement
*root
= getRoot();
89 BinaryReadHandler
*rh
= editRoot()->getReadHandler();
92 if(root
->getHeaderVersion() >= OSGOSBHeaderVersion200
)
94 if(root
->getHeaderVersion() > OSGOSBHeaderVersion200
)
96 FINFO(("OSBImageElement::read: "
97 "Unknown version, trying to process as latest.\n"));
100 rh
->getValue(fcPtrType
);
103 ImageUnrecPtr img
= Image::create();
106 rh
->getValue(_version
);
108 if(_version
>= OSGOSBHeaderVersion200
)
113 if(flags
& FlagPixelDataCompressedMask
)
115 // compressed inline texture
116 std::string endMarker
= "'pixel'";
117 std::string fieldName
= readFields("", endMarker
);
119 if(fieldName
== "pixel")
121 readCompressedPixelData();
126 // read fields stored in file
129 if(flags
& FlagPixelDataOutOfLineMask
)
131 // read out-of-line image data
132 const std::string
&fileName
= img
->getName();
133 img
= ImageFileHandler::the()->read(fileName
.c_str());
138 else if(_version
>= OSGOSBHeaderVersion100
)
140 std::string endMarker
= "'cpixel'";
141 std::string fieldName
= readFields("", endMarker
);
143 // read compressed pixel data - should be the last field
144 if(fieldName
== "cpixel")
146 readCompressedPixelData();
149 // read any remaining fields - should be none, but this is safe to do.
150 readFieldsContinue(fieldName
, "", "");
152 // read out-of-line image data
153 if(img
->getMFPixel()->empty())
155 const std::string
&fileName
= img
->getName();
156 img
= ImageFileHandler::the()->read(fileName
.c_str());
163 OSBImageElement::postRead(void)
168 /*-------------------------------------------------------------------------*/
172 OSBImageElement::preWrite(FieldContainer
* const fc
)
174 OSG_OSB_LOG(("OSBImageElement::preWrite\n"));
176 preWriteFieldContainer(fc
, "");
180 OSBImageElement::write(void)
182 OSG_OSB_LOG(("OSBImageElement::write\n"));
184 if(getContainer() == NULL
)
186 FWARNING(("OSBImageElement::write: Attempt to write NULL.\n"));
190 Image
*img
= dynamic_cast<Image
*>(getContainer());
191 BinaryWriteHandler
*wh
= editRoot()->getWriteHandler();
192 const OSBRootElement
*root
= getRoot();
195 wh
->putValue(getFCPtrType(getContainer()));
196 wh
->putValue(getVersion() );
198 std::string excludeFields
= "";
199 bool compressTextures
= false;
201 if(getRoot()->getOptions().inlineTextures() == false)
203 // only write "name" field
204 flags
|= FlagPixelDataOutOfLine
;
205 excludeFields
.append("'dimension' 'width' 'height' 'depth' 'bpp' "
206 "'mipMapCount' 'frameCount' 'frameDelay' "
207 "'pixelFormat' 'pixel' 'frameSize' " );
211 if(_hasJPEGSupport
&& root
->getOptions().compressTextures() &&
212 (img
->getDataType() == Image::OSG_UINT8_IMAGEDATA
) &&
213 ((img
->getBpp() == 1) || (img
->getBpp() == 3)) )
215 compressTextures
= true;
216 flags
|= FlagPixelDataCompressed
;
217 excludeFields
.append("'pixel'");
224 // write all fields that do not require special handling
225 writeFields(excludeFields
, false);
228 writeCompressedPixelData();
233 /*-------------------------------------------------------------------------*/
234 /* Reading Helper Functions */
237 OSBImageElement::readCompressedPixelData(void)
239 BinaryReadHandler
*rh
= editRoot()->getReadHandler();
240 Image
*img
= dynamic_cast<Image
*>(getContainer());
242 std::string fieldTypeName
;
245 std::vector
<UInt8
> buffer
;
247 rh
->getValue(fieldTypeName
);
248 rh
->getValue(fieldSize
);
252 FWARNING(("OSBImageElement::readCompressedPixelData: "
253 "JPEG Support not available, skipping compressed "
259 rh
->getValue(byteSize
);
261 // allocate and fill buffer
262 buffer
.resize(byteSize
);
263 rh
->getValues(&buffer
.front(), byteSize
);
265 img
->restore(&buffer
.front(), byteSize
);
268 /*-------------------------------------------------------------------------*/
269 /* Writing Helper Functions */
272 OSBImageElement::writeCompressedPixelData(void)
274 // FIXME Inline Images are disabled right now. A more recent versin of
275 // the ImageFileHandler from CVS needs to be ported to OpenSG 2.
277 const OSBRootElement
*root
= getRoot();
278 BinaryWriteHandler
*wh
= editRoot()->getWriteHandler();
280 Image
*img
= dynamic_cast<Image
*>(getContainer());
281 std::string imageType
= root
->getOptions().texturesImageType();
282 // std::string imageType = "jpeg";
284 std::vector
<UInt8
> buffer
;
287 // JPEG always uses RGB, so single channel images need additional memory
288 if((imageType
== "jpeg") && (img
->getBpp() == 1))
291 // some extra space is needed for the image header
293 ImageFileHandler::the()->getDefaultType()->maxBufferSize(img
) * factor
+
296 buffer
.resize(bufferSize
);
297 UInt64 compressedSize
= img
->store(imageType
.c_str(), &buffer
.front());
298 // UInt64 compressedSize = 0;
300 UInt32 byteSize
= static_cast<UInt32
>(compressedSize
);
301 UInt32 fieldSize
= sizeof(UInt32
) + sizeof(UInt8
) * byteSize
;
303 wh
->putValue (fieldSize
);
304 wh
->putValue (byteSize
);
305 wh
->putValues(&buffer
.front(), byteSize
);