PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/System/FileIO/OSB/OSGOSBImageElement.cpp

https://github.com/msteners/OpenSGDevMaster_Toolbox
C++ | 306 lines | 178 code | 57 blank | 71 comment | 28 complexity | 0d2384d05550541a3a860cd146dad9b8 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause
  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. \*---------------------------------------------------------------------------*/
  38. #include "OSGOSBImageElement.h"
  39. #include "OSGOSBRootElement.h"
  40. #include "OSGImage.h"
  41. #include "OSGImageFileHandler.h"
  42. OSG_USING_NAMESPACE
  43. /*-------------------------------------------------------------------------*/
  44. /* OSBImageElement */
  45. /*-------------------------------------------------------------------------*/
  46. /*-------------------------------------------------------------------------*/
  47. /* Static members */
  48. OSBElementRegistrationHelper<OSBImageElement>
  49. OSBImageElement::_regHelper =
  50. OSBElementRegistrationHelper<OSBImageElement>("Image");
  51. const UInt8 OSBImageElement::FlagPixelDataCompressedMask;
  52. const UInt8 OSBImageElement::FlagPixelDataCompressed;
  53. const UInt8 OSBImageElement::FlagPixelDataOutOfLineMask;
  54. const UInt8 OSBImageElement::FlagPixelDataOutOfLine;
  55. /*-------------------------------------------------------------------------*/
  56. /* Constructor */
  57. OSBImageElement::OSBImageElement(OSBRootElement *root)
  58. : Inherited (root, OSGOSBHeaderVersion200),
  59. _hasJPEGSupport(false ),
  60. _version (OSGOSBHeaderVersion200 )
  61. {
  62. }
  63. /*-------------------------------------------------------------------------*/
  64. /* Destructor */
  65. OSBImageElement::~OSBImageElement(void)
  66. {
  67. }
  68. /*-------------------------------------------------------------------------*/
  69. /* Reading */
  70. void
  71. OSBImageElement::read(const std::string &typeName)
  72. {
  73. OSG_OSB_LOG(("OSBImageElement::read [%s]\n", typeName.c_str()));
  74. const OSBRootElement *root = getRoot();
  75. BinaryReadHandler *rh = editRoot()->getReadHandler();
  76. UInt8 fcPtrType;
  77. if(root->getHeaderVersion() >= OSGOSBHeaderVersion200)
  78. {
  79. if(root->getHeaderVersion() > OSGOSBHeaderVersion200)
  80. {
  81. FINFO(("OSBImageElement::read: "
  82. "Unknown version, trying to process as latest.\n"));
  83. }
  84. rh->getValue(fcPtrType);
  85. }
  86. ImageUnrecPtr img = Image::create();
  87. setContainer(img);
  88. rh->getValue(_version);
  89. if(_version >= OSGOSBHeaderVersion200)
  90. {
  91. UInt8 flags;
  92. rh->getValue(flags);
  93. if(flags & FlagPixelDataCompressedMask)
  94. {
  95. // compressed inline texture
  96. std::string endMarker = "'pixel'";
  97. std::string fieldName = readFields("", endMarker);
  98. if(fieldName == "pixel")
  99. {
  100. readCompressedPixelData();
  101. }
  102. }
  103. else
  104. {
  105. // read fields stored in file
  106. readFields("", "");
  107. if(flags & FlagPixelDataOutOfLineMask)
  108. {
  109. // read out-of-line image data
  110. const std::string &fileName = img->getName();
  111. img = ImageFileHandler::the()->read(fileName.c_str());
  112. setContainer(img);
  113. }
  114. }
  115. }
  116. else if(_version >= OSGOSBHeaderVersion100)
  117. {
  118. std::string endMarker = "'cpixel'";
  119. std::string fieldName = readFields("", endMarker);
  120. // read compressed pixel data - should be the last field
  121. if(fieldName == "cpixel")
  122. {
  123. readCompressedPixelData();
  124. }
  125. // read any remaining fields - should be none, but this is safe to do.
  126. readFieldsContinue(fieldName, "", "");
  127. // read out-of-line image data
  128. if(img->getMFPixel()->empty())
  129. {
  130. const std::string &fileName = img->getName();
  131. img = ImageFileHandler::the()->read(fileName.c_str());
  132. setContainer(img);
  133. }
  134. }
  135. }
  136. void
  137. OSBImageElement::postRead(void)
  138. {
  139. // nothing to do
  140. }
  141. /*-------------------------------------------------------------------------*/
  142. /* Writing */
  143. void
  144. OSBImageElement::preWrite(FieldContainer * const fc)
  145. {
  146. OSG_OSB_LOG(("OSBImageElement::preWrite\n"));
  147. preWriteFieldContainer(fc, "");
  148. }
  149. void
  150. OSBImageElement::write(void)
  151. {
  152. OSG_OSB_LOG(("OSBImageElement::write\n"));
  153. if(getContainer() == NULL)
  154. {
  155. FWARNING(("OSBImageElement::write: Attempt to write NULL.\n"));
  156. return;
  157. }
  158. Image *img = dynamic_cast<Image *>(getContainer());
  159. BinaryWriteHandler *wh = editRoot()->getWriteHandler();
  160. const OSBRootElement *root = getRoot();
  161. UInt8 flags = 0;
  162. wh->putValue(getFCPtrType(getContainer()));
  163. wh->putValue(getVersion() );
  164. std::string excludeFields = "";
  165. bool compressTextures = false;
  166. if(getRoot()->getOptions().inlineTextures() == false)
  167. {
  168. // only write "name" field
  169. flags |= FlagPixelDataOutOfLine;
  170. excludeFields.append("'dimension' 'width' 'height' 'depth' 'bpp' "
  171. "'mipMapCount' 'frameCount' 'frameDelay' "
  172. "'pixelFormat' 'pixel' 'frameSize' " );
  173. }
  174. else
  175. {
  176. if(_hasJPEGSupport && root->getOptions().compressTextures() &&
  177. (img->getDataType() == Image::OSG_UINT8_IMAGEDATA) &&
  178. ((img->getBpp() == 1) || (img->getBpp() == 3)) )
  179. {
  180. compressTextures = true;
  181. flags |= FlagPixelDataCompressed;
  182. excludeFields.append("'pixel'");
  183. }
  184. }
  185. // write flags
  186. wh->putValue(flags);
  187. // write all fields that do not require special handling
  188. writeFields(excludeFields, false);
  189. if(compressTextures)
  190. writeCompressedPixelData();
  191. writeEndMarker();
  192. }
  193. /*-------------------------------------------------------------------------*/
  194. /* Reading Helper Functions */
  195. void
  196. OSBImageElement::readCompressedPixelData(void)
  197. {
  198. BinaryReadHandler *rh = editRoot()->getReadHandler();
  199. Image *img = dynamic_cast<Image *>(getContainer());
  200. std::string fieldTypeName;
  201. UInt32 fieldSize;
  202. UInt32 byteSize;
  203. std::vector<UInt8> buffer;
  204. rh->getValue(fieldTypeName);
  205. rh->getValue(fieldSize );
  206. if(!_hasJPEGSupport)
  207. {
  208. FWARNING(("OSBImageElement::readCompressedPixelData: "
  209. "JPEG Support not available, skipping compressed "
  210. "texture data.\n"));
  211. rh->skip(fieldSize);
  212. return;
  213. }
  214. rh->getValue(byteSize);
  215. // allocate and fill buffer
  216. buffer.resize(byteSize);
  217. rh->getValues(&buffer.front(), byteSize);
  218. img->restore(&buffer.front(), byteSize);
  219. }
  220. /*-------------------------------------------------------------------------*/
  221. /* Writing Helper Functions */
  222. void
  223. OSBImageElement::writeCompressedPixelData(void)
  224. {
  225. // FIXME Inline Images are disabled right now. A more recent versin of
  226. // the ImageFileHandler from CVS needs to be ported to OpenSG 2.
  227. const OSBRootElement *root = getRoot();
  228. BinaryWriteHandler *wh = editRoot()->getWriteHandler();
  229. Image *img = dynamic_cast<Image *>(getContainer());
  230. std::string imageType = root->getOptions().texturesImageType();
  231. // std::string imageType = "jpeg";
  232. std::vector<UInt8> buffer;
  233. UInt32 factor = 1;
  234. // JPEG always uses RGB, so single channel images need additional memory
  235. if((imageType == "jpeg") && (img->getBpp() == 1))
  236. factor = 3;
  237. // some extra space is needed for the image header
  238. UInt32 bufferSize =
  239. ImageFileHandler::the()->getDefaultType()->maxBufferSize(img) * factor +
  240. 16384;
  241. buffer.resize(bufferSize);
  242. UInt64 compressedSize = img->store(imageType.c_str(), &buffer.front());
  243. // UInt64 compressedSize = 0;
  244. UInt32 byteSize = static_cast<UInt32>(compressedSize);
  245. UInt32 fieldSize = sizeof(UInt32) + sizeof(UInt8) * byteSize;
  246. wh->putValue (fieldSize );
  247. wh->putValue (byteSize );
  248. wh->putValues(&buffer.front(), byteSize);
  249. }