PageRenderTime 77ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/System/Image/WS/OSGImage.cpp

https://github.com/msteners/OpenSGDevMaster_Toolbox
C++ | 4396 lines | 3567 code | 562 blank | 267 comment | 508 complexity | ff0725ce8aebf3f44e101061dc457d17 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause
  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. \*---------------------------------------------------------------------------*/
  38. #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
  39. #pragma GCC diagnostic warning "-Wsign-compare"
  40. #endif
  41. #ifdef WIN32
  42. #pragma warning( disable : 4018 )
  43. #endif
  44. //---------------------------------------------------------------------------
  45. // Includes
  46. //---------------------------------------------------------------------------
  47. #define OSG_COMPILEIMAGE
  48. #include <cstdlib>
  49. #include <cstdio>
  50. #include <algorithm>
  51. #include "OSGConfig.h"
  52. #include "OSGLog.h"
  53. #include "OSGImageGenericAtt.h"
  54. #include "OSGFieldContainerFields.h"
  55. #include "OSGFileSystem.h"
  56. #include "OSGImageFileHandler.h"
  57. #include "OSGSquish.h"
  58. /*
  59. #include "OSGPathHandler.h"
  60. #include "OSGSceneFileHandler.h"
  61. */
  62. #include "OSGImage.h"
  63. OSG_USING_NAMESPACE
  64. /*! \class OSG::Image
  65. 1D/2D/3D Image with various pixel types data, can also optional hold
  66. mipMap and simple multi-frame data.
  67. */
  68. /*------------------------------------------------------------------------*/
  69. /* static member */
  70. /*! Static dictionary to map pixelData values to the bytes per pixel
  71. (bpp) value.
  72. Internaly used in the createData() method.
  73. */
  74. UInt32 Image::_formatDic[][2] =
  75. {
  76. { OSG_A_PF, 1 },
  77. { OSG_I_PF, 1 },
  78. { OSG_L_PF, 1 },
  79. { OSG_LA_PF, 2 },
  80. { OSG_RGB_PF, 3 },
  81. { OSG_RGBA_PF, 4 },
  82. { OSG_BGR_PF, 3 },
  83. { OSG_BGRA_PF, 4 },
  84. { OSG_RGB_DXT1, 3 },
  85. { OSG_RGBA_DXT1, 4 },
  86. { OSG_RGBA_DXT3, 4 },
  87. { OSG_RGBA_DXT5, 4 },
  88. { OSG_ALPHA_INTEGER_PF, 1 },
  89. { OSG_RGB_INTEGER_PF, 3 },
  90. { OSG_RGBA_INTEGER_PF, 4 },
  91. { OSG_BGR_INTEGER_PF, 3 },
  92. { OSG_BGRA_INTEGER_PF, 4 },
  93. { OSG_LUMINANCE_INTEGER_PF, 1 },
  94. { OSG_LUMINANCE_ALPHA_INTEGER_PF, 2 }
  95. };
  96. Int32 Image::_typeDic[][2] =
  97. {
  98. { OSG_INVALID_IMAGEDATATYPE, 0 },
  99. { OSG_UINT8_IMAGEDATA, 1 },
  100. { OSG_UINT16_IMAGEDATA, 2 },
  101. { OSG_UINT32_IMAGEDATA, 4 },
  102. { OSG_FLOAT32_IMAGEDATA, 4 },
  103. { OSG_FLOAT16_IMAGEDATA, 2 },
  104. { OSG_INT16_IMAGEDATA, 2 },
  105. { OSG_INT32_IMAGEDATA, 4 }
  106. };
  107. /*----------------------------- class specific ----------------------------*/
  108. void Image::initMethod(InitPhase ePhase)
  109. {
  110. }
  111. /*! Inform parents, when image was changed
  112. */
  113. void Image::changed(ConstFieldMaskArg whichField,
  114. UInt32 origin,
  115. BitVector details)
  116. {
  117. const Image *pThis = this;
  118. MFParentFieldContainerPtr::const_iterator parentsIt =
  119. pThis->_mfParents.begin();
  120. MFParentFieldContainerPtr::const_iterator parentsEnd =
  121. pThis->_mfParents.end();
  122. while(parentsIt != parentsEnd)
  123. {
  124. (*parentsIt)->changed(
  125. TypeTraits<BitVector>::One << parentsIt.getParentFieldPos(),
  126. ChangedOrigin::Child,
  127. whichField);
  128. ++parentsIt;
  129. }
  130. if(0x0000 != (whichField & DataTypeFieldMask))
  131. {
  132. // Update internals
  133. Int32 mapSizeType = sizeof(_typeDic) / sizeof(UInt32[2]);
  134. UInt32 typeFormat = 0;
  135. Int32 i;
  136. for(i = 0; i < mapSizeType; i++)
  137. {
  138. if(_typeDic[i][0] == _sfDataType.getValue())
  139. {
  140. typeFormat = _typeDic[i][1];
  141. }
  142. }
  143. setComponentSize( typeFormat );
  144. }
  145. if(0x0000 != (whichField & (MipMapCountFieldMask |
  146. WidthFieldMask |
  147. HeightFieldMask |
  148. DepthFieldMask |
  149. PixelFormatFieldMask )))
  150. {
  151. setSideSize(calcMipmapSumSize(_sfMipMapCount.getValue()));
  152. }
  153. if(0x0000 != (whichField & (SideSizeFieldMask | SideCountFieldMask)))
  154. {
  155. setFrameSize(_sfSideSize.getValue() * _sfSideCount.getValue());
  156. }
  157. calcMipmapOffsets();
  158. Inherited::changed(whichField, origin, details);
  159. }
  160. /*----------------------------- output ------------------------------------*/
  161. void Image::dump( UInt32 ,
  162. const BitVector ) const
  163. {
  164. const Char8 *pfStr = "UNDEF_PIXEL_FORMAT";
  165. const Char8 *typeStr = "INVALID_IMAGEDATA_TYPE";
  166. switch(getPixelFormat())
  167. {
  168. case OSG_A_PF:
  169. pfStr = "ALPHA";
  170. break;
  171. case OSG_I_PF:
  172. pfStr = "INTENSITY";
  173. break;
  174. case OSG_L_PF:
  175. pfStr = "LUMINANCE";
  176. break;
  177. case OSG_LA_PF:
  178. pfStr = "LUMINANCE_ALPHA";
  179. break;
  180. case OSG_BGR_PF:
  181. pfStr = "BGR";
  182. break;
  183. case OSG_BGRA_PF:
  184. pfStr = "BGRA";
  185. break;
  186. case OSG_RGB_PF:
  187. pfStr = "RGB";
  188. break;
  189. case OSG_RGBA_PF:
  190. pfStr = "RGBA";
  191. break;
  192. case OSG_RGB_DXT1:
  193. pfStr = "RGB_DXT1";
  194. break;
  195. case OSG_RGBA_DXT1:
  196. pfStr = "RGBA_DXT1";
  197. break;
  198. case OSG_RGBA_DXT3:
  199. pfStr = "RGBA_DXT3";
  200. break;
  201. case OSG_RGBA_DXT5:
  202. pfStr = "RGBA_DXT5";
  203. break;
  204. case OSG_ALPHA_INTEGER_PF:
  205. pfStr = "ALPHA_INTEGER";
  206. break;
  207. case OSG_RGB_INTEGER_PF:
  208. pfStr = "RGB_INTEGER";
  209. break;
  210. case OSG_RGBA_INTEGER_PF:
  211. pfStr = "RGBA_INTEGER";
  212. break;
  213. case OSG_BGR_INTEGER_PF:
  214. pfStr = "BGR_INTEGER";
  215. break;
  216. case OSG_BGRA_INTEGER_PF:
  217. pfStr = "BGRA_INTEGER";
  218. break;
  219. case OSG_LUMINANCE_INTEGER_PF:
  220. pfStr = "LUMINANCE_INTEGER";
  221. break;
  222. case OSG_LUMINANCE_ALPHA_INTEGER_PF:
  223. pfStr = "LUMINANCE_ALPHA_INTEGER";
  224. break;
  225. default:
  226. pfStr = "UNKNOWN_PIXEL_FORMAT";
  227. break;
  228. };
  229. switch (getDataType())
  230. {
  231. case OSG_UINT8_IMAGEDATA:
  232. typeStr = "IMAGEDATA_TYPE UCHAR8";
  233. break;
  234. case OSG_UINT16_IMAGEDATA:
  235. typeStr = "IMAGEDATA_TYPE UCHAR16";
  236. break;
  237. case OSG_UINT32_IMAGEDATA:
  238. typeStr = "IMAGEDATA_TYPE UCHAR32";
  239. break;
  240. case OSG_FLOAT16_IMAGEDATA:
  241. typeStr = "IMAGEDATA_TYPE FLOAT16";
  242. break;
  243. case OSG_FLOAT32_IMAGEDATA:
  244. typeStr = "IMAGEDATA_TYPE FLOAT32";
  245. break;
  246. case OSG_INT16_IMAGEDATA:
  247. typeStr = "IMAGEDATA_TYPE INT16";
  248. break;
  249. case OSG_INT32_IMAGEDATA:
  250. typeStr = "IMAGEDATA_TYPE INT32";
  251. break;
  252. default:
  253. typeStr = "UNKNOWN_IMAGEDATA_TYPE";
  254. break;
  255. };
  256. FLOG (("ImageDump: %s; %d/%d/%d; #mm: %d, side %d, #frame: %d, "
  257. "frameDelay %g, dataType %s, size: %ld\n",
  258. pfStr,
  259. getWidth(),
  260. getHeight(),
  261. getDepth(),
  262. getMipMapCount(),
  263. getSideCount(),
  264. getFrameCount(),
  265. getFrameDelay(),
  266. typeStr,
  267. getSize()));
  268. }
  269. // Return the number of components per pixel.
  270. UInt8 Image::getComponents(void) const
  271. {
  272. UInt16 mapSizeFormat = sizeof(_formatDic) / sizeof(UInt32[2]);
  273. for(UInt16 i = 0; i < mapSizeFormat; i++)
  274. {
  275. if(_formatDic[i][0] == getPixelFormat())
  276. return _formatDic[i][1];
  277. }
  278. FWARNING(("Image::getComponents: image %p has unknown pixel format 0x%x!",
  279. this, getPixelFormat()));
  280. return 0;
  281. }
  282. /*------------------------------ set object data --------------------------*/
  283. /*! method to set the image data. Use the doCopy parameter to specify, whether
  284. the method should copy or link the pixel data.
  285. */
  286. bool Image::set( UInt32 pF,
  287. Int32 w,
  288. Int32 h,
  289. Int32 d,
  290. Int32 mmS,
  291. Int32 fS,
  292. Time fD,
  293. const UChar8 *da,
  294. Int32 t,
  295. bool allocMem,
  296. Int32 sS)
  297. {
  298. setPixelFormat(pF );
  299. setWidth (osgMax ( 1, w ));
  300. setHeight (osgMax ( 1, h ));
  301. setDepth (osgMax ( 1, d ));
  302. setMipMapCount(osgMax ( 1, mmS));
  303. setSideCount (osgMax ( 1, sS ));
  304. setFrameCount (osgMax ( 1, fS ));
  305. setFrameDelay (fD);
  306. setDataType (t );
  307. calcMipmapOffsets();
  308. return createData(da, allocMem);
  309. }
  310. /*! method to set the image from another image object.
  311. Use the doCopy parameter to specify, whether
  312. the method should copy or link the pixel data.
  313. */
  314. bool Image::set(Image *image)
  315. {
  316. this->set(image->getPixelFormat(),
  317. image->getWidth (),
  318. image->getHeight (),
  319. image->getDepth (),
  320. image->getMipMapCount(),
  321. image->getFrameCount (),
  322. image->getFrameDelay (),
  323. image->getData (),
  324. image->getDataType (),
  325. true,
  326. image->getSideCount ());
  327. return true;
  328. }
  329. /*! method to set only the image pixel data, all parameter (e. pixelFormat
  330. width,height and depth) stay the same
  331. */
  332. bool Image::setData(const UChar8 *da)
  333. {
  334. if(da)
  335. {
  336. createData(da);
  337. }
  338. else
  339. {
  340. FWARNING(("Image::setData(Null) call\n"));
  341. }
  342. return (da ? true : false);
  343. }
  344. void Image::clearData(void)
  345. {
  346. editMFPixel()->clear();
  347. }
  348. /*! method to update just a subregion of the image data
  349. all paramter (e. pixelFormat,width,height,depth) stay the same
  350. */
  351. bool Image::setSubData( Int32 offX,
  352. Int32 offY,
  353. Int32 offZ,
  354. Int32 srcW,
  355. Int32 srcH,
  356. Int32 srcD,
  357. const UInt8 *src )
  358. {
  359. UChar8 *dest = editData();
  360. UInt64 lineSize;
  361. FDEBUG(( "Image::setSubData (%d %d %d) - (%d %d %d) - src %p\n",
  362. offX, offY, offZ, srcW, srcH, srcD, src ));
  363. if (hasCompressedData())
  364. {
  365. FFATAL (("Invalid Image::setSubData for compressed image\n"));
  366. return false;
  367. }
  368. if(!src || !dest)
  369. {
  370. FFATAL(("Invalid data pointer in Image::setSubData\n"));
  371. return false;
  372. }
  373. // determine the area to actually copy
  374. UInt32 xMin = osgMax(0, offX);
  375. UInt32 yMin = osgMax(0, offY);
  376. UInt32 zMin = osgMax(0, offZ);
  377. UInt32 xMax = osgMin(getWidth (), offX + srcW);
  378. UInt32 yMax = osgMin(getHeight(), offY + srcH);
  379. UInt32 zMax = osgMin(getDepth (), offZ + srcD);
  380. // fill the destination buffer with the subdata
  381. UInt32 destIdx, srcIdx = 0;
  382. for(UInt32 z = zMin; z < zMax; z++)
  383. {
  384. for(UInt32 y = yMin; y < yMax; y++)
  385. {
  386. lineSize = (xMax - xMin) * getBpp();
  387. destIdx = ((z * getHeight() + y) * getWidth() + xMin) * getBpp();
  388. memcpy (&dest[destIdx], &src[srcIdx], size_t(lineSize));
  389. srcIdx += Int32((srcW - (xMax - xMin)) * getBpp() + lineSize);
  390. }
  391. srcIdx += (srcH - (yMax - yMin)) * srcW * getBpp();
  392. }
  393. return true;
  394. }
  395. /*! The Image is not just a 2D container. The class can hold 3D (volume)
  396. and movie data. If we have 3D/singleFrame or 2D/multiFrame data without
  397. mipmaps we can flip between this two formats by just swapping the
  398. getFrameCount() and getDepth() values.
  399. */
  400. bool Image::flipDepthFrameData(void)
  401. {
  402. bool retCode = false;
  403. Int32 value;
  404. if((getMipMapCount() == 1) &&
  405. ((getFrameCount() == 1) || (getDepth() == 1)))
  406. {
  407. value = getFrameCount();
  408. setFrameCount(getDepth());
  409. setDepth (value );
  410. retCode = true;
  411. }
  412. else
  413. {
  414. FWARNING (("Cant flipDepthFrameData(); invalid data layout\n"));
  415. }
  416. return retCode;
  417. }
  418. /*! This method is used by the parser to fill the image with
  419. string pixel data. It expects the data in VRML PixelTexture Format.
  420. */
  421. bool Image::addValue(const char *value)
  422. {
  423. static Image *currentImage = 0;
  424. static UChar8 *currentData = 0;
  425. Int64 j;
  426. Int64 v;
  427. bool isHead = strchr(value, ' ') ? true : false;
  428. if (hasCompressedData())
  429. {
  430. FFATAL (("Invalid Image::addValue for compressed image\n"));
  431. return false;
  432. }
  433. // make sure we only read one image at a time
  434. if(currentImage == this)
  435. {
  436. if(isHead)
  437. {
  438. FDEBUG(("Start new read cycle in image::addValue()\n"));
  439. }
  440. }
  441. else
  442. {
  443. if(!isHead)
  444. {
  445. FFATAL(("Additional image date for different image\n"));
  446. }
  447. }
  448. currentImage = this;
  449. if(isHead == true)
  450. {
  451. Int32 width;
  452. Int32 height;
  453. Int32 pixelDepth;
  454. PixelFormat pf = Image::OSG_INVALID_PF;
  455. // read the head
  456. sscanf(value, "%d %d %d", &width, &height, &pixelDepth);
  457. FDEBUG(("Image::addValue() set: w/h/bpp: %d/%d/%d\n",
  458. width, height, pixelDepth));
  459. switch(getDataType())
  460. {
  461. case OSG_UINT8_IMAGEDATA:
  462. switch(pixelDepth)
  463. {
  464. case 1:
  465. pf = OSG::Image::OSG_L_PF;
  466. break;
  467. case 2:
  468. pf = OSG::Image::OSG_LA_PF;
  469. break;
  470. case 3:
  471. pf = OSG::Image::OSG_RGB_PF;
  472. break;
  473. case 4:
  474. pf = OSG::Image::OSG_RGBA_PF;
  475. break;
  476. default:
  477. pf = OSG::Image::OSG_INVALID_PF;
  478. FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
  479. break;
  480. }
  481. break;
  482. case OSG_UINT16_IMAGEDATA:
  483. switch(pixelDepth)
  484. {
  485. case 2:
  486. pf = OSG::Image::OSG_L_PF;
  487. break;
  488. case 4:
  489. pf = OSG::Image::OSG_LA_PF;
  490. break;
  491. case 6:
  492. pf = OSG::Image::OSG_RGB_PF;
  493. break;
  494. case 8:
  495. pf = OSG::Image::OSG_RGBA_PF;
  496. break;
  497. default:
  498. pf = OSG::Image::OSG_INVALID_PF;
  499. FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
  500. break;
  501. }
  502. break;
  503. case OSG_UINT32_IMAGEDATA:
  504. switch(pixelDepth)
  505. {
  506. case 4:
  507. pf = OSG::Image::OSG_L_PF;
  508. break;
  509. case 8:
  510. pf = OSG::Image::OSG_LA_PF;
  511. break;
  512. case 12:
  513. pf = OSG::Image::OSG_RGB_PF;
  514. break;
  515. case 16:
  516. pf = OSG::Image::OSG_RGBA_PF;
  517. break;
  518. default:
  519. pf = OSG::Image::OSG_INVALID_PF;
  520. FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
  521. break;
  522. }
  523. break;
  524. case OSG_FLOAT32_IMAGEDATA:
  525. switch(pixelDepth)
  526. {
  527. case 4:
  528. pf = OSG::Image::OSG_L_PF;
  529. break;
  530. case 8:
  531. pf = OSG::Image::OSG_LA_PF;
  532. break;
  533. case 12:
  534. pf = OSG::Image::OSG_RGB_PF;
  535. break;
  536. case 16:
  537. pf = OSG::Image::OSG_RGBA_PF;
  538. break;
  539. default:
  540. pf = OSG::Image::OSG_INVALID_PF;
  541. FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
  542. break;
  543. }
  544. break;
  545. case OSG_FLOAT16_IMAGEDATA:
  546. switch(pixelDepth)
  547. {
  548. case 2:
  549. pf = OSG::Image::OSG_L_PF;
  550. break;
  551. case 4:
  552. pf = OSG::Image::OSG_LA_PF;
  553. break;
  554. case 6:
  555. pf = OSG::Image::OSG_RGB_PF;
  556. break;
  557. case 8:
  558. pf = OSG::Image::OSG_RGBA_PF;
  559. break;
  560. default:
  561. pf = OSG::Image::OSG_INVALID_PF;
  562. FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
  563. break;
  564. }
  565. break;
  566. case OSG_INT16_IMAGEDATA:
  567. case OSG_INT32_IMAGEDATA:
  568. {
  569. FFATAL((" 'addValue' NYI\n "));
  570. }
  571. break;
  572. default:
  573. setDataType(OSG_INVALID_IMAGEDATATYPE);
  574. FFATAL(("Invalid type of image data: %d\n", getDataType()));
  575. }
  576. if(pf != 0 && (width > 0) && (height > 0))
  577. {
  578. set(pf, width, height);
  579. currentData = editData();
  580. }
  581. else
  582. {
  583. currentData = NULL;
  584. }
  585. }
  586. else
  587. {
  588. if(currentData != NULL)
  589. {
  590. // add data
  591. // TODO; should we check the bounds, should be done by the parser
  592. v = strtoul(value, 0, strchr(value, 'x') ? 16 : 10);
  593. for(j = getBpp(); j--;)
  594. {
  595. *currentData++ = UChar8( (v >> (8 * j)) & 255 );
  596. }
  597. }
  598. }
  599. return currentData ? true : false;
  600. }
  601. /*! It is a simple method to reformat the image pixelFormat (not the size).
  602. So you can for example convert a RGBA to RGB or RGB to Grey image.
  603. */
  604. bool Image::reformat(const Image::PixelFormat pixelFormat,
  605. Image *destination,
  606. Int32 iCompressionFlags)
  607. {
  608. UChar8 *data = NULL;
  609. const UChar8 *sourceData = NULL;
  610. UInt32 srcI, destI, destSize = 0;
  611. UInt32 sum;
  612. Real64 sumReal;
  613. ImageUnrecPtr dest(destination);
  614. if (hasCompressedData())
  615. {
  616. FFATAL (("Invalid Image::reformat for compressed image\n"));
  617. return false;
  618. }
  619. if(destination == NULL)
  620. {
  621. dest = Image::create();
  622. }
  623. FINFO(("Try to reformat image from pixelDepth %d to %d\n",
  624. getPixelFormat(),
  625. pixelFormat ));
  626. if(iCompressionFlags == 0)
  627. {
  628. iCompressionFlags = (osgsquish::kColourMetricPerceptual |
  629. osgsquish::kColourRangeFit );
  630. }
  631. iCompressionFlags &= ~0x07;
  632. // TODO !!! code all the cases !!!
  633. if(getSize() != 0 &&
  634. pixelFormat != OSG_INVALID_PF &&
  635. (destination != 0 || (pixelFormat != static_cast<Image::PixelFormat>(getPixelFormat()))))
  636. {
  637. dest->set(pixelFormat,
  638. getWidth (),
  639. getHeight (),
  640. getDepth (),
  641. getMipMapCount(),
  642. getFrameCount (),
  643. getFrameDelay (),
  644. NULL,
  645. getDataType (),
  646. true,
  647. getSideCount ());
  648. sourceData = getData();
  649. data = dest->editData();
  650. destSize = dest->getSize();
  651. const UInt16 *sourceDataUC16 =
  652. reinterpret_cast<const UInt16 *>(sourceData);
  653. UInt16 *destDataUC16 = reinterpret_cast<UInt16 *>(data);
  654. const UInt32 *sourceDataUC32 =
  655. reinterpret_cast<const UInt32 *>(sourceData);
  656. UInt32 *destDataUC32 = reinterpret_cast<UInt32 *>(data);
  657. const Real32 *sourceDataF32 =
  658. reinterpret_cast<const Real32 *>(sourceData);
  659. Real32 *destDataF32 = reinterpret_cast<Real32 *>(data);
  660. const Real16 *sourceDataH16 =
  661. reinterpret_cast<const Real16 *>(sourceData);
  662. Real16 *destDataH16 = reinterpret_cast<Real16 *>(data);
  663. if(data)
  664. {
  665. switch (getPixelFormat())
  666. {
  667. //-----------------------------------------------------
  668. case OSG_A_PF:
  669. switch (pixelFormat)
  670. {
  671. case OSG_A_PF:
  672. case OSG_I_PF:
  673. case OSG_L_PF:
  674. switch (getDataType())
  675. {
  676. case OSG_UINT8_IMAGEDATA:
  677. case OSG_UINT16_IMAGEDATA:
  678. case OSG_UINT32_IMAGEDATA:
  679. case OSG_FLOAT32_IMAGEDATA:
  680. case OSG_FLOAT16_IMAGEDATA:
  681. memcpy (data, getData(), destSize);
  682. break;
  683. default:
  684. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  685. break;
  686. }
  687. break;
  688. case OSG_LA_PF:
  689. switch (getDataType())
  690. {
  691. case OSG_UINT8_IMAGEDATA:
  692. for (srcI = destI = 0; destI < destSize;)
  693. {
  694. data[destI++] = sourceData[srcI];
  695. data[destI++] = sourceData[srcI++];
  696. }
  697. break;
  698. case OSG_UINT16_IMAGEDATA:
  699. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  700. {
  701. destDataUC16[destI++] = sourceDataUC16[srcI];
  702. destDataUC16[destI++] = sourceDataUC16[srcI++];
  703. }
  704. break;
  705. case OSG_UINT32_IMAGEDATA:
  706. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  707. {
  708. destDataUC32[destI++] = sourceDataUC32[srcI];
  709. destDataUC32[destI++] = sourceDataUC32[srcI++];
  710. }
  711. break;
  712. case OSG_FLOAT32_IMAGEDATA:
  713. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  714. {
  715. destDataF32[destI++] = sourceDataF32[srcI];
  716. destDataF32[destI++] = sourceDataF32[srcI++];
  717. }
  718. break;
  719. case OSG_FLOAT16_IMAGEDATA:
  720. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  721. {
  722. destDataH16[destI++] = sourceDataH16[srcI];
  723. destDataH16[destI++] = sourceDataH16[srcI++];
  724. }
  725. break;
  726. default:
  727. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  728. break;
  729. }
  730. break;
  731. case OSG_RGB_PF:
  732. switch (getDataType())
  733. {
  734. case OSG_UINT8_IMAGEDATA:
  735. for (srcI = destI = 0; destI < destSize;)
  736. {
  737. data[destI++] = sourceData[srcI];
  738. data[destI++] = sourceData[srcI];
  739. data[destI++] = sourceData[srcI++];
  740. }
  741. break;
  742. case OSG_UINT16_IMAGEDATA:
  743. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  744. {
  745. destDataUC16[destI++] = sourceDataUC16[srcI];
  746. destDataUC16[destI++] = sourceDataUC16[srcI];
  747. destDataUC16[destI++] = sourceDataUC16[srcI++];
  748. }
  749. break;
  750. case OSG_UINT32_IMAGEDATA:
  751. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  752. {
  753. destDataUC32[destI++] = sourceDataUC32[srcI];
  754. destDataUC32[destI++] = sourceDataUC32[srcI];
  755. destDataUC32[destI++] = sourceDataUC32[srcI++];
  756. }
  757. break;
  758. case OSG_FLOAT32_IMAGEDATA:
  759. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  760. {
  761. destDataF32[destI++] = sourceDataF32[srcI];
  762. destDataF32[destI++] = sourceDataF32[srcI];
  763. destDataF32[destI++] = sourceDataF32[srcI++];
  764. }
  765. break;
  766. case OSG_FLOAT16_IMAGEDATA:
  767. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  768. {
  769. destDataH16[destI++] = sourceDataH16[srcI];
  770. destDataH16[destI++] = sourceDataH16[srcI];
  771. destDataH16[destI++] = sourceDataH16[srcI++];
  772. }
  773. break;
  774. default:
  775. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  776. break;
  777. }
  778. break;
  779. case OSG_RGBA_PF:
  780. switch (getDataType())
  781. {
  782. case OSG_UINT8_IMAGEDATA:
  783. for (srcI = destI = 0; destI < destSize;)
  784. {
  785. data[destI++] = sourceData[srcI];
  786. data[destI++] = sourceData[srcI];
  787. data[destI++] = sourceData[srcI];
  788. data[destI++] = sourceData[srcI++];
  789. }
  790. break;
  791. case OSG_UINT16_IMAGEDATA:
  792. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  793. {
  794. destDataUC16[destI++] = sourceDataUC16[srcI];
  795. destDataUC16[destI++] = sourceDataUC16[srcI];
  796. destDataUC16[destI++] = sourceDataUC16[srcI];
  797. destDataUC16[destI++] = sourceDataUC16[srcI++];
  798. }
  799. break;
  800. case OSG_UINT32_IMAGEDATA:
  801. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  802. {
  803. destDataUC32[destI++] = sourceDataUC32[srcI];
  804. destDataUC32[destI++] = sourceDataUC32[srcI];
  805. destDataUC32[destI++] = sourceDataUC32[srcI];
  806. destDataUC32[destI++] = sourceDataUC32[srcI++];
  807. }
  808. break;
  809. case OSG_FLOAT32_IMAGEDATA:
  810. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  811. {
  812. destDataF32[destI++] = sourceDataF32[srcI];
  813. destDataF32[destI++] = sourceDataF32[srcI];
  814. destDataF32[destI++] = sourceDataF32[srcI];
  815. destDataF32[destI++] = sourceDataF32[srcI++];
  816. }
  817. break;
  818. case OSG_FLOAT16_IMAGEDATA:
  819. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  820. {
  821. destDataH16[destI++] = sourceDataH16[srcI];
  822. destDataH16[destI++] = sourceDataH16[srcI];
  823. destDataH16[destI++] = sourceDataH16[srcI];
  824. destDataH16[destI++] = sourceDataH16[srcI++];
  825. }
  826. break;
  827. default:
  828. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  829. break;
  830. }
  831. break;
  832. default:
  833. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  834. break;
  835. }
  836. break;
  837. //-----------------------------------------------------
  838. case OSG_I_PF:
  839. switch (pixelFormat)
  840. {
  841. case OSG_A_PF:
  842. case OSG_I_PF:
  843. case OSG_L_PF:
  844. switch (getDataType())
  845. {
  846. case OSG_UINT8_IMAGEDATA:
  847. memcpy (data, getData(), destSize);
  848. break;
  849. case OSG_UINT16_IMAGEDATA:
  850. memcpy (data, getData(), destSize);
  851. break;
  852. case OSG_UINT32_IMAGEDATA:
  853. memcpy (data, getData(), destSize);
  854. break;
  855. case OSG_FLOAT32_IMAGEDATA:
  856. memcpy (data, getData(), destSize);
  857. break;
  858. case OSG_FLOAT16_IMAGEDATA:
  859. memcpy (data, getData(), destSize);
  860. break;
  861. default:
  862. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  863. break;
  864. }
  865. break;
  866. case OSG_LA_PF:
  867. switch (getDataType())
  868. {
  869. case OSG_UINT8_IMAGEDATA:
  870. for (srcI = destI = 0; destI < destSize;)
  871. {
  872. data[destI++] = sourceData[srcI];
  873. data[destI++] = sourceData[srcI++];
  874. }
  875. break;
  876. case OSG_UINT16_IMAGEDATA:
  877. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  878. {
  879. destDataUC16[destI++] = sourceDataUC16[srcI];
  880. destDataUC16[destI++] = sourceDataUC16[srcI++];
  881. }
  882. break;
  883. case OSG_UINT32_IMAGEDATA:
  884. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  885. {
  886. destDataUC32[destI++] = sourceDataUC32[srcI];
  887. destDataUC32[destI++] = sourceDataUC32[srcI++];
  888. }
  889. break;
  890. case OSG_FLOAT32_IMAGEDATA:
  891. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  892. {
  893. destDataF32[destI++] = sourceDataF32[srcI];
  894. destDataF32[destI++] = sourceDataF32[srcI++];
  895. }
  896. break;
  897. case OSG_FLOAT16_IMAGEDATA:
  898. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  899. {
  900. destDataH16[destI++] = sourceDataH16[srcI];
  901. destDataH16[destI++] = sourceDataH16[srcI++];
  902. }
  903. break;
  904. default:
  905. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  906. break;
  907. }
  908. break;
  909. case OSG_RGB_PF:
  910. switch (getDataType())
  911. {
  912. case OSG_UINT8_IMAGEDATA:
  913. for (srcI = destI = 0; destI < destSize;)
  914. {
  915. data[destI++] = sourceData[srcI];
  916. data[destI++] = sourceData[srcI];
  917. data[destI++] = sourceData[srcI++];
  918. }
  919. break;
  920. case OSG_UINT16_IMAGEDATA:
  921. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  922. {
  923. destDataUC16[destI++] = sourceDataUC16[srcI];
  924. destDataUC16[destI++] = sourceDataUC16[srcI];
  925. destDataUC16[destI++] = sourceDataUC16[srcI++];
  926. }
  927. break;
  928. case OSG_UINT32_IMAGEDATA:
  929. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  930. {
  931. destDataUC32[destI++] = sourceDataUC32[srcI];
  932. destDataUC32[destI++] = sourceDataUC32[srcI];
  933. destDataUC32[destI++] = sourceDataUC32[srcI++];
  934. }
  935. break;
  936. case OSG_FLOAT32_IMAGEDATA:
  937. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  938. {
  939. destDataF32[destI++] = sourceDataF32[srcI];
  940. destDataF32[destI++] = sourceDataF32[srcI];
  941. destDataF32[destI++] = sourceDataF32[srcI++];
  942. }
  943. break;
  944. case OSG_FLOAT16_IMAGEDATA:
  945. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  946. {
  947. destDataH16[destI++] = sourceDataH16[srcI];
  948. destDataH16[destI++] = sourceDataH16[srcI];
  949. destDataH16[destI++] = sourceDataH16[srcI++];
  950. }
  951. break;
  952. default:
  953. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  954. break;
  955. }
  956. break;
  957. case OSG_RGBA_PF:
  958. switch (getDataType())
  959. {
  960. case OSG_UINT8_IMAGEDATA:
  961. for (srcI = destI = 0; destI < destSize;)
  962. {
  963. data[destI++] = sourceData[srcI];
  964. data[destI++] = sourceData[srcI];
  965. data[destI++] = sourceData[srcI];
  966. data[destI++] = sourceData[srcI++];
  967. }
  968. break;
  969. case OSG_UINT16_IMAGEDATA:
  970. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  971. {
  972. destDataUC16[destI++] = sourceDataUC16[srcI];
  973. destDataUC16[destI++] = sourceDataUC16[srcI];
  974. destDataUC16[destI++] = sourceDataUC16[srcI];
  975. destDataUC16[destI++] = sourceDataUC16[srcI++];
  976. }
  977. break;
  978. case OSG_UINT32_IMAGEDATA:
  979. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  980. {
  981. destDataUC32[destI++] = sourceDataUC32[srcI];
  982. destDataUC32[destI++] = sourceDataUC32[srcI];
  983. destDataUC32[destI++] = sourceDataUC32[srcI];
  984. destDataUC32[destI++] = sourceDataUC32[srcI++];
  985. }
  986. break;
  987. case OSG_FLOAT32_IMAGEDATA:
  988. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  989. {
  990. destDataF32[destI++] = sourceDataF32[srcI];
  991. destDataF32[destI++] = sourceDataF32[srcI];
  992. destDataF32[destI++] = sourceDataF32[srcI];
  993. destDataF32[destI++] = sourceDataF32[srcI++];
  994. }
  995. break;
  996. case OSG_FLOAT16_IMAGEDATA:
  997. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  998. {
  999. destDataH16[destI++] = sourceDataH16[srcI];
  1000. destDataH16[destI++] = sourceDataH16[srcI];
  1001. destDataH16[destI++] = sourceDataH16[srcI];
  1002. destDataH16[destI++] = sourceDataH16[srcI++];
  1003. }
  1004. break;
  1005. default:
  1006. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1007. break;
  1008. }
  1009. break;
  1010. default:
  1011. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1012. break;
  1013. }
  1014. break;
  1015. //-----------------------------------------------------
  1016. case OSG_L_PF:
  1017. switch (pixelFormat)
  1018. {
  1019. case OSG_A_PF:
  1020. case OSG_I_PF:
  1021. case OSG_L_PF:
  1022. switch (getDataType())
  1023. {
  1024. case OSG_UINT8_IMAGEDATA:
  1025. memcpy (data, getData(), destSize);
  1026. break;
  1027. case OSG_UINT16_IMAGEDATA:
  1028. memcpy (data, getData(), destSize);
  1029. break;
  1030. case OSG_UINT32_IMAGEDATA:
  1031. memcpy (data, getData(), destSize);
  1032. break;
  1033. case OSG_FLOAT32_IMAGEDATA:
  1034. memcpy (data, getData(), destSize);
  1035. break;
  1036. case OSG_FLOAT16_IMAGEDATA:
  1037. memcpy (data, getData(), destSize);
  1038. break;
  1039. default:
  1040. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1041. break;
  1042. }
  1043. break;
  1044. case OSG_LA_PF:
  1045. switch (getDataType())
  1046. {
  1047. case OSG_UINT8_IMAGEDATA:
  1048. for (srcI = destI = 0; destI < destSize;)
  1049. {
  1050. data[destI++] = sourceData[srcI];
  1051. data[destI++] = sourceData[srcI++];
  1052. }
  1053. break;
  1054. case OSG_UINT16_IMAGEDATA:
  1055. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1056. {
  1057. destDataUC16[destI++] = sourceDataUC16[srcI];
  1058. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1059. }
  1060. break;
  1061. case OSG_UINT32_IMAGEDATA:
  1062. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1063. {
  1064. destDataUC32[destI++] = sourceDataUC32[srcI];
  1065. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1066. }
  1067. break;
  1068. case OSG_FLOAT32_IMAGEDATA:
  1069. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1070. {
  1071. destDataF32[destI++] = sourceDataF32[srcI];
  1072. destDataF32[destI++] = sourceDataF32[srcI++];
  1073. }
  1074. break;
  1075. case OSG_FLOAT16_IMAGEDATA:
  1076. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1077. {
  1078. destDataH16[destI++] = sourceDataH16[srcI];
  1079. destDataH16[destI++] = sourceDataH16[srcI++];
  1080. }
  1081. break;
  1082. default:
  1083. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1084. break;
  1085. }
  1086. break;
  1087. case OSG_RGB_PF:
  1088. switch (getDataType())
  1089. {
  1090. case OSG_UINT8_IMAGEDATA:
  1091. for (srcI = destI = 0; destI < destSize;)
  1092. {
  1093. data[destI++] = sourceData[srcI];
  1094. data[destI++] = sourceData[srcI];
  1095. data[destI++] = sourceData[srcI++];
  1096. }
  1097. break;
  1098. case OSG_UINT16_IMAGEDATA:
  1099. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1100. {
  1101. destDataUC16[destI++] = sourceDataUC16[srcI];
  1102. destDataUC16[destI++] = sourceDataUC16[srcI];
  1103. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1104. }
  1105. break;
  1106. case OSG_UINT32_IMAGEDATA:
  1107. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1108. {
  1109. destDataUC32[destI++] = sourceDataUC32[srcI];
  1110. destDataUC32[destI++] = sourceDataUC32[srcI];
  1111. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1112. }
  1113. break;
  1114. case OSG_FLOAT32_IMAGEDATA:
  1115. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1116. {
  1117. destDataF32[destI++] = sourceDataF32[srcI];
  1118. destDataF32[destI++] = sourceDataF32[srcI];
  1119. destDataF32[destI++] = sourceDataF32[srcI++];
  1120. }
  1121. break;
  1122. case OSG_FLOAT16_IMAGEDATA:
  1123. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1124. {
  1125. destDataH16[destI++] = sourceDataH16[srcI];
  1126. destDataH16[destI++] = sourceDataH16[srcI];
  1127. destDataH16[destI++] = sourceDataH16[srcI++];
  1128. }
  1129. break;
  1130. default:
  1131. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1132. break;
  1133. }
  1134. break;
  1135. case OSG_RGBA_PF:
  1136. switch (getDataType())
  1137. {
  1138. case OSG_UINT8_IMAGEDATA:
  1139. for (srcI = destI = 0; destI < destSize;)
  1140. {
  1141. data[destI++] = sourceData[srcI];
  1142. data[destI++] = sourceData[srcI];
  1143. data[destI++] = sourceData[srcI];
  1144. data[destI++] = sourceData[srcI++];
  1145. }
  1146. break;
  1147. case OSG_UINT16_IMAGEDATA:
  1148. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1149. {
  1150. destDataUC16[destI++] = sourceDataUC16[srcI];
  1151. destDataUC16[destI++] = sourceDataUC16[srcI];
  1152. destDataUC16[destI++] = sourceDataUC16[srcI];
  1153. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1154. }
  1155. break;
  1156. case OSG_UINT32_IMAGEDATA:
  1157. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1158. {
  1159. destDataUC32[destI++] = sourceDataUC32[srcI];
  1160. destDataUC32[destI++] = sourceDataUC32[srcI];
  1161. destDataUC32[destI++] = sourceDataUC32[srcI];
  1162. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1163. }
  1164. break;
  1165. case OSG_FLOAT32_IMAGEDATA:
  1166. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1167. {
  1168. destDataF32[destI++] = sourceDataF32[srcI];
  1169. destDataF32[destI++] = sourceDataF32[srcI];
  1170. destDataF32[destI++] = sourceDataF32[srcI];
  1171. destDataF32[destI++] = sourceDataF32[srcI++];
  1172. }
  1173. break;
  1174. case OSG_FLOAT16_IMAGEDATA:
  1175. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1176. {
  1177. destDataH16[destI++] = sourceDataH16[srcI];
  1178. destDataH16[destI++] = sourceDataH16[srcI];
  1179. destDataH16[destI++] = sourceDataH16[srcI];
  1180. destDataH16[destI++] = sourceDataH16[srcI++];
  1181. }
  1182. break;
  1183. default:
  1184. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1185. break;
  1186. }
  1187. break;
  1188. default:
  1189. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1190. break;
  1191. }
  1192. break;
  1193. //-----------------------------------------------------
  1194. case OSG_LA_PF:
  1195. switch (pixelFormat)
  1196. {
  1197. case OSG_A_PF:
  1198. switch (getDataType())
  1199. {
  1200. case OSG_UINT8_IMAGEDATA:
  1201. for (srcI = destI = 0; destI < destSize;)
  1202. {
  1203. srcI++;
  1204. data[destI++] = sourceData[srcI++];
  1205. }
  1206. break;
  1207. case OSG_UINT16_IMAGEDATA:
  1208. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1209. {
  1210. srcI++;
  1211. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1212. }
  1213. break;
  1214. case OSG_UINT32_IMAGEDATA:
  1215. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1216. {
  1217. srcI++;
  1218. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1219. }
  1220. break;
  1221. case OSG_FLOAT32_IMAGEDATA:
  1222. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1223. {
  1224. srcI++;
  1225. destDataF32[destI++] = sourceDataF32[srcI++];
  1226. }
  1227. break;
  1228. case OSG_FLOAT16_IMAGEDATA:
  1229. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1230. {
  1231. srcI++;
  1232. destDataH16[destI++] = sourceDataH16[srcI++];
  1233. }
  1234. break;
  1235. default:
  1236. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1237. break;
  1238. }
  1239. break;
  1240. case OSG_I_PF:
  1241. case OSG_L_PF:
  1242. switch (getDataType())
  1243. {
  1244. case OSG_UINT8_IMAGEDATA:
  1245. for (srcI = destI = 0; destI < destSize;)
  1246. {
  1247. data[destI++] = sourceData[srcI++];
  1248. srcI++;
  1249. }
  1250. break;
  1251. case OSG_UINT16_IMAGEDATA:
  1252. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1253. {
  1254. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1255. srcI++;
  1256. }
  1257. break;
  1258. case OSG_UINT32_IMAGEDATA:
  1259. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1260. {
  1261. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1262. srcI++;
  1263. }
  1264. break;
  1265. case OSG_FLOAT32_IMAGEDATA:
  1266. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1267. {
  1268. destDataF32[destI++] = sourceDataF32[srcI++];
  1269. srcI++;
  1270. }
  1271. break;
  1272. case OSG_FLOAT16_IMAGEDATA:
  1273. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1274. {
  1275. destDataH16[destI++] = sourceDataH16[srcI++];
  1276. srcI++;
  1277. }
  1278. break;
  1279. default:
  1280. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1281. break;
  1282. }
  1283. break;
  1284. case OSG_LA_PF:
  1285. switch (getDataType())
  1286. {
  1287. case OSG_UINT8_IMAGEDATA:
  1288. memcpy (data, getData(), destSize);
  1289. break;
  1290. case OSG_UINT16_IMAGEDATA:
  1291. memcpy (data, getData(), destSize);
  1292. break;
  1293. case OSG_UINT32_IMAGEDATA:
  1294. memcpy (data, getData(), destSize);
  1295. break;
  1296. case OSG_FLOAT32_IMAGEDATA:
  1297. memcpy (data, getData(), destSize);
  1298. break;
  1299. case OSG_FLOAT16_IMAGEDATA:
  1300. memcpy (data, getData(), destSize);
  1301. break;
  1302. default:
  1303. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1304. break;
  1305. }
  1306. break;
  1307. case OSG_RGB_PF:
  1308. switch (getDataType())
  1309. {
  1310. case OSG_UINT8_IMAGEDATA:
  1311. for (srcI = destI = 0; destI < destSize;)
  1312. {
  1313. data[destI++] = sourceData[srcI];
  1314. data[destI++] = sourceData[srcI];
  1315. data[destI++] = sourceData[srcI++];
  1316. srcI++;
  1317. }
  1318. break;
  1319. case OSG_UINT16_IMAGEDATA:
  1320. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1321. {
  1322. destDataUC16[destI++] = sourceDataUC16[srcI];
  1323. destDataUC16[destI++] = sourceDataUC16[srcI];
  1324. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1325. srcI++;
  1326. }
  1327. break;
  1328. case OSG_UINT32_IMAGEDATA:
  1329. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1330. {
  1331. destDataUC32[destI++] = sourceDataUC32[srcI];
  1332. destDataUC32[destI++] = sourceDataUC32[srcI];
  1333. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1334. srcI++;
  1335. }
  1336. break;
  1337. case OSG_FLOAT32_IMAGEDATA:
  1338. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1339. {
  1340. destDataF32[destI++] = sourceDataF32[srcI];
  1341. destDataF32[destI++] = sourceDataF32[srcI];
  1342. destDataF32[destI++] = sourceDataF32[srcI++];
  1343. srcI++;
  1344. }
  1345. break;
  1346. case OSG_FLOAT16_IMAGEDATA:
  1347. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1348. {
  1349. destDataH16[destI++] = sourceDataH16[srcI];
  1350. destDataH16[destI++] = sourceDataH16[srcI];
  1351. destDataH16[destI++] = sourceDataH16[srcI++];
  1352. srcI++;
  1353. }
  1354. break;
  1355. default:
  1356. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1357. break;
  1358. }
  1359. break;
  1360. case OSG_RGBA_PF:
  1361. switch (getDataType())
  1362. {
  1363. case OSG_UINT8_IMAGEDATA:
  1364. for (srcI = destI = 0; destI < destSize;)
  1365. {
  1366. data[destI++] = sourceData[srcI];
  1367. data[destI++] = sourceData[srcI];
  1368. data[destI++] = sourceData[srcI++];
  1369. data[destI++] = sourceData[srcI++];
  1370. }
  1371. break;
  1372. case OSG_UINT16_IMAGEDATA:
  1373. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1374. {
  1375. destDataUC16[destI++] = sourceDataUC16[srcI];
  1376. destDataUC16[destI++] = sourceDataUC16[srcI];
  1377. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1378. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1379. }
  1380. break;
  1381. case OSG_UINT32_IMAGEDATA:
  1382. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1383. {
  1384. destDataUC32[destI++] = sourceDataUC32[srcI];
  1385. destDataUC32[destI++] = sourceDataUC32[srcI];
  1386. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1387. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1388. }
  1389. break;
  1390. case OSG_FLOAT32_IMAGEDATA:
  1391. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1392. {
  1393. destDataF32[destI++] = sourceDataF32[srcI];
  1394. destDataF32[destI++] = sourceDataF32[srcI];
  1395. destDataF32[destI++] = sourceDataF32[srcI++];
  1396. destDataF32[destI++] = sourceDataF32[srcI++];
  1397. }
  1398. break;
  1399. case OSG_FLOAT16_IMAGEDATA:
  1400. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1401. {
  1402. destDataH16[destI++] = sourceDataH16[srcI];
  1403. destDataH16[destI++] = sourceDataH16[srcI];
  1404. destDataH16[destI++] = sourceDataH16[srcI++];
  1405. destDataH16[destI++] = sourceDataH16[srcI++];
  1406. }
  1407. break;
  1408. default:
  1409. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1410. break;
  1411. }
  1412. break;
  1413. default:
  1414. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  1415. break;
  1416. }
  1417. break;
  1418. //-----------------------------------------------------
  1419. case OSG_RGB_PF:
  1420. switch (pixelFormat)
  1421. {
  1422. case OSG_A_PF:
  1423. case OSG_I_PF:
  1424. case OSG_L_PF:
  1425. switch (getDataType())
  1426. {
  1427. case OSG_UINT8_IMAGEDATA:
  1428. for (srcI = destI = 0; destI < destSize;)
  1429. {
  1430. sum = 0;
  1431. sum += sourceData[srcI++];
  1432. sum += sourceData[srcI++];
  1433. sum += sourceData[srcI++];
  1434. data[destI++] = sum / 3;
  1435. }
  1436. break;
  1437. case OSG_UINT16_IMAGEDATA:
  1438. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1439. {
  1440. sum = 0;
  1441. sum += sourceDataUC16[srcI++];
  1442. sum += sourceDataUC16[srcI++];
  1443. sum += sourceDataUC16[srcI++];
  1444. destDataUC16[destI++] = sum / 3;
  1445. }
  1446. break;
  1447. case OSG_UINT32_IMAGEDATA:
  1448. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1449. {
  1450. sum = 0;
  1451. sum += sourceDataUC32[srcI++];
  1452. sum += sourceDataUC32[srcI++];
  1453. sum += sourceDataUC32[srcI++];
  1454. destDataUC32[destI++] = sum / 3;
  1455. }
  1456. break;
  1457. case OSG_FLOAT32_IMAGEDATA:
  1458. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1459. {
  1460. sumReal = 0;
  1461. sumReal += sourceDataF32[srcI++];
  1462. sumReal += sourceDataF32[srcI++];
  1463. sumReal += sourceDataF32[srcI++];
  1464. destDataF32[destI++] = sumReal / 3.0;
  1465. }
  1466. break;
  1467. case OSG_FLOAT16_IMAGEDATA:
  1468. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1469. {
  1470. sumReal = 0;
  1471. sumReal += sourceDataH16[srcI++];
  1472. sumReal += sourceDataH16[srcI++];
  1473. sumReal += sourceDataH16[srcI++];
  1474. destDataH16[destI++] = sumReal / 3.0;
  1475. }
  1476. break;
  1477. default:
  1478. FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
  1479. break;
  1480. }
  1481. break;
  1482. case OSG_LA_PF:
  1483. switch (getDataType())
  1484. {
  1485. case OSG_UINT8_IMAGEDATA:
  1486. for (srcI = destI = 0; destI < destSize;)
  1487. {
  1488. sum = 0;
  1489. sum += sourceData[srcI++];
  1490. sum += sourceData[srcI++];
  1491. sum += sourceData[srcI++];
  1492. data[destI++] = sum / 3;
  1493. data[destI++] = sum / 3;
  1494. }
  1495. break;
  1496. case OSG_UINT16_IMAGEDATA:
  1497. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1498. {
  1499. sum = 0;
  1500. sum += sourceDataUC16[srcI++];
  1501. sum += sourceDataUC16[srcI++];
  1502. sum += sourceDataUC16[srcI++];
  1503. destDataUC16[destI++] = sum / 3;
  1504. destDataUC16[destI++] = sum / 3;
  1505. }
  1506. break;
  1507. case OSG_UINT32_IMAGEDATA:
  1508. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1509. {
  1510. sum = 0;
  1511. sum += sourceDataUC32[srcI++];
  1512. sum += sourceDataUC32[srcI++];
  1513. sum += sourceDataUC32[srcI++];
  1514. destDataUC32[destI++] = sum / 3;
  1515. destDataUC32[destI++] = sum / 3;
  1516. }
  1517. break;
  1518. case OSG_FLOAT32_IMAGEDATA:
  1519. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1520. {
  1521. sumReal = 0;
  1522. sumReal += sourceDataF32[srcI++];
  1523. sumReal += sourceDataF32[srcI++];
  1524. sumReal += sourceDataF32[srcI++];
  1525. destDataF32[destI++] = sumReal / 3.0;
  1526. destDataF32[destI++] = sumReal / 3.0;
  1527. }
  1528. break;
  1529. case OSG_FLOAT16_IMAGEDATA:
  1530. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1531. {
  1532. sumReal = 0;
  1533. sumReal += sourceDataH16[srcI++];
  1534. sumReal += sourceDataH16[srcI++];
  1535. sumReal += sourceDataH16[srcI++];
  1536. destDataH16[destI++] = sumReal / 3.0;
  1537. destDataH16[destI++] = sumReal / 3.0;
  1538. }
  1539. break;
  1540. default:
  1541. FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
  1542. break;
  1543. }
  1544. break;
  1545. case OSG_RGB_PF:
  1546. switch (getDataType())
  1547. {
  1548. case OSG_UINT8_IMAGEDATA:
  1549. memcpy (data, getData(), destSize);
  1550. break;
  1551. case OSG_UINT16_IMAGEDATA:
  1552. memcpy (data, getData(), destSize);
  1553. break;
  1554. case OSG_UINT32_IMAGEDATA:
  1555. memcpy (data, getData(), destSize);
  1556. break;
  1557. case OSG_FLOAT32_IMAGEDATA:
  1558. memcpy (data, getData(), destSize);
  1559. break;
  1560. case OSG_FLOAT16_IMAGEDATA:
  1561. memcpy (data, getData(), destSize);
  1562. break;
  1563. default:
  1564. FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
  1565. break;
  1566. }
  1567. break;
  1568. case OSG_RGBA_PF:
  1569. switch (getDataType())
  1570. {
  1571. case OSG_UINT8_IMAGEDATA:
  1572. for (srcI = destI = 0; destI < destSize;)
  1573. {
  1574. sum = 0;
  1575. sum += data[destI++] = sourceData[srcI++];
  1576. sum += data[destI++] = sourceData[srcI++];
  1577. sum += data[destI++] = sourceData[srcI++];
  1578. data[destI++] = sum / 3;
  1579. }
  1580. break;
  1581. case OSG_UINT16_IMAGEDATA:
  1582. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1583. {
  1584. sum = 0;
  1585. sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
  1586. sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
  1587. sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
  1588. destDataUC16[destI++] = sum / 3;
  1589. }
  1590. break;
  1591. case OSG_UINT32_IMAGEDATA:
  1592. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1593. {
  1594. sum = 0;
  1595. sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
  1596. sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
  1597. sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
  1598. destDataUC32[destI++] = sum / 3;
  1599. }
  1600. break;
  1601. case OSG_FLOAT32_IMAGEDATA:
  1602. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1603. {
  1604. sumReal = 0;
  1605. sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
  1606. sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
  1607. sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
  1608. destDataF32[destI++] = sumReal / 3.0;
  1609. }
  1610. break;
  1611. case OSG_FLOAT16_IMAGEDATA:
  1612. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1613. {
  1614. sumReal = 0;
  1615. sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
  1616. sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
  1617. sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
  1618. destDataH16[destI++] = sumReal / 3.0;
  1619. }
  1620. break;
  1621. default:
  1622. FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
  1623. break;
  1624. }
  1625. break;
  1626. #if defined(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
  1627. case OSG_RGB_DXT1:
  1628. {
  1629. iCompressionFlags |= osgsquish::kDxt1;
  1630. #ifdef OSG_DEBUG
  1631. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1632. getHeight(),
  1633. iCompressionFlags);
  1634. OSG_ASSERT(iStorage == destSize);
  1635. #endif
  1636. osgsquish::CompressImage(sourceData,
  1637. 255,
  1638. getWidth (),
  1639. getHeight(),
  1640. data,
  1641. iCompressionFlags);
  1642. }
  1643. break;
  1644. #endif
  1645. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
  1646. case OSG_RGBA_DXT1:
  1647. {
  1648. iCompressionFlags |= osgsquish::kDxt1;
  1649. #ifdef OSG_DEBUG
  1650. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1651. getHeight(),
  1652. iCompressionFlags);
  1653. OSG_ASSERT(iStorage == destSize);
  1654. #endif
  1655. osgsquish::CompressImage(sourceData,
  1656. 255,
  1657. getWidth (),
  1658. getHeight(),
  1659. data,
  1660. iCompressionFlags);
  1661. }
  1662. break;
  1663. #endif
  1664. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
  1665. case OSG_RGBA_DXT3:
  1666. {
  1667. iCompressionFlags |= osgsquish::kDxt3;
  1668. #ifdef OSG_DEBUG
  1669. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1670. getHeight(),
  1671. iCompressionFlags);
  1672. OSG_ASSERT(iStorage == destSize);
  1673. #endif
  1674. osgsquish::CompressImage(sourceData,
  1675. 255,
  1676. getWidth (),
  1677. getHeight(),
  1678. data,
  1679. iCompressionFlags);
  1680. }
  1681. break;
  1682. #endif
  1683. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
  1684. case OSG_RGBA_DXT5:
  1685. {
  1686. iCompressionFlags |= osgsquish::kDxt5;
  1687. #ifdef OSG_DEBUG
  1688. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1689. getHeight(),
  1690. iCompressionFlags);
  1691. OSG_ASSERT(iStorage == destSize);
  1692. #endif
  1693. osgsquish::CompressImage(sourceData,
  1694. 255,
  1695. getWidth (),
  1696. getHeight(),
  1697. data,
  1698. iCompressionFlags);
  1699. }
  1700. break;
  1701. #endif
  1702. default:
  1703. FWARNING (( "RGB: Invalid target IMAGE_DATA_TYPE\n" ));
  1704. break;
  1705. }
  1706. break;
  1707. //-----------------------------------------------------
  1708. case OSG_RGBA_PF:
  1709. {
  1710. switch (pixelFormat)
  1711. {
  1712. case OSG_A_PF:
  1713. switch (getDataType())
  1714. {
  1715. case OSG_UINT8_IMAGEDATA:
  1716. for (srcI = destI = 0; destI < destSize;)
  1717. {
  1718. srcI += 3;
  1719. data[destI++] = sourceData[srcI++];;
  1720. }
  1721. break;
  1722. case OSG_UINT16_IMAGEDATA:
  1723. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1724. {
  1725. srcI += 3;
  1726. destDataUC16[destI++] = sourceDataUC16[srcI++];;
  1727. }
  1728. break;
  1729. case OSG_UINT32_IMAGEDATA:
  1730. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1731. {
  1732. srcI += 3;
  1733. destDataUC32[destI++] = sourceDataUC32[srcI++];;
  1734. }
  1735. break;
  1736. case OSG_FLOAT32_IMAGEDATA:
  1737. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1738. {
  1739. srcI += 3;
  1740. destDataF32[destI++] = sourceDataF32[srcI++];
  1741. }
  1742. break;
  1743. case OSG_FLOAT16_IMAGEDATA:
  1744. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1745. {
  1746. srcI += 3;
  1747. destDataH16[destI++] = sourceDataH16[srcI++];
  1748. }
  1749. break;
  1750. default:
  1751. FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
  1752. break;
  1753. }
  1754. break;
  1755. case OSG_I_PF:
  1756. case OSG_L_PF:
  1757. switch (getDataType())
  1758. {
  1759. case OSG_UINT8_IMAGEDATA:
  1760. for (srcI = destI = 0; destI < destSize;)
  1761. {
  1762. sum = 0;
  1763. sum += sourceData[srcI++];
  1764. sum += sourceData[srcI++];
  1765. sum += sourceData[srcI++];
  1766. data[destI++] = sum / 3;
  1767. srcI++;
  1768. }
  1769. break;
  1770. case OSG_UINT16_IMAGEDATA:
  1771. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1772. {
  1773. sum = 0;
  1774. sum += sourceDataUC16[srcI++];
  1775. sum += sourceDataUC16[srcI++];
  1776. sum += sourceDataUC16[srcI++];
  1777. destDataUC16[destI++] = sum / 3;
  1778. srcI++;
  1779. }
  1780. break;
  1781. case OSG_UINT32_IMAGEDATA:
  1782. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1783. {
  1784. sum = 0;
  1785. sum += sourceDataUC32[srcI++];
  1786. sum += sourceDataUC32[srcI++];
  1787. sum += sourceDataUC32[srcI++];
  1788. destDataUC32[destI++] = sum / 3;
  1789. srcI++;
  1790. }
  1791. break;
  1792. case OSG_FLOAT32_IMAGEDATA:
  1793. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1794. {
  1795. sumReal = 0;
  1796. sumReal += sourceDataF32[srcI++];
  1797. sumReal += sourceDataF32[srcI++];
  1798. sumReal += sourceDataF32[srcI++];
  1799. destDataF32[destI++] = sumReal / 3.0;
  1800. srcI++;
  1801. }
  1802. break;
  1803. case OSG_FLOAT16_IMAGEDATA:
  1804. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1805. {
  1806. sumReal = 0;
  1807. sumReal += sourceDataH16[srcI++];
  1808. sumReal += sourceDataH16[srcI++];
  1809. sumReal += sourceDataH16[srcI++];
  1810. destDataH16[destI++] = sumReal / 3.0;
  1811. srcI++;
  1812. }
  1813. break;
  1814. default:
  1815. FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
  1816. break;
  1817. }
  1818. break;
  1819. case OSG_LA_PF:
  1820. switch (getDataType())
  1821. {
  1822. case OSG_UINT8_IMAGEDATA:
  1823. for (srcI = destI = 0; destI < destSize;)
  1824. {
  1825. sum = 0;
  1826. sum += sourceData[srcI++];
  1827. sum += sourceData[srcI++];
  1828. sum += sourceData[srcI++];
  1829. data[destI++] = sum / 3;
  1830. data[destI++] = sourceData[srcI++];;
  1831. }
  1832. break;
  1833. case OSG_UINT16_IMAGEDATA:
  1834. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1835. {
  1836. sum = 0;
  1837. sum += sourceDataUC16[srcI++];
  1838. sum += sourceDataUC16[srcI++];
  1839. sum += sourceDataUC16[srcI++];
  1840. destDataUC16[destI++] = sum / 3;
  1841. destDataUC16[destI++] = sourceDataUC16[srcI++];;
  1842. }
  1843. break;
  1844. case OSG_UINT32_IMAGEDATA:
  1845. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1846. {
  1847. sum = 0;
  1848. sum += sourceDataUC32[srcI++];
  1849. sum += sourceDataUC32[srcI++];
  1850. sum += sourceDataUC32[srcI++];
  1851. destDataUC32[destI++] = sum / 3;
  1852. destDataUC32[destI++] = sourceDataUC32[srcI++];;
  1853. }
  1854. break;
  1855. case OSG_FLOAT32_IMAGEDATA:
  1856. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1857. {
  1858. sumReal = 0;
  1859. sumReal += sourceDataF32[srcI++];
  1860. sumReal += sourceDataF32[srcI++];
  1861. sumReal += sourceDataF32[srcI++];
  1862. destDataF32[destI++] = sumReal / 3.0;
  1863. destDataF32[destI++] = sourceDataF32[srcI++];
  1864. }
  1865. break;
  1866. case OSG_FLOAT16_IMAGEDATA:
  1867. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1868. {
  1869. sumReal = 0;
  1870. sumReal += sourceDataH16[srcI++];
  1871. sumReal += sourceDataH16[srcI++];
  1872. sumReal += sourceDataH16[srcI++];
  1873. destDataH16[destI++] = sumReal / 3.0;
  1874. destDataH16[destI++] = sourceDataH16[srcI++];
  1875. }
  1876. break;
  1877. default:
  1878. FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
  1879. break;
  1880. }
  1881. break;
  1882. case OSG_RGB_PF:
  1883. switch (getDataType())
  1884. {
  1885. case OSG_UINT8_IMAGEDATA:
  1886. for (srcI = destI = 0; destI < destSize;)
  1887. {
  1888. data[destI++] = sourceData[srcI++];
  1889. data[destI++] = sourceData[srcI++];
  1890. data[destI++] = sourceData[srcI++];
  1891. srcI++;
  1892. }
  1893. break;
  1894. case OSG_UINT16_IMAGEDATA:
  1895. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1896. {
  1897. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1898. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1899. destDataUC16[destI++] = sourceDataUC16[srcI++];
  1900. srcI++;
  1901. }
  1902. break;
  1903. case OSG_UINT32_IMAGEDATA:
  1904. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1905. {
  1906. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1907. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1908. destDataUC32[destI++] = sourceDataUC32[srcI++];
  1909. srcI++;
  1910. }
  1911. break;
  1912. case OSG_FLOAT32_IMAGEDATA:
  1913. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1914. {
  1915. destDataF32[destI++] = sourceDataF32[srcI++];
  1916. destDataF32[destI++] = sourceDataF32[srcI++];
  1917. destDataF32[destI++] = sourceDataF32[srcI++];
  1918. srcI++;
  1919. }
  1920. break;
  1921. case OSG_FLOAT16_IMAGEDATA:
  1922. for (srcI = destI = 0; destI < destSize/getComponentSize();)
  1923. {
  1924. destDataH16[destI++] = sourceDataH16[srcI++];
  1925. destDataH16[destI++] = sourceDataH16[srcI++];
  1926. destDataH16[destI++] = sourceDataH16[srcI++];
  1927. srcI++;
  1928. }
  1929. break;
  1930. default:
  1931. FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
  1932. break;
  1933. }
  1934. break;
  1935. case OSG_RGBA_PF:
  1936. switch (getDataType())
  1937. {
  1938. case OSG_UINT8_IMAGEDATA:
  1939. memcpy (data, getData(), destSize);
  1940. break;
  1941. case OSG_UINT16_IMAGEDATA:
  1942. memcpy (data, getData(), destSize);
  1943. break;
  1944. case OSG_UINT32_IMAGEDATA:
  1945. memcpy (data, getData(), destSize);
  1946. break;
  1947. case OSG_FLOAT32_IMAGEDATA:
  1948. memcpy (data, getData(), destSize);
  1949. break;
  1950. case OSG_FLOAT16_IMAGEDATA:
  1951. memcpy (data, getData(), destSize);
  1952. break;
  1953. default:
  1954. FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
  1955. break;
  1956. }
  1957. break;
  1958. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
  1959. case OSG_RGBA_DXT1:
  1960. {
  1961. iCompressionFlags |= osgsquish::kDxt1;
  1962. #ifdef OSG_DEBUG
  1963. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1964. getHeight(),
  1965. iCompressionFlags);
  1966. OSG_ASSERT(iStorage == destSize);
  1967. #endif
  1968. osgsquish::CompressImage(sourceData,
  1969. getWidth (),
  1970. getHeight(),
  1971. data,
  1972. iCompressionFlags);
  1973. }
  1974. break;
  1975. #endif
  1976. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
  1977. case OSG_RGBA_DXT3:
  1978. {
  1979. iCompressionFlags |= osgsquish::kDxt3;
  1980. #ifdef OSG_DEBUG
  1981. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  1982. getHeight(),
  1983. iCompressionFlags);
  1984. OSG_ASSERT(iStorage == destSize);
  1985. #endif
  1986. osgsquish::CompressImage(sourceData,
  1987. getWidth (),
  1988. getHeight(),
  1989. data,
  1990. iCompressionFlags);
  1991. }
  1992. break;
  1993. #endif
  1994. #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
  1995. case OSG_RGBA_DXT5:
  1996. {
  1997. iCompressionFlags |= osgsquish::kDxt5;
  1998. #ifdef OSG_DEBUG
  1999. Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
  2000. getHeight(),
  2001. iCompressionFlags);
  2002. OSG_ASSERT(iStorage == destSize);
  2003. #endif
  2004. osgsquish::CompressImage(sourceData,
  2005. getWidth (),
  2006. getHeight(),
  2007. data,
  2008. iCompressionFlags);
  2009. }
  2010. break;
  2011. #endif
  2012. default:
  2013. break;
  2014. }
  2015. break;
  2016. }
  2017. case OSG_ALPHA_INTEGER_PF:
  2018. case OSG_RGB_INTEGER_PF:
  2019. case OSG_RGBA_INTEGER_PF:
  2020. case OSG_BGR_INTEGER_PF:
  2021. case OSG_BGRA_INTEGER_PF:
  2022. case OSG_LUMINANCE_INTEGER_PF:
  2023. case OSG_LUMINANCE_ALPHA_INTEGER_PF:
  2024. {
  2025. FFATAL((" 'reformat' NYI\n "));
  2026. }
  2027. break;
  2028. default:
  2029. FWARNING (( "Unvalid pixeldepth (%d) in reformat() !\n",
  2030. pixelFormat ));
  2031. }
  2032. }
  2033. if (data)
  2034. {
  2035. // rip the data from the local destImage if necessary
  2036. if(destination == NULL)
  2037. {
  2038. this->set(dest);
  2039. }
  2040. }
  2041. }
  2042. return (data ? true : false);
  2043. }
  2044. void Image::swapDataEndian(void)
  2045. {
  2046. UChar8 *data = editData();
  2047. UInt32 size = getSize() / getComponentSize();
  2048. UInt16 *dataUC16 = reinterpret_cast<UInt16 *>(data);
  2049. UInt32 *dataUC32 = reinterpret_cast<UInt32 *>(data);
  2050. Real32 *dataF32 = reinterpret_cast<Real32 *>(data);
  2051. switch (getDataType())
  2052. {
  2053. case OSG_UINT8_IMAGEDATA:
  2054. // do nothing
  2055. break;
  2056. case OSG_UINT16_IMAGEDATA:
  2057. for(UInt32 i=0;i<size;++i)
  2058. {
  2059. UInt16 p = dataUC16[i];
  2060. dataUC16[i] = (((p >> 8)) | (p << 8));
  2061. }
  2062. break;
  2063. case OSG_UINT32_IMAGEDATA:
  2064. for(UInt32 i=0;i<size;++i)
  2065. {
  2066. UInt32 p = dataUC32[i];
  2067. dataUC32[i] =
  2068. (((p & 0x000000FF) << 24) | ((p & 0x0000FF00) << 8) |
  2069. ((p & 0x00FF0000) >> 8) | ((p & 0xFF000000) >> 24) );
  2070. }
  2071. break;
  2072. case OSG_FLOAT32_IMAGEDATA:
  2073. for(UInt32 i=0;i<size;++i)
  2074. {
  2075. Real32 p = dataF32[i];
  2076. UInt8 *b = reinterpret_cast<UInt8 *>(&p);
  2077. std::swap(b[0], b[3]);
  2078. std::swap(b[1], b[2]);
  2079. dataF32[i] = p;
  2080. }
  2081. break;
  2082. case OSG_INT16_IMAGEDATA:
  2083. case OSG_INT32_IMAGEDATA:
  2084. {
  2085. FFATAL((" 'swapDataEndian' NYI\n "));
  2086. }
  2087. break;
  2088. default:
  2089. FWARNING (( "invalid source data type \n"));
  2090. break;
  2091. }
  2092. }
  2093. /*! It is a simple method to convert the image dataType. Does not change
  2094. the pixelFormat. So you can for example convert a image consisting of
  2095. UChar8 data to Float data.
  2096. */
  2097. bool Image::convertDataTypeTo(Int32 destDataType)
  2098. {
  2099. if (hasCompressedData())
  2100. {
  2101. FFATAL (("Invalid Image::convertDataTypeTo for compressed image\n"));
  2102. return false;
  2103. }
  2104. if(destDataType == getDataType())
  2105. {
  2106. FWARNING (( "source image and destination image have same data "
  2107. "types: no conversion possible"));
  2108. return true;
  2109. }
  2110. FINFO(("Try to convert image from dataType %d to %d\n",
  2111. getDataType(), destDataType));
  2112. ImageUnrecPtr dest;
  2113. dest = Image::create();
  2114. dest->set(getPixelFormat(),
  2115. getWidth (),
  2116. getHeight (),
  2117. getDepth (),
  2118. getMipMapCount(),
  2119. getFrameCount (),
  2120. 0.0,
  2121. 0,
  2122. destDataType,
  2123. true,
  2124. getSideCount() );
  2125. const UChar8 *sourceData = getData();
  2126. UChar8 *destData = dest->editData();
  2127. UInt32 sourceSize = getSize() / getComponentSize();
  2128. const UInt16 *sourceDataUC16 = reinterpret_cast<const UInt16 *>(sourceData);
  2129. UInt16 *destDataUC16 = reinterpret_cast< UInt16 *>(destData );
  2130. const UInt32 *sourceDataUC32 = reinterpret_cast<const UInt32 *>(sourceData);
  2131. UInt32 *destDataUC32 = reinterpret_cast< UInt32 *>(destData );
  2132. const Real32 *sourceDataF32 = reinterpret_cast<const Real32 *>(sourceData);
  2133. Real32 *destDataF32 = reinterpret_cast< Real32 *>(destData );
  2134. // const Real16 *sourceDataH16 = reinterpret_cast<const Real16 *>(sourceData);
  2135. Real16 *destDataH16 = reinterpret_cast< Real16 *>(destData );
  2136. switch (getDataType())
  2137. {
  2138. case OSG_UINT8_IMAGEDATA:
  2139. switch (destDataType)
  2140. {
  2141. case OSG_UINT16_IMAGEDATA:
  2142. for (UInt32 i = 0; i < sourceSize; i++)
  2143. {
  2144. destDataUC16[i] = UInt16(sourceData[i]<<8);
  2145. }
  2146. break;
  2147. case OSG_UINT32_IMAGEDATA:
  2148. for (UInt32 i = 0; i < sourceSize; i++)
  2149. {
  2150. destDataUC32[i] = UInt32(sourceData[i]<<24);
  2151. }
  2152. break;
  2153. case OSG_FLOAT32_IMAGEDATA:
  2154. for (UInt32 i = 0; i < sourceSize; i++)
  2155. {
  2156. destDataF32[i] = Real32(sourceData[i]/255.0);
  2157. }
  2158. break;
  2159. case OSG_FLOAT16_IMAGEDATA:
  2160. for (UInt32 i = 0; i < sourceSize; i++)
  2161. {
  2162. destDataH16[i] = Real16(sourceData[i]/255.0);
  2163. }
  2164. break;
  2165. default:
  2166. FWARNING (( "invalid destination data type \n" ));
  2167. break;
  2168. }
  2169. break;
  2170. case OSG_UINT16_IMAGEDATA:
  2171. switch (destDataType)
  2172. {
  2173. case OSG_UINT8_IMAGEDATA:
  2174. {
  2175. UInt16 nMin = UInt16(65535);
  2176. UInt16 nMax = UInt16(0 );
  2177. for (UInt32 i = 0; i < sourceSize; ++i)
  2178. {
  2179. if(sourceDataUC16[i] > nMax)
  2180. nMax = sourceDataUC16[i];
  2181. if(sourceDataUC16[i] < nMin)
  2182. nMin = sourceDataUC16[i];
  2183. }
  2184. Real32 fRange = Real32(nMax - nMin);
  2185. if (fRange <= 0.0)
  2186. {
  2187. for(UInt32 i = 0; i < sourceSize; ++i)
  2188. destData[i] = 0;
  2189. }
  2190. else
  2191. {
  2192. for(UInt32 i = 0; i < sourceSize; ++i)
  2193. {
  2194. destData[i] = UInt8
  2195. (255.0 *
  2196. (Real32 (sourceDataUC16[i] - nMin)) /
  2197. fRange) ;
  2198. }
  2199. }
  2200. }
  2201. break;
  2202. case OSG_UINT32_IMAGEDATA:
  2203. for (UInt32 i = 0; i < sourceSize; i++)
  2204. {
  2205. destDataUC32[i] = UInt32(sourceDataUC16[i]<<16);
  2206. }
  2207. break;
  2208. case OSG_FLOAT32_IMAGEDATA:
  2209. for (UInt32 i = 0; i < sourceSize; i++)
  2210. {
  2211. destDataF32[i] = Real32(sourceDataUC16[i]/65535.0);
  2212. }
  2213. break;
  2214. case OSG_FLOAT16_IMAGEDATA:
  2215. for (UInt32 i = 0; i < sourceSize; i++)
  2216. {
  2217. destDataH16[i] = Real16(sourceDataUC16[i]/255.0);
  2218. }
  2219. break;
  2220. default:
  2221. FWARNING (( "invalid destination data type \n" ));
  2222. break;
  2223. }
  2224. break;
  2225. case OSG_UINT32_IMAGEDATA:
  2226. switch (destDataType)
  2227. {
  2228. case OSG_UINT8_IMAGEDATA:
  2229. {
  2230. UInt32 nMin = UInt32(4294967295ul);
  2231. UInt32 nMax = UInt32(0 );
  2232. for (UInt32 i = 0; i < sourceSize; ++i)
  2233. {
  2234. if(sourceDataUC32[i] > nMax)
  2235. nMax = sourceDataUC32[i];
  2236. if(sourceDataUC32[i] < nMin)
  2237. nMin = sourceDataUC32[i];
  2238. }
  2239. Real32 fRange = Real32(nMax - nMin);
  2240. if (fRange <= 0.0)
  2241. {
  2242. for(UInt32 i = 0; i < sourceSize; ++i)
  2243. destData[i] = 0;
  2244. }
  2245. else
  2246. {
  2247. for(UInt32 i = 0; i < sourceSize; ++i)
  2248. {
  2249. destData[i] = UInt8
  2250. (255.0 *
  2251. (Real32(sourceDataUC32[i] - nMin)) /
  2252. fRange );
  2253. }
  2254. }
  2255. }
  2256. break;
  2257. case OSG_UINT16_IMAGEDATA:
  2258. {
  2259. UInt32 nMin = UInt32(4294967295ul);
  2260. UInt32 nMax = UInt32(0 );
  2261. for(UInt32 i = 0; i < sourceSize; ++i)
  2262. {
  2263. if(sourceDataUC32[i] > nMax)
  2264. nMax = sourceDataUC32[i];
  2265. if(sourceDataUC32[i] < nMin)
  2266. nMin = sourceDataUC32[i];
  2267. }
  2268. Real32 fRange = Real32(nMax - nMin);
  2269. if(fRange <= 0.0)
  2270. {
  2271. for(UInt32 i = 0; i < sourceSize; ++i)
  2272. destDataUC16[i] = 0;
  2273. }
  2274. else
  2275. {
  2276. for(UInt32 i = 0; i < sourceSize; ++i)
  2277. destDataUC16[i] = UInt16
  2278. (65535.0 *
  2279. (Real32(sourceDataUC32[i] - nMin)) /
  2280. fRange);
  2281. }
  2282. }
  2283. break;
  2284. case OSG_FLOAT32_IMAGEDATA:
  2285. for(UInt32 i = 0; i < sourceSize; i++)
  2286. {
  2287. destDataF32[i] =
  2288. (Real32(sourceDataUC32[i])) / 4294967295.0;
  2289. }
  2290. break;
  2291. case OSG_FLOAT16_IMAGEDATA:
  2292. for (UInt32 i = 0; i < sourceSize; i++)
  2293. {
  2294. destDataH16[i] =
  2295. (Real16(sourceDataUC32[i])) / REAL16_MAX;
  2296. }
  2297. break;
  2298. default:
  2299. FWARNING(("invalid destination data type \n"));
  2300. break;
  2301. }
  2302. break;
  2303. case OSG_FLOAT32_IMAGEDATA:
  2304. switch(destDataType)
  2305. {
  2306. case OSG_UINT8_IMAGEDATA:
  2307. for(UInt32 i = 0; i < sourceSize; i++)
  2308. {
  2309. destData[i] = UInt8(sourceDataF32[i]*255.0);
  2310. }
  2311. break;
  2312. case OSG_UINT16_IMAGEDATA:
  2313. for(UInt32 i = 0; i < sourceSize; i++)
  2314. {
  2315. destDataUC16[i] =
  2316. UInt16(sourceDataF32[i] * 65535.0);
  2317. }
  2318. break;
  2319. case OSG_UINT32_IMAGEDATA:
  2320. for(UInt32 i = 0; i < sourceSize; i++)
  2321. {
  2322. destDataUC32[i] =
  2323. UInt32(sourceDataF32[i] * 4294967295.0);
  2324. }
  2325. break;
  2326. case OSG_FLOAT16_IMAGEDATA:
  2327. for (UInt32 i = 0; i < sourceSize; i++)
  2328. {
  2329. destDataH16[i] =
  2330. Real16(sourceDataF32[i]); // half-constructor
  2331. }
  2332. break;
  2333. default:
  2334. FWARNING(("invalid destination data type \n"));
  2335. break;
  2336. }
  2337. break;
  2338. case OSG_INT16_IMAGEDATA:
  2339. case OSG_INT32_IMAGEDATA:
  2340. {
  2341. FFATAL((" 'convertDataTypeTo' NYI\n "));
  2342. }
  2343. break;
  2344. default:
  2345. FWARNING (( "invalid source data type \n"));
  2346. break;
  2347. }
  2348. if(dest->getData() != NULL)
  2349. {
  2350. this->set(dest);
  2351. }
  2352. return (getData() ? true : false);
  2353. }
  2354. /*! It just fills the hole image data with the given pixel value. It is
  2355. mainly used to initialize the image data.
  2356. */
  2357. void Image::clear(UChar8 pixelValue)
  2358. {
  2359. if(getData() != NULL)
  2360. memset(editData(), pixelValue, getSize());
  2361. }
  2362. void Image::clearFloat(Real32 pixelValue)
  2363. {
  2364. unsigned long n = getSize()/getComponentSize();
  2365. Real32 *d = reinterpret_cast<Real32 *>(editData());
  2366. if(n && d)
  2367. {
  2368. while(n--)
  2369. {
  2370. *d++ = pixelValue;
  2371. }
  2372. }
  2373. }
  2374. void Image::clearHalf(Real16 pixelValue)
  2375. {
  2376. unsigned long n = getSize()/getComponentSize();
  2377. Real16 *d = reinterpret_cast<Real16 *>(editData());
  2378. if(n && d)
  2379. while(n--)
  2380. *d++ = pixelValue;
  2381. }
  2382. /*-------------------------------------------------------------------------*/
  2383. /* attachment handling */
  2384. /*! returns true if the image has any attachments
  2385. */
  2386. bool Image::hasAttachment(void) const
  2387. {
  2388. Image *img=const_cast<Image*>(this);
  2389. ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
  2390. img->Inherited::findAttachment(
  2391. ImageGenericAtt::getClassType().getGroupId()));
  2392. if(att != NULL && att->getType().getNumFieldDescs() > 1)
  2393. return true;
  2394. else
  2395. return false;
  2396. }
  2397. /*! returns the number of attachments
  2398. */
  2399. UInt32 Image::attachmentCount(void) const
  2400. {
  2401. Image *img=const_cast<Image*>(this);
  2402. ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
  2403. img->Inherited::findAttachment(
  2404. ImageGenericAtt::getClassType().getGroupId()));
  2405. if(att != NULL)
  2406. {
  2407. return att->getType().getNumFieldDescs() -1;
  2408. }
  2409. else
  2410. {
  2411. return 0;
  2412. }
  2413. }
  2414. /*! set a single string attachment for the given key/data pair
  2415. */
  2416. void Image::setAttachmentField(const std::string &key,
  2417. const std::string &data)
  2418. {
  2419. ImageGenericAttUnrecPtr att(dynamic_cast<ImageGenericAtt *>(
  2420. findAttachment(
  2421. ImageGenericAtt::getClassType().getGroupId())));
  2422. if(att == NULL)
  2423. {
  2424. att = ImageGenericAtt::create();
  2425. addAttachment(att);
  2426. }
  2427. if(att == NULL)
  2428. {
  2429. FWARNING(("Image::setAttachmentField - can not create attachment\n"));
  2430. return;
  2431. }
  2432. EditFieldHandlePtr field = att->editDynamicFieldByName(key.c_str());
  2433. if(field == NULL)
  2434. {
  2435. SFString::Description pDesc = SFString::Description(
  2436. SFString::getClassType(),
  2437. key.c_str(),
  2438. "",
  2439. 0,
  2440. 0,
  2441. true,
  2442. Field::SFDefaultFlags,
  2443. static_cast<FieldIndexEditMethodSig>(
  2444. &ImageGenericAtt::editDynamicField),
  2445. static_cast<FieldIndexGetMethodSig >(
  2446. &ImageGenericAtt::getDynamicField ));
  2447. UInt32 fieldId = att->addField(pDesc);
  2448. field = att->editDynamicField(fieldId);
  2449. }
  2450. SFString::EditHandlePtr strField =
  2451. boost::static_pointer_cast<SFString::EditHandle>(field);
  2452. if(strField != NULL && strField->isValid() == true)
  2453. (*strField)->setValue(data);
  2454. }
  2455. /*! returns the string attachment for the given key or Null
  2456. */
  2457. const std::string *Image::findAttachmentField(const std::string &key) const
  2458. {
  2459. Image *img=const_cast<Image*>(this);
  2460. ImageGenericAtt *att = dynamic_cast<ImageGenericAtt *>(
  2461. img->findAttachment(
  2462. ImageGenericAtt::getClassType().getGroupId()));
  2463. if(att != NULL)
  2464. {
  2465. GetFieldHandlePtr field = att->getDynamicFieldByName(key.c_str());
  2466. if(field != NULL)
  2467. {
  2468. SFString::GetHandlePtr strField =
  2469. boost::static_pointer_cast<SFString::GetHandle>(field);
  2470. if(strField != NULL && strField->isValid() == true)
  2471. return &((*strField)->getValue());
  2472. }
  2473. }
  2474. return NULL;
  2475. }
  2476. /*! Method to scale the image. It just does a very simple but fast
  2477. 'nearest' scale. Should handle mipmap and frame data correct.
  2478. The method can operate on the object or stores the result in
  2479. the optional destination Image.
  2480. */
  2481. bool Image::scale(Int32 width,
  2482. Int32 height,
  2483. Int32 depth,
  2484. Image *destination)
  2485. {
  2486. Image *destImage;
  2487. UInt32 sw, sh, sd, dw, dh, dd;
  2488. Int32 frame, side, mipmap;
  2489. const UChar8 *src;
  2490. UChar8 *dest;
  2491. Int32 oldWidth =getWidth();
  2492. Int32 oldHeight=getHeight();
  2493. Int32 oldDepth =getDepth();
  2494. if ( (oldWidth == width ) &&
  2495. (oldHeight == height) &&
  2496. (oldDepth == depth ) )
  2497. {
  2498. if(destination != NULL)
  2499. *destination = *this;
  2500. return true;
  2501. }
  2502. if (hasCompressedData())
  2503. {
  2504. FFATAL (("Invalid Image::scale for compressed image\n"));
  2505. return false;
  2506. }
  2507. if(destination != NULL)
  2508. {
  2509. destImage = destination;
  2510. }
  2511. else
  2512. {
  2513. destImage = this;
  2514. }
  2515. // get pixel
  2516. // !!!!!!!! WARNING WARNING !!!!!!!!!!!
  2517. // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
  2518. const MFUInt8 srcPixel = *getMFPixel();
  2519. // set image data
  2520. destImage->set(PixelFormat(getPixelFormat()),
  2521. width,
  2522. height,
  2523. depth,
  2524. getMipMapCount(),
  2525. getFrameCount (),
  2526. getFrameDelay (),
  2527. 0,
  2528. getDataType (),
  2529. true,
  2530. getSideCount ());
  2531. // copy every mipmap in every side in every frame
  2532. for(frame = 0; frame < getFrameCount(); frame++)
  2533. {
  2534. for (side = 0; side < getSideCount(); side++)
  2535. {
  2536. for(mipmap = 0; mipmap < getMipMapCount(); mipmap++)
  2537. {
  2538. // get the memory pointer
  2539. src = (&(srcPixel[0])) +
  2540. (side * getSideSize ()) +
  2541. (frame * getFrameSize()) ;
  2542. if(mipmap)
  2543. {
  2544. src += calcMipmapSumSize (mipmap,
  2545. oldWidth,
  2546. oldHeight,
  2547. oldDepth);
  2548. }
  2549. dest = destImage->editData(mipmap, frame, side);
  2550. // calc the mipmap size
  2551. sw = oldWidth >> mipmap;
  2552. sh = oldHeight >> mipmap;
  2553. sd = oldDepth >> mipmap;
  2554. destImage->calcMipmapGeometry(mipmap, dw, dh, dd);
  2555. // copy and scale the data
  2556. scaleData(src, sw, sh, sd, dest, dw, dh, dd);
  2557. }
  2558. }
  2559. }
  2560. return true;
  2561. }
  2562. /*! Mirror the image along horizontal, vertical, or depth.
  2563. The method can operate on the object or stores the result in
  2564. the optional destination Image.
  2565. */
  2566. bool Image::mirror(bool horizontal,
  2567. bool vertical,
  2568. bool flipDepth,
  2569. Image *destination)
  2570. {
  2571. if ( !horizontal && !vertical)
  2572. {
  2573. if(destination != NULL)
  2574. *destination = *this;
  2575. return true;
  2576. }
  2577. Image *destImage;
  2578. if(destination != NULL)
  2579. {
  2580. destImage = destination;
  2581. }
  2582. else
  2583. {
  2584. destImage = this;
  2585. }
  2586. // Get pixels.
  2587. // !!!!!!!! WARNING WARNING !!!!!!!!!!!
  2588. // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
  2589. const MFUInt8 srcPixel = (*getMFPixel());
  2590. UInt32 width = getWidth();
  2591. UInt32 height = getHeight();
  2592. UInt32 depth = getDepth();
  2593. destImage->set(PixelFormat(getPixelFormat()),
  2594. width,
  2595. height,
  2596. depth,
  2597. getMipMapCount(),
  2598. getFrameCount (),
  2599. getFrameDelay (),
  2600. 0,
  2601. getDataType (),
  2602. true,
  2603. getSideCount ());
  2604. Int32 frame, side, mipmap;
  2605. const UChar8 *src;
  2606. UChar8 *dest;
  2607. // copy every mipmap in every side in every frame
  2608. for(frame = 0; frame < getFrameCount(); frame++)
  2609. {
  2610. for (side = 0; side < getSideCount(); side++)
  2611. {
  2612. for(mipmap = 0; mipmap < getMipMapCount(); mipmap++)
  2613. {
  2614. // get the memory pointer
  2615. src = (&(srcPixel[0])) +
  2616. (side * getSideSize ()) +
  2617. (frame * getFrameSize());
  2618. if(mipmap)
  2619. {
  2620. src += calcMipmapSumSize(mipmap, width, height, depth);
  2621. }
  2622. dest = destImage->editData(mipmap, frame, side);
  2623. destImage->calcMipmapGeometry(mipmap, width, height, depth);
  2624. // copy and mirror the data
  2625. mirrorData(src, dest, width, height, depth, horizontal,
  2626. vertical, flipDepth);
  2627. }
  2628. }
  2629. }
  2630. return true;
  2631. }
  2632. /*! Scale the image to the next power of 2 dimensions
  2633. The method can operate on the object or stores the result in
  2634. the optional destination Image.
  2635. */
  2636. bool Image::scaleNextPower2(Image *destination)
  2637. {
  2638. return scale(osgNextPower2(getWidth ()),
  2639. osgNextPower2(getHeight()),
  2640. osgNextPower2(getDepth ()),
  2641. destination );
  2642. }
  2643. /*! Crop the image to the given bounding box.
  2644. The method can operate on the object or stores the result in
  2645. the optional destination Image.
  2646. */
  2647. bool Image::subImage(Int32 offX,
  2648. Int32 offY,
  2649. Int32 offZ,
  2650. Int32 destW,
  2651. Int32 destH,
  2652. Int32 destD,
  2653. Image *destination)
  2654. {
  2655. ImageUnrecPtr destImage(destination);
  2656. bool retCode = true;
  2657. if (hasCompressedData())
  2658. {
  2659. FFATAL (("Invalid Image::subImage for compressed image\n"));
  2660. return false;
  2661. }
  2662. if(destination == NULL)
  2663. {
  2664. destImage = Image::create();
  2665. }
  2666. destImage->set(PixelFormat(getPixelFormat()),
  2667. destW,
  2668. destH,
  2669. destD,
  2670. 1,
  2671. 1,
  2672. 0.0,
  2673. 0,
  2674. getDataType());
  2675. const UChar8 *src = getData ();
  2676. UChar8 *dest = destImage->editData();
  2677. FDEBUG(("Image::subImage (%d %d %d) - (%d %d %d) - destPtr %p\n",
  2678. offX, offY, offZ, destW, destH, destD, dest));
  2679. // ensure destination data is zero
  2680. memset(dest, 0, destImage->getSize());
  2681. // determine the area to actually copy
  2682. UInt32 xMin = offX;
  2683. UInt32 yMin = offY;
  2684. UInt32 zMin = offZ;
  2685. UInt32 xMax = osgMin(getWidth (), offX + destW);
  2686. UInt32 yMax = osgMin(getHeight(), offY + destH);
  2687. UInt32 zMax = osgMin(getDepth (), offZ + destD);
  2688. // fill the destination buffer with the subdata
  2689. UInt32 destIdx = 0;
  2690. for(UInt32 z = zMin; z < zMax; z++)
  2691. {
  2692. for(UInt32 y = yMin; y < yMax; y++)
  2693. {
  2694. for(UInt32 x = xMin; x < xMax; x++)
  2695. {
  2696. for(Int32 i = 0; i < getBpp(); i++)
  2697. {
  2698. dest[destIdx] = src[((z * getHeight() + y) *
  2699. getWidth() + x) * getBpp() + i];
  2700. destIdx++;
  2701. }
  2702. }
  2703. destIdx += (destW - (xMax - xMin)) * getBpp();
  2704. }
  2705. destIdx += (destH - (yMax - yMin)) * destW * getBpp();
  2706. }
  2707. // rip the data from the local destImage if necessary
  2708. if(destination == NULL)
  2709. {
  2710. this->set(destImage);
  2711. }
  2712. return retCode;
  2713. }
  2714. /*! Crop a slice.
  2715. The method can operate on the object or stores the result in
  2716. the optional destination Image.
  2717. */
  2718. bool Image::slice(Int32 offX,
  2719. Int32 offY,
  2720. Int32 offZ,
  2721. Image *destination)
  2722. {
  2723. ImageUnrecPtr destImage(destination);
  2724. bool retCode = true;
  2725. UInt32 counter = 0;
  2726. if (hasCompressedData())
  2727. {
  2728. FFATAL (("Invalid Image::slice for compressed image\n"));
  2729. return false;
  2730. }
  2731. if(destination == NULL)
  2732. {
  2733. destImage = Image::create();
  2734. }
  2735. FDEBUG(("Image::slice (%d %d %d)\n",
  2736. offX, offY, offZ));
  2737. if(offX >= 0)
  2738. counter++;
  2739. if(offY >= 0)
  2740. counter++;
  2741. if(offZ >= 0)
  2742. counter++;
  2743. if(counter != 1)
  2744. {
  2745. FWARNING(("Image::slice - more/less than one non negative value\n"));
  2746. return false;
  2747. }
  2748. if(offZ >= 0)
  2749. {
  2750. // XY slice
  2751. retCode = subImage(0,
  2752. 0,
  2753. offZ,
  2754. getWidth (),
  2755. getHeight(),
  2756. 1,
  2757. destImage );
  2758. }
  2759. if(offY >= 0)
  2760. {
  2761. // XZ slice
  2762. destImage->set(PixelFormat(getPixelFormat()),
  2763. getWidth(),
  2764. getDepth(),
  2765. 1,
  2766. 1,
  2767. 1,
  2768. 0.0,
  2769. 0,
  2770. getDataType());
  2771. const UChar8 *src = getData ();
  2772. UChar8 *dest = destImage->editData();
  2773. // ensure destination data is zero
  2774. memset(dest, 0, destImage->getSize());
  2775. for(Int32 z = 0; z < getDepth(); z++)
  2776. {
  2777. for(Int32 x = 0; x < getWidth(); x++)
  2778. {
  2779. for(Int32 i = 0; i < getBpp(); i++)
  2780. {
  2781. dest[(z * getWidth() + x) * getBpp() + i] =
  2782. src[((z * getHeight() + offY) * getWidth() + x) *
  2783. getBpp() + i];
  2784. }
  2785. }
  2786. }
  2787. }
  2788. if(offX >= 0)
  2789. {
  2790. // YZ slice
  2791. destImage->set(PixelFormat(getPixelFormat()),
  2792. getWidth(),
  2793. getDepth(),
  2794. 1,
  2795. 1,
  2796. 1,
  2797. 0.0,
  2798. 0,
  2799. getDataType());
  2800. const UChar8 *src = getData ();
  2801. UChar8 *dest = destImage->editData();
  2802. // ensure destination data is zero
  2803. memset(dest, 0, destImage->getSize());
  2804. for(Int32 z = 0; z < getDepth(); z++)
  2805. {
  2806. for(Int32 y = 0; y < getHeight(); y++)
  2807. {
  2808. for(Int32 i = 0; i < getBpp(); i++)
  2809. {
  2810. dest[(z * getHeight() + y) * getBpp() + i] =
  2811. src[((z * getHeight() + y) * getWidth() + offX) *
  2812. getBpp() + i];
  2813. }
  2814. }
  2815. }
  2816. }
  2817. // rip the data from the local destImage if necessary
  2818. if(destination == NULL)
  2819. {
  2820. this->set(destImage);
  2821. }
  2822. return retCode;
  2823. }
  2824. /*! Create mipmaps data, level defines the number of level
  2825. The method can operate on the object or stores the result in
  2826. the optional destination Image.
  2827. */
  2828. bool Image::createMipmap(Int32 level, Image *destination)
  2829. {
  2830. struct Offset
  2831. {
  2832. Int32 d;
  2833. Int32 h;
  2834. Int32 w;
  2835. };
  2836. Offset offset[][8] =
  2837. {
  2838. { // 000
  2839. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
  2840. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2841. },
  2842. { // 100
  2843. { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
  2844. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2845. },
  2846. { // 010
  2847. { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
  2848. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2849. },
  2850. { // 110
  2851. { 0, 0, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 1, 0 },
  2852. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2853. },
  2854. { // 001
  2855. { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 },
  2856. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2857. },
  2858. { // 101
  2859. { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 },
  2860. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2861. },
  2862. { // 011
  2863. { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 1 },
  2864. { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
  2865. },
  2866. { // 111
  2867. { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 },
  2868. { 0, 0, 1 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }
  2869. }
  2870. };
  2871. Int32 offsetSize[] = { 0, 2, 2, 4, 2, 4, 4, 8 };
  2872. ImageUnrecPtr destImage(destination);
  2873. Int32 w = getWidth(), h = getHeight(), d = getDepth();
  2874. Int32 wm, hm, dm, wi, hi, di;
  2875. const UChar8 *src;
  2876. UChar8 *dest;
  2877. const UInt16 *sourceDataUC16;
  2878. UInt16 *destDataUC16;
  2879. const UInt32 *sourceDataUC32;
  2880. UInt32 *destDataUC32;
  2881. const Real32 *sourceDataF32;
  2882. Real32 *destDataF32;
  2883. const Real16 *sourceDataH16;
  2884. Real16 *destDataH16;
  2885. if (hasCompressedData())
  2886. {
  2887. FFATAL (("Invalid Image::createMipmap for compressed image\n"));
  2888. return false;
  2889. }
  2890. if(destImage == NULL)
  2891. {
  2892. destImage = Image::create();
  2893. }
  2894. Real32 valueFloat;
  2895. Int32 value, i, elem, dim, side, frame, size, mipmap;
  2896. Int32 channel, lineSize, sliceSize;
  2897. // calc the level count
  2898. if(level < 0)
  2899. {
  2900. level = calcMipmapLevelCount();
  2901. }
  2902. // create destination image
  2903. destImage->set(getPixelFormat(),
  2904. getWidth(),
  2905. getHeight(),
  2906. getDepth(),
  2907. level,
  2908. getFrameCount(),
  2909. getFrameDelay(),
  2910. 0,
  2911. getDataType(),
  2912. true,
  2913. getSideCount());
  2914. // copy the data;
  2915. switch (getDataType())
  2916. {
  2917. case OSG_UINT8_IMAGEDATA:
  2918. for(frame = 0; frame < getFrameCount(); frame++)
  2919. {
  2920. for(side = 0; side < getSideCount(); side++)
  2921. {
  2922. src = this ->getData (0, frame, side);
  2923. dest = destImage->editData(0, frame, side);
  2924. size = getWidth() * getHeight() * getDepth() * getBpp();
  2925. memcpy(dest, src, size);
  2926. src = dest;
  2927. dest = dest + size;
  2928. w = getWidth ();
  2929. h = getHeight();
  2930. d = getDepth ();
  2931. for(mipmap = 1; mipmap < level; mipmap++)
  2932. {
  2933. lineSize = w * getBpp();
  2934. sliceSize = w * h * getBpp();
  2935. wm = (w == 1) ? w : (w >> 1);
  2936. hm = (h == 1) ? h : (h >> 1);
  2937. dm = (d == 1) ? d : (d >> 1);
  2938. dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
  2939. elem = offsetSize[dim];
  2940. for(di = 0; di < dm; di++)
  2941. {
  2942. for(hi = 0; hi < hm; hi++)
  2943. {
  2944. for(wi = 0; wi < wm; wi++)
  2945. {
  2946. for(channel = 0; channel < getBpp(); channel++)
  2947. {
  2948. value = 0;
  2949. for(i = 0; i < elem; i++)
  2950. {
  2951. value += src[
  2952. ((wi * 2) + offset[dim][i].w) * getBpp() +
  2953. ((hi * 2) + offset[dim][i].h) * lineSize +
  2954. ((di * 2) + offset[dim][i].d) * sliceSize +
  2955. channel];
  2956. }
  2957. *dest++ = Int8(value / elem);
  2958. }
  2959. }
  2960. }
  2961. }
  2962. src += sliceSize;
  2963. w = wm;
  2964. h = hm;
  2965. d = dm;
  2966. }
  2967. }
  2968. }
  2969. break;
  2970. case OSG_UINT16_IMAGEDATA:
  2971. for(frame = 0; frame < getFrameCount(); frame++)
  2972. {
  2973. for(side = 0; side < getSideCount(); side++)
  2974. {
  2975. src = this ->getData (0, frame, side);
  2976. dest = destImage->editData(0, frame, side);
  2977. size = getWidth() * getHeight() * getDepth() * getBpp();
  2978. memcpy(dest, src, size);
  2979. src = dest;
  2980. dest = dest + size;
  2981. w = getWidth ();
  2982. h = getHeight();
  2983. d = getDepth ();
  2984. sourceDataUC16 = reinterpret_cast<const UInt16 *>(src );
  2985. destDataUC16 = reinterpret_cast< UInt16 *>(dest);
  2986. for(mipmap = 1; mipmap < level; mipmap++)
  2987. {
  2988. lineSize = w * (getBpp() / getComponentSize());
  2989. sliceSize = w * h * (getBpp() / getComponentSize());
  2990. wm = (w == 1) ? w : (w >> 1);
  2991. hm = (h == 1) ? h : (h >> 1);
  2992. dm = (d == 1) ? d : (d >> 1);
  2993. dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
  2994. elem = offsetSize[dim];
  2995. for(di = 0; di < dm; di++)
  2996. {
  2997. for(hi = 0; hi < hm; hi++)
  2998. {
  2999. for(wi = 0; wi < wm; wi++)
  3000. {
  3001. for(channel = 0;
  3002. channel < (getBpp() / getComponentSize());
  3003. channel++)
  3004. {
  3005. value = 0;
  3006. for(i = 0; i < elem; i++)
  3007. {
  3008. value += sourceDataUC16[
  3009. ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
  3010. ((hi * 2) + offset[dim][i].h) * lineSize +
  3011. ((di * 2) + offset[dim][i].d) * sliceSize +
  3012. channel];
  3013. }
  3014. *destDataUC16++ = UInt16(value / elem);
  3015. }
  3016. }
  3017. }
  3018. }
  3019. sourceDataUC16 += sliceSize;
  3020. w = wm;
  3021. h = hm;
  3022. d = dm;
  3023. }
  3024. }
  3025. }
  3026. break;
  3027. case OSG_UINT32_IMAGEDATA:
  3028. for(frame = 0; frame < getFrameCount(); frame++)
  3029. {
  3030. for(side = 0; side < getSideCount(); side++)
  3031. {
  3032. src = this ->getData (0, frame,side);
  3033. dest = destImage->editData(0, frame,side);
  3034. size = getWidth() * getHeight() * getDepth() * getBpp();
  3035. memcpy(dest, src, size);
  3036. src = dest;
  3037. dest = dest + size;
  3038. w = getWidth ();
  3039. h = getHeight();
  3040. d = getDepth ();
  3041. sourceDataUC32 = reinterpret_cast<const UInt32 *>(src );
  3042. destDataUC32 = reinterpret_cast< UInt32 *>(dest);
  3043. for(mipmap = 1; mipmap < level; mipmap++)
  3044. {
  3045. lineSize = w * (getBpp() / getComponentSize());
  3046. sliceSize = w * h * (getBpp() / getComponentSize());
  3047. wm = (w == 1) ? w : (w >> 1);
  3048. hm = (h == 1) ? h : (h >> 1);
  3049. dm = (d == 1) ? d : (d >> 1);
  3050. dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
  3051. elem = offsetSize[dim];
  3052. for(di = 0; di < dm; di++)
  3053. {
  3054. for(hi = 0; hi < hm; hi++)
  3055. {
  3056. for(wi = 0; wi < wm; wi++)
  3057. {
  3058. for(channel = 0;
  3059. channel < (getBpp()/getComponentSize());
  3060. channel++)
  3061. {
  3062. value = 0;
  3063. for(i = 0; i < elem; i++)
  3064. {
  3065. value += (sourceDataUC32[
  3066. ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
  3067. ((hi * 2) + offset[dim][i].h) * lineSize +
  3068. ((di * 2) + offset[dim][i].d) * sliceSize +
  3069. channel]/elem);
  3070. }
  3071. *destDataUC32++ = UInt32(value);
  3072. }
  3073. }
  3074. }
  3075. }
  3076. sourceDataUC32 += sliceSize;
  3077. w = wm;
  3078. h = hm;
  3079. d = dm;
  3080. }
  3081. }
  3082. }
  3083. break;
  3084. case OSG_FLOAT32_IMAGEDATA:
  3085. for(frame = 0; frame < getFrameCount(); frame++)
  3086. {
  3087. for(side = 0; side < getSideCount(); side++)
  3088. {
  3089. src = this ->getData (0, frame,side);
  3090. dest = destImage->editData(0, frame,side);
  3091. size = getWidth() * getHeight() * getDepth() * getBpp();
  3092. memcpy(dest, src, size);
  3093. src = dest;
  3094. dest = dest + size;
  3095. w = getWidth ();
  3096. h = getHeight();
  3097. d = getDepth ();
  3098. sourceDataF32 = reinterpret_cast<const Real32 *>(src );
  3099. destDataF32 = reinterpret_cast< Real32 *>(dest);
  3100. for(mipmap = 1; mipmap < level; mipmap++)
  3101. {
  3102. lineSize = w * (getBpp() / getComponentSize());
  3103. sliceSize = w * h * (getBpp() / getComponentSize());
  3104. wm = (w == 1) ? w : (w >> 1);
  3105. hm = (h == 1) ? h : (h >> 1);
  3106. dm = (d == 1) ? d : (d >> 1);
  3107. dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
  3108. elem = offsetSize[dim];
  3109. for(di = 0; di < dm; di++)
  3110. {
  3111. for(hi = 0; hi < hm; hi++)
  3112. {
  3113. for(wi = 0; wi < wm; wi++)
  3114. {
  3115. for(channel = 0;
  3116. channel < (getBpp() / getComponentSize());
  3117. channel++)
  3118. {
  3119. valueFloat = 0;
  3120. for(i = 0; i < elem; i++)
  3121. {
  3122. valueFloat += sourceDataF32[
  3123. ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
  3124. ((hi * 2) + offset[dim][i].h) * lineSize +
  3125. ((di * 2) + offset[dim][i].d) * sliceSize +
  3126. channel];
  3127. }
  3128. *destDataF32++ = Real32(valueFloat / elem);
  3129. }
  3130. }
  3131. }
  3132. }
  3133. sourceDataF32 += sliceSize;
  3134. w = wm;
  3135. h = hm;
  3136. d = dm;
  3137. }
  3138. }
  3139. }
  3140. break;
  3141. case OSG_FLOAT16_IMAGEDATA:
  3142. for(frame = 0; frame < getFrameCount(); frame++)
  3143. {
  3144. for(side = 0; side < getSideCount(); side++)
  3145. {
  3146. src = this->getData(0, frame,side);
  3147. dest = destImage->editData(0, frame,side);
  3148. size = getWidth() * getHeight() * getDepth() * getBpp();
  3149. memcpy(dest,src, size);
  3150. src = dest;
  3151. dest = dest + size;
  3152. w = getWidth();
  3153. h = getHeight();
  3154. d = getDepth();
  3155. sourceDataH16 = reinterpret_cast<const Real16 *>(src );
  3156. destDataH16 = reinterpret_cast< Real16 *>(dest);
  3157. for(mipmap = 1; mipmap < level; mipmap++)
  3158. {
  3159. lineSize = w * (getBpp() / getComponentSize());
  3160. sliceSize = w * h * (getBpp() / getComponentSize());
  3161. wm = (w == 1) ? w : (w >> 1);
  3162. hm = (h == 1) ? h : (h >> 1);
  3163. dm = (d == 1) ? d : (d >> 1);
  3164. dim = (d > dm) * 1 + (h > hm) * 2 + (w > wm) * 4;
  3165. elem = offsetSize[dim];
  3166. for(di = 0; di < dm; di++)
  3167. {
  3168. for(hi = 0; hi < hm; hi++)
  3169. {
  3170. for(wi = 0; wi < wm; wi++)
  3171. {
  3172. for(channel = 0; channel < (getBpp()/getComponentSize()); channel++)
  3173. {
  3174. valueFloat = 0;
  3175. for(i = 0; i < elem; i++)
  3176. {
  3177. valueFloat += sourceDataH16[
  3178. ((wi * 2) + offset[dim][i].w) * (getBpp() / getComponentSize()) +
  3179. ((hi * 2) + offset[dim][i].h) * lineSize +
  3180. ((di * 2) + offset[dim][i].d) * sliceSize +
  3181. channel];
  3182. }
  3183. *destDataH16++ = Real16(valueFloat / elem);
  3184. }
  3185. }
  3186. }
  3187. }
  3188. sourceDataH16 += sliceSize;
  3189. w = wm;
  3190. h = hm;
  3191. d = dm;
  3192. }
  3193. }
  3194. }
  3195. break;
  3196. case OSG_INT16_IMAGEDATA:
  3197. case OSG_INT32_IMAGEDATA:
  3198. {
  3199. FFATAL((" 'createMipmap' NYI\n "));
  3200. }
  3201. break;
  3202. default:
  3203. FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
  3204. break;
  3205. }
  3206. // rip the data from the local destImage if necessary
  3207. if(destination == NULL)
  3208. {
  3209. this->set(destImage);
  3210. }
  3211. return true;
  3212. }
  3213. bool Image::removeMipmap(void)
  3214. {
  3215. if(getMipMapCount() == 1) // no mipmaps nothing to do.
  3216. return true;
  3217. // create destination image
  3218. ImageUnrecPtr destImage = Image::create();
  3219. destImage->set(getPixelFormat(),
  3220. getWidth (),
  3221. getHeight (),
  3222. getDepth (),
  3223. 1,
  3224. getFrameCount (),
  3225. getFrameDelay (),
  3226. NULL,
  3227. getDataType (),
  3228. true,
  3229. getSideCount ());
  3230. if(!destImage->isValid())
  3231. {
  3232. destImage = NULL;
  3233. return false;
  3234. }
  3235. // copy the data;
  3236. for(Int32 frame = 0; frame < getFrameCount(); frame++)
  3237. {
  3238. for(Int32 side = 0; side < getSideCount(); side++)
  3239. {
  3240. const UChar8 *src = this->getData(0, frame, side);
  3241. UChar8 *dest = destImage->editData(0, frame, side);
  3242. Int32 size = getWidth() * getHeight() * getDepth() * getBpp();
  3243. memcpy(dest,src, size);
  3244. }
  3245. }
  3246. this->set(destImage);
  3247. destImage = NULL;
  3248. return true;
  3249. }
  3250. /*! Write the image to the a file. The mimetype will be set automatically
  3251. from the fileName suffix. Returns true on success.
  3252. */
  3253. bool Image::write(const Char8 *fileName)
  3254. {
  3255. return ImageFileHandler::the()->write(this, fileName);
  3256. }
  3257. /*! Read the image data from a file. Returns true on success.
  3258. */
  3259. bool Image::read(const Char8 *fileName)
  3260. {
  3261. return ImageFileHandler::the()->read(this, fileName);
  3262. }
  3263. /*! Store the image to the given mem block as 'mimeType'.
  3264. mimeType can be 0, in which case the method will store the
  3265. object as uncompressed mtd data.
  3266. Returns the number of bytes used.
  3267. */
  3268. UInt64 Image::store(const Char8 *mimeType, UChar8 *mem, Int32 memSize)
  3269. {
  3270. return ImageFileHandler::the()->store(this,
  3271. mimeType,
  3272. mem,
  3273. memSize);
  3274. }
  3275. /*! Restore the image from the given mem block. Returns the
  3276. number of bytes used.
  3277. */
  3278. UInt64 Image::restore(const UChar8 *mem, Int32 memSize)
  3279. {
  3280. return ImageFileHandler::the()->restore(this, mem, memSize);;
  3281. }
  3282. /*-------------------------------------------------------------------------*/
  3283. /* Constructor / Destructor */
  3284. /*! Default Constructor. Creates a invalid Image of the size 0x0x0
  3285. */
  3286. Image::Image(void) :
  3287. Inherited (),
  3288. _mipmapOffset()
  3289. {
  3290. }
  3291. /*! Copy Constructor. Creates a copy of the given image
  3292. */
  3293. Image::Image(const Image &obj) :
  3294. Inherited (obj ),
  3295. _mipmapOffset(obj._mipmapOffset)
  3296. {
  3297. }
  3298. /*! Destructor.
  3299. */
  3300. Image::~Image(void)
  3301. {
  3302. }
  3303. /*! Method to check, whether the object data defines a alpha channel or not
  3304. */
  3305. bool Image::hasAlphaChannel(void)
  3306. {
  3307. return
  3308. (getForceAlphaChannel() == true ) ||
  3309. (getPixelFormat () == OSG_RGBA_PF ) ||
  3310. (getPixelFormat () == OSG_BGRA_PF ) ||
  3311. (getPixelFormat () == OSG_RGBA_DXT1) ||
  3312. (getPixelFormat () == OSG_RGBA_DXT3) ||
  3313. (getPixelFormat () == OSG_RGBA_DXT5) ||
  3314. (getPixelFormat () == OSG_A_PF ) ||
  3315. (getPixelFormat () == OSG_I_PF ) ||
  3316. (getPixelFormat () == OSG_LA_PF ) ||
  3317. (getPixelFormat () == OSG_ALPHA_INTEGER_PF ) ||
  3318. (getPixelFormat () == OSG_RGBA_INTEGER_PF ) ||
  3319. (getPixelFormat () == OSG_BGRA_INTEGER_PF ) ||
  3320. (getPixelFormat () == OSG_LUMINANCE_ALPHA_INTEGER_PF);
  3321. }
  3322. /*! Method to check, whether the alpha channel is just fully transparent/
  3323. fully opaque
  3324. */
  3325. bool Image::isAlphaBinary(void)
  3326. {
  3327. return
  3328. (getForceAlphaBinary() == true ) ||
  3329. (getPixelFormat () == OSG_RGBA_DXT1);
  3330. }
  3331. /*! Method to check, whether the data is compressed
  3332. */
  3333. bool Image::hasCompressedData(void)
  3334. {
  3335. return
  3336. (getForceCompressedData() == true ) ||
  3337. (getPixelFormat () == OSG_RGB_DXT1 ) ||
  3338. (getPixelFormat () == OSG_RGBA_DXT1) ||
  3339. (getPixelFormat () == OSG_RGBA_DXT3) ||
  3340. (getPixelFormat () == OSG_RGBA_DXT5);
  3341. }
  3342. /*! Method to check, whether the object data defines a color channel or not
  3343. */
  3344. bool Image::hasColorChannel(void)
  3345. {
  3346. return
  3347. ( !( getPixelFormat() == OSG_A_PF ||
  3348. getPixelFormat() == OSG_I_PF ||
  3349. getPixelFormat() == OSG_L_PF ||
  3350. getPixelFormat() == OSG_LA_PF ||
  3351. getPixelFormat() == OSG_ALPHA_INTEGER_PF ||
  3352. getPixelFormat() == OSG_LUMINANCE_ALPHA_INTEGER_PF )) ||
  3353. getForceColorChannel();
  3354. }
  3355. /*! Method returns the right frame data for the given time.
  3356. */
  3357. const UInt8 *Image::getDataByTime(Time time, UInt32) const
  3358. {
  3359. UInt32 frameNum = calcFrameNum(time, true);
  3360. return getData(0, frameNum);
  3361. }
  3362. UInt8 *Image::editDataByTime(Time time, UInt32)
  3363. {
  3364. UInt32 frameNum = calcFrameNum(time, true);
  3365. return editData(0, frameNum);
  3366. }
  3367. /*! Check all the alpha values to see if they're 0 or 1, return true if they
  3368. are, false if no alpha or intermediate values. No Alpha channel is considered
  3369. 0.
  3370. */
  3371. bool Image::calcIsAlphaBinary(void)
  3372. {
  3373. if(!hasAlphaChannel() || getPixelFormat() == OSG_RGBA_DXT1)
  3374. return true;
  3375. if(getPixelFormat() == OSG_RGBA_DXT3 || getPixelFormat() == OSG_RGBA_DXT5)
  3376. {
  3377. FWARNING(("Image::calcIsAlphaBinary: not implemenetd for DXT3 "
  3378. "and DXT5 yet, assuming false.\n"));
  3379. return false;
  3380. }
  3381. UInt32 npix = getWidth() * getHeight() * getDepth() * getFrameCount();
  3382. UInt8 pixelsize = getBpp();
  3383. const UInt8 *data = getData();
  3384. switch(getPixelFormat())
  3385. {
  3386. case OSG_LA_PF:
  3387. data += getComponentSize(); break;
  3388. case OSG_BGRA_PF:
  3389. case OSG_RGBA_PF:
  3390. data += getComponentSize() * 3; break;
  3391. default:
  3392. FWARNING(("Image::calcIsAlphaBinary: found unknown "
  3393. "image format %x, assumning false.\n",
  3394. getPixelFormat()));
  3395. return false;
  3396. }
  3397. switch(getDataType())
  3398. {
  3399. case OSG_UINT8_IMAGEDATA:
  3400. for(; npix > 0; --npix, data += pixelsize)
  3401. {
  3402. if(*data != 0 && *data != 0xffU)
  3403. break;
  3404. }
  3405. break;
  3406. case OSG_UINT16_IMAGEDATA:
  3407. for(; npix > 0; --npix, data += pixelsize)
  3408. {
  3409. const UInt16 *d = reinterpret_cast<const UInt16*>(data);
  3410. if(*d != 0 && *d != 0xffffU)
  3411. break;
  3412. }
  3413. break;
  3414. case OSG_UINT32_IMAGEDATA:
  3415. for(; npix > 0; --npix, data += pixelsize)
  3416. {
  3417. const UInt32 *d = reinterpret_cast<const UInt32*>(data);
  3418. if(*d != 0 && *d != 0xffffffffU)
  3419. break;
  3420. }
  3421. break;
  3422. case OSG_FLOAT16_IMAGEDATA:
  3423. for(; npix > 0; --npix, data += pixelsize)
  3424. {
  3425. const Real16 *d = reinterpret_cast<const Real16*>(data);
  3426. if(*d != 0 && *d != 1)
  3427. break;
  3428. }
  3429. break;
  3430. case OSG_FLOAT32_IMAGEDATA:
  3431. for(; npix > 0; --npix, data += pixelsize)
  3432. {
  3433. const Real32 *d = reinterpret_cast<const Real32*>(data);
  3434. if(*d != 0 && *d != 1)
  3435. break;
  3436. }
  3437. break;
  3438. case OSG_INT16_IMAGEDATA:
  3439. case OSG_INT32_IMAGEDATA:
  3440. {
  3441. FFATAL((" 'calcIsAlphaBinary' NYI\n "));
  3442. }
  3443. break;
  3444. default:
  3445. FWARNING(("Image::calcIsAlphaBinary: found unknown "
  3446. "data type %d, assumning false.\n",
  3447. getDataType()));
  3448. return false;
  3449. }
  3450. return npix == 0;
  3451. }
  3452. /*! Method which returns the frame number for the given time
  3453. */
  3454. UInt32 Image::calcFrameNum(Time time, bool OSG_CHECK_ARG(loop)) const
  3455. {
  3456. UInt64 frameNum = ((getFrameDelay() > 0) && (getFrameCount() > 0)) ?
  3457. (UInt64(time / getFrameDelay()) % getFrameCount()) : 0;
  3458. return ((frameNum > 0) ? UInt32(frameNum) : 0);
  3459. }
  3460. /*! Internal used method to calculate the next mipmap geo for the given level
  3461. */
  3462. void Image::calcMipmapGeometry(UInt32 mipmapNum,
  3463. UInt32 &width,
  3464. UInt32 &height,
  3465. UInt32 &depth ) const
  3466. {
  3467. width = getWidth() ? osgMax(getWidth () >> mipmapNum, 1) : 0 ;
  3468. height = getHeight() ? osgMax(getHeight() >> mipmapNum, 1) : 0 ;
  3469. depth = getDepth() ? osgMax(getDepth () >> mipmapNum, 1) : 0 ;
  3470. }
  3471. #ifdef __sgi
  3472. #pragma set woff 1209
  3473. #endif
  3474. /*! Internal used method to calculate the number of mipmaps levels
  3475. */
  3476. UInt32 Image::calcMipmapLevelCount(void) const
  3477. {
  3478. UInt32 w = getWidth(), h = getHeight(), d = getDepth();
  3479. UInt32 level;
  3480. for (level = 1; true; level++)
  3481. {
  3482. if ((w == 1) && (h == 1) && (d == 1))
  3483. {
  3484. break;
  3485. }
  3486. else
  3487. {
  3488. w = (w >>= 1) ? w : 1;
  3489. h = (h >>= 1) ? h : 1;
  3490. d = (d >>= 1) ? d : 1;
  3491. }
  3492. }
  3493. return level;
  3494. }
  3495. #ifdef __sgi
  3496. #pragma reset woff 1209
  3497. #endif
  3498. /*-------------------------------------------------------------------------*/
  3499. /* Calculate Mipmap Size */
  3500. /*! Method to calculate the mem sum of a mipmap level in byte
  3501. */
  3502. UInt32 Image::calcMipmapLevelSize ( UInt32 mipmapNum,
  3503. UInt32 w, UInt32 h, UInt32 d) const
  3504. {
  3505. Int32 sum;
  3506. switch (getPixelFormat())
  3507. {
  3508. case OSG_RGB_DXT1:
  3509. case OSG_RGBA_DXT1:
  3510. sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 8;
  3511. break;
  3512. case OSG_RGBA_DXT3:
  3513. case OSG_RGBA_DXT5:
  3514. sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 16;
  3515. break;
  3516. default:
  3517. sum = (w?w:1) * (h?h:1) * getBpp();
  3518. break;
  3519. }
  3520. sum *= (d?d:1);
  3521. return sum;
  3522. }
  3523. /*! Internal used method to calculate the size in bpp of a single mipmap
  3524. level for the current image settings
  3525. */
  3526. UInt32 Image::calcMipmapLevelSize(UInt32 mipmapNum) const
  3527. {
  3528. UInt32 w, h, d;
  3529. calcMipmapGeometry(mipmapNum, w, h, d);
  3530. return calcMipmapLevelSize(mipmapNum, w, h, d);
  3531. }
  3532. /*! Internal used method to calculate the mem sum of all mipmap levels in bpp
  3533. */
  3534. UInt32 Image::calcMipmapSumSize(UInt32 mipmapNum,
  3535. UInt32 w,
  3536. UInt32 h,
  3537. UInt32 d) const
  3538. {
  3539. Int32 sum = 0;
  3540. if (w && h && d)
  3541. {
  3542. while (mipmapNum--)
  3543. {
  3544. sum += calcMipmapLevelSize(mipmapNum,w,h,d);
  3545. w >>= 1;
  3546. h >>= 1;
  3547. d >>= 1;
  3548. }
  3549. }
  3550. return sum;
  3551. }
  3552. /*! Method to calculate the mem sum of all mipmap levels in byte
  3553. for the current Image paramter
  3554. */
  3555. UInt32 Image::calcMipmapSumSize (UInt32 mipmapNum) const
  3556. {
  3557. return calcMipmapSumSize(mipmapNum, getWidth(), getHeight(), getDepth());
  3558. }
  3559. /*-------------------------------------------------------------------------*/
  3560. /* Image data */
  3561. /*! Internal method to set the data and update related properties.
  3562. */
  3563. bool Image::createData(const UInt8 *data, bool allocMem)
  3564. {
  3565. Int32 i;
  3566. Int32 mapSizeFormat = sizeof(_formatDic) / sizeof(UInt32[2]);
  3567. Int32 mapSizeType = sizeof(_typeDic ) / sizeof(UInt32[2]);
  3568. UInt32 byteCount = 0;
  3569. // set bpp
  3570. UInt32 pixelFormat = 0;
  3571. UInt32 typeFormat = 0;
  3572. for(i = 0; i < mapSizeFormat; i++)
  3573. {
  3574. if(_formatDic[i][0] == getPixelFormat())
  3575. pixelFormat = _formatDic[i][1];
  3576. }
  3577. for(i = 0; i < mapSizeType; i++)
  3578. {
  3579. if(_typeDic[i][0] == getDataType())
  3580. typeFormat = _typeDic[i][1];
  3581. }
  3582. setComponentSize(typeFormat );
  3583. setBpp (pixelFormat * typeFormat);
  3584. // set dimension
  3585. setDimension(0);
  3586. if(getDepth() == 1)
  3587. {
  3588. if(getHeight() == 1)
  3589. {
  3590. setDimension(1);
  3591. }
  3592. else
  3593. {
  3594. setDimension(2);
  3595. }
  3596. }
  3597. else
  3598. {
  3599. setDimension(3);
  3600. }
  3601. // set sideSize
  3602. UInt32 mipmapSumSize = calcMipmapSumSize(getMipMapCount());
  3603. setSideSize (mipmapSumSize);
  3604. // set frameSize
  3605. setFrameSize(getSideSize() * getSideCount());
  3606. // copy the data
  3607. if(allocMem && (byteCount = getSize()))
  3608. {
  3609. if(getMFPixel()->size() != byteCount)
  3610. {
  3611. try
  3612. {
  3613. if(byteCount < getMFPixel()->size())
  3614. {
  3615. editMFPixel()->clear();
  3616. // free unused memory.
  3617. MFUInt8 tmp;
  3618. tmp.swap(*editMFPixel());
  3619. }
  3620. editMFPixel()->resize(byteCount);
  3621. }
  3622. catch(...)
  3623. {
  3624. FFATAL(("Image::createData : Couldn't allocate %u bytes!\n",
  3625. byteCount));
  3626. return false;
  3627. }
  3628. }
  3629. if(data)
  3630. {
  3631. memcpy(editData(), data, byteCount);
  3632. }
  3633. }
  3634. else
  3635. {
  3636. editMFPixel()->clear();
  3637. }
  3638. return (getData() != NULL);
  3639. }
  3640. /*! Internal method to scale image data blocks
  3641. */
  3642. bool Image::scaleData(const UInt8 *srcData,
  3643. Int32 srcW,
  3644. Int32 srcH,
  3645. Int32 srcD,
  3646. UInt8 *destData,
  3647. Int32 destW,
  3648. Int32 destH,
  3649. Int32 destD )
  3650. {
  3651. Real32 sx = Real32(srcW) / Real32(destW);
  3652. Real32 sy = Real32(srcH) / Real32(destH);
  3653. Real32 sz = Real32(srcD) / Real32(destD);
  3654. Int32 srcSize = srcW * srcH * srcD * getBpp();
  3655. // Int32 destDize = destW * destH * destD;
  3656. Int32 x, y, z, p;
  3657. const UInt8 *slice;
  3658. const UInt8 *line;
  3659. const UInt8 *pixel;
  3660. if(destW == srcW && destH == srcH && destD == srcD)
  3661. {
  3662. // same size, just copy
  3663. memcpy(destData, srcData, srcSize);
  3664. }
  3665. else
  3666. { // different size, to 'nearest' copy
  3667. for(z = 0; z < destD; z++)
  3668. {
  3669. slice = srcData + int(sz * z) * getBpp() * srcW * srcH;
  3670. for(y = 0; y < destH; y++)
  3671. {
  3672. line = slice + int(sy * y) * getBpp() * srcW;
  3673. for(x = 0; x < destW; x++)
  3674. {
  3675. pixel = line + int(sx * x) * getBpp();
  3676. p = getBpp();
  3677. while(p--)
  3678. {
  3679. *destData++ = *pixel++;
  3680. }
  3681. }
  3682. }
  3683. }
  3684. }
  3685. return true;
  3686. }
  3687. void Image::calcMipmapOffsets(void)
  3688. {
  3689. UInt32 mipMapCount = getMipMapCount();
  3690. if(mipMapCount == 0)
  3691. mipMapCount = 1;
  3692. _mipmapOffset.resize(mipMapCount);
  3693. /*
  3694. for(UInt32 i=0;i<mipMapCount;++i)
  3695. _mipmapOffset[i] = calcMipmapSumSize[i];
  3696. */
  3697. Int32 sum = 0;
  3698. UInt32 w = getWidth ();
  3699. UInt32 h = getHeight();
  3700. UInt32 d = getDepth ();
  3701. _mipmapOffset[0] = 0;
  3702. for(UInt32 i=1;i<mipMapCount;++i)
  3703. {
  3704. sum += calcMipmapLevelSize(i,w,h,d);
  3705. _mipmapOffset[i] = sum;
  3706. w >>= 1;
  3707. h >>= 1;
  3708. d >>= 1;
  3709. }
  3710. }
  3711. /*! Internal method to mirror image data blocks
  3712. */
  3713. bool Image::mirrorData(const UInt8 *srcData,
  3714. UInt8 *destData,
  3715. Int32 width,
  3716. Int32 height,
  3717. Int32 depth,
  3718. bool horizontal,
  3719. bool vertical,
  3720. bool flipDepth)
  3721. {
  3722. int dx_step = horizontal ? -1 : 1;
  3723. int dx_start = horizontal ? width-1 : 0;
  3724. int dy_step = vertical ? -1 : 1;
  3725. int dy_start = vertical ? height-1 : 0;
  3726. int dz_step = flipDepth ? -1 : 1;
  3727. int dz_start = flipDepth ? depth-1 : 0;
  3728. int dz = dz_start;
  3729. for(int sz = 0; sz < depth; sz++, dz += dz_step)
  3730. {
  3731. const UInt8 *src_slice = srcData + (sz * getBpp() * width * height);
  3732. UInt8 *dst_slice = destData + (dz * getBpp() * width * height);
  3733. int dy = dy_start;
  3734. for(int sy = 0; sy < height; sy++, dy += dy_step)
  3735. {
  3736. const UInt8 *src_line = src_slice + (sy * getBpp() * width);
  3737. UInt8 *dst_line = dst_slice + (dy * getBpp() * width);
  3738. int dx = dx_start;
  3739. for(int sx = 0; sx < width; sx++, dx += dx_step)
  3740. {
  3741. const UInt8 *src_pixel = src_line + (sx * getBpp());
  3742. UInt8 *dst_pixel = dst_line + (dx * getBpp());
  3743. Int32 p = getBpp();
  3744. while(p--)
  3745. {
  3746. *dst_pixel++ = *src_pixel++;
  3747. }
  3748. }
  3749. }
  3750. }
  3751. return true;
  3752. }
  3753. /*! Assign operator. Does a copy of the given Image object.
  3754. */
  3755. Image &Image::operator=(const Image &image)
  3756. {
  3757. this->set(PixelFormat(image.getPixelFormat()),
  3758. image.getWidth (),
  3759. image.getHeight (),
  3760. image.getDepth (),
  3761. image.getMipMapCount(),
  3762. image.getFrameCount (),
  3763. image.getFrameDelay (),
  3764. image.getData (),
  3765. image.getDataType (),
  3766. true,
  3767. image.getSideCount ());
  3768. return *this;
  3769. }
  3770. /*! Less operator; compares the data sizes of the two images
  3771. */
  3772. bool Image::operator<(const Image &image)
  3773. {
  3774. return (getSize() < image.getSize()) ? true : false;
  3775. }
  3776. /*! Method to compare the object to another Image instance;
  3777. Checks first all parameter and afterwards the Image data;
  3778. */
  3779. bool Image::operator ==(const Image &image)
  3780. {
  3781. unsigned long i, s = getSize();
  3782. if((getWidth () == image.getWidth ()) &&
  3783. (getHeight () == image.getHeight ()) &&
  3784. (getDepth () == image.getDepth ()) &&
  3785. (getMipMapCount() == image.getMipMapCount()) &&
  3786. (getFrameCount () == image.getFrameCount ()) &&
  3787. (getFrameDelay () == image.getFrameDelay ()) &&
  3788. (getPixelFormat() == image.getPixelFormat()) &&
  3789. (getDataType () == image.getDataType ()) &&
  3790. (getSideCount () == image.getSideCount ()))
  3791. {
  3792. for(i = 0; i < s; ++i)
  3793. {
  3794. if(image.getData()[i] != getData()[i])
  3795. return false;
  3796. }
  3797. return true;
  3798. }
  3799. return false;
  3800. }
  3801. /*! Method to compare the object to another Image instance;
  3802. Checks first all parameter and afterwards the Image data;
  3803. */
  3804. bool Image::operator !=(const Image &image)
  3805. {
  3806. return !(*this == image);
  3807. }
  3808. #if 0
  3809. /*! Explicitly notfies parents about a change of the image contents. This is
  3810. not strictly required because they are notified anyways, but can be used
  3811. for optimization by specifying only the area that has actually changed.
  3812. \note Currently only TextureChunks are notified.
  3813. \warning Successive calls to this function will overwrite the previously
  3814. set dirty area. If an application makes changes to multiple regions
  3815. they have to accumulated by the user before calling this function.
  3816. */
  3817. void
  3818. Image::imageContentChanged(
  3819. Int32 minX, Int32 maxX, Int32 minY, Int32 maxY, Int32 minZ, Int32 maxZ)
  3820. {
  3821. MFFieldContainerPtr::iterator parentsIt = _mfParents.begin();
  3822. MFFieldContainerPtr::iterator parentsEnd = _mfParents.end ();
  3823. for(; parentsIt != parentsEnd; ++parentsIt)
  3824. {
  3825. TextureChunkPtr texParent = TextureChunkPtr::dcast(*parentsIt);
  3826. if(texParent != NullFC)
  3827. {
  3828. texParent->imageContentChanged(minX, maxX, minY, maxY, minZ, maxZ);
  3829. }
  3830. }
  3831. }
  3832. #endif