changed: gcc8 base update
[opensg.git] / Source / System / FileIO / OSB / OSGOSBImageElement.cpp
blob519b8f23b6497e1b5b20a7aa96277b77ea9afdc0
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2007 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 #include "OSGOSBImageElement.h"
41 #include "OSGOSBRootElement.h"
42 #include "OSGImage.h"
43 #include "OSGImageFileHandler.h"
45 OSG_USING_NAMESPACE
47 /*-------------------------------------------------------------------------*/
48 /* OSBImageElement */
49 /*-------------------------------------------------------------------------*/
51 /*-------------------------------------------------------------------------*/
52 /* Static members */
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 /*-------------------------------------------------------------------------*/
64 /* Constructor */
66 OSBImageElement::OSBImageElement(OSBRootElement *root)
67 : Inherited (root, OSGOSBHeaderVersion200),
68 _hasJPEGSupport(false ),
69 _version (OSGOSBHeaderVersion200 )
73 /*-------------------------------------------------------------------------*/
74 /* Destructor */
76 OSBImageElement::~OSBImageElement(void)
80 /*-------------------------------------------------------------------------*/
81 /* Reading */
83 void
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();
90 UInt8 fcPtrType;
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();
104 setContainer(img);
106 rh->getValue(_version);
108 if(_version >= OSGOSBHeaderVersion200)
110 UInt8 flags;
111 rh->getValue(flags);
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();
124 else
126 // read fields stored in file
127 readFields("", "");
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());
134 setContainer(img);
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());
157 setContainer(img);
162 void
163 OSBImageElement::postRead(void)
165 // nothing to do
168 /*-------------------------------------------------------------------------*/
169 /* Writing */
171 void
172 OSBImageElement::preWrite(FieldContainer * const fc)
174 OSG_OSB_LOG(("OSBImageElement::preWrite\n"));
176 preWriteFieldContainer(fc, "");
179 void
180 OSBImageElement::write(void)
182 OSG_OSB_LOG(("OSBImageElement::write\n"));
184 if(getContainer() == NULL)
186 FWARNING(("OSBImageElement::write: Attempt to write NULL.\n"));
187 return;
190 Image *img = dynamic_cast<Image *>(getContainer());
191 BinaryWriteHandler *wh = editRoot()->getWriteHandler();
192 const OSBRootElement *root = getRoot();
193 UInt8 flags = 0;
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' " );
209 else
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'");
221 // write flags
222 wh->putValue(flags);
224 // write all fields that do not require special handling
225 writeFields(excludeFields, false);
227 if(compressTextures)
228 writeCompressedPixelData();
230 writeEndMarker();
233 /*-------------------------------------------------------------------------*/
234 /* Reading Helper Functions */
236 void
237 OSBImageElement::readCompressedPixelData(void)
239 BinaryReadHandler *rh = editRoot()->getReadHandler();
240 Image *img = dynamic_cast<Image *>(getContainer());
242 std::string fieldTypeName;
243 UInt32 fieldSize;
244 UInt32 byteSize;
245 std::vector<UInt8> buffer;
247 rh->getValue(fieldTypeName);
248 rh->getValue(fieldSize );
250 if(!_hasJPEGSupport)
252 FWARNING(("OSBImageElement::readCompressedPixelData: "
253 "JPEG Support not available, skipping compressed "
254 "texture data.\n"));
255 rh->skip(fieldSize);
256 return;
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 */
271 void
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;
285 UInt32 factor = 1;
287 // JPEG always uses RGB, so single channel images need additional memory
288 if((imageType == "jpeg") && (img->getBpp() == 1))
289 factor = 3;
291 // some extra space is needed for the image header
292 UInt32 bufferSize =
293 ImageFileHandler::the()->getDefaultType()->maxBufferSize(img) * factor +
294 16384;
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);